⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 osutils.cxx

📁 基于VXWORKS H323通信技术源代码
💻 CXX
📖 第 1 页 / 共 4 页
字号:
  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;
	#if defined(P_VXWORKS)
		exit(1);
	#else
      _exit(1);
	#endif
    }
  }

  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_THREADS

PSemaphore::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)
{
}


#endif

void 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 + -