UHD 003.005.002-0-unknown

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

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
36 class UHD_API atomic_uint32_t{
37 public:
38
40 UHD_INLINE atomic_uint32_t(void){
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
76 class UHD_API reusable_barrier{
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
118 UHD_INLINE bool spin_wait_with_timeout(
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
137 class simple_claimer{
138 public:
139 simple_claimer(void){
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::atomic_uint32_t::read
UHD_INLINE boost::uint32_t read(void)
Gets the current value of the atomic integer.
Definition: atomic.hpp:55
uhd::reusable_barrier::wait
UHD_INLINE void wait(void)
Wait on the barrier condition.
Definition: atomic.hpp:95
uhd::simple_claimer::release
UHD_INLINE void release(void)
Definition: atomic.hpp:143
uhd::reusable_barrier
Definition: atomic.hpp:76
uhd::time_spec_t
Definition: time_spec.hpp:39
uhd::atomic_uint32_t
A 32-bit integer that can be atomically accessed.
Definition: atomic.hpp:36
config.hpp
uhd::spin_wait_with_timeout
UHD_INLINE bool spin_wait_with_timeout(atomic_uint32_t &cond, boost::uint32_t value, const double timeout)
Definition: atomic.hpp:118
uhd::time_spec_t::get_system_time
static time_spec_t get_system_time(void)
UHD_API
#define UHD_API
Definition: config.hpp:76
uhd::atomic_uint32_t::cas
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::simple_claimer::claim_with_wait
UHD_INLINE bool claim_with_wait(const double timeout)
Definition: atomic.hpp:147
UHD_INLINE
#define UHD_INLINE
Definition: config.hpp:67
uhd::atomic_uint32_t::atomic_uint32_t
UHD_INLINE atomic_uint32_t(void)
Create a new atomic 32-bit integer, initialized to zero.
Definition: atomic.hpp:40
uhd::atomic_uint32_t::write
UHD_INLINE void write(const boost::uint32_t newval)
Sets the atomic integer to a new value.
Definition: atomic.hpp:50
time_spec.hpp
uhd::atomic_uint32_t::inc
UHD_INLINE boost::uint32_t inc(void)
Increment by 1 and return the old value.
Definition: atomic.hpp:60
uhd::simple_claimer::simple_claimer
simple_claimer(void)
Definition: atomic.hpp:139
uhd::atomic_uint32_t::dec
UHD_INLINE boost::uint32_t dec(void)
Decrement by 1 and return the old value.
Definition: atomic.hpp:65
uhd::reusable_barrier::resize
void resize(const size_t size)
Resize the barrier for N threads.
Definition: atomic.hpp:80
uhd::simple_claimer
Definition: atomic.hpp:137
uhd::reusable_barrier::interrupt
void interrupt(void)
Definition: atomic.hpp:89