void
rescheduleAllCoreNoLock()
{
   // Reschedule other cores first, or we might exit early!
   rescheduleOtherCoreNoLock();
   rescheduleSelfNoLock();
}
Example #2
0
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();
}