void clock_process() { envQ = MsgEnvQ_create(); clockDisplayRequest = 0; clockTime = 0; timeoutEnv = (MsgEnv*) request_msg_env(); displayEnv = (MsgEnv*) request_msg_env(); checkBit = request_delay(1,WAKEUP10,timeoutEnv); if (checkBit!=SUCCESS) { ps("Message couldnt be sent to timer iproc from clock process"); } while (1) { if (MsgEnvQ_is_empty(envQ)) generalEnv = receive_message(); else generalEnv = MsgEnvQ_dequeue(envQ); if (generalEnv->msg_type==DISPLAY_ACK) { displayEnv = generalEnv; continue; } //envelope from timing services if (generalEnv->msg_type == WAKEUP10) { //release_message_env(generalEnv); timeoutEnv = generalEnv; checkBit = request_delay(1, WAKEUP10, timeoutEnv); if (checkBit != SUCCESS) { ps("Message couldnt be sent to timer iproc from clock process"); } //86400 = 24hrs in secs clockTime++;//(int32_t)((clock_get_system_time()-ref)/10+offset)%SEC_IN_HR; if (clockDisplayRequest) { /*int hours = clockTime%3600; int mins = (clockTime - hours*60*60)%60; int secs = (clockTime - hours*60*60 - mins*60)%60;*/ int hours = clockTime/3600; int mins = (clockTime%3600)/60; int secs = clockTime%60; // whatever is remainder is seconds sprintf(displayEnv->data,"\n%02i:%02i:%02i",hours,mins,secs); send_console_chars(displayEnv); } } } release_processor(); }
void test_process_send() { //pid == 3 //testing message send MessageEnvelope* env = request_message_envelope(); printf("sending message to %d\n", 2); request_delay(10, 1, env); env = receive_message(); strcpy(env->data, "does this work?"); send_message(4, env); printf("send message successful\n"); fflush(stdout); while (1) release_processor(); }
void procC() { //create local message queue to store msg envs in FIFO order MsgEnvQ *msgQueue = (MsgEnvQ*)MsgEnvQ_create(); //initialize msg env pointers to keep track of messages MsgEnv *msg_env; MsgEnv *msg_env2; //loop forever while(1) { //if the local msg queue is empty, then receive a message, enqueue it to avoid null pointers for deallocation if(msgQueue->head == NULL) { msg_env = (MsgEnv*)receive_message(); MsgEnvQ_enqueue(msgQueue, msg_env); } //dequeue the first msg on the local msg queue msg_env = (MsgEnv*)MsgEnvQ_dequeue(msgQueue); //check if the dequeued msg type is 'COUNT_REPORT' if(msg_env->msg_type == COUNT_REPORT) { //the msg originated from proc_A, check if the data is divisible by 20 //********check the line below plz********* if( (*(int*)msg_env->data) % 20 == 0) { //get a message envelope, set the data to 'Process C' //send it to display on the screen msg_env2 = (MsgEnv*)request_msg_env(); char tempData[20] = "Process C"; memcpy(msg_env2->data,tempData,strlen(tempData)); //msg_env2->data = '\nProcess C\n'; send_console_chars(msg_env2); //wait for output confirmation with 'DISPLAY_ACK' msg type while(1) { //receive message, possibly from send_console_chars or proc_B msg_env2 = (MsgEnv*)receive_message(); //check for msg type 'env2LAY_ACK' or 'COUNT_REPORT' if (msg_env2->msg_type == DISPLAY_ACK) { //go passive for 10seconds, use the msg env we got back from send_console_chars int stat = request_delay(10000, WAKEUP10, msg_env2); //if the delay request fails //*****what do i do here?***** print error if(stat != SUCCESS) { printf("\nWHAT?!?! something went wrong with the delay request...\n"); } //resume after getting a 10seconds delay request while(1) { //reuse the msg_env2 pointer to get returned msg env from delay request msg_env2 = (MsgEnv*)receive_message(); //check if its msg_type is 'WAKEUP_10' or 'COUNT_REPORT' if(msg_env2->msg_type == WAKEUP10) { //get out of "waiting for delay finish' loop break; }else if(msg_env2->msg_type == COUNT_REPORT){ //enqueue the msg env onto local msg queue if it originated from proc_A MsgEnvQ_enqueue(msgQueue, msg_env2); }else{ //shouldn't get here, useless msg env to proc_c } } //get out of 'waiting for output confirmation' loop break; }else if(msg_env2->msg_type == COUNT_REPORT){ //enqueue the msg env onto local msg queue if it originated from proc_A MsgEnvQ_enqueue(msgQueue, msg_env2); }else{ //shouldn't get here, useless msg env to proc_c } } } } //deallocate message envelopes and release processor release_message_env(msg_env); release_message_env(msg_env2); 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 }
void process_C() { msg_env_queue_t* messageQueue = msg_env_queue_create(); while(1) { // setup variables that will be used by the process MsgEnv *deq_msg; MsgEnv *rec_msg = NULL; MsgEnv *rec_msg_2 = NULL; // check if the process message queue is empty or not // if the queue is empty, then recieve a message env // and enqueue it! if(msg_env_queue_is_empty(messageQueue)) { MsgEnv *received_msg = receive_message(); msg_env_queue_enqueue(messageQueue, received_msg); } // dequeue a message env from the message queue deq_msg = msg_env_queue_dequeue(messageQueue); // check if the dequeued message type is a COUNT_REPORT if(deq_msg->msg_type == COUNT_REPORT) { //check if the message in the env is divisible by 20 //if it is divisible, then continue into the if statement //otherwise release all envelopes and and yeild processor if (*((int *)(deq_msg->msg)) % 20 == 0) { //copys the 'Process C' string into the dequeued msg env strcpy(deq_msg->msg, "\nProcess C\n"); //send the message env to the console for printing send_console_chars(deq_msg); //loop forever (until 'breaked') while(1) { //recieve a message rec_msg = receive_message(); //check if the recieved message is a type "DISPLAY_ACK" //if not then check if it is a type "COUNT_REPORT" //and if that fails then we got a error and the RTX should report it! if(rec_msg->msg_type == DISPLAY_ACK) { //check for an error case if(request_delay(100, WAKEUP_10, rec_msg) != CODE_SUCCESS) { } break; } else if (rec_msg->msg_type == COUNT_REPORT) { //enqueue the released env back into the message queue msg_env_queue_enqueue(messageQueue, rec_msg); } else { assert(0); } } // "Go passive for 10 seconds" in the outline while(1) { //recieve a message env rec_msg_2 = receive_message(); //if the recieved env is a type 'WAKEUP_10' then //exit the while loop //otherwise, enqueue the recieved message env back into the //message env queue if(rec_msg_2->msg_type == WAKEUP_10) { break; } else { msg_env_queue_enqueue(messageQueue, rec_msg_2); } } } } //release all the envelopes and yeild the processor release_msg_env(rec_msg); release_msg_env(rec_msg_2); release_msg_env(deq_msg); release_processor(); } }
void procC() { //create local message queue to store msg envs in FIFO order MsgEnvQ *msgQueue = (MsgEnvQ*)MsgEnvQ_create(); //initialize msg env pointers to keep track of messages ps("Proc C started!"); MsgEnv *msg_env; while(1) { //while (MsgEnvQ_size(CURRENT_PROCESS->rcv_msg_queue) > 0 || MsgEnvQ_size(msgQueue) == 0) while(MsgEnvQ_size(msgQueue) == 0) { msg_env = (MsgEnv*)receive_message(); MsgEnvQ_enqueue(msgQueue, msg_env); } msg_env = (MsgEnv*)MsgEnvQ_dequeue(msgQueue); if(msg_env->msg_type == COUNT_REPORT) { if( (atoi(msg_env->data)) % 20 == 0) //if( (msg_env->time_delay) % 20 == 0) { // BBJ. Don't use memcpy etc anymore, I think this is causing memory problems in OS since it crashes like 5-6 minutes in!! //char tempData[20] = "\nProcess C\0"; //memcpy(msg_env->data,tempData,strlen(tempData)+1); sprintf(msg_env->data, "\nProcess C\n"); send_console_chars(msg_env); //wait for output confirmation with 'DISPLAY_ACK' msg type while(1) { msg_env = (MsgEnv*)receive_message(); if (msg_env->msg_type == DISPLAY_ACK) { if(request_delay(3, WAKEUP10, msg_env)!= SUCCESS) { ps("requesting delay for Process C went wrong"); } while(1){ msg_env = receive_message(); if(msg_env->msg_type==WAKEUP10) { break; }else if(msg_env->msg_type == COUNT_REPORT){ MsgEnvQ_enqueue(msgQueue, msg_env); }else{ release_message_env(msg_env); } } break; }else if(msg_env->msg_type == COUNT_REPORT){ //enqueue the msg env onto local msg queue if it originated from proc_A MsgEnvQ_enqueue(msgQueue, msg_env); } // random message. ignore else release_message_env(msg_env); } } } //deallocate message envelopes and release processor release_message_env(msg_env); if (MsgEnvQ_size(msgQueue) == 0) { ps("Process C is releasing processor!"); release_processor(); } } }
void start_wallclock() { uint32_t status; //initialise offset = 0; ref = 0; clock_display_en = 0; //clock not displayed by default timeout_env = request_msg_env(); send_env = request_msg_env(); msg_q = msg_env_queue_create(); status = request_delay ( ONE_SECOND_DELAY, WAKEUP_CODE, timeout_env); if (status != CODE_SUCCESS) { params[0] = &status; params[1] = NULL; rtx_sprintf(str, "request_delay failed with status %d\r\n", params); print_ack(str, send_env, msg_q); } MsgEnv* env; while (1) { if (msg_env_queue_is_empty(msg_q)) { env = receive_message(); } else { env = msg_env_queue_dequeue(msg_q); } //envelope from timing services if (env->msg_type == WAKEUP_CODE) { status = request_delay( ONE_SECOND_DELAY, WAKEUP_CODE, timeout_env); if (status != CODE_SUCCESS) { params[0] = &status; params[1] = NULL; rtx_sprintf(str, "request_delay failed with status %d\r\n", params); print_ack(str, send_env, msg_q); } //86400 = 24hrs in secs int32_t clock_time = (int32_t)((get_system_time()-ref)/100 +offset)%SEC_IN_HR; if (clock_display_en) { int32_t hr, min, sec; hr = clock_time/3600; min = (clock_time%3600)/60; sec = clock_time%60; params[0] = &hr; params[1] = &min; params[2] = &sec; params[3] = NULL; rtx_sprintf(str, SAVE_CURSOR MOVE_CURSOR CLOCK_FORMAT RESTORE_CURSOR, params); print_ack(str, send_env, msg_q); } } else if (env->msg_type == CLOCK_ON) { _displayWallClock (1); env->msg_type = CLOCK_RET; send_message(env->send_pid,env); } else if (env->msg_type == CLOCK_OFF) { _displayWallClock (0); env->msg_type = CLOCK_RET; send_message(env->send_pid,env); } else if (env->msg_type == CLOCK_SET) { int status = _setWallClock (env->msg); if (status == ERROR_ILLEGAL_ARG) { params[0] = NULL; rtx_sprintf( str, "c\r\n" "Sets the console clock (24h).\r\n" "Usage: c <hh:mm:ss>\r\n" "hh must be 00-23\r\n" "mm must be 00-59\r\n" "ss must be 00-59\r\n", params ); print_ack(str, send_env, msg_q); } else if (status != CODE_SUCCESS) { params[0] = &status; params[1] = NULL; rtx_sprintf( str, "CCI_setClock failed with status %d\r\n", params); print_ack(str, send_env, msg_q); } env->msg_type = CLOCK_RET; send_message(env->send_pid,env); } } }
void update_board () { MsgEnv* message = receive_message(); //release_msg_env(msg); init_pong(); print_board(); char cmd[100]; void * params [11]; request_delay(DELAY_AMOUNT, WAKEUP_10, message); while (1) { /*MsgEnv**/ message = receive_message(); if (message->msg_type == CONSOLE_INPUT) // people moving their paddles { // Keys for left are A -> UP, S -> DOWN // Keys for right are K -> UP, L -> DOWN if ((message->msg[0] == 'a' || message->msg[0] == 'A') && (left_paddle_pos > 0)) { board[left_paddle_pos+4][1] = ' '; left_paddle_pos--; board[left_paddle_pos][1] = 'M'; } else if ((message->msg[0] == 's' || message->msg[0] == 'S') && (left_paddle_pos < BOARD_COLS-5)) { board[left_paddle_pos+4][1] = ' '; left_paddle_pos++; board[left_paddle_pos][1] = 'M'; } else if ((message->msg[0] == 'k' || message->msg[0] == 'K') && (right_paddle_pos > BOARD_COLS-5)) { board[right_paddle_pos+4][BOARD_COLS-2] = ' '; right_paddle_pos--; board[right_paddle_pos][BOARD_COLS-2] = 'M'; } else if ((message->msg[0] == 'l' || message->msg[0] == 'L') && (right_paddle_pos < 15)) { board[right_paddle_pos+4][BOARD_COLS-2] = ' '; right_paddle_pos++; board[right_paddle_pos][BOARD_COLS-2] = 'M'; } release_msg_env(message); } else if (message->msg_type == WAKEUP_10) // the timer, so update the ball; { if (ball_c == 0) { init_pong();// RIGHT PLAYER SCORED print_board(); request_delay(DELAY_AMOUNT, WAKEUP_10, message); continue; } if (ball_c == BOARD_COLS-1) { init_pong();// LEFT PLAYER SCORED print_board(); request_delay(DELAY_AMOUNT, WAKEUP_10, message); continue; } // bouncing checks if (ball_r == 1 || ball_r == BOARD_ROWS-2) { r_speed = r_speed * -1; } if (ball_c == 2 && board[ball_r+r_speed][1] == 'M') { c_speed = c_speed * -1; } else if (ball_c == BOARD_COLS-3 && board[ball_r+r_speed][BOARD_COLS-2] == 'M') { c_speed = c_speed * -1; } board[ball_r][ball_c] = ' '; ball_r += r_speed; ball_c += c_speed; board[ball_r][ball_c] = 'O'; /*int prev_r = ball_r - r_speed; int prev_c = ball_c - c_speed; params[0] = &prev_r; params[1] = &prev_c; params[2] = &ball_r; params[3] = &ball_c; params[4] = NULL; rtx_sprintf(cmd, "\033[%d;%dH \033[%d;%dHO", params); MsgEnv* env = request_msg_env(); env->msg = cmd; send_console_chars(env, FALSE);*/ request_delay(DELAY_AMOUNT, WAKEUP_10, message); } print_board(); } }
void process_C() { msg_env_queue_t* messageQueue = msg_env_queue_create(); MsgEnv * timeout_msg = request_msg_env(); while(1) { // setup variables that will be used by the process MsgEnv *deq_msg; // check if the process message queue is empty or not // if the queue is empty, then recieve a message env // and enqueue it! if(msg_env_queue_is_empty(messageQueue)) { MsgEnv *received_msg = receive_message(); msg_env_queue_enqueue(messageQueue, received_msg); } // dequeue a message env from the message queue deq_msg = msg_env_queue_dequeue(messageQueue); // check if the dequeued message type is a COUNT_REPORT if(deq_msg->msg_type == COUNT_REPORT) { //check if the message in the env is divisible by 20 //if it is divisible, then continue into the if statement //otherwise release all envelopes and and yeild processor if (*((int *)(deq_msg->msg)) % 20 == 0) { //copys the 'Process C' string into the dequeued msg env rtx_strcpy(deq_msg->msg, "\r\nProcess C\r\n", 1024); //send the message env to the console for printing send_console_chars(deq_msg, 0); request_delay(1000, WAKEUP_10, timeout_msg); // "Go passive for 10 seconds" in the outline while(1) { //recieve a message env deq_msg = receive_message(); //if the recieved env is a type 'WAKEUP_10' then //exit the while loop //otherwise, enqueue the recieved message env back into the //message env queue if(deq_msg->msg_type == WAKEUP_10) { break; } else { msg_env_queue_enqueue(messageQueue, deq_msg); } } } else { release_msg_env(deq_msg); } } else { trace(ERROR, "WTEDF"); release_msg_env(deq_msg); } //release all the envelopes and yeild the processor release_processor(); } }