File: | projects/openmp/runtime/src/z_Linux_util.cpp |
Warning: | line 198, column 13 Use of memory after it is freed |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* | |||||
2 | * z_Linux_util.cpp -- platform specific routines. | |||||
3 | */ | |||||
4 | ||||||
5 | //===----------------------------------------------------------------------===// | |||||
6 | // | |||||
7 | // The LLVM Compiler Infrastructure | |||||
8 | // | |||||
9 | // This file is dual licensed under the MIT and the University of Illinois Open | |||||
10 | // Source Licenses. See LICENSE.txt for details. | |||||
11 | // | |||||
12 | //===----------------------------------------------------------------------===// | |||||
13 | ||||||
14 | #include "kmp.h" | |||||
15 | #include "kmp_affinity.h" | |||||
16 | #include "kmp_i18n.h" | |||||
17 | #include "kmp_io.h" | |||||
18 | #include "kmp_itt.h" | |||||
19 | #include "kmp_lock.h" | |||||
20 | #include "kmp_stats.h" | |||||
21 | #include "kmp_str.h" | |||||
22 | #include "kmp_wait_release.h" | |||||
23 | #include "kmp_wrapper_getpid.h" | |||||
24 | ||||||
25 | #if !KMP_OS_FREEBSD0 && !KMP_OS_NETBSD0 | |||||
26 | #include <alloca.h> | |||||
27 | #endif | |||||
28 | #include <math.h> // HUGE_VAL. | |||||
29 | #include <sys/resource.h> | |||||
30 | #include <sys/syscall.h> | |||||
31 | #include <sys/time.h> | |||||
32 | #include <sys/times.h> | |||||
33 | #include <unistd.h> | |||||
34 | ||||||
35 | #if KMP_OS_LINUX1 && !KMP_OS_CNK0 | |||||
36 | #include <sys/sysinfo.h> | |||||
37 | #if KMP_USE_FUTEX(1 && !0 && (0 || 1 || KMP_ARCH_ARM || 0)) | |||||
38 | // We should really include <futex.h>, but that causes compatibility problems on | |||||
39 | // different Linux* OS distributions that either require that you include (or | |||||
40 | // break when you try to include) <pci/types.h>. Since all we need is the two | |||||
41 | // macros below (which are part of the kernel ABI, so can't change) we just | |||||
42 | // define the constants here and don't include <futex.h> | |||||
43 | #ifndef FUTEX_WAIT0 | |||||
44 | #define FUTEX_WAIT0 0 | |||||
45 | #endif | |||||
46 | #ifndef FUTEX_WAKE1 | |||||
47 | #define FUTEX_WAKE1 1 | |||||
48 | #endif | |||||
49 | #endif | |||||
50 | #elif KMP_OS_DARWIN0 | |||||
51 | #include <mach/mach.h> | |||||
52 | #include <sys/sysctl.h> | |||||
53 | #elif KMP_OS_FREEBSD0 | |||||
54 | #include <pthread_np.h> | |||||
55 | #endif | |||||
56 | ||||||
57 | #include <ctype.h> | |||||
58 | #include <dirent.h> | |||||
59 | #include <fcntl.h> | |||||
60 | ||||||
61 | #include "tsan_annotations.h" | |||||
62 | ||||||
63 | struct kmp_sys_timer { | |||||
64 | struct timespec start; | |||||
65 | }; | |||||
66 | ||||||
67 | // Convert timespec to nanoseconds. | |||||
68 | #define TS2NS(timespec)(((timespec).tv_sec * 1e9) + (timespec).tv_nsec) (((timespec).tv_sec * 1e9) + (timespec).tv_nsec) | |||||
69 | ||||||
70 | static struct kmp_sys_timer __kmp_sys_timer_data; | |||||
71 | ||||||
72 | #if KMP_HANDLE_SIGNALS(1 || 0) | |||||
73 | typedef void (*sig_func_t)(int); | |||||
74 | STATIC_EFI2_WORKAROUND struct sigaction __kmp_sighldrs[NSIG65]; | |||||
75 | static sigset_t __kmp_sigset; | |||||
76 | #endif | |||||
77 | ||||||
78 | static int __kmp_init_runtime = FALSE0; | |||||
79 | ||||||
80 | static int __kmp_fork_count = 0; | |||||
81 | ||||||
82 | static pthread_condattr_t __kmp_suspend_cond_attr; | |||||
83 | static pthread_mutexattr_t __kmp_suspend_mutex_attr; | |||||
84 | ||||||
85 | static kmp_cond_align_t __kmp_wait_cv; | |||||
86 | static kmp_mutex_align_t __kmp_wait_mx; | |||||
87 | ||||||
88 | kmp_uint64 __kmp_ticks_per_msec = 1000000; | |||||
89 | ||||||
90 | #ifdef DEBUG_SUSPEND | |||||
91 | static void __kmp_print_cond(char *buffer, kmp_cond_align_t *cond) { | |||||
92 | KMP_SNPRINTFsnprintf(buffer, 128, "(cond (lock (%ld, %d)), (descr (%p)))", | |||||
93 | cond->c_cond.__c_lock.__status, cond->c_cond.__c_lock.__spinlock, | |||||
94 | cond->c_cond.__c_waiting); | |||||
95 | } | |||||
96 | #endif | |||||
97 | ||||||
98 | #if (KMP_OS_LINUX1 && KMP_AFFINITY_SUPPORTED1) | |||||
99 | ||||||
100 | /* Affinity support */ | |||||
101 | ||||||
102 | void __kmp_affinity_bind_thread(int which) { | |||||
103 | KMP_ASSERT2(KMP_AFFINITY_CAPABLE(),if (!((__kmp_affin_mask_size > 0))) { __kmp_debug_assert(( "Illegal set affinity operation when not capable"), "/build/llvm-toolchain-snapshot-8~svn345461/projects/openmp/runtime/src/z_Linux_util.cpp" , 104); } | |||||
104 | "Illegal set affinity operation when not capable")if (!((__kmp_affin_mask_size > 0))) { __kmp_debug_assert(( "Illegal set affinity operation when not capable"), "/build/llvm-toolchain-snapshot-8~svn345461/projects/openmp/runtime/src/z_Linux_util.cpp" , 104); }; | |||||
105 | ||||||
106 | kmp_affin_mask_t *mask; | |||||
107 | KMP_CPU_ALLOC_ON_STACK(mask)(mask = __kmp_affinity_dispatch->allocate_mask()); | |||||
108 | KMP_CPU_ZERO(mask)(mask)->zero(); | |||||
109 | KMP_CPU_SET(which, mask)(mask)->set(which); | |||||
110 | __kmp_set_system_affinity(mask, TRUE)(mask)->set_system_affinity((!0)); | |||||
111 | KMP_CPU_FREE_FROM_STACK(mask)__kmp_affinity_dispatch->deallocate_mask(mask); | |||||
112 | } | |||||
113 | ||||||
114 | /* Determine if we can access affinity functionality on this version of | |||||
115 | * Linux* OS by checking __NR_sched_{get,set}affinity system calls, and set | |||||
116 | * __kmp_affin_mask_size to the appropriate value (0 means not capable). */ | |||||
117 | void __kmp_affinity_determine_capable(const char *env_var) { | |||||
118 | // Check and see if the OS supports thread affinity. | |||||
119 | ||||||
120 | #define KMP_CPU_SET_SIZE_LIMIT(1024 * 1024) (1024 * 1024) | |||||
121 | ||||||
122 | int gCode; | |||||
123 | int sCode; | |||||
124 | unsigned char *buf; | |||||
125 | buf = (unsigned char *)KMP_INTERNAL_MALLOC(KMP_CPU_SET_SIZE_LIMIT)malloc((1024 * 1024)); | |||||
| ||||||
126 | ||||||
127 | // If Linux* OS: | |||||
128 | // If the syscall fails or returns a suggestion for the size, | |||||
129 | // then we don't have to search for an appropriate size. | |||||
130 | gCode = syscall(__NR_sched_getaffinity204, 0, KMP_CPU_SET_SIZE_LIMIT(1024 * 1024), buf); | |||||
131 | KA_TRACE(30, ("__kmp_affinity_determine_capable: "if (kmp_a_debug >= 30) { __kmp_debug_printf ("__kmp_affinity_determine_capable: " "initial getaffinity call returned %d errno = %d\n", gCode, ( *__errno_location ())); } | |||||
132 | "initial getaffinity call returned %d errno = %d\n",if (kmp_a_debug >= 30) { __kmp_debug_printf ("__kmp_affinity_determine_capable: " "initial getaffinity call returned %d errno = %d\n", gCode, ( *__errno_location ())); } | |||||
133 | gCode, errno))if (kmp_a_debug >= 30) { __kmp_debug_printf ("__kmp_affinity_determine_capable: " "initial getaffinity call returned %d errno = %d\n", gCode, ( *__errno_location ())); }; | |||||
134 | ||||||
135 | // if ((gCode < 0) && (errno == ENOSYS)) | |||||
136 | if (gCode < 0) { | |||||
137 | // System call not supported | |||||
138 | if (__kmp_affinity_verbose || | |||||
139 | (__kmp_affinity_warnings && (__kmp_affinity_type != affinity_none) && | |||||
140 | (__kmp_affinity_type != affinity_default) && | |||||
141 | (__kmp_affinity_type != affinity_disabled))) { | |||||
142 | int error = errno(*__errno_location ()); | |||||
143 | kmp_msg_t err_code = KMP_ERR(error)__kmp_msg_error_code(error); | |||||
144 | __kmp_msg(kmp_ms_warning, KMP_MSG(GetAffSysCallNotSupported, env_var)__kmp_msg_format(kmp_i18n_msg_GetAffSysCallNotSupported, env_var ), | |||||
145 | err_code, __kmp_msg_null); | |||||
146 | if (__kmp_generate_warnings == kmp_warnings_off) { | |||||
147 | __kmp_str_free(&err_code.str); | |||||
148 | } | |||||
149 | } | |||||
150 | KMP_AFFINITY_DISABLE()(__kmp_affin_mask_size = 0); | |||||
151 | KMP_INTERNAL_FREE(buf)free(buf); | |||||
152 | return; | |||||
153 | } | |||||
154 | if (gCode > 0) { // Linux* OS only | |||||
155 | // The optimal situation: the OS returns the size of the buffer it expects. | |||||
156 | // | |||||
157 | // A verification of correct behavior is that Isetaffinity on a NULL | |||||
158 | // buffer with the same size fails with errno set to EFAULT. | |||||
159 | sCode = syscall(__NR_sched_setaffinity203, 0, gCode, NULL__null); | |||||
160 | KA_TRACE(30, ("__kmp_affinity_determine_capable: "if (kmp_a_debug >= 30) { __kmp_debug_printf ("__kmp_affinity_determine_capable: " "setaffinity for mask size %d returned %d errno = %d\n", gCode , sCode, (*__errno_location ())); } | |||||
161 | "setaffinity for mask size %d returned %d errno = %d\n",if (kmp_a_debug >= 30) { __kmp_debug_printf ("__kmp_affinity_determine_capable: " "setaffinity for mask size %d returned %d errno = %d\n", gCode , sCode, (*__errno_location ())); } | |||||
162 | gCode, sCode, errno))if (kmp_a_debug >= 30) { __kmp_debug_printf ("__kmp_affinity_determine_capable: " "setaffinity for mask size %d returned %d errno = %d\n", gCode , sCode, (*__errno_location ())); }; | |||||
163 | if (sCode < 0) { | |||||
164 | if (errno(*__errno_location ()) == ENOSYS38) { | |||||
165 | if (__kmp_affinity_verbose || | |||||
166 | (__kmp_affinity_warnings && | |||||
167 | (__kmp_affinity_type != affinity_none) && | |||||
168 | (__kmp_affinity_type != affinity_default) && | |||||
169 | (__kmp_affinity_type != affinity_disabled))) { | |||||
170 | int error = errno(*__errno_location ()); | |||||
171 | kmp_msg_t err_code = KMP_ERR(error)__kmp_msg_error_code(error); | |||||
172 | __kmp_msg(kmp_ms_warning, KMP_MSG(SetAffSysCallNotSupported, env_var)__kmp_msg_format(kmp_i18n_msg_SetAffSysCallNotSupported, env_var ), | |||||
173 | err_code, __kmp_msg_null); | |||||
174 | if (__kmp_generate_warnings == kmp_warnings_off) { | |||||
175 | __kmp_str_free(&err_code.str); | |||||
176 | } | |||||
177 | } | |||||
178 | KMP_AFFINITY_DISABLE()(__kmp_affin_mask_size = 0); | |||||
179 | KMP_INTERNAL_FREE(buf)free(buf); | |||||
180 | } | |||||
181 | if (errno(*__errno_location ()) == EFAULT14) { | |||||
182 | KMP_AFFINITY_ENABLE(gCode)(__kmp_affin_mask_size = gCode); | |||||
183 | KA_TRACE(10, ("__kmp_affinity_determine_capable: "if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_affinity_determine_capable: " "affinity supported (mask size %d)\n", (int)__kmp_affin_mask_size ); } | |||||
184 | "affinity supported (mask size %d)\n",if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_affinity_determine_capable: " "affinity supported (mask size %d)\n", (int)__kmp_affin_mask_size ); } | |||||
185 | (int)__kmp_affin_mask_size))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_affinity_determine_capable: " "affinity supported (mask size %d)\n", (int)__kmp_affin_mask_size ); }; | |||||
186 | KMP_INTERNAL_FREE(buf)free(buf); | |||||
187 | return; | |||||
188 | } | |||||
189 | } | |||||
190 | } | |||||
191 | ||||||
192 | // Call the getaffinity system call repeatedly with increasing set sizes | |||||
193 | // until we succeed, or reach an upper bound on the search. | |||||
194 | KA_TRACE(30, ("__kmp_affinity_determine_capable: "if (kmp_a_debug >= 30) { __kmp_debug_printf ("__kmp_affinity_determine_capable: " "searching for proper set size\n"); } | |||||
195 | "searching for proper set size\n"))if (kmp_a_debug >= 30) { __kmp_debug_printf ("__kmp_affinity_determine_capable: " "searching for proper set size\n"); }; | |||||
196 | int size; | |||||
197 | for (size = 1; size <= KMP_CPU_SET_SIZE_LIMIT(1024 * 1024); size *= 2) { | |||||
198 | gCode = syscall(__NR_sched_getaffinity204, 0, size, buf); | |||||
| ||||||
199 | KA_TRACE(30, ("__kmp_affinity_determine_capable: "if (kmp_a_debug >= 30) { __kmp_debug_printf ("__kmp_affinity_determine_capable: " "getaffinity for mask size %d returned %d errno = %d\n", size , gCode, (*__errno_location ())); } | |||||
200 | "getaffinity for mask size %d returned %d errno = %d\n",if (kmp_a_debug >= 30) { __kmp_debug_printf ("__kmp_affinity_determine_capable: " "getaffinity for mask size %d returned %d errno = %d\n", size , gCode, (*__errno_location ())); } | |||||
201 | size, gCode, errno))if (kmp_a_debug >= 30) { __kmp_debug_printf ("__kmp_affinity_determine_capable: " "getaffinity for mask size %d returned %d errno = %d\n", size , gCode, (*__errno_location ())); }; | |||||
202 | ||||||
203 | if (gCode < 0) { | |||||
204 | if (errno(*__errno_location ()) == ENOSYS38) { | |||||
205 | // We shouldn't get here | |||||
206 | KA_TRACE(30, ("__kmp_affinity_determine_capable: "if (kmp_a_debug >= 30) { __kmp_debug_printf ("__kmp_affinity_determine_capable: " "inconsistent OS call behavior: errno == ENOSYS for mask " "size %d\n" , size); } | |||||
207 | "inconsistent OS call behavior: errno == ENOSYS for mask "if (kmp_a_debug >= 30) { __kmp_debug_printf ("__kmp_affinity_determine_capable: " "inconsistent OS call behavior: errno == ENOSYS for mask " "size %d\n" , size); } | |||||
208 | "size %d\n",if (kmp_a_debug >= 30) { __kmp_debug_printf ("__kmp_affinity_determine_capable: " "inconsistent OS call behavior: errno == ENOSYS for mask " "size %d\n" , size); } | |||||
209 | size))if (kmp_a_debug >= 30) { __kmp_debug_printf ("__kmp_affinity_determine_capable: " "inconsistent OS call behavior: errno == ENOSYS for mask " "size %d\n" , size); }; | |||||
210 | if (__kmp_affinity_verbose || | |||||
211 | (__kmp_affinity_warnings && | |||||
212 | (__kmp_affinity_type != affinity_none) && | |||||
213 | (__kmp_affinity_type != affinity_default) && | |||||
214 | (__kmp_affinity_type != affinity_disabled))) { | |||||
215 | int error = errno(*__errno_location ()); | |||||
216 | kmp_msg_t err_code = KMP_ERR(error)__kmp_msg_error_code(error); | |||||
217 | __kmp_msg(kmp_ms_warning, KMP_MSG(GetAffSysCallNotSupported, env_var)__kmp_msg_format(kmp_i18n_msg_GetAffSysCallNotSupported, env_var ), | |||||
218 | err_code, __kmp_msg_null); | |||||
219 | if (__kmp_generate_warnings == kmp_warnings_off) { | |||||
220 | __kmp_str_free(&err_code.str); | |||||
221 | } | |||||
222 | } | |||||
223 | KMP_AFFINITY_DISABLE()(__kmp_affin_mask_size = 0); | |||||
224 | KMP_INTERNAL_FREE(buf)free(buf); | |||||
225 | return; | |||||
226 | } | |||||
227 | continue; | |||||
228 | } | |||||
229 | ||||||
230 | sCode = syscall(__NR_sched_setaffinity203, 0, gCode, NULL__null); | |||||
231 | KA_TRACE(30, ("__kmp_affinity_determine_capable: "if (kmp_a_debug >= 30) { __kmp_debug_printf ("__kmp_affinity_determine_capable: " "setaffinity for mask size %d returned %d errno = %d\n", gCode , sCode, (*__errno_location ())); } | |||||
232 | "setaffinity for mask size %d returned %d errno = %d\n",if (kmp_a_debug >= 30) { __kmp_debug_printf ("__kmp_affinity_determine_capable: " "setaffinity for mask size %d returned %d errno = %d\n", gCode , sCode, (*__errno_location ())); } | |||||
233 | gCode, sCode, errno))if (kmp_a_debug >= 30) { __kmp_debug_printf ("__kmp_affinity_determine_capable: " "setaffinity for mask size %d returned %d errno = %d\n", gCode , sCode, (*__errno_location ())); }; | |||||
234 | if (sCode < 0) { | |||||
235 | if (errno(*__errno_location ()) == ENOSYS38) { // Linux* OS only | |||||
236 | // We shouldn't get here | |||||
237 | KA_TRACE(30, ("__kmp_affinity_determine_capable: "if (kmp_a_debug >= 30) { __kmp_debug_printf ("__kmp_affinity_determine_capable: " "inconsistent OS call behavior: errno == ENOSYS for mask " "size %d\n" , size); } | |||||
238 | "inconsistent OS call behavior: errno == ENOSYS for mask "if (kmp_a_debug >= 30) { __kmp_debug_printf ("__kmp_affinity_determine_capable: " "inconsistent OS call behavior: errno == ENOSYS for mask " "size %d\n" , size); } | |||||
239 | "size %d\n",if (kmp_a_debug >= 30) { __kmp_debug_printf ("__kmp_affinity_determine_capable: " "inconsistent OS call behavior: errno == ENOSYS for mask " "size %d\n" , size); } | |||||
240 | size))if (kmp_a_debug >= 30) { __kmp_debug_printf ("__kmp_affinity_determine_capable: " "inconsistent OS call behavior: errno == ENOSYS for mask " "size %d\n" , size); }; | |||||
241 | if (__kmp_affinity_verbose || | |||||
242 | (__kmp_affinity_warnings && | |||||
243 | (__kmp_affinity_type != affinity_none) && | |||||
244 | (__kmp_affinity_type != affinity_default) && | |||||
245 | (__kmp_affinity_type != affinity_disabled))) { | |||||
246 | int error = errno(*__errno_location ()); | |||||
247 | kmp_msg_t err_code = KMP_ERR(error)__kmp_msg_error_code(error); | |||||
248 | __kmp_msg(kmp_ms_warning, KMP_MSG(SetAffSysCallNotSupported, env_var)__kmp_msg_format(kmp_i18n_msg_SetAffSysCallNotSupported, env_var ), | |||||
249 | err_code, __kmp_msg_null); | |||||
250 | if (__kmp_generate_warnings == kmp_warnings_off) { | |||||
251 | __kmp_str_free(&err_code.str); | |||||
252 | } | |||||
253 | } | |||||
254 | KMP_AFFINITY_DISABLE()(__kmp_affin_mask_size = 0); | |||||
255 | KMP_INTERNAL_FREE(buf)free(buf); | |||||
256 | return; | |||||
257 | } | |||||
258 | if (errno(*__errno_location ()) == EFAULT14) { | |||||
259 | KMP_AFFINITY_ENABLE(gCode)(__kmp_affin_mask_size = gCode); | |||||
260 | KA_TRACE(10, ("__kmp_affinity_determine_capable: "if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_affinity_determine_capable: " "affinity supported (mask size %d)\n", (int)__kmp_affin_mask_size ); } | |||||
261 | "affinity supported (mask size %d)\n",if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_affinity_determine_capable: " "affinity supported (mask size %d)\n", (int)__kmp_affin_mask_size ); } | |||||
262 | (int)__kmp_affin_mask_size))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_affinity_determine_capable: " "affinity supported (mask size %d)\n", (int)__kmp_affin_mask_size ); }; | |||||
263 | KMP_INTERNAL_FREE(buf)free(buf); | |||||
264 | return; | |||||
265 | } | |||||
266 | } | |||||
267 | } | |||||
268 | // save uncaught error code | |||||
269 | // int error = errno; | |||||
270 | KMP_INTERNAL_FREE(buf)free(buf); | |||||
271 | // restore uncaught error code, will be printed at the next KMP_WARNING below | |||||
272 | // errno = error; | |||||
273 | ||||||
274 | // Affinity is not supported | |||||
275 | KMP_AFFINITY_DISABLE()(__kmp_affin_mask_size = 0); | |||||
276 | KA_TRACE(10, ("__kmp_affinity_determine_capable: "if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_affinity_determine_capable: " "cannot determine mask size - affinity not supported\n"); } | |||||
277 | "cannot determine mask size - affinity not supported\n"))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_affinity_determine_capable: " "cannot determine mask size - affinity not supported\n"); }; | |||||
278 | if (__kmp_affinity_verbose || | |||||
279 | (__kmp_affinity_warnings && (__kmp_affinity_type != affinity_none) && | |||||
280 | (__kmp_affinity_type != affinity_default) && | |||||
281 | (__kmp_affinity_type != affinity_disabled))) { | |||||
282 | KMP_WARNING(AffCantGetMaskSize, env_var)__kmp_msg(kmp_ms_warning, __kmp_msg_format(kmp_i18n_msg_AffCantGetMaskSize , env_var), __kmp_msg_null); | |||||
283 | } | |||||
284 | } | |||||
285 | ||||||
286 | #endif // KMP_OS_LINUX && KMP_AFFINITY_SUPPORTED | |||||
287 | ||||||
288 | #if KMP_USE_FUTEX(1 && !0 && (0 || 1 || KMP_ARCH_ARM || 0)) | |||||
289 | ||||||
290 | int __kmp_futex_determine_capable() { | |||||
291 | int loc = 0; | |||||
292 | int rc = syscall(__NR_futex202, &loc, FUTEX_WAKE1, 1, NULL__null, NULL__null, 0); | |||||
293 | int retval = (rc == 0) || (errno(*__errno_location ()) != ENOSYS38); | |||||
294 | ||||||
295 | KA_TRACE(10,if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_futex_determine_capable: rc = %d errno = %d\n" , rc, (*__errno_location ())); } | |||||
296 | ("__kmp_futex_determine_capable: rc = %d errno = %d\n", rc, errno))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_futex_determine_capable: rc = %d errno = %d\n" , rc, (*__errno_location ())); }; | |||||
297 | KA_TRACE(10, ("__kmp_futex_determine_capable: futex syscall%s supported\n",if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_futex_determine_capable: futex syscall%s supported\n" , retval ? "" : " not"); } | |||||
298 | retval ? "" : " not"))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_futex_determine_capable: futex syscall%s supported\n" , retval ? "" : " not"); }; | |||||
299 | ||||||
300 | return retval; | |||||
301 | } | |||||
302 | ||||||
303 | #endif // KMP_USE_FUTEX | |||||
304 | ||||||
305 | #if (KMP_ARCH_X860 || KMP_ARCH_X86_641) && (!KMP_ASM_INTRINS1) | |||||
306 | /* Only 32-bit "add-exchange" instruction on IA-32 architecture causes us to | |||||
307 | use compare_and_store for these routines */ | |||||
308 | ||||||
309 | kmp_int8 __kmp_test_then_or8(volatile kmp_int8 *p, kmp_int8 d) { | |||||
310 | kmp_int8 old_value, new_value; | |||||
311 | ||||||
312 | old_value = TCR_1(*p)(*p); | |||||
313 | new_value = old_value | d; | |||||
314 | ||||||
315 | while (!KMP_COMPARE_AND_STORE_REL8(p, old_value, new_value)__sync_bool_compare_and_swap((volatile kmp_uint8 *)(p), (kmp_uint8 )(old_value), (kmp_uint8)(new_value))) { | |||||
316 | KMP_CPU_PAUSE()__kmp_x86_pause(); | |||||
317 | old_value = TCR_1(*p)(*p); | |||||
318 | new_value = old_value | d; | |||||
319 | } | |||||
320 | return old_value; | |||||
321 | } | |||||
322 | ||||||
323 | kmp_int8 __kmp_test_then_and8(volatile kmp_int8 *p, kmp_int8 d) { | |||||
324 | kmp_int8 old_value, new_value; | |||||
325 | ||||||
326 | old_value = TCR_1(*p)(*p); | |||||
327 | new_value = old_value & d; | |||||
328 | ||||||
329 | while (!KMP_COMPARE_AND_STORE_REL8(p, old_value, new_value)__sync_bool_compare_and_swap((volatile kmp_uint8 *)(p), (kmp_uint8 )(old_value), (kmp_uint8)(new_value))) { | |||||
330 | KMP_CPU_PAUSE()__kmp_x86_pause(); | |||||
331 | old_value = TCR_1(*p)(*p); | |||||
332 | new_value = old_value & d; | |||||
333 | } | |||||
334 | return old_value; | |||||
335 | } | |||||
336 | ||||||
337 | kmp_uint32 __kmp_test_then_or32(volatile kmp_uint32 *p, kmp_uint32 d) { | |||||
338 | kmp_uint32 old_value, new_value; | |||||
339 | ||||||
340 | old_value = TCR_4(*p)(*p); | |||||
341 | new_value = old_value | d; | |||||
342 | ||||||
343 | while (!KMP_COMPARE_AND_STORE_REL32(p, old_value, new_value)__sync_bool_compare_and_swap((volatile kmp_uint32 *)(p), (kmp_uint32 )(old_value), (kmp_uint32)(new_value))) { | |||||
344 | KMP_CPU_PAUSE()__kmp_x86_pause(); | |||||
345 | old_value = TCR_4(*p)(*p); | |||||
346 | new_value = old_value | d; | |||||
347 | } | |||||
348 | return old_value; | |||||
349 | } | |||||
350 | ||||||
351 | kmp_uint32 __kmp_test_then_and32(volatile kmp_uint32 *p, kmp_uint32 d) { | |||||
352 | kmp_uint32 old_value, new_value; | |||||
353 | ||||||
354 | old_value = TCR_4(*p)(*p); | |||||
355 | new_value = old_value & d; | |||||
356 | ||||||
357 | while (!KMP_COMPARE_AND_STORE_REL32(p, old_value, new_value)__sync_bool_compare_and_swap((volatile kmp_uint32 *)(p), (kmp_uint32 )(old_value), (kmp_uint32)(new_value))) { | |||||
358 | KMP_CPU_PAUSE()__kmp_x86_pause(); | |||||
359 | old_value = TCR_4(*p)(*p); | |||||
360 | new_value = old_value & d; | |||||
361 | } | |||||
362 | return old_value; | |||||
363 | } | |||||
364 | ||||||
365 | #if KMP_ARCH_X860 | |||||
366 | kmp_int8 __kmp_test_then_add8(volatile kmp_int8 *p, kmp_int8 d) { | |||||
367 | kmp_int8 old_value, new_value; | |||||
368 | ||||||
369 | old_value = TCR_1(*p)(*p); | |||||
370 | new_value = old_value + d; | |||||
371 | ||||||
372 | while (!KMP_COMPARE_AND_STORE_REL8(p, old_value, new_value)__sync_bool_compare_and_swap((volatile kmp_uint8 *)(p), (kmp_uint8 )(old_value), (kmp_uint8)(new_value))) { | |||||
373 | KMP_CPU_PAUSE()__kmp_x86_pause(); | |||||
374 | old_value = TCR_1(*p)(*p); | |||||
375 | new_value = old_value + d; | |||||
376 | } | |||||
377 | return old_value; | |||||
378 | } | |||||
379 | ||||||
380 | kmp_int64 __kmp_test_then_add64(volatile kmp_int64 *p, kmp_int64 d) { | |||||
381 | kmp_int64 old_value, new_value; | |||||
382 | ||||||
383 | old_value = TCR_8(*p)(*p); | |||||
384 | new_value = old_value + d; | |||||
385 | ||||||
386 | while (!KMP_COMPARE_AND_STORE_REL64(p, old_value, new_value)__sync_bool_compare_and_swap((volatile kmp_uint64 *)(p), (kmp_uint64 )(old_value), (kmp_uint64)(new_value))) { | |||||
387 | KMP_CPU_PAUSE()__kmp_x86_pause(); | |||||
388 | old_value = TCR_8(*p)(*p); | |||||
389 | new_value = old_value + d; | |||||
390 | } | |||||
391 | return old_value; | |||||
392 | } | |||||
393 | #endif /* KMP_ARCH_X86 */ | |||||
394 | ||||||
395 | kmp_uint64 __kmp_test_then_or64(volatile kmp_uint64 *p, kmp_uint64 d) { | |||||
396 | kmp_uint64 old_value, new_value; | |||||
397 | ||||||
398 | old_value = TCR_8(*p)(*p); | |||||
399 | new_value = old_value | d; | |||||
400 | while (!KMP_COMPARE_AND_STORE_REL64(p, old_value, new_value)__sync_bool_compare_and_swap((volatile kmp_uint64 *)(p), (kmp_uint64 )(old_value), (kmp_uint64)(new_value))) { | |||||
401 | KMP_CPU_PAUSE()__kmp_x86_pause(); | |||||
402 | old_value = TCR_8(*p)(*p); | |||||
403 | new_value = old_value | d; | |||||
404 | } | |||||
405 | return old_value; | |||||
406 | } | |||||
407 | ||||||
408 | kmp_uint64 __kmp_test_then_and64(volatile kmp_uint64 *p, kmp_uint64 d) { | |||||
409 | kmp_uint64 old_value, new_value; | |||||
410 | ||||||
411 | old_value = TCR_8(*p)(*p); | |||||
412 | new_value = old_value & d; | |||||
413 | while (!KMP_COMPARE_AND_STORE_REL64(p, old_value, new_value)__sync_bool_compare_and_swap((volatile kmp_uint64 *)(p), (kmp_uint64 )(old_value), (kmp_uint64)(new_value))) { | |||||
414 | KMP_CPU_PAUSE()__kmp_x86_pause(); | |||||
415 | old_value = TCR_8(*p)(*p); | |||||
416 | new_value = old_value & d; | |||||
417 | } | |||||
418 | return old_value; | |||||
419 | } | |||||
420 | ||||||
421 | #endif /* (KMP_ARCH_X86 || KMP_ARCH_X86_64) && (! KMP_ASM_INTRINS) */ | |||||
422 | ||||||
423 | void __kmp_terminate_thread(int gtid) { | |||||
424 | int status; | |||||
425 | kmp_info_t *th = __kmp_threads[gtid]; | |||||
426 | ||||||
427 | if (!th) | |||||
428 | return; | |||||
429 | ||||||
430 | #ifdef KMP_CANCEL_THREADS | |||||
431 | KA_TRACE(10, ("__kmp_terminate_thread: kill (%d)\n", gtid))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_terminate_thread: kill (%d)\n" , gtid); }; | |||||
432 | status = pthread_cancel(th->th.th_info.ds.ds_thread); | |||||
433 | if (status != 0 && status != ESRCH3) { | |||||
434 | __kmp_fatal(KMP_MSG(CantTerminateWorkerThread)__kmp_msg_format(kmp_i18n_msg_CantTerminateWorkerThread), KMP_ERR(status)__kmp_msg_error_code(status), | |||||
435 | __kmp_msg_null); | |||||
436 | } | |||||
437 | #endif | |||||
438 | __kmp_yield(TRUE(!0)); | |||||
439 | } // | |||||
440 | ||||||
441 | /* Set thread stack info according to values returned by pthread_getattr_np(). | |||||
442 | If values are unreasonable, assume call failed and use incremental stack | |||||
443 | refinement method instead. Returns TRUE if the stack parameters could be | |||||
444 | determined exactly, FALSE if incremental refinement is necessary. */ | |||||
445 | static kmp_int32 __kmp_set_stack_info(int gtid, kmp_info_t *th) { | |||||
446 | int stack_data; | |||||
447 | #if KMP_OS_LINUX1 || KMP_OS_FREEBSD0 || KMP_OS_NETBSD0 | |||||
448 | /* Linux* OS only -- no pthread_getattr_np support on OS X* */ | |||||
449 | pthread_attr_t attr; | |||||
450 | int status; | |||||
451 | size_t size = 0; | |||||
452 | void *addr = 0; | |||||
453 | ||||||
454 | /* Always do incremental stack refinement for ubermaster threads since the | |||||
455 | initial thread stack range can be reduced by sibling thread creation so | |||||
456 | pthread_attr_getstack may cause thread gtid aliasing */ | |||||
457 | if (!KMP_UBER_GTID(gtid)) { | |||||
458 | ||||||
459 | /* Fetch the real thread attributes */ | |||||
460 | status = pthread_attr_init(&attr); | |||||
461 | KMP_CHECK_SYSFAIL("pthread_attr_init", status){ if (status) { __kmp_fatal(__kmp_msg_format(kmp_i18n_msg_FunctionError , "pthread_attr_init"), __kmp_msg_error_code(status), __kmp_msg_null ); } }; | |||||
462 | #if KMP_OS_FREEBSD0 || KMP_OS_NETBSD0 | |||||
463 | status = pthread_attr_get_np(pthread_self(), &attr); | |||||
464 | KMP_CHECK_SYSFAIL("pthread_attr_get_np", status){ if (status) { __kmp_fatal(__kmp_msg_format(kmp_i18n_msg_FunctionError , "pthread_attr_get_np"), __kmp_msg_error_code(status), __kmp_msg_null ); } }; | |||||
465 | #else | |||||
466 | status = pthread_getattr_np(pthread_self(), &attr); | |||||
467 | KMP_CHECK_SYSFAIL("pthread_getattr_np", status){ if (status) { __kmp_fatal(__kmp_msg_format(kmp_i18n_msg_FunctionError , "pthread_getattr_np"), __kmp_msg_error_code(status), __kmp_msg_null ); } }; | |||||
468 | #endif | |||||
469 | status = pthread_attr_getstack(&attr, &addr, &size); | |||||
470 | KMP_CHECK_SYSFAIL("pthread_attr_getstack", status){ if (status) { __kmp_fatal(__kmp_msg_format(kmp_i18n_msg_FunctionError , "pthread_attr_getstack"), __kmp_msg_error_code(status), __kmp_msg_null ); } }; | |||||
471 | KA_TRACE(60,if (kmp_a_debug >= 60) { __kmp_debug_printf ("__kmp_set_stack_info: T#%d pthread_attr_getstack returned size:" " %lu, low addr: %p\n", gtid, size, addr); } | |||||
472 | ("__kmp_set_stack_info: T#%d pthread_attr_getstack returned size:"if (kmp_a_debug >= 60) { __kmp_debug_printf ("__kmp_set_stack_info: T#%d pthread_attr_getstack returned size:" " %lu, low addr: %p\n", gtid, size, addr); } | |||||
473 | " %lu, low addr: %p\n",if (kmp_a_debug >= 60) { __kmp_debug_printf ("__kmp_set_stack_info: T#%d pthread_attr_getstack returned size:" " %lu, low addr: %p\n", gtid, size, addr); } | |||||
474 | gtid, size, addr))if (kmp_a_debug >= 60) { __kmp_debug_printf ("__kmp_set_stack_info: T#%d pthread_attr_getstack returned size:" " %lu, low addr: %p\n", gtid, size, addr); }; | |||||
475 | status = pthread_attr_destroy(&attr); | |||||
476 | KMP_CHECK_SYSFAIL("pthread_attr_destroy", status){ if (status) { __kmp_fatal(__kmp_msg_format(kmp_i18n_msg_FunctionError , "pthread_attr_destroy"), __kmp_msg_error_code(status), __kmp_msg_null ); } }; | |||||
477 | } | |||||
478 | ||||||
479 | if (size != 0 && addr != 0) { // was stack parameter determination successful? | |||||
480 | /* Store the correct base and size */ | |||||
481 | TCW_PTR(th->th.th_info.ds.ds_stackbase, (((char *)addr) + size))((th->th.th_info.ds.ds_stackbase)) = (((((char *)addr) + size ))); | |||||
482 | TCW_PTR(th->th.th_info.ds.ds_stacksize, size)((th->th.th_info.ds.ds_stacksize)) = ((size)); | |||||
483 | TCW_4(th->th.th_info.ds.ds_stackgrow, FALSE)(th->th.th_info.ds.ds_stackgrow) = (0); | |||||
484 | return TRUE(!0); | |||||
485 | } | |||||
486 | #endif /* KMP_OS_LINUX || KMP_OS_FREEBSD || KMP_OS_NETBSD */ | |||||
487 | /* Use incremental refinement starting from initial conservative estimate */ | |||||
488 | TCW_PTR(th->th.th_info.ds.ds_stacksize, 0)((th->th.th_info.ds.ds_stacksize)) = ((0)); | |||||
489 | TCW_PTR(th->th.th_info.ds.ds_stackbase, &stack_data)((th->th.th_info.ds.ds_stackbase)) = ((&stack_data)); | |||||
490 | TCW_4(th->th.th_info.ds.ds_stackgrow, TRUE)(th->th.th_info.ds.ds_stackgrow) = ((!0)); | |||||
491 | return FALSE0; | |||||
492 | } | |||||
493 | ||||||
494 | static void *__kmp_launch_worker(void *thr) { | |||||
495 | int status, old_type, old_state; | |||||
496 | #ifdef KMP_BLOCK_SIGNALS | |||||
497 | sigset_t new_set, old_set; | |||||
498 | #endif /* KMP_BLOCK_SIGNALS */ | |||||
499 | void *exit_val; | |||||
500 | #if KMP_OS_LINUX1 || KMP_OS_FREEBSD0 || KMP_OS_NETBSD0 | |||||
501 | void *volatile padding = 0; | |||||
502 | #endif | |||||
503 | int gtid; | |||||
504 | ||||||
505 | gtid = ((kmp_info_t *)thr)->th.th_info.ds.ds_gtid; | |||||
506 | __kmp_gtid_set_specific(gtid); | |||||
507 | #ifdef KMP_TDATA_GTID1 | |||||
508 | __kmp_gtid = gtid; | |||||
509 | #endif | |||||
510 | #if KMP_STATS_ENABLED0 | |||||
511 | // set thread local index to point to thread-specific stats | |||||
512 | __kmp_stats_thread_ptr = ((kmp_info_t *)thr)->th.th_stats; | |||||
513 | __kmp_stats_thread_ptr->startLife(); | |||||
514 | KMP_SET_THREAD_STATE(IDLE)((void)0); | |||||
515 | KMP_INIT_PARTITIONED_TIMERS(OMP_idle)((void)0); | |||||
516 | #endif | |||||
517 | ||||||
518 | #if USE_ITT_BUILD1 | |||||
519 | __kmp_itt_thread_name(gtid); | |||||
520 | #endif /* USE_ITT_BUILD */ | |||||
521 | ||||||
522 | #if KMP_AFFINITY_SUPPORTED1 | |||||
523 | __kmp_affinity_set_init_mask(gtid, FALSE0); | |||||
524 | #endif | |||||
525 | ||||||
526 | #ifdef KMP_CANCEL_THREADS | |||||
527 | status = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUSPTHREAD_CANCEL_ASYNCHRONOUS, &old_type); | |||||
528 | KMP_CHECK_SYSFAIL("pthread_setcanceltype", status){ if (status) { __kmp_fatal(__kmp_msg_format(kmp_i18n_msg_FunctionError , "pthread_setcanceltype"), __kmp_msg_error_code(status), __kmp_msg_null ); } }; | |||||
529 | // josh todo: isn't PTHREAD_CANCEL_ENABLE default for newly-created threads? | |||||
530 | status = pthread_setcancelstate(PTHREAD_CANCEL_ENABLEPTHREAD_CANCEL_ENABLE, &old_state); | |||||
531 | KMP_CHECK_SYSFAIL("pthread_setcancelstate", status){ if (status) { __kmp_fatal(__kmp_msg_format(kmp_i18n_msg_FunctionError , "pthread_setcancelstate"), __kmp_msg_error_code(status), __kmp_msg_null ); } }; | |||||
532 | #endif | |||||
533 | ||||||
534 | #if KMP_ARCH_X860 || KMP_ARCH_X86_641 | |||||
535 | // Set FP control regs to be a copy of the parallel initialization thread's. | |||||
536 | __kmp_clear_x87_fpu_status_word(); | |||||
537 | __kmp_load_x87_fpu_control_word(&__kmp_init_x87_fpu_control_word); | |||||
538 | __kmp_load_mxcsr(&__kmp_init_mxcsr)_mm_setcsr(*(&__kmp_init_mxcsr)); | |||||
539 | #endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */ | |||||
540 | ||||||
541 | #ifdef KMP_BLOCK_SIGNALS | |||||
542 | status = sigfillset(&new_set); | |||||
543 | KMP_CHECK_SYSFAIL_ERRNO("sigfillset", status){ if (status != 0) { int error = (*__errno_location ()); __kmp_fatal (__kmp_msg_format(kmp_i18n_msg_FunctionError, "sigfillset"), __kmp_msg_error_code (error), __kmp_msg_null); } }; | |||||
544 | status = pthread_sigmask(SIG_BLOCK0, &new_set, &old_set); | |||||
545 | KMP_CHECK_SYSFAIL("pthread_sigmask", status){ if (status) { __kmp_fatal(__kmp_msg_format(kmp_i18n_msg_FunctionError , "pthread_sigmask"), __kmp_msg_error_code(status), __kmp_msg_null ); } }; | |||||
546 | #endif /* KMP_BLOCK_SIGNALS */ | |||||
547 | ||||||
548 | #if KMP_OS_LINUX1 || KMP_OS_FREEBSD0 || KMP_OS_NETBSD0 | |||||
549 | if (__kmp_stkoffset > 0 && gtid > 0) { | |||||
550 | padding = KMP_ALLOCA(gtid * __kmp_stkoffset)__builtin_alloca (gtid * __kmp_stkoffset); | |||||
551 | } | |||||
552 | #endif | |||||
553 | ||||||
554 | KMP_MB(); | |||||
555 | __kmp_set_stack_info(gtid, (kmp_info_t *)thr); | |||||
556 | ||||||
557 | __kmp_check_stack_overlap((kmp_info_t *)thr); | |||||
558 | ||||||
559 | exit_val = __kmp_launch_thread((kmp_info_t *)thr); | |||||
560 | ||||||
561 | #ifdef KMP_BLOCK_SIGNALS | |||||
562 | status = pthread_sigmask(SIG_SETMASK2, &old_set, NULL__null); | |||||
563 | KMP_CHECK_SYSFAIL("pthread_sigmask", status){ if (status) { __kmp_fatal(__kmp_msg_format(kmp_i18n_msg_FunctionError , "pthread_sigmask"), __kmp_msg_error_code(status), __kmp_msg_null ); } }; | |||||
564 | #endif /* KMP_BLOCK_SIGNALS */ | |||||
565 | ||||||
566 | return exit_val; | |||||
567 | } | |||||
568 | ||||||
569 | #if KMP_USE_MONITOR | |||||
570 | /* The monitor thread controls all of the threads in the complex */ | |||||
571 | ||||||
572 | static void *__kmp_launch_monitor(void *thr) { | |||||
573 | int status, old_type, old_state; | |||||
574 | #ifdef KMP_BLOCK_SIGNALS | |||||
575 | sigset_t new_set; | |||||
576 | #endif /* KMP_BLOCK_SIGNALS */ | |||||
577 | struct timespec interval; | |||||
578 | int yield_count; | |||||
579 | int yield_cycles = 0; | |||||
580 | ||||||
581 | KMP_MB(); /* Flush all pending memory write invalidates. */ | |||||
582 | ||||||
583 | KA_TRACE(10, ("__kmp_launch_monitor: #1 launched\n"))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_launch_monitor: #1 launched\n" ); }; | |||||
584 | ||||||
585 | /* register us as the monitor thread */ | |||||
586 | __kmp_gtid_set_specific(KMP_GTID_MONITOR(-4)); | |||||
587 | #ifdef KMP_TDATA_GTID1 | |||||
588 | __kmp_gtid = KMP_GTID_MONITOR(-4); | |||||
589 | #endif | |||||
590 | ||||||
591 | KMP_MB(); | |||||
592 | ||||||
593 | #if USE_ITT_BUILD1 | |||||
594 | // Instruct Intel(R) Threading Tools to ignore monitor thread. | |||||
595 | __kmp_itt_thread_ignore(); | |||||
596 | #endif /* USE_ITT_BUILD */ | |||||
597 | ||||||
598 | __kmp_set_stack_info(((kmp_info_t *)thr)->th.th_info.ds.ds_gtid, | |||||
599 | (kmp_info_t *)thr); | |||||
600 | ||||||
601 | __kmp_check_stack_overlap((kmp_info_t *)thr); | |||||
602 | ||||||
603 | #ifdef KMP_CANCEL_THREADS | |||||
604 | status = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUSPTHREAD_CANCEL_ASYNCHRONOUS, &old_type); | |||||
605 | KMP_CHECK_SYSFAIL("pthread_setcanceltype", status){ if (status) { __kmp_fatal(__kmp_msg_format(kmp_i18n_msg_FunctionError , "pthread_setcanceltype"), __kmp_msg_error_code(status), __kmp_msg_null ); } }; | |||||
606 | // josh todo: isn't PTHREAD_CANCEL_ENABLE default for newly-created threads? | |||||
607 | status = pthread_setcancelstate(PTHREAD_CANCEL_ENABLEPTHREAD_CANCEL_ENABLE, &old_state); | |||||
608 | KMP_CHECK_SYSFAIL("pthread_setcancelstate", status){ if (status) { __kmp_fatal(__kmp_msg_format(kmp_i18n_msg_FunctionError , "pthread_setcancelstate"), __kmp_msg_error_code(status), __kmp_msg_null ); } }; | |||||
609 | #endif | |||||
610 | ||||||
611 | #if KMP_REAL_TIME_FIX | |||||
612 | // This is a potential fix which allows application with real-time scheduling | |||||
613 | // policy work. However, decision about the fix is not made yet, so it is | |||||
614 | // disabled by default. | |||||
615 | { // Are program started with real-time scheduling policy? | |||||
616 | int sched = sched_getscheduler(0); | |||||
617 | if (sched == SCHED_FIFO1 || sched == SCHED_RR2) { | |||||
618 | // Yes, we are a part of real-time application. Try to increase the | |||||
619 | // priority of the monitor. | |||||
620 | struct sched_param param; | |||||
621 | int max_priority = sched_get_priority_max(sched); | |||||
622 | int rc; | |||||
623 | KMP_WARNING(RealTimeSchedNotSupported)__kmp_msg(kmp_ms_warning, __kmp_msg_format(kmp_i18n_msg_RealTimeSchedNotSupported ), __kmp_msg_null); | |||||
624 | sched_getparam(0, ¶m); | |||||
625 | if (param.sched_priority__sched_priority < max_priority) { | |||||
626 | param.sched_priority__sched_priority += 1; | |||||
627 | rc = sched_setscheduler(0, sched, ¶m); | |||||
628 | if (rc != 0) { | |||||
629 | int error = errno(*__errno_location ()); | |||||
630 | kmp_msg_t err_code = KMP_ERR(error)__kmp_msg_error_code(error); | |||||
631 | __kmp_msg(kmp_ms_warning, KMP_MSG(CantChangeMonitorPriority)__kmp_msg_format(kmp_i18n_msg_CantChangeMonitorPriority), | |||||
632 | err_code, KMP_MSG(MonitorWillStarve)__kmp_msg_format(kmp_i18n_msg_MonitorWillStarve), __kmp_msg_null); | |||||
633 | if (__kmp_generate_warnings == kmp_warnings_off) { | |||||
634 | __kmp_str_free(&err_code.str); | |||||
635 | } | |||||
636 | } | |||||
637 | } else { | |||||
638 | // We cannot abort here, because number of CPUs may be enough for all | |||||
639 | // the threads, including the monitor thread, so application could | |||||
640 | // potentially work... | |||||
641 | __kmp_msg(kmp_ms_warning, KMP_MSG(RunningAtMaxPriority)__kmp_msg_format(kmp_i18n_msg_RunningAtMaxPriority), | |||||
642 | KMP_MSG(MonitorWillStarve)__kmp_msg_format(kmp_i18n_msg_MonitorWillStarve), KMP_HNT(RunningAtMaxPriority)__kmp_msg_format(kmp_i18n_hnt_RunningAtMaxPriority), | |||||
643 | __kmp_msg_null); | |||||
644 | } | |||||
645 | } | |||||
646 | // AC: free thread that waits for monitor started | |||||
647 | TCW_4(__kmp_global.g.g_time.dt.t_value, 0)(__kmp_global.g.g_time.dt.t_value) = (0); | |||||
648 | } | |||||
649 | #endif // KMP_REAL_TIME_FIX | |||||
650 | ||||||
651 | KMP_MB(); /* Flush all pending memory write invalidates. */ | |||||
652 | ||||||
653 | if (__kmp_monitor_wakeups == 1) { | |||||
654 | interval.tv_sec = 1; | |||||
655 | interval.tv_nsec = 0; | |||||
656 | } else { | |||||
657 | interval.tv_sec = 0; | |||||
658 | interval.tv_nsec = (KMP_NSEC_PER_SEC1000000000L / __kmp_monitor_wakeups); | |||||
659 | } | |||||
660 | ||||||
661 | KA_TRACE(10, ("__kmp_launch_monitor: #2 monitor\n"))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_launch_monitor: #2 monitor\n" ); }; | |||||
662 | ||||||
663 | if (__kmp_yield_cycle) { | |||||
664 | __kmp_yielding_on = 0; /* Start out with yielding shut off */ | |||||
665 | yield_count = __kmp_yield_off_count; | |||||
666 | } else { | |||||
667 | __kmp_yielding_on = 1; /* Yielding is on permanently */ | |||||
668 | } | |||||
669 | ||||||
670 | while (!TCR_4(__kmp_global.g.g_done)(__kmp_global.g.g_done)) { | |||||
671 | struct timespec now; | |||||
672 | struct timeval tval; | |||||
673 | ||||||
674 | /* This thread monitors the state of the system */ | |||||
675 | ||||||
676 | KA_TRACE(15, ("__kmp_launch_monitor: update\n"))if (kmp_a_debug >= 15) { __kmp_debug_printf ("__kmp_launch_monitor: update\n" ); }; | |||||
677 | ||||||
678 | status = gettimeofday(&tval, NULL__null); | |||||
679 | KMP_CHECK_SYSFAIL_ERRNO("gettimeofday", status){ if (status != 0) { int error = (*__errno_location ()); __kmp_fatal (__kmp_msg_format(kmp_i18n_msg_FunctionError, "gettimeofday") , __kmp_msg_error_code(error), __kmp_msg_null); } }; | |||||
680 | TIMEVAL_TO_TIMESPEC(&tval, &now){ (&now)->tv_sec = (&tval)->tv_sec; (&now)-> tv_nsec = (&tval)->tv_usec * 1000; }; | |||||
681 | ||||||
682 | now.tv_sec += interval.tv_sec; | |||||
683 | now.tv_nsec += interval.tv_nsec; | |||||
684 | ||||||
685 | if (now.tv_nsec >= KMP_NSEC_PER_SEC1000000000L) { | |||||
686 | now.tv_sec += 1; | |||||
687 | now.tv_nsec -= KMP_NSEC_PER_SEC1000000000L; | |||||
688 | } | |||||
689 | ||||||
690 | status = pthread_mutex_lock(&__kmp_wait_mx.m_mutex); | |||||
691 | KMP_CHECK_SYSFAIL("pthread_mutex_lock", status){ if (status) { __kmp_fatal(__kmp_msg_format(kmp_i18n_msg_FunctionError , "pthread_mutex_lock"), __kmp_msg_error_code(status), __kmp_msg_null ); } }; | |||||
692 | // AC: the monitor should not fall asleep if g_done has been set | |||||
693 | if (!TCR_4(__kmp_global.g.g_done)(__kmp_global.g.g_done)) { // check once more under mutex | |||||
694 | status = pthread_cond_timedwait(&__kmp_wait_cv.c_cond, | |||||
695 | &__kmp_wait_mx.m_mutex, &now); | |||||
696 | if (status != 0) { | |||||
697 | if (status != ETIMEDOUT110 && status != EINTR4) { | |||||
698 | KMP_SYSFAIL("pthread_cond_timedwait", status)__kmp_fatal(__kmp_msg_format(kmp_i18n_msg_FunctionError, "pthread_cond_timedwait" ), __kmp_msg_error_code(status), __kmp_msg_null); | |||||
699 | } | |||||
700 | } | |||||
701 | } | |||||
702 | status = pthread_mutex_unlock(&__kmp_wait_mx.m_mutex); | |||||
703 | KMP_CHECK_SYSFAIL("pthread_mutex_unlock", status){ if (status) { __kmp_fatal(__kmp_msg_format(kmp_i18n_msg_FunctionError , "pthread_mutex_unlock"), __kmp_msg_error_code(status), __kmp_msg_null ); } }; | |||||
704 | ||||||
705 | if (__kmp_yield_cycle) { | |||||
706 | yield_cycles++; | |||||
707 | if ((yield_cycles % yield_count) == 0) { | |||||
708 | if (__kmp_yielding_on) { | |||||
709 | __kmp_yielding_on = 0; /* Turn it off now */ | |||||
710 | yield_count = __kmp_yield_off_count; | |||||
711 | } else { | |||||
712 | __kmp_yielding_on = 1; /* Turn it on now */ | |||||
713 | yield_count = __kmp_yield_on_count; | |||||
714 | } | |||||
715 | yield_cycles = 0; | |||||
716 | } | |||||
717 | } else { | |||||
718 | __kmp_yielding_on = 1; | |||||
719 | } | |||||
720 | ||||||
721 | TCW_4(__kmp_global.g.g_time.dt.t_value,(__kmp_global.g.g_time.dt.t_value) = ((__kmp_global.g.g_time. dt.t_value) + 1) | |||||
722 | TCR_4(__kmp_global.g.g_time.dt.t_value) + 1)(__kmp_global.g.g_time.dt.t_value) = ((__kmp_global.g.g_time. dt.t_value) + 1); | |||||
723 | ||||||
724 | KMP_MB(); /* Flush all pending memory write invalidates. */ | |||||
725 | } | |||||
726 | ||||||
727 | KA_TRACE(10, ("__kmp_launch_monitor: #3 cleanup\n"))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_launch_monitor: #3 cleanup\n" ); }; | |||||
728 | ||||||
729 | #ifdef KMP_BLOCK_SIGNALS | |||||
730 | status = sigfillset(&new_set); | |||||
731 | KMP_CHECK_SYSFAIL_ERRNO("sigfillset", status){ if (status != 0) { int error = (*__errno_location ()); __kmp_fatal (__kmp_msg_format(kmp_i18n_msg_FunctionError, "sigfillset"), __kmp_msg_error_code (error), __kmp_msg_null); } }; | |||||
732 | status = pthread_sigmask(SIG_UNBLOCK1, &new_set, NULL__null); | |||||
733 | KMP_CHECK_SYSFAIL("pthread_sigmask", status){ if (status) { __kmp_fatal(__kmp_msg_format(kmp_i18n_msg_FunctionError , "pthread_sigmask"), __kmp_msg_error_code(status), __kmp_msg_null ); } }; | |||||
734 | #endif /* KMP_BLOCK_SIGNALS */ | |||||
735 | ||||||
736 | KA_TRACE(10, ("__kmp_launch_monitor: #4 finished\n"))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_launch_monitor: #4 finished\n" ); }; | |||||
737 | ||||||
738 | if (__kmp_global.g.g_abort != 0) { | |||||
739 | /* now we need to terminate the worker threads */ | |||||
740 | /* the value of t_abort is the signal we caught */ | |||||
741 | ||||||
742 | int gtid; | |||||
743 | ||||||
744 | KA_TRACE(10, ("__kmp_launch_monitor: #5 terminate sig=%d\n",if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_launch_monitor: #5 terminate sig=%d\n" , __kmp_global.g.g_abort); } | |||||
745 | __kmp_global.g.g_abort))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_launch_monitor: #5 terminate sig=%d\n" , __kmp_global.g.g_abort); }; | |||||
746 | ||||||
747 | /* terminate the OpenMP worker threads */ | |||||
748 | /* TODO this is not valid for sibling threads!! | |||||
749 | * the uber master might not be 0 anymore.. */ | |||||
750 | for (gtid = 1; gtid < __kmp_threads_capacity; ++gtid) | |||||
751 | __kmp_terminate_thread(gtid); | |||||
752 | ||||||
753 | __kmp_cleanup(); | |||||
754 | ||||||
755 | KA_TRACE(10, ("__kmp_launch_monitor: #6 raise sig=%d\n",if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_launch_monitor: #6 raise sig=%d\n" , __kmp_global.g.g_abort); } | |||||
756 | __kmp_global.g.g_abort))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_launch_monitor: #6 raise sig=%d\n" , __kmp_global.g.g_abort); }; | |||||
757 | ||||||
758 | if (__kmp_global.g.g_abort > 0) | |||||
759 | raise(__kmp_global.g.g_abort); | |||||
760 | } | |||||
761 | ||||||
762 | KA_TRACE(10, ("__kmp_launch_monitor: #7 exit\n"))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_launch_monitor: #7 exit\n" ); }; | |||||
763 | ||||||
764 | return thr; | |||||
765 | } | |||||
766 | #endif // KMP_USE_MONITOR | |||||
767 | ||||||
768 | void __kmp_create_worker(int gtid, kmp_info_t *th, size_t stack_size) { | |||||
769 | pthread_t handle; | |||||
770 | pthread_attr_t thread_attr; | |||||
771 | int status; | |||||
772 | ||||||
773 | th->th.th_info.ds.ds_gtid = gtid; | |||||
774 | ||||||
775 | #if KMP_STATS_ENABLED0 | |||||
776 | // sets up worker thread stats | |||||
777 | __kmp_acquire_tas_lock(&__kmp_stats_lock, gtid); | |||||
778 | ||||||
779 | // th->th.th_stats is used to transfer thread-specific stats-pointer to | |||||
780 | // __kmp_launch_worker. So when thread is created (goes into | |||||
781 | // __kmp_launch_worker) it will set its thread local pointer to | |||||
782 | // th->th.th_stats | |||||
783 | if (!KMP_UBER_GTID(gtid)) { | |||||
784 | th->th.th_stats = __kmp_stats_list->push_back(gtid); | |||||
785 | } else { | |||||
786 | // For root threads, __kmp_stats_thread_ptr is set in __kmp_register_root(), | |||||
787 | // so set the th->th.th_stats field to it. | |||||
788 | th->th.th_stats = __kmp_stats_thread_ptr; | |||||
789 | } | |||||
790 | __kmp_release_tas_lock(&__kmp_stats_lock, gtid); | |||||
791 | ||||||
792 | #endif // KMP_STATS_ENABLED | |||||
793 | ||||||
794 | if (KMP_UBER_GTID(gtid)) { | |||||
795 | KA_TRACE(10, ("__kmp_create_worker: uber thread (%d)\n", gtid))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_create_worker: uber thread (%d)\n" , gtid); }; | |||||
796 | th->th.th_info.ds.ds_thread = pthread_self(); | |||||
797 | __kmp_set_stack_info(gtid, th); | |||||
798 | __kmp_check_stack_overlap(th); | |||||
799 | return; | |||||
800 | } | |||||
801 | ||||||
802 | KA_TRACE(10, ("__kmp_create_worker: try to create thread (%d)\n", gtid))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_create_worker: try to create thread (%d)\n" , gtid); }; | |||||
803 | ||||||
804 | KMP_MB(); /* Flush all pending memory write invalidates. */ | |||||
805 | ||||||
806 | #ifdef KMP_THREAD_ATTR | |||||
807 | status = pthread_attr_init(&thread_attr); | |||||
808 | if (status != 0) { | |||||
809 | __kmp_fatal(KMP_MSG(CantInitThreadAttrs)__kmp_msg_format(kmp_i18n_msg_CantInitThreadAttrs), KMP_ERR(status)__kmp_msg_error_code(status), __kmp_msg_null); | |||||
810 | } | |||||
811 | status = pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_JOINABLEPTHREAD_CREATE_JOINABLE); | |||||
812 | if (status != 0) { | |||||
813 | __kmp_fatal(KMP_MSG(CantSetWorkerState)__kmp_msg_format(kmp_i18n_msg_CantSetWorkerState), KMP_ERR(status)__kmp_msg_error_code(status), __kmp_msg_null); | |||||
814 | } | |||||
815 | ||||||
816 | /* Set stack size for this thread now. | |||||
817 | The multiple of 2 is there because on some machines, requesting an unusual | |||||
818 | stacksize causes the thread to have an offset before the dummy alloca() | |||||
819 | takes place to create the offset. Since we want the user to have a | |||||
820 | sufficient stacksize AND support a stack offset, we alloca() twice the | |||||
821 | offset so that the upcoming alloca() does not eliminate any premade offset, | |||||
822 | and also gives the user the stack space they requested for all threads */ | |||||
823 | stack_size += gtid * __kmp_stkoffset * 2; | |||||
824 | ||||||
825 | KA_TRACE(10, ("__kmp_create_worker: T#%d, default stacksize = %lu bytes, "if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_create_worker: T#%d, default stacksize = %lu bytes, " "__kmp_stksize = %lu bytes, final stacksize = %lu bytes\n", gtid , ((size_t)(4 * 1024 * 1024)), __kmp_stksize, stack_size); } | |||||
826 | "__kmp_stksize = %lu bytes, final stacksize = %lu bytes\n",if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_create_worker: T#%d, default stacksize = %lu bytes, " "__kmp_stksize = %lu bytes, final stacksize = %lu bytes\n", gtid , ((size_t)(4 * 1024 * 1024)), __kmp_stksize, stack_size); } | |||||
827 | gtid, KMP_DEFAULT_STKSIZE, __kmp_stksize, stack_size))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_create_worker: T#%d, default stacksize = %lu bytes, " "__kmp_stksize = %lu bytes, final stacksize = %lu bytes\n", gtid , ((size_t)(4 * 1024 * 1024)), __kmp_stksize, stack_size); }; | |||||
828 | ||||||
829 | #ifdef _POSIX_THREAD_ATTR_STACKSIZE200809L | |||||
830 | status = pthread_attr_setstacksize(&thread_attr, stack_size); | |||||
831 | #ifdef KMP_BACKUP_STKSIZE((size_t)(2 * 1024 * 1024)) | |||||
832 | if (status != 0) { | |||||
833 | if (!__kmp_env_stksize) { | |||||
834 | stack_size = KMP_BACKUP_STKSIZE((size_t)(2 * 1024 * 1024)) + gtid * __kmp_stkoffset; | |||||
835 | __kmp_stksize = KMP_BACKUP_STKSIZE((size_t)(2 * 1024 * 1024)); | |||||
836 | KA_TRACE(10, ("__kmp_create_worker: T#%d, default stacksize = %lu bytes, "if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_create_worker: T#%d, default stacksize = %lu bytes, " "__kmp_stksize = %lu bytes, (backup) final stacksize = %lu " "bytes\n", gtid, ((size_t)(4 * 1024 * 1024)), __kmp_stksize, stack_size); } | |||||
837 | "__kmp_stksize = %lu bytes, (backup) final stacksize = %lu "if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_create_worker: T#%d, default stacksize = %lu bytes, " "__kmp_stksize = %lu bytes, (backup) final stacksize = %lu " "bytes\n", gtid, ((size_t)(4 * 1024 * 1024)), __kmp_stksize, stack_size); } | |||||
838 | "bytes\n",if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_create_worker: T#%d, default stacksize = %lu bytes, " "__kmp_stksize = %lu bytes, (backup) final stacksize = %lu " "bytes\n", gtid, ((size_t)(4 * 1024 * 1024)), __kmp_stksize, stack_size); } | |||||
839 | gtid, KMP_DEFAULT_STKSIZE, __kmp_stksize, stack_size))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_create_worker: T#%d, default stacksize = %lu bytes, " "__kmp_stksize = %lu bytes, (backup) final stacksize = %lu " "bytes\n", gtid, ((size_t)(4 * 1024 * 1024)), __kmp_stksize, stack_size); }; | |||||
840 | status = pthread_attr_setstacksize(&thread_attr, stack_size); | |||||
841 | } | |||||
842 | } | |||||
843 | #endif /* KMP_BACKUP_STKSIZE */ | |||||
844 | if (status != 0) { | |||||
845 | __kmp_fatal(KMP_MSG(CantSetWorkerStackSize, stack_size)__kmp_msg_format(kmp_i18n_msg_CantSetWorkerStackSize, stack_size ), KMP_ERR(status)__kmp_msg_error_code(status), | |||||
846 | KMP_HNT(ChangeWorkerStackSize)__kmp_msg_format(kmp_i18n_hnt_ChangeWorkerStackSize), __kmp_msg_null); | |||||
847 | } | |||||
848 | #endif /* _POSIX_THREAD_ATTR_STACKSIZE */ | |||||
849 | ||||||
850 | #endif /* KMP_THREAD_ATTR */ | |||||
851 | ||||||
852 | status = | |||||
853 | pthread_create(&handle, &thread_attr, __kmp_launch_worker, (void *)th); | |||||
854 | if (status != 0 || !handle) { // ??? Why do we check handle?? | |||||
855 | #ifdef _POSIX_THREAD_ATTR_STACKSIZE200809L | |||||
856 | if (status == EINVAL22) { | |||||
857 | __kmp_fatal(KMP_MSG(CantSetWorkerStackSize, stack_size)__kmp_msg_format(kmp_i18n_msg_CantSetWorkerStackSize, stack_size ), KMP_ERR(status)__kmp_msg_error_code(status), | |||||
858 | KMP_HNT(IncreaseWorkerStackSize)__kmp_msg_format(kmp_i18n_hnt_IncreaseWorkerStackSize), __kmp_msg_null); | |||||
859 | } | |||||
860 | if (status == ENOMEM12) { | |||||
861 | __kmp_fatal(KMP_MSG(CantSetWorkerStackSize, stack_size)__kmp_msg_format(kmp_i18n_msg_CantSetWorkerStackSize, stack_size ), KMP_ERR(status)__kmp_msg_error_code(status), | |||||
862 | KMP_HNT(DecreaseWorkerStackSize)__kmp_msg_format(kmp_i18n_hnt_DecreaseWorkerStackSize), __kmp_msg_null); | |||||
863 | } | |||||
864 | #endif /* _POSIX_THREAD_ATTR_STACKSIZE */ | |||||
865 | if (status == EAGAIN11) { | |||||
866 | __kmp_fatal(KMP_MSG(NoResourcesForWorkerThread)__kmp_msg_format(kmp_i18n_msg_NoResourcesForWorkerThread), KMP_ERR(status)__kmp_msg_error_code(status), | |||||
867 | KMP_HNT(Decrease_NUM_THREADS)__kmp_msg_format(kmp_i18n_hnt_Decrease_NUM_THREADS), __kmp_msg_null); | |||||
868 | } | |||||
869 | KMP_SYSFAIL("pthread_create", status)__kmp_fatal(__kmp_msg_format(kmp_i18n_msg_FunctionError, "pthread_create" ), __kmp_msg_error_code(status), __kmp_msg_null); | |||||
870 | } | |||||
871 | ||||||
872 | th->th.th_info.ds.ds_thread = handle; | |||||
873 | ||||||
874 | #ifdef KMP_THREAD_ATTR | |||||
875 | status = pthread_attr_destroy(&thread_attr); | |||||
876 | if (status) { | |||||
877 | kmp_msg_t err_code = KMP_ERR(status)__kmp_msg_error_code(status); | |||||
878 | __kmp_msg(kmp_ms_warning, KMP_MSG(CantDestroyThreadAttrs)__kmp_msg_format(kmp_i18n_msg_CantDestroyThreadAttrs), err_code, | |||||
879 | __kmp_msg_null); | |||||
880 | if (__kmp_generate_warnings == kmp_warnings_off) { | |||||
881 | __kmp_str_free(&err_code.str); | |||||
882 | } | |||||
883 | } | |||||
884 | #endif /* KMP_THREAD_ATTR */ | |||||
885 | ||||||
886 | KMP_MB(); /* Flush all pending memory write invalidates. */ | |||||
887 | ||||||
888 | KA_TRACE(10, ("__kmp_create_worker: done creating thread (%d)\n", gtid))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_create_worker: done creating thread (%d)\n" , gtid); }; | |||||
889 | ||||||
890 | } // __kmp_create_worker | |||||
891 | ||||||
892 | #if KMP_USE_MONITOR | |||||
893 | void __kmp_create_monitor(kmp_info_t *th) { | |||||
894 | pthread_t handle; | |||||
895 | pthread_attr_t thread_attr; | |||||
896 | size_t size; | |||||
897 | int status; | |||||
898 | int auto_adj_size = FALSE0; | |||||
899 | ||||||
900 | if (__kmp_dflt_blocktime == KMP_MAX_BLOCKTIME(2147483647)) { | |||||
901 | // We don't need monitor thread in case of MAX_BLOCKTIME | |||||
902 | KA_TRACE(10, ("__kmp_create_monitor: skipping monitor thread because of "if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_create_monitor: skipping monitor thread because of " "MAX blocktime\n"); } | |||||
903 | "MAX blocktime\n"))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_create_monitor: skipping monitor thread because of " "MAX blocktime\n"); }; | |||||
904 | th->th.th_info.ds.ds_tid = 0; // this makes reap_monitor no-op | |||||
905 | th->th.th_info.ds.ds_gtid = 0; | |||||
906 | return; | |||||
907 | } | |||||
908 | KA_TRACE(10, ("__kmp_create_monitor: try to create monitor\n"))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_create_monitor: try to create monitor\n" ); }; | |||||
909 | ||||||
910 | KMP_MB(); /* Flush all pending memory write invalidates. */ | |||||
911 | ||||||
912 | th->th.th_info.ds.ds_tid = KMP_GTID_MONITOR(-4); | |||||
913 | th->th.th_info.ds.ds_gtid = KMP_GTID_MONITOR(-4); | |||||
914 | #if KMP_REAL_TIME_FIX | |||||
915 | TCW_4(__kmp_global.g.g_time.dt.t_value,(__kmp_global.g.g_time.dt.t_value) = (-1) | |||||
916 | -1)(__kmp_global.g.g_time.dt.t_value) = (-1); // Will use it for synchronization a bit later. | |||||
917 | #else | |||||
918 | TCW_4(__kmp_global.g.g_time.dt.t_value, 0)(__kmp_global.g.g_time.dt.t_value) = (0); | |||||
919 | #endif // KMP_REAL_TIME_FIX | |||||
920 | ||||||
921 | #ifdef KMP_THREAD_ATTR | |||||
922 | if (__kmp_monitor_stksize == 0) { | |||||
923 | __kmp_monitor_stksize = KMP_DEFAULT_MONITOR_STKSIZE; | |||||
924 | auto_adj_size = TRUE(!0); | |||||
925 | } | |||||
926 | status = pthread_attr_init(&thread_attr); | |||||
927 | if (status != 0) { | |||||
928 | __kmp_fatal(KMP_MSG(CantInitThreadAttrs)__kmp_msg_format(kmp_i18n_msg_CantInitThreadAttrs), KMP_ERR(status)__kmp_msg_error_code(status), __kmp_msg_null); | |||||
929 | } | |||||
930 | status = pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_JOINABLEPTHREAD_CREATE_JOINABLE); | |||||
931 | if (status != 0) { | |||||
932 | __kmp_fatal(KMP_MSG(CantSetMonitorState)__kmp_msg_format(kmp_i18n_msg_CantSetMonitorState), KMP_ERR(status)__kmp_msg_error_code(status), __kmp_msg_null); | |||||
933 | } | |||||
934 | ||||||
935 | #ifdef _POSIX_THREAD_ATTR_STACKSIZE200809L | |||||
936 | status = pthread_attr_getstacksize(&thread_attr, &size); | |||||
937 | KMP_CHECK_SYSFAIL("pthread_attr_getstacksize", status){ if (status) { __kmp_fatal(__kmp_msg_format(kmp_i18n_msg_FunctionError , "pthread_attr_getstacksize"), __kmp_msg_error_code(status), __kmp_msg_null); } }; | |||||
938 | #else | |||||
939 | size = __kmp_sys_min_stksize; | |||||
940 | #endif /* _POSIX_THREAD_ATTR_STACKSIZE */ | |||||
941 | #endif /* KMP_THREAD_ATTR */ | |||||
942 | ||||||
943 | if (__kmp_monitor_stksize == 0) { | |||||
944 | __kmp_monitor_stksize = KMP_DEFAULT_MONITOR_STKSIZE; | |||||
945 | } | |||||
946 | if (__kmp_monitor_stksize < __kmp_sys_min_stksize) { | |||||
947 | __kmp_monitor_stksize = __kmp_sys_min_stksize; | |||||
948 | } | |||||
949 | ||||||
950 | KA_TRACE(10, ("__kmp_create_monitor: default stacksize = %lu bytes,"if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_create_monitor: default stacksize = %lu bytes," "requested stacksize = %lu bytes\n", size, __kmp_monitor_stksize ); } | |||||
951 | "requested stacksize = %lu bytes\n",if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_create_monitor: default stacksize = %lu bytes," "requested stacksize = %lu bytes\n", size, __kmp_monitor_stksize ); } | |||||
952 | size, __kmp_monitor_stksize))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_create_monitor: default stacksize = %lu bytes," "requested stacksize = %lu bytes\n", size, __kmp_monitor_stksize ); }; | |||||
953 | ||||||
954 | retry: | |||||
955 | ||||||
956 | /* Set stack size for this thread now. */ | |||||
957 | #ifdef _POSIX_THREAD_ATTR_STACKSIZE200809L | |||||
958 | KA_TRACE(10, ("__kmp_create_monitor: setting stacksize = %lu bytes,",if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_create_monitor: setting stacksize = %lu bytes," , __kmp_monitor_stksize); } | |||||
959 | __kmp_monitor_stksize))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_create_monitor: setting stacksize = %lu bytes," , __kmp_monitor_stksize); }; | |||||
960 | status = pthread_attr_setstacksize(&thread_attr, __kmp_monitor_stksize); | |||||
961 | if (status != 0) { | |||||
962 | if (auto_adj_size) { | |||||
963 | __kmp_monitor_stksize *= 2; | |||||
964 | goto retry; | |||||
965 | } | |||||
966 | kmp_msg_t err_code = KMP_ERR(status)__kmp_msg_error_code(status); | |||||
967 | __kmp_msg(kmp_ms_warning, // should this be fatal? BB | |||||
968 | KMP_MSG(CantSetMonitorStackSize, (long int)__kmp_monitor_stksize)__kmp_msg_format(kmp_i18n_msg_CantSetMonitorStackSize, (long int )__kmp_monitor_stksize), | |||||
969 | err_code, KMP_HNT(ChangeMonitorStackSize)__kmp_msg_format(kmp_i18n_hnt_ChangeMonitorStackSize), __kmp_msg_null); | |||||
970 | if (__kmp_generate_warnings == kmp_warnings_off) { | |||||
971 | __kmp_str_free(&err_code.str); | |||||
972 | } | |||||
973 | } | |||||
974 | #endif /* _POSIX_THREAD_ATTR_STACKSIZE */ | |||||
975 | ||||||
976 | status = | |||||
977 | pthread_create(&handle, &thread_attr, __kmp_launch_monitor, (void *)th); | |||||
978 | ||||||
979 | if (status != 0) { | |||||
980 | #ifdef _POSIX_THREAD_ATTR_STACKSIZE200809L | |||||
981 | if (status == EINVAL22) { | |||||
982 | if (auto_adj_size && (__kmp_monitor_stksize < (size_t)0x40000000)) { | |||||
983 | __kmp_monitor_stksize *= 2; | |||||
984 | goto retry; | |||||
985 | } | |||||
986 | __kmp_fatal(KMP_MSG(CantSetMonitorStackSize, __kmp_monitor_stksize)__kmp_msg_format(kmp_i18n_msg_CantSetMonitorStackSize, __kmp_monitor_stksize ), | |||||
987 | KMP_ERR(status)__kmp_msg_error_code(status), KMP_HNT(IncreaseMonitorStackSize)__kmp_msg_format(kmp_i18n_hnt_IncreaseMonitorStackSize), | |||||
988 | __kmp_msg_null); | |||||
989 | } | |||||
990 | if (status == ENOMEM12) { | |||||
991 | __kmp_fatal(KMP_MSG(CantSetMonitorStackSize, __kmp_monitor_stksize)__kmp_msg_format(kmp_i18n_msg_CantSetMonitorStackSize, __kmp_monitor_stksize ), | |||||
992 | KMP_ERR(status)__kmp_msg_error_code(status), KMP_HNT(DecreaseMonitorStackSize)__kmp_msg_format(kmp_i18n_hnt_DecreaseMonitorStackSize), | |||||
993 | __kmp_msg_null); | |||||
994 | } | |||||
995 | #endif /* _POSIX_THREAD_ATTR_STACKSIZE */ | |||||
996 | if (status == EAGAIN11) { | |||||
997 | __kmp_fatal(KMP_MSG(NoResourcesForMonitorThread)__kmp_msg_format(kmp_i18n_msg_NoResourcesForMonitorThread), KMP_ERR(status)__kmp_msg_error_code(status), | |||||
998 | KMP_HNT(DecreaseNumberOfThreadsInUse)__kmp_msg_format(kmp_i18n_hnt_DecreaseNumberOfThreadsInUse), __kmp_msg_null); | |||||
999 | } | |||||
1000 | KMP_SYSFAIL("pthread_create", status)__kmp_fatal(__kmp_msg_format(kmp_i18n_msg_FunctionError, "pthread_create" ), __kmp_msg_error_code(status), __kmp_msg_null); | |||||
1001 | } | |||||
1002 | ||||||
1003 | th->th.th_info.ds.ds_thread = handle; | |||||
1004 | ||||||
1005 | #if KMP_REAL_TIME_FIX | |||||
1006 | // Wait for the monitor thread is really started and set its *priority*. | |||||
1007 | KMP_DEBUG_ASSERT(sizeof(kmp_uint32) ==if (!(sizeof(kmp_uint32) == sizeof(__kmp_global.g.g_time.dt.t_value ))) { __kmp_debug_assert("sizeof(kmp_uint32) == sizeof(__kmp_global.g.g_time.dt.t_value)" , "/build/llvm-toolchain-snapshot-8~svn345461/projects/openmp/runtime/src/z_Linux_util.cpp" , 1008); } | |||||
1008 | sizeof(__kmp_global.g.g_time.dt.t_value))if (!(sizeof(kmp_uint32) == sizeof(__kmp_global.g.g_time.dt.t_value ))) { __kmp_debug_assert("sizeof(kmp_uint32) == sizeof(__kmp_global.g.g_time.dt.t_value)" , "/build/llvm-toolchain-snapshot-8~svn345461/projects/openmp/runtime/src/z_Linux_util.cpp" , 1008); }; | |||||
1009 | __kmp_wait_yield_4((kmp_uint32 volatile *)&__kmp_global.g.g_time.dt.t_value, | |||||
1010 | -1, &__kmp_neq_4, NULL__null); | |||||
1011 | #endif // KMP_REAL_TIME_FIX | |||||
1012 | ||||||
1013 | #ifdef KMP_THREAD_ATTR | |||||
1014 | status = pthread_attr_destroy(&thread_attr); | |||||
1015 | if (status != 0) { | |||||
1016 | kmp_msg_t err_code = KMP_ERR(status)__kmp_msg_error_code(status); | |||||
1017 | __kmp_msg(kmp_ms_warning, KMP_MSG(CantDestroyThreadAttrs)__kmp_msg_format(kmp_i18n_msg_CantDestroyThreadAttrs), err_code, | |||||
1018 | __kmp_msg_null); | |||||
1019 | if (__kmp_generate_warnings == kmp_warnings_off) { | |||||
1020 | __kmp_str_free(&err_code.str); | |||||
1021 | } | |||||
1022 | } | |||||
1023 | #endif | |||||
1024 | ||||||
1025 | KMP_MB(); /* Flush all pending memory write invalidates. */ | |||||
1026 | ||||||
1027 | KA_TRACE(10, ("__kmp_create_monitor: monitor created %#.8lx\n",if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_create_monitor: monitor created %#.8lx\n" , th->th.th_info.ds.ds_thread); } | |||||
1028 | th->th.th_info.ds.ds_thread))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_create_monitor: monitor created %#.8lx\n" , th->th.th_info.ds.ds_thread); }; | |||||
1029 | ||||||
1030 | } // __kmp_create_monitor | |||||
1031 | #endif // KMP_USE_MONITOR | |||||
1032 | ||||||
1033 | void __kmp_exit_thread(int exit_status) { | |||||
1034 | pthread_exit((void *)(intptr_t)exit_status); | |||||
1035 | } // __kmp_exit_thread | |||||
1036 | ||||||
1037 | #if KMP_USE_MONITOR | |||||
1038 | void __kmp_resume_monitor(); | |||||
1039 | ||||||
1040 | void __kmp_reap_monitor(kmp_info_t *th) { | |||||
1041 | int status; | |||||
1042 | void *exit_val; | |||||
1043 | ||||||
1044 | KA_TRACE(10, ("__kmp_reap_monitor: try to reap monitor thread with handle"if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_reap_monitor: try to reap monitor thread with handle" " %#.8lx\n", th->th.th_info.ds.ds_thread); } | |||||
1045 | " %#.8lx\n",if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_reap_monitor: try to reap monitor thread with handle" " %#.8lx\n", th->th.th_info.ds.ds_thread); } | |||||
1046 | th->th.th_info.ds.ds_thread))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_reap_monitor: try to reap monitor thread with handle" " %#.8lx\n", th->th.th_info.ds.ds_thread); }; | |||||
1047 | ||||||
1048 | // If monitor has been created, its tid and gtid should be KMP_GTID_MONITOR. | |||||
1049 | // If both tid and gtid are 0, it means the monitor did not ever start. | |||||
1050 | // If both tid and gtid are KMP_GTID_DNE, the monitor has been shut down. | |||||
1051 | KMP_DEBUG_ASSERT(th->th.th_info.ds.ds_tid == th->th.th_info.ds.ds_gtid)if (!(th->th.th_info.ds.ds_tid == th->th.th_info.ds.ds_gtid )) { __kmp_debug_assert("th->th.th_info.ds.ds_tid == th->th.th_info.ds.ds_gtid" , "/build/llvm-toolchain-snapshot-8~svn345461/projects/openmp/runtime/src/z_Linux_util.cpp" , 1051); }; | |||||
1052 | if (th->th.th_info.ds.ds_gtid != KMP_GTID_MONITOR(-4)) { | |||||
1053 | KA_TRACE(10, ("__kmp_reap_monitor: monitor did not start, returning\n"))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_reap_monitor: monitor did not start, returning\n" ); }; | |||||
1054 | return; | |||||
1055 | } | |||||
1056 | ||||||
1057 | KMP_MB(); /* Flush all pending memory write invalidates. */ | |||||
1058 | ||||||
1059 | /* First, check to see whether the monitor thread exists to wake it up. This | |||||
1060 | is to avoid performance problem when the monitor sleeps during | |||||
1061 | blocktime-size interval */ | |||||
1062 | ||||||
1063 | status = pthread_kill(th->th.th_info.ds.ds_thread, 0); | |||||
1064 | if (status != ESRCH3) { | |||||
1065 | __kmp_resume_monitor(); // Wake up the monitor thread | |||||
1066 | } | |||||
1067 | KA_TRACE(10, ("__kmp_reap_monitor: try to join with monitor\n"))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_reap_monitor: try to join with monitor\n" ); }; | |||||
1068 | status = pthread_join(th->th.th_info.ds.ds_thread, &exit_val); | |||||
1069 | if (exit_val != th) { | |||||
1070 | __kmp_fatal(KMP_MSG(ReapMonitorError)__kmp_msg_format(kmp_i18n_msg_ReapMonitorError), KMP_ERR(status)__kmp_msg_error_code(status), __kmp_msg_null); | |||||
1071 | } | |||||
1072 | ||||||
1073 | th->th.th_info.ds.ds_tid = KMP_GTID_DNE(-2); | |||||
1074 | th->th.th_info.ds.ds_gtid = KMP_GTID_DNE(-2); | |||||
1075 | ||||||
1076 | KA_TRACE(10, ("__kmp_reap_monitor: done reaping monitor thread with handle"if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_reap_monitor: done reaping monitor thread with handle" " %#.8lx\n", th->th.th_info.ds.ds_thread); } | |||||
1077 | " %#.8lx\n",if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_reap_monitor: done reaping monitor thread with handle" " %#.8lx\n", th->th.th_info.ds.ds_thread); } | |||||
1078 | th->th.th_info.ds.ds_thread))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_reap_monitor: done reaping monitor thread with handle" " %#.8lx\n", th->th.th_info.ds.ds_thread); }; | |||||
1079 | ||||||
1080 | KMP_MB(); /* Flush all pending memory write invalidates. */ | |||||
1081 | } | |||||
1082 | #endif // KMP_USE_MONITOR | |||||
1083 | ||||||
1084 | void __kmp_reap_worker(kmp_info_t *th) { | |||||
1085 | int status; | |||||
1086 | void *exit_val; | |||||
1087 | ||||||
1088 | KMP_MB(); /* Flush all pending memory write invalidates. */ | |||||
1089 | ||||||
1090 | KA_TRACE(if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_reap_worker: try to reap T#%d\n" , th->th.th_info.ds.ds_gtid); } | |||||
1091 | 10, ("__kmp_reap_worker: try to reap T#%d\n", th->th.th_info.ds.ds_gtid))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_reap_worker: try to reap T#%d\n" , th->th.th_info.ds.ds_gtid); }; | |||||
1092 | ||||||
1093 | status = pthread_join(th->th.th_info.ds.ds_thread, &exit_val); | |||||
1094 | #ifdef KMP_DEBUG1 | |||||
1095 | /* Don't expose these to the user until we understand when they trigger */ | |||||
1096 | if (status != 0) { | |||||
1097 | __kmp_fatal(KMP_MSG(ReapWorkerError)__kmp_msg_format(kmp_i18n_msg_ReapWorkerError), KMP_ERR(status)__kmp_msg_error_code(status), __kmp_msg_null); | |||||
1098 | } | |||||
1099 | if (exit_val != th) { | |||||
1100 | KA_TRACE(10, ("__kmp_reap_worker: worker T#%d did not reap properly, "if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_reap_worker: worker T#%d did not reap properly, " "exit_val = %p\n", th->th.th_info.ds.ds_gtid, exit_val); } | |||||
1101 | "exit_val = %p\n",if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_reap_worker: worker T#%d did not reap properly, " "exit_val = %p\n", th->th.th_info.ds.ds_gtid, exit_val); } | |||||
1102 | th->th.th_info.ds.ds_gtid, exit_val))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_reap_worker: worker T#%d did not reap properly, " "exit_val = %p\n", th->th.th_info.ds.ds_gtid, exit_val); }; | |||||
1103 | } | |||||
1104 | #endif /* KMP_DEBUG */ | |||||
1105 | ||||||
1106 | KA_TRACE(10, ("__kmp_reap_worker: done reaping T#%d\n",if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_reap_worker: done reaping T#%d\n" , th->th.th_info.ds.ds_gtid); } | |||||
1107 | th->th.th_info.ds.ds_gtid))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_reap_worker: done reaping T#%d\n" , th->th.th_info.ds.ds_gtid); }; | |||||
1108 | ||||||
1109 | KMP_MB(); /* Flush all pending memory write invalidates. */ | |||||
1110 | } | |||||
1111 | ||||||
1112 | #if KMP_HANDLE_SIGNALS(1 || 0) | |||||
1113 | ||||||
1114 | static void __kmp_null_handler(int signo) { | |||||
1115 | // Do nothing, for doing SIG_IGN-type actions. | |||||
1116 | } // __kmp_null_handler | |||||
1117 | ||||||
1118 | static void __kmp_team_handler(int signo) { | |||||
1119 | if (__kmp_global.g.g_abort == 0) { | |||||
1120 | /* Stage 1 signal handler, let's shut down all of the threads */ | |||||
1121 | #ifdef KMP_DEBUG1 | |||||
1122 | __kmp_debug_printf("__kmp_team_handler: caught signal = %d\n", signo); | |||||
1123 | #endif | |||||
1124 | switch (signo) { | |||||
1125 | case SIGHUP1: | |||||
1126 | case SIGINT2: | |||||
1127 | case SIGQUIT3: | |||||
1128 | case SIGILL4: | |||||
1129 | case SIGABRT6: | |||||
1130 | case SIGFPE8: | |||||
1131 | case SIGBUS7: | |||||
1132 | case SIGSEGV11: | |||||
1133 | #ifdef SIGSYS31 | |||||
1134 | case SIGSYS31: | |||||
1135 | #endif | |||||
1136 | case SIGTERM15: | |||||
1137 | if (__kmp_debug_buf) { | |||||
1138 | __kmp_dump_debug_buffer(); | |||||
1139 | } | |||||
1140 | KMP_MB(); // Flush all pending memory write invalidates. | |||||
1141 | TCW_4(__kmp_global.g.g_abort, signo)(__kmp_global.g.g_abort) = (signo); | |||||
1142 | KMP_MB(); // Flush all pending memory write invalidates. | |||||
1143 | TCW_4(__kmp_global.g.g_done, TRUE)(__kmp_global.g.g_done) = ((!0)); | |||||
1144 | KMP_MB(); // Flush all pending memory write invalidates. | |||||
1145 | break; | |||||
1146 | default: | |||||
1147 | #ifdef KMP_DEBUG1 | |||||
1148 | __kmp_debug_printf("__kmp_team_handler: unknown signal type"); | |||||
1149 | #endif | |||||
1150 | break; | |||||
1151 | } | |||||
1152 | } | |||||
1153 | } // __kmp_team_handler | |||||
1154 | ||||||
1155 | static void __kmp_sigaction(int signum, const struct sigaction *act, | |||||
1156 | struct sigaction *oldact) { | |||||
1157 | int rc = sigaction(signum, act, oldact); | |||||
1158 | KMP_CHECK_SYSFAIL_ERRNO("sigaction", rc){ if (rc != 0) { int error = (*__errno_location ()); __kmp_fatal (__kmp_msg_format(kmp_i18n_msg_FunctionError, "sigaction"), __kmp_msg_error_code (error), __kmp_msg_null); } }; | |||||
1159 | } | |||||
1160 | ||||||
1161 | static void __kmp_install_one_handler(int sig, sig_func_t handler_func, | |||||
1162 | int parallel_init) { | |||||
1163 | KMP_MB(); // Flush all pending memory write invalidates. | |||||
1164 | KB_TRACE(60,if (kmp_b_debug >= 60) { __kmp_debug_printf ("__kmp_install_one_handler( %d, ..., %d )\n" , sig, parallel_init); } | |||||
1165 | ("__kmp_install_one_handler( %d, ..., %d )\n", sig, parallel_init))if (kmp_b_debug >= 60) { __kmp_debug_printf ("__kmp_install_one_handler( %d, ..., %d )\n" , sig, parallel_init); }; | |||||
1166 | if (parallel_init) { | |||||
1167 | struct sigaction new_action; | |||||
1168 | struct sigaction old_action; | |||||
1169 | new_action.sa_handler__sigaction_handler.sa_handler = handler_func; | |||||
1170 | new_action.sa_flags = 0; | |||||
1171 | sigfillset(&new_action.sa_mask); | |||||
1172 | __kmp_sigaction(sig, &new_action, &old_action); | |||||
1173 | if (old_action.sa_handler__sigaction_handler.sa_handler == __kmp_sighldrs[sig].sa_handler__sigaction_handler.sa_handler) { | |||||
1174 | sigaddset(&__kmp_sigset, sig); | |||||
1175 | } else { | |||||
1176 | // Restore/keep user's handler if one previously installed. | |||||
1177 | __kmp_sigaction(sig, &old_action, NULL__null); | |||||
1178 | } | |||||
1179 | } else { | |||||
1180 | // Save initial/system signal handlers to see if user handlers installed. | |||||
1181 | __kmp_sigaction(sig, NULL__null, &__kmp_sighldrs[sig]); | |||||
1182 | } | |||||
1183 | KMP_MB(); // Flush all pending memory write invalidates. | |||||
1184 | } // __kmp_install_one_handler | |||||
1185 | ||||||
1186 | static void __kmp_remove_one_handler(int sig) { | |||||
1187 | KB_TRACE(60, ("__kmp_remove_one_handler( %d )\n", sig))if (kmp_b_debug >= 60) { __kmp_debug_printf ("__kmp_remove_one_handler( %d )\n" , sig); }; | |||||
1188 | if (sigismember(&__kmp_sigset, sig)) { | |||||
1189 | struct sigaction old; | |||||
1190 | KMP_MB(); // Flush all pending memory write invalidates. | |||||
1191 | __kmp_sigaction(sig, &__kmp_sighldrs[sig], &old); | |||||
1192 | if ((old.sa_handler__sigaction_handler.sa_handler != __kmp_team_handler) && | |||||
1193 | (old.sa_handler__sigaction_handler.sa_handler != __kmp_null_handler)) { | |||||
1194 | // Restore the users signal handler. | |||||
1195 | KB_TRACE(10, ("__kmp_remove_one_handler: oops, not our handler, "if (kmp_b_debug >= 10) { __kmp_debug_printf ("__kmp_remove_one_handler: oops, not our handler, " "restoring: sig=%d\n", sig); } | |||||
1196 | "restoring: sig=%d\n",if (kmp_b_debug >= 10) { __kmp_debug_printf ("__kmp_remove_one_handler: oops, not our handler, " "restoring: sig=%d\n", sig); } | |||||
1197 | sig))if (kmp_b_debug >= 10) { __kmp_debug_printf ("__kmp_remove_one_handler: oops, not our handler, " "restoring: sig=%d\n", sig); }; | |||||
1198 | __kmp_sigaction(sig, &old, NULL__null); | |||||
1199 | } | |||||
1200 | sigdelset(&__kmp_sigset, sig); | |||||
1201 | KMP_MB(); // Flush all pending memory write invalidates. | |||||
1202 | } | |||||
1203 | } // __kmp_remove_one_handler | |||||
1204 | ||||||
1205 | void __kmp_install_signals(int parallel_init) { | |||||
1206 | KB_TRACE(10, ("__kmp_install_signals( %d )\n", parallel_init))if (kmp_b_debug >= 10) { __kmp_debug_printf ("__kmp_install_signals( %d )\n" , parallel_init); }; | |||||
1207 | if (__kmp_handle_signals || !parallel_init) { | |||||
1208 | // If ! parallel_init, we do not install handlers, just save original | |||||
1209 | // handlers. Let us do it even __handle_signals is 0. | |||||
1210 | sigemptyset(&__kmp_sigset); | |||||
1211 | __kmp_install_one_handler(SIGHUP1, __kmp_team_handler, parallel_init); | |||||
1212 | __kmp_install_one_handler(SIGINT2, __kmp_team_handler, parallel_init); | |||||
1213 | __kmp_install_one_handler(SIGQUIT3, __kmp_team_handler, parallel_init); | |||||
1214 | __kmp_install_one_handler(SIGILL4, __kmp_team_handler, parallel_init); | |||||
1215 | __kmp_install_one_handler(SIGABRT6, __kmp_team_handler, parallel_init); | |||||
1216 | __kmp_install_one_handler(SIGFPE8, __kmp_team_handler, parallel_init); | |||||
1217 | __kmp_install_one_handler(SIGBUS7, __kmp_team_handler, parallel_init); | |||||
1218 | __kmp_install_one_handler(SIGSEGV11, __kmp_team_handler, parallel_init); | |||||
1219 | #ifdef SIGSYS31 | |||||
1220 | __kmp_install_one_handler(SIGSYS31, __kmp_team_handler, parallel_init); | |||||
1221 | #endif // SIGSYS | |||||
1222 | __kmp_install_one_handler(SIGTERM15, __kmp_team_handler, parallel_init); | |||||
1223 | #ifdef SIGPIPE13 | |||||
1224 | __kmp_install_one_handler(SIGPIPE13, __kmp_team_handler, parallel_init); | |||||
1225 | #endif // SIGPIPE | |||||
1226 | } | |||||
1227 | } // __kmp_install_signals | |||||
1228 | ||||||
1229 | void __kmp_remove_signals(void) { | |||||
1230 | int sig; | |||||
1231 | KB_TRACE(10, ("__kmp_remove_signals()\n"))if (kmp_b_debug >= 10) { __kmp_debug_printf ("__kmp_remove_signals()\n" ); }; | |||||
1232 | for (sig = 1; sig < NSIG65; ++sig) { | |||||
1233 | __kmp_remove_one_handler(sig); | |||||
1234 | } | |||||
1235 | } // __kmp_remove_signals | |||||
1236 | ||||||
1237 | #endif // KMP_HANDLE_SIGNALS | |||||
1238 | ||||||
1239 | void __kmp_enable(int new_state) { | |||||
1240 | #ifdef KMP_CANCEL_THREADS | |||||
1241 | int status, old_state; | |||||
1242 | status = pthread_setcancelstate(new_state, &old_state); | |||||
1243 | KMP_CHECK_SYSFAIL("pthread_setcancelstate", status){ if (status) { __kmp_fatal(__kmp_msg_format(kmp_i18n_msg_FunctionError , "pthread_setcancelstate"), __kmp_msg_error_code(status), __kmp_msg_null ); } }; | |||||
1244 | KMP_DEBUG_ASSERT(old_state == PTHREAD_CANCEL_DISABLE)if (!(old_state == PTHREAD_CANCEL_DISABLE)) { __kmp_debug_assert ("old_state == PTHREAD_CANCEL_DISABLE", "/build/llvm-toolchain-snapshot-8~svn345461/projects/openmp/runtime/src/z_Linux_util.cpp" , 1244); }; | |||||
1245 | #endif | |||||
1246 | } | |||||
1247 | ||||||
1248 | void __kmp_disable(int *old_state) { | |||||
1249 | #ifdef KMP_CANCEL_THREADS | |||||
1250 | int status; | |||||
1251 | status = pthread_setcancelstate(PTHREAD_CANCEL_DISABLEPTHREAD_CANCEL_DISABLE, old_state); | |||||
1252 | KMP_CHECK_SYSFAIL("pthread_setcancelstate", status){ if (status) { __kmp_fatal(__kmp_msg_format(kmp_i18n_msg_FunctionError , "pthread_setcancelstate"), __kmp_msg_error_code(status), __kmp_msg_null ); } }; | |||||
1253 | #endif | |||||
1254 | } | |||||
1255 | ||||||
1256 | static void __kmp_atfork_prepare(void) { | |||||
1257 | __kmp_acquire_bootstrap_lock(&__kmp_initz_lock); | |||||
1258 | __kmp_acquire_bootstrap_lock(&__kmp_forkjoin_lock); | |||||
1259 | } | |||||
1260 | ||||||
1261 | static void __kmp_atfork_parent(void) { | |||||
1262 | __kmp_release_bootstrap_lock(&__kmp_initz_lock); | |||||
1263 | __kmp_release_bootstrap_lock(&__kmp_forkjoin_lock); | |||||
1264 | } | |||||
1265 | ||||||
1266 | /* Reset the library so execution in the child starts "all over again" with | |||||
1267 | clean data structures in initial states. Don't worry about freeing memory | |||||
1268 | allocated by parent, just abandon it to be safe. */ | |||||
1269 | static void __kmp_atfork_child(void) { | |||||
1270 | __kmp_release_bootstrap_lock(&__kmp_forkjoin_lock); | |||||
1271 | /* TODO make sure this is done right for nested/sibling */ | |||||
1272 | // ATT: Memory leaks are here? TODO: Check it and fix. | |||||
1273 | /* KMP_ASSERT( 0 ); */ | |||||
1274 | ||||||
1275 | ++__kmp_fork_count; | |||||
1276 | ||||||
1277 | #if KMP_AFFINITY_SUPPORTED1 | |||||
1278 | #if KMP_OS_LINUX1 | |||||
1279 | // reset the affinity in the child to the initial thread | |||||
1280 | // affinity in the parent | |||||
1281 | kmp_set_thread_affinity_mask_initial(); | |||||
1282 | #endif | |||||
1283 | // Set default not to bind threads tightly in the child (we’re expecting | |||||
1284 | // over-subscription after the fork and this can improve things for | |||||
1285 | // scripting languages that use OpenMP inside process-parallel code). | |||||
1286 | __kmp_affinity_type = affinity_none; | |||||
1287 | #if OMP_40_ENABLED(50 >= 40) | |||||
1288 | if (__kmp_nested_proc_bind.bind_types != NULL__null) { | |||||
1289 | __kmp_nested_proc_bind.bind_types[0] = proc_bind_false; | |||||
1290 | } | |||||
1291 | #endif // OMP_40_ENABLED | |||||
1292 | #endif // KMP_AFFINITY_SUPPORTED | |||||
1293 | ||||||
1294 | __kmp_init_runtime = FALSE0; | |||||
1295 | #if KMP_USE_MONITOR | |||||
1296 | __kmp_init_monitor = 0; | |||||
1297 | #endif | |||||
1298 | __kmp_init_parallel = FALSE0; | |||||
1299 | __kmp_init_middle = FALSE0; | |||||
1300 | __kmp_init_serial = FALSE0; | |||||
1301 | TCW_4(__kmp_init_gtid, FALSE)(__kmp_init_gtid) = (0); | |||||
1302 | __kmp_init_common = FALSE0; | |||||
1303 | ||||||
1304 | TCW_4(__kmp_init_user_locks, FALSE)(__kmp_init_user_locks) = (0); | |||||
1305 | #if !KMP_USE_DYNAMIC_LOCK1 | |||||
1306 | __kmp_user_lock_table.used = 1; | |||||
1307 | __kmp_user_lock_table.allocated = 0; | |||||
1308 | __kmp_user_lock_table.table = NULL__null; | |||||
1309 | __kmp_lock_blocks = NULL__null; | |||||
1310 | #endif | |||||
1311 | ||||||
1312 | __kmp_all_nth = 0; | |||||
1313 | TCW_4(__kmp_nth, 0)(__kmp_nth) = (0); | |||||
1314 | ||||||
1315 | __kmp_thread_pool = NULL__null; | |||||
1316 | __kmp_thread_pool_insert_pt = NULL__null; | |||||
1317 | __kmp_team_pool = NULL__null; | |||||
1318 | ||||||
1319 | /* Must actually zero all the *cache arguments passed to __kmpc_threadprivate | |||||
1320 | here so threadprivate doesn't use stale data */ | |||||
1321 | KA_TRACE(10, ("__kmp_atfork_child: checking cache address list %p\n",if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_atfork_child: checking cache address list %p\n" , __kmp_threadpriv_cache_list); } | |||||
1322 | __kmp_threadpriv_cache_list))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_atfork_child: checking cache address list %p\n" , __kmp_threadpriv_cache_list); }; | |||||
1323 | ||||||
1324 | while (__kmp_threadpriv_cache_list != NULL__null) { | |||||
1325 | ||||||
1326 | if (*__kmp_threadpriv_cache_list->addr != NULL__null) { | |||||
1327 | KC_TRACE(50, ("__kmp_atfork_child: zeroing cache at address %p\n",if (kmp_c_debug >= 50) { __kmp_debug_printf ("__kmp_atfork_child: zeroing cache at address %p\n" , &(*__kmp_threadpriv_cache_list->addr)); } | |||||
1328 | &(*__kmp_threadpriv_cache_list->addr)))if (kmp_c_debug >= 50) { __kmp_debug_printf ("__kmp_atfork_child: zeroing cache at address %p\n" , &(*__kmp_threadpriv_cache_list->addr)); }; | |||||
1329 | ||||||
1330 | *__kmp_threadpriv_cache_list->addr = NULL__null; | |||||
1331 | } | |||||
1332 | __kmp_threadpriv_cache_list = __kmp_threadpriv_cache_list->next; | |||||
1333 | } | |||||
1334 | ||||||
1335 | __kmp_init_runtime = FALSE0; | |||||
1336 | ||||||
1337 | /* reset statically initialized locks */ | |||||
1338 | __kmp_init_bootstrap_lock(&__kmp_initz_lock); | |||||
1339 | __kmp_init_bootstrap_lock(&__kmp_stdio_lock); | |||||
1340 | __kmp_init_bootstrap_lock(&__kmp_console_lock); | |||||
1341 | __kmp_init_bootstrap_lock(&__kmp_task_team_lock); | |||||
1342 | ||||||
1343 | #if USE_ITT_BUILD1 | |||||
1344 | __kmp_itt_reset(); // reset ITT's global state | |||||
1345 | #endif /* USE_ITT_BUILD */ | |||||
1346 | ||||||
1347 | /* This is necessary to make sure no stale data is left around */ | |||||
1348 | /* AC: customers complain that we use unsafe routines in the atfork | |||||
1349 | handler. Mathworks: dlsym() is unsafe. We call dlsym and dlopen | |||||
1350 | in dynamic_link when check the presence of shared tbbmalloc library. | |||||
1351 | Suggestion is to make the library initialization lazier, similar | |||||
1352 | to what done for __kmpc_begin(). */ | |||||
1353 | // TODO: synchronize all static initializations with regular library | |||||
1354 | // startup; look at kmp_global.cpp and etc. | |||||
1355 | //__kmp_internal_begin (); | |||||
1356 | } | |||||
1357 | ||||||
1358 | void __kmp_register_atfork(void) { | |||||
1359 | if (__kmp_need_register_atfork) { | |||||
1360 | int status = pthread_atfork(__kmp_atfork_prepare, __kmp_atfork_parent, | |||||
1361 | __kmp_atfork_child); | |||||
1362 | KMP_CHECK_SYSFAIL("pthread_atfork", status){ if (status) { __kmp_fatal(__kmp_msg_format(kmp_i18n_msg_FunctionError , "pthread_atfork"), __kmp_msg_error_code(status), __kmp_msg_null ); } }; | |||||
1363 | __kmp_need_register_atfork = FALSE0; | |||||
1364 | } | |||||
1365 | } | |||||
1366 | ||||||
1367 | void __kmp_suspend_initialize(void) { | |||||
1368 | int status; | |||||
1369 | status = pthread_mutexattr_init(&__kmp_suspend_mutex_attr); | |||||
1370 | KMP_CHECK_SYSFAIL("pthread_mutexattr_init", status){ if (status) { __kmp_fatal(__kmp_msg_format(kmp_i18n_msg_FunctionError , "pthread_mutexattr_init"), __kmp_msg_error_code(status), __kmp_msg_null ); } }; | |||||
1371 | status = pthread_condattr_init(&__kmp_suspend_cond_attr); | |||||
1372 | KMP_CHECK_SYSFAIL("pthread_condattr_init", status){ if (status) { __kmp_fatal(__kmp_msg_format(kmp_i18n_msg_FunctionError , "pthread_condattr_init"), __kmp_msg_error_code(status), __kmp_msg_null ); } }; | |||||
1373 | } | |||||
1374 | ||||||
1375 | static void __kmp_suspend_initialize_thread(kmp_info_t *th) { | |||||
1376 | ANNOTATE_HAPPENS_AFTER(&th->th.th_suspend_init_count); | |||||
1377 | if (th->th.th_suspend_init_count <= __kmp_fork_count) { | |||||
1378 | /* this means we haven't initialized the suspension pthread objects for this | |||||
1379 | thread in this instance of the process */ | |||||
1380 | int status; | |||||
1381 | status = pthread_cond_init(&th->th.th_suspend_cv.c_cond, | |||||
1382 | &__kmp_suspend_cond_attr); | |||||
1383 | KMP_CHECK_SYSFAIL("pthread_cond_init", status){ if (status) { __kmp_fatal(__kmp_msg_format(kmp_i18n_msg_FunctionError , "pthread_cond_init"), __kmp_msg_error_code(status), __kmp_msg_null ); } }; | |||||
1384 | status = pthread_mutex_init(&th->th.th_suspend_mx.m_mutex, | |||||
1385 | &__kmp_suspend_mutex_attr); | |||||
1386 | KMP_CHECK_SYSFAIL("pthread_mutex_init", status){ if (status) { __kmp_fatal(__kmp_msg_format(kmp_i18n_msg_FunctionError , "pthread_mutex_init"), __kmp_msg_error_code(status), __kmp_msg_null ); } }; | |||||
1387 | *(volatile int *)&th->th.th_suspend_init_count = __kmp_fork_count + 1; | |||||
1388 | ANNOTATE_HAPPENS_BEFORE(&th->th.th_suspend_init_count); | |||||
1389 | } | |||||
1390 | } | |||||
1391 | ||||||
1392 | void __kmp_suspend_uninitialize_thread(kmp_info_t *th) { | |||||
1393 | if (th->th.th_suspend_init_count > __kmp_fork_count) { | |||||
1394 | /* this means we have initialize the suspension pthread objects for this | |||||
1395 | thread in this instance of the process */ | |||||
1396 | int status; | |||||
1397 | ||||||
1398 | status = pthread_cond_destroy(&th->th.th_suspend_cv.c_cond); | |||||
1399 | if (status != 0 && status != EBUSY16) { | |||||
1400 | KMP_SYSFAIL("pthread_cond_destroy", status)__kmp_fatal(__kmp_msg_format(kmp_i18n_msg_FunctionError, "pthread_cond_destroy" ), __kmp_msg_error_code(status), __kmp_msg_null); | |||||
1401 | } | |||||
1402 | status = pthread_mutex_destroy(&th->th.th_suspend_mx.m_mutex); | |||||
1403 | if (status != 0 && status != EBUSY16) { | |||||
1404 | KMP_SYSFAIL("pthread_mutex_destroy", status)__kmp_fatal(__kmp_msg_format(kmp_i18n_msg_FunctionError, "pthread_mutex_destroy" ), __kmp_msg_error_code(status), __kmp_msg_null); | |||||
1405 | } | |||||
1406 | --th->th.th_suspend_init_count; | |||||
1407 | KMP_DEBUG_ASSERT(th->th.th_suspend_init_count == __kmp_fork_count)if (!(th->th.th_suspend_init_count == __kmp_fork_count)) { __kmp_debug_assert("th->th.th_suspend_init_count == __kmp_fork_count" , "/build/llvm-toolchain-snapshot-8~svn345461/projects/openmp/runtime/src/z_Linux_util.cpp" , 1407); }; | |||||
1408 | } | |||||
1409 | } | |||||
1410 | ||||||
1411 | /* This routine puts the calling thread to sleep after setting the | |||||
1412 | sleep bit for the indicated flag variable to true. */ | |||||
1413 | template <class C> | |||||
1414 | static inline void __kmp_suspend_template(int th_gtid, C *flag) { | |||||
1415 | KMP_TIME_DEVELOPER_PARTITIONED_BLOCK(USER_suspend)((void)0); | |||||
1416 | kmp_info_t *th = __kmp_threads[th_gtid]; | |||||
1417 | int status; | |||||
1418 | typename C::flag_t old_spin; | |||||
1419 | ||||||
1420 | KF_TRACE(30, ("__kmp_suspend_template: T#%d enter for flag = %p\n", th_gtid,if (kmp_f_debug >= 30) { __kmp_debug_printf ("__kmp_suspend_template: T#%d enter for flag = %p\n" , th_gtid, flag->get()); } | |||||
1421 | flag->get()))if (kmp_f_debug >= 30) { __kmp_debug_printf ("__kmp_suspend_template: T#%d enter for flag = %p\n" , th_gtid, flag->get()); }; | |||||
1422 | ||||||
1423 | __kmp_suspend_initialize_thread(th); | |||||
1424 | ||||||
1425 | status = pthread_mutex_lock(&th->th.th_suspend_mx.m_mutex); | |||||
1426 | KMP_CHECK_SYSFAIL("pthread_mutex_lock", status){ if (status) { __kmp_fatal(__kmp_msg_format(kmp_i18n_msg_FunctionError , "pthread_mutex_lock"), __kmp_msg_error_code(status), __kmp_msg_null ); } }; | |||||
1427 | ||||||
1428 | KF_TRACE(10, ("__kmp_suspend_template: T#%d setting sleep bit for spin(%p)\n",if (kmp_f_debug >= 10) { __kmp_debug_printf ("__kmp_suspend_template: T#%d setting sleep bit for spin(%p)\n" , th_gtid, flag->get()); } | |||||
1429 | th_gtid, flag->get()))if (kmp_f_debug >= 10) { __kmp_debug_printf ("__kmp_suspend_template: T#%d setting sleep bit for spin(%p)\n" , th_gtid, flag->get()); }; | |||||
1430 | ||||||
1431 | /* TODO: shouldn't this use release semantics to ensure that | |||||
1432 | __kmp_suspend_initialize_thread gets called first? */ | |||||
1433 | old_spin = flag->set_sleeping(); | |||||
1434 | ||||||
1435 | KF_TRACE(5, ("__kmp_suspend_template: T#%d set sleep bit for spin(%p)==%x,"if (kmp_f_debug >= 5) { __kmp_debug_printf ("__kmp_suspend_template: T#%d set sleep bit for spin(%p)==%x," " was %x\n", th_gtid, flag->get(), flag->load(), old_spin ); } | |||||
1436 | " was %x\n",if (kmp_f_debug >= 5) { __kmp_debug_printf ("__kmp_suspend_template: T#%d set sleep bit for spin(%p)==%x," " was %x\n", th_gtid, flag->get(), flag->load(), old_spin ); } | |||||
1437 | th_gtid, flag->get(), flag->load(), old_spin))if (kmp_f_debug >= 5) { __kmp_debug_printf ("__kmp_suspend_template: T#%d set sleep bit for spin(%p)==%x," " was %x\n", th_gtid, flag->get(), flag->load(), old_spin ); }; | |||||
1438 | ||||||
1439 | if (flag->done_check_val(old_spin)) { | |||||
1440 | old_spin = flag->unset_sleeping(); | |||||
1441 | KF_TRACE(5, ("__kmp_suspend_template: T#%d false alarm, reset sleep bit "if (kmp_f_debug >= 5) { __kmp_debug_printf ("__kmp_suspend_template: T#%d false alarm, reset sleep bit " "for spin(%p)\n", th_gtid, flag->get()); } | |||||
1442 | "for spin(%p)\n",if (kmp_f_debug >= 5) { __kmp_debug_printf ("__kmp_suspend_template: T#%d false alarm, reset sleep bit " "for spin(%p)\n", th_gtid, flag->get()); } | |||||
1443 | th_gtid, flag->get()))if (kmp_f_debug >= 5) { __kmp_debug_printf ("__kmp_suspend_template: T#%d false alarm, reset sleep bit " "for spin(%p)\n", th_gtid, flag->get()); }; | |||||
1444 | } else { | |||||
1445 | /* Encapsulate in a loop as the documentation states that this may | |||||
1446 | "with low probability" return when the condition variable has | |||||
1447 | not been signaled or broadcast */ | |||||
1448 | int deactivated = FALSE0; | |||||
1449 | TCW_PTR(th->th.th_sleep_loc, (void *)flag)((th->th.th_sleep_loc)) = (((void *)flag)); | |||||
1450 | ||||||
1451 | while (flag->is_sleeping()) { | |||||
1452 | #ifdef DEBUG_SUSPEND | |||||
1453 | char buffer[128]; | |||||
1454 | __kmp_suspend_count++; | |||||
1455 | __kmp_print_cond(buffer, &th->th.th_suspend_cv); | |||||
1456 | __kmp_printf("__kmp_suspend_template: suspending T#%d: %s\n", th_gtid, | |||||
1457 | buffer); | |||||
1458 | #endif | |||||
1459 | // Mark the thread as no longer active (only in the first iteration of the | |||||
1460 | // loop). | |||||
1461 | if (!deactivated) { | |||||
1462 | th->th.th_active = FALSE0; | |||||
1463 | if (th->th.th_active_in_pool) { | |||||
1464 | th->th.th_active_in_pool = FALSE0; | |||||
1465 | KMP_ATOMIC_DEC(&__kmp_thread_pool_active_nth)(&__kmp_thread_pool_active_nth)->fetch_sub(1, std::memory_order_acq_rel ); | |||||
1466 | KMP_DEBUG_ASSERT(TCR_4(__kmp_thread_pool_active_nth) >= 0)if (!((__kmp_thread_pool_active_nth) >= 0)) { __kmp_debug_assert ("(__kmp_thread_pool_active_nth) >= 0", "/build/llvm-toolchain-snapshot-8~svn345461/projects/openmp/runtime/src/z_Linux_util.cpp" , 1466); }; | |||||
1467 | } | |||||
1468 | deactivated = TRUE(!0); | |||||
1469 | } | |||||
1470 | ||||||
1471 | #if USE_SUSPEND_TIMEOUT | |||||
1472 | struct timespec now; | |||||
1473 | struct timeval tval; | |||||
1474 | int msecs; | |||||
1475 | ||||||
1476 | status = gettimeofday(&tval, NULL__null); | |||||
1477 | KMP_CHECK_SYSFAIL_ERRNO("gettimeofday", status){ if (status != 0) { int error = (*__errno_location ()); __kmp_fatal (__kmp_msg_format(kmp_i18n_msg_FunctionError, "gettimeofday") , __kmp_msg_error_code(error), __kmp_msg_null); } }; | |||||
1478 | TIMEVAL_TO_TIMESPEC(&tval, &now){ (&now)->tv_sec = (&tval)->tv_sec; (&now)-> tv_nsec = (&tval)->tv_usec * 1000; }; | |||||
1479 | ||||||
1480 | msecs = (4 * __kmp_dflt_blocktime) + 200; | |||||
1481 | now.tv_sec += msecs / 1000; | |||||
1482 | now.tv_nsec += (msecs % 1000) * 1000; | |||||
1483 | ||||||
1484 | KF_TRACE(15, ("__kmp_suspend_template: T#%d about to perform "if (kmp_f_debug >= 15) { __kmp_debug_printf ("__kmp_suspend_template: T#%d about to perform " "pthread_cond_timedwait\n", th_gtid); } | |||||
1485 | "pthread_cond_timedwait\n",if (kmp_f_debug >= 15) { __kmp_debug_printf ("__kmp_suspend_template: T#%d about to perform " "pthread_cond_timedwait\n", th_gtid); } | |||||
1486 | th_gtid))if (kmp_f_debug >= 15) { __kmp_debug_printf ("__kmp_suspend_template: T#%d about to perform " "pthread_cond_timedwait\n", th_gtid); }; | |||||
1487 | status = pthread_cond_timedwait(&th->th.th_suspend_cv.c_cond, | |||||
1488 | &th->th.th_suspend_mx.m_mutex, &now); | |||||
1489 | #else | |||||
1490 | KF_TRACE(15, ("__kmp_suspend_template: T#%d about to perform"if (kmp_f_debug >= 15) { __kmp_debug_printf ("__kmp_suspend_template: T#%d about to perform" " pthread_cond_wait\n", th_gtid); } | |||||
1491 | " pthread_cond_wait\n",if (kmp_f_debug >= 15) { __kmp_debug_printf ("__kmp_suspend_template: T#%d about to perform" " pthread_cond_wait\n", th_gtid); } | |||||
1492 | th_gtid))if (kmp_f_debug >= 15) { __kmp_debug_printf ("__kmp_suspend_template: T#%d about to perform" " pthread_cond_wait\n", th_gtid); }; | |||||
1493 | status = pthread_cond_wait(&th->th.th_suspend_cv.c_cond, | |||||
1494 | &th->th.th_suspend_mx.m_mutex); | |||||
1495 | #endif | |||||
1496 | ||||||
1497 | if ((status != 0) && (status != EINTR4) && (status != ETIMEDOUT110)) { | |||||
1498 | KMP_SYSFAIL("pthread_cond_wait", status)__kmp_fatal(__kmp_msg_format(kmp_i18n_msg_FunctionError, "pthread_cond_wait" ), __kmp_msg_error_code(status), __kmp_msg_null); | |||||
1499 | } | |||||
1500 | #ifdef KMP_DEBUG1 | |||||
1501 | if (status == ETIMEDOUT110) { | |||||
1502 | if (flag->is_sleeping()) { | |||||
1503 | KF_TRACE(100,if (kmp_f_debug >= 100) { __kmp_debug_printf ("__kmp_suspend_template: T#%d timeout wakeup\n" , th_gtid); } | |||||
1504 | ("__kmp_suspend_template: T#%d timeout wakeup\n", th_gtid))if (kmp_f_debug >= 100) { __kmp_debug_printf ("__kmp_suspend_template: T#%d timeout wakeup\n" , th_gtid); }; | |||||
1505 | } else { | |||||
1506 | KF_TRACE(2, ("__kmp_suspend_template: T#%d timeout wakeup, sleep bit "if (kmp_f_debug >= 2) { __kmp_debug_printf ("__kmp_suspend_template: T#%d timeout wakeup, sleep bit " "not set!\n", th_gtid); } | |||||
1507 | "not set!\n",if (kmp_f_debug >= 2) { __kmp_debug_printf ("__kmp_suspend_template: T#%d timeout wakeup, sleep bit " "not set!\n", th_gtid); } | |||||
1508 | th_gtid))if (kmp_f_debug >= 2) { __kmp_debug_printf ("__kmp_suspend_template: T#%d timeout wakeup, sleep bit " "not set!\n", th_gtid); }; | |||||
1509 | } | |||||
1510 | } else if (flag->is_sleeping()) { | |||||
1511 | KF_TRACE(100,if (kmp_f_debug >= 100) { __kmp_debug_printf ("__kmp_suspend_template: T#%d spurious wakeup\n" , th_gtid); } | |||||
1512 | ("__kmp_suspend_template: T#%d spurious wakeup\n", th_gtid))if (kmp_f_debug >= 100) { __kmp_debug_printf ("__kmp_suspend_template: T#%d spurious wakeup\n" , th_gtid); }; | |||||
1513 | } | |||||
1514 | #endif | |||||
1515 | } // while | |||||
1516 | ||||||
1517 | // Mark the thread as active again (if it was previous marked as inactive) | |||||
1518 | if (deactivated) { | |||||
1519 | th->th.th_active = TRUE(!0); | |||||
1520 | if (TCR_4(th->th.th_in_pool)(th->th.th_in_pool)) { | |||||
1521 | KMP_ATOMIC_INC(&__kmp_thread_pool_active_nth)(&__kmp_thread_pool_active_nth)->fetch_add(1, std::memory_order_acq_rel ); | |||||
1522 | th->th.th_active_in_pool = TRUE(!0); | |||||
1523 | } | |||||
1524 | } | |||||
1525 | } | |||||
1526 | #ifdef DEBUG_SUSPEND | |||||
1527 | { | |||||
1528 | char buffer[128]; | |||||
1529 | __kmp_print_cond(buffer, &th->th.th_suspend_cv); | |||||
1530 | __kmp_printf("__kmp_suspend_template: T#%d has awakened: %s\n", th_gtid, | |||||
1531 | buffer); | |||||
1532 | } | |||||
1533 | #endif | |||||
1534 | ||||||
1535 | status = pthread_mutex_unlock(&th->th.th_suspend_mx.m_mutex); | |||||
1536 | KMP_CHECK_SYSFAIL("pthread_mutex_unlock", status){ if (status) { __kmp_fatal(__kmp_msg_format(kmp_i18n_msg_FunctionError , "pthread_mutex_unlock"), __kmp_msg_error_code(status), __kmp_msg_null ); } }; | |||||
1537 | KF_TRACE(30, ("__kmp_suspend_template: T#%d exit\n", th_gtid))if (kmp_f_debug >= 30) { __kmp_debug_printf ("__kmp_suspend_template: T#%d exit\n" , th_gtid); }; | |||||
1538 | } | |||||
1539 | ||||||
1540 | void __kmp_suspend_32(int th_gtid, kmp_flag_32 *flag) { | |||||
1541 | __kmp_suspend_template(th_gtid, flag); | |||||
1542 | } | |||||
1543 | void __kmp_suspend_64(int th_gtid, kmp_flag_64 *flag) { | |||||
1544 | __kmp_suspend_template(th_gtid, flag); | |||||
1545 | } | |||||
1546 | void __kmp_suspend_oncore(int th_gtid, kmp_flag_oncore *flag) { | |||||
1547 | __kmp_suspend_template(th_gtid, flag); | |||||
1548 | } | |||||
1549 | ||||||
1550 | /* This routine signals the thread specified by target_gtid to wake up | |||||
1551 | after setting the sleep bit indicated by the flag argument to FALSE. | |||||
1552 | The target thread must already have called __kmp_suspend_template() */ | |||||
1553 | template <class C> | |||||
1554 | static inline void __kmp_resume_template(int target_gtid, C *flag) { | |||||
1555 | KMP_TIME_DEVELOPER_PARTITIONED_BLOCK(USER_resume)((void)0); | |||||
1556 | kmp_info_t *th = __kmp_threads[target_gtid]; | |||||
1557 | int status; | |||||
1558 | ||||||
1559 | #ifdef KMP_DEBUG1 | |||||
1560 | int gtid = TCR_4(__kmp_init_gtid)(__kmp_init_gtid) ? __kmp_get_gtid()__kmp_get_global_thread_id() : -1; | |||||
1561 | #endif | |||||
1562 | ||||||
1563 | KF_TRACE(30, ("__kmp_resume_template: T#%d wants to wakeup T#%d enter\n",if (kmp_f_debug >= 30) { __kmp_debug_printf ("__kmp_resume_template: T#%d wants to wakeup T#%d enter\n" , gtid, target_gtid); } | |||||
1564 | gtid, target_gtid))if (kmp_f_debug >= 30) { __kmp_debug_printf ("__kmp_resume_template: T#%d wants to wakeup T#%d enter\n" , gtid, target_gtid); }; | |||||
1565 | KMP_DEBUG_ASSERT(gtid != target_gtid)if (!(gtid != target_gtid)) { __kmp_debug_assert("gtid != target_gtid" , "/build/llvm-toolchain-snapshot-8~svn345461/projects/openmp/runtime/src/z_Linux_util.cpp" , 1565); }; | |||||
1566 | ||||||
1567 | __kmp_suspend_initialize_thread(th); | |||||
1568 | ||||||
1569 | status = pthread_mutex_lock(&th->th.th_suspend_mx.m_mutex); | |||||
1570 | KMP_CHECK_SYSFAIL("pthread_mutex_lock", status){ if (status) { __kmp_fatal(__kmp_msg_format(kmp_i18n_msg_FunctionError , "pthread_mutex_lock"), __kmp_msg_error_code(status), __kmp_msg_null ); } }; | |||||
1571 | ||||||
1572 | if (!flag) { // coming from __kmp_null_resume_wrapper | |||||
1573 | flag = (C *)CCAST(void *, th->th.th_sleep_loc)const_cast<void *>(th->th.th_sleep_loc); | |||||
1574 | } | |||||
1575 | ||||||
1576 | // First, check if the flag is null or its type has changed. If so, someone | |||||
1577 | // else woke it up. | |||||
1578 | if (!flag || flag->get_type() != flag->get_ptr_type()) { // get_ptr_type | |||||
1579 | // simply shows what | |||||
1580 | // flag was cast to | |||||
1581 | KF_TRACE(5, ("__kmp_resume_template: T#%d exiting, thread T#%d already "if (kmp_f_debug >= 5) { __kmp_debug_printf ("__kmp_resume_template: T#%d exiting, thread T#%d already " "awake: flag(%p)\n", gtid, target_gtid, __null); } | |||||
1582 | "awake: flag(%p)\n",if (kmp_f_debug >= 5) { __kmp_debug_printf ("__kmp_resume_template: T#%d exiting, thread T#%d already " "awake: flag(%p)\n", gtid, target_gtid, __null); } | |||||
1583 | gtid, target_gtid, NULL))if (kmp_f_debug >= 5) { __kmp_debug_printf ("__kmp_resume_template: T#%d exiting, thread T#%d already " "awake: flag(%p)\n", gtid, target_gtid, __null); }; | |||||
1584 | status = pthread_mutex_unlock(&th->th.th_suspend_mx.m_mutex); | |||||
1585 | KMP_CHECK_SYSFAIL("pthread_mutex_unlock", status){ if (status) { __kmp_fatal(__kmp_msg_format(kmp_i18n_msg_FunctionError , "pthread_mutex_unlock"), __kmp_msg_error_code(status), __kmp_msg_null ); } }; | |||||
1586 | return; | |||||
1587 | } else { // if multiple threads are sleeping, flag should be internally | |||||
1588 | // referring to a specific thread here | |||||
1589 | typename C::flag_t old_spin = flag->unset_sleeping(); | |||||
1590 | if (!flag->is_sleeping_val(old_spin)) { | |||||
1591 | KF_TRACE(5, ("__kmp_resume_template: T#%d exiting, thread T#%d already "if (kmp_f_debug >= 5) { __kmp_debug_printf ("__kmp_resume_template: T#%d exiting, thread T#%d already " "awake: flag(%p): " "%u => %u\n", gtid, target_gtid, flag ->get(), old_spin, flag->load()); } | |||||
1592 | "awake: flag(%p): "if (kmp_f_debug >= 5) { __kmp_debug_printf ("__kmp_resume_template: T#%d exiting, thread T#%d already " "awake: flag(%p): " "%u => %u\n", gtid, target_gtid, flag ->get(), old_spin, flag->load()); } | |||||
1593 | "%u => %u\n",if (kmp_f_debug >= 5) { __kmp_debug_printf ("__kmp_resume_template: T#%d exiting, thread T#%d already " "awake: flag(%p): " "%u => %u\n", gtid, target_gtid, flag ->get(), old_spin, flag->load()); } | |||||
1594 | gtid, target_gtid, flag->get(), old_spin, flag->load()))if (kmp_f_debug >= 5) { __kmp_debug_printf ("__kmp_resume_template: T#%d exiting, thread T#%d already " "awake: flag(%p): " "%u => %u\n", gtid, target_gtid, flag ->get(), old_spin, flag->load()); }; | |||||
1595 | status = pthread_mutex_unlock(&th->th.th_suspend_mx.m_mutex); | |||||
1596 | KMP_CHECK_SYSFAIL("pthread_mutex_unlock", status){ if (status) { __kmp_fatal(__kmp_msg_format(kmp_i18n_msg_FunctionError , "pthread_mutex_unlock"), __kmp_msg_error_code(status), __kmp_msg_null ); } }; | |||||
1597 | return; | |||||
1598 | } | |||||
1599 | KF_TRACE(5, ("__kmp_resume_template: T#%d about to wakeup T#%d, reset "if (kmp_f_debug >= 5) { __kmp_debug_printf ("__kmp_resume_template: T#%d about to wakeup T#%d, reset " "sleep bit for flag's loc(%p): " "%u => %u\n", gtid, target_gtid , flag->get(), old_spin, flag->load()); } | |||||
1600 | "sleep bit for flag's loc(%p): "if (kmp_f_debug >= 5) { __kmp_debug_printf ("__kmp_resume_template: T#%d about to wakeup T#%d, reset " "sleep bit for flag's loc(%p): " "%u => %u\n", gtid, target_gtid , flag->get(), old_spin, flag->load()); } | |||||
1601 | "%u => %u\n",if (kmp_f_debug >= 5) { __kmp_debug_printf ("__kmp_resume_template: T#%d about to wakeup T#%d, reset " "sleep bit for flag's loc(%p): " "%u => %u\n", gtid, target_gtid , flag->get(), old_spin, flag->load()); } | |||||
1602 | gtid, target_gtid, flag->get(), old_spin, flag->load()))if (kmp_f_debug >= 5) { __kmp_debug_printf ("__kmp_resume_template: T#%d about to wakeup T#%d, reset " "sleep bit for flag's loc(%p): " "%u => %u\n", gtid, target_gtid , flag->get(), old_spin, flag->load()); }; | |||||
1603 | } | |||||
1604 | TCW_PTR(th->th.th_sleep_loc, NULL)((th->th.th_sleep_loc)) = ((__null)); | |||||
1605 | ||||||
1606 | #ifdef DEBUG_SUSPEND | |||||
1607 | { | |||||
1608 | char buffer[128]; | |||||
1609 | __kmp_print_cond(buffer, &th->th.th_suspend_cv); | |||||
1610 | __kmp_printf("__kmp_resume_template: T#%d resuming T#%d: %s\n", gtid, | |||||
1611 | target_gtid, buffer); | |||||
1612 | } | |||||
1613 | #endif | |||||
1614 | status = pthread_cond_signal(&th->th.th_suspend_cv.c_cond); | |||||
1615 | KMP_CHECK_SYSFAIL("pthread_cond_signal", status){ if (status) { __kmp_fatal(__kmp_msg_format(kmp_i18n_msg_FunctionError , "pthread_cond_signal"), __kmp_msg_error_code(status), __kmp_msg_null ); } }; | |||||
1616 | status = pthread_mutex_unlock(&th->th.th_suspend_mx.m_mutex); | |||||
1617 | KMP_CHECK_SYSFAIL("pthread_mutex_unlock", status){ if (status) { __kmp_fatal(__kmp_msg_format(kmp_i18n_msg_FunctionError , "pthread_mutex_unlock"), __kmp_msg_error_code(status), __kmp_msg_null ); } }; | |||||
1618 | KF_TRACE(30, ("__kmp_resume_template: T#%d exiting after signaling wake up"if (kmp_f_debug >= 30) { __kmp_debug_printf ("__kmp_resume_template: T#%d exiting after signaling wake up" " for T#%d\n", gtid, target_gtid); } | |||||
1619 | " for T#%d\n",if (kmp_f_debug >= 30) { __kmp_debug_printf ("__kmp_resume_template: T#%d exiting after signaling wake up" " for T#%d\n", gtid, target_gtid); } | |||||
1620 | gtid, target_gtid))if (kmp_f_debug >= 30) { __kmp_debug_printf ("__kmp_resume_template: T#%d exiting after signaling wake up" " for T#%d\n", gtid, target_gtid); }; | |||||
1621 | } | |||||
1622 | ||||||
1623 | void __kmp_resume_32(int target_gtid, kmp_flag_32 *flag) { | |||||
1624 | __kmp_resume_template(target_gtid, flag); | |||||
1625 | } | |||||
1626 | void __kmp_resume_64(int target_gtid, kmp_flag_64 *flag) { | |||||
1627 | __kmp_resume_template(target_gtid, flag); | |||||
1628 | } | |||||
1629 | void __kmp_resume_oncore(int target_gtid, kmp_flag_oncore *flag) { | |||||
1630 | __kmp_resume_template(target_gtid, flag); | |||||
1631 | } | |||||
1632 | ||||||
1633 | #if KMP_USE_MONITOR | |||||
1634 | void __kmp_resume_monitor() { | |||||
1635 | KMP_TIME_DEVELOPER_PARTITIONED_BLOCK(USER_resume)((void)0); | |||||
1636 | int status; | |||||
1637 | #ifdef KMP_DEBUG1 | |||||
1638 | int gtid = TCR_4(__kmp_init_gtid)(__kmp_init_gtid) ? __kmp_get_gtid()__kmp_get_global_thread_id() : -1; | |||||
1639 | KF_TRACE(30, ("__kmp_resume_monitor: T#%d wants to wakeup T#%d enter\n", gtid,if (kmp_f_debug >= 30) { __kmp_debug_printf ("__kmp_resume_monitor: T#%d wants to wakeup T#%d enter\n" , gtid, (-4)); } | |||||
1640 | KMP_GTID_MONITOR))if (kmp_f_debug >= 30) { __kmp_debug_printf ("__kmp_resume_monitor: T#%d wants to wakeup T#%d enter\n" , gtid, (-4)); }; | |||||
1641 | KMP_DEBUG_ASSERT(gtid != KMP_GTID_MONITOR)if (!(gtid != (-4))) { __kmp_debug_assert("gtid != (-4)", "/build/llvm-toolchain-snapshot-8~svn345461/projects/openmp/runtime/src/z_Linux_util.cpp" , 1641); }; | |||||
1642 | #endif | |||||
1643 | status = pthread_mutex_lock(&__kmp_wait_mx.m_mutex); | |||||
1644 | KMP_CHECK_SYSFAIL("pthread_mutex_lock", status){ if (status) { __kmp_fatal(__kmp_msg_format(kmp_i18n_msg_FunctionError , "pthread_mutex_lock"), __kmp_msg_error_code(status), __kmp_msg_null ); } }; | |||||
1645 | #ifdef DEBUG_SUSPEND | |||||
1646 | { | |||||
1647 | char buffer[128]; | |||||
1648 | __kmp_print_cond(buffer, &__kmp_wait_cv.c_cond); | |||||
1649 | __kmp_printf("__kmp_resume_monitor: T#%d resuming T#%d: %s\n", gtid, | |||||
1650 | KMP_GTID_MONITOR(-4), buffer); | |||||
1651 | } | |||||
1652 | #endif | |||||
1653 | status = pthread_cond_signal(&__kmp_wait_cv.c_cond); | |||||
1654 | KMP_CHECK_SYSFAIL("pthread_cond_signal", status){ if (status) { __kmp_fatal(__kmp_msg_format(kmp_i18n_msg_FunctionError , "pthread_cond_signal"), __kmp_msg_error_code(status), __kmp_msg_null ); } }; | |||||
1655 | status = pthread_mutex_unlock(&__kmp_wait_mx.m_mutex); | |||||
1656 | KMP_CHECK_SYSFAIL("pthread_mutex_unlock", status){ if (status) { __kmp_fatal(__kmp_msg_format(kmp_i18n_msg_FunctionError , "pthread_mutex_unlock"), __kmp_msg_error_code(status), __kmp_msg_null ); } }; | |||||
1657 | KF_TRACE(30, ("__kmp_resume_monitor: T#%d exiting after signaling wake up"if (kmp_f_debug >= 30) { __kmp_debug_printf ("__kmp_resume_monitor: T#%d exiting after signaling wake up" " for T#%d\n", gtid, (-4)); } | |||||
1658 | " for T#%d\n",if (kmp_f_debug >= 30) { __kmp_debug_printf ("__kmp_resume_monitor: T#%d exiting after signaling wake up" " for T#%d\n", gtid, (-4)); } | |||||
1659 | gtid, KMP_GTID_MONITOR))if (kmp_f_debug >= 30) { __kmp_debug_printf ("__kmp_resume_monitor: T#%d exiting after signaling wake up" " for T#%d\n", gtid, (-4)); }; | |||||
1660 | } | |||||
1661 | #endif // KMP_USE_MONITOR | |||||
1662 | ||||||
1663 | void __kmp_yield(int cond) { | |||||
1664 | if (!cond) | |||||
1665 | return; | |||||
1666 | #if KMP_USE_MONITOR | |||||
1667 | if (!__kmp_yielding_on) | |||||
1668 | return; | |||||
1669 | #else | |||||
1670 | if (__kmp_yield_cycle && !KMP_YIELD_NOW()((__kmp_hardware_timestamp() / __kmp_ticks_per_msec) / ((__kmp_dflt_blocktime ) > (1) ? (__kmp_dflt_blocktime) : (1)) % (__kmp_yield_on_count + __kmp_yield_off_count) < (kmp_uint32)__kmp_yield_on_count )) | |||||
1671 | return; | |||||
1672 | #endif | |||||
1673 | sched_yield(); | |||||
1674 | } | |||||
1675 | ||||||
1676 | void __kmp_gtid_set_specific(int gtid) { | |||||
1677 | if (__kmp_init_gtid) { | |||||
1678 | int status; | |||||
1679 | status = pthread_setspecific(__kmp_gtid_threadprivate_key, | |||||
1680 | (void *)(intptr_t)(gtid + 1)); | |||||
1681 | KMP_CHECK_SYSFAIL("pthread_setspecific", status){ if (status) { __kmp_fatal(__kmp_msg_format(kmp_i18n_msg_FunctionError , "pthread_setspecific"), __kmp_msg_error_code(status), __kmp_msg_null ); } }; | |||||
1682 | } else { | |||||
1683 | KA_TRACE(50, ("__kmp_gtid_set_specific: runtime shutdown, returning\n"))if (kmp_a_debug >= 50) { __kmp_debug_printf ("__kmp_gtid_set_specific: runtime shutdown, returning\n" ); }; | |||||
1684 | } | |||||
1685 | } | |||||
1686 | ||||||
1687 | int __kmp_gtid_get_specific() { | |||||
1688 | int gtid; | |||||
1689 | if (!__kmp_init_gtid) { | |||||
1690 | KA_TRACE(50, ("__kmp_gtid_get_specific: runtime shutdown, returning "if (kmp_a_debug >= 50) { __kmp_debug_printf ("__kmp_gtid_get_specific: runtime shutdown, returning " "KMP_GTID_SHUTDOWN\n"); } | |||||
1691 | "KMP_GTID_SHUTDOWN\n"))if (kmp_a_debug >= 50) { __kmp_debug_printf ("__kmp_gtid_get_specific: runtime shutdown, returning " "KMP_GTID_SHUTDOWN\n"); }; | |||||
1692 | return KMP_GTID_SHUTDOWN(-3); | |||||
1693 | } | |||||
1694 | gtid = (int)(size_t)pthread_getspecific(__kmp_gtid_threadprivate_key); | |||||
1695 | if (gtid == 0) { | |||||
1696 | gtid = KMP_GTID_DNE(-2); | |||||
1697 | } else { | |||||
1698 | gtid--; | |||||
1699 | } | |||||
1700 | KA_TRACE(50, ("__kmp_gtid_get_specific: key:%d gtid:%d\n",if (kmp_a_debug >= 50) { __kmp_debug_printf ("__kmp_gtid_get_specific: key:%d gtid:%d\n" , __kmp_gtid_threadprivate_key, gtid); } | |||||
1701 | __kmp_gtid_threadprivate_key, gtid))if (kmp_a_debug >= 50) { __kmp_debug_printf ("__kmp_gtid_get_specific: key:%d gtid:%d\n" , __kmp_gtid_threadprivate_key, gtid); }; | |||||
1702 | return gtid; | |||||
1703 | } | |||||
1704 | ||||||
1705 | double __kmp_read_cpu_time(void) { | |||||
1706 | /*clock_t t;*/ | |||||
1707 | struct tms buffer; | |||||
1708 | ||||||
1709 | /*t =*/times(&buffer); | |||||
1710 | ||||||
1711 | return (buffer.tms_utime + buffer.tms_cutime) / (double)CLOCKS_PER_SEC((clock_t) 1000000); | |||||
1712 | } | |||||
1713 | ||||||
1714 | int __kmp_read_system_info(struct kmp_sys_info *info) { | |||||
1715 | int status; | |||||
1716 | struct rusage r_usage; | |||||
1717 | ||||||
1718 | memset(info, 0, sizeof(*info)); | |||||
1719 | ||||||
1720 | status = getrusage(RUSAGE_SELFRUSAGE_SELF, &r_usage); | |||||
1721 | KMP_CHECK_SYSFAIL_ERRNO("getrusage", status){ if (status != 0) { int error = (*__errno_location ()); __kmp_fatal (__kmp_msg_format(kmp_i18n_msg_FunctionError, "getrusage"), __kmp_msg_error_code (error), __kmp_msg_null); } }; | |||||
1722 | ||||||
1723 | // The maximum resident set size utilized (in kilobytes) | |||||
1724 | info->maxrss = r_usage.ru_maxrss; | |||||
1725 | // The number of page faults serviced without any I/O | |||||
1726 | info->minflt = r_usage.ru_minflt; | |||||
1727 | // The number of page faults serviced that required I/O | |||||
1728 | info->majflt = r_usage.ru_majflt; | |||||
1729 | // The number of times a process was "swapped" out of memory | |||||
1730 | info->nswap = r_usage.ru_nswap; | |||||
1731 | // The number of times the file system had to perform input | |||||
1732 | info->inblock = r_usage.ru_inblock; | |||||
1733 | // The number of times the file system had to perform output | |||||
1734 | info->oublock = r_usage.ru_oublock; | |||||
1735 | // The number of times a context switch was voluntarily | |||||
1736 | info->nvcsw = r_usage.ru_nvcsw; | |||||
1737 | // The number of times a context switch was forced | |||||
1738 | info->nivcsw = r_usage.ru_nivcsw; | |||||
1739 | ||||||
1740 | return (status != 0); | |||||
1741 | } | |||||
1742 | ||||||
1743 | void __kmp_read_system_time(double *delta) { | |||||
1744 | double t_ns; | |||||
1745 | struct timeval tval; | |||||
1746 | struct timespec stop; | |||||
1747 | int status; | |||||
1748 | ||||||
1749 | status = gettimeofday(&tval, NULL__null); | |||||
1750 | KMP_CHECK_SYSFAIL_ERRNO("gettimeofday", status){ if (status != 0) { int error = (*__errno_location ()); __kmp_fatal (__kmp_msg_format(kmp_i18n_msg_FunctionError, "gettimeofday") , __kmp_msg_error_code(error), __kmp_msg_null); } }; | |||||
1751 | TIMEVAL_TO_TIMESPEC(&tval, &stop){ (&stop)->tv_sec = (&tval)->tv_sec; (&stop )->tv_nsec = (&tval)->tv_usec * 1000; }; | |||||
1752 | t_ns = TS2NS(stop)(((stop).tv_sec * 1e9) + (stop).tv_nsec) - TS2NS(__kmp_sys_timer_data.start)(((__kmp_sys_timer_data.start).tv_sec * 1e9) + (__kmp_sys_timer_data .start).tv_nsec); | |||||
1753 | *delta = (t_ns * 1e-9); | |||||
1754 | } | |||||
1755 | ||||||
1756 | void __kmp_clear_system_time(void) { | |||||
1757 | struct timeval tval; | |||||
1758 | int status; | |||||
1759 | status = gettimeofday(&tval, NULL__null); | |||||
1760 | KMP_CHECK_SYSFAIL_ERRNO("gettimeofday", status){ if (status != 0) { int error = (*__errno_location ()); __kmp_fatal (__kmp_msg_format(kmp_i18n_msg_FunctionError, "gettimeofday") , __kmp_msg_error_code(error), __kmp_msg_null); } }; | |||||
1761 | TIMEVAL_TO_TIMESPEC(&tval, &__kmp_sys_timer_data.start){ (&__kmp_sys_timer_data.start)->tv_sec = (&tval)-> tv_sec; (&__kmp_sys_timer_data.start)->tv_nsec = (& tval)->tv_usec * 1000; }; | |||||
1762 | } | |||||
1763 | ||||||
1764 | static int __kmp_get_xproc(void) { | |||||
1765 | ||||||
1766 | int r = 0; | |||||
1767 | ||||||
1768 | #if KMP_OS_LINUX1 || KMP_OS_FREEBSD0 || KMP_OS_NETBSD0 | |||||
1769 | ||||||
1770 | r = sysconf(_SC_NPROCESSORS_ONLN_SC_NPROCESSORS_ONLN); | |||||
1771 | ||||||
1772 | #elif KMP_OS_DARWIN0 | |||||
1773 | ||||||
1774 | // Bug C77011 High "OpenMP Threads and number of active cores". | |||||
1775 | ||||||
1776 | // Find the number of available CPUs. | |||||
1777 | kern_return_t rc; | |||||
1778 | host_basic_info_data_t info; | |||||
1779 | mach_msg_type_number_t num = HOST_BASIC_INFO_COUNT; | |||||
1780 | rc = host_info(mach_host_self(), HOST_BASIC_INFO, (host_info_t)&info, &num); | |||||
1781 | if (rc == 0 && num == HOST_BASIC_INFO_COUNT) { | |||||
1782 | // Cannot use KA_TRACE() here because this code works before trace support | |||||
1783 | // is initialized. | |||||
1784 | r = info.avail_cpus; | |||||
1785 | } else { | |||||
1786 | KMP_WARNING(CantGetNumAvailCPU)__kmp_msg(kmp_ms_warning, __kmp_msg_format(kmp_i18n_msg_CantGetNumAvailCPU ), __kmp_msg_null); | |||||
1787 | KMP_INFORM(AssumedNumCPU)__kmp_msg(kmp_ms_inform, __kmp_msg_format(kmp_i18n_msg_AssumedNumCPU ), __kmp_msg_null); | |||||
1788 | } | |||||
1789 | ||||||
1790 | #else | |||||
1791 | ||||||
1792 | #error "Unknown or unsupported OS." | |||||
1793 | ||||||
1794 | #endif | |||||
1795 | ||||||
1796 | return r > 0 ? r : 2; /* guess value of 2 if OS told us 0 */ | |||||
1797 | ||||||
1798 | } // __kmp_get_xproc | |||||
1799 | ||||||
1800 | int __kmp_read_from_file(char const *path, char const *format, ...) { | |||||
1801 | int result; | |||||
1802 | va_list args; | |||||
1803 | ||||||
1804 | va_start(args, format)__builtin_va_start(args, format); | |||||
1805 | FILE *f = fopen(path, "rb"); | |||||
1806 | if (f == NULL__null) | |||||
1807 | return 0; | |||||
1808 | result = vfscanf(f, format, args); | |||||
1809 | fclose(f); | |||||
1810 | ||||||
1811 | return result; | |||||
1812 | } | |||||
1813 | ||||||
1814 | void __kmp_runtime_initialize(void) { | |||||
1815 | int status; | |||||
1816 | pthread_mutexattr_t mutex_attr; | |||||
1817 | pthread_condattr_t cond_attr; | |||||
1818 | ||||||
1819 | if (__kmp_init_runtime) { | |||||
1820 | return; | |||||
1821 | } | |||||
1822 | ||||||
1823 | #if (KMP_ARCH_X860 || KMP_ARCH_X86_641) | |||||
1824 | if (!__kmp_cpuinfo.initialized) { | |||||
1825 | __kmp_query_cpuid(&__kmp_cpuinfo); | |||||
1826 | } | |||||
1827 | #endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */ | |||||
1828 | ||||||
1829 | __kmp_xproc = __kmp_get_xproc(); | |||||
1830 | ||||||
1831 | if (sysconf(_SC_THREADS_SC_THREADS)) { | |||||
1832 | ||||||
1833 | /* Query the maximum number of threads */ | |||||
1834 | __kmp_sys_max_nth = sysconf(_SC_THREAD_THREADS_MAX_SC_THREAD_THREADS_MAX); | |||||
1835 | if (__kmp_sys_max_nth == -1) { | |||||
1836 | /* Unlimited threads for NPTL */ | |||||
1837 | __kmp_sys_max_nth = INT_MAX2147483647; | |||||
1838 | } else if (__kmp_sys_max_nth <= 1) { | |||||
1839 | /* Can't tell, just use PTHREAD_THREADS_MAX */ | |||||
1840 | __kmp_sys_max_nth = KMP_MAX_NTH2147483647; | |||||
1841 | } | |||||
1842 | ||||||
1843 | /* Query the minimum stack size */ | |||||
1844 | __kmp_sys_min_stksize = sysconf(_SC_THREAD_STACK_MIN_SC_THREAD_STACK_MIN); | |||||
1845 | if (__kmp_sys_min_stksize <= 1) { | |||||
1846 | __kmp_sys_min_stksize = KMP_MIN_STKSIZE16384; | |||||
1847 | } | |||||
1848 | } | |||||
1849 | ||||||
1850 | /* Set up minimum number of threads to switch to TLS gtid */ | |||||
1851 | __kmp_tls_gtid_min = KMP_TLS_GTID_MIN5; | |||||
1852 | ||||||
1853 | status = pthread_key_create(&__kmp_gtid_threadprivate_key, | |||||
1854 | __kmp_internal_end_dest); | |||||
1855 | KMP_CHECK_SYSFAIL("pthread_key_create", status){ if (status) { __kmp_fatal(__kmp_msg_format(kmp_i18n_msg_FunctionError , "pthread_key_create"), __kmp_msg_error_code(status), __kmp_msg_null ); } }; | |||||
1856 | status = pthread_mutexattr_init(&mutex_attr); | |||||
1857 | KMP_CHECK_SYSFAIL("pthread_mutexattr_init", status){ if (status) { __kmp_fatal(__kmp_msg_format(kmp_i18n_msg_FunctionError , "pthread_mutexattr_init"), __kmp_msg_error_code(status), __kmp_msg_null ); } }; | |||||
1858 | status = pthread_mutex_init(&__kmp_wait_mx.m_mutex, &mutex_attr); | |||||
1859 | KMP_CHECK_SYSFAIL("pthread_mutex_init", status){ if (status) { __kmp_fatal(__kmp_msg_format(kmp_i18n_msg_FunctionError , "pthread_mutex_init"), __kmp_msg_error_code(status), __kmp_msg_null ); } }; | |||||
1860 | status = pthread_condattr_init(&cond_attr); | |||||
1861 | KMP_CHECK_SYSFAIL("pthread_condattr_init", status){ if (status) { __kmp_fatal(__kmp_msg_format(kmp_i18n_msg_FunctionError , "pthread_condattr_init"), __kmp_msg_error_code(status), __kmp_msg_null ); } }; | |||||
1862 | status = pthread_cond_init(&__kmp_wait_cv.c_cond, &cond_attr); | |||||
1863 | KMP_CHECK_SYSFAIL("pthread_cond_init", status){ if (status) { __kmp_fatal(__kmp_msg_format(kmp_i18n_msg_FunctionError , "pthread_cond_init"), __kmp_msg_error_code(status), __kmp_msg_null ); } }; | |||||
1864 | #if USE_ITT_BUILD1 | |||||
1865 | __kmp_itt_initialize(); | |||||
1866 | #endif /* USE_ITT_BUILD */ | |||||
1867 | ||||||
1868 | __kmp_init_runtime = TRUE(!0); | |||||
1869 | } | |||||
1870 | ||||||
1871 | void __kmp_runtime_destroy(void) { | |||||
1872 | int status; | |||||
1873 | ||||||
1874 | if (!__kmp_init_runtime) { | |||||
1875 | return; // Nothing to do. | |||||
1876 | } | |||||
1877 | ||||||
1878 | #if USE_ITT_BUILD1 | |||||
1879 | __kmp_itt_destroy(); | |||||
1880 | #endif /* USE_ITT_BUILD */ | |||||
1881 | ||||||
1882 | status = pthread_key_delete(__kmp_gtid_threadprivate_key); | |||||
1883 | KMP_CHECK_SYSFAIL("pthread_key_delete", status){ if (status) { __kmp_fatal(__kmp_msg_format(kmp_i18n_msg_FunctionError , "pthread_key_delete"), __kmp_msg_error_code(status), __kmp_msg_null ); } }; | |||||
1884 | ||||||
1885 | status = pthread_mutex_destroy(&__kmp_wait_mx.m_mutex); | |||||
1886 | if (status != 0 && status != EBUSY16) { | |||||
1887 | KMP_SYSFAIL("pthread_mutex_destroy", status)__kmp_fatal(__kmp_msg_format(kmp_i18n_msg_FunctionError, "pthread_mutex_destroy" ), __kmp_msg_error_code(status), __kmp_msg_null); | |||||
1888 | } | |||||
1889 | status = pthread_cond_destroy(&__kmp_wait_cv.c_cond); | |||||
1890 | if (status != 0 && status != EBUSY16) { | |||||
1891 | KMP_SYSFAIL("pthread_cond_destroy", status)__kmp_fatal(__kmp_msg_format(kmp_i18n_msg_FunctionError, "pthread_cond_destroy" ), __kmp_msg_error_code(status), __kmp_msg_null); | |||||
1892 | } | |||||
1893 | #if KMP_AFFINITY_SUPPORTED1 | |||||
1894 | __kmp_affinity_uninitialize(); | |||||
1895 | #endif | |||||
1896 | ||||||
1897 | __kmp_init_runtime = FALSE0; | |||||
1898 | } | |||||
1899 | ||||||
1900 | /* Put the thread to sleep for a time period */ | |||||
1901 | /* NOTE: not currently used anywhere */ | |||||
1902 | void __kmp_thread_sleep(int millis) { sleep((millis + 500) / 1000); } | |||||
1903 | ||||||
1904 | /* Calculate the elapsed wall clock time for the user */ | |||||
1905 | void __kmp_elapsed(double *t) { | |||||
1906 | int status; | |||||
1907 | #ifdef FIX_SGI_CLOCK | |||||
1908 | struct timespec ts; | |||||
1909 | ||||||
1910 | status = clock_gettime(CLOCK_PROCESS_CPUTIME_ID2, &ts); | |||||
1911 | KMP_CHECK_SYSFAIL_ERRNO("clock_gettime", status){ if (status != 0) { int error = (*__errno_location ()); __kmp_fatal (__kmp_msg_format(kmp_i18n_msg_FunctionError, "clock_gettime" ), __kmp_msg_error_code(error), __kmp_msg_null); } }; | |||||
1912 | *t = | |||||
1913 | (double)ts.tv_nsec * (1.0 / (double)KMP_NSEC_PER_SEC1000000000L) + (double)ts.tv_sec; | |||||
1914 | #else | |||||
1915 | struct timeval tv; | |||||
1916 | ||||||
1917 | status = gettimeofday(&tv, NULL__null); | |||||
1918 | KMP_CHECK_SYSFAIL_ERRNO("gettimeofday", status){ if (status != 0) { int error = (*__errno_location ()); __kmp_fatal (__kmp_msg_format(kmp_i18n_msg_FunctionError, "gettimeofday") , __kmp_msg_error_code(error), __kmp_msg_null); } }; | |||||
1919 | *t = | |||||
1920 | (double)tv.tv_usec * (1.0 / (double)KMP_USEC_PER_SEC1000000L) + (double)tv.tv_sec; | |||||
1921 | #endif | |||||
1922 | } | |||||
1923 | ||||||
1924 | /* Calculate the elapsed wall clock tick for the user */ | |||||
1925 | void __kmp_elapsed_tick(double *t) { *t = 1 / (double)CLOCKS_PER_SEC((clock_t) 1000000); } | |||||
1926 | ||||||
1927 | /* Return the current time stamp in nsec */ | |||||
1928 | kmp_uint64 __kmp_now_nsec() { | |||||
1929 | struct timeval t; | |||||
1930 | gettimeofday(&t, NULL__null); | |||||
1931 | return KMP_NSEC_PER_SEC1000000000L * t.tv_sec + 1000 * t.tv_usec; | |||||
1932 | } | |||||
1933 | ||||||
1934 | #if KMP_ARCH_X860 || KMP_ARCH_X86_641 | |||||
1935 | /* Measure clock ticks per millisecond */ | |||||
1936 | void __kmp_initialize_system_tick() { | |||||
1937 | kmp_uint64 delay = 100000; // 50~100 usec on most machines. | |||||
1938 | kmp_uint64 nsec = __kmp_now_nsec(); | |||||
1939 | kmp_uint64 goal = __kmp_hardware_timestamp() + delay; | |||||
1940 | kmp_uint64 now; | |||||
1941 | while ((now = __kmp_hardware_timestamp()) < goal) | |||||
1942 | ; | |||||
1943 | __kmp_ticks_per_msec = | |||||
1944 | (kmp_uint64)(1e6 * (delay + (now - goal)) / (__kmp_now_nsec() - nsec)); | |||||
1945 | } | |||||
1946 | #endif | |||||
1947 | ||||||
1948 | /* Determine whether the given address is mapped into the current address | |||||
1949 | space. */ | |||||
1950 | ||||||
1951 | int __kmp_is_address_mapped(void *addr) { | |||||
1952 | ||||||
1953 | int found = 0; | |||||
1954 | int rc; | |||||
1955 | ||||||
1956 | #if KMP_OS_LINUX1 || KMP_OS_FREEBSD0 | |||||
1957 | ||||||
1958 | /* On Linux* OS, read the /proc/<pid>/maps pseudo-file to get all the address | |||||
1959 | ranges mapped into the address space. */ | |||||
1960 | ||||||
1961 | char *name = __kmp_str_format("/proc/%d/maps", getpid()); | |||||
1962 | FILE *file = NULL__null; | |||||
1963 | ||||||
1964 | file = fopen(name, "r"); | |||||
1965 | KMP_ASSERT(file != NULL)if (!(file != __null)) { __kmp_debug_assert("file != NULL", "/build/llvm-toolchain-snapshot-8~svn345461/projects/openmp/runtime/src/z_Linux_util.cpp" , 1965); }; | |||||
1966 | ||||||
1967 | for (;;) { | |||||
1968 | ||||||
1969 | void *beginning = NULL__null; | |||||
1970 | void *ending = NULL__null; | |||||
1971 | char perms[5]; | |||||
1972 | ||||||
1973 | rc = fscanf(file, "%p-%p %4s %*[^\n]\n", &beginning, &ending, perms); | |||||
1974 | if (rc == EOF(-1)) { | |||||
1975 | break; | |||||
1976 | } | |||||
1977 | KMP_ASSERT(rc == 3 &&if (!(rc == 3 && strlen(perms) == 4)) { __kmp_debug_assert ("rc == 3 && KMP_STRLEN(perms) == 4", "/build/llvm-toolchain-snapshot-8~svn345461/projects/openmp/runtime/src/z_Linux_util.cpp" , 1978); } | |||||
1978 | KMP_STRLEN(perms) == 4)if (!(rc == 3 && strlen(perms) == 4)) { __kmp_debug_assert ("rc == 3 && KMP_STRLEN(perms) == 4", "/build/llvm-toolchain-snapshot-8~svn345461/projects/openmp/runtime/src/z_Linux_util.cpp" , 1978); }; // Make sure all fields are read. | |||||
1979 | ||||||
1980 | // Ending address is not included in the region, but beginning is. | |||||
1981 | if ((addr >= beginning) && (addr < ending)) { | |||||
1982 | perms[2] = 0; // 3th and 4th character does not matter. | |||||
1983 | if (strcmp(perms, "rw") == 0) { | |||||
1984 | // Memory we are looking for should be readable and writable. | |||||
1985 | found = 1; | |||||
1986 | } | |||||
1987 | break; | |||||
1988 | } | |||||
1989 | } | |||||
1990 | ||||||
1991 | // Free resources. | |||||
1992 | fclose(file); | |||||
1993 | KMP_INTERNAL_FREE(name)free(name); | |||||
1994 | ||||||
1995 | #elif KMP_OS_DARWIN0 | |||||
1996 | ||||||
1997 | /* On OS X*, /proc pseudo filesystem is not available. Try to read memory | |||||
1998 | using vm interface. */ | |||||
1999 | ||||||
2000 | int buffer; | |||||
2001 | vm_size_t count; | |||||
2002 | rc = vm_read_overwrite( | |||||
2003 | mach_task_self(), // Task to read memory of. | |||||
2004 | (vm_address_t)(addr), // Address to read from. | |||||
2005 | 1, // Number of bytes to be read. | |||||
2006 | (vm_address_t)(&buffer), // Address of buffer to save read bytes in. | |||||
2007 | &count // Address of var to save number of read bytes in. | |||||
2008 | ); | |||||
2009 | if (rc == 0) { | |||||
2010 | // Memory successfully read. | |||||
2011 | found = 1; | |||||
2012 | } | |||||
2013 | ||||||
2014 | #elif KMP_OS_FREEBSD0 || KMP_OS_NETBSD0 | |||||
2015 | ||||||
2016 | // FIXME(FreeBSD, NetBSD): Implement this | |||||
2017 | found = 1; | |||||
2018 | ||||||
2019 | #else | |||||
2020 | ||||||
2021 | #error "Unknown or unsupported OS" | |||||
2022 | ||||||
2023 | #endif | |||||
2024 | ||||||
2025 | return found; | |||||
2026 | ||||||
2027 | } // __kmp_is_address_mapped | |||||
2028 | ||||||
2029 | #ifdef USE_LOAD_BALANCE1 | |||||
2030 | ||||||
2031 | #if KMP_OS_DARWIN0 | |||||
2032 | ||||||
2033 | // The function returns the rounded value of the system load average | |||||
2034 | // during given time interval which depends on the value of | |||||
2035 | // __kmp_load_balance_interval variable (default is 60 sec, other values | |||||
2036 | // may be 300 sec or 900 sec). | |||||
2037 | // It returns -1 in case of error. | |||||
2038 | int __kmp_get_load_balance(int max) { | |||||
2039 | double averages[3]; | |||||
2040 | int ret_avg = 0; | |||||
2041 | ||||||
2042 | int res = getloadavg(averages, 3); | |||||
2043 | ||||||
2044 | // Check __kmp_load_balance_interval to determine which of averages to use. | |||||
2045 | // getloadavg() may return the number of samples less than requested that is | |||||
2046 | // less than 3. | |||||
2047 | if (__kmp_load_balance_interval < 180 && (res >= 1)) { | |||||
2048 | ret_avg = averages[0]; // 1 min | |||||
2049 | } else if ((__kmp_load_balance_interval >= 180 && | |||||
2050 | __kmp_load_balance_interval < 600) && | |||||
2051 | (res >= 2)) { | |||||
2052 | ret_avg = averages[1]; // 5 min | |||||
2053 | } else if ((__kmp_load_balance_interval >= 600) && (res == 3)) { | |||||
2054 | ret_avg = averages[2]; // 15 min | |||||
2055 | } else { // Error occurred | |||||
2056 | return -1; | |||||
2057 | } | |||||
2058 | ||||||
2059 | return ret_avg; | |||||
2060 | } | |||||
2061 | ||||||
2062 | #else // Linux* OS | |||||
2063 | ||||||
2064 | // The fuction returns number of running (not sleeping) threads, or -1 in case | |||||
2065 | // of error. Error could be reported if Linux* OS kernel too old (without | |||||
2066 | // "/proc" support). Counting running threads stops if max running threads | |||||
2067 | // encountered. | |||||
2068 | int __kmp_get_load_balance(int max) { | |||||
2069 | static int permanent_error = 0; | |||||
2070 | static int glb_running_threads = 0; // Saved count of the running threads for | |||||
2071 | // the thread balance algortihm | |||||
2072 | static double glb_call_time = 0; /* Thread balance algorithm call time */ | |||||
2073 | ||||||
2074 | int running_threads = 0; // Number of running threads in the system. | |||||
2075 | ||||||
2076 | DIR *proc_dir = NULL__null; // Handle of "/proc/" directory. | |||||
2077 | struct dirent *proc_entry = NULL__null; | |||||
2078 | ||||||
2079 | kmp_str_buf_t task_path; // "/proc/<pid>/task/<tid>/" path. | |||||
2080 | DIR *task_dir = NULL__null; // Handle of "/proc/<pid>/task/<tid>/" directory. | |||||
2081 | struct dirent *task_entry = NULL__null; | |||||
2082 | int task_path_fixed_len; | |||||
2083 | ||||||
2084 | kmp_str_buf_t stat_path; // "/proc/<pid>/task/<tid>/stat" path. | |||||
2085 | int stat_file = -1; | |||||
2086 | int stat_path_fixed_len; | |||||
2087 | ||||||
2088 | int total_processes = 0; // Total number of processes in system. | |||||
2089 | int total_threads = 0; // Total number of threads in system. | |||||
2090 | ||||||
2091 | double call_time = 0.0; | |||||
2092 | ||||||
2093 | __kmp_str_buf_init(&task_path){ (&task_path)->str = (&task_path)->bulk; (& task_path)->size = sizeof((&task_path)->bulk); (& task_path)->used = 0; (&task_path)->bulk[0] = 0; }; | |||||
2094 | __kmp_str_buf_init(&stat_path){ (&stat_path)->str = (&stat_path)->bulk; (& stat_path)->size = sizeof((&stat_path)->bulk); (& stat_path)->used = 0; (&stat_path)->bulk[0] = 0; }; | |||||
2095 | ||||||
2096 | __kmp_elapsed(&call_time); | |||||
2097 | ||||||
2098 | if (glb_call_time && | |||||
2099 | (call_time - glb_call_time < __kmp_load_balance_interval)) { | |||||
2100 | running_threads = glb_running_threads; | |||||
2101 | goto finish; | |||||
2102 | } | |||||
2103 | ||||||
2104 | glb_call_time = call_time; | |||||
2105 | ||||||
2106 | // Do not spend time on scanning "/proc/" if we have a permanent error. | |||||
2107 | if (permanent_error) { | |||||
2108 | running_threads = -1; | |||||
2109 | goto finish; | |||||
2110 | } | |||||
2111 | ||||||
2112 | if (max <= 0) { | |||||
2113 | max = INT_MAX2147483647; | |||||
2114 | } | |||||
2115 | ||||||
2116 | // Open "/proc/" directory. | |||||
2117 | proc_dir = opendir("/proc"); | |||||
2118 | if (proc_dir == NULL__null) { | |||||
2119 | // Cannot open "/prroc/". Probably the kernel does not support it. Return an | |||||
2120 | // error now and in subsequent calls. | |||||
2121 | running_threads = -1; | |||||
2122 | permanent_error = 1; | |||||
2123 | goto finish; | |||||
2124 | } | |||||
2125 | ||||||
2126 | // Initialize fixed part of task_path. This part will not change. | |||||
2127 | __kmp_str_buf_cat(&task_path, "/proc/", 6); | |||||
2128 | task_path_fixed_len = task_path.used; // Remember number of used characters. | |||||
2129 | ||||||
2130 | proc_entry = readdir(proc_dir); | |||||
2131 | while (proc_entry != NULL__null) { | |||||
2132 | // Proc entry is a directory and name starts with a digit. Assume it is a | |||||
2133 | // process' directory. | |||||
2134 | if (proc_entry->d_type == DT_DIRDT_DIR && isdigit(proc_entry->d_name[0])) { | |||||
2135 | ||||||
2136 | ++total_processes; | |||||
2137 | // Make sure init process is the very first in "/proc", so we can replace | |||||
2138 | // strcmp( proc_entry->d_name, "1" ) == 0 with simpler total_processes == | |||||
2139 | // 1. We are going to check that total_processes == 1 => d_name == "1" is | |||||
2140 | // true (where "=>" is implication). Since C++ does not have => operator, | |||||
2141 | // let us replace it with its equivalent: a => b == ! a || b. | |||||
2142 | KMP_DEBUG_ASSERT(total_processes != 1 ||if (!(total_processes != 1 || strcmp(proc_entry->d_name, "1" ) == 0)) { __kmp_debug_assert("total_processes != 1 || strcmp(proc_entry->d_name, \"1\") == 0" , "/build/llvm-toolchain-snapshot-8~svn345461/projects/openmp/runtime/src/z_Linux_util.cpp" , 2143); } | |||||
2143 | strcmp(proc_entry->d_name, "1") == 0)if (!(total_processes != 1 || strcmp(proc_entry->d_name, "1" ) == 0)) { __kmp_debug_assert("total_processes != 1 || strcmp(proc_entry->d_name, \"1\") == 0" , "/build/llvm-toolchain-snapshot-8~svn345461/projects/openmp/runtime/src/z_Linux_util.cpp" , 2143); }; | |||||
2144 | ||||||
2145 | // Construct task_path. | |||||
2146 | task_path.used = task_path_fixed_len; // Reset task_path to "/proc/". | |||||
2147 | __kmp_str_buf_cat(&task_path, proc_entry->d_name, | |||||
2148 | KMP_STRLENstrlen(proc_entry->d_name)); | |||||
2149 | __kmp_str_buf_cat(&task_path, "/task", 5); | |||||
2150 | ||||||
2151 | task_dir = opendir(task_path.str); | |||||
2152 | if (task_dir == NULL__null) { | |||||
2153 | // Process can finish between reading "/proc/" directory entry and | |||||
2154 | // opening process' "task/" directory. So, in general case we should not | |||||
2155 | // complain, but have to skip this process and read the next one. But on | |||||
2156 | // systems with no "task/" support we will spend lot of time to scan | |||||
2157 | // "/proc/" tree again and again without any benefit. "init" process | |||||
2158 | // (its pid is 1) should exist always, so, if we cannot open | |||||
2159 | // "/proc/1/task/" directory, it means "task/" is not supported by | |||||
2160 | // kernel. Report an error now and in the future. | |||||
2161 | if (strcmp(proc_entry->d_name, "1") == 0) { | |||||
2162 | running_threads = -1; | |||||
2163 | permanent_error = 1; | |||||
2164 | goto finish; | |||||
2165 | } | |||||
2166 | } else { | |||||
2167 | // Construct fixed part of stat file path. | |||||
2168 | __kmp_str_buf_clear(&stat_path); | |||||
2169 | __kmp_str_buf_cat(&stat_path, task_path.str, task_path.used); | |||||
2170 | __kmp_str_buf_cat(&stat_path, "/", 1); | |||||
2171 | stat_path_fixed_len = stat_path.used; | |||||
2172 | ||||||
2173 | task_entry = readdir(task_dir); | |||||
2174 | while (task_entry != NULL__null) { | |||||
2175 | // It is a directory and name starts with a digit. | |||||
2176 | if (proc_entry->d_type == DT_DIRDT_DIR && isdigit(task_entry->d_name[0])) { | |||||
2177 | ++total_threads; | |||||
2178 | ||||||
2179 | // Consruct complete stat file path. Easiest way would be: | |||||
2180 | // __kmp_str_buf_print( & stat_path, "%s/%s/stat", task_path.str, | |||||
2181 | // task_entry->d_name ); | |||||
2182 | // but seriae of __kmp_str_buf_cat works a bit faster. | |||||
2183 | stat_path.used = | |||||
2184 | stat_path_fixed_len; // Reset stat path to its fixed part. | |||||
2185 | __kmp_str_buf_cat(&stat_path, task_entry->d_name, | |||||
2186 | KMP_STRLENstrlen(task_entry->d_name)); | |||||
2187 | __kmp_str_buf_cat(&stat_path, "/stat", 5); | |||||
2188 | ||||||
2189 | // Note: Low-level API (open/read/close) is used. High-level API | |||||
2190 | // (fopen/fclose) works ~ 30 % slower. | |||||
2191 | stat_file = open(stat_path.str, O_RDONLY00); | |||||
2192 | if (stat_file == -1) { | |||||
2193 | // We cannot report an error because task (thread) can terminate | |||||
2194 | // just before reading this file. | |||||
2195 | } else { | |||||
2196 | /* Content of "stat" file looks like: | |||||
2197 | 24285 (program) S ... | |||||
2198 | ||||||
2199 | It is a single line (if program name does not include funny | |||||
2200 | symbols). First number is a thread id, then name of executable | |||||
2201 | file name in paretheses, then state of the thread. We need just | |||||
2202 | thread state. | |||||
2203 | ||||||
2204 | Good news: Length of program name is 15 characters max. Longer | |||||
2205 | names are truncated. | |||||
2206 | ||||||
2207 | Thus, we need rather short buffer: 15 chars for program name + | |||||
2208 | 2 parenthesis, + 3 spaces + ~7 digits of pid = 37. | |||||
2209 | ||||||
2210 | Bad news: Program name may contain special symbols like space, | |||||
2211 | closing parenthesis, or even new line. This makes parsing | |||||
2212 | "stat" file not 100 % reliable. In case of fanny program names | |||||
2213 | parsing may fail (report incorrect thread state). | |||||
2214 | ||||||
2215 | Parsing "status" file looks more promissing (due to different | |||||
2216 | file structure and escaping special symbols) but reading and | |||||
2217 | parsing of "status" file works slower. | |||||
2218 | -- ln | |||||
2219 | */ | |||||
2220 | char buffer[65]; | |||||
2221 | int len; | |||||
2222 | len = read(stat_file, buffer, sizeof(buffer) - 1); | |||||
2223 | if (len >= 0) { | |||||
2224 | buffer[len] = 0; | |||||
2225 | // Using scanf: | |||||
2226 | // sscanf( buffer, "%*d (%*s) %c ", & state ); | |||||
2227 | // looks very nice, but searching for a closing parenthesis | |||||
2228 | // works a bit faster. | |||||
2229 | char *close_parent = strstr(buffer, ") "); | |||||
2230 | if (close_parent != NULL__null) { | |||||
2231 | char state = *(close_parent + 2); | |||||
2232 | if (state == 'R') { | |||||
2233 | ++running_threads; | |||||
2234 | if (running_threads >= max) { | |||||
2235 | goto finish; | |||||
2236 | } | |||||
2237 | } | |||||
2238 | } | |||||
2239 | } | |||||
2240 | close(stat_file); | |||||
2241 | stat_file = -1; | |||||
2242 | } | |||||
2243 | } | |||||
2244 | task_entry = readdir(task_dir); | |||||
2245 | } | |||||
2246 | closedir(task_dir); | |||||
2247 | task_dir = NULL__null; | |||||
2248 | } | |||||
2249 | } | |||||
2250 | proc_entry = readdir(proc_dir); | |||||
2251 | } | |||||
2252 | ||||||
2253 | // There _might_ be a timing hole where the thread executing this | |||||
2254 | // code get skipped in the load balance, and running_threads is 0. | |||||
2255 | // Assert in the debug builds only!!! | |||||
2256 | KMP_DEBUG_ASSERT(running_threads > 0)if (!(running_threads > 0)) { __kmp_debug_assert("running_threads > 0" , "/build/llvm-toolchain-snapshot-8~svn345461/projects/openmp/runtime/src/z_Linux_util.cpp" , 2256); }; | |||||
2257 | if (running_threads <= 0) { | |||||
2258 | running_threads = 1; | |||||
2259 | } | |||||
2260 | ||||||
2261 | finish: // Clean up and exit. | |||||
2262 | if (proc_dir != NULL__null) { | |||||
2263 | closedir(proc_dir); | |||||
2264 | } | |||||
2265 | __kmp_str_buf_free(&task_path); | |||||
2266 | if (task_dir != NULL__null) { | |||||
2267 | closedir(task_dir); | |||||
2268 | } | |||||
2269 | __kmp_str_buf_free(&stat_path); | |||||
2270 | if (stat_file != -1) { | |||||
2271 | close(stat_file); | |||||
2272 | } | |||||
2273 | ||||||
2274 | glb_running_threads = running_threads; | |||||
2275 | ||||||
2276 | return running_threads; | |||||
2277 | ||||||
2278 | } // __kmp_get_load_balance | |||||
2279 | ||||||
2280 | #endif // KMP_OS_DARWIN | |||||
2281 | ||||||
2282 | #endif // USE_LOAD_BALANCE | |||||
2283 | ||||||
2284 | #if !(KMP_ARCH_X860 || KMP_ARCH_X86_641 || KMP_MIC0 || \ | |||||
2285 | ((KMP_OS_LINUX1 || KMP_OS_DARWIN0) && KMP_ARCH_AARCH640) || KMP_ARCH_PPC64(0 || 0)) | |||||
2286 | ||||||
2287 | // we really only need the case with 1 argument, because CLANG always build | |||||
2288 | // a struct of pointers to shared variables referenced in the outlined function | |||||
2289 | int __kmp_invoke_microtask(microtask_t pkfn, int gtid, int tid, int argc, | |||||
2290 | void *p_argv[] | |||||
2291 | #if OMPT_SUPPORT1 | |||||
2292 | , | |||||
2293 | void **exit_frame_ptr | |||||
2294 | #endif | |||||
2295 | ) { | |||||
2296 | #if OMPT_SUPPORT1 | |||||
2297 | *exit_frame_ptr = OMPT_GET_FRAME_ADDRESS(0)__builtin_frame_address(0); | |||||
2298 | #endif | |||||
2299 | ||||||
2300 | switch (argc) { | |||||
2301 | default: | |||||
2302 | fprintf(stderrstderr, "Too many args to microtask: %d!\n", argc); | |||||
2303 | fflush(stderrstderr); | |||||
2304 | exit(-1); | |||||
2305 | case 0: | |||||
2306 | (*pkfn)(>id, &tid); | |||||
2307 | break; | |||||
2308 | case 1: | |||||
2309 | (*pkfn)(>id, &tid, p_argv[0]); | |||||
2310 | break; | |||||
2311 | case 2: | |||||
2312 | (*pkfn)(>id, &tid, p_argv[0], p_argv[1]); | |||||
2313 | break; | |||||
2314 | case 3: | |||||
2315 | (*pkfn)(>id, &tid, p_argv[0], p_argv[1], p_argv[2]); | |||||
2316 | break; | |||||
2317 | case 4: | |||||
2318 | (*pkfn)(>id, &tid, p_argv[0], p_argv[1], p_argv[2], p_argv[3]); | |||||
2319 | break; | |||||
2320 | case 5: | |||||
2321 | (*pkfn)(>id, &tid, p_argv[0], p_argv[1], p_argv[2], p_argv[3], p_argv[4]); | |||||
2322 | break; | |||||
2323 | case 6: | |||||
2324 | (*pkfn)(>id, &tid, p_argv[0], p_argv[1], p_argv[2], p_argv[3], p_argv[4], | |||||
2325 | p_argv[5]); | |||||
2326 | break; | |||||
2327 | case 7: | |||||
2328 | (*pkfn)(>id, &tid, p_argv[0], p_argv[1], p_argv[2], p_argv[3], p_argv[4], | |||||
2329 | p_argv[5], p_argv[6]); | |||||
2330 | break; | |||||
2331 | case 8: | |||||
2332 | (*pkfn)(>id, &tid, p_argv[0], p_argv[1], p_argv[2], p_argv[3], p_argv[4], | |||||
2333 | p_argv[5], p_argv[6], p_argv[7]); | |||||
2334 | break; | |||||
2335 | case 9: | |||||
2336 | (*pkfn)(>id, &tid, p_argv[0], p_argv[1], p_argv[2], p_argv[3], p_argv[4], | |||||
2337 | p_argv[5], p_argv[6], p_argv[7], p_argv[8]); | |||||
2338 | break; | |||||
2339 | case 10: | |||||
2340 | (*pkfn)(>id, &tid, p_argv[0], p_argv[1], p_argv[2], p_argv[3], p_argv[4], | |||||
2341 | p_argv[5], p_argv[6], p_argv[7], p_argv[8], p_argv[9]); | |||||
2342 | break; | |||||
2343 | case 11: | |||||
2344 | (*pkfn)(>id, &tid, p_argv[0], p_argv[1], p_argv[2], p_argv[3], p_argv[4], | |||||
2345 | p_argv[5], p_argv[6], p_argv[7], p_argv[8], p_argv[9], p_argv[10]); | |||||
2346 | break; | |||||
2347 | case 12: | |||||
2348 | (*pkfn)(>id, &tid, p_argv[0], p_argv[1], p_argv[2], p_argv[3], p_argv[4], | |||||
2349 | p_argv[5], p_argv[6], p_argv[7], p_argv[8], p_argv[9], p_argv[10], | |||||
2350 | p_argv[11]); | |||||
2351 | break; | |||||
2352 | case 13: | |||||
2353 | (*pkfn)(>id, &tid, p_argv[0], p_argv[1], p_argv[2], p_argv[3], p_argv[4], | |||||
2354 | p_argv[5], p_argv[6], p_argv[7], p_argv[8], p_argv[9], p_argv[10], | |||||
2355 | p_argv[11], p_argv[12]); | |||||
2356 | break; | |||||
2357 | case 14: | |||||
2358 | (*pkfn)(>id, &tid, p_argv[0], p_argv[1], p_argv[2], p_argv[3], p_argv[4], | |||||
2359 | p_argv[5], p_argv[6], p_argv[7], p_argv[8], p_argv[9], p_argv[10], | |||||
2360 | p_argv[11], p_argv[12], p_argv[13]); | |||||
2361 | break; | |||||
2362 | case 15: | |||||
2363 | (*pkfn)(>id, &tid, p_argv[0], p_argv[1], p_argv[2], p_argv[3], p_argv[4], | |||||
2364 | p_argv[5], p_argv[6], p_argv[7], p_argv[8], p_argv[9], p_argv[10], | |||||
2365 | p_argv[11], p_argv[12], p_argv[13], p_argv[14]); | |||||
2366 | break; | |||||
2367 | } | |||||
2368 | ||||||
2369 | #if OMPT_SUPPORT1 | |||||
2370 | *exit_frame_ptr = 0; | |||||
2371 | #endif | |||||
2372 | ||||||
2373 | return 1; | |||||
2374 | } | |||||
2375 | ||||||
2376 | #endif | |||||
2377 | ||||||
2378 | // end of file // |