UHD  003.005.002-0-g0cce80c1
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
atomic.hpp
Go to the documentation of this file.
1 //
2 // Copyright 2012 Ettus Research LLC
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16 //
17 
18 #ifndef INCLUDED_UHD_UTILS_ATOMIC_HPP
19 #define INCLUDED_UHD_UTILS_ATOMIC_HPP
20 
21 #include <uhd/config.hpp>
22 #include <uhd/types/time_spec.hpp>
23 #include <boost/thread/thread.hpp>
24 #include <boost/interprocess/detail/atomic.hpp>
25 
26 #include <boost/version.hpp>
27 #if BOOST_VERSION >= 104800
28 # define BOOST_IPC_DETAIL boost::interprocess::ipcdetail
29 #else
30 # define BOOST_IPC_DETAIL boost::interprocess::detail
31 #endif
32 
33 namespace uhd{
34 
37  public:
38 
41  this->write(0);
42  }
43 
45  UHD_INLINE boost::uint32_t cas(boost::uint32_t newval, boost::uint32_t cmp){
46  return BOOST_IPC_DETAIL::atomic_cas32(&_num, newval, cmp);
47  }
48 
50  UHD_INLINE void write(const boost::uint32_t newval){
51  BOOST_IPC_DETAIL::atomic_write32(&_num, newval);
52  }
53 
55  UHD_INLINE boost::uint32_t read(void){
56  return BOOST_IPC_DETAIL::atomic_read32(&_num);
57  }
58 
60  UHD_INLINE boost::uint32_t inc(void){
61  return BOOST_IPC_DETAIL::atomic_inc32(&_num);
62  }
63 
65  UHD_INLINE boost::uint32_t dec(void){
66  return BOOST_IPC_DETAIL::atomic_dec32(&_num);
67  }
68 
69  private: volatile boost::uint32_t _num;
70  };
71 
77  public:
78 
80  void resize(const size_t size){
81  _size = size;
82  _count.write(size);
83  }
84 
89  void interrupt(void)
90  {
91  _count.write(boost::uint32_t(~0));
92  }
93 
95  UHD_INLINE void wait(void){
96  _count.dec();
97  _count.cas(_size, 0);
98  while (_count.read() != _size){
99  boost::this_thread::interruption_point();
100  if (_count.read() == boost::uint32_t(~0))
101  throw boost::thread_interrupted();
102  boost::this_thread::yield();
103  }
104  }
105 
106  private:
107  size_t _size;
108  atomic_uint32_t _count;
109  };
110 
119  atomic_uint32_t &cond,
120  boost::uint32_t value,
121  const double timeout
122  ){
123  if (cond.read() == value) return true;
124  const time_spec_t exit_time = time_spec_t::get_system_time() + time_spec_t(timeout);
125  while (cond.read() != value){
126  if (time_spec_t::get_system_time() > exit_time) return false;
127  boost::this_thread::interruption_point();
128  boost::this_thread::yield();
129  }
130  return true;
131  }
132 
138  public:
140  this->release();
141  }
142 
143  UHD_INLINE void release(void){
144  _locked.write(0);
145  }
146 
147  UHD_INLINE bool claim_with_wait(const double timeout){
148  if (spin_wait_with_timeout(_locked, 0, timeout)){
149  _locked.write(1);
150  return true;
151  }
152  return false;
153  }
154 
155  private:
156  atomic_uint32_t _locked;
157  };
158 
159 } //namespace uhd
160 
161 #endif /* INCLUDED_UHD_UTILS_ATOMIC_HPP */
UHD_INLINE boost::uint32_t read(void)
Gets the current value of the atomic integer.
Definition: atomic.hpp:55
UHD_INLINE void wait(void)
Wait on the barrier condition.
Definition: atomic.hpp:95
UHD_INLINE void release(void)
Definition: atomic.hpp:143
Definition: atomic.hpp:76
Definition: time_spec.hpp:39
A 32-bit integer that can be atomically accessed.
Definition: atomic.hpp:36
UHD_INLINE bool spin_wait_with_timeout(atomic_uint32_t &cond, boost::uint32_t value, const double timeout)
Definition: atomic.hpp:118
static time_spec_t get_system_time(void)
#define UHD_API
Definition: config.hpp:76
Definition: convert.hpp:28
UHD_INLINE boost::uint32_t cas(boost::uint32_t newval, boost::uint32_t cmp)
Compare with cmp, swap with newval if same, return old value.
Definition: atomic.hpp:45
UHD_INLINE bool claim_with_wait(const double timeout)
Definition: atomic.hpp:147
#define UHD_INLINE
Definition: config.hpp:67
UHD_INLINE atomic_uint32_t(void)
Create a new atomic 32-bit integer, initialized to zero.
Definition: atomic.hpp:40
UHD_INLINE void write(const boost::uint32_t newval)
Sets the atomic integer to a new value.
Definition: atomic.hpp:50
UHD_INLINE boost::uint32_t inc(void)
Increment by 1 and return the old value.
Definition: atomic.hpp:60
simple_claimer(void)
Definition: atomic.hpp:139
UHD_INLINE boost::uint32_t dec(void)
Decrement by 1 and return the old value.
Definition: atomic.hpp:65
void resize(const size_t size)
Resize the barrier for N threads.
Definition: atomic.hpp:80
Definition: atomic.hpp:137
void interrupt(void)
Definition: atomic.hpp:89