From 1e2550c0d59ce4b28baf3608821680cae4553531 Mon Sep 17 00:00:00 2001 From: Jonas 'Sortie' Termansen Date: Sun, 12 May 2013 22:10:34 +0200 Subject: [PATCH] Add clock_*(2) API. --- libc/Makefile | 9 +++++-- libc/include/time.h | 6 +++++ libc/{ => sys/time}/gettimeofday.cpp | 18 +++++++------- libc/time/clock_getres.cpp | 30 +++++++++++++++++++++++ libc/time/clock_gettime.cpp | 30 +++++++++++++++++++++++ libc/time/clock_gettimeres.cpp | 36 ++++++++++++++++++++++++++++ libc/time/clock_settime.cpp | 30 +++++++++++++++++++++++ libc/time/clock_settimeres.cpp | 36 ++++++++++++++++++++++++++++ libc/{ => time}/time.cpp | 14 +++++------ sortix/include/sortix/syscallnum.h | 4 +++- sortix/user-timer.cpp | 34 ++++++++++++++++++++++++++ 11 files changed, 228 insertions(+), 19 deletions(-) rename libc/{ => sys/time}/gettimeofday.cpp (77%) create mode 100644 libc/time/clock_getres.cpp create mode 100644 libc/time/clock_gettime.cpp create mode 100644 libc/time/clock_gettimeres.cpp create mode 100644 libc/time/clock_settime.cpp create mode 100644 libc/time/clock_settimeres.cpp rename libc/{ => time}/time.cpp (82%) diff --git a/libc/Makefile b/libc/Makefile index 28ef0488..e8d18de7 100644 --- a/libc/Makefile +++ b/libc/Makefile @@ -242,7 +242,6 @@ getpagesize.o \ getpid.o \ getppid.o \ gettermmode.o \ -gettimeofday.o \ getuid.o \ grent.o \ init.o \ @@ -350,8 +349,14 @@ sys/socket/sockatmark.o \ sys/socket/socket.o \ sys/socket/socketpair.o \ system.o \ +sys/time/gettimeofday.o \ tfork.o \ -time.o \ +time/clock_getres.o \ +time/clock_gettime.o \ +time/clock_gettimeres.o \ +time/clock_settime.o \ +time/clock_settimeres.o \ +time/time.o \ time/timer_create.o \ time/timer_delete.o \ time/timer_getoverrun.o \ diff --git a/libc/include/time.h b/libc/include/time.h index 7abdedda..6d7305b3 100644 --- a/libc/include/time.h +++ b/libc/include/time.h @@ -102,6 +102,12 @@ int timer_settime(timer_t, int, const struct itimerspec* __restrict, struct itimerspec* __restrict); void tzset(void); + +#if defined(_SORTIX_SOURCE) +int clock_gettimeres(clockid_t, struct timespec*, struct timespec*); +int clock_settimeres(clockid_t, const struct timespec*, const struct timespec*); +#endif + extern int daylight; extern long timezone; extern char* tzname[]; diff --git a/libc/gettimeofday.cpp b/libc/sys/time/gettimeofday.cpp similarity index 77% rename from libc/gettimeofday.cpp rename to libc/sys/time/gettimeofday.cpp index 710880e0..14875c49 100644 --- a/libc/gettimeofday.cpp +++ b/libc/sys/time/gettimeofday.cpp @@ -1,6 +1,6 @@ /******************************************************************************* - Copyright(C) Jonas 'Sortie' Termansen 2011, 2012. + Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013. This file is part of the Sortix C Library. @@ -17,20 +17,22 @@ You should have received a copy of the GNU Lesser General Public License along with the Sortix C Library. If not, see . - gettimeofday.cpp + sys/time/gettimeofday.cpp Get date and time. *******************************************************************************/ #include -#include -#include + +#include extern "C" int gettimeofday(struct timeval* tp, void* /*tzp*/) { - uintmax_t sinceboot; - uptime(&sinceboot); - tp->tv_sec = sinceboot / 1000000ULL; - tp->tv_usec = sinceboot % 1000000ULL; + struct timespec now; + // TODO: We should be using CLOCK_REALTIME. + if ( clock_gettime(CLOCK_MONOTONIC, &now) < 0 ) + return -1; + tp->tv_sec = now.tv_sec; + tp->tv_usec = now.tv_nsec / 1000; return 0; } diff --git a/libc/time/clock_getres.cpp b/libc/time/clock_getres.cpp new file mode 100644 index 00000000..9fc1d1f9 --- /dev/null +++ b/libc/time/clock_getres.cpp @@ -0,0 +1,30 @@ +/******************************************************************************* + + Copyright(C) Jonas 'Sortie' Termansen 2013. + + This file is part of the Sortix C Library. + + The Sortix C Library is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or (at your + option) any later version. + + The Sortix C Library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with the Sortix C Library. If not, see . + + time/clock_getres.cpp + Get clock resolution. + +*******************************************************************************/ + +#include + +extern "C" int clock_getres(clockid_t clockid, struct timespec* res) +{ + return clock_gettimeres(clockid, NULL, res); +} diff --git a/libc/time/clock_gettime.cpp b/libc/time/clock_gettime.cpp new file mode 100644 index 00000000..d01fd061 --- /dev/null +++ b/libc/time/clock_gettime.cpp @@ -0,0 +1,30 @@ +/******************************************************************************* + + Copyright(C) Jonas 'Sortie' Termansen 2013. + + This file is part of the Sortix C Library. + + The Sortix C Library is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or (at your + option) any later version. + + The Sortix C Library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with the Sortix C Library. If not, see . + + time/clock_gettime.cpp + Get clock time. + +*******************************************************************************/ + +#include + +extern "C" int clock_gettime(clockid_t clockid, struct timespec* time) +{ + return clock_gettimeres(clockid, time, NULL); +} diff --git a/libc/time/clock_gettimeres.cpp b/libc/time/clock_gettimeres.cpp new file mode 100644 index 00000000..987d389d --- /dev/null +++ b/libc/time/clock_gettimeres.cpp @@ -0,0 +1,36 @@ +/******************************************************************************* + + Copyright(C) Jonas 'Sortie' Termansen 2013. + + This file is part of the Sortix C Library. + + The Sortix C Library is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or (at your + option) any later version. + + The Sortix C Library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with the Sortix C Library. If not, see . + + time/clock_gettimeres.cpp + Get clock time and resolution. + +*******************************************************************************/ + +#include + +#include + +DEFN_SYSCALL3(int, sys_clock_gettimeres, SYSCALL_CLOCK_GETTIMERES, clockid_t, + struct timespec*, struct timespec*); + +extern "C" int clock_gettimeres(clockid_t clockid, struct timespec* time, + struct timespec* res) +{ + return sys_clock_gettimeres(clockid, time, res); +} diff --git a/libc/time/clock_settime.cpp b/libc/time/clock_settime.cpp new file mode 100644 index 00000000..c7609f96 --- /dev/null +++ b/libc/time/clock_settime.cpp @@ -0,0 +1,30 @@ +/******************************************************************************* + + Copyright(C) Jonas 'Sortie' Termansen 2013. + + This file is part of the Sortix C Library. + + The Sortix C Library is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or (at your + option) any later version. + + The Sortix C Library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with the Sortix C Library. If not, see . + + time/clock_settime.cpp + Set clock time. + +*******************************************************************************/ + +#include + +extern "C" int clock_settime(clockid_t clockid, const struct timespec* time) +{ + return clock_settimeres(clockid, time, NULL); +} diff --git a/libc/time/clock_settimeres.cpp b/libc/time/clock_settimeres.cpp new file mode 100644 index 00000000..049e8f18 --- /dev/null +++ b/libc/time/clock_settimeres.cpp @@ -0,0 +1,36 @@ +/******************************************************************************* + + Copyright(C) Jonas 'Sortie' Termansen 2013. + + This file is part of the Sortix C Library. + + The Sortix C Library is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or (at your + option) any later version. + + The Sortix C Library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with the Sortix C Library. If not, see . + + time/clock_settimeres.cpp + Set clock time and resolution. + +*******************************************************************************/ + +#include + +#include + +DEFN_SYSCALL3(int, sys_clock_settimeres, SYSCALL_CLOCK_SETTIMERES, clockid_t, + const struct timespec*, const struct timespec*); + +extern "C" int clock_settimeres(clockid_t clockid, const struct timespec* time, + const struct timespec* res) +{ + return sys_clock_settimeres(clockid, time, res); +} diff --git a/libc/time.cpp b/libc/time/time.cpp similarity index 82% rename from libc/time.cpp rename to libc/time/time.cpp index 7b1702f9..44f3a50d 100644 --- a/libc/time.cpp +++ b/libc/time/time.cpp @@ -1,6 +1,6 @@ /******************************************************************************* - Copyright(C) Jonas 'Sortie' Termansen 2011, 2012. + Copyright(C) Jonas 'Sortie' Termansen 2013 This file is part of the Sortix C Library. @@ -17,19 +17,17 @@ You should have received a copy of the GNU Lesser General Public License along with the Sortix C Library. If not, see . - time.cpp + time/time.cpp Get time in seconds. *******************************************************************************/ -#include -#include #include extern "C" time_t time(time_t* t) { - struct timeval tv; - gettimeofday(&tv, NULL); - time_t result = tv.tv_sec; - return t ? *t = result : result; + struct timespec now; + if ( clock_gettime(CLOCK_REALTIME, &now) < 0 ) + return -1; + return t ? *t = now.tv_sec : now.tv_sec; } diff --git a/sortix/include/sortix/syscallnum.h b/sortix/include/sortix/syscallnum.h index 43cc3cb3..d58e4c88 100644 --- a/sortix/include/sortix/syscallnum.h +++ b/sortix/include/sortix/syscallnum.h @@ -124,6 +124,8 @@ #define SYSCALL_TIMER_GETTIME 100 #define SYSCALL_TIMER_SETTIME 101 #define SYSCALL_ALARMNS 102 -#define SYSCALL_MAX_NUM 103 /* index of highest constant + 1 */ +#define SYSCALL_CLOCK_GETTIMERES 103 +#define SYSCALL_CLOCK_SETTIMERES 104 +#define SYSCALL_MAX_NUM 105 /* index of highest constant + 1 */ #endif diff --git a/sortix/user-timer.cpp b/sortix/user-timer.cpp index aca67ea5..6f8d0d34 100644 --- a/sortix/user-timer.cpp +++ b/sortix/user-timer.cpp @@ -211,6 +211,38 @@ static int sys_timer_settime(timer_t timerid, int flags, return 0; } +static int sys_clock_gettimeres(clockid_t clockid, struct timespec* time, + struct timespec* res) +{ + Clock* clock = Time::GetClock(clockid); + if ( !clock ) + return -1; + + struct timespec ktime, kres; + clock->Get(&ktime, &kres); + + return (!time || CopyToUser(time, &ktime, sizeof(ktime))) && + (!res || CopyToUser(res, &kres, sizeof(kres))) ? 0 : -1; +} + +static int sys_clock_settimeres(clockid_t clockid, const struct timespec* time, + const struct timespec* res) +{ + Clock* clock = Time::GetClock(clockid); + if ( !clock ) + return -1; + + struct timespec ktime, kres; + if ( (time && !CopyFromUser(&ktime, time, sizeof(ktime))) || + (res && !CopyFromUser(&kres, res, sizeof(kres))) ) + return -1; + + clock->Set(time ? &ktime : NULL, res ? &kres : NULL); + + return 0; +} + +// TODO: Made obsolete by cloc_gettimeres. static int sys_uptime(uintmax_t* usecssinceboot) { struct timespec now; @@ -226,6 +258,8 @@ static int sys_uptime(uintmax_t* usecssinceboot) void UserTimer::Init() { + Syscall::Register(SYSCALL_CLOCK_GETTIMERES, (void*) sys_clock_gettimeres); + Syscall::Register(SYSCALL_CLOCK_SETTIMERES, (void*) sys_clock_settimeres); Syscall::Register(SYSCALL_TIMER_CREATE, (void*) sys_timer_create); Syscall::Register(SYSCALL_TIMER_DELETE, (void*) sys_timer_delete); Syscall::Register(SYSCALL_TIMER_GETOVERRUN, (void*) sys_timer_getoverrun);