diff --git a/repos/libports/src/lib/libc/task.cc b/repos/libports/src/lib/libc/task.cc index c0ae3e360..4e2012110 100644 --- a/repos/libports/src/lib/libc/task.cc +++ b/repos/libports/src/lib/libc/task.cc @@ -217,9 +217,9 @@ struct Libc::Timer Timer(Genode::Env &env) : _timer(env) { } - unsigned long curr_time() + Genode::Duration curr_time() { - return _timer.curr_time().trunc_to_plain_us().value/1000; + return _timer.curr_time(); } static Microseconds microseconds(unsigned long timeout_ms) @@ -281,22 +281,22 @@ struct Libc::Timeout void start(unsigned long timeout_ms) { - unsigned long const now = _timer_accessor.timer().curr_time(); + Milliseconds const now = _timer_accessor.timer().curr_time().trunc_to_plain_ms(); _expired = false; - _absolute_timeout_ms = now + timeout_ms; + _absolute_timeout_ms = now.value + timeout_ms; _timeout.schedule(_timer_accessor.timer().microseconds(timeout_ms)); } unsigned long duration_left() const { - unsigned long const now = _timer_accessor.timer().curr_time(); + Milliseconds const now = _timer_accessor.timer().curr_time().trunc_to_plain_ms(); - if (_expired || _absolute_timeout_ms < now) + if (_expired || _absolute_timeout_ms < now.value) return 0; - return _absolute_timeout_ms - now; + return _absolute_timeout_ms - now.value; } }; @@ -751,7 +751,7 @@ struct Libc::Kernel } } - unsigned long current_time() + Genode::Duration current_time() { return _timer_accessor.timer().curr_time(); } @@ -889,7 +889,7 @@ void Libc::dispatch_pending_io_signals() } -unsigned long Libc::current_time() +Genode::Duration Libc::current_time() { return kernel->current_time(); } diff --git a/repos/libports/src/lib/libc/task.h b/repos/libports/src/lib/libc/task.h index fbac5921c..cf39bf2aa 100644 --- a/repos/libports/src/lib/libc/task.h +++ b/repos/libports/src/lib/libc/task.h @@ -21,6 +21,7 @@ #ifndef _LIBC__TASK_H_ #define _LIBC__TASK_H_ +#include #include namespace Libc { @@ -53,7 +54,7 @@ namespace Libc { /** * Get time since startup in ms */ - unsigned long current_time(); + Genode::Duration current_time(); /** * Suspend main user context and the component entrypoint diff --git a/repos/libports/src/lib/libc/time.cc b/repos/libports/src/lib/libc/time.cc index b0ac34a13..c9945ac57 100644 --- a/repos/libports/src/lib/libc/time.cc +++ b/repos/libports/src/lib/libc/time.cc @@ -24,32 +24,54 @@ namespace Libc { time_t read_rtc(); } extern "C" __attribute__((weak)) int clock_gettime(clockid_t clk_id, struct timespec *ts) { - if (!ts) return 0; - - static bool initial_rtc_requested = false; - static time_t initial_rtc = 0; - static unsigned long t0 = 0; + if (!ts) return Libc::Errno(EFAULT); + /* initialize timespec just in case users do not check for errors */ ts->tv_sec = 0; ts->tv_nsec = 0; - /* try to read rtc once */ - if (!initial_rtc_requested) { - initial_rtc_requested = true; + switch (clk_id) { - initial_rtc = Libc::read_rtc(); + /* IRL wall-time */ + case CLOCK_REALTIME: + case CLOCK_SECOND: /* FreeBSD specific */ + { + static bool initial_rtc_requested = false; + static time_t initial_rtc = 0; + static unsigned long t0_ms = 0; - if (initial_rtc) - t0 = Libc::current_time(); + /* try to read rtc once */ + if (!initial_rtc_requested) { + initial_rtc_requested = true; + initial_rtc = Libc::read_rtc(); + if (initial_rtc) { + t0_ms = Libc::current_time().trunc_to_plain_ms().value; + } + } + + if (!initial_rtc) return Libc::Errno(EINVAL); + + unsigned long time = Libc::current_time().trunc_to_plain_ms().value - t0_ms; + + ts->tv_sec = initial_rtc + time/1000; + ts->tv_nsec = (time % 1000) * (1000*1000); + break; } - if (!initial_rtc) + /* component uptime */ + case CLOCK_MONOTONIC: + case CLOCK_UPTIME: + { + unsigned long us = Libc::current_time().trunc_to_plain_us().value; + + ts->tv_sec = us / (1000*1000); + ts->tv_nsec = (us % (1000*1000)) * 1000; + break; + } + + default: return Libc::Errno(EINVAL); - - unsigned long time = Libc::current_time() - t0; - - ts->tv_sec = initial_rtc + time/1000; - ts->tv_nsec = (time % 1000) * (1000*1000); + } return 0; } @@ -62,7 +84,7 @@ int gettimeofday(struct timeval *tv, struct timezone *) struct timespec ts; - if (int ret = clock_gettime(0, &ts)) + if (int ret = clock_gettime(CLOCK_REALTIME, &ts)) return ret; tv->tv_sec = ts.tv_sec;