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); } // 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, OSTimeToChrono(alarm->nextFire)); return TRUE; }
void OSCheckAlarms(uint32_t core, OSContext *context) { ScopedSpinLock lock(gAlarmLock); auto queue = gAlarmQueue[core]; auto now = OSGetTime(); auto next = std::chrono::time_point<std::chrono::system_clock>::max(); for (OSAlarm *alarm = queue->head; alarm; ) { auto nextAlarm = alarm->link.next; // Trigger alarm if it is time if (alarm->nextFire <= now) { OSTriggerAlarmNoLock(alarm, context); } // Set next timer if alarm is set if (alarm->state == OSAlarmState::Set && alarm->nextFire) { auto nextFire = OSTimeToChrono(alarm->nextFire); if (nextFire < next) { next = nextFire; } } alarm = nextAlarm; } gProcessor.setInterruptTimer(core, next); }
void OSTicksToCalendarTime(OSTime time, OSCalendarTime *calendarTime) { auto chrono = OSTimeToChrono(time); std::time_t system_time_t = std::chrono::system_clock::to_time_t(chrono); std::tm tm = platform::localtime(system_time_t); calendarTime->tm_sec = tm.tm_sec; calendarTime->tm_min = tm.tm_min; calendarTime->tm_hour = tm.tm_hour; calendarTime->tm_mday = tm.tm_mday; calendarTime->tm_mon = tm.tm_mon; calendarTime->tm_year = tm.tm_year + 1900; // posix tm_year is year - 1900 }