* 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
This commit is contained in:
Axel Dörfler 2006-08-20 22:44:53 +00:00
parent 505347b0b2
commit 26a9fcd6ab
3 changed files with 24 additions and 13 deletions

View File

@ -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;
}

View File

@ -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));

View File

@ -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 <OS.h>
@ -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;
}