diff options
author | Bjoern Brandenburg <bbb@mpi-sws.org> | 2016-07-19 19:46:02 -0400 |
---|---|---|
committer | Bjoern Brandenburg <bbb@mpi-sws.org> | 2016-07-19 20:00:11 -0400 |
commit | 7ae970e73bc1d026bbf65a82c066aab79c860fe8 (patch) | |
tree | dbc28229098af78b92996dbcb6b41663598bfcbe | |
parent | cf1d1f6e4b1138a5a841a47a2cba4aacdcaf0d72 (diff) |
Add sleep_until_mono(), lt_sleep_until() helpers
-rw-r--r-- | include/litmus.h | 23 | ||||
-rw-r--r-- | src/clocks.c | 52 |
2 files changed, 75 insertions, 0 deletions
diff --git a/include/litmus.h b/include/litmus.h index 70e7552..751b5ec 100644 --- a/include/litmus.h +++ b/include/litmus.h | |||
@@ -158,6 +158,10 @@ int sporadic_clustered(lt_t e_ns, lt_t p_ns, int cluster); | |||
158 | * @param us Time units in microseconds */ | 158 | * @param us Time units in microseconds */ |
159 | #define us2ns(us) ((us)*1000LL) | 159 | #define us2ns(us) ((us)*1000LL) |
160 | 160 | ||
161 | /** Convert nanoseconds to seconds (truncating) | ||
162 | * @param ns Time units in nanoseconds */ | ||
163 | #define ns2s(ns) ((ns)/1000000000LL) | ||
164 | |||
161 | /** | 165 | /** |
162 | * Locking protocols for allocated shared objects | 166 | * Locking protocols for allocated shared objects |
163 | */ | 167 | */ |
@@ -330,6 +334,13 @@ int read_litmus_stats(int *ready, int *total); | |||
330 | int lt_sleep(lt_t timeout); | 334 | int lt_sleep(lt_t timeout); |
331 | 335 | ||
332 | /** | 336 | /** |
337 | * Sleep until the given point in time. | ||
338 | * @param wake_up_time Point in time when to wake up (w.r.t. CLOCK_MONOTONIC, | ||
339 | * in nanoseconds). | ||
340 | */ | ||
341 | void lt_sleep_until(lt_t wake_up_time); | ||
342 | |||
343 | /** | ||
333 | * Obtain CPU time consumed so far | 344 | * Obtain CPU time consumed so far |
334 | * @return CPU time in seconds | 345 | * @return CPU time in seconds |
335 | */ | 346 | */ |
@@ -347,6 +358,18 @@ double wctime(void); | |||
347 | */ | 358 | */ |
348 | double monotime(void); | 359 | double monotime(void); |
349 | 360 | ||
361 | /** | ||
362 | * Sleep until the given point in time. | ||
363 | * @param wake_up_time Point in time when to wake up (w.r.t. CLOCK_MONOTONIC) | ||
364 | */ | ||
365 | void sleep_until_mono(double wake_up_time); | ||
366 | |||
367 | /** | ||
368 | * Sleep until the given point in time. | ||
369 | * @param wake_up_time Point in time when to wake up (w.r.t. CLOCK_REALTIME) | ||
370 | */ | ||
371 | void sleep_until_wc(double wake_up_time); | ||
372 | |||
350 | /***** semaphore allocation ******/ | 373 | /***** semaphore allocation ******/ |
351 | /** | 374 | /** |
352 | * Allocate a semaphore following the FMLP protocol | 375 | * Allocate a semaphore following the FMLP protocol |
diff --git a/src/clocks.c b/src/clocks.c index 5af4c1f..43838eb 100644 --- a/src/clocks.c +++ b/src/clocks.c | |||
@@ -1,6 +1,7 @@ | |||
1 | #include <stdio.h> | 1 | #include <stdio.h> |
2 | 2 | ||
3 | #include <sys/time.h> | 3 | #include <sys/time.h> |
4 | #include <errno.h> | ||
4 | #include <time.h> | 5 | #include <time.h> |
5 | 6 | ||
6 | #include "litmus.h" | 7 | #include "litmus.h" |
@@ -35,6 +36,57 @@ double monotime(void) | |||
35 | return (ts.tv_sec + 1E-9 * ts.tv_nsec); | 36 | return (ts.tv_sec + 1E-9 * ts.tv_nsec); |
36 | } | 37 | } |
37 | 38 | ||
39 | static void do_sleep_until(struct timespec *ts, clockid_t clock_id) | ||
40 | { | ||
41 | int err; | ||
42 | |||
43 | do { | ||
44 | /* sleep to exact absolute release time */ | ||
45 | err = clock_nanosleep(clock_id, TIMER_ABSTIME, ts, NULL); | ||
46 | /* If we were interrupted by a signal and we didn't terminate, | ||
47 | * then keep sleeping. */ | ||
48 | } while (err != 0 && errno == EINTR); | ||
49 | } | ||
50 | |||
51 | /* Sleep until we've reached wake_up_time (in seconds) on the given timeline */ | ||
52 | static void clock_sleep_until(double wake_up_time, clockid_t clock_id) | ||
53 | { | ||
54 | struct timespec ts; | ||
55 | |||
56 | /* convert from double (seconds) */ | ||
57 | ts.tv_sec = (time_t) wake_up_time; | ||
58 | ts.tv_nsec = (wake_up_time - ts.tv_sec) * 1E9; | ||
59 | |||
60 | do_sleep_until(&ts, clock_id); | ||
61 | } | ||
62 | |||
63 | /* Sleep until we've reached wake_up_time (in seconds) on the CLOCK_MONOTONIC | ||
64 | * timeline. */ | ||
65 | void sleep_until_mono(double wake_up_time) | ||
66 | { | ||
67 | clock_sleep_until(wake_up_time, CLOCK_MONOTONIC); | ||
68 | } | ||
69 | |||
70 | /* Sleep until we've reached wake_up_time (in seconds) on the CLOCK_MONOTONIC | ||
71 | * timeline. */ | ||
72 | void sleep_until_wc(double wake_up_time) | ||
73 | { | ||
74 | clock_sleep_until(wake_up_time, CLOCK_REALTIME); | ||
75 | } | ||
76 | |||
77 | /* Sleep until we've reached wake_up_time (in nanoseconds) on the | ||
78 | * CLOCK_MONOTONIC timeline. */ | ||
79 | void lt_sleep_until(lt_t wake_up_time) | ||
80 | { | ||
81 | struct timespec ts; | ||
82 | |||
83 | /* convert from double (seconds) */ | ||
84 | ts.tv_sec = (time_t) ns2s(wake_up_time); | ||
85 | ts.tv_nsec = (long) (wake_up_time - s2ns(ts.tv_sec)); | ||
86 | |||
87 | do_sleep_until(&ts, CLOCK_MONOTONIC); | ||
88 | } | ||
89 | |||
38 | int lt_sleep(lt_t timeout) | 90 | int lt_sleep(lt_t timeout) |
39 | { | 91 | { |
40 | struct timespec delay; | 92 | struct timespec delay; |