Files
sxmo-utils/programs/sxmo_aligned_sleep.c
ArenM fba369252f avoid drift in clocks
This adds a sleep program that wakes up when the time (in seconds) is
divisible by a specific number, so for example passing 60 to it will
make it exit at the beginning of each minute.

This program is also able to exit when the system exits suspend (when
the kernel syncs the clock), which means we don't need to signal the
clocks anymore.

Signed-off-by: Stacy Harper <contact@stacyharper.net>
2022-07-01 12:06:27 +02:00

49 lines
1.4 KiB
C

#include <errno.h> // error handling
#include <stdint.h> // uint64_t type
#include <stdio.h> // dprintf
#include <stdlib.h> // strtol, exit
#include <string.h> // strerror, strcmp
#include <sys/timerfd.h> // timers
#include <unistd.h> // read
static void error(char *message, int err) {
dprintf(2, "%s: %s\n", message, strerror(err));
exit(1);
}
int main(int argc, char **argv) {
uint64_t buf;
long duration = -1;
int time_fd;
struct timespec now;
struct itimerspec time = {
.it_value = { .tv_sec = 0, .tv_nsec = 0 },
.it_interval = { .tv_sec = 0, .tv_nsec = 0 }
};
// Process arguments
if (argc >= 2) duration = strtol(argv[1], NULL, 0);
if (duration <= 0) {
dprintf(2, "Usage: %s <seconds>\n", argv[0]);
dprintf(2, "ERROR: duration must be a positive integer\n");
return 1;
}
// Setup timer
if ((time_fd = timerfd_create(CLOCK_REALTIME, 0)) == -1)
error("Failed to create timerfd", errno);
if (clock_gettime(CLOCK_REALTIME, &now) == -1)
error("Failed to get current time", errno);
// find the next time that's divisable by the provided number of seconds
time.it_value.tv_sec = now.tv_sec + duration - (now.tv_sec % duration);
if (timerfd_settime(time_fd, TFD_TIMER_ABSTIME | TFD_TIMER_CANCEL_ON_SET, &time, NULL) == -1)
error("Failed to set timer",errno);
// Wait for timer
read(time_fd, &buf, sizeof(uint64_t));
}