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/include | |
| 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/include')
| -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 | 
