From 808aaaacaf3bf08d614419e355b8e0c4b45bd803 Mon Sep 17 00:00:00 2001 From: Medour Mehdi Date: Sun, 6 Oct 2024 20:15:56 +0200 Subject: [PATCH] Minimal implementation of clock_nanosleep function (#79) --- include/time.h | 3 ++ posix/SRCFILES | 1 + posix/clock_nanosleep.c | 80 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 84 insertions(+) create mode 100644 posix/clock_nanosleep.c diff --git a/include/time.h b/include/time.h index c9e6918..e5e6a25 100644 --- a/include/time.h +++ b/include/time.h @@ -279,6 +279,9 @@ extern int nanosleep (__const struct timespec *__requested_time, struct timespec *__remaining); extern int clock_gettime(clockid_t clock_id, struct timespec *tp); + +extern int clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req, + struct timespec *rem); # endif # ifdef __USE_XOPEN_EXTENDED diff --git a/posix/SRCFILES b/posix/SRCFILES index 3de058a..852b497 100644 --- a/posix/SRCFILES +++ b/posix/SRCFILES @@ -21,6 +21,7 @@ SRCFILES = \ isfdtype.c \ nanosleep.c \ clock_gettime.c \ + clock_nanosleep.c \ posix_fallocate.c \ pread.c \ pwrite.c \ diff --git a/posix/clock_nanosleep.c b/posix/clock_nanosleep.c new file mode 100644 index 0000000..ed0f0a8 --- /dev/null +++ b/posix/clock_nanosleep.c @@ -0,0 +1,80 @@ +/* High-resolution sleep with the specified clock. + Copyright (C) 2000-2012 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU 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 2.1 of the License, or (at your option) any later version. + + The GNU 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 GNU C Library; if not, see + . */ + +#include +#include +#include +#include + +__typeof__(clock_nanosleep) __clock_nanosleep; + +/* This implementation assumes that these is only a `nanosleep' system + call. So we have to remap all other activities. */ +int +__clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req, struct timespec *rem) +{ + struct timespec now; + + if (__builtin_expect (req->tv_nsec, 0) < 0 || __builtin_expect (req->tv_nsec, 0) >= 1000000000){ + return EINVAL; + } + + /* If we got an absolute time, remap it. */ + if (flags == TIMER_ABSTIME) + { + long int nsec; + long int sec; + + /* Make sure we use safe data types. */ + assert (sizeof (sec) >= sizeof (now.tv_sec)); + + /* Get the current time for this clock. */ + if (__builtin_expect (clock_gettime (clock_id, &now), 0) != 0){ + return errno; + } + + /* Compute the difference. */ + nsec = req->tv_nsec - now.tv_nsec; + sec = req->tv_sec - now.tv_sec - (nsec < 0); + + if (sec < 0){ + /* The time has already elapsed. */ + return 0; + } + + now.tv_sec = sec; + now.tv_nsec = nsec + (nsec < 0 ? 1000000000 : 0); + + /* From now on this is our time. */ + req = &now; + + /* Make sure we are not modifying the struct pointed to by REM. */ + rem = NULL; + } + else if (__builtin_expect (flags, 0) != 0){ + return EINVAL; + } + else if ((clock_id != CLOCK_REALTIME) && clock_id != CLOCK_MONOTONIC){ + /* Not supported. */ + return ENOTSUP; + } + + return __builtin_expect (nanosleep (req, rem), 0) ? errno : 0; +} + +weak_alias (__clock_nanosleep, clock_nanosleep)