Atmosphere/mesosphere/source/interrupts/KAlarm.cpp

58 lines
1.4 KiB
C++
Raw Normal View History

2018-10-31 20:47:31 +00:00
#include <mesosphere/interrupts/KAlarm.hpp>
#include <mesosphere/threading/KScheduler.hpp>
#include <mesosphere/arch/KInterruptMaskGuard.hpp>
namespace mesosphere
{
void KAlarm::AddAlarmable(IAlarmable &alarmable)
{
2018-11-05 13:12:38 +00:00
std::scoped_lock guard{spinlock};
2018-10-31 20:47:31 +00:00
alarmables.insert(alarmable);
KSystemClock::SetAlarm(alarmables.cbegin()->GetAlarmTime());
}
void KAlarm::RemoveAlarmable(const IAlarmable &alarmable)
{
2018-11-05 13:12:38 +00:00
std::scoped_lock guard{spinlock};
2018-10-31 20:47:31 +00:00
alarmables.erase(alarmable);
KSystemClock::SetAlarm(alarmables.cbegin()->GetAlarmTime());
}
void KAlarm::HandleAlarm()
{
{
KCriticalSection &critsec = KScheduler::GetCriticalSection();
2018-11-05 13:12:38 +00:00
std::scoped_lock criticalSection{critsec};
std::scoped_lock guard{spinlock};
2018-10-31 20:47:31 +00:00
KSystemClock::SetInterruptMasked(true); // mask timer interrupt
KSystemClock::time_point currentTime = KSystemClock::now(), maxAlarmTime;
while (alarmables.begin() != alarmables.end()) {
IAlarmable &a = *alarmables.begin();
maxAlarmTime = a.alarmTime;
if (maxAlarmTime > currentTime) {
break;
}
alarmables.erase(a);
a.alarmTime = KSystemClock::time_point{};
a.OnAlarm();
}
if (maxAlarmTime > KSystemClock::time_point{}) {
KSystemClock::SetAlarm(maxAlarmTime);
}
}
{
// TODO Reenable interrupt 30
KInterruptMaskGuard guard{};
}
}
}