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