UHD  003.005.000-0-g5cb9779d
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 
86  UHD_INLINE void wait(void){
87  _count.dec();
88  _count.cas(_size, 0);
89  while (_count.read() != _size){
90  boost::this_thread::interruption_point();
91  boost::this_thread::yield();
92  }
93  }
94 
95  private:
96  size_t _size;
97  atomic_uint32_t _count;
98  };
99 
108  atomic_uint32_t &cond,
109  boost::uint32_t value,
110  const double timeout
111  ){
112  if (cond.read() == value) return true;
113  const time_spec_t exit_time = time_spec_t::get_system_time() + time_spec_t(timeout);
114  while (cond.read() != value){
115  if (time_spec_t::get_system_time() > exit_time) return false;
116  boost::this_thread::interruption_point();
117  boost::this_thread::yield();
118  }
119  return true;
120  }
121 
127  public:
129  this->release();
130  }
131 
132  UHD_INLINE void release(void){
133  _locked.write(0);
134  }
135 
136  UHD_INLINE bool claim_with_wait(const double timeout){
137  if (spin_wait_with_timeout(_locked, 0, timeout)){
138  _locked.write(1);
139  return true;
140  }
141  return false;
142  }
143 
144  private:
145  atomic_uint32_t _locked;
146  };
147 
148 } //namespace uhd
149 
150 #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:86
UHD_INLINE void release(void)
Definition: atomic.hpp:132
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:107
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:136
#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:128
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:126