Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-18 08:10:08

0001 //////////////////////////////////////////////////////////////////////////////
0002 //
0003 // (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
0004 // Software License, Version 1.0. (See accompanying file
0005 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 //
0007 // See http://www.boost.org/libs/interprocess for documentation.
0008 //
0009 //////////////////////////////////////////////////////////////////////////////
0010 
0011 //Thread launching functions are adapted from boost/detail/lightweight_thread.hpp
0012 //
0013 //  boost/detail/lightweight_thread.hpp
0014 //
0015 //  Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
0016 //  Copyright (c) 2008 Peter Dimov
0017 //
0018 //  Distributed under the Boost Software License, Version 1.0.
0019 //  See accompanying file LICENSE_1_0.txt or copy at
0020 //  http://www.boost.org/LICENSE_1_0.txt
0021 
0022 #ifndef BOOST_INTERPROCESS_DETAIL_OS_THREAD_FUNCTIONS_HPP
0023 #define BOOST_INTERPROCESS_DETAIL_OS_THREAD_FUNCTIONS_HPP
0024 
0025 #ifndef BOOST_CONFIG_HPP
0026 #  include <boost/config.hpp>
0027 #endif
0028 0029 ">#
0030 #if defined(BOOST_HAS_PRAGMA_ONCE)
0031 #  pragma once
0032 #endif
0033 
0034 #include <boost/interprocess/detail/config_begin.hpp>
0035 #include <boost/interprocess/detail/workaround.hpp>
0036 #include <boost/interprocess/streams/bufferstream.hpp>
0037 #include <cstddef>
0038 #include <cassert>
0039 
0040 #if defined(BOOST_INTERPROCESS_WINDOWS)
0041 #  include <boost/interprocess/detail/win32_api.hpp>
0042 #  include <boost/winapi/thread.hpp>
0043 #else
0044 #  include <pthread.h>
0045 #  include <unistd.h>
0046 #  include <sched.h>
0047 #  include <time.h>
0048 #  include <errno.h>
0049 #  ifdef BOOST_INTERPROCESS_BSD_DERIVATIVE
0050       //Some *BSD systems (OpenBSD & NetBSD) need sys/param.h before sys/sysctl.h, whereas
0051       //others (FreeBSD & Darwin) need sys/types.h
0052 #     include <sys/types.h>
0053 #     include <sys/param.h>
0054 #     include <sys/sysctl.h>
0055 #  endif
0056 #if defined(__VXWORKS__) 
0057 #include <vxCpuLib.h>
0058 #endif 
0059 //According to the article "C/C++ tip: How to measure elapsed real time for benchmarking"
0060 //Check MacOs first as macOS 10.12 SDK defines both CLOCK_MONOTONIC and
0061 //CLOCK_MONOTONIC_RAW and no clock_gettime.
0062 #  if (defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__))
0063 #     include <mach/mach_time.h>  // mach_absolute_time, mach_timebase_info_data_t
0064 #     define BOOST_INTERPROCESS_MATCH_ABSOLUTE_TIME
0065 #  elif defined(CLOCK_MONOTONIC_PRECISE)   //BSD
0066 #     define BOOST_INTERPROCESS_CLOCK_MONOTONIC CLOCK_MONOTONIC_PRECISE
0067 #  elif defined(CLOCK_MONOTONIC_RAW)     //Linux
0068 #     define BOOST_INTERPROCESS_CLOCK_MONOTONIC CLOCK_MONOTONIC_RAW
0069 #  elif defined(CLOCK_HIGHRES)           //Solaris
0070 #     define BOOST_INTERPROCESS_CLOCK_MONOTONIC CLOCK_HIGHRES
0071 #  elif defined(CLOCK_MONOTONIC)         //POSIX (AIX, BSD, Linux, Solaris)
0072 #     define BOOST_INTERPROCESS_CLOCK_MONOTONIC CLOCK_MONOTONIC
0073 #  else
0074 #     error "No high resolution steady clock in your system, please provide a patch"
0075 #  endif
0076 #endif
0077 
0078 namespace boost {
0079 namespace interprocess {
0080 namespace ipcdetail{
0081 
0082 #if defined (BOOST_INTERPROCESS_WINDOWS)
0083 
0084 typedef unsigned long OS_process_id_t;
0085 typedef unsigned long OS_thread_id_t;
0086 struct OS_thread_t
0087 {
0088    OS_thread_t()
0089       : m_handle()
0090    {}
0091 
0092    
0093    void* handle() const
0094    {  return m_handle;  }
0095 
0096    void* m_handle;
0097 };
0098 
0099 typedef OS_thread_id_t OS_systemwide_thread_id_t;
0100 
0101 //process
0102 inline OS_process_id_t get_current_process_id()
0103 {  return winapi::get_current_process_id();  }
0104 
0105 inline OS_process_id_t get_invalid_process_id()
0106 {  return OS_process_id_t(0);  }
0107 
0108 //thread
0109 inline OS_thread_id_t get_current_thread_id()
0110 {  return winapi::get_current_thread_id();  }
0111 
0112 inline OS_thread_id_t get_invalid_thread_id()
0113 {  return OS_thread_id_t(0xffffffff);  }
0114 
0115 inline bool equal_thread_id(OS_thread_id_t id1, OS_thread_id_t id2)
0116 {  return id1 == id2;  }
0117 
0118 //return the system tick in ns
0119 inline unsigned long get_system_tick_ns()
0120 {
0121    unsigned long curres, ignore1, ignore2;
0122    winapi::query_timer_resolution(&ignore1, &ignore2, &curres);
0123    //Windows API returns the value in hundreds of ns
0124    return (curres - 1ul)*100ul;
0125 }
0126 
0127 //return the system tick in us
0128 inline unsigned long get_system_tick_us()
0129 {
0130    unsigned long curres, ignore1, ignore2;
0131    winapi::query_timer_resolution(&ignore1, &ignore2, &curres);
0132    //Windows API returns the value in hundreds of ns
0133    return (curres - 1ul)/10ul + 1ul;
0134 }
0135 
0136 typedef unsigned __int64 OS_highres_count_t;
0137 
0138 inline unsigned long get_system_tick_in_highres_counts()
0139 {
0140    __int64 freq;
0141    unsigned long curres, ignore1, ignore2;
0142    winapi::query_timer_resolution(&ignore1, &ignore2, &curres);
0143    //Frequency in counts per second
0144    if(!winapi::query_performance_frequency(&freq)){
0145       //Tick resolution in ms
0146       return (curres-1ul)/10000ul + 1ul;
0147    }
0148    else{
0149       //In femtoseconds
0150       __int64 count_fs    = (1000000000000000LL - 1LL)/freq + 1LL;
0151       __int64 tick_counts = (static_cast<__int64>(curres)*100000000LL - 1LL)/count_fs + 1LL;
0152       return static_cast<unsigned long>(tick_counts);
0153    }
0154 }
0155 
0156 inline OS_highres_count_t get_current_system_highres_count()
0157 {
0158    __int64 count;
0159    if(!winapi::query_performance_counter(&count)){
0160       count = winapi::get_tick_count();
0161    }
0162    return (OS_highres_count_t)count;
0163 }
0164 
0165 inline unsigned get_current_system_highres_rand()
0166 {
0167    unsigned __int64 count = (unsigned __int64) get_current_system_highres_count();
0168    return static_cast<unsigned>(count + (count >> 32u));
0169 }
0170 
0171 inline void zero_highres_count(OS_highres_count_t &count)
0172 {  count = 0;  }
0173 
0174 inline bool is_highres_count_zero(const OS_highres_count_t &count)
0175 {  return count == 0;  }
0176 
0177 template <class Ostream>
0178 inline Ostream &ostream_highres_count(Ostream &ostream, const OS_highres_count_t &count)
0179 {
0180    ostream << count;
0181    return ostream;
0182 }
0183 
0184 inline OS_highres_count_t system_highres_count_subtract(const OS_highres_count_t &l, const OS_highres_count_t &r)
0185 {  return l - r;  }
0186 
0187 inline bool system_highres_count_less(const OS_highres_count_t &l, const OS_highres_count_t &r)
0188 {  return l < r;  }
0189 
0190 inline bool system_highres_count_less_ul(const OS_highres_count_t &l, unsigned long r)
0191 {  return l < static_cast<OS_highres_count_t>(r);  }
0192 
0193 inline void thread_sleep_tick()
0194 {  winapi::sleep_tick();   }
0195 
0196 inline void thread_yield()
0197 {  winapi::sched_yield();  }
0198 
0199 inline void thread_sleep_ms(unsigned int ms)
0200 {  winapi::sleep(ms);  }
0201 
0202 //systemwide thread
0203 inline OS_systemwide_thread_id_t get_current_systemwide_thread_id()
0204 {
0205    return get_current_thread_id();
0206 }
0207 
0208 inline void systemwide_thread_id_copy
0209    (const volatile OS_systemwide_thread_id_t &from, volatile OS_systemwide_thread_id_t &to)
0210 {
0211    to = from;
0212 }
0213 
0214 inline bool equal_systemwide_thread_id(const OS_systemwide_thread_id_t &id1, const OS_systemwide_thread_id_t &id2)
0215 {
0216    return equal_thread_id(id1, id2);
0217 }
0218 
0219 inline OS_systemwide_thread_id_t get_invalid_systemwide_thread_id()
0220 {
0221    return get_invalid_thread_id();
0222 }
0223 
0224 inline unsigned long long get_current_process_creation_time()
0225 {
0226    winapi::interprocess_filetime CreationTime, ExitTime, KernelTime, UserTime;
0227 
0228    winapi::get_process_times
0229       ( winapi::get_current_process(), &CreationTime, &ExitTime, &KernelTime, &UserTime);
0230 
0231    unsigned long long microsecs = CreationTime.dwHighDateTime;
0232    microsecs <<= 32u;
0233    microsecs |= CreationTime.dwLowDateTime;
0234    microsecs /= 10u;
0235    return microsecs;
0236 }
0237 
0238 inline unsigned int get_num_cores()
0239 {
0240    winapi::interprocess_system_info sysinfo;
0241    winapi::get_system_info( &sysinfo );
0242    //in Windows dw is long which is equal in bits to int
0243    return static_cast<unsigned>(sysinfo.dwNumberOfProcessors);
0244 }
0245 
0246 #else    //#if defined (BOOST_INTERPROCESS_WINDOWS)
0247 
0248 typedef pthread_t OS_thread_t;
0249 typedef pthread_t OS_thread_id_t;
0250 typedef pid_t     OS_process_id_t;
0251 
0252 struct OS_systemwide_thread_id_t
0253 {
0254    OS_systemwide_thread_id_t()
0255       :  pid(), tid()
0256    {}
0257 
0258    OS_systemwide_thread_id_t(pid_t p, pthread_t t)
0259       :  pid(p), tid(t)
0260    {}
0261 
0262    OS_systemwide_thread_id_t(const OS_systemwide_thread_id_t &x)
0263       :  pid(x.pid), tid(x.tid)
0264    {}
0265 
0266    OS_systemwide_thread_id_t(const volatile OS_systemwide_thread_id_t &x)
0267       :  pid(x.pid), tid(x.tid)
0268    {}
0269 
0270    OS_systemwide_thread_id_t & operator=(const OS_systemwide_thread_id_t &x)
0271    {  pid = x.pid;   tid = x.tid;   return *this;   }
0272 
0273    OS_systemwide_thread_id_t & operator=(const volatile OS_systemwide_thread_id_t &x)
0274    {  pid = x.pid;   tid = x.tid;   return *this;  }
0275 
0276    void operator=(const OS_systemwide_thread_id_t &x) volatile
0277    {  pid = x.pid;   tid = x.tid;   }
0278 
0279    pid_t       pid;
0280    pthread_t   tid;
0281 };
0282 
0283 inline void systemwide_thread_id_copy
0284    (const volatile OS_systemwide_thread_id_t &from, volatile OS_systemwide_thread_id_t &to)
0285 {
0286    to.pid = from.pid;
0287    to.tid = from.tid;
0288 }
0289 
0290 //process
0291 inline OS_process_id_t get_current_process_id()
0292 {  return ::getpid();  }
0293 
0294 inline OS_process_id_t get_invalid_process_id()
0295 {  return pid_t(0);  }
0296 
0297 //thread
0298 inline OS_thread_id_t get_current_thread_id()
0299 {  return ::pthread_self();  }
0300 
0301 inline OS_thread_id_t get_invalid_thread_id()
0302 {
0303    static pthread_t invalid_id;
0304    return invalid_id;
0305 }
0306 
0307 inline bool equal_thread_id(OS_thread_id_t id1, OS_thread_id_t id2)
0308 {  return 0 != pthread_equal(id1, id2);  }
0309 
0310 inline void thread_yield()
0311 {  ::sched_yield();  }
0312 
0313 #ifndef BOOST_INTERPROCESS_MATCH_ABSOLUTE_TIME
0314 typedef struct timespec OS_highres_count_t;
0315 #else
0316 typedef unsigned long long OS_highres_count_t;
0317 #endif
0318 
0319 inline unsigned long get_system_tick_ns()
0320 {
0321    #ifdef _SC_CLK_TCK
0322    long ticks_per_second =::sysconf(_SC_CLK_TCK); // ticks per sec
0323    if(ticks_per_second <= 0){   //Try a typical value on error
0324       ticks_per_second = 100;
0325    }
0326    return 999999999ul/static_cast<unsigned long>(ticks_per_second)+1ul;
0327    #else
0328       #error "Can't obtain system tick value for your system, please provide a patch"
0329    #endif
0330 }
0331 
0332 inline unsigned long get_system_tick_in_highres_counts()
0333 {
0334    #ifndef BOOST_INTERPROCESS_MATCH_ABSOLUTE_TIME
0335    return get_system_tick_ns();
0336    #else
0337    mach_timebase_info_data_t info;
0338    mach_timebase_info(&info);
0339             //ns
0340    return static_cast<unsigned long>
0341    (
0342       static_cast<double>(get_system_tick_ns())
0343          / (static_cast<double>(info.numer) / info.denom)
0344    );
0345    #endif
0346 }
0347 
0348 //return system ticks in us
0349 inline unsigned long get_system_tick_us()
0350 {
0351    return (get_system_tick_ns()-1)/1000ul + 1ul;
0352 }
0353 
0354 inline OS_highres_count_t get_current_system_highres_count()
0355 {
0356    #if defined(BOOST_INTERPROCESS_CLOCK_MONOTONIC)
0357       struct timespec count;
0358       ::clock_gettime(BOOST_INTERPROCESS_CLOCK_MONOTONIC, &count);
0359       return count;
0360    #elif defined(BOOST_INTERPROCESS_MATCH_ABSOLUTE_TIME)
0361       return ::mach_absolute_time();
0362    #endif
0363 }
0364 
0365 inline unsigned get_current_system_highres_rand()
0366 {
0367    OS_highres_count_t count = get_current_system_highres_count();
0368    #if defined(BOOST_INTERPROCESS_CLOCK_MONOTONIC)
0369       return static_cast<unsigned>(count.tv_sec + count.tv_nsec);
0370    #elif defined(BOOST_INTERPROCESS_MATCH_ABSOLUTE_TIME)
0371       return static_cast<unsigned>(count);
0372    #endif
0373 }
0374 
0375 #ifndef BOOST_INTERPROCESS_MATCH_ABSOLUTE_TIME
0376 
0377 inline void zero_highres_count(OS_highres_count_t &count)
0378 {  count.tv_sec = 0; count.tv_nsec = 0;  }
0379 
0380 inline bool is_highres_count_zero(const OS_highres_count_t &count)
0381 {  return count.tv_sec == 0 && count.tv_nsec == 0;  }
0382 
0383 template <class Ostream>
0384 inline Ostream &ostream_highres_count(Ostream &ostream, const OS_highres_count_t &count)
0385 {
0386    ostream << count.tv_sec << "s:" << count.tv_nsec << "ns";
0387    return ostream;
0388 }
0389 
0390 inline OS_highres_count_t system_highres_count_subtract(const OS_highres_count_t &l, const OS_highres_count_t &r)
0391 {
0392    OS_highres_count_t res;
0393 
0394    if (l.tv_nsec < r.tv_nsec){
0395       res.tv_nsec = 1000000000 + l.tv_nsec - r.tv_nsec;
0396       res.tv_sec  = l.tv_sec - 1 - r.tv_sec;
0397    }
0398    else{
0399       res.tv_nsec = l.tv_nsec - r.tv_nsec;
0400       res.tv_sec  = l.tv_sec - r.tv_sec;
0401    }
0402 
0403    return res;
0404 }
0405 
0406 inline bool system_highres_count_less(const OS_highres_count_t &l, const OS_highres_count_t &r)
0407 {  return l.tv_sec < r.tv_sec || (l.tv_sec == r.tv_sec && l.tv_nsec < r.tv_nsec);  }
0408 
0409 inline bool system_highres_count_less_ul(const OS_highres_count_t &l, unsigned long r)
0410 {  return !l.tv_sec && (static_cast<unsigned long>(l.tv_nsec) < r);  }
0411 
0412 #else
0413 
0414 inline void zero_highres_count(OS_highres_count_t &count)
0415 {  count = 0;  }
0416 
0417 inline bool is_highres_count_zero(const OS_highres_count_t &count)
0418 {  return count == 0;  }
0419 
0420 template <class Ostream>
0421 inline Ostream &ostream_highres_count(Ostream &ostream, const OS_highres_count_t &count)
0422 {
0423    ostream << count ;
0424    return ostream;
0425 }
0426 
0427 inline OS_highres_count_t system_highres_count_subtract(const OS_highres_count_t &l, const OS_highres_count_t &r)
0428 {  return l - r;  }
0429 
0430 inline bool system_highres_count_less(const OS_highres_count_t &l, const OS_highres_count_t &r)
0431 {  return l < r;  }
0432 
0433 inline bool system_highres_count_less_ul(const OS_highres_count_t &l, unsigned long r)
0434 {  return l < static_cast<OS_highres_count_t>(r);  }
0435 
0436 #endif
0437 
0438 inline void thread_sleep_tick()
0439 {
0440    struct timespec rqt;
0441    //Sleep for the half of the tick time
0442    rqt.tv_sec  = 0;
0443    rqt.tv_nsec = (long)get_system_tick_ns()/2;
0444 
0445    struct timespec rmn;
0446    while (0 != BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::nanosleep(&rqt, &rmn)) && errno == EINTR) {
0447       rqt.tv_sec = rmn.tv_sec;
0448       rqt.tv_nsec = rmn.tv_nsec;
0449    }
0450 }
0451 
0452 inline void thread_sleep_ms(unsigned int ms)
0453 {
0454    struct timespec rqt;
0455    rqt.tv_sec = static_cast<time_t>(ms/1000u);
0456    rqt.tv_nsec = static_cast<long int>((ms%1000u)*1000000u);
0457 
0458    struct timespec rmn;
0459    while (0 != BOOST_INTERPROCESS_EINTR_RETRY(int, -1, ::nanosleep(&rqt, &rmn)) && errno == EINTR) {
0460       rqt.tv_sec  = rmn.tv_sec;
0461       rqt.tv_nsec = rmn.tv_nsec;
0462    }
0463 }
0464 
0465 //systemwide thread
0466 inline OS_systemwide_thread_id_t get_current_systemwide_thread_id()
0467 {
0468    return OS_systemwide_thread_id_t(::getpid(), ::pthread_self());
0469 }
0470 
0471 inline bool equal_systemwide_thread_id(const OS_systemwide_thread_id_t &id1, const OS_systemwide_thread_id_t &id2)
0472 {
0473    return (0 != pthread_equal(id1.tid, id2.tid)) && (id1.pid == id2.pid);
0474 }
0475 
0476 inline OS_systemwide_thread_id_t get_invalid_systemwide_thread_id()
0477 {
0478    return OS_systemwide_thread_id_t(get_invalid_process_id(), get_invalid_thread_id());
0479 }
0480 
0481 inline unsigned long long get_current_process_creation_time()
0482 { return 0u; }
0483 
0484 inline unsigned int get_num_cores()
0485 {
0486    #ifdef _SC_NPROCESSORS_ONLN
0487       long cores = ::sysconf(_SC_NPROCESSORS_ONLN);
0488       // sysconf returns -1 if the name is invalid, the option does not exist or
0489       // does not have a definite limit.
0490       // if sysconf returns some other negative number, we have no idea
0491       // what is going on. Default to something safe.
0492       if(cores <= 0){
0493          return 1;
0494       }
0495       //Check for overflow (unlikely)
0496       else if(static_cast<unsigned long>(cores) >=
0497               static_cast<unsigned long>(static_cast<unsigned int>(-1))){
0498          return static_cast<unsigned int>(-1);
0499       }
0500       else{
0501          return static_cast<unsigned int>(cores);
0502       }
0503    #elif defined(BOOST_INTERPROCESS_BSD_DERIVATIVE) && defined(HW_NCPU)
0504       int request[2] = { CTL_HW, HW_NCPU };
0505       int num_cores;
0506       std::size_t result_len = sizeof(num_cores);
0507       if ( (::sysctl (request, 2, &num_cores, &result_len, 0, 0) < 0) || (num_cores <= 0) ){
0508          //Return a safe value
0509          return 1;
0510       }
0511       else{
0512          return static_cast<unsigned int>(num_cores);
0513       }
0514    #elif defined(__VXWORKS__)
0515       cpuset_t set =  ::vxCpuEnabledGet();
0516     #ifdef __DCC__
0517       int i;
0518       for( i = 0; set; ++i)
0519           {
0520                set &= set -1;
0521           }
0522       return(i);
0523     #else  
0524       return (__builtin_popcount(set) );
0525     #endif  
0526    #endif
0527 }
0528 
0529 inline int thread_create(OS_thread_t * thread, void *(*start_routine)(void*), void* arg)
0530 {  return pthread_create(thread, 0, start_routine, arg); }
0531 
0532 inline void thread_join(OS_thread_t thread)
0533 {
0534    int ret = pthread_join(thread, 0);
0535    (void)ret;
0536    assert(0 == ret);
0537 }
0538 
0539 #endif   //#if defined (BOOST_INTERPROCESS_WINDOWS)
0540 
0541 typedef char pid_str_t[sizeof(OS_process_id_t)*3+1];
0542 
0543 inline void get_pid_str(pid_str_t &pid_str, OS_process_id_t pid)
0544 {
0545    bufferstream bstream(pid_str, sizeof(pid_str));
0546    bstream << pid << std::ends;
0547 }
0548 
0549 inline void get_pid_str(pid_str_t &pid_str)
0550 {  get_pid_str(pid_str, get_current_process_id());  }
0551 
0552 #if defined(BOOST_INTERPROCESS_WINDOWS)
0553 
0554 inline int thread_create( OS_thread_t * thread, boost::ipwinapiext::LPTHREAD_START_ROUTINE_ start_routine, void* arg )
0555 {
0556    void* h = boost::ipwinapiext::CreateThread(0, 0, start_routine, arg, 0, 0);
0557 
0558    if( h != 0 ){
0559       thread->m_handle = h;
0560       return 0;
0561    }
0562    else{
0563       return 1;
0564    }
0565 }
0566 
0567 inline void thread_join( OS_thread_t thread)
0568 {
0569    {
0570       unsigned long ret = winapi::wait_for_single_object( thread.handle(), winapi::infinite_time );
0571       assert(0 == ret);
0572       (void)ret;
0573    }
0574    {
0575       bool ret = winapi::close_handle(thread.handle());
0576       assert(true == ret);
0577       (void)ret;
0578    }
0579 }
0580 
0581 #endif
0582 
0583 class abstract_thread
0584 {
0585    public:
0586    virtual ~abstract_thread() {}
0587    virtual void run() = 0;
0588 };
0589 
0590 template<class T>
0591 class os_thread_func_ptr_deleter
0592 {
0593    public:
0594    explicit os_thread_func_ptr_deleter(T* p)
0595       : m_p(p)
0596    {}
0597 
0598    T *release()
0599    {  T *p = m_p; m_p = 0; return p;  }
0600 
0601    T *get() const
0602    {  return m_p;  }
0603 
0604    T *operator ->() const
0605    {  return m_p;  }
0606 
0607    ~os_thread_func_ptr_deleter()
0608    {  delete m_p; }
0609 
0610    private:
0611    T *m_p;
0612 };
0613 
0614 #if defined(BOOST_INTERPROCESS_WINDOWS)
0615 
0616 inline boost::winapi::DWORD_ __stdcall launch_thread_routine(boost::winapi::LPVOID_ pv)
0617 {
0618    os_thread_func_ptr_deleter<abstract_thread> pt( static_cast<abstract_thread *>( pv ) );
0619    pt->run();
0620    return 0;
0621 }
0622 
0623 #else
0624 
0625 extern "C" void * launch_thread_routine( void * pv );
0626 
0627 inline void * launch_thread_routine( void * pv )
0628 {
0629    os_thread_func_ptr_deleter<abstract_thread> pt( static_cast<abstract_thread *>( pv ) );
0630    pt->run();
0631    return 0;
0632 }
0633 
0634 #endif
0635 
0636 template<class F>
0637 class launch_thread_impl
0638    : public abstract_thread
0639 {
0640    public:
0641    explicit launch_thread_impl( F f )
0642       : f_( f )
0643    {}
0644 
0645    virtual void run() BOOST_OVERRIDE
0646    {  f_();  }
0647 
0648    private:
0649    F f_;
0650 };
0651 
0652 template<class F>
0653 inline int thread_launch( OS_thread_t & pt, F f )
0654 {
0655    os_thread_func_ptr_deleter<abstract_thread> p( new launch_thread_impl<F>( f ) );
0656 
0657    int r = thread_create(&pt, launch_thread_routine, p.get());
0658    if( r == 0 ){
0659       p.release();
0660    }
0661 
0662    return r;
0663 }
0664 
0665 }  //namespace ipcdetail{
0666 }  //namespace interprocess {
0667 }  //namespace boost {
0668 
0669 #include <boost/interprocess/detail/config_end.hpp>
0670 
0671 #endif   //BOOST_INTERPROCESS_DETAIL_OS_THREAD_FUNCTIONS_HPP