diff options
Diffstat (limited to 'libhw/host_alarmclock.c')
-rw-r--r-- | libhw/host_alarmclock.c | 133 |
1 files changed, 0 insertions, 133 deletions
diff --git a/libhw/host_alarmclock.c b/libhw/host_alarmclock.c deleted file mode 100644 index 19ece7c..0000000 --- a/libhw/host_alarmclock.c +++ /dev/null @@ -1,133 +0,0 @@ -/* libhw/host_alarmclock.c - <libhw/generic/alarmclock.h> implementation for POSIX hosts - * - * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com> - * SPDX-License-Identifier: AGPL-3.0-or-later - */ - -#include <errno.h> -#include <error.h> -#include <signal.h> - -#include <libcr/coroutine.h> -#include <libmisc/assert.h> - -#define IMPLEMENTATION_FOR_LIBHW_GENERIC_ALARMCLOCK_H YES -#include <libhw/generic/alarmclock.h> - -#define IMPLEMENTATION_FOR_LIBHW_HOST_ALARMCLOCK_H YES -#include <libhw/host_alarmclock.h> - -#include "host_util.h" /* for host_sigrt_alloc(), ns_to_host_ns_time() */ - -LO_IMPLEMENTATION_C(alarmclock, struct hostclock, hostclock, static) - -static uint64_t hostclock_get_time_ns(struct hostclock *alarmclock) { - assert(alarmclock); - - struct timespec ts; - - if (clock_gettime(alarmclock->clock_id, &ts) != 0) - error(1, errno, "clock_gettime(%d)", (int)alarmclock->clock_id); - - return ns_from_host_ns_time(ts); -} - -static void hostclock_handle_sig_alarm(int LM_UNUSED(sig), siginfo_t *info, void *LM_UNUSED(ucontext)) { - struct hostclock *alarmclock = info->si_value.sival_ptr; - assert(alarmclock); - - while (alarmclock->queue && - alarmclock->queue->fire_at_ns <= hostclock_get_time_ns(alarmclock)) { - struct alarmclock_trigger *trigger = alarmclock->queue; - trigger->cb(trigger->cb_arg); - alarmclock->queue = trigger->next; - trigger->alarmclock = NULL; - trigger->next = NULL; - trigger->prev = NULL; - } - - if (alarmclock->queue) { - struct itimerspec alarmspec = { - .it_value = ns_to_host_ns_time(alarmclock->queue->fire_at_ns), - .it_interval = {0}, - }; - if (timer_settime(alarmclock->timer_id, TIMER_ABSTIME, &alarmspec, NULL) != 0) - error(1, errno, "timer_settime"); - } -} - -static bool hostclock_add_trigger(struct hostclock *alarmclock, - struct alarmclock_trigger *trigger, - uint64_t fire_at_ns, - void (*cb)(void *), - void *cb_arg) { - assert(alarmclock); - assert(trigger); - assert(fire_at_ns); - assert(cb); - - trigger->alarmclock = alarmclock; - trigger->fire_at_ns = fire_at_ns; - trigger->cb = cb; - trigger->cb_arg = cb_arg; - - bool saved = cr_save_and_disable_interrupts(); - struct alarmclock_trigger **dst = &alarmclock->queue; - while (*dst && fire_at_ns >= (*dst)->fire_at_ns) - dst = &(*dst)->next; - trigger->next = *dst; - trigger->prev = *dst ? (*dst)->prev : NULL; - if (*dst) - (*dst)->prev = trigger; - *dst = trigger; - if (!alarmclock->initialized) { - struct sigevent how_to_notify = { - .sigev_notify = SIGEV_SIGNAL, - .sigev_signo = host_sigrt_alloc(), - .sigev_value = { - .sival_ptr = alarmclock, - }, - }; - struct sigaction action = { - .sa_flags = SA_SIGINFO, - .sa_sigaction = hostclock_handle_sig_alarm, - }; - if (sigaction(how_to_notify.sigev_signo, &action, NULL) != 0) - error(1, errno, "sigaction"); - if (timer_create(alarmclock->clock_id, &how_to_notify, &alarmclock->timer_id) != 0) - error(1, errno, "timer_create(%d)", (int)alarmclock->clock_id); - alarmclock->initialized = true; - } - if (alarmclock->queue == trigger) { - struct itimerspec alarmspec = { - .it_value = ns_to_host_ns_time(trigger->fire_at_ns), - .it_interval = {0}, - }; - if (timer_settime(alarmclock->timer_id, TIMER_ABSTIME, &alarmspec, NULL) != 0) - error(1, errno, "timer_settime"); - } - cr_restore_interrupts(saved); - - return false; -} - -static void hostclock_del_trigger(struct hostclock *alarmclock, - struct alarmclock_trigger *trigger) { - assert(alarmclock); - assert(trigger); - - bool saved = cr_save_and_disable_interrupts(); - if (trigger->alarmclock == alarmclock) { - if (!trigger->prev) - alarmclock->queue = trigger->next; - else - trigger->prev->next = trigger->next; - if (trigger->next) - trigger->next->prev = trigger->prev; - trigger->alarmclock = NULL; - trigger->prev = NULL; - trigger->next = NULL; - } else - assert(!trigger->alarmclock); - cr_restore_interrupts(saved); -} |