void rescheduleAllCoreNoLock() { // Reschedule other cores first, or we might exit early! rescheduleOtherCoreNoLock(); rescheduleSelfNoLock(); }
void handleAlarmInterrupt(OSContext *context) { auto core_id = cpu::this_core::id(); auto queue = sAlarmQueue[core_id]; auto cbQueue = sAlarmCallbackQueue[core_id]; auto cbThreadQueue = sAlarmCallbackThreadQueue[core_id]; auto now = OSGetTime(); auto next = std::chrono::time_point<std::chrono::system_clock>::max(); bool callbacksNeeded = false; internal::lockScheduler(); acquireIdLock(sAlarmLock); for (OSAlarm *alarm = queue->head; alarm; ) { auto nextAlarm = alarm->link.next; // Expire it if its past its nextFire time if (alarm->nextFire <= now) { decaf_check(alarm->state == OSAlarmState::Set); internal::AlarmQueue::erase(queue, alarm); alarm->alarmQueue = nullptr; alarm->state = OSAlarmState::Expired; alarm->context = context; if (alarm->threadQueue.head) { wakeupThreadNoLock(&alarm->threadQueue); rescheduleOtherCoreNoLock(); } if (alarm->group == 0xFFFFFFFF) { // System-internal alarm if (alarm->callback) { auto originalMask = cpu::this_core::setInterruptMask(0); alarm->callback(alarm, context); cpu::this_core::setInterruptMask(originalMask); } } else { internal::AlarmQueue::append(cbQueue, alarm); alarm->alarmQueue = cbQueue; wakeupThreadNoLock(cbThreadQueue); } } alarm = nextAlarm; } internal::updateCpuAlarmNoALock(); releaseIdLock(sAlarmLock); internal::unlockScheduler(); }