diff options
-rw-r--r-- | host/include/uhd/utils/atomic.hpp | 67 | ||||
-rw-r--r-- | host/lib/usrp/common/recv_packet_demuxer_3000.hpp | 8 | ||||
-rw-r--r-- | host/lib/usrp/e300/e300_fifo_config.cpp | 15 |
3 files changed, 28 insertions, 62 deletions
diff --git a/host/include/uhd/utils/atomic.hpp b/host/include/uhd/utils/atomic.hpp index f37fb4395..d75a60c3b 100644 --- a/host/include/uhd/utils/atomic.hpp +++ b/host/include/uhd/utils/atomic.hpp @@ -1,5 +1,5 @@ // -// Copyright 2012-2013,2016 Ettus Research LLC +// Copyright 2012-2013,2016-2017 Ettus Research LLC // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -21,52 +21,10 @@ #include <uhd/config.hpp> #include <uhd/types/time_spec.hpp> #include <boost/thread/thread.hpp> -#include <boost/thread/mutex.hpp> -#include <boost/thread/condition_variable.hpp> -#include <boost/interprocess/detail/atomic.hpp> - -#include <boost/version.hpp> -#define BOOST_IPC_DETAIL boost::interprocess::ipcdetail +#include <atomic> namespace uhd{ - //! A 32-bit integer that can be atomically accessed - class UHD_API atomic_uint32_t{ - public: - - //! Create a new atomic 32-bit integer, initialized to zero - UHD_INLINE atomic_uint32_t(void){ - this->write(0); - } - - //! Compare with cmp, swap with newval if same, return old value - UHD_INLINE uint32_t cas(uint32_t newval, uint32_t cmp){ - return BOOST_IPC_DETAIL::atomic_cas32(&_num, newval, cmp); - } - - //! Sets the atomic integer to a new value - UHD_INLINE void write(const uint32_t newval){ - BOOST_IPC_DETAIL::atomic_write32(&_num, newval); - } - - //! Gets the current value of the atomic integer - UHD_INLINE uint32_t read(void){ - return BOOST_IPC_DETAIL::atomic_read32(&_num); - } - - //! Increment by 1 and return the old value - UHD_INLINE uint32_t inc(void){ - return BOOST_IPC_DETAIL::atomic_inc32(&_num); - } - - //! Decrement by 1 and return the old value - UHD_INLINE uint32_t dec(void){ - return BOOST_IPC_DETAIL::atomic_dec32(&_num); - } - - private: volatile uint32_t _num; - }; - /*! * Spin-wait on a condition with a timeout. * \param cond an atomic variable to compare @@ -74,15 +32,18 @@ namespace uhd{ * \param timeout the timeout in seconds * \return true for cond == value, false for timeout */ + template<typename T> UHD_INLINE bool spin_wait_with_timeout( - atomic_uint32_t &cond, - uint32_t value, + std::atomic<T> &cond, + const T value, const double timeout ){ - if (cond.read() == value) return true; + if (cond == value) return true; const time_spec_t exit_time = time_spec_t::get_system_time() + time_spec_t(timeout); - while (cond.read() != value){ - if (time_spec_t::get_system_time() > exit_time) return false; + while (cond != value) { + if (time_spec_t::get_system_time() > exit_time) { + return false; + } boost::this_thread::interruption_point(); boost::this_thread::yield(); } @@ -100,19 +61,19 @@ namespace uhd{ } UHD_INLINE void release(void){ - _locked.write(0); + _locked = false; } UHD_INLINE bool claim_with_wait(const double timeout){ - if (spin_wait_with_timeout(_locked, 0, timeout)){ - _locked.write(1); + if (spin_wait_with_timeout(_locked, false, timeout)){ + _locked = true; return true; } return false; } private: - atomic_uint32_t _locked; + std::atomic<bool> _locked; }; } //namespace uhd diff --git a/host/lib/usrp/common/recv_packet_demuxer_3000.hpp b/host/lib/usrp/common/recv_packet_demuxer_3000.hpp index a970e81a5..2fe534c03 100644 --- a/host/lib/usrp/common/recv_packet_demuxer_3000.hpp +++ b/host/lib/usrp/common/recv_packet_demuxer_3000.hpp @@ -1,5 +1,5 @@ // -// Copyright 2013 Ettus Research LLC +// Copyright 2013,2017 Ettus Research LLC // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -84,7 +84,7 @@ namespace uhd{ namespace usrp{ //---------------------------------------------------------- //-- Try to claim the transport or wait patiently //---------------------------------------------------------- - if (_claimed.cas(1, 0)) + if (_claimed.exchange(true)) { boost::mutex::scoped_lock l(mutex); cond.timed_wait(l, boost::posix_time::microseconds(long(timeout*1e6))); @@ -111,7 +111,7 @@ namespace uhd{ namespace usrp{ } } #ifdef RECV_PACKET_DEMUXER_3000_THREAD_SAFE - _claimed.write(0); + _claimed = false; cond.notify_all(); #endif // RECV_PACKET_DEMUXER_3000_THREAD_SAFE } @@ -133,7 +133,7 @@ namespace uhd{ namespace usrp{ std::map<uint32_t, queue_type_t> _queues; transport::zero_copy_if::sptr _xport; #ifdef RECV_PACKET_DEMUXER_3000_THREAD_SAFE - uhd::atomic_uint32_t _claimed; + std::atomic_bool _claimed; boost::condition_variable cond; #endif // RECV_PACKET_DEMUXER_3000_THREAD_SAFE boost::mutex mutex; diff --git a/host/lib/usrp/e300/e300_fifo_config.cpp b/host/lib/usrp/e300/e300_fifo_config.cpp index 3d0f0d497..556e19120 100644 --- a/host/lib/usrp/e300/e300_fifo_config.cpp +++ b/host/lib/usrp/e300/e300_fifo_config.cpp @@ -1,5 +1,5 @@ // -// Copyright 2013-2014 Ettus Research LLC +// Copyright 2013-2017 Ettus Research LLC // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -17,8 +17,9 @@ #ifdef E300_NATIVE -#include <stdint.h> #include <uhd/config.hpp> +#include <stdint.h> +#include <atomic> // constants coded into the fpga parameters static const size_t ZF_CONFIG_BASE = 0x40000000; @@ -100,9 +101,13 @@ struct e300_fifo_poll_waiter //NOP } + /*! + * Waits until the file descriptor fd has data to read. + * Access to the file descriptor is thread safe. + */ void wait(const double timeout) { - if (_poll_claimed.cas(1, 0)) + if (_poll_claimed.exchange(true)) { boost::mutex::scoped_lock l(mutex); cond.wait(l); @@ -116,12 +121,12 @@ struct e300_fifo_poll_waiter if (fds[0].revents & POLLIN) ::read(fd, NULL, 0); - _poll_claimed.write(0); + _poll_claimed = false; cond.notify_all(); } } - uhd::atomic_uint32_t _poll_claimed; + std::atomic_bool _poll_claimed; boost::condition_variable cond; boost::mutex mutex; int fd; |