コード例 #1
0
ファイル: coreinit_thread.cpp プロジェクト: cfwprpht/wiiu-emu
BOOL
OSSetThreadPriority(OSThread *thread, uint32_t priority)
{
   if (priority > 31) {
      return FALSE;
   }

   OSLockScheduler();
   thread->basePriority = priority;
   OSRescheduleNoLock();
   OSUnlockScheduler();
   return TRUE;
}
コード例 #2
0
ファイル: coreinit_thread.cpp プロジェクト: cfwprpht/wiiu-emu
int32_t
OSResumeThread(OSThread *thread)
{
   OSLockScheduler();
   auto old = OSResumeThreadNoLock(thread, 1);
   
   if (thread->suspendCounter == 0) {
      OSRescheduleNoLock();
   }

   OSUnlockScheduler();
   return old;
}
コード例 #3
0
ファイル: coreinit_thread.cpp プロジェクト: lioncash/wiiu-emu
BOOL
OSRunThread(OSThread *thread, ThreadEntryPoint entry, uint32_t argc, p32<void> argv)
{
   BOOL result = false;
   OSLockScheduler();

   if (OSIsThreadTerminated(thread)) {
      InitialiseThreadState(thread, entry, argc, argv);
      OSResumeThreadNoLock(thread, 1);
      OSRescheduleNoLock();
   }

   OSUnlockScheduler();
   return result;
}
コード例 #4
0
int32_t
OSSignalSemaphore(OSSemaphore *semaphore)
{
   int32_t previous;
   OSLockScheduler();
   assert(semaphore && semaphore->tag == OSSemaphore::Tag);

   // Increase semaphore
   previous =  semaphore->count++;

   // Wakeup any waiting threads
   OSWakeupThreadNoLock(&semaphore->queue);
   OSRescheduleNoLock();

   OSUnlockScheduler();
   return previous;
}
コード例 #5
0
int32_t
OSWaitSemaphore(OSSemaphore *semaphore)
{
   int32_t previous;
   OSLockScheduler();
   assert(semaphore && semaphore->tag == OSSemaphore::Tag);

   while (semaphore->count <= 0) {
      // Wait until we can decrease semaphore
      OSSleepThreadNoLock(&semaphore->queue);
      OSRescheduleNoLock();
   }

   previous = semaphore->count--;
   OSUnlockScheduler();
   return previous;
}
コード例 #6
0
ファイル: coreinit_event.cpp プロジェクト: Subv/decaf-emu
/**
 * Wait for an event value to be TRUE with a timeout
 *
 * Behaves the same than OSWaitEvent but with a timeout.
 *
 * Returns TRUE if the event was signalled, FALSE if wait timed out.
 */
BOOL
OSWaitEventWithTimeout(OSEvent *event, OSTime timeout)
{
   BOOL result = TRUE;
   OSLockScheduler();

   // Check if event is already set
   if (event->value) {
      if (event->mode == OSEventMode::AutoReset) {
         // Reset event
         event->value = FALSE;
      }

      OSUnlockScheduler();
      return TRUE;
   }

   // Setup some alarm data for callback
   auto data = OSAllocFromSystem<EventAlarmData>();
   data->event = event;
   data->thread = OSGetCurrentThread();
   data->timeout = FALSE;

   // Create an alarm to trigger timeout
   auto alarm = OSAllocFromSystem<OSAlarm>();
   OSCreateAlarm(alarm);
   OSSetAlarmUserData(alarm, data);
   OSSetAlarm(alarm, timeout, pEventAlarmHandler);

   // Wait for the event
   OSSleepThreadNoLock(&event->queue);
   OSRescheduleNoLock();

   if (data->timeout) {
      // Timed out, remove from wait queue
      OSEraseFromThreadQueue(&event->queue, data->thread);
      result = FALSE;
   }

   OSFreeToSystem(data);
   OSFreeToSystem(alarm);
   OSUnlockScheduler();
   return result;
}
コード例 #7
0
BOOL
OSWaitAlarm(OSAlarm *alarm)
{
   OSAcquireSpinLock(gAlarmLock);
   assert(alarm);
   assert(alarm->tag == OSAlarm::Tag);

   if (alarm->state != OSAlarmState::Set) {
      OSReleaseSpinLock(gAlarmLock);
      return FALSE;
   }

   OSLockScheduler();
   OSSleepThreadNoLock(&alarm->threadQueue);
   OSReleaseSpinLock(gAlarmLock);
   OSRescheduleNoLock();
   OSUnlockScheduler();
   return TRUE;
}
コード例 #8
0
ファイル: coreinit_mutex.cpp プロジェクト: Subv/decaf-emu
void
OSUnlockMutexNoLock(OSMutex *mutex)
{
   auto thread = OSGetCurrentThread();
   assert(mutex && mutex->tag == OSMutex::Tag);
   assert(mutex->owner == thread);
   assert(mutex->count > 0);
   mutex->count--;

   if (mutex->count == 0) {
      mutex->owner = nullptr;

      // Remove mutex from thread's mutex queue
      OSEraseFromQueue(&thread->mutexQueue, mutex);

      // Wakeup any threads trying to lock this mutex
      OSWakeupThreadNoLock(&mutex->queue);
      OSRescheduleNoLock();
   }
}
コード例 #9
0
ファイル: coreinit_thread.cpp プロジェクト: lioncash/wiiu-emu
BOOL
OSJoinThread(OSThread *thread, be_val<int> *val)
{
   OSLockScheduler();

   if (thread->attr & OSThreadAttributes::Detached) {
      OSUnlockScheduler();
      return FALSE;
   }

   if (thread->state != OSThreadState::Moribund) {
      OSSleepThreadNoLock(&thread->joinQueue);
      OSRescheduleNoLock();
   }

   if (val) {
      *val = thread->exitValue;
   }

   OSUnlockScheduler();
   return TRUE;
}
コード例 #10
0
ファイル: coreinit_mutex.cpp プロジェクト: Subv/decaf-emu
void
OSLockMutexNoLock(OSMutex *mutex)
{
   assert(mutex && mutex->tag == OSMutex::Tag);
   auto thread = OSGetCurrentThread();

   while (mutex->owner && mutex->owner != thread) {
      thread->mutex = mutex;

      // Wait for other owner to unlock
      OSSleepThreadNoLock(&mutex->queue);
      OSRescheduleNoLock();

      thread->mutex = nullptr;
   }

   if (mutex->owner != thread) {
      // Add to mutex queue
      OSAppendQueue(&thread->mutexQueue, mutex);
   }

   mutex->owner = thread;
   mutex->count++;
}
コード例 #11
0
ファイル: coreinit_mutex.cpp プロジェクト: Subv/decaf-emu
void
OSWaitCond(OSCondition *condition, OSMutex *mutex)
{
   auto thread = OSGetCurrentThread();
   OSLockScheduler();
   assert(mutex && mutex->tag == OSMutex::Tag);
   assert(condition && condition->tag == OSCondition::Tag);
   assert(mutex->owner == thread);

   // Force an unlock
   auto mutexCount = mutex->count;
   mutex->count = 1;
   OSUnlockMutexNoLock(mutex);

   // Sleep on the condition
   OSSleepThreadNoLock(&condition->queue);
   OSRescheduleNoLock();

   // Restore lock
   OSLockMutexNoLock(mutex);
   mutex->count = mutexCount;

   OSUnlockScheduler();
}
コード例 #12
0
ファイル: coreinit_thread.cpp プロジェクト: lioncash/wiiu-emu
void
OSSleepTicks(OSTime ticks)
{
   auto thread = OSGetCurrentThread();
   OSLockScheduler();

   // Create the alarm user data
   auto data = OSAllocFromSystem<SleepAlarmData>();
   data->thread = thread;

   // Create an alarm to trigger wakeup
   auto alarm = OSAllocFromSystem<OSAlarm>();
   OSCreateAlarm(alarm);
   OSSetAlarmUserData(alarm, data);
   OSSetAlarm(alarm, ticks, pSleepAlarmHandler);

   // Sleep thread
   OSSleepThreadNoLock(nullptr);
   OSRescheduleNoLock();

   OSFreeToSystem(data);
   OSFreeToSystem(alarm);
   OSUnlockScheduler();
}