void k_kb_iProcess() { kernel->suspended_process = kernel->current_process; kernel->current_process = getPCB(KB_PID); //k_atomic(on); MsgEnv * msg_env = k_receive_message(); if(msg_env){ if(kb_share_mem->ok_flag == 1){ int i = 0; while((msg_env->msg[i] = kb_share_mem->value[i])) i++; msg_env->type = CONSOLE_INPUT; k_send_message(msg_env->senderID, msg_env); kb_share_mem->size = 0; kb_share_mem->ok_flag = 0; }else{ PCB * kb_pcb = getPCB(KB_PID); msg_env->nextMsgEnv = kb_pcb->msgEnvQueue->nextMsgEnv; kb_pcb->msgEnvQueue->nextMsgEnv = msg_env; } } kernel->current_process = kernel->suspended_process; //k_atomic(off); }
int k_send_message(int dest_process_id, MsgEnv * msg_envelope){ PCB * pcb = getPCB(dest_process_id); if(!pcb || !msg_envelope){ return 1; } //Edit msg info and enqueue to env queue msg_envelope->senderID = kernel->current_process->id; msg_envelope->destID = dest_process_id; MsgEnv * tail = pcb->msgEnvQueue; if(tail){ while(tail->nextMsgEnv) tail = tail->nextMsgEnv; tail->nextMsgEnv = msg_envelope; }else{ pcb->msgEnvQueue = msg_envelope; } if(pcb->state == BLOCK_ON_RCV){ //dePQ(kernel->bq, pcb); pcb->state = READY; enPQ(kernel->rq, pcb, pcb->priority); } enTraceBuf(kernel->firstSent, msg_envelope); return 0; }
int k_change_priority(int new_priority, int target_process_id) { if (new_priority > 3 || new_priority < 0) { MsgEnv *output; sprintf(output->msg, "KERNEL ERROR: Priority is out of bounds\n"); send_console_chars(output); return 1; } else { PCB * pcb = getPCB(target_process_id); pcb->priority = new_priority; } return 0; }
int Scheduler::requestProcessStatus(MsgEnv* returnMsg) { char* dataPtr = returnMsg->_messageContents; dataPtr = dataPtr + sprintf(dataPtr, "Process ID Process Name Run Count Priority Status\n"); for(int i=0; i<PROCESS_COUNT; i++) { PCB* nextPCB = getPCB(i); dataPtr = dataPtr + sprintf(dataPtr, "%-14d", nextPCB->_processID); dataPtr = dataPtr + sprintf(dataPtr, "%-15s", PROCESS_DESCS[nextPCB->_processID]); dataPtr = dataPtr + sprintf(dataPtr, "%-13d", nextPCB->_runCount); dataPtr = dataPtr + sprintf(dataPtr, "%-12s", PRIORITY_DESCS[nextPCB->_priority]); dataPtr = dataPtr + sprintf(dataPtr, "%s\n", STATUS_DESCS[nextPCB->_status]); } return SUCCESS; }
//crt-iprocess check local buffer //if its ready, copy data to share memory and reset local buffer void k_crt_iProcess() { kernel->suspended_process = kernel->current_process; kernel->current_process = getPCB(CRT_PID); MsgEnv * msg_env = k_receive_message(); if(msg_env != NULL){ if (msg_env->senderID) if(crt_share_mem->ok_flag == 0){ int i = 0; while((crt_share_mem->value[i] = msg_env->msg[i])) i++; msg_env->type = DISPLAY_ACK; k_send_message(msg_env->senderID, msg_env); crt_share_mem->ok_flag = 1; crt_share_mem->size = i; }else{ //we send the env back to the beginnning of the msg queue PCB * crt_pcb = getPCB(CRT_PID); msg_env->nextMsgEnv = crt_pcb->msgEnvQueue; crt_pcb->msgEnvQueue = msg_env; } } kernel->current_process = kernel->suspended_process; }
void k_timing_iProcess(){ if(kernel->current_process == NULL) return; //PCB * old_process = kernel->current_process; //kernel->current_process = getPCB(TIMING_PID); k_atomic(on); kernel->totalTicks++; PCB * timing_pcb = getPCB(TIMING_PID); MsgEnv * envPrev = timing_pcb->msgEnvQueue; MsgEnv * envCurrent = envPrev; int destID = 0; while(envCurrent){ envCurrent->msg[0]--; if(envCurrent->msg[0] == 0){ //dequeue from msg queue if(envPrev == envCurrent && envCurrent->nextMsgEnv==NULL){ timing_pcb->msgEnvQueue = NULL; }else if (envPrev == envCurrent) { timing_pcb->msgEnvQueue = envCurrent->nextMsgEnv; envPrev =timing_pcb->msgEnvQueue; envCurrent->nextMsgEnv = NULL; }else{ envPrev->nextMsgEnv = envCurrent->nextMsgEnv; envCurrent->nextMsgEnv = NULL; } //send message back to sender process envCurrent->type = WAKEUP_CODE; destID = envCurrent->senderID; envCurrent->senderID = envCurrent->destID; k_send_message(destID, envCurrent); envCurrent = envPrev->nextMsgEnv; }else{ envPrev = envCurrent; envCurrent = envCurrent->nextMsgEnv; } } //k_release_processor(); k_atomic(off); //kernel->current_process = old_process; }
int Scheduler::changePriority(int newPriority, int processID) { // Validate input... if(newPriority < CRITICAL || newPriority >= NULL_PROCESS || processID >= PROCESS_COUNT) { return OUT_OF_BOUNDS; } PCB* changedPCB = getPCB(processID); int oldPriority = changedPCB->_priority; // Cannot change the priority of the null process if(oldPriority == NULL_PROCESS) { return INVALID_INPUT; } // If no change is required, return immediatly if(oldPriority == newPriority) { return SUCCESS; } else { changedPCB->_priority = newPriority; } // Inspect the PCB to find out where it is if(changedPCB->_status == RUNNING || changedPCB->_status == BLOCKED_MSG_RECEIVE) { // No shuffling required return SUCCESS; } else if(changedPCB->_status == READY) { // Switch ready queues _readyQueues[oldPriority].remove(changedPCB); _readyQueues[newPriority].enqueue(changedPCB); return SUCCESS; } else if(changedPCB->_status < BLOCKED_QUEUE_COUNT) { // Rearrange it in its blocked queue _blockedQueues[changedPCB->_status].remove(changedPCB); _blockedQueues[changedPCB->_status].insert(changedPCB, &prioritySort); return SUCCESS; } // PCB status is invalid return UNKNOWN_ERROR; }