typedef enum EventSourceType {
SOURCE_IO,
SOURCE_TIME_REALTIME,
+ SOURCE_TIME_BOOTTIME,
SOURCE_TIME_MONOTONIC,
SOURCE_TIME_REALTIME_ALARM,
SOURCE_TIME_BOOTTIME_ALARM,
_SOURCE_EVENT_SOURCE_TYPE_INVALID = -1
} EventSourceType;
-#define EVENT_SOURCE_IS_TIME(t) IN_SET((t), SOURCE_TIME_REALTIME, SOURCE_TIME_MONOTONIC, SOURCE_TIME_REALTIME_ALARM, SOURCE_TIME_BOOTTIME_ALARM)
+#define EVENT_SOURCE_IS_TIME(t) IN_SET((t), SOURCE_TIME_REALTIME, SOURCE_TIME_BOOTTIME, SOURCE_TIME_MONOTONIC, SOURCE_TIME_REALTIME_ALARM, SOURCE_TIME_BOOTTIME_ALARM)
struct sd_event_source {
unsigned n_ref;
Prioq *pending;
Prioq *prepare;
- /* timerfd_create() only supports these four clocks so far. We
+ /* timerfd_create() only supports these five clocks so far. We
* can add support for more clocks when the kernel learns to
* deal with them, too. */
struct clock_data realtime;
+ struct clock_data boottime;
struct clock_data monotonic;
struct clock_data realtime_alarm;
struct clock_data boottime_alarm;
safe_close(e->watchdog_fd);
free_clock_data(&e->realtime);
+ free_clock_data(&e->boottime);
free_clock_data(&e->monotonic);
free_clock_data(&e->realtime_alarm);
free_clock_data(&e->boottime_alarm);
return -ENOMEM;
e->n_ref = 1;
- e->signal_fd = e->watchdog_fd = e->epoll_fd = e->realtime.fd = e->monotonic.fd = e->realtime_alarm.fd = e->boottime_alarm.fd = -1;
- e->realtime.next = e->monotonic.next = e->realtime_alarm.next = e->boottime_alarm.next = (usec_t) -1;
+ e->signal_fd = e->watchdog_fd = e->epoll_fd = e->realtime.fd = e->boottime.fd = e->monotonic.fd = e->realtime_alarm.fd = e->boottime_alarm.fd = -1;
+ e->realtime.next = e->boottime.next = e->monotonic.next = e->realtime_alarm.next = e->boottime_alarm.next = (usec_t) -1;
e->original_pid = getpid();
e->perturb = (usec_t) -1;
case SOURCE_TIME_REALTIME:
return CLOCK_REALTIME;
+ case SOURCE_TIME_BOOTTIME:
+ return CLOCK_BOOTTIME;
+
case SOURCE_TIME_MONOTONIC:
return CLOCK_MONOTONIC;
case CLOCK_REALTIME:
return SOURCE_TIME_REALTIME;
+ case CLOCK_BOOTTIME:
+ return SOURCE_TIME_BOOTTIME;
+
case CLOCK_MONOTONIC:
return SOURCE_TIME_MONOTONIC;
case SOURCE_TIME_REALTIME:
return &e->realtime;
+ case SOURCE_TIME_BOOTTIME:
+ return &e->boottime;
+
case SOURCE_TIME_MONOTONIC:
return &e->monotonic;
break;
case SOURCE_TIME_REALTIME:
+ case SOURCE_TIME_BOOTTIME:
case SOURCE_TIME_MONOTONIC:
case SOURCE_TIME_REALTIME_ALARM:
case SOURCE_TIME_BOOTTIME_ALARM: {
break;
case SOURCE_TIME_REALTIME:
+ case SOURCE_TIME_BOOTTIME:
case SOURCE_TIME_MONOTONIC:
case SOURCE_TIME_REALTIME_ALARM:
case SOURCE_TIME_BOOTTIME_ALARM: {
break;
case SOURCE_TIME_REALTIME:
+ case SOURCE_TIME_BOOTTIME:
case SOURCE_TIME_MONOTONIC:
case SOURCE_TIME_REALTIME_ALARM:
case SOURCE_TIME_BOOTTIME_ALARM: {
break;
case SOURCE_TIME_REALTIME:
+ case SOURCE_TIME_BOOTTIME:
case SOURCE_TIME_MONOTONIC:
case SOURCE_TIME_REALTIME_ALARM:
case SOURCE_TIME_BOOTTIME_ALARM:
if (r < 0)
goto finish;
+ r = event_arm_timer(e, &e->boottime);
+ if (r < 0)
+ goto finish;
+
r = event_arm_timer(e, &e->monotonic);
if (r < 0)
goto finish;
if (ev_queue[i].data.ptr == INT_TO_PTR(SOURCE_TIME_REALTIME))
r = flush_timer(e, e->realtime.fd, ev_queue[i].events, &e->realtime.next);
+ else if (ev_queue[i].data.ptr == INT_TO_PTR(SOURCE_TIME_BOOTTIME))
+ r = flush_timer(e, e->boottime.fd, ev_queue[i].events, &e->boottime.next);
else if (ev_queue[i].data.ptr == INT_TO_PTR(SOURCE_TIME_MONOTONIC))
r = flush_timer(e, e->monotonic.fd, ev_queue[i].events, &e->monotonic.next);
else if (ev_queue[i].data.ptr == INT_TO_PTR(SOURCE_TIME_REALTIME_ALARM))
if (r < 0)
goto finish;
+ r = process_timer(e, e->timestamp_boottime, &e->boottime);
+ if (r < 0)
+ goto finish;
+
r = process_timer(e, e->timestamp.monotonic, &e->monotonic);
if (r < 0)
goto finish;
*usec = e->timestamp.monotonic;
break;
+ case CLOCK_BOOTTIME:
case CLOCK_BOOTTIME_ALARM:
*usec = e->timestamp_boottime;
break;