1 // thread -*- C++ -*- 2 3 // Copyright (C) 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. 4 // 5 // This file is part of the GNU ISO C++ Library. This library is free 6 // software; you can redistribute it and/or modify it under the 7 // terms of the GNU General Public License as published by the 8 // Free Software Foundation; either version 3, or (at your option) 9 // any later version. 10 11 // This library is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 16 // Under Section 7 of GPL version 3, you are granted additional 17 // permissions described in the GCC Runtime Library Exception, version 18 // 3.1, as published by the Free Software Foundation. 19 20 // You should have received a copy of the GNU General Public License and 21 // a copy of the GCC Runtime Library Exception along with this program; 22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 // <http://www.gnu.org/licenses/>. 24 25 26 #include <thread> 27 #include <system_error> 28 #include <cerrno> 29 #include <cxxabi_forced.h> 30 31 #if defined(_GLIBCXX_USE_GET_NPROCS) 32 # include <sys/sysinfo.h> 33 # define _GLIBCXX_NPROCS get_nprocs() 34 #elif defined(_GLIBCXX_USE_PTHREADS_NUM_PROCESSORS_NP) 35 # define _GLIBCXX_NPROCS pthread_num_processors_np() 36 #elif defined(_GLIBCXX_USE_SYSCTL_HW_NCPU) 37 # include <stddef.h> 38 # include <sys/sysctl.h> 39 static inline int get_nprocs() 40 { 41 int count; 42 size_t size = sizeof(count); 43 int mib[] = { CTL_HW, HW_NCPU }; 44 if (!sysctl(mib, 2, &count, &size, NULL, 0)) 45 return count; 46 return 0; 47 } 48 # define _GLIBCXX_NPROCS get_nprocs() 49 #elif defined(_GLIBCXX_USE_SC_NPROCESSORS_ONLN) 50 # include <unistd.h> 51 # define _GLIBCXX_NPROCS sysconf(_SC_NPROCESSORS_ONLN) 52 #elif defined(_GLIBCXX_USE_SC_NPROC_ONLN) 53 # include <unistd.h> 54 # define _GLIBCXX_NPROCS sysconf(_SC_NPROC_ONLN) 55 #else 56 # define _GLIBCXX_NPROCS 0 57 #endif 58 59 #if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1) 60 61 namespace std _GLIBCXX_VISIBILITY(default) 62 { 63 namespace 64 { 65 extern "C" void* 66 execute_native_thread_routine(void* __p) 67 { 68 thread::_Impl_base* __t = static_cast<thread::_Impl_base*>(__p); 69 thread::__shared_base_type __local; 70 __local.swap(__t->_M_this_ptr); 71 72 __try 73 { 74 __t->_M_run(); 75 } 76 __catch(const __cxxabiv1::__forced_unwind&) 77 { 78 __throw_exception_again; 79 } 80 __catch(...) 81 { 82 std::terminate(); 83 } 84 85 return 0; 86 } 87 } 88 89 _GLIBCXX_BEGIN_NAMESPACE_VERSION 90 91 void 92 thread::join() 93 { 94 int __e = EINVAL; 95 96 if (_M_id != id()) 97 __e = __gthread_join(_M_id._M_thread, 0); 98 99 if (__e) 100 __throw_system_error(__e); 101 102 _M_id = id(); 103 } 104 105 void 106 thread::detach() 107 { 108 int __e = EINVAL; 109 110 if (_M_id != id()) 111 __e = __gthread_detach(_M_id._M_thread); 112 113 if (__e) 114 __throw_system_error(__e); 115 116 _M_id = id(); 117 } 118 119 void 120 thread::_M_start_thread(__shared_base_type __b) 121 { 122 if (!__gthread_active_p()) 123 __throw_system_error(int(errc::operation_not_permitted)); 124 125 __b->_M_this_ptr = __b; 126 int __e = __gthread_create(&_M_id._M_thread, 127 &execute_native_thread_routine, __b.get()); 128 if (__e) 129 { 130 __b->_M_this_ptr.reset(); 131 __throw_system_error(__e); 132 } 133 } 134 135 unsigned int 136 thread::hardware_concurrency() noexcept 137 { 138 int __n = _GLIBCXX_NPROCS; 139 if (__n < 0) 140 __n = 0; 141 return __n; 142 } 143 144 _GLIBCXX_END_NAMESPACE_VERSION 145 } // namespace std 146 147 #endif // _GLIBCXX_HAS_GTHREADS && _GLIBCXX_USE_C99_STDINT_TR1 148