comparison DEPENDENCIES/generic/include/boost/thread/barrier.hpp @ 16:2665513ce2d3

Add boost headers
author Chris Cannam
date Tue, 05 Aug 2014 11:11:38 +0100
parents
children c530137014c0
comparison
equal deleted inserted replaced
15:663ca0da4350 16:2665513ce2d3
1 // Copyright (C) 2002-2003
2 // David Moore, William E. Kempf
3 // Copyright (C) 2007-8 Anthony Williams
4 //
5 // Distributed under the Boost Software License, Version 1.0. (See accompanying
6 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7
8 #ifndef BOOST_BARRIER_JDM030602_HPP
9 #define BOOST_BARRIER_JDM030602_HPP
10
11 #include <boost/thread/detail/config.hpp>
12 #include <boost/thread/detail/delete.hpp>
13
14 #include <boost/throw_exception.hpp>
15 #include <boost/thread/mutex.hpp>
16 #include <boost/thread/lock_types.hpp>
17 #include <boost/thread/condition_variable.hpp>
18 #include <string>
19 #include <stdexcept>
20 #ifdef BOOST_NO_CXX11_HDR_FUNCTIONAL
21 #include <boost/function.hpp>
22 #else
23 #include <functional>
24 #endif
25 #include <boost/type_traits/is_same.hpp>
26 #include <boost/type_traits/is_void.hpp>
27 #include <boost/utility/enable_if.hpp>
28 #include <boost/utility/result_of.hpp>
29
30 #include <boost/config/abi_prefix.hpp>
31
32 namespace boost
33 {
34 namespace thread_detail
35 {
36 #ifdef BOOST_NO_CXX11_HDR_FUNCTIONAL
37 typedef function<void()> void_completion_function;
38 typedef function<size_t()> size_completion_function;
39 #else
40 typedef std::function<void()> void_completion_function;
41 typedef std::function<size_t()> size_completion_function;
42 #endif
43
44 struct default_barrier_reseter
45 {
46 unsigned int size_;
47 default_barrier_reseter(unsigned int size) :
48 size_(size)
49 {
50 }
51 unsigned int operator()()
52 {
53 return size_;
54 }
55 };
56
57 struct void_functor_barrier_reseter
58 {
59 unsigned int size_;
60 void_completion_function fct_;
61 template <typename F>
62 #ifndef BOOST_NO_CXX11_HDR_FUNCTIONAL
63 void_functor_barrier_reseter(unsigned int size, BOOST_THREAD_RV_REF(F) funct)
64 : size_(size), fct_(boost::move(funct))
65 {}
66 #else
67 void_functor_barrier_reseter(unsigned int size, F funct)
68 : size_(size), fct_(funct)
69 {}
70 #endif
71 unsigned int operator()()
72 {
73 fct_();
74 return size_;
75 }
76 };
77 struct void_fct_ptr_barrier_reseter
78 {
79 unsigned int size_;
80 void(*fct_)();
81 void_fct_ptr_barrier_reseter(unsigned int size, void(*funct)()) :
82 size_(size), fct_(funct)
83 {
84 }
85 unsigned int operator()()
86 {
87 fct_();
88 return size_;
89 }
90 };
91 }
92 class barrier
93 {
94 static inline unsigned int check_counter(unsigned int count)
95 {
96 if (count == 0) boost::throw_exception(
97 thread_exception(system::errc::invalid_argument, "barrier constructor: count cannot be zero."));
98 return count;
99 }
100 struct dummy
101 {
102 };
103
104 public:
105 BOOST_THREAD_NO_COPYABLE( barrier)
106
107 explicit barrier(unsigned int count) :
108 m_count(check_counter(count)), m_generation(0), fct_(thread_detail::default_barrier_reseter(count))
109 {
110 }
111
112 template <typename F>
113 barrier(
114 unsigned int count,
115 #ifndef BOOST_NO_CXX11_HDR_FUNCTIONAL
116 BOOST_THREAD_RV_REF(F) funct,
117 #else
118 F funct,
119 #endif
120 typename enable_if<
121 typename is_void<typename result_of<F>::type>::type, dummy*
122 >::type=0
123 )
124 : m_count(check_counter(count)),
125 m_generation(0),
126 fct_(thread_detail::void_functor_barrier_reseter(count,
127 #ifndef BOOST_NO_CXX11_HDR_FUNCTIONAL
128 boost::move(funct)
129 #else
130 funct
131 #endif
132 )
133 )
134 {
135 }
136
137 template <typename F>
138 barrier(
139 unsigned int count,
140 #ifndef BOOST_NO_CXX11_HDR_FUNCTIONAL
141 BOOST_THREAD_RV_REF(F) funct,
142 #else
143 F funct,
144 #endif
145 typename enable_if<
146 typename is_same<typename result_of<F>::type, unsigned int>::type, dummy*
147 >::type=0
148 )
149 : m_count(check_counter(count)),
150 m_generation(0),
151 fct_(
152 #ifndef BOOST_NO_CXX11_HDR_FUNCTIONAL
153 boost::move(funct)
154 #else
155 funct
156 #endif
157 )
158 {
159 }
160
161 barrier(unsigned int count, void(*funct)()) :
162 m_count(check_counter(count)), m_generation(0),
163 fct_(funct
164 ? thread_detail::size_completion_function(thread_detail::void_fct_ptr_barrier_reseter(count, funct))
165 : thread_detail::size_completion_function(thread_detail::default_barrier_reseter(count))
166 )
167 {
168 }
169 barrier(unsigned int count, unsigned int(*funct)()) :
170 m_count(check_counter(count)), m_generation(0),
171 fct_(funct
172 ? thread_detail::size_completion_function(funct)
173 : thread_detail::size_completion_function(thread_detail::default_barrier_reseter(count))
174 )
175 {
176 }
177
178 bool wait()
179 {
180 boost::unique_lock < boost::mutex > lock(m_mutex);
181 unsigned int gen = m_generation;
182
183 if (--m_count == 0)
184 {
185 m_generation++;
186 m_count = static_cast<unsigned int>(fct_());
187 BOOST_ASSERT(m_count != 0);
188 m_cond.notify_all();
189 return true;
190 }
191
192 while (gen == m_generation)
193 m_cond.wait(lock);
194 return false;
195 }
196
197 void count_down_and_wait()
198 {
199 wait();
200 }
201
202 private:
203 mutex m_mutex;
204 condition_variable m_cond;
205 unsigned int m_count;
206 unsigned int m_generation;
207 thread_detail::size_completion_function fct_;
208 };
209
210 } // namespace boost
211
212 #include <boost/config/abi_suffix.hpp>
213
214 #endif