diff options
author | Martin Braun <martin.braun@ettus.com> | 2021-12-20 15:17:28 +0100 |
---|---|---|
committer | Aaron Rossetto <aaron.rossetto@ni.com> | 2022-01-14 14:45:01 -0600 |
commit | 568c02c0e75e6d6e3cfb10a14ed321816719695a (patch) | |
tree | a8615bdf1b97b973d8f1f59ed1ec49af390e26b3 /host/lib | |
parent | 828f00012c9fcddc7ae422fdda29679bdde852ff (diff) | |
download | uhd-568c02c0e75e6d6e3cfb10a14ed321816719695a.tar.gz uhd-568c02c0e75e6d6e3cfb10a14ed321816719695a.tar.bz2 uhd-568c02c0e75e6d6e3cfb10a14ed321816719695a.zip |
lib: Make simple_claimer atomic
This fixes multiple issues:
- The simple_claimer was not truly atomic, it tested and set the
locked-flag on separate lines
- It used a Boost yield statement, although we're not running Boost
threads
- It used the deprecated UHD_INLINE macro
We also remove spin_wait_with_timeout(), which was only used in
claim_with_wait() because it's not worth putting into its own function.
This is no API change on simple_claimer, but it may result in different
performance of this spinlock.
Diffstat (limited to 'host/lib')
-rw-r--r-- | host/lib/include/uhdlib/utils/atomic.hpp | 57 |
1 files changed, 19 insertions, 38 deletions
diff --git a/host/lib/include/uhdlib/utils/atomic.hpp b/host/lib/include/uhdlib/utils/atomic.hpp index 33bc78fed..0db828ee9 100644 --- a/host/lib/include/uhdlib/utils/atomic.hpp +++ b/host/lib/include/uhdlib/utils/atomic.hpp @@ -9,67 +9,48 @@ #include <uhd/config.hpp> #include <uhd/types/time_spec.hpp> -#include <boost/thread/thread.hpp> #include <atomic> #include <chrono> namespace uhd { -/*! DEPRECATED -- Will be removed in coming versions of UHD. - * - * Spin-wait on a condition with a timeout. - * \param cond an atomic variable to compare - * \param value compare to atomic for true/false - * \param timeout the timeout in seconds - * \return true for cond == value, false for timeout - */ -template <typename T> -UHD_INLINE bool spin_wait_with_timeout( - std::atomic<T>& cond, const T value, const double timeout) -{ - if (cond == value) - return true; - const auto exit_time = std::chrono::high_resolution_clock::now() - + std::chrono::microseconds(int64_t(timeout * 1e6)); - while (cond != value) { - if (std::chrono::high_resolution_clock::now() > exit_time) { - return false; - } - boost::this_thread::interruption_point(); - boost::this_thread::yield(); - } - return true; -} - -/*! DEPRECATED -- Will be removed in coming versions of UHD. +/*! DEPRECATED -- May be removed in coming versions of UHD. * * Claimer class to provide synchronization for multi-thread access. - * Claiming enables buffer classes to be used with a buffer queue. + * + * Implements a spinlock mutex with a timeout. */ class simple_claimer { public: simple_claimer(void) { - this->release(); + _locked.clear(); } - UHD_INLINE void release(void) + inline void release(void) { - _locked = false; + _locked.clear(std::memory_order_release); } - UHD_INLINE bool claim_with_wait(const double timeout) + //! + // \param timeout Timeout in seconds + inline bool claim_with_wait(const double timeout) { - if (spin_wait_with_timeout(_locked, false, timeout)) { - _locked = true; - return true; + const auto exit_time = std::chrono::high_resolution_clock::now() + + std::chrono::microseconds(int64_t(timeout * 1e6)); + // Try acquiring lock until successful or timeout + while (_locked.test_and_set(std::memory_order_acquire)) { + if (std::chrono::high_resolution_clock::now() > exit_time) { + return false; + } + std::this_thread::yield(); } - return false; + return true; } private: - std::atomic<bool> _locked; + std::atomic_flag _locked; }; } // namespace uhd |