// ***KEYBOARD I-PROCESS*** void kbd_iproc(int sigval) { // temporary env pointer msg_env *temp_k = NULL; // only continue if the flag is 1, ie there's stuff in the buffer if (*in_mem_p->ok_flag == 1) { // start at the beginning of the buffer buf_index = 0; // get a pointer to the kb-iprocess PCB PCB * temp = convert_PID(0); //dequeue env from Keyboard env queue into temp temp_k = env_DEQ(temp->receive_msg_Q); // if the dequeued env is not NULL if (temp_k == NULL) return; // read buffer into the env, while we haven't reached the NULL do { temp_k->msg_text[buf_index] = in_mem_p->indata[buf_index]; buf_index++; } while (in_mem_p->indata[buf_index - 1] != '\0'); // printf("Keyboard input was: %s\n",in_mem_p->indata); //used for debugging // reset flag *in_mem_p->ok_flag = 0; // set the env message type to 'console input' strcpy(temp_k->msg_type, "console_input"); // send env back to process int Z = send_message(4, temp_k); // if it didn't send like it should have if (Z == 0) printf("Error with sending\n"); } /* if the buffer was empty (ie flag != 1) else printf("There is no input in the memory to read in!\n"); */ }
// *** SEND MESSAGE *** int send_message(int dest_id, msg_env *e) { // if the env is NULL if (!e) return 0; // if the PCB ID is not valid if (dest_id > (NUM_PROC - 1) ) { //printf("Invalid 'Send To' ID, %i, ", dest_id); return 0; } // if the PCD ID is valid // set the target_id parameter of the env to dest_id e->target_id = dest_id; e->sender_id = curr_process->pid; // create a pointer to the target PCB using the target_id PCB *target = convert_PID(dest_id); // if the PID converts correctly to a pointer if (target){ /*unblock the target process if necessary*/ // if the target's receive message queue is empty or the target is not an i-process /*if (target->receive_msg_Q->head == NULL || target->priority != -1) { // enqueue the PCB of the process on the appropriate ready queue PCB_ENQ(target, convert_priority(target->priority)); //*****not sure if need to put a '&' before convert_priority // set the target state to 'ready' strcpy(target->state, "READY"); //apparently strcpy is how you write into an array of chars }*/ // enqueue the env on the target's receive queue env_ENQ(e, target->receive_msg_Q); return 1; } // if the PID doesn't convert successfully else return 0; }
void crt_iproc(int sigval) { // temporary env pointer msg_env *temp_c = NULL; // put stuff in buffer only if the buffer is empty if (*out_mem_p->oc_flag == 0) { buf_index = 0; // dequeue env into msg_env temp_c = env_DEQ(convert_PID(1)->receive_msg_Q); // if the envelope is NULL don't continue if (temp_c == NULL) return; // read env into the buffer do { out_mem_p->outdata[buf_index] = temp_c->msg_text[buf_index]; buf_index++; } while (out_mem_p->outdata[buf_index - 1] != '\0'); // set flag so UART will read memory *out_mem_p->oc_flag = 1; // set env message type to 'display ack' strcpy(temp_c->msg_type, "display_ack"); // send env back to process int Z = send_message(4, temp_c); //fix this later, sender_id is 31 // if sending is stupid if (Z == 0) printf("Error with sending\n"); } /* if memory is full (ie. flag != 0) else{ printf("fix the function!!!!\n"); */ }
// *** PROCESS A *** PID 3 void ProcessA(){ // initialize return int, count int num = 0; PCB* pA_pcb = convert_PID(3); // receive the message from the CCI msg_env* envA = receive_message(); int R = 0; R = get_console_chars(envA); if (R==0) release_processor(); // deallocate the message from Proc A's queue in its PCB envA= env_DEQ(pA_pcb->receive_msg_Q); while(1) { printf("A\n"); // request an envelope msg_env* tempEnv = request_msg_env(); if(tempEnv) { // set the env type and text tempEnv->msg_type = 2; tempEnv->msg_text[0] = num; // send to ProcessB int result = send_message(4, tempEnv); num++; } release_processor(); } }
// *** PROCESS C *** PID 5 void ProcessC(){ // init the local queue struct envQ* localQ = (struct envQ *) malloc (sizeof (struct envQ)); if (localQ==NULL) { printf("localQ in Proc C not created properly"); return; } // can we use the queue on the proc pcb instead? PCB* pC_pcb = convert_PID(5); msg_env* envC = request_msg_env(); // infinite loop of normal activity while (1) { printf("A\n"); int NUM =envC->msg_text[0]; // if theres nothing the localQ, receive a message and enqueue it if (localQ->head == NULL) { envC = receive_message(); int H = env_ENQ(envC,localQ); if (H ==0) printf("Cannot enqueue on localQ"); } // if there is something on the localQ, dequeue it else { envC = env_DEQ(localQ); } // if the message type is count report, and the value in msg_text is evenly divisible by 20, display "Process C" if (envC->msg_type == 2 && NUM % 20 == 0){ // send the display message strcpy(envC->msg_text, "Process C\n\0"); int W = send_console_chars(envC); // Returns confirmation of sending if (W==1) { // if it is the ack message request a delay of 10s, with wakeup code "wakeup10" int R = request_delay(10000, WAKEUP, envC); // request_delay returns an int if (R==0) printf("Error with request_delay"); // wait for wakeup message envC = receive_message(); // if its not the wakeup message put it on the local Q while (envC->msg_type != WAKEUP) { envC = receive_message(); int XX = env_ENQ(envC,localQ); if (XX==0) printf("Error with putting message on local Q in Proc C"); } } else printf("Error sending 'Process C' to screen in Proc C"); } // deallocate envelopes int dun = release_msg_env(envC); if (dun==0) printf("ERROR IN DEALLOCATING ENVELOPE AT END OF Proc C"); // release processor release_processor(); }// end of infinite loop }