/** * Set a repeated alarm to execute a callback every interval from start. */ BOOL OSSetPeriodicAlarm(OSAlarm *alarm, OSTime start, OSTime interval, AlarmCallback callback) { ScopedSpinLock lock(gAlarmLock); // Set alarm alarm->nextFire = start; alarm->callback = callback; alarm->period = interval; alarm->context = nullptr; alarm->state = OSAlarmState::Set; // Erase from old alarm queue if (alarm->alarmQueue) { OSEraseFromQueue(static_cast<OSAlarmQueue*>(alarm->alarmQueue), alarm); alarm->alarmQueue = nullptr; } // Add to this core's alarm queue auto core = OSGetCoreId(); auto queue = gAlarmQueue[core]; alarm->alarmQueue = queue; OSAppendQueue(queue, alarm); // Set the interrupt timer in processor gProcessor.setInterruptTimer(core, coreinit::internal::toTimepoint(alarm->nextFire)); return TRUE; }
static BOOL OSCancelAlarmNoLock(OSAlarm *alarm) { if (!alarm->state == OSAlarmState::Set) { return FALSE; } alarm->state = OSAlarmState::Cancelled; alarm->nextFire = 0; alarm->period = 0; OSEraseFromQueue(static_cast<OSAlarmQueue*>(alarm->alarmQueue), alarm); return TRUE; }
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(); } }
static bool OSTriggerAlarmNoLock(OSAlarm *alarm, OSContext *context) { alarm->context = context; if (alarm->callback && alarm->state != OSAlarmState::Cancelled) { alarm->callback(alarm, context); } OSWakeupThread(&alarm->threadQueue); if (alarm->period) { alarm->nextFire = OSGetTime() + alarm->period; alarm->state = OSAlarmState::Set; } else { alarm->nextFire = 0; alarm->state = OSAlarmState::None; OSEraseFromQueue(static_cast<OSAlarmQueue*>(alarm->alarmQueue), alarm); } return alarm->nextFire == 0; }
void OSEraseFromThreadQueue(OSThreadQueue *queue, OSThread *thread) { OSEraseFromQueue(queue, thread); }