Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/thread/pthread/thread_data.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 #ifndef BOOST_THREAD_PTHREAD_THREAD_DATA_HPP | |
2 #define BOOST_THREAD_PTHREAD_THREAD_DATA_HPP | |
3 // Distributed under the Boost Software License, Version 1.0. (See | |
4 // accompanying file LICENSE_1_0.txt or copy at | |
5 // http://www.boost.org/LICENSE_1_0.txt) | |
6 // (C) Copyright 2007 Anthony Williams | |
7 // (C) Copyright 2011-2012 Vicente J. Botet Escriba | |
8 | |
9 #include <boost/thread/detail/config.hpp> | |
10 #include <boost/thread/exceptions.hpp> | |
11 #include <boost/thread/lock_guard.hpp> | |
12 #include <boost/thread/lock_types.hpp> | |
13 #include <boost/thread/mutex.hpp> | |
14 #include <boost/thread/pthread/condition_variable_fwd.hpp> | |
15 | |
16 #include <boost/shared_ptr.hpp> | |
17 #include <boost/enable_shared_from_this.hpp> | |
18 #include <boost/optional.hpp> | |
19 #include <boost/assert.hpp> | |
20 #ifdef BOOST_THREAD_USES_CHRONO | |
21 #include <boost/chrono/system_clocks.hpp> | |
22 #endif | |
23 | |
24 #include <map> | |
25 #include <vector> | |
26 #include <utility> | |
27 | |
28 #if defined(__ANDROID__) | |
29 #include <asm/page.h> // http://code.google.com/p/android/issues/detail?id=39983 | |
30 #endif | |
31 | |
32 #include <pthread.h> | |
33 #include <unistd.h> | |
34 | |
35 #include <boost/config/abi_prefix.hpp> | |
36 | |
37 namespace boost | |
38 { | |
39 class thread_attributes { | |
40 public: | |
41 thread_attributes() BOOST_NOEXCEPT { | |
42 int res = pthread_attr_init(&val_); | |
43 BOOST_VERIFY(!res && "pthread_attr_init failed"); | |
44 } | |
45 ~thread_attributes() { | |
46 int res = pthread_attr_destroy(&val_); | |
47 BOOST_VERIFY(!res && "pthread_attr_destroy failed"); | |
48 } | |
49 // stack | |
50 void set_stack_size(std::size_t size) BOOST_NOEXCEPT { | |
51 if (size==0) return; | |
52 std::size_t page_size = getpagesize(); | |
53 #ifdef PTHREAD_STACK_MIN | |
54 if (size<PTHREAD_STACK_MIN) size=PTHREAD_STACK_MIN; | |
55 #endif | |
56 size = ((size+page_size-1)/page_size)*page_size; | |
57 int res = pthread_attr_setstacksize(&val_, size); | |
58 BOOST_VERIFY(!res && "pthread_attr_setstacksize failed"); | |
59 } | |
60 | |
61 std::size_t get_stack_size() const BOOST_NOEXCEPT { | |
62 std::size_t size; | |
63 int res = pthread_attr_getstacksize(&val_, &size); | |
64 BOOST_VERIFY(!res && "pthread_attr_getstacksize failed"); | |
65 return size; | |
66 } | |
67 #define BOOST_THREAD_DEFINES_THREAD_ATTRIBUTES_NATIVE_HANDLE | |
68 | |
69 typedef pthread_attr_t native_handle_type; | |
70 native_handle_type* native_handle() BOOST_NOEXCEPT { | |
71 return &val_; | |
72 } | |
73 const native_handle_type* native_handle() const BOOST_NOEXCEPT { | |
74 return &val_; | |
75 } | |
76 | |
77 private: | |
78 pthread_attr_t val_; | |
79 }; | |
80 | |
81 class thread; | |
82 | |
83 namespace detail | |
84 { | |
85 struct shared_state_base; | |
86 struct tss_cleanup_function; | |
87 struct thread_exit_callback_node; | |
88 struct tss_data_node | |
89 { | |
90 boost::shared_ptr<boost::detail::tss_cleanup_function> func; | |
91 void* value; | |
92 | |
93 tss_data_node(boost::shared_ptr<boost::detail::tss_cleanup_function> func_, | |
94 void* value_): | |
95 func(func_),value(value_) | |
96 {} | |
97 }; | |
98 | |
99 struct thread_data_base; | |
100 typedef boost::shared_ptr<thread_data_base> thread_data_ptr; | |
101 | |
102 struct BOOST_THREAD_DECL thread_data_base: | |
103 enable_shared_from_this<thread_data_base> | |
104 { | |
105 thread_data_ptr self; | |
106 pthread_t thread_handle; | |
107 boost::mutex data_mutex; | |
108 boost::condition_variable done_condition; | |
109 boost::mutex sleep_mutex; | |
110 boost::condition_variable sleep_condition; | |
111 bool done; | |
112 bool join_started; | |
113 bool joined; | |
114 boost::detail::thread_exit_callback_node* thread_exit_callbacks; | |
115 std::map<void const*,boost::detail::tss_data_node> tss_data; | |
116 | |
117 pthread_mutex_t* cond_mutex; | |
118 pthread_cond_t* current_cond; | |
119 typedef std::vector<std::pair<condition_variable*, mutex*> | |
120 //, hidden_allocator<std::pair<condition_variable*, mutex*> > | |
121 > notify_list_t; | |
122 notify_list_t notify; | |
123 | |
124 typedef std::vector<shared_ptr<shared_state_base> > async_states_t; | |
125 async_states_t async_states_; | |
126 | |
127 //#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS | |
128 // These data must be at the end so that the access to the other fields doesn't change | |
129 // when BOOST_THREAD_PROVIDES_INTERRUPTIONS is defined. | |
130 // Another option is to have them always | |
131 bool interrupt_enabled; | |
132 bool interrupt_requested; | |
133 //#endif | |
134 thread_data_base(): | |
135 thread_handle(0), | |
136 done(false),join_started(false),joined(false), | |
137 thread_exit_callbacks(0), | |
138 cond_mutex(0), | |
139 current_cond(0), | |
140 notify(), | |
141 async_states_() | |
142 //#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS | |
143 , interrupt_enabled(true) | |
144 , interrupt_requested(false) | |
145 //#endif | |
146 {} | |
147 virtual ~thread_data_base(); | |
148 | |
149 typedef pthread_t native_handle_type; | |
150 | |
151 virtual void run()=0; | |
152 virtual void notify_all_at_thread_exit(condition_variable* cv, mutex* m) | |
153 { | |
154 notify.push_back(std::pair<condition_variable*, mutex*>(cv, m)); | |
155 } | |
156 | |
157 void make_ready_at_thread_exit(shared_ptr<shared_state_base> as) | |
158 { | |
159 async_states_.push_back(as); | |
160 } | |
161 | |
162 }; | |
163 | |
164 BOOST_THREAD_DECL thread_data_base* get_current_thread_data(); | |
165 | |
166 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS | |
167 class interruption_checker | |
168 { | |
169 thread_data_base* const thread_info; | |
170 pthread_mutex_t* m; | |
171 bool set; | |
172 | |
173 void check_for_interruption() | |
174 { | |
175 #ifndef BOOST_NO_EXCEPTIONS | |
176 if(thread_info->interrupt_requested) | |
177 { | |
178 thread_info->interrupt_requested=false; | |
179 throw thread_interrupted(); // BOOST_NO_EXCEPTIONS protected | |
180 } | |
181 #endif | |
182 } | |
183 | |
184 void operator=(interruption_checker&); | |
185 public: | |
186 explicit interruption_checker(pthread_mutex_t* cond_mutex,pthread_cond_t* cond): | |
187 thread_info(detail::get_current_thread_data()),m(cond_mutex), | |
188 set(thread_info && thread_info->interrupt_enabled) | |
189 { | |
190 if(set) | |
191 { | |
192 lock_guard<mutex> guard(thread_info->data_mutex); | |
193 check_for_interruption(); | |
194 thread_info->cond_mutex=cond_mutex; | |
195 thread_info->current_cond=cond; | |
196 BOOST_VERIFY(!pthread_mutex_lock(m)); | |
197 } | |
198 else | |
199 { | |
200 BOOST_VERIFY(!pthread_mutex_lock(m)); | |
201 } | |
202 } | |
203 ~interruption_checker() | |
204 { | |
205 if(set) | |
206 { | |
207 BOOST_VERIFY(!pthread_mutex_unlock(m)); | |
208 lock_guard<mutex> guard(thread_info->data_mutex); | |
209 thread_info->cond_mutex=NULL; | |
210 thread_info->current_cond=NULL; | |
211 } | |
212 else | |
213 { | |
214 BOOST_VERIFY(!pthread_mutex_unlock(m)); | |
215 } | |
216 } | |
217 }; | |
218 #endif | |
219 } | |
220 | |
221 namespace this_thread | |
222 { | |
223 namespace hiden | |
224 { | |
225 void BOOST_THREAD_DECL sleep_for(const timespec& ts); | |
226 void BOOST_THREAD_DECL sleep_until(const timespec& ts); | |
227 } | |
228 | |
229 #ifdef BOOST_THREAD_USES_CHRONO | |
230 #ifdef BOOST_THREAD_SLEEP_FOR_IS_STEADY | |
231 | |
232 inline | |
233 void BOOST_SYMBOL_VISIBLE sleep_for(const chrono::nanoseconds& ns) | |
234 { | |
235 return boost::this_thread::hiden::sleep_for(boost::detail::to_timespec(ns)); | |
236 } | |
237 #endif | |
238 #endif // BOOST_THREAD_USES_CHRONO | |
239 | |
240 void BOOST_THREAD_DECL yield() BOOST_NOEXCEPT; | |
241 | |
242 #if defined BOOST_THREAD_USES_DATETIME | |
243 #ifdef __DECXXX | |
244 /// Workaround of DECCXX issue of incorrect template substitution | |
245 template<> | |
246 #endif | |
247 inline void sleep(system_time const& abs_time) | |
248 { | |
249 return boost::this_thread::hiden::sleep_until(boost::detail::to_timespec(abs_time)); | |
250 } | |
251 | |
252 template<typename TimeDuration> | |
253 inline BOOST_SYMBOL_VISIBLE void sleep(TimeDuration const& rel_time) | |
254 { | |
255 this_thread::sleep(get_system_time()+rel_time); | |
256 } | |
257 #endif // BOOST_THREAD_USES_DATETIME | |
258 } // this_thread | |
259 } | |
260 | |
261 #include <boost/config/abi_suffix.hpp> | |
262 | |
263 #endif |