Author: bonefish Date: 2011-05-30 23:42:16 +0200 (Mon, 30 May 2011) New Revision: 41841 Changeset: https://dev.haiku-os.org/changeset/41841 Added: haiku/branches/developer/bonefish/signals/src/system/libroot/posix/sys/itimer.cpp Removed: haiku/branches/developer/bonefish/signals/src/system/libroot/posix/sys/itimer.c Modified: haiku/branches/developer/bonefish/signals/headers/private/libroot/time_private.h haiku/branches/developer/bonefish/signals/src/system/libroot/posix/sys/Jamfile Log: * itimer.c -> itimer.cpp * Added helper functions timeval_to_timespec(), timespec_to_timeval() to time_private.h. * Reimplemented setitimer() using timer_settime() and the pre-defined timer USER_TIMER_REAL_TIME_ID. Still doesn't support ITIMER_VIRTUAL and ITIMER_PROF. * Implemented getitimer(). Modified: haiku/branches/developer/bonefish/signals/headers/private/libroot/time_private.h =================================================================== --- haiku/branches/developer/bonefish/signals/headers/private/libroot/time_private.h 2011-05-30 21:36:06 UTC (rev 41840) +++ haiku/branches/developer/bonefish/signals/headers/private/libroot/time_private.h 2011-05-30 21:42:16 UTC (rev 41841) @@ -49,4 +49,25 @@ } +static inline bool +timeval_to_timespec(const timeval& val, timespec& spec) +{ + if (val.tv_usec < 0 || val.tv_usec >= 1000000) + return false; + + spec.tv_sec = val.tv_sec; + spec.tv_nsec = val.tv_usec * 1000; + + return true; +} + + +static inline void +timespec_to_timeval(const timespec& spec, timeval& val) +{ + val.tv_sec = spec.tv_sec; + val.tv_usec = spec.tv_nsec / 1000; +} + + #endif // _LIBROOT_TIME_PRIVATE_H Modified: haiku/branches/developer/bonefish/signals/src/system/libroot/posix/sys/Jamfile =================================================================== --- haiku/branches/developer/bonefish/signals/src/system/libroot/posix/sys/Jamfile 2011-05-30 21:36:06 UTC (rev 41840) +++ haiku/branches/developer/bonefish/signals/src/system/libroot/posix/sys/Jamfile 2011-05-30 21:42:16 UTC (rev 41841) @@ -10,7 +10,7 @@ ftok.c getrusage.c gettimeofday.c - itimer.c + itimer.cpp mkdir.c mkfifo.c mman.cpp Copied: haiku/branches/developer/bonefish/signals/src/system/libroot/posix/sys/itimer.cpp (from rev 41670, haiku/branches/developer/bonefish/signals/src/system/libroot/posix/sys/itimer.c) =================================================================== --- haiku/branches/developer/bonefish/signals/src/system/libroot/posix/sys/itimer.cpp (rev 0) +++ haiku/branches/developer/bonefish/signals/src/system/libroot/posix/sys/itimer.cpp 2011-05-30 21:42:16 UTC (rev 41841) @@ -0,0 +1,93 @@ +/* + * Copyright 2011, Ingo Weinhold, ingo_weinhold@xxxxxxx + * Copyright 2004-2006, Axel Dörfler, axeld@xxxxxxxxxxxxxxxxx + * All rights reserved. + * Distributed under the terms of the MIT License. + */ + + +#include <sys/time.h> + +#include <errno.h> +#include <string.h> + +#include <OS.h> + +#include <syscall_utils.h> + +#include <user_timer_defs.h> + +#include <time_private.h> + + +static bool +itimerval_to_itimerspec(const itimerval& val, itimerspec& spec) +{ + return timeval_to_timespec(val.it_value, spec.it_value) + && timeval_to_timespec(val.it_interval, spec.it_interval); +} + + +static void +itimerspec_to_itimerval(const itimerspec& spec, itimerval& val) +{ + timespec_to_timeval(spec.it_value, val.it_value); + timespec_to_timeval(spec.it_interval, val.it_interval); +} + + +// #pragma mark - + + +int +getitimer(int which, struct itimerval* value) +{ + if (which != ITIMER_REAL) + RETURN_AND_SET_ERRNO(B_NOT_SUPPORTED); + + // prepare the respective timer and let timer_gettime() do the job + __timer_t timer; + timer.SetTo(USER_TIMER_REAL_TIME_ID, -1, CLOCK_MONOTONIC); + + itimerspec valueSpec; + if (timer_gettime(&timer, &valueSpec) != 0) + return -1; + + // convert back to itimerval value + itimerspec_to_itimerval(valueSpec, *value); + + return 0; +} + + +int +setitimer(int which, const struct itimerval* value, struct itimerval* oldValue) +{ + // TODO: implement me properly! + // We probably need a better internal set_alarm() implementation to do this + + // Only real time timers work at all. + if (which != ITIMER_REAL) + RETURN_AND_SET_ERRNO(B_NOT_SUPPORTED); + + // convert value to itimerspec + itimerspec valueSpec; + if (!itimerval_to_itimerspec(*value, valueSpec)) + RETURN_AND_SET_ERRNO(EINVAL); + + // prepare the respective timer and let timer_settime() do the job + __timer_t timer; + timer.SetTo(USER_TIMER_REAL_TIME_ID, -1, CLOCK_MONOTONIC); + + itimerspec oldValueSpec; + if (timer_settime(&timer, 0, &valueSpec, + oldValue != NULL ? &oldValueSpec : NULL) != 0) { + return -1; + } + + // convert back to itimerval oldValue + if (oldValue != NULL) + itimerspec_to_itimerval(oldValueSpec, *oldValue); + + return 0; +}