diff options
author | Wolfgang Hommel <wolfgang.hommel@unibw.de> | 2019-08-21 18:04:48 +0200 |
---|---|---|
committer | Wolfgang Hommel <wolfgang.hommel@unibw.de> | 2019-08-21 18:05:17 +0200 |
commit | 314b1298c96d29c38b84ff8e5e027e2e65c81966 (patch) | |
tree | bcb091dcea1614a9e234ba0284fb1bb3caedfd11 | |
parent | 7573d20cd4db40bfb4eda9b20e9fafb5dad8e562 (diff) | |
download | libfaketime-314b1298c96d29c38b84ff8e5e027e2e65c81966.tar.gz |
Added support for clock_nanosleep() (#105)
-rw-r--r-- | NEWS | 1 | ||||
-rw-r--r-- | src/libfaketime.c | 85 |
2 files changed, 86 insertions, 0 deletions
@@ -15,6 +15,7 @@ Since 0.9.7: - Fixes for shared memory related issues, especially when not using the faketime wrapper - Updated glibc compatibility settings for various platforms + - Support for clock_nanosleep() with realtime and monotonic clocks Since 0.9.6: - Julien Gilli added an option to disable monotonic time faking diff --git a/src/libfaketime.c b/src/libfaketime.c index 74c34e8..d84a799 100644 --- a/src/libfaketime.c +++ b/src/libfaketime.c @@ -166,6 +166,9 @@ static int (*real_timer_gettime_233) (timer_t timerid, #endif #ifdef FAKE_SLEEP static int (*real_nanosleep) (const struct timespec *req, struct timespec *rem); +#ifndef __APPLE__ +static int (*real_clock_nanosleep) (clockid_t clock_id, int flags, const struct timespec *req, struct timespec *rem); +#endif static int (*real_usleep) (useconds_t usec); static unsigned int (*real_sleep) (unsigned int seconds); static unsigned int (*real_alarm) (unsigned int seconds); @@ -1052,6 +1055,85 @@ int nanosleep(const struct timespec *req, struct timespec *rem) return result; } +#ifndef __APPLE__ +/* + * Faked clock_nanosleep() + */ +int clock_nanosleep(clockid_t clock_id, int flags, const struct timespec *req, struct timespec *rem) +{ + int result; + struct timespec real_req; + + if (!initialized) + { + ftpl_init(); + } + if (real_clock_nanosleep == NULL) + { + return -1; + } + if (req != NULL) + { + if (flags & TIMER_ABSTIME) /* sleep until absolute time */ + { + struct timespec tdiff, timeadj; + timespecsub(req, &user_faked_time_timespec, &timeadj); + if (user_rate_set) + { + timespecmul(&timeadj, 1.0/user_rate, &tdiff); + } + else + { + tdiff = timeadj; + } + if (clock_id == CLOCK_REALTIME) + { + timespecadd(&ftpl_starttime.real, &tdiff, &real_req); + } + else if (clock_id == CLOCK_MONOTONIC) + { + timespecadd(&ftpl_starttime.mon, &tdiff, &real_req); + } + else /* presumably only CLOCK_PROCESS_CPUTIME_ID, leave untouched */ + { + real_req = *req; + } + } + else /* sleep for a relative time interval */ + { + if (user_rate_set && !dont_fake && ((clock_id == CLOCK_REALTIME) || (clock_id == CLOCK_MONOTONIC))) /* don't touch CLOCK_PROCESS_CPUTIME_ID */ + { + timespecmul(req, 1.0 / user_rate, &real_req); + } + else + { + real_req = *req; + } + } + } + else + { + return -1; + } + + DONT_FAKE_TIME(result = (*real_clock_nanosleep)(clock_id, flags, &real_req, rem)); + if (result == -1) + { + return result; + } + /* fake returned parts */ + if ((rem != NULL) && ((rem->tv_sec != 0) || (rem->tv_nsec != 0))) + { + if (user_rate_set && !dont_fake) + { + timespecmul(rem, user_rate, rem); + } + } + /* return the result to the caller */ + return result; +} +#endif + /* * Faked usleep() */ @@ -1928,6 +2010,9 @@ static void ftpl_init(void) #endif #ifdef FAKE_SLEEP real_nanosleep = dlsym(RTLD_NEXT, "nanosleep"); +#ifndef __APPLE__ + real_clock_nanosleep = dlsym(RTLD_NEXT, "clock_nanosleep"); +#endif real_usleep = dlsym(RTLD_NEXT, "usleep"); real_sleep = dlsym(RTLD_NEXT, "sleep"); real_alarm = dlsym(RTLD_NEXT, "alarm"); |