Author: bonefish Date: 2011-05-26 01:40:53 +0200 (Thu, 26 May 2011) New Revision: 41756 Changeset: https://dev.haiku-os.org/changeset/41756 Added: haiku/branches/developer/bonefish/signals/src/system/libroot/posix/time/clock_support.cpp haiku/branches/developer/bonefish/signals/src/system/libroot/posix/time/timer_support.cpp Modified: haiku/branches/developer/bonefish/signals/headers/posix/sys/types.h haiku/branches/developer/bonefish/signals/headers/posix/time.h haiku/branches/developer/bonefish/signals/headers/posix/unistd.h haiku/branches/developer/bonefish/signals/src/system/libroot/posix/time/Jamfile haiku/branches/developer/bonefish/signals/src/system/libroot/posix/time/nanosleep.c haiku/branches/developer/bonefish/signals/src/system/libroot/posix/unistd/conf.c Log: * <time.h>: Added clock and timer prototypes and macro definitions. * <unistd.h>: Added _POSIX_MONOTONIC_CLOCK, _POSIX_CLOCKRES_MIN, and _SC_MONOTONIC_CLOCK, and added case in sysconf() for the latter. * Implemented the clock functionality (for monotonic and real time clock). * Added stubs for the timer functionality. * Reimplemented nanosleep() (via clock_nanosleep()). Modified: haiku/branches/developer/bonefish/signals/headers/posix/sys/types.h =================================================================== --- haiku/branches/developer/bonefish/signals/headers/posix/sys/types.h 2011-05-25 23:36:06 UTC (rev 41755) +++ haiku/branches/developer/bonefish/signals/headers/posix/sys/types.h 2011-05-25 23:40:53 UTC (rev 41756) @@ -52,7 +52,10 @@ typedef __haiku_addr_t addr_t; typedef __haiku_int32 key_t; +typedef __haiku_std_int32 clockid_t; +typedef __haiku_std_int32 timer_t; + /* pthread types */ typedef struct _pthread_thread *pthread_t; Modified: haiku/branches/developer/bonefish/signals/headers/posix/time.h =================================================================== --- haiku/branches/developer/bonefish/signals/headers/posix/time.h 2011-05-25 23:36:06 UTC (rev 41755) +++ haiku/branches/developer/bonefish/signals/headers/posix/time.h 2011-05-25 23:40:53 UTC (rev 41756) @@ -1,5 +1,5 @@ /* - * Copyright 2005-2010 Haiku Inc. All Rights Reserved. + * Copyright 2005-2011, Haiku, Inc. All Rights Reserved. * Distributed under the terms of the MIT License. */ #ifndef _TIME_H_ @@ -9,17 +9,33 @@ #include <sys/types.h> +struct sigevent; /* defined in <signal.h> */ + + typedef __haiku_int32 clock_t; typedef __haiku_int32 time_t; typedef __haiku_int32 suseconds_t; typedef __haiku_uint32 useconds_t; + #define CLOCKS_PER_SEC 1000 + /* TODO: Should actually be 1000000. */ #define CLK_TCK CLOCKS_PER_SEC #define MAX_TIMESTR 70 /* maximum length of a string returned by asctime(), and ctime() */ +#define CLOCK_MONOTONIC 0 /* system-wide monotonic clock (aka system + time) */ +#define CLOCK_REALTIME 1 /* system-wide real time clock */ +#if 0 /* not supported */ +#define CLOCK_PROCESS_CPUTIME_ID 2 /* process-specific clock */ +#define CLOCK_THREAD_CPUTIME_ID 3 /* thread-specific clock */ +#endif + +#define TIMER_ABSTIME 1 /* absolute timer flag */ + + struct timespec { time_t tv_sec; /* seconds */ long tv_nsec; /* and nanoseconds */ @@ -72,6 +88,25 @@ const struct tm *tm); extern char *strptime(const char *buf, const char *format, struct tm *tm); +/* clock functions */ +int clock_getres(clockid_t clockID, struct timespec* resolution); +int clock_gettime(clockid_t clockID, struct timespec* time); +int clock_settime(clockid_t clockID, const struct timespec* time); +int clock_nanosleep(clockid_t clockID, int flags, + const struct timespec* time, struct timespec* remainingTime); +#if 0 /* not supported */ +int clock_getcpuclockid(pid_t pid, clockid_t* clockID); +#endif + +/* timer functions */ +int timer_create(clockid_t clockID, struct sigevent* event, + timer_t* timerID); +int timer_delete(timer_t timerID); +int timer_gettime(timer_t timerID, struct itimerspec* value); +int timer_settime(timer_t timerID, int flags, + const struct itimerspec* value, struct itimerspec* oldValue); +int timer_getoverrun(timer_t timerID); + /* special timezone support */ extern void tzset(void); Modified: haiku/branches/developer/bonefish/signals/headers/posix/unistd.h =================================================================== --- haiku/branches/developer/bonefish/signals/headers/posix/unistd.h 2011-05-25 23:36:06 UTC (rev 41755) +++ haiku/branches/developer/bonefish/signals/headers/posix/unistd.h 2011-05-25 23:40:53 UTC (rev 41756) @@ -50,6 +50,8 @@ #define _POSIX_SEM_VALUE_MAX INT_MAX #define _POSIX_SIGQUEUE_MAX 32 #define _POSIX_RTSIG_MAX 8 +#define _POSIX_MONOTONIC_CLOCK (200809L) +#define _POSIX_CLOCKRES_MIN 20000000 /* pathconf() constants */ @@ -124,6 +126,7 @@ #define _SC_MEMORY_PROTECTION 52 #define _SC_SIGQUEUE_MAX 53 #define _SC_RTSIG_MAX 54 +#define _SC_MONOTONIC_CLOCK 55 /* confstr() constants */ Modified: haiku/branches/developer/bonefish/signals/src/system/libroot/posix/time/Jamfile =================================================================== --- haiku/branches/developer/bonefish/signals/src/system/libroot/posix/time/Jamfile 2011-05-25 23:36:06 UTC (rev 41755) +++ haiku/branches/developer/bonefish/signals/src/system/libroot/posix/time/Jamfile 2011-05-25 23:40:53 UTC (rev 41756) @@ -7,12 +7,14 @@ UsePrivateHeaders [ FDirName libroot locale ] [ FDirName libroot time ] + shared ; UsePrivateSystemHeaders ; MergeObject posix_time.o : asctime.cpp clock.c + clock_support.cpp ctime.c difftime.c localtime_fading_out.c @@ -23,6 +25,7 @@ strptime.c timelocal.cpp time.c + timer_support.cpp wcsftime.c ; Added: haiku/branches/developer/bonefish/signals/src/system/libroot/posix/time/clock_support.cpp =================================================================== --- haiku/branches/developer/bonefish/signals/src/system/libroot/posix/time/clock_support.cpp (rev 0) +++ haiku/branches/developer/bonefish/signals/src/system/libroot/posix/time/clock_support.cpp 2011-05-25 23:40:53 UTC (rev 41756) @@ -0,0 +1,144 @@ +/* + * Copyright 2011, Ingo Weinhold, ingo_weinhold@xxxxxxx + * Distributed under the terms of the MIT License. + */ + + +#include <time.h> + +#include <errno.h> + +#include <OS.h> + +#include <syscall_utils.h> + +#include <syscalls.h> + + +int +clock_getres(clockid_t clockID, struct timespec* resolution) +{ + // check the clock ID + switch (clockID) { + case CLOCK_MONOTONIC: + case CLOCK_REALTIME: + break; + default: + RETURN_AND_SET_ERRNO(EINVAL); + } + + // currently resolution is always 1us + if (resolution != NULL) { + resolution->tv_sec = 0; + resolution->tv_nsec = 1000; + } + + return 0; +} + + +int +clock_gettime(clockid_t clockID, struct timespec* time) +{ + // get the time in microseconds + bigtime_t microSeconds; + + switch (clockID) { + case CLOCK_MONOTONIC: + microSeconds = system_time(); + break; + case CLOCK_REALTIME: + microSeconds = real_time_clock_usecs(); + break; + default: + RETURN_AND_SET_ERRNO(EINVAL); + } + + // set the result + time->tv_sec = microSeconds / 1000000; + time->tv_nsec = (microSeconds % 1000000) * 1000; + + return 0; +} + + +int +clock_settime(clockid_t clockID, const struct timespec* time) +{ + // only the real time clock (and the ones we don't support yet) can be set + if (clockID != CLOCK_REALTIME) + RETURN_AND_SET_ERRNO(EINVAL); + + if (time->tv_nsec < 0 || time->tv_nsec >= 1000000000) + RETURN_AND_SET_ERRNO(EINVAL); + + bigtime_t microSeconds = (bigtime_t)time->tv_sec * 1000000 + + time->tv_nsec / 1000; + + RETURN_AND_SET_ERRNO(_kern_set_real_time_clock(microSeconds)); +} + + +int +clock_nanosleep(clockid_t clockID, int flags, const struct timespec* time, + struct timespec* remainingTime) +{ + // convert time to microseconds (round up) + if (time->tv_nsec < 0 || time->tv_nsec >= 1000000000) + RETURN_AND_SET_ERRNO(EINVAL); + + bigtime_t microSeconds = (bigtime_t)time->tv_sec * 1000000 + + (time->tv_nsec + 999) / 1000; + + // Get the timeout flag (absolute/relative) and for relative waits also the + // start time. + bigtime_t startTime = 0; + uint32 timeoutFlags; + + switch (clockID) { + case CLOCK_MONOTONIC: + if ((flags & TIMER_ABSTIME) != 0) { + timeoutFlags = B_ABSOLUTE_TIMEOUT; + } else { + timeoutFlags = B_RELATIVE_TIMEOUT; + startTime = system_time(); + } + break; + case CLOCK_REALTIME: + if ((flags & TIMER_ABSTIME) != 0) { + timeoutFlags = B_ABSOLUTE_REAL_TIME_TIMEOUT; + } else { + timeoutFlags = B_RELATIVE_TIMEOUT; + startTime = real_time_clock_usecs(); + } + break; + default: + RETURN_AND_SET_ERRNO(EINVAL); + } + + if (microSeconds == 0) + return 0; + + // sleep + status_t error = _kern_snooze_etc(microSeconds, B_SYSTEM_TIMEBASE, + timeoutFlags); + + // If interrupted and this is a relative wait, compute and return the + // remaining wait time. + if (error == B_INTERRUPTED && remainingTime != NULL + && (flags & TIMER_ABSTIME) != 0) { + bigtime_t endTime = clockID == CLOCK_MONOTONIC + ? system_time() : real_time_clock_usecs(); + microSeconds -= endTime - startTime; + + if (microSeconds > 0) { + remainingTime->tv_sec = microSeconds / 1000000; + remainingTime->tv_nsec = (microSeconds % 1000000) * 1000; + } else { + // We were slow enough that the wait time passed anyway. + error = B_OK; + } + } + + RETURN_AND_SET_ERRNO(error); +} Modified: haiku/branches/developer/bonefish/signals/src/system/libroot/posix/time/nanosleep.c =================================================================== --- haiku/branches/developer/bonefish/signals/src/system/libroot/posix/time/nanosleep.c 2011-05-25 23:36:06 UTC (rev 41755) +++ haiku/branches/developer/bonefish/signals/src/system/libroot/posix/time/nanosleep.c 2011-05-25 23:40:53 UTC (rev 41756) @@ -1,35 +1,15 @@ -/* -** Copyright 2007, Jérôme Duval. All rights reserved. -** Distributed under the terms of the Haiku License. -*/ -#include <errno.h> +/* + * Copyright 2011, Ingo Weinhold, ingo_weinhold@xxxxxxx + * Distributed under the terms of the MIT License. + */ + + #include <time.h> -#include <OS.h> + int -nanosleep(const struct timespec *rqtp, struct timespec *rmtp) +nanosleep(const struct timespec* time, struct timespec* remainingTime) { - bigtime_t ms, begin_ms; - status_t err; - - if (!rqtp) { - errno = EINVAL; - return -1; - } - - // round up tv_nsec - ms = rqtp->tv_sec * 1000000LL + (rqtp->tv_nsec + 999) / 1000; - begin_ms = system_time(); - err = snooze(ms); - if (err == B_INTERRUPTED) { - errno = EINTR; - if (rmtp) { - bigtime_t remain_ms = ms - system_time() + begin_ms; - rmtp->tv_sec = remain_ms / 1000000; - rmtp->tv_nsec = (remain_ms - rmtp->tv_sec) * 1000; - } - return -1; - } - return 0; + return clock_nanosleep(CLOCK_MONOTONIC, 0, time, remainingTime); } Added: haiku/branches/developer/bonefish/signals/src/system/libroot/posix/time/timer_support.cpp =================================================================== --- haiku/branches/developer/bonefish/signals/src/system/libroot/posix/time/timer_support.cpp (rev 0) +++ haiku/branches/developer/bonefish/signals/src/system/libroot/posix/time/timer_support.cpp 2011-05-25 23:40:53 UTC (rev 41756) @@ -0,0 +1,52 @@ +/* + * Copyright 2011, Ingo Weinhold, ingo_weinhold@xxxxxxx + * Distributed under the terms of the MIT License. + */ + + +#include <time.h> + +#include <errno.h> + +#include <syscall_utils.h> + + +int +timer_create(clockid_t clockID, struct sigevent* event, timer_t* timerID) +{ + // TODO: Implement! + RETURN_AND_SET_ERRNO(EINVAL); +} + + +int +timer_delete(timer_t timerID) +{ + // TODO: Implement! + RETURN_AND_SET_ERRNO(EINVAL); +} + + +int +timer_gettime(timer_t timerID, struct itimerspec* value) +{ + // TODO: Implement! + RETURN_AND_SET_ERRNO(EINVAL); +} + + +int +timer_settime(timer_t timerID, int flags, const struct itimerspec* value, + struct itimerspec* oldValue) +{ + // TODO: Implement! + RETURN_AND_SET_ERRNO(EINVAL); +} + + +int +timer_getoverrun(timer_t timerID) +{ + // TODO: Implement! + RETURN_AND_SET_ERRNO(EINVAL); +} Modified: haiku/branches/developer/bonefish/signals/src/system/libroot/posix/unistd/conf.c =================================================================== --- haiku/branches/developer/bonefish/signals/src/system/libroot/posix/unistd/conf.c 2011-05-25 23:36:06 UTC (rev 41755) +++ haiku/branches/developer/bonefish/signals/src/system/libroot/posix/unistd/conf.c 2011-05-25 23:40:53 UTC (rev 41756) @@ -153,6 +153,8 @@ return MAX_QUEUED_SIGNALS; case _SC_RTSIG_MAX: return SIGRTMAX - SIGRTMIN + 1; + case _SC_MONOTONIC_CLOCK: + return _POSIX_MONOTONIC_CLOCK; // not POSIX (anymore) case _SC_PIPE: