Changeset View
Changeset View
Standalone View
Standalone View
sys/compat/linux/linux_event.c
Show First 20 Lines • Show All 1,171 Lines • ▼ Show 20 Lines | |||||
static void | static void | ||||
linux_timerfd_curval(struct timerfd *tfd, struct itimerspec *ots) | linux_timerfd_curval(struct timerfd *tfd, struct itimerspec *ots) | ||||
{ | { | ||||
struct timespec cts; | struct timespec cts; | ||||
linux_timerfd_clocktime(tfd, &cts); | linux_timerfd_clocktime(tfd, &cts); | ||||
*ots = tfd->tfd_time; | *ots = tfd->tfd_time; | ||||
if (ots->it_value.tv_sec != 0 || ots->it_value.tv_nsec != 0) { | if (ots->it_value.tv_sec != 0 || ots->it_value.tv_nsec != 0) { | ||||
timespecsub(&ots->it_value, &cts); | timespecsub(&ots->it_value, &cts, &ots->it_value); | ||||
if (ots->it_value.tv_sec < 0 || | if (ots->it_value.tv_sec < 0 || | ||||
(ots->it_value.tv_sec == 0 && | (ots->it_value.tv_sec == 0 && | ||||
ots->it_value.tv_nsec == 0)) { | ots->it_value.tv_nsec == 0)) { | ||||
ots->it_value.tv_sec = 0; | ots->it_value.tv_sec = 0; | ||||
ots->it_value.tv_nsec = 1; | ots->it_value.tv_nsec = 1; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
▲ Show 20 Lines • Show All 67 Lines • ▼ Show 20 Lines | linux_timerfd_settime(struct thread *td, struct linux_timerfd_settime_args *args) | ||||
if (args->old_value != NULL) | if (args->old_value != NULL) | ||||
linux_timerfd_curval(tfd, &ots); | linux_timerfd_curval(tfd, &ots); | ||||
tfd->tfd_time = nts; | tfd->tfd_time = nts; | ||||
if (timespecisset(&nts.it_value)) { | if (timespecisset(&nts.it_value)) { | ||||
linux_timerfd_clocktime(tfd, &cts); | linux_timerfd_clocktime(tfd, &cts); | ||||
ts = nts.it_value; | ts = nts.it_value; | ||||
if ((args->flags & LINUX_TFD_TIMER_ABSTIME) == 0) { | if ((args->flags & LINUX_TFD_TIMER_ABSTIME) == 0) { | ||||
timespecadd(&tfd->tfd_time.it_value, &cts); | timespecadd(&tfd->tfd_time.it_value, &cts, | ||||
&tfd->tfd_time.it_value); | |||||
} else { | } else { | ||||
timespecsub(&ts, &cts); | timespecsub(&ts, &cts, &ts); | ||||
} | } | ||||
TIMESPEC_TO_TIMEVAL(&tv, &ts); | TIMESPEC_TO_TIMEVAL(&tv, &ts); | ||||
callout_reset(&tfd->tfd_callout, tvtohz(&tv), | callout_reset(&tfd->tfd_callout, tvtohz(&tv), | ||||
linux_timerfd_expire, tfd); | linux_timerfd_expire, tfd); | ||||
tfd->tfd_canceled = false; | tfd->tfd_canceled = false; | ||||
} else { | } else { | ||||
tfd->tfd_canceled = true; | tfd->tfd_canceled = true; | ||||
callout_stop(&tfd->tfd_callout); | callout_stop(&tfd->tfd_callout); | ||||
Show All 19 Lines | linux_timerfd_expire(void *arg) | ||||
struct timerfd *tfd; | struct timerfd *tfd; | ||||
tfd = (struct timerfd *)arg; | tfd = (struct timerfd *)arg; | ||||
linux_timerfd_clocktime(tfd, &cts); | linux_timerfd_clocktime(tfd, &cts); | ||||
if (timespeccmp(&cts, &tfd->tfd_time.it_value, >=)) { | if (timespeccmp(&cts, &tfd->tfd_time.it_value, >=)) { | ||||
if (timespecisset(&tfd->tfd_time.it_interval)) | if (timespecisset(&tfd->tfd_time.it_interval)) | ||||
timespecadd(&tfd->tfd_time.it_value, | timespecadd(&tfd->tfd_time.it_value, | ||||
&tfd->tfd_time.it_interval); | &tfd->tfd_time.it_interval, | ||||
&tfd->tfd_time.it_value); | |||||
else | else | ||||
/* single shot timer */ | /* single shot timer */ | ||||
timespecclear(&tfd->tfd_time.it_value); | timespecclear(&tfd->tfd_time.it_value); | ||||
if (timespecisset(&tfd->tfd_time.it_value)) { | if (timespecisset(&tfd->tfd_time.it_value)) { | ||||
ts = tfd->tfd_time.it_value; | timespecsub(&tfd->tfd_time.it_value, &cts, &ts); | ||||
timespecsub(&ts, &cts); | |||||
TIMESPEC_TO_TIMEVAL(&tv, &ts); | TIMESPEC_TO_TIMEVAL(&tv, &ts); | ||||
callout_reset(&tfd->tfd_callout, tvtohz(&tv), | callout_reset(&tfd->tfd_callout, tvtohz(&tv), | ||||
linux_timerfd_expire, tfd); | linux_timerfd_expire, tfd); | ||||
} | } | ||||
tfd->tfd_count++; | tfd->tfd_count++; | ||||
KNOTE_LOCKED(&tfd->tfd_sel.si_note, 0); | KNOTE_LOCKED(&tfd->tfd_sel.si_note, 0); | ||||
selwakeup(&tfd->tfd_sel); | selwakeup(&tfd->tfd_sel); | ||||
wakeup(&tfd->tfd_count); | wakeup(&tfd->tfd_count); | ||||
} else if (timespecisset(&tfd->tfd_time.it_value)) { | } else if (timespecisset(&tfd->tfd_time.it_value)) { | ||||
ts = tfd->tfd_time.it_value; | timespecsub(&tfd->tfd_time.it_value, &cts, &ts); | ||||
timespecsub(&ts, &cts); | |||||
TIMESPEC_TO_TIMEVAL(&tv, &ts); | TIMESPEC_TO_TIMEVAL(&tv, &ts); | ||||
callout_reset(&tfd->tfd_callout, tvtohz(&tv), | callout_reset(&tfd->tfd_callout, tvtohz(&tv), | ||||
linux_timerfd_expire, tfd); | linux_timerfd_expire, tfd); | ||||
} | } | ||||
} | } |