]> xenbits.xensource.com Git - unikraft/libs/newlib.git/commitdiff
Fix remaining time in nanosleep
authorDafna Hirschfeld <dafna3@gmail.com>
Mon, 17 Sep 2018 19:42:25 +0000 (22:42 +0300)
committerFlorian Schmidt <florian.schmidt@neclab.eu>
Mon, 24 Sep 2018 08:39:34 +0000 (10:39 +0200)
Add the fix of commit 96f68ab in unikraft to newlib:
Calculate the remaining time to sleep and update
the rem parameter if it is given.
If the remaining time is larger than 0, it means that
the thread was waken up explicitly and nanosleep returns -1
to indicate that. Otherwise nanosleep returns 0.

Signed-off-by: Dafna Hirschfeld <dafna3@gmail.com>
Reviewed-by: Florian Schmidt <florian.schmidt@neclab.eu>
time.c

diff --git a/time.c b/time.c
index 9f1232986f7461adff01eba7d5419cedd2db256e..16747ebae14dee04d51eb6bab3ce0362ae336e67 100644 (file)
--- a/time.c
+++ b/time.c
 
 #include <sys/time.h>
 #include <utime.h>
+#include <uk/plat/time.h>
 #include <uk/config.h>
 #if CONFIG_HAVE_SCHED
 #include <uk/sched.h>
 #else
 #include <uk/plat/lcpu.h>
-#include <uk/plat/time.h>
 #endif
 
 int
@@ -71,9 +71,16 @@ static void __spin_wait(__nsec nsec)
 
 int nanosleep(const struct timespec *req, struct timespec *rem)
 {
-       __nsec nsec = (__nsec) req->tv_sec * 1000000000L;
+       __nsec before, after, diff, nsec;
 
+       if (!req || req->tv_nsec < 0 || req->tv_nsec > 999999999) {
+               errno = EINVAL;
+               return -1;
+       }
+
+       nsec = (__nsec) req->tv_sec * 1000000000L;
        nsec += req->tv_nsec;
+       before = ukplat_monotonic_clock();
 
 #if CONFIG_HAVE_SCHED
        uk_sched_thread_sleep(nsec);
@@ -81,9 +88,16 @@ int nanosleep(const struct timespec *req, struct timespec *rem)
        __spin_wait(nsec);
 #endif
 
-       if (rem) {
-               rem->tv_sec = 0;
-               rem->tv_nsec = 0;
+       after = ukplat_monotonic_clock();
+       diff = after - before;
+
+       if (diff < nsec) {
+               if (rem) {
+                       rem->tv_sec = ukarch_time_nsec_to_sec(nsec - diff);
+                       rem->tv_nsec = ukarch_time_subsec(nsec - diff);
+               }
+               errno = EINTR;
+               return -1;
        }
        return 0;
 }