annotate DEPENDENCIES/generic/include/boost/interprocess/detail/os_thread_functions.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents c530137014c0
children
rev   line source
Chris@16 1 //////////////////////////////////////////////////////////////////////////////
Chris@16 2 //
Chris@16 3 // (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
Chris@16 4 // Software License, Version 1.0. (See accompanying file
Chris@16 5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Chris@16 6 //
Chris@16 7 // See http://www.boost.org/libs/interprocess for documentation.
Chris@16 8 //
Chris@16 9 //////////////////////////////////////////////////////////////////////////////
Chris@16 10
Chris@16 11 //Thread launching functions are adapted from boost/detail/lightweight_thread.hpp
Chris@16 12 //
Chris@16 13 // boost/detail/lightweight_thread.hpp
Chris@16 14 //
Chris@16 15 // Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
Chris@16 16 // Copyright (c) 2008 Peter Dimov
Chris@16 17 //
Chris@16 18 // Distributed under the Boost Software License, Version 1.0.
Chris@16 19 // See accompanying file LICENSE_1_0.txt or copy at
Chris@16 20 // http://www.boost.org/LICENSE_1_0.txt
Chris@16 21
Chris@16 22 #ifndef BOOST_INTERPROCESS_DETAIL_OS_THREAD_FUNCTIONS_HPP
Chris@16 23 #define BOOST_INTERPROCESS_DETAIL_OS_THREAD_FUNCTIONS_HPP
Chris@16 24
Chris@101 25 #ifndef BOOST_CONFIG_HPP
Chris@101 26 # include <boost/config.hpp>
Chris@101 27 #endif
Chris@101 28 #
Chris@101 29 #if defined(BOOST_HAS_PRAGMA_ONCE)
Chris@101 30 # pragma once
Chris@101 31 #endif
Chris@101 32
Chris@16 33 #include <boost/interprocess/detail/config_begin.hpp>
Chris@16 34 #include <boost/interprocess/detail/workaround.hpp>
Chris@16 35 #include <boost/interprocess/streams/bufferstream.hpp>
Chris@16 36 #include <boost/interprocess/detail/posix_time_types_wrk.hpp>
Chris@16 37 #include <cstddef>
Chris@101 38 #include <ostream>
Chris@16 39
Chris@16 40 #if defined(BOOST_INTERPROCESS_WINDOWS)
Chris@16 41 # include <boost/interprocess/detail/win32_api.hpp>
Chris@16 42 # include <process.h>
Chris@16 43 #else
Chris@16 44 # include <pthread.h>
Chris@16 45 # include <unistd.h>
Chris@16 46 # include <sched.h>
Chris@16 47 # include <time.h>
Chris@16 48 # ifdef BOOST_INTERPROCESS_BSD_DERIVATIVE
Chris@16 49 //Some *BSD systems (OpenBSD & NetBSD) need sys/param.h before sys/sysctl.h, whereas
Chris@16 50 //others (FreeBSD & Darwin) need sys/types.h
Chris@16 51 # include <sys/types.h>
Chris@16 52 # include <sys/param.h>
Chris@16 53 # include <sys/sysctl.h>
Chris@16 54 # endif
Chris@16 55 //According to the article "C/C++ tip: How to measure elapsed real time for benchmarking"
Chris@16 56 # if defined(CLOCK_MONOTONIC_PRECISE) //BSD
Chris@16 57 # define BOOST_INTERPROCESS_CLOCK_MONOTONIC CLOCK_MONOTONIC_PRECISE
Chris@16 58 # elif defined(CLOCK_MONOTONIC_RAW) //Linux
Chris@16 59 # define BOOST_INTERPROCESS_CLOCK_MONOTONIC CLOCK_MONOTONIC_RAW
Chris@16 60 # elif defined(CLOCK_HIGHRES) //Solaris
Chris@16 61 # define BOOST_INTERPROCESS_CLOCK_MONOTONIC CLOCK_HIGHRES
Chris@16 62 # elif defined(CLOCK_MONOTONIC) //POSIX (AIX, BSD, Linux, Solaris)
Chris@16 63 # define BOOST_INTERPROCESS_CLOCK_MONOTONIC CLOCK_MONOTONIC
Chris@16 64 # elif !defined(CLOCK_MONOTONIC) && (defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__))
Chris@16 65 # include <mach/mach_time.h> // mach_absolute_time, mach_timebase_info_data_t
Chris@16 66 # define BOOST_INTERPROCESS_MATCH_ABSOLUTE_TIME
Chris@16 67 # else
Chris@16 68 # error "No high resolution steady clock in your system, please provide a patch"
Chris@16 69 # endif
Chris@16 70 #endif
Chris@16 71
Chris@16 72 namespace boost {
Chris@16 73 namespace interprocess {
Chris@16 74 namespace ipcdetail{
Chris@16 75
Chris@101 76 #if defined (BOOST_INTERPROCESS_WINDOWS)
Chris@16 77
Chris@16 78 typedef unsigned long OS_process_id_t;
Chris@16 79 typedef unsigned long OS_thread_id_t;
Chris@16 80 typedef void* OS_thread_t;
Chris@16 81 typedef OS_thread_id_t OS_systemwide_thread_id_t;
Chris@16 82
Chris@16 83 //process
Chris@16 84 inline OS_process_id_t get_current_process_id()
Chris@16 85 { return winapi::get_current_process_id(); }
Chris@16 86
Chris@16 87 inline OS_process_id_t get_invalid_process_id()
Chris@16 88 { return OS_process_id_t(0); }
Chris@16 89
Chris@16 90 //thread
Chris@16 91 inline OS_thread_id_t get_current_thread_id()
Chris@16 92 { return winapi::get_current_thread_id(); }
Chris@16 93
Chris@16 94 inline OS_thread_id_t get_invalid_thread_id()
Chris@16 95 { return OS_thread_id_t(0xffffffff); }
Chris@16 96
Chris@16 97 inline bool equal_thread_id(OS_thread_id_t id1, OS_thread_id_t id2)
Chris@16 98 { return id1 == id2; }
Chris@16 99
Chris@16 100 //return the system tick in ns
Chris@16 101 inline unsigned long get_system_tick_ns()
Chris@16 102 {
Chris@16 103 unsigned long curres;
Chris@16 104 winapi::set_timer_resolution(10000, 0, &curres);
Chris@16 105 //Windows API returns the value in hundreds of ns
Chris@16 106 return (curres - 1ul)*100ul;
Chris@16 107 }
Chris@16 108
Chris@16 109 //return the system tick in us
Chris@16 110 inline unsigned long get_system_tick_us()
Chris@16 111 {
Chris@16 112 unsigned long curres;
Chris@16 113 winapi::set_timer_resolution(10000, 0, &curres);
Chris@16 114 //Windows API returns the value in hundreds of ns
Chris@16 115 return (curres - 1ul)/10ul + 1ul;
Chris@16 116 }
Chris@16 117
Chris@16 118 typedef unsigned __int64 OS_highres_count_t;
Chris@16 119
Chris@16 120 inline unsigned long get_system_tick_in_highres_counts()
Chris@16 121 {
Chris@16 122 __int64 freq;
Chris@16 123 unsigned long curres;
Chris@16 124 winapi::set_timer_resolution(10000, 0, &curres);
Chris@16 125 //Frequency in counts per second
Chris@16 126 if(!winapi::query_performance_frequency(&freq)){
Chris@16 127 //Tick resolution in ms
Chris@16 128 return (curres-1ul)/10000ul + 1ul;
Chris@16 129 }
Chris@16 130 else{
Chris@16 131 //In femtoseconds
Chris@16 132 __int64 count_fs = (1000000000000000LL - 1LL)/freq + 1LL;
Chris@16 133 __int64 tick_counts = (static_cast<__int64>(curres)*100000000LL - 1LL)/count_fs + 1LL;
Chris@16 134 return static_cast<unsigned long>(tick_counts);
Chris@16 135 }
Chris@16 136 }
Chris@16 137
Chris@16 138 inline OS_highres_count_t get_current_system_highres_count()
Chris@16 139 {
Chris@16 140 __int64 count;
Chris@16 141 if(!winapi::query_performance_counter(&count)){
Chris@16 142 count = winapi::get_tick_count();
Chris@16 143 }
Chris@16 144 return count;
Chris@16 145 }
Chris@16 146
Chris@16 147 inline void zero_highres_count(OS_highres_count_t &count)
Chris@16 148 { count = 0; }
Chris@16 149
Chris@16 150 inline bool is_highres_count_zero(const OS_highres_count_t &count)
Chris@16 151 { return count == 0; }
Chris@16 152
Chris@16 153 template <class Ostream>
Chris@16 154 inline Ostream &ostream_highres_count(Ostream &ostream, const OS_highres_count_t &count)
Chris@16 155 {
Chris@16 156 ostream << count;
Chris@16 157 return ostream;
Chris@16 158 }
Chris@16 159
Chris@16 160 inline OS_highres_count_t system_highres_count_subtract(const OS_highres_count_t &l, const OS_highres_count_t &r)
Chris@16 161 { return l - r; }
Chris@16 162
Chris@16 163 inline bool system_highres_count_less(const OS_highres_count_t &l, const OS_highres_count_t &r)
Chris@101 164 { return l < r; }
Chris@16 165
Chris@16 166 inline bool system_highres_count_less_ul(const OS_highres_count_t &l, unsigned long r)
Chris@16 167 { return l < static_cast<OS_highres_count_t>(r); }
Chris@16 168
Chris@16 169 inline void thread_sleep_tick()
Chris@16 170 { winapi::sleep_tick(); }
Chris@16 171
Chris@16 172 inline void thread_yield()
Chris@16 173 { winapi::sched_yield(); }
Chris@16 174
Chris@16 175 inline void thread_sleep(unsigned int ms)
Chris@101 176 { winapi::sleep(ms); }
Chris@16 177
Chris@16 178 //systemwide thread
Chris@16 179 inline OS_systemwide_thread_id_t get_current_systemwide_thread_id()
Chris@16 180 {
Chris@16 181 return get_current_thread_id();
Chris@16 182 }
Chris@16 183
Chris@16 184 inline void systemwide_thread_id_copy
Chris@16 185 (const volatile OS_systemwide_thread_id_t &from, volatile OS_systemwide_thread_id_t &to)
Chris@16 186 {
Chris@16 187 to = from;
Chris@16 188 }
Chris@16 189
Chris@16 190 inline bool equal_systemwide_thread_id(const OS_systemwide_thread_id_t &id1, const OS_systemwide_thread_id_t &id2)
Chris@16 191 {
Chris@16 192 return equal_thread_id(id1, id2);
Chris@16 193 }
Chris@16 194
Chris@16 195 inline OS_systemwide_thread_id_t get_invalid_systemwide_thread_id()
Chris@16 196 {
Chris@16 197 return get_invalid_thread_id();
Chris@16 198 }
Chris@16 199
Chris@16 200 inline long double get_current_process_creation_time()
Chris@16 201 {
Chris@16 202 winapi::interprocess_filetime CreationTime, ExitTime, KernelTime, UserTime;
Chris@16 203
Chris@101 204 winapi::get_process_times
Chris@16 205 ( winapi::get_current_process(), &CreationTime, &ExitTime, &KernelTime, &UserTime);
Chris@16 206
Chris@16 207 typedef long double ldouble_t;
Chris@16 208 const ldouble_t resolution = (100.0l/1000000000.0l);
Chris@16 209 return CreationTime.dwHighDateTime*(ldouble_t(1u<<31u)*2.0l*resolution) +
Chris@16 210 CreationTime.dwLowDateTime*resolution;
Chris@16 211 }
Chris@16 212
Chris@16 213 inline unsigned int get_num_cores()
Chris@16 214 {
Chris@16 215 winapi::system_info sysinfo;
Chris@16 216 winapi::get_system_info( &sysinfo );
Chris@16 217 //in Windows dw is long which is equal in bits to int
Chris@16 218 return static_cast<unsigned>(sysinfo.dwNumberOfProcessors);
Chris@16 219 }
Chris@16 220
Chris@101 221 #else //#if defined (BOOST_INTERPROCESS_WINDOWS)
Chris@16 222
Chris@16 223 typedef pthread_t OS_thread_t;
Chris@16 224 typedef pthread_t OS_thread_id_t;
Chris@16 225 typedef pid_t OS_process_id_t;
Chris@16 226
Chris@16 227 struct OS_systemwide_thread_id_t
Chris@16 228 {
Chris@16 229 OS_systemwide_thread_id_t()
Chris@16 230 : pid(), tid()
Chris@16 231 {}
Chris@16 232
Chris@16 233 OS_systemwide_thread_id_t(pid_t p, pthread_t t)
Chris@16 234 : pid(p), tid(t)
Chris@16 235 {}
Chris@16 236
Chris@16 237 OS_systemwide_thread_id_t(const OS_systemwide_thread_id_t &x)
Chris@16 238 : pid(x.pid), tid(x.tid)
Chris@16 239 {}
Chris@16 240
Chris@16 241 OS_systemwide_thread_id_t(const volatile OS_systemwide_thread_id_t &x)
Chris@16 242 : pid(x.pid), tid(x.tid)
Chris@16 243 {}
Chris@16 244
Chris@16 245 OS_systemwide_thread_id_t & operator=(const OS_systemwide_thread_id_t &x)
Chris@16 246 { pid = x.pid; tid = x.tid; return *this; }
Chris@16 247
Chris@16 248 OS_systemwide_thread_id_t & operator=(const volatile OS_systemwide_thread_id_t &x)
Chris@16 249 { pid = x.pid; tid = x.tid; return *this; }
Chris@16 250
Chris@16 251 void operator=(const OS_systemwide_thread_id_t &x) volatile
Chris@16 252 { pid = x.pid; tid = x.tid; }
Chris@16 253
Chris@16 254 pid_t pid;
Chris@16 255 pthread_t tid;
Chris@16 256 };
Chris@16 257
Chris@16 258 inline void systemwide_thread_id_copy
Chris@16 259 (const volatile OS_systemwide_thread_id_t &from, volatile OS_systemwide_thread_id_t &to)
Chris@16 260 {
Chris@16 261 to.pid = from.pid;
Chris@16 262 to.tid = from.tid;
Chris@16 263 }
Chris@16 264
Chris@16 265 //process
Chris@16 266 inline OS_process_id_t get_current_process_id()
Chris@16 267 { return ::getpid(); }
Chris@16 268
Chris@16 269 inline OS_process_id_t get_invalid_process_id()
Chris@16 270 { return pid_t(0); }
Chris@16 271
Chris@16 272 //thread
Chris@16 273 inline OS_thread_id_t get_current_thread_id()
Chris@16 274 { return ::pthread_self(); }
Chris@16 275
Chris@16 276 inline OS_thread_id_t get_invalid_thread_id()
Chris@16 277 {
Chris@16 278 static pthread_t invalid_id;
Chris@16 279 return invalid_id;
Chris@16 280 }
Chris@16 281
Chris@16 282 inline bool equal_thread_id(OS_thread_id_t id1, OS_thread_id_t id2)
Chris@16 283 { return 0 != pthread_equal(id1, id2); }
Chris@16 284
Chris@16 285 inline void thread_yield()
Chris@16 286 { ::sched_yield(); }
Chris@16 287
Chris@16 288 #ifndef BOOST_INTERPROCESS_MATCH_ABSOLUTE_TIME
Chris@16 289 typedef struct timespec OS_highres_count_t;
Chris@16 290 #else
Chris@16 291 typedef unsigned long long OS_highres_count_t;
Chris@16 292 #endif
Chris@16 293
Chris@16 294 inline unsigned long get_system_tick_ns()
Chris@16 295 {
Chris@16 296 #ifdef _SC_CLK_TCK
Chris@101 297 long ticks_per_second =::sysconf(_SC_CLK_TCK); // ticks per sec
Chris@101 298 if(ticks_per_second <= 0){ //Try a typical value on error
Chris@101 299 ticks_per_second = 100;
Chris@16 300 }
Chris@101 301 return 999999999ul/static_cast<unsigned long>(ticks_per_second)+1ul;
Chris@16 302 #else
Chris@16 303 #error "Can't obtain system tick value for your system, please provide a patch"
Chris@16 304 #endif
Chris@16 305 }
Chris@16 306
Chris@16 307 inline unsigned long get_system_tick_in_highres_counts()
Chris@16 308 {
Chris@16 309 #ifndef BOOST_INTERPROCESS_MATCH_ABSOLUTE_TIME
Chris@16 310 return get_system_tick_ns();
Chris@16 311 #else
Chris@16 312 mach_timebase_info_data_t info;
Chris@16 313 mach_timebase_info(&info);
Chris@16 314 //ns
Chris@16 315 return static_cast<unsigned long>
Chris@101 316 (
Chris@101 317 static_cast<double>(get_system_tick_ns())
Chris@16 318 / (static_cast<double>(info.numer) / info.denom)
Chris@16 319 );
Chris@16 320 #endif
Chris@16 321 }
Chris@16 322
Chris@16 323 //return system ticks in us
Chris@16 324 inline unsigned long get_system_tick_us()
Chris@16 325 {
Chris@16 326 return (get_system_tick_ns()-1)/1000ul + 1ul;
Chris@16 327 }
Chris@16 328
Chris@16 329 inline OS_highres_count_t get_current_system_highres_count()
Chris@16 330 {
Chris@16 331 #if defined(BOOST_INTERPROCESS_CLOCK_MONOTONIC)
Chris@16 332 struct timespec count;
Chris@16 333 ::clock_gettime(BOOST_INTERPROCESS_CLOCK_MONOTONIC, &count);
Chris@16 334 return count;
Chris@16 335 #elif defined(BOOST_INTERPROCESS_MATCH_ABSOLUTE_TIME)
Chris@16 336 return ::mach_absolute_time();
Chris@16 337 #endif
Chris@16 338 }
Chris@16 339
Chris@16 340 #ifndef BOOST_INTERPROCESS_MATCH_ABSOLUTE_TIME
Chris@16 341
Chris@16 342 inline void zero_highres_count(OS_highres_count_t &count)
Chris@16 343 { count.tv_sec = 0; count.tv_nsec = 0; }
Chris@16 344
Chris@16 345 inline bool is_highres_count_zero(const OS_highres_count_t &count)
Chris@16 346 { return count.tv_sec == 0 && count.tv_nsec == 0; }
Chris@16 347
Chris@16 348 template <class Ostream>
Chris@16 349 inline Ostream &ostream_highres_count(Ostream &ostream, const OS_highres_count_t &count)
Chris@16 350 {
Chris@16 351 ostream << count.tv_sec << "s:" << count.tv_nsec << "ns";
Chris@16 352 return ostream;
Chris@16 353 }
Chris@16 354
Chris@16 355 inline OS_highres_count_t system_highres_count_subtract(const OS_highres_count_t &l, const OS_highres_count_t &r)
Chris@16 356 {
Chris@16 357 OS_highres_count_t res;
Chris@16 358
Chris@16 359 if (l.tv_nsec < r.tv_nsec){
Chris@101 360 res.tv_nsec = 1000000000 + l.tv_nsec - r.tv_nsec;
Chris@16 361 res.tv_sec = l.tv_sec - 1 - r.tv_sec;
Chris@16 362 }
Chris@16 363 else{
Chris@101 364 res.tv_nsec = l.tv_nsec - r.tv_nsec;
Chris@16 365 res.tv_sec = l.tv_sec - r.tv_sec;
Chris@16 366 }
Chris@16 367
Chris@16 368 return res;
Chris@16 369 }
Chris@16 370
Chris@16 371 inline bool system_highres_count_less(const OS_highres_count_t &l, const OS_highres_count_t &r)
Chris@16 372 { return l.tv_sec < r.tv_sec || (l.tv_sec == r.tv_sec && l.tv_nsec < r.tv_nsec); }
Chris@16 373
Chris@16 374 inline bool system_highres_count_less_ul(const OS_highres_count_t &l, unsigned long r)
Chris@101 375 { return !l.tv_sec && (static_cast<unsigned long>(l.tv_nsec) < r); }
Chris@16 376
Chris@16 377 #else
Chris@16 378
Chris@16 379 inline void zero_highres_count(OS_highres_count_t &count)
Chris@16 380 { count = 0; }
Chris@16 381
Chris@16 382 inline bool is_highres_count_zero(const OS_highres_count_t &count)
Chris@16 383 { return count == 0; }
Chris@16 384
Chris@16 385 template <class Ostream>
Chris@16 386 inline Ostream &ostream_highres_count(Ostream &ostream, const OS_highres_count_t &count)
Chris@16 387 {
Chris@16 388 ostream << count ;
Chris@16 389 return ostream;
Chris@16 390 }
Chris@16 391
Chris@16 392 inline OS_highres_count_t system_highres_count_subtract(const OS_highres_count_t &l, const OS_highres_count_t &r)
Chris@16 393 { return l - r; }
Chris@16 394
Chris@16 395 inline bool system_highres_count_less(const OS_highres_count_t &l, const OS_highres_count_t &r)
Chris@16 396 { return l < r; }
Chris@16 397
Chris@16 398 inline bool system_highres_count_less_ul(const OS_highres_count_t &l, unsigned long r)
Chris@16 399 { return l < static_cast<OS_highres_count_t>(r); }
Chris@16 400
Chris@16 401 #endif
Chris@16 402
Chris@16 403 inline void thread_sleep_tick()
Chris@16 404 {
Chris@16 405 struct timespec rqt;
Chris@16 406 //Sleep for the half of the tick time
Chris@16 407 rqt.tv_sec = 0;
Chris@16 408 rqt.tv_nsec = get_system_tick_ns()/2;
Chris@16 409 ::nanosleep(&rqt, 0);
Chris@16 410 }
Chris@16 411
Chris@16 412 inline void thread_sleep(unsigned int ms)
Chris@16 413 {
Chris@16 414 struct timespec rqt;
Chris@16 415 rqt.tv_sec = ms/1000u;
Chris@16 416 rqt.tv_nsec = (ms%1000u)*1000000u;
Chris@16 417 ::nanosleep(&rqt, 0);
Chris@16 418 }
Chris@16 419
Chris@16 420 //systemwide thread
Chris@16 421 inline OS_systemwide_thread_id_t get_current_systemwide_thread_id()
Chris@16 422 {
Chris@16 423 return OS_systemwide_thread_id_t(::getpid(), ::pthread_self());
Chris@16 424 }
Chris@16 425
Chris@16 426 inline bool equal_systemwide_thread_id(const OS_systemwide_thread_id_t &id1, const OS_systemwide_thread_id_t &id2)
Chris@16 427 {
Chris@16 428 return (0 != pthread_equal(id1.tid, id2.tid)) && (id1.pid == id2.pid);
Chris@16 429 }
Chris@16 430
Chris@16 431 inline OS_systemwide_thread_id_t get_invalid_systemwide_thread_id()
Chris@16 432 {
Chris@16 433 return OS_systemwide_thread_id_t(get_invalid_process_id(), get_invalid_thread_id());
Chris@16 434 }
Chris@16 435
Chris@16 436 inline long double get_current_process_creation_time()
Chris@16 437 { return 0.0L; }
Chris@16 438
Chris@16 439 inline unsigned int get_num_cores()
Chris@16 440 {
Chris@16 441 #ifdef _SC_NPROCESSORS_ONLN
Chris@16 442 long cores = ::sysconf(_SC_NPROCESSORS_ONLN);
Chris@16 443 // sysconf returns -1 if the name is invalid, the option does not exist or
Chris@16 444 // does not have a definite limit.
Chris@16 445 // if sysconf returns some other negative number, we have no idea
Chris@16 446 // what is going on. Default to something safe.
Chris@16 447 if(cores <= 0){
Chris@16 448 return 1;
Chris@16 449 }
Chris@16 450 //Check for overflow (unlikely)
Chris@16 451 else if(static_cast<unsigned long>(cores) >=
Chris@16 452 static_cast<unsigned long>(static_cast<unsigned int>(-1))){
Chris@16 453 return static_cast<unsigned int>(-1);
Chris@16 454 }
Chris@16 455 else{
Chris@16 456 return static_cast<unsigned int>(cores);
Chris@16 457 }
Chris@16 458 #elif defined(BOOST_INTERPROCESS_BSD_DERIVATIVE) && defined(HW_NCPU)
Chris@16 459 int request[2] = { CTL_HW, HW_NCPU };
Chris@16 460 int num_cores;
Chris@16 461 std::size_t result_len = sizeof(num_cores);
Chris@16 462 if ( (::sysctl (request, 2, &num_cores, &result_len, 0, 0) < 0) || (num_cores <= 0) ){
Chris@16 463 //Return a safe value
Chris@16 464 return 1;
Chris@16 465 }
Chris@16 466 else{
Chris@16 467 return static_cast<unsigned int>(num_cores);
Chris@16 468 }
Chris@16 469 #endif
Chris@16 470 }
Chris@16 471
Chris@16 472 inline int thread_create(OS_thread_t * thread, void *(*start_routine)(void*), void* arg)
Chris@16 473 { return pthread_create(thread, 0, start_routine, arg); }
Chris@16 474
Chris@16 475 inline void thread_join(OS_thread_t thread)
Chris@16 476 { (void)pthread_join(thread, 0); }
Chris@16 477
Chris@101 478 #endif //#if defined (BOOST_INTERPROCESS_WINDOWS)
Chris@16 479
Chris@16 480 typedef char pid_str_t[sizeof(OS_process_id_t)*3+1];
Chris@16 481
Chris@16 482 inline void get_pid_str(pid_str_t &pid_str, OS_process_id_t pid)
Chris@16 483 {
Chris@16 484 bufferstream bstream(pid_str, sizeof(pid_str));
Chris@16 485 bstream << pid << std::ends;
Chris@16 486 }
Chris@16 487
Chris@16 488 inline void get_pid_str(pid_str_t &pid_str)
Chris@16 489 { get_pid_str(pid_str, get_current_process_id()); }
Chris@16 490
Chris@16 491 #if defined(BOOST_INTERPROCESS_WINDOWS)
Chris@16 492
Chris@16 493 inline int thread_create( OS_thread_t * thread, unsigned (__stdcall * start_routine) (void*), void* arg )
Chris@16 494 {
Chris@16 495 void* h = (void*)_beginthreadex( 0, 0, start_routine, arg, 0, 0 );
Chris@16 496
Chris@16 497 if( h != 0 ){
Chris@16 498 *thread = h;
Chris@16 499 return 0;
Chris@16 500 }
Chris@16 501 else{
Chris@16 502 return 1;
Chris@16 503 }
Chris@16 504 }
Chris@16 505
Chris@16 506 inline void thread_join( OS_thread_t thread)
Chris@16 507 {
Chris@16 508 winapi::wait_for_single_object( thread, winapi::infinite_time );
Chris@16 509 winapi::close_handle( thread );
Chris@16 510 }
Chris@16 511
Chris@16 512 #endif
Chris@16 513
Chris@16 514 class abstract_thread
Chris@16 515 {
Chris@16 516 public:
Chris@16 517 virtual ~abstract_thread() {}
Chris@16 518 virtual void run() = 0;
Chris@16 519 };
Chris@16 520
Chris@101 521 template<class T>
Chris@101 522 class os_thread_func_ptr_deleter
Chris@101 523 {
Chris@101 524 public:
Chris@101 525 explicit os_thread_func_ptr_deleter(T* p)
Chris@101 526 : m_p(p)
Chris@101 527 {}
Chris@101 528
Chris@101 529 T *release()
Chris@101 530 { T *p = m_p; m_p = 0; return p; }
Chris@101 531
Chris@101 532 T *get() const
Chris@101 533 { return m_p; }
Chris@101 534
Chris@101 535 T *operator ->() const
Chris@101 536 { return m_p; }
Chris@101 537
Chris@101 538 ~os_thread_func_ptr_deleter()
Chris@101 539 { delete m_p; }
Chris@101 540
Chris@101 541 private:
Chris@101 542 T *m_p;
Chris@101 543 };
Chris@101 544
Chris@16 545 #if defined(BOOST_INTERPROCESS_WINDOWS)
Chris@16 546
Chris@16 547 inline unsigned __stdcall launch_thread_routine( void * pv )
Chris@16 548 {
Chris@101 549 os_thread_func_ptr_deleter<abstract_thread> pt( static_cast<abstract_thread *>( pv ) );
Chris@16 550 pt->run();
Chris@16 551 return 0;
Chris@16 552 }
Chris@16 553
Chris@16 554 #else
Chris@16 555
Chris@16 556 extern "C" void * launch_thread_routine( void * pv );
Chris@16 557
Chris@16 558 inline void * launch_thread_routine( void * pv )
Chris@16 559 {
Chris@101 560 os_thread_func_ptr_deleter<abstract_thread> pt( static_cast<abstract_thread *>( pv ) );
Chris@16 561 pt->run();
Chris@16 562 return 0;
Chris@16 563 }
Chris@16 564
Chris@16 565 #endif
Chris@16 566
Chris@16 567 template<class F>
Chris@16 568 class launch_thread_impl
Chris@16 569 : public abstract_thread
Chris@16 570 {
Chris@16 571 public:
Chris@16 572 explicit launch_thread_impl( F f )
Chris@16 573 : f_( f )
Chris@16 574 {}
Chris@16 575
Chris@16 576 void run()
Chris@16 577 { f_(); }
Chris@16 578
Chris@16 579 private:
Chris@16 580 F f_;
Chris@16 581 };
Chris@16 582
Chris@16 583 template<class F>
Chris@16 584 inline int thread_launch( OS_thread_t & pt, F f )
Chris@16 585 {
Chris@101 586 os_thread_func_ptr_deleter<abstract_thread> p( new launch_thread_impl<F>( f ) );
Chris@16 587
Chris@16 588 int r = thread_create(&pt, launch_thread_routine, p.get());
Chris@16 589 if( r == 0 ){
Chris@16 590 p.release();
Chris@16 591 }
Chris@16 592
Chris@16 593 return r;
Chris@16 594 }
Chris@16 595
Chris@16 596 } //namespace ipcdetail{
Chris@16 597 } //namespace interprocess {
Chris@16 598 } //namespace boost {
Chris@16 599
Chris@16 600 #include <boost/interprocess/detail/config_end.hpp>
Chris@16 601
Chris@16 602 #endif //BOOST_INTERPROCESS_DETAIL_OS_THREAD_FUNCTIONS_HPP