Pid_t OSSim::contextSwitch(CPU_t cpu, Pid_t nPid) { // This is the process we displaced to run the target process Pid_t oldPid=-1; ProcessId *newProc = ProcessId::getProcessId(nPid); I(newProc); GProcessor *newCore=cpus.getProcessor(cpu); I(newCore); // Get the cpu where the target process is already running CPU_t runCpu=(newProc->getState()==RunningState)?newProc->getCPU():-1; // If already running on the target processor, do nothing if(runCpu==cpu) return -1; // If target core has no available flows, make one if(!newCore->availableFlows()) { oldPid=newCore->findVictimPid(); ProcessId *oldProc=ProcessId::getProcessId(oldPid); cpus.switchOut(cpu, oldProc); } // Is the target process already running on another cpu? if(runCpu!=-1) { // Get another process to run on original cpu ProcessId *repProc=ProcessId::queueGet(runCpu); // Get the target process out of old core cpus.switchOut(runCpu, newProc); // Get the replacement process (if any) into the old core if(repProc) cpus.switchIn(runCpu,repProc); // Get the target process in the target cpu cpus.switchIn(cpu, newProc); } else { // If new process not ready, make it ready if(newProc->getState()!=ReadyState) { // Make it prefer the target cpu newProc->setCPU(cpu); // Make it ready newProc->setState(InvalidState); cpus.makeRunnable(newProc); // The target cpu is prefered by the target process, and // the target cpu has available flows. Thus, the target // process should be now running on the target cpu I(newProc->getCPU()==cpu); I(newProc->getState()==RunningState); } else { // The new process is already ready, just switch it in cpus.switchIn(cpu,newProc); } } return oldPid; }
int32_t OSSim::eventYield(Pid_t curPid, Pid_t yieldPid) { // LOG("OSSim::yield(%d,%d)", curPid, yieldPid); ProcessId *curProc=ProcessId::getProcessId(curPid); // The current process should be running I(curProc->getState()==RunningState); // get the CPU where the current process is running CPU_t cpu=curProc->getCPU(); // Get the ProcessId of the new process ProcessId *yieldProc; if(yieldPid<0) { // No specific new process, get next ready process yieldProc=ProcessId::queueGet(cpu); } else { // Specific ready process, get its ProcessId yieldProc=ProcessId::getProcessId(yieldPid); // there should be such a process if(!yieldProc) { LOG("OSSim::yield(%d) to non existing process???", yieldPid); return 0; } } // Do nothing if no process to yield to if(!yieldProc) return 1; // Do nothing if the new process already running if(yieldProc->getState()==RunningState) return 1; // The new process should not be suspended if(yieldProc->getState()==SuspendedState) { LOG("OSSim::yield(%d) to a suspended process???", yieldPid); return 0; } // The new process should not be pinned to a other processor if(yieldProc->isPinned()&&(yieldProc->getCPU()!=cpu)) { LOG("OSSim::yield(%d) to a NOMIGRABLE process in another CPU", yieldPid); return 0; } // Remove current process from the processor cpus.switchOut(cpu,curProc); // Put the new process on that processor cpus.switchIn(cpu,yieldProc); return 1; }
void OSSim::setPriority(Pid_t pid, int32_t newPrio) { ProcessId *proc = ProcessId::getProcessId(pid); I(proc); int32_t oldPrio=proc->getPriority(); if(newPrio==oldPrio) return; // Set the new priority of the process ProcessId *otherProc=proc->setPriority(newPrio); if(newPrio>oldPrio) { // Priority is better now, check if still running if(proc->getState()==RunningState) { // Is there a process we need to swap with if(otherProc) { // Get the cpu where the demoted process is running CPU_t cpu=proc->getCPU(); // Switch the demoted process out cpus.switchOut(cpu,proc); // Switch the new process in cpus.switchIn(cpu,otherProc); } } } else { // Priority is worse now, check if ready but not already running if(proc->getState()==ReadyState) { // Is there a process we need to swap with if(otherProc) { // Get the cpu where the other process is running CPU_t cpu=otherProc->getCPU(); // Switch the victim process out cpus.switchOut(cpu,otherProc); // Switch the promoted process in cpus.switchIn(cpu,proc); } } } }