From cbc6725f0f8309a8f910a8601afecf865d3f9e78 Mon Sep 17 00:00:00 2001 From: Zygo Blaxell Date: Sun, 9 Dec 2018 23:30:21 -0500 Subject: [PATCH] time: separate sleep time calculation from sleep_for method We need to replace nanosleeps with condition variables so that we can implement BeesContext::stop. Export the time calculation from sleep_for() into a new method called sleep_time(). If the thread executing RateLimiter::sleep_for() is interrupted, it will no longer be able to restart, as the sleep_time() method is destructive. This calls for further refactoring of sleep_time() into destructive and non-destructive parts; however, there are currently no users of sleep_for() which rely on being able to restart after being interrupted by a signal. Signed-off-by: Zygo Blaxell --- include/crucible/time.h | 1 + lib/time.cc | 31 +++++++++++++++++-------------- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/include/crucible/time.h b/include/crucible/time.h index 7261013..cad7fe3 100644 --- a/include/crucible/time.h +++ b/include/crucible/time.h @@ -42,6 +42,7 @@ namespace crucible { RateLimiter(double rate, double burst); RateLimiter(double rate); void sleep_for(double cost = 1.0); + double sleep_time(double cost = 1.0); bool is_ready(); void borrow(double cost = 1.0); }; diff --git a/lib/time.cc b/lib/time.cc index 77a99ad..99001b6 100644 --- a/lib/time.cc +++ b/lib/time.cc @@ -116,23 +116,26 @@ namespace crucible { } } + double + RateLimiter::sleep_time(double cost) + { + borrow(cost); + unique_lock lock(m_mutex); + update_tokens(); + if (m_tokens >= 0) { + return 0; + } + return -m_tokens / m_rate; + } + void RateLimiter::sleep_for(double cost) { - borrow(cost); - while (1) { - unique_lock lock(m_mutex); - update_tokens(); - if (m_tokens >= 0) { - return; - } - double sleep_time(-m_tokens / m_rate); - lock.unlock(); - if (sleep_time > 0.0) { - nanosleep(sleep_time); - } else { - return; - } + double time_to_sleep = sleep_time(cost); + if (time_to_sleep > 0.0) { + nanosleep(time_to_sleep); + } else { + return; } }