diff options
author | Lucas De Marchi <lucas.de.marchi@gmail.com> | 2022-06-03 14:50:45 -0700 |
---|---|---|
committer | Lucas De Marchi <lucas.de.marchi@gmail.com> | 2022-06-26 23:23:46 -0700 |
commit | 8ab15eceafd46fcaf2f8874af7d52d0622127655 (patch) | |
tree | afc4d840e2e1983382be6e2d049712454faf6bfe | |
parent | ba105fafed8ccabc0a427049a14e093b914f7ddc (diff) | |
download | kmod-8ab15eceafd46fcaf2f8874af7d52d0622127655.tar.gz kmod-8ab15eceafd46fcaf2f8874af7d52d0622127655.tar.bz2 kmod-8ab15eceafd46fcaf2f8874af7d52d0622127655.zip |
util: Add exponential backoff sleep
Add simple functions to put the current thread to sleep using
exponential backoff to split the interval in smaller pieces.
Signed-off-by: Lucas De Marchi <lucas.de.marchi@gmail.com>
-rw-r--r-- | shared/util.c | 46 | ||||
-rw-r--r-- | shared/util.h | 5 |
2 files changed, 51 insertions, 0 deletions
diff --git a/shared/util.c b/shared/util.c index d4452eb..4b547ff 100644 --- a/shared/util.c +++ b/shared/util.c @@ -472,6 +472,52 @@ unsigned long long ts_msec(const struct timespec *ts) (unsigned long long) ts->tv_nsec / NSEC_PER_MSEC; } +static struct timespec msec_ts(unsigned long long msec) +{ + struct timespec ts = { + .tv_sec = msec / MSEC_PER_SEC, + .tv_nsec = (msec % MSEC_PER_SEC) * NSEC_PER_MSEC, + }; + + return ts; +} + +int sleep_until_msec(unsigned long long msec) +{ + struct timespec ts = msec_ts(msec); + + if (clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &ts, NULL) < 0 && + errno != EINTR) + return -errno; + + return 0; +} + +/* + * Exponential retry backoff with tail + */ +unsigned long long get_backoff_delta_msec(unsigned long long t0, + unsigned long long tend, + unsigned long long *delta) +{ + unsigned long long t; + + t = now_msec(); + + if (!*delta) + *delta = 1; + else + *delta <<= 1; + + while (t + *delta > tend) + *delta >>= 1; + + if (!*delta && tend > t) + *delta = tend - t; + + return t + *delta; +} + unsigned long long now_usec(void) { struct timespec ts; diff --git a/shared/util.h b/shared/util.h index bedafa3..7030653 100644 --- a/shared/util.h +++ b/shared/util.h @@ -55,6 +55,11 @@ unsigned long long ts_usec(const struct timespec *ts); unsigned long long ts_msec(const struct timespec *ts); unsigned long long now_usec(void); unsigned long long now_msec(void); +int sleep_until_msec(unsigned long long msec); +unsigned long long get_backoff_delta_msec(unsigned long long t0, + unsigned long long tend, + unsigned long long *delta); + /* endianess and alignments */ /* ************************************************************************ */ |