From 26a9fcd6ab564f29d834cb1a41e369870cf58a9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Sun, 20 Aug 2006 22:44:53 +0000 Subject: [PATCH] * set_alarm() now correctly returns the time left for the currently active alarm, or 0 if there isn't any. * setitimer() now also sets the previous timer values correctly, so that alarm() and ualarm() now return the correct values as well - this fixes the test fork_9-1 failing at alarm(). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@18545 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/system/kernel/signal.c | 16 +++++++++++++--- src/system/kernel/thread.c | 1 + src/system/libroot/posix/sys/itimer.c | 20 ++++++++++---------- 3 files changed, 24 insertions(+), 13 deletions(-) diff --git a/src/system/kernel/signal.c b/src/system/kernel/signal.c index 3532403f9d..fd5f9e2611 100644 --- a/src/system/kernel/signal.c +++ b/src/system/kernel/signal.c @@ -493,11 +493,17 @@ alarm_event(timer *t) } +/** Sets the alarm timer for the current thread. The timer fires at the + * specified time in the future, periodically or just once, as determined + * by \a mode. + * \return the time left until a previous set alarm would have fired. + */ + bigtime_t set_alarm(bigtime_t time, uint32 mode) { struct thread *thread = thread_get_current_thread(); - bigtime_t rv = 0; + bigtime_t remainingTime = 0; ASSERT(B_ONE_SHOT_RELATIVE_ALARM == B_ONE_SHOT_RELATIVE_TIMER); // just to be sure no one changes the headers some day @@ -505,14 +511,18 @@ set_alarm(bigtime_t time, uint32 mode) TRACE(("set_alarm: thread = %p\n", thread)); if (thread->alarm.period) - rv = (bigtime_t)thread->alarm.entry.key - system_time(); + remainingTime = (bigtime_t)thread->alarm.entry.key - system_time(); cancel_timer(&thread->alarm); if (time != B_INFINITE_TIMEOUT) add_timer(&thread->alarm, &alarm_event, time, mode); + else { + // this marks the alarm as canceled (for returning the remaining time) + thread->alarm.period = 0; + } - return rv; + return remainingTime; } diff --git a/src/system/kernel/thread.c b/src/system/kernel/thread.c index e49b247456..5048a52269 100644 --- a/src/system/kernel/thread.c +++ b/src/system/kernel/thread.c @@ -209,6 +209,7 @@ create_thread_struct(const char *name, thread_id threadID) thread->queue_next = NULL; thread->priority = thread->next_priority = -1; thread->args1 = NULL; thread->args2 = NULL; + thread->alarm.period = 0; thread->sig_pending = 0; thread->sig_block_mask = 0; memset(thread->sig_action, 0, 32 * sizeof(struct sigaction)); diff --git a/src/system/libroot/posix/sys/itimer.c b/src/system/libroot/posix/sys/itimer.c index bd72789f61..be4144e026 100644 --- a/src/system/libroot/posix/sys/itimer.c +++ b/src/system/libroot/posix/sys/itimer.c @@ -1,7 +1,7 @@ /* -** Copyright 2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved. -** Distributed under the terms of the Haiku License. -*/ + * Copyright 2004-2006, Axel Dörfler, axeld@pinc-software.de. All rights reserved. + * Distributed under the terms of the MIT License. + */ #include @@ -28,22 +28,22 @@ setitimer(int which, const struct itimerval *value, struct itimerval *oldValue) // We probably need a better internal set_alarm() implementation to do this bigtime_t interval = value->it_interval.tv_sec * USEC_PER_SECOND + value->it_interval.tv_usec; + bigtime_t remaining; if (interval != 0) - set_alarm(interval, B_PERIODIC_ALARM); + remaining = set_alarm(interval, B_PERIODIC_ALARM); else { bigtime_t timeout = value->it_value.tv_sec * USEC_PER_SECOND + value->it_value.tv_usec; if (timeout != 0) - set_alarm(timeout, B_ONE_SHOT_RELATIVE_ALARM); + remaining = set_alarm(timeout, B_ONE_SHOT_RELATIVE_ALARM); else { // cancel alarm - set_alarm(B_INFINITE_TIMEOUT, B_PERIODIC_ALARM); + remaining = set_alarm(B_INFINITE_TIMEOUT, B_PERIODIC_ALARM); } } - // whatever set_alarm() returns (not documented in the BeBook, and I haven't - // investigated this yet), maybe we can maintain the oldValue with it. - - memset(oldValue, 0, sizeof(struct itimerval)); + // Record the time left of any previous itimer + oldValue->it_value.tv_sec = remaining / USEC_PER_SECOND; + oldValue->it_value.tv_usec = remaining % USEC_PER_SECOND; return 0; }