8#ifndef POSIX_TIMER_STATE_H
9#define POSIX_TIMER_STATE_H
11#include "pedigree/kernel/time/Time.h"
13namespace PosixTimerState {
14constexpr Time::Timestamp MaximumTime = Time::Infinity - 1;
25static_assert(
sizeof(
Setting) == 32,
"Linux amd64 itimerspec ABI");
28 Time::Timestamp deadline = 0;
29 Time::Timestamp interval = 0;
31 bool realtime =
false;
34inline bool decode(
const Timespec& source, Time::Timestamp& result) {
35 if (source.seconds < 0 || source.nanoseconds < 0 ||
36 source.nanoseconds >=
static_cast<int64_t
>(Time::Multiplier::Second))
38 const uint64_t seconds = source.seconds;
39 result = seconds > (MaximumTime - source.nanoseconds) / Time::Multiplier::Second
41 : seconds * Time::Multiplier::Second + source.nanoseconds;
45inline Timespec encode(Time::Timestamp value) {
46 return {
static_cast<int64_t
>(value / Time::Multiplier::Second),
47 static_cast<int64_t
>(value % Time::Multiplier::Second)};
50inline Time::Timestamp add(Time::Timestamp start, Time::Timestamp duration) {
51 return start >= MaximumTime || duration > MaximumTime - start ? MaximumTime : start + duration;
56inline uint64_t advance(State& state, Time::Timestamp now) {
57 if (!state.armed || now < state.deadline)
59 if (!state.interval) {
63 const uint64_t elapsed = now - state.deadline;
64 const uint64_t expirations = elapsed / state.interval + 1;
65 const uint64_t remaining = state.interval - elapsed % state.interval;
66 state.deadline = add(now, remaining);
67 state.armed = state.deadline > now;
71inline Setting snapshot(
const State& state, Time::Timestamp now) {
72 return {encode(state.interval),
73 encode(state.armed && state.deadline > now ? state.deadline - now : 0)};