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; |
