int32_t OSSim::eventSuspend(Pid_t cpid, Pid_t pid) { LOG("OSSim::suspend(%d) Received from pid %d",pid,cpid); ProcessId *proc = ProcessId::getProcessId(pid); if( proc == 0 ) { LOG("OSSim::suspend(%d) non existing process???", pid); return 0; } // Increment the suspend counter proc->incSuspendedCounter(); // Check if process already suspended if(proc->getState()==SuspendedState) { I(0); LOG("OSSim::suspend(%d) already suspended (recursive=%d)" , pid, proc->getSuspendedCounter()); return 0; } // The process should be ready or running I((proc->getState()==ReadyState)||(proc->getState()==RunningState)); // Need to suspend only if suspended counter is positive if(proc->getSuspendedCounter()>0) { // The process is no longer runnable cpus.makeNonRunnable(proc); // Set the state to SuspendedState proc->setState(SuspendedState); } else { I(0); LOG("OSSim::suspend(%d,%d) OOO suspend/resume (%d)", cpid, pid, proc->getSuspendedCounter()); } return 1; }
void OSSim::stop(Pid_t pid) { // Get the procss descriptor ProcessId *proc = ProcessId::getProcessId(pid); // The descriptor should exist, and the process should be runnable I(proc&&((proc->getState()==ReadyState)||(proc->getState()==RunningState))); // Make the process non-runnable cpus.makeNonRunnable(proc); }
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::eventResume(Pid_t cpid, Pid_t pid) { LOG("OSSim::resume(%d,%d)", cpid, pid); ProcessId *proc = ProcessId::getProcessId(pid); if( proc == 0 ) { LOG("OSSim::resume(%d,%d) non existing process???", cpid, pid); return 0; } // Decrement the suspend counter proc->decSuspendedCounter(); // If process is in SuspendedState if(proc->getState()==SuspendedState) { // If the suspend count is not positive if(proc->getSuspendedCounter()<=0) { // Make the process runnable proc->setState(InvalidState); cpus.makeRunnable(proc); } return 1; } else { I(0); LOG("OSSim::resume(%d,%d) OOO suspend/resume (%d)", cpid, pid, proc->getSuspendedCounter()); } return 0; }
void OSSim::eventExit(Pid_t cpid, int32_t err) { LOG("OSSim::exit err[%d] (cpid %d)", err, cpid); ProcessId *proc = ProcessId::getProcessId(cpid); I(proc); // If not in InvalidState, removefrom the running queue if(proc->getState()==RunningState || proc->getState()==ReadyState ) cpus.makeNonRunnable(proc); // Try to wakeup parent tryWakeupParent(cpid); // Destroy the process proc->destroy(); #ifdef SESC_THERM ReportTherm::stopCB(); #endif }
void OSSim::unstop(Pid_t pid) { // Get the procss descriptor ProcessId *proc = ProcessId::getProcessId(pid); // The descriptor should exist, and the process should be in the InvalidState I(proc&&(proc->getState()==InvalidState)); // Make the process runnable cpus.makeRunnable(proc); }
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); } } } }
void OSSim::eventWait(Pid_t cpid) { // All the threads have already finished if(cpid<0) return; LOG("OSSim::wait (cpid %d)", cpid); ProcessId *proc = ProcessId::getProcessId(cpid); if(proc->getNChilds()==0) { // No child pending return; } // Should be still running I(proc->getState()==RunningState); // Make it non-runnable cpus.makeNonRunnable(proc); // Set state to WaitingState proc->setState(WaitingState); }
void OSSim::tryWakeupParent(Pid_t cpid) { ProcessId *proc = ProcessId::getProcessId(cpid); I(proc); Pid_t ppid = proc->getPPid(); if (ppid < 0) return; ProcessId *pproc = ProcessId::getProcessId(ppid); // Does the parent process still exist? if(pproc == 0) return; if(pproc->getState()==WaitingState) { LOG("Waiting pid(%d) is awaked (child %d call)",ppid,cpid); pproc->setState(InvalidState); cpus.makeRunnable(pproc); } }