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 start_f() { while (1) { append_result(); MsgEnv *env = request_msg_env(); utest_assert(send_message(0, env) == CODE_SUCCESS, "F could not send an env to A"); env = request_msg_env(); utest_assert(send_message(1, env) == CODE_SUCCESS, "F could not send an env to B"); release_processor(); } }
void procA () { //receive the message envelope from CCI when user types in 's' //then deallocate the received message envelope ps("1"); MsgEnv *init_msg = (MsgEnv*)receive_message(); while (init_msg==NULL) { init_msg = (MsgEnv*)receive_message(); } release_message_env(init_msg); ps("2"); //initialize counter int num_count = 0; //loop forever while(1) { //request a message envelope, and set the type to COUNT_REPORT //set the data field of the msg env equal to the counter MsgEnv *toB = (MsgEnv*)request_msg_env(); toB->msg_type = COUNT_REPORT; toB->data[0] = (char)num_count; toB->data[1] = '\0'; //send the message envelope to B //increment the counter and yield the processor to other processes send_message(PROCB_ID, toB); num_count++; ps("test2"); release_processor(); } }
void print_board () { MsgEnv* msg = request_msg_env(); rtx_strcpy(msg->msg, "\033[0;0H", 1024); send_console_chars(msg, FALSE); int r, c; for (r = 0; r < BOARD_ROWS; r++) { MsgEnv* message = request_msg_env(); for (c = 0; c < BOARD_COLS; c++) { message->msg[c] = board[r][c]; } message->msg[BOARD_COLS] = '\n'; message->msg[BOARD_COLS+1] = '\r'; message->msg[BOARD_COLS+2] = '\0'; send_console_chars(message, FALSE); } }
void procA () { MsgEnv *init_msg = (MsgEnv*)receive_message(); while (init_msg==NULL) { init_msg = (MsgEnv*)receive_message(); } release_message_env(init_msg); int num_count = 0; /* MsgEnv *env = (MsgEnv*)request_msg_env(); ps("Timer for 5 secs"); request_delay(5,WAKEUP10,env); env = (MsgEnv*)receive_message(); while(env->msg_type!=WAKEUP10) { env = (MsgEnv*) receive_message(); } */ //loop forever while(1) { //request a message envelope, and set the type to COUNT_REPORT //set the data field of the msg env equal to the counter MsgEnv *toB = (MsgEnv*)request_msg_env(); // BBJ no need for while loop. We get blocked on request if we couldnt get env. /*while(toB == NULL) { toB = (MsgEnv*)request_msg_env(); }*/ toB->msg_type = COUNT_REPORT; sprintf(toB->data,"%i",num_count); //toB->time_delay=num_count; //send the message envelope to B //increment the counter and yield the processor to other processes send_message(PROCB_ID, toB); num_count++; usleep(50000); release_processor(); } }
// *** 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(); } }
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 cci_process() { CCI_DISPLAY_ENV = request_msg_env(); MsgEnv *cci_env = request_msg_env(); MsgEnv* a_env = request_msg_env(); // this wont be released as process A will release it later char formatted_msg[1000]; int retVal; while(1) { const int twait = 500000; cci_print("CCI: "); //cci_env = request_msg_env(); get_console_chars(cci_env); cci_env = receive_message(); while(cci_env->msg_type != CONSOLE_INPUT) { release_message_env(cci_env); cci_env = receive_message(); } //Obtained keyboard input char command [MAXCHAR]; int offset = sprintf(command, cci_env->data); // Check atleast 2 characters even if user entered 1. if (offset < 2) offset = 2; // Send a message to process A. This only happens once. If it has already been sent, then prompt user. if (strncasecmp(command, "s", offset) == 0) { if (a_env != NULL) { retVal = send_message(PROCA_ID, a_env); if (retVal != SUCCESS) cci_print("Failed to send message envlope and start A\n"); a_env = NULL; } else { cci_print("A has already started.\n"); } } else if(strncasecmp(command, "ps", offset ) == 0) { retVal = request_process_status(cci_env); if (retVal != SUCCESS) cci_print("Failed to request process status"); sprintf(formatted_msg, cci_env->data); cci_print(formatted_msg); } else if(strncasecmp(command, "cd", offset) == 0) { displayClock(1); } else if(strncasecmp(command, "ct", offset) == 0) { displayClock(0); } // Display Trace Buffers else if(strncasecmp(command, "b", offset) == 0) { retVal = get_trace_buffers(cci_env); if (retVal != SUCCESS) cci_print("Failed to get trace buffers"); sprintf(formatted_msg, "%s", cci_env->data); cci_print(formatted_msg); } else if(strncasecmp(command, "c", 2) == 0) { if(command[4] != ':' || command[7] != ':' || strlen(command) != 10) { sprintf(formatted_msg, "Invalid format for command %s. It should be: c <hh>:<mm>:<ss>\n", "c"); cci_print(formatted_msg); } else { const char * rawTimeString = command+2; char hourString [3] = { '0', '0', '\0'}; char minString [3] = { '0', '0', '\0'}; char secString [3] = { '0', '0', '\0'}; int i, hr, min, sec; for (i=0;i<2;i++) { hourString[i] =rawTimeString[i]; minString[i]=rawTimeString[3+i]; secString[i]=rawTimeString[6+i]; } hour = atoi(hourString); min = atoi(minString); sec = atoi(secString); if (hour>23 || min>59 || sec > 59) { sprintf(formatted_msg, "Invalid input." " Ensure hh not greater than 23, mm not greater than 59, ss not greater than 59.\n"); cci_print(formatted_msg); } else setClock(hour, min, sec); // offset the "c " (c-space) } } else if(strncasecmp(command, "n", 1) == 0) { int priority, pid; // extract priority and pid from the command if (sscanf(command, "%*s %i %i", &priority, &pid)!=2) { sprintf(formatted_msg, "Invalid format for command %s. It should be: n <priority> <process id>\n", "n"); cci_print(formatted_msg); } else { retVal = change_priority(priority, pid); sprintf(formatted_msg, "Priority: %i, Pid: %i\n", priority, pid); cci_print(formatted_msg); if (retVal == ILLEGAL_ARGUMENT) { sprintf(formatted_msg, "Invalid arguments. Ensure that the priority is between [0-3], and the process ID is a valid" "process ID other than the NULL process ID\n"); cci_print(formatted_msg); } else if (retVal != SUCCESS) { cci_print("Priority of specified process could not be changed\n"); } } } else if(strncasecmp(command, "t", offset) == 0) { // no need to release envelopes as terminate will free all memory from MSG_LIST terminate(); } // debugging function. find where all the envelopes are. else if(strncasecmp(command, "en", offset) == 0) { int offset = sprintf(formatted_msg, "\nEnvelope Num\tHeld By\n"); int i; for (i = 0; i < MSG_ENV_COUNT; ++i) { const char* pcb_name; switch(MSG_LIST[i]->dest_pid) { case(-1): pcb_name = "NONE\0"; break; default: pcb_name = PCB_LIST[MSG_LIST[i]->dest_pid]->name; } offset += sprintf(formatted_msg+offset, "%i\t\t%s\n", i+1, pcb_name); } cci_print(formatted_msg); } // debugging, check all queues else if(strncasecmp(command, "cq", offset) == 0) { int offset = 0; offset += sprintf(formatted_msg, "\nREADY QUEUE"); int rdy_queues = proc_pq_get_num_prorities(RDY_PROC_QUEUE); int i; for (i = 0; i < rdy_queues; ++i) { offset+= sprintf(formatted_msg+offset, "\nPriority %i: ", i); pcb* head = RDY_PROC_QUEUE->priority_queues[i]->head; while (head != NULL) { offset += sprintf(formatted_msg+offset, "%s->", head->name); head = head->next; } } offset += sprintf(formatted_msg+offset, "\n\nBLOCKED QUEUE: "); pcb* head = BLOCKED_QUEUE->head; while(head!=NULL) { offset += sprintf(formatted_msg+offset, "%s->", head->name); head = head->next; } offset += sprintf(formatted_msg + offset, "\n\n"); cci_print(formatted_msg); } // One space and enter results in CCI: being printed again else if(strncasecmp(command, " ", offset) == 0) { } // If enter is directly pressed, display a different error else if(strcmp(command, "") == 0) { cci_print("Enter a command!\n"); } // Default error message else { sprintf(formatted_msg, "The command %s is not supported\n", command); cci_print(formatted_msg); } //printf("releasing %p\n", cci_env); //release_message_env(cci_env); } fflush(stdout); printf("=====================WTH! CCI came out of while loop!"); fflush(stdout); terminate(); }
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 CCI() { //printf("You're in the CCI\n"); int HH=0; int MM=0; int SS=0; int pri=0; int id=0; int U = 0; int dun = 0; msg_env* env = request_msg_env(); msg_env* first = request_msg_env(); while(1) { // send the welcome message /* if (first == NULL){ terminate(1); } strcpy(first->msg_text, "Enter input for the CCI [s, ps, c [##:##:##], cd, ct, b, n [new_prio] [pid], e... , t]:\0"); int F = 0; F = send_console_chars(first); if (F == 0){ terminate(1); } */ U = get_console_chars(env); //keyboard input //sleep(5); // only do this if there was input if (U==1) { env = receive_message(); while (env->msg_type != CONSOLE_INPUT) { env = receive_message(); //***STOPS HERE TO WAIT FOR INPUT } char* input_txt = env->msg_text; // send envelope to Process A if (strcmp(input_txt,"s")==0) { // printf("input was s\n"); //if the text in the field is "s" env = request_msg_env(); //request an envelope int Z =0; Z = send_message(3,env); // send message to Process A } // display process status of all processes else if (strcmp(input_txt,"ps")==0) { // printf("input was ps\n"); env = request_msg_env(); //request an envelope int J=request_process_status(env); if (J==0) printf("Error with getting Process Status\n"); } // allows time to be displayed on console and halts if getting ct else if (strcmp(input_txt,"cd")==0) { // printf("input was cd\n"); wallClockOut = 1; } else if (strcmp(input_txt,"ct")==0) { // printf("input was ct\n"); wallClockOut = 0; } // set clock to any valid 24hr time else if (strncmp(input_txt,"c", 1)==0) { // printf("input was c\n"); int HH = atoi(input_txt+2); int MM = atoi(input_txt+5); int SS = atoi(input_txt+8); int R = clock_set(wallclock, HH, MM, SS); if (R==0) printf("Error with setting clock in CCI\n"); } // b displays past instances of send and receive messages else if (strcmp(input_txt,"b")==0) { // printf("input was b\n"); env = request_msg_env(); //request an envelope int U=get_trace_buffers(env); if (U==0) printf("Error performing call on Trace Buffers\n"); } // terminates RTX else if (strcmp(input_txt,"t")==0) { terminate(0); } // changes priority else if (strncmp(input_txt,"n",1)==0) { // printf("input was n\n"); int new_pri = atoi(input_txt+2); int ID = atoi(input_txt+4); int R = change_priority(new_pri, ID); if (R==0) printf("Error with changing priority in CCI\n"); } // echo the input back else if (strncmp(input_txt,"e", 1)==0) { // printf("input was e\n"); env = request_msg_env(); //request an envelope input_txt[0] = ' '; strcat(input_txt, "\n\n"); strcpy(env->msg_text, "echo is: "); strcpy(env->msg_text, input_txt); int R = send_console_chars(env); if (R==0) printf("Error with echoing to screen\n"); } else { env = request_msg_env(); //request an envelope char* temp = (char*) malloc(sizeof(SIZE)); sprintf(temp, "'%s' is not valid CCI input. Please try again.\n\n", input_txt); strcpy(env->msg_text, temp); int R = send_console_chars(env); if (R==0) printf("Error with printing invalid input message\n"); // printf("'%s' is not valid CCI input. Please try again.\n\n", input_txt); } dun = release_msg_env(env); if (dun == 0) { env = request_msg_env(); //request an envelope strcpy(env->msg_text, "ERROR IN DEALLOCATING ENVELOPE AT END OF CCI\n"); int R = send_console_chars(env); if (R==0) printf("Error with printing error message\n"); } //else // printf("CCI finished, I think\n"); } env = request_msg_env(); // if there was no input release_processor(); } }
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(); } }