From 9dec0b7e8b6bec2350994eef5980234e76f8fc67 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Mon, 2 Jul 2012 10:56:39 -0700 Subject: uhd: added header with misc atomic wrappers --- host/include/uhd/utils/CMakeLists.txt | 3 +- host/include/uhd/utils/atomic.hpp | 143 ++++++++++++++++++++++++++++++++++ 2 files changed, 145 insertions(+), 1 deletion(-) create mode 100644 host/include/uhd/utils/atomic.hpp (limited to 'host/include') diff --git a/host/include/uhd/utils/CMakeLists.txt b/host/include/uhd/utils/CMakeLists.txt index 5a434fd9a..de91993fe 100644 --- a/host/include/uhd/utils/CMakeLists.txt +++ b/host/include/uhd/utils/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2010-2011 Ettus Research LLC +# Copyright 2010-2012 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 @@ -19,6 +19,7 @@ INSTALL(FILES algorithm.hpp assert_has.hpp assert_has.ipp + atomic.hpp byteswap.hpp byteswap.ipp csv.hpp diff --git a/host/include/uhd/utils/atomic.hpp b/host/include/uhd/utils/atomic.hpp new file mode 100644 index 000000000..f9bc728cc --- /dev/null +++ b/host/include/uhd/utils/atomic.hpp @@ -0,0 +1,143 @@ +// +// Copyright 2012 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 +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// + +#ifndef INCLUDED_UHD_UTILS_ATOMIC_HPP +#define INCLUDED_UHD_UTILS_ATOMIC_HPP + +#include +#include +#include +#include + +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 boost::uint32_t cas(boost::uint32_t newval, boost::uint32_t cmp){ + return boost::interprocess::detail::atomic_cas32(&_num, newval, cmp); + } + + //! Sets the atomic integer to a new value + UHD_INLINE void write(const boost::uint32_t newval){ + boost::interprocess::detail::atomic_write32(&_num, newval); + } + + //! Gets the current value of the atomic integer + UHD_INLINE boost::uint32_t read(void){ + return boost::interprocess::detail::atomic_read32(&_num); + } + + //! Increment by 1 and return the old value + UHD_INLINE boost::uint32_t inc(void){ + return boost::interprocess::detail::atomic_inc32(&_num); + } + + //! Decrement by 1 and return the old value + UHD_INLINE boost::uint32_t dec(void){ + return boost::interprocess::detail::atomic_dec32(&_num); + } + + private: volatile boost::uint32_t _num; + }; + + /*! + * A reusable barrier to sync multiple threads. + * All threads spin on wait() until count is reset. + */ + class UHD_API reusable_barrier{ + public: + + //! Resize the barrier for N threads + void resize(const size_t size){ + _size = size; + _count.write(size); + } + + //! Wait on the barrier condition + UHD_INLINE void wait(void){ + _count.dec(); + _count.cas(_size, 0); + while (_count.read() != _size){ + boost::this_thread::interruption_point(); + boost::this_thread::yield(); + } + } + + private: + size_t _size; + atomic_uint32_t _count; + }; + + /*! + * 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 + */ + UHD_INLINE bool spin_wait_with_timeout( + atomic_uint32_t &cond, + boost::uint32_t value, + const double timeout + ){ + if (cond.read() == 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; + boost::this_thread::interruption_point(); + boost::this_thread::yield(); + } + return true; + } + + /*! + * Claimer class to provide synchronization for multi-thread access. + * Claiming enables buffer classes to be used with a buffer queue. + */ + class simple_claimer{ + public: + simple_claimer(void){ + this->release(); + } + + UHD_INLINE void release(void){ + _locked.write(0); + } + + UHD_INLINE bool claim_with_wait(const double timeout){ + if (spin_wait_with_timeout(_locked, 0, timeout)){ + _locked.write(1); + return true; + } + return false; + } + + private: + atomic_uint32_t _locked; + }; + +} //namespace uhd + +#endif /* INCLUDED_UHD_UTILS_ATOMIC_HPP */ -- cgit v1.2.3 From d61c9b29b357579aa41928c225d137645144e20d Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 4 Jul 2012 13:40:19 -0700 Subject: uhd: make range_t a lightweight object --- host/include/uhd/types/ranges.hpp | 5 ++--- host/include/uhd/version.hpp | 2 +- host/lib/types/ranges.cpp | 21 ++++++--------------- 3 files changed, 9 insertions(+), 19 deletions(-) (limited to 'host/include') diff --git a/host/include/uhd/types/ranges.hpp b/host/include/uhd/types/ranges.hpp index f0d0e1c0b..ac632df93 100644 --- a/host/include/uhd/types/ranges.hpp +++ b/host/include/uhd/types/ranges.hpp @@ -1,5 +1,5 @@ // -// Copyright 2010-2011 Ettus Research LLC +// Copyright 2010-2012 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 @@ -19,7 +19,6 @@ #define INCLUDED_UHD_TYPES_RANGES_HPP #include -#include #include #include @@ -60,7 +59,7 @@ namespace uhd{ //! Convert this range to a printable string const std::string to_pp_string(void) const; - private: UHD_PIMPL_DECL(impl) _impl; + private: double _start, _stop, _step; }; /*! diff --git a/host/include/uhd/version.hpp b/host/include/uhd/version.hpp index 09d0e55fd..ec017ee32 100644 --- a/host/include/uhd/version.hpp +++ b/host/include/uhd/version.hpp @@ -27,7 +27,7 @@ * The format is oldest ABI compatible release - ABI compat number. * The compatibility number allows pre-release ABI to be versioned. */ -#define UHD_VERSION_ABI_STRING "3.4.0-2" +#define UHD_VERSION_ABI_STRING "3.4.0-3" namespace uhd{ diff --git a/host/lib/types/ranges.cpp b/host/lib/types/ranges.cpp index 6e39bc688..82a9a84e1 100644 --- a/host/lib/types/ranges.cpp +++ b/host/lib/types/ranges.cpp @@ -1,5 +1,5 @@ // -// Copyright 2011-2011 Ettus Research LLC +// Copyright 2011-2012 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 @@ -27,17 +27,8 @@ using namespace uhd; /*********************************************************************** * range_t implementation code **********************************************************************/ -struct range_t::impl{ - impl(double start, double stop, double step): - start(start), stop(stop), step(step) - { - /* NOP */ - } - double start, stop, step; -}; - range_t::range_t(double value): - _impl(UHD_PIMPL_MAKE(impl, (value, value, 0))) + _start(value), _stop(value), _step(0.0) { /* NOP */ } @@ -45,7 +36,7 @@ range_t::range_t(double value): range_t::range_t( double start, double stop, double step ): - _impl(UHD_PIMPL_MAKE(impl, (start, stop, step))) + _start(start), _stop(stop), _step(step) { if (stop < start){ throw uhd::value_error("cannot make range where stop < start"); @@ -53,15 +44,15 @@ range_t::range_t( } double range_t::start(void) const{ - return _impl->start; + return _start; } double range_t::stop(void) const{ - return _impl->stop; + return _stop; } double range_t::step(void) const{ - return _impl->step; + return _step; } const std::string range_t::to_pp_string(void) const{ -- cgit v1.2.3 From b9bd6a2167d818b1db1271a8e9d195bff2f91250 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 8 Aug 2012 18:17:49 -0700 Subject: uhd: special case boost versions for ipc namespace --- host/include/uhd/utils/atomic.hpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'host/include') diff --git a/host/include/uhd/utils/atomic.hpp b/host/include/uhd/utils/atomic.hpp index f9bc728cc..b12dde58e 100644 --- a/host/include/uhd/utils/atomic.hpp +++ b/host/include/uhd/utils/atomic.hpp @@ -23,6 +23,12 @@ #include #include +#if BOOST_VERSION >= 104800 +# define BOOST_IPC_DETAIL boost::interprocess::ipcdetail +#else +# define BOOST_IPC_DETAIL boost::interprocess::detail +#endif + namespace uhd{ //! A 32-bit integer that can be atomically accessed @@ -36,27 +42,27 @@ namespace uhd{ //! Compare with cmp, swap with newval if same, return old value UHD_INLINE boost::uint32_t cas(boost::uint32_t newval, boost::uint32_t cmp){ - return boost::interprocess::detail::atomic_cas32(&_num, newval, cmp); + return BOOST_IPC_DETAIL::atomic_cas32(&_num, newval, cmp); } //! Sets the atomic integer to a new value UHD_INLINE void write(const boost::uint32_t newval){ - boost::interprocess::detail::atomic_write32(&_num, newval); + BOOST_IPC_DETAIL::atomic_write32(&_num, newval); } //! Gets the current value of the atomic integer UHD_INLINE boost::uint32_t read(void){ - return boost::interprocess::detail::atomic_read32(&_num); + return BOOST_IPC_DETAIL::atomic_read32(&_num); } //! Increment by 1 and return the old value UHD_INLINE boost::uint32_t inc(void){ - return boost::interprocess::detail::atomic_inc32(&_num); + return BOOST_IPC_DETAIL::atomic_inc32(&_num); } //! Decrement by 1 and return the old value UHD_INLINE boost::uint32_t dec(void){ - return boost::interprocess::detail::atomic_dec32(&_num); + return BOOST_IPC_DETAIL::atomic_dec32(&_num); } private: volatile boost::uint32_t _num; -- cgit v1.2.3 From 36a7def9aa6cecaa6f3cbf9979544d6fd5848a08 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 30 Aug 2012 11:05:04 -0700 Subject: uhd: added boost version header to define BOOST_VERSION --- host/include/uhd/utils/atomic.hpp | 1 + 1 file changed, 1 insertion(+) (limited to 'host/include') diff --git a/host/include/uhd/utils/atomic.hpp b/host/include/uhd/utils/atomic.hpp index b12dde58e..dc1790c3f 100644 --- a/host/include/uhd/utils/atomic.hpp +++ b/host/include/uhd/utils/atomic.hpp @@ -23,6 +23,7 @@ #include #include +#include #if BOOST_VERSION >= 104800 # define BOOST_IPC_DETAIL boost::interprocess::ipcdetail #else -- cgit v1.2.3