// ***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"); */ }
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"); */ }
// ***RECEIVE MESSAGE*** msg_env *receive_message() { //Doesn't take the PCB as a parameter. Dealt with using curr_process // if the receive message queue is empty if (curr_process->receive_msg_Q->head == NULL) { // if the process is an iprocess or should never be blocked, return a NULL pointer (ie. no env) if (curr_process->priority == -1 || curr_process->state == "NEVER_BLK_PROC") return NULL; // if it's a normal process, block it on receive strcpy(curr_process->state, "BLK_ON_RCV"); //*********Doesn't need to be put in a queue, and don't care about process switch now********* FIX THIS return NULL; // *****TO BE FIXED WITH CONTEXT SWITCHING } // if the message queue is not empty, dequeue the first message in the queue else return env_DEQ(curr_process->receive_msg_Q); }
// *** 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 }