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