📄 osutils.cxx
字号:
Yield();}BOOL PThread::WaitForTermination(const PTimeInterval & maxWait) const{ PTimer timeout = maxWait; while (!IsTerminated()) { if (timeout == 0) return FALSE; Yield(); } return TRUE;}void PThread::Suspend(BOOL susp){ // Suspend/Resume the thread if (susp) suspendCount++; else suspendCount--; switch (status) { case Running : // Suspending itself, yield to next thread if (IsSuspended()) { status = Suspended; Yield(); } break; case Waiting : if (IsSuspended()) status = Suspended; break; case BlockedIO : if (IsSuspended()) status = SuspendedBlockIO; break; case BlockedSem : if (IsSuspended()) status = SuspendedBlockSem; break; case Suspended : if (!IsSuspended()) status = Waiting; break; case SuspendedBlockIO : if (!IsSuspended()) status = BlockedIO; break; case SuspendedBlockSem : if (!IsSuspended()) status = BlockedSem; break; default : break; }}void PThread::Sleep(const PTimeInterval & time){ sleepTimer = time; if (time == PMaxTimeInterval) sleepTimer.Pause(); switch (status) { case Running : // Suspending itself, yield to next thread status = Sleeping; Yield(); break; case Waiting : case Suspended : status = Sleeping; break; default : break; }}void PThread::BeginThread(){ if (IsSuspended()) { // Begins suspended status = Suspended; Yield(); } else status = Running; Main(); status = Terminating; Yield(); // Never returns from here}void PThread::Yield(){ PThread * current = PProcessInstance->currentThread; if (current == PProcessInstance) { PProcessInstance->GetTimerList()->Process(); if (current->link == current) return; } else { char stackUsed; if (&stackUsed < current->stackBase) { char * buf = (char *)malloc(1000); sprintf(buf, "Stack overflow!\n" "\n" "Thread: 0x%08x - %s\n" "Stack top : 0x%08x\n" "Stack base : 0x%08x\n" "Stack frame: 0x%08x\n" "\n", (int)current, current->GetClass(), (int)current->stackTop, (int)current->stackBase, (int)&stackUsed); PAssertAlways(buf); PError << "Aborting." << endl; _exit(1); } } if (current->status == Running && current->basePriority == HighestPriority) return; do { if (current->status == Running) current->status = Waiting; static const int dynamicLevel[NumPriorities] = { -1, 3, 1, 0, 0 }; current->dynamicPriority = dynamicLevel[current->basePriority]; PThread * next = NULL; // Next thread to be scheduled PThread * prev = current; // Need the thread in the previous link PThread * start = current; // Need thread in list that is the "start" PThread * thread = current->link; BOOL pass = 0; BOOL canUseLowest = TRUE; for (;;) { if (PProcessTerminating) { next = PProcessInstance; next->status = Running; break; } switch (thread->status) { case Waiting : if (thread->dynamicPriority == 0) { next = thread; next->status = Running; } else if (thread->dynamicPriority > 0) { thread->dynamicPriority--; canUseLowest = FALSE; } else if (pass > 1 && canUseLowest) thread->dynamicPriority++; break; case Sleeping : if (thread->sleepTimer == 0) { if (thread->IsSuspended()) thread->status = Suspended; else { thread->status = Running; next = thread; } } break; case BlockedIO : if (thread->IsNoLongerBlocked()) { if (PProcessTerminating) next = PProcessInstance; else { thread->ClearBlock(); next = thread; } next->status = Running; } break; case BlockedSem : case SuspendedBlockSem : if (thread->blockingSemaphore->timeout == 0) { thread->blockingSemaphore->PSemaphore::Signal(); thread->blockingSemaphore->timeout = 0; if (thread->status == Waiting) { next = thread; next->status = Running; } } break; case Starting : if (!thread->IsSuspended()) next = thread; break; case Terminating : if (thread == current) // Cannot self terminate next = PProcessInstance; // So switch to process thread first else { prev->link = thread->link; // Unlink it from the list if (thread == start) // If unlinking the "start" thread start = prev; // then we better make it still in list thread->status = Terminated; // Flag thread as terminated if (thread->autoDelete) delete thread; // Destroy if auto-delete thread = prev; } break; default : break; } if (next != NULL) // Have a thread to run break; // Need to have previous thread so can unlink a terminating thread prev = thread; thread = thread->link; if (thread == start) { pass++; if (pass > 3) // Everything is blocked PProcessInstance->OperatingSystemYield(); } } PProcessInstance->currentThread = next; next->SwitchContext(current); // Could get here with a self terminating thread, so go around again if all // we did was switch stacks, and do not actually have a running thread. } while (PProcessInstance->currentThread->status != Running); if (PProcessTerminating) { PProcessTerminating = FALSE; if (PProcessInstance->IsDescendant(PServiceProcess::Class())) ((PServiceProcess *)PProcessInstance)->OnStop(); exit(PProcessInstance->terminationValue); }}#endif///////////////////////////////////////////////////////////////////////////////// PSemaphore#ifndef P_PLATFORM_HAS_THREADSPSemaphore::PSemaphore(unsigned initial, unsigned maxCount){ PAssert(maxCount > 0, "Invalid semaphore maximum."); if (initial > maxCount) initial = maxCount; currentCount = initial; maximumCount = maxCount;}PSemaphore::~PSemaphore(){ PAssert(blockedThreads.IsEmpty(), "Semaphore destroyed while still has blocked threads");}void PSemaphore::Wait(){ Wait(PMaxTimeInterval);}BOOL PSemaphore::Wait(const PTimeInterval & time){ if (currentCount > 0) currentCount--; else { PThread * thread = PThread::Current(); blockedThreads.Enqueue(thread); thread->blockingSemaphore = this; thread->status = PThread::BlockedSem; timeout = time; if (time == PMaxTimeInterval) timeout.Pause(); PThread::Yield(); if (timeout == 0) return FALSE; } return TRUE;}void PSemaphore::Signal(){ if (blockedThreads.GetSize() > 0) { PThread * thread = blockedThreads.Dequeue(); switch (thread->status) { case PThread::BlockedSem : thread->status = PThread::Waiting; break; case PThread::SuspendedBlockSem : thread->status = PThread::Suspended; break; default: PAssertAlways("Semaphore unblock of thread that is not blocked"); } thread->sleepTimer = 0; timeout = PMaxTimeInterval; timeout.Pause(); } else if (currentCount < maximumCount) currentCount++;}BOOL PSemaphore::WillBlock() const{ return currentCount == 0;}PMutex::PMutex() : PSemaphore(1, 1){}PSyncPoint::PSyncPoint() : PSemaphore(0, 1){}#endifvoid PSyncPointAck::Signal(){ PSyncPoint::Signal(); ack.Wait();}void PSyncPointAck::Signal(const PTimeInterval & wait){ PSyncPoint::Signal(); ack.Wait(wait);}void PSyncPointAck::Acknowledge(){ ack.Signal();}void PCondMutex::WaitCondition(){ for (;;) { Wait(); if (Condition()) return; PMutex::Signal(); OnWait(); syncPoint.Wait(); }}void PCondMutex::Signal(){ if (Condition()) syncPoint.Signal(); PMutex::Signal();}void PCondMutex::OnWait(){ // Do nothing}PIntCondMutex::PIntCondMutex(int val, int targ, Operation op){ value = val; target = targ; operation = op;}void PIntCondMutex::PrintOn(ostream & strm) const{ strm << '(' << value; switch (operation) { case LT : strm << " < "; case LE : strm << " <= "; case GE : strm << " >= "; case GT : strm << " > "; default: strm << " == "; } strm << target << ')';}BOOL PIntCondMutex::Condition(){ switch (operation) { case LT : return value < target; case LE : return value <= target; case GE : return value >= target; case GT : return value > target; default : break; } return value == target;}PIntCondMutex & PIntCondMutex::operator=(int newval){ Wait(); value = newval; Signal(); return *this;}PIntCondMutex & PIntCondMutex::operator++(){ Wait(); value++; Signal(); return *this;}PIntCondMutex & PIntCondMutex::operator+=(int inc){ Wait(); value += inc; Signal(); return *this;}PIntCondMutex & PIntCondMutex::operator--(){ Wait(); value--; Signal(); return *this;}PIntCondMutex & PIntCondMutex::operator-=(int dec){ Wait(); value -= dec; Signal(); return *this;}void PReadWriteMutex::StartRead(){ starvationPreventer.Wait(); starvationPreventer.Signal(); ++readers;}void PReadWriteMutex::EndRead(){ --readers;}void PReadWriteMutex::StartWrite(){ starvationPreventer.Wait(); readers.WaitCondition();}void PReadWriteMutex::EndWrite(){ starvationPreventer.Signal(); readers.Signal();}// End Of File ///////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -