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>
get_nprocs()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*
execute_native_thread_routine(void * __p)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
join()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
detach()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
_M_start_thread(__shared_base_type __b)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
hardware_concurrency()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