annotate DEPENDENCIES/generic/include/boost/thread/pthread/thread_data.hpp @ 125:34e428693f5d vext

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