refactor lockstep_scheduler: fix class member naming convention

This commit is contained in:
Beat Küng
2019-01-09 13:30:40 +01:00
committed by Julian Oes
parent 828e31d3a9
commit 2a47715385
3 changed files with 58 additions and 57 deletions
@@ -13,13 +13,11 @@ public:
~LockstepScheduler(); ~LockstepScheduler();
void set_absolute_time(uint64_t time_us); void set_absolute_time(uint64_t time_us);
inline uint64_t get_absolute_time() const { return time_us_; } inline uint64_t get_absolute_time() const { return _time_us; }
int cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *lock, uint64_t time_us); int cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *lock, uint64_t time_us);
int usleep_until(uint64_t timed_us); int usleep_until(uint64_t timed_us);
private: private:
std::atomic<uint64_t> time_us_{0};
struct TimedWait { struct TimedWait {
~TimedWait() ~TimedWait()
{ {
@@ -42,7 +40,10 @@ private:
TimedWait *next{nullptr}; ///< linked list TimedWait *next{nullptr}; ///< linked list
}; };
TimedWait *timed_waits_{nullptr}; ///< head of linked list
std::mutex timed_waits_mutex_; std::atomic<uint64_t> _time_us{0};
std::atomic<bool> setting_time_{false}; ///< true if set_absolute_time() is currently being executed
TimedWait *_timed_waits{nullptr}; ///< head of linked list
std::mutex _timed_waits_mutex;
std::atomic<bool> _setting_time{false}; ///< true if set_absolute_time() is currently being executed
}; };
@@ -3,24 +3,24 @@
LockstepScheduler::~LockstepScheduler() LockstepScheduler::~LockstepScheduler()
{ {
// cleanup the linked list // cleanup the linked list
std::unique_lock<std::mutex> lock_timed_waits(timed_waits_mutex_); std::unique_lock<std::mutex> lock_timed_waits(_timed_waits_mutex);
while (timed_waits_) { while (_timed_waits) {
TimedWait *tmp = timed_waits_; TimedWait *tmp = _timed_waits;
timed_waits_ = timed_waits_->next; _timed_waits = _timed_waits->next;
tmp->removed = true; tmp->removed = true;
} }
} }
void LockstepScheduler::set_absolute_time(uint64_t time_us) void LockstepScheduler::set_absolute_time(uint64_t time_us)
{ {
time_us_ = time_us; _time_us = time_us;
{ {
std::unique_lock<std::mutex> lock_timed_waits(timed_waits_mutex_); std::unique_lock<std::mutex> lock_timed_waits(_timed_waits_mutex);
setting_time_ = true; _setting_time = true;
TimedWait *timed_wait = timed_waits_; TimedWait *timed_wait = _timed_waits;
TimedWait *timed_wait_prev = nullptr; TimedWait *timed_wait_prev = nullptr;
while (timed_wait) { while (timed_wait) {
@@ -31,7 +31,7 @@ void LockstepScheduler::set_absolute_time(uint64_t time_us)
timed_wait_prev->next = timed_wait->next; timed_wait_prev->next = timed_wait->next;
} else { } else {
timed_waits_ = timed_wait->next; _timed_waits = timed_wait->next;
} }
TimedWait *tmp = timed_wait; TimedWait *tmp = timed_wait;
@@ -54,7 +54,7 @@ void LockstepScheduler::set_absolute_time(uint64_t time_us)
timed_wait = timed_wait->next; timed_wait = timed_wait->next;
} }
setting_time_ = false; _setting_time = false;
} }
} }
@@ -64,10 +64,10 @@ int LockstepScheduler::cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *loc
// longer. And using thread_local is more efficient than malloc. // longer. And using thread_local is more efficient than malloc.
static thread_local TimedWait timed_wait; static thread_local TimedWait timed_wait;
{ {
std::lock_guard<std::mutex> lock_timed_waits(timed_waits_mutex_); std::lock_guard<std::mutex> lock_timed_waits(_timed_waits_mutex);
// The time has already passed. // The time has already passed.
if (time_us <= time_us_) { if (time_us <= _time_us) {
return ETIMEDOUT; return ETIMEDOUT;
} }
@@ -80,8 +80,8 @@ int LockstepScheduler::cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *loc
// Add to linked list if not removed yet (otherwise just re-use the object) // Add to linked list if not removed yet (otherwise just re-use the object)
if (timed_wait.removed) { if (timed_wait.removed) {
timed_wait.removed = false; timed_wait.removed = false;
timed_wait.next = timed_waits_; timed_wait.next = _timed_waits;
timed_waits_ = &timed_wait; _timed_waits = &timed_wait;
} }
} }
@@ -95,7 +95,7 @@ int LockstepScheduler::cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *loc
timed_wait.done = true; timed_wait.done = true;
if (!timeout && setting_time_) { if (!timeout && _setting_time) {
// This is where it gets tricky: the timeout has not been triggered yet, // This is where it gets tricky: the timeout has not been triggered yet,
// and another thread is in set_absolute_time(). // and another thread is in set_absolute_time().
// If it already passed the 'done' check, it will access the mutex and // If it already passed the 'done' check, it will access the mutex and
@@ -106,8 +106,8 @@ int LockstepScheduler::cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *loc
// Note that this case does not happen too frequently, and thus can be // Note that this case does not happen too frequently, and thus can be
// a bit more expensive. // a bit more expensive.
pthread_mutex_unlock(lock); pthread_mutex_unlock(lock);
timed_waits_mutex_.lock(); _timed_waits_mutex.lock();
timed_waits_mutex_.unlock(); _timed_waits_mutex.unlock();
pthread_mutex_lock(lock); pthread_mutex_lock(lock);
} }
@@ -125,69 +125,69 @@ class TestCase
{ {
public: public:
TestCase(unsigned timeout, unsigned unlocked_after, LockstepScheduler &ls) : TestCase(unsigned timeout, unsigned unlocked_after, LockstepScheduler &ls) :
timeout_(timeout + some_time_us), _timeout(timeout + some_time_us),
unlocked_after_(unlocked_after + some_time_us), _unlocked_after(unlocked_after + some_time_us),
ls_(ls) _ls(ls)
{ {
pthread_mutex_init(&lock_, NULL); pthread_mutex_init(&_lock, NULL);
pthread_cond_init(&cond_, NULL); pthread_cond_init(&_cond, NULL);
} }
~TestCase() ~TestCase()
{ {
assert(is_done_); assert(_is_done);
pthread_mutex_destroy(&lock_); pthread_mutex_destroy(&_lock);
pthread_cond_destroy(&cond_); pthread_cond_destroy(&_cond);
} }
void run() void run()
{ {
pthread_mutex_lock(&lock_); pthread_mutex_lock(&_lock);
thread_ = std::make_shared<TestThread>([this]() { _thread = std::make_shared<TestThread>([this]() {
result_ = ls_.cond_timedwait(&cond_, &lock_, timeout_); _result = _ls.cond_timedwait(&_cond, &_lock, _timeout);
pthread_mutex_unlock(&lock_); pthread_mutex_unlock(&_lock);
}); });
} }
void check() void check()
{ {
if (is_done_) { if (_is_done) {
return; return;
} }
uint64_t time_us = ls_.get_absolute_time(); uint64_t time_us = _ls.get_absolute_time();
const bool unlock_reached = (time_us >= unlocked_after_); const bool unlock_reached = (time_us >= _unlocked_after);
const bool unlock_is_before_timeout = (unlocked_after_ <= timeout_); const bool unlock_is_before_timeout = (_unlocked_after <= _timeout);
const bool timeout_reached = (time_us >= timeout_); const bool timeout_reached = (time_us >= _timeout);
if (unlock_reached && unlock_is_before_timeout && !(timeout_reached)) { if (unlock_reached && unlock_is_before_timeout && !(timeout_reached)) {
pthread_mutex_lock(&lock_); pthread_mutex_lock(&_lock);
pthread_cond_broadcast(&cond_); pthread_cond_broadcast(&_cond);
pthread_mutex_unlock(&lock_); pthread_mutex_unlock(&_lock);
is_done_ = true; _is_done = true;
// We can be sure that this triggers. // We can be sure that this triggers.
thread_->join(ls_); _thread->join(_ls);
assert(result_ == 0); assert(_result == 0);
} }
else if (timeout_reached) { else if (timeout_reached) {
is_done_ = true; _is_done = true;
thread_->join(ls_); _thread->join(_ls);
assert(result_ == ETIMEDOUT); assert(_result == ETIMEDOUT);
} }
} }
private: private:
static constexpr int INITIAL_RESULT = 42; static constexpr int INITIAL_RESULT = 42;
unsigned timeout_; unsigned _timeout;
unsigned unlocked_after_; unsigned _unlocked_after;
pthread_cond_t cond_; pthread_cond_t _cond;
pthread_mutex_t lock_; pthread_mutex_t _lock;
LockstepScheduler &ls_; LockstepScheduler &_ls;
std::atomic<bool> is_done_{false}; std::atomic<bool> _is_done{false};
std::atomic<int> result_ {INITIAL_RESULT}; std::atomic<int> _result {INITIAL_RESULT};
std::shared_ptr<TestThread> thread_{}; std::shared_ptr<TestThread> _thread{};
}; };
int random_number(int min, int max) int random_number(int min, int max)