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{};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|