StarPU Handbook - StarPU Language Bindings
starpu_thread_util.h
Go to the documentation of this file.
1 /* StarPU --- Runtime system for heterogeneous multicore architectures.
2  *
3  * Copyright (C) 2010-2021 Université de Bordeaux, CNRS (LaBRI UMR 5800), Inria
4  *
5  * StarPU is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU Lesser General Public License as published by
7  * the Free Software Foundation; either version 2.1 of the License, or (at
8  * your option) any later version.
9  *
10  * StarPU is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13  *
14  * See the GNU Lesser General Public License in COPYING.LGPL for more details.
15  */
16 
17 // The documentation for this file is in doc/doxygen/chapters/api/threads.doxy
18 
19 #ifndef __STARPU_THREAD_UTIL_H__
20 #define __STARPU_THREAD_UTIL_H__
21 
22 #include <starpu_util.h>
23 #include <starpu_thread.h>
24 #include <errno.h>
25 
26 #if !(defined(_MSC_VER) && !defined(BUILDING_STARPU))
27 /*
28  * Encapsulation of the starpu_pthread_create_* functions.
29  */
30 
31 #define STARPU_PTHREAD_CREATE_ON(name, thread, attr, routine, arg, where) \
32  do { \
33  int p_ret = starpu_pthread_create_on((name), (thread), (attr), (routine), (arg), (where)); \
34  if (STARPU_UNLIKELY(p_ret != 0)) \
35  { \
36  fprintf(stderr, \
37  "%s:%d starpu_pthread_create_on: %s\n", \
38  __FILE__, __LINE__, strerror(p_ret)); \
39  STARPU_ABORT(); \
40  } \
41  } \
42  while (0)
43 
44 #define STARPU_PTHREAD_CREATE(thread, attr, routine, arg) \
45  do { \
46  int p_ret = starpu_pthread_create((thread), (attr), (routine), (arg)); \
47  if (STARPU_UNLIKELY(p_ret != 0)) \
48  { \
49  fprintf(stderr, \
50  "%s:%d starpu_pthread_create: %s\n", \
51  __FILE__, __LINE__, strerror(p_ret)); \
52  STARPU_ABORT(); \
53  } \
54  } \
55  while (0)
56 
57 #define STARPU_PTHREAD_JOIN(thread, retval) \
58  do { \
59  int p_ret = starpu_pthread_join((thread), (retval)); \
60  if (STARPU_UNLIKELY(p_ret != 0)) \
61  { \
62  fprintf(stderr, \
63  "%s:%d starpu_pthread_join: %s\n", \
64  __FILE__, __LINE__, strerror(p_ret)); \
65  STARPU_ABORT(); \
66  } \
67  } \
68  while (0)
69 
70 /*
71  * Encapsulation of the starpu_pthread_mutex_* functions.
72  */
73 
74 #define _STARPU_PTHREAD_MUTEX_INIT(mutex, attr) \
75  do { \
76  int p_ret = starpu_pthread_mutex_init((mutex), (attr)); \
77  if (STARPU_UNLIKELY(p_ret)) \
78  { \
79  fprintf(stderr, \
80  "%s:%d starpu_pthread_mutex_init: %s\n", \
81  __FILE__, __LINE__, strerror(p_ret)); \
82  STARPU_ABORT(); \
83  } \
84  } \
85  while (0)
86 
87 #ifdef STARPU_PTHREAD_MUTEX_INITIALIZER_ZERO
88 #define STARPU_PTHREAD_MUTEX_INIT(mutex, attr) \
89  do { \
90  if (!attr) \
91  memset(mutex, 0, sizeof(*mutex)); \
92  else \
93  _STARPU_PTHREAD_MUTEX_INIT(mutex, attr); \
94  } \
95  while (0)
96 #define STARPU_PTHREAD_MUTEX_INIT0(mutex, attr) \
97  do { \
98  if (attr) \
99  _STARPU_PTHREAD_MUTEX_INIT(mutex, attr); \
100  } \
101  while (0)
102 #else
103 #define STARPU_PTHREAD_MUTEX_INIT(mutex, attr) _STARPU_PTHREAD_MUTEX_INIT(mutex, attr)
104 #define STARPU_PTHREAD_MUTEX_INIT0(mutex, attr) _STARPU_PTHREAD_MUTEX_INIT(mutex, attr)
105 #endif
106 
107 #define STARPU_PTHREAD_MUTEX_DESTROY(mutex) \
108  do { \
109  int p_ret = starpu_pthread_mutex_destroy(mutex); \
110  if (STARPU_UNLIKELY(p_ret)) \
111  { \
112  fprintf(stderr, \
113  "%s:%d starpu_pthread_mutex_destroy: %s\n", \
114  __FILE__, __LINE__, strerror(p_ret)); \
115  STARPU_ABORT(); \
116  } \
117  } \
118  while (0)
119 
120 #ifdef STARPU_DEBUG
121 #define _STARPU_CHECK_NOT_SCHED_MUTEX(mutex, file, line) \
122  starpu_pthread_mutex_check_sched((mutex), file, line)
123 #else
124 #define _STARPU_CHECK_NOT_SCHED_MUTEX(mutex, file, line)
125 #endif
126 
127 #define STARPU_PTHREAD_MUTEX_LOCK(mutex) \
128  do { \
129  int p_ret = starpu_pthread_mutex_lock(mutex); \
130  if (STARPU_UNLIKELY(p_ret)) \
131  { \
132  fprintf(stderr, \
133  "%s:%d starpu_pthread_mutex_lock: %s\n", \
134  __FILE__, __LINE__, strerror(p_ret)); \
135  STARPU_ABORT(); \
136  } \
137  _STARPU_CHECK_NOT_SCHED_MUTEX(mutex, __FILE__, __LINE__); \
138  } \
139  while (0)
140 
141 #define STARPU_PTHREAD_MUTEX_LOCK_SCHED(mutex) \
142  do { \
143  int p_ret = starpu_pthread_mutex_lock_sched(mutex); \
144  if (STARPU_UNLIKELY(p_ret)) \
145  { \
146  fprintf(stderr, \
147  "%s:%d starpu_pthread_mutex_lock_sched: %s\n", \
148  __FILE__, __LINE__, strerror(p_ret)); \
149  STARPU_ABORT(); \
150  } \
151  } \
152  while (0)
153 
154 #define STARPU_PTHREAD_MUTEX_TRYLOCK(mutex) \
155  _starpu_pthread_mutex_trylock(mutex, __FILE__, __LINE__)
156 static STARPU_INLINE int _starpu_pthread_mutex_trylock(starpu_pthread_mutex_t *mutex, char *file, int line)
157 {
158  int p_ret = starpu_pthread_mutex_trylock(mutex);
159  if (STARPU_UNLIKELY(p_ret != 0 && p_ret != EBUSY))
160  {
161  fprintf(stderr,
162  "%s:%d starpu_pthread_mutex_trylock: %s\n",
163  file, line, strerror(p_ret));
164  STARPU_ABORT();
165  }
166  _STARPU_CHECK_NOT_SCHED_MUTEX(mutex, file, line);
167  return p_ret;
168 }
169 
170 #define STARPU_PTHREAD_MUTEX_TRYLOCK_SCHED(mutex) \
171  _starpu_pthread_mutex_trylock_sched(mutex, __FILE__, __LINE__)
172 static STARPU_INLINE int _starpu_pthread_mutex_trylock_sched(starpu_pthread_mutex_t *mutex, char *file, int line)
173 {
174  int p_ret = starpu_pthread_mutex_trylock_sched(mutex);
175  if (STARPU_UNLIKELY(p_ret != 0 && p_ret != EBUSY))
176  {
177  fprintf(stderr,
178  "%s:%d starpu_pthread_mutex_trylock_sched: %s\n",
179  file, line, strerror(p_ret));
180  STARPU_ABORT();
181  }
182  return p_ret;
183 }
184 
185 #define STARPU_PTHREAD_MUTEX_UNLOCK(mutex) \
186  do { \
187  _STARPU_CHECK_NOT_SCHED_MUTEX(mutex, __FILE__, __LINE__); \
188  int p_ret = starpu_pthread_mutex_unlock(mutex); \
189  if (STARPU_UNLIKELY(p_ret)) \
190  { \
191  fprintf(stderr, \
192  "%s:%d starpu_pthread_mutex_unlock: %s\n", \
193  __FILE__, __LINE__, strerror(p_ret)); \
194  STARPU_ABORT(); \
195  } \
196  } \
197  while (0)
198 
199 #define STARPU_PTHREAD_MUTEX_UNLOCK_SCHED(mutex) \
200  do { \
201  int p_ret = starpu_pthread_mutex_unlock_sched(mutex); \
202  if (STARPU_UNLIKELY(p_ret)) \
203  { \
204  fprintf(stderr, \
205  "%s:%d starpu_pthread_mutex_unlock_sched: %s\n", \
206  __FILE__, __LINE__, strerror(p_ret)); \
207  STARPU_ABORT(); \
208  } \
209  } \
210  while (0)
211 
212 /*
213  * Encapsulation of the starpu_pthread_key_* functions.
214  */
215 #define STARPU_PTHREAD_KEY_CREATE(key, destr) \
216  do { \
217  int p_ret = starpu_pthread_key_create((key), (destr)); \
218  if (STARPU_UNLIKELY(p_ret != 0)) \
219  { \
220  fprintf(stderr, \
221  "%s:%d starpu_pthread_key_create: %s\n", \
222  __FILE__, __LINE__, strerror(p_ret)); \
223  } \
224  } \
225  while (0)
226 
227 #define STARPU_PTHREAD_KEY_DELETE(key) \
228  do { \
229  int p_ret = starpu_pthread_key_delete((key)); \
230  if (STARPU_UNLIKELY(p_ret != 0)) \
231  { \
232  fprintf(stderr, \
233  "%s:%d starpu_pthread_key_delete: %s\n", \
234  __FILE__, __LINE__, strerror(p_ret)); \
235  } \
236  } \
237  while (0)
238 
239 #define STARPU_PTHREAD_SETSPECIFIC(key, ptr) \
240  do { \
241  int p_ret = starpu_pthread_setspecific((key), (ptr)); \
242  if (STARPU_UNLIKELY(p_ret != 0)) \
243  { \
244  fprintf(stderr, \
245  "%s:%d starpu_pthread_setspecific: %s\n", \
246  __FILE__, __LINE__, strerror(p_ret)); \
247  }; \
248  } \
249  while (0)
250 
251 #define STARPU_PTHREAD_GETSPECIFIC(key) starpu_pthread_getspecific((key))
252 
253 /*
254  * Encapsulation of the starpu_pthread_rwlock_* functions.
255  */
256 #define _STARPU_PTHREAD_RWLOCK_INIT(rwlock, attr) \
257  do { \
258  int p_ret = starpu_pthread_rwlock_init((rwlock), (attr)); \
259  if (STARPU_UNLIKELY(p_ret)) \
260  { \
261  fprintf(stderr, \
262  "%s:%d starpu_pthread_rwlock_init: %s\n", \
263  __FILE__, __LINE__, strerror(p_ret)); \
264  STARPU_ABORT(); \
265  } \
266  } \
267  while (0)
268 
269 #ifdef STARPU_PTHREAD_RWLOCK_INITIALIZER_ZERO
270 #define STARPU_PTHREAD_RWLOCK_INIT(rwlock, attr) \
271  do { \
272  if (!attr) \
273  memset(rwlock, 0, sizeof(*rwlock)); \
274  else \
275  _STARPU_PTHREAD_RWLOCK_INIT(rwlock, attr); \
276  } \
277  while (0)
278 #define STARPU_PTHREAD_RWLOCK_INIT0(rwlock, attr) \
279  do { \
280  if (attr) \
281  _STARPU_PTHREAD_RWLOCK_INIT(rwlock, attr); \
282  } \
283  while (0)
284 #else
285 #define STARPU_PTHREAD_RWLOCK_INIT(rwlock, attr) _STARPU_PTHREAD_RWLOCK_INIT(rwlock, attr)
286 #define STARPU_PTHREAD_RWLOCK_INIT0(rwlock, attr) _STARPU_PTHREAD_RWLOCK_INIT(rwlock, attr)
287 #endif
288 
289 #define STARPU_PTHREAD_RWLOCK_RDLOCK(rwlock) \
290  do { \
291  int p_ret = starpu_pthread_rwlock_rdlock(rwlock); \
292  if (STARPU_UNLIKELY(p_ret)) \
293  { \
294  fprintf(stderr, \
295  "%s:%d starpu_pthread_rwlock_rdlock: %s\n", \
296  __FILE__, __LINE__, strerror(p_ret)); \
297  STARPU_ABORT(); \
298  } \
299  } \
300  while (0)
301 
302 #define STARPU_PTHREAD_RWLOCK_TRYRDLOCK(rwlock) \
303  _starpu_pthread_rwlock_tryrdlock(rwlock, __FILE__, __LINE__)
304 static STARPU_INLINE int _starpu_pthread_rwlock_tryrdlock(starpu_pthread_rwlock_t *rwlock, char *file, int line)
305 {
306  int p_ret = starpu_pthread_rwlock_tryrdlock(rwlock);
307  if (STARPU_UNLIKELY(p_ret != 0 && p_ret != EBUSY))
308  {
309  fprintf(stderr,
310  "%s:%d starpu_pthread_rwlock_tryrdlock: %s\n",
311  file, line, strerror(p_ret));
312  STARPU_ABORT();
313  }
314  return p_ret;
315 }
316 
317 #define STARPU_PTHREAD_RWLOCK_WRLOCK(rwlock) \
318  do { \
319  int p_ret = starpu_pthread_rwlock_wrlock(rwlock); \
320  if (STARPU_UNLIKELY(p_ret)) \
321  { \
322  fprintf(stderr, \
323  "%s:%d starpu_pthread_rwlock_wrlock: %s\n", \
324  __FILE__, __LINE__, strerror(p_ret)); \
325  STARPU_ABORT(); \
326  } \
327  } \
328  while (0)
329 
330 #define STARPU_PTHREAD_RWLOCK_TRYWRLOCK(rwlock) \
331  _starpu_pthread_rwlock_trywrlock(rwlock, __FILE__, __LINE__)
332 static STARPU_INLINE int _starpu_pthread_rwlock_trywrlock(starpu_pthread_rwlock_t *rwlock, char *file, int line)
333 {
334  int p_ret = starpu_pthread_rwlock_trywrlock(rwlock);
335  if (STARPU_UNLIKELY(p_ret != 0 && p_ret != EBUSY))
336  {
337  fprintf(stderr,
338  "%s:%d starpu_pthread_rwlock_trywrlock: %s\n",
339  file, line, strerror(p_ret));
340  STARPU_ABORT();
341  }
342  return p_ret;
343 }
344 
345 #define STARPU_PTHREAD_RWLOCK_UNLOCK(rwlock) \
346  do { \
347  int p_ret = starpu_pthread_rwlock_unlock(rwlock); \
348  if (STARPU_UNLIKELY(p_ret)) \
349  { \
350  fprintf(stderr, \
351  "%s:%d starpu_pthread_rwlock_unlock: %s\n", \
352  __FILE__, __LINE__, strerror(p_ret)); \
353  STARPU_ABORT(); \
354  } \
355  } \
356  while (0)
357 
358 #define STARPU_PTHREAD_RWLOCK_DESTROY(rwlock) \
359  do { \
360  int p_ret = starpu_pthread_rwlock_destroy(rwlock); \
361  if (STARPU_UNLIKELY(p_ret)) \
362  { \
363  fprintf(stderr, \
364  "%s:%d starpu_pthread_rwlock_destroy: %s\n", \
365  __FILE__, __LINE__, strerror(p_ret)); \
366  STARPU_ABORT(); \
367  } \
368  } \
369  while (0)
370 
371 /*
372  * Encapsulation of the starpu_pthread_cond_* functions.
373  */
374 #define _STARPU_PTHREAD_COND_INIT(cond, attr) \
375  do { \
376  int p_ret = starpu_pthread_cond_init((cond), (attr)); \
377  if (STARPU_UNLIKELY(p_ret)) \
378  { \
379  fprintf(stderr, \
380  "%s:%d starpu_pthread_cond_init: %s\n", \
381  __FILE__, __LINE__, strerror(p_ret)); \
382  STARPU_ABORT(); \
383  } \
384  } \
385  while (0)
386 
387 #ifdef STARPU_PTHREAD_COND_INITIALIZER_ZERO
388 #define STARPU_PTHREAD_COND_INIT(cond, attr) \
389  do { \
390  if (!attr) \
391  memset(cond, 0, sizeof(*cond)); \
392  else \
393  _STARPU_PTHREAD_COND_INIT(cond, attr); \
394  } \
395  while (0)
396 #define STARPU_PTHREAD_COND_INIT0(cond, attr) \
397  do { \
398  if (attr) \
399  _STARPU_PTHREAD_COND_INIT(cond, attr); \
400  } \
401  while (0)
402 #else
403 #define STARPU_PTHREAD_COND_INIT(cond, attr) _STARPU_PTHREAD_COND_INIT(cond, attr)
404 #define STARPU_PTHREAD_COND_INIT0(cond, attr) _STARPU_PTHREAD_COND_INIT(cond, attr)
405 #endif
406 
407 #define STARPU_PTHREAD_COND_DESTROY(cond) \
408  do { \
409  int p_ret = starpu_pthread_cond_destroy(cond); \
410  if (STARPU_UNLIKELY(p_ret)) \
411  { \
412  fprintf(stderr, \
413  "%s:%d starpu_pthread_cond_destroy: %s\n", \
414  __FILE__, __LINE__, strerror(p_ret)); \
415  STARPU_ABORT(); \
416  } \
417  } \
418  while (0)
419 
420 #define STARPU_PTHREAD_COND_SIGNAL(cond) \
421  do { \
422  int p_ret = starpu_pthread_cond_signal(cond); \
423  if (STARPU_UNLIKELY(p_ret)) \
424  { \
425  fprintf(stderr, \
426  "%s:%d starpu_pthread_cond_signal: %s\n", \
427  __FILE__, __LINE__, strerror(p_ret)); \
428  STARPU_ABORT(); \
429  } \
430  } \
431  while (0)
432 
433 #define STARPU_PTHREAD_COND_BROADCAST(cond) \
434  do { \
435  int p_ret = starpu_pthread_cond_broadcast(cond); \
436  if (STARPU_UNLIKELY(p_ret)) \
437  { \
438  fprintf(stderr, \
439  "%s:%d starpu_pthread_cond_broadcast: %s\n", \
440  __FILE__, __LINE__, strerror(p_ret)); \
441  STARPU_ABORT(); \
442  } \
443  } \
444  while (0)
445 
446 #define STARPU_PTHREAD_COND_WAIT(cond, mutex) \
447  do { \
448  int p_ret = starpu_pthread_cond_wait((cond), (mutex)); \
449  if (STARPU_UNLIKELY(p_ret)) \
450  { \
451  fprintf(stderr, \
452  "%s:%d starpu_pthread_cond_wait: %s\n", \
453  __FILE__, __LINE__, strerror(p_ret)); \
454  STARPU_ABORT(); \
455  } \
456  } \
457  while (0)
458 
459 /* pthread_cond_timedwait not yet available on windows, but we don't run simgrid there anyway */
460 #ifdef STARPU_SIMGRID
461 #define STARPU_PTHREAD_COND_TIMEDWAIT(cond, mutex, abstime) \
462  _starpu_pthread_cond_timedwait(cond, mutex, abstime, __FILE__, __LINE__)
463 static STARPU_INLINE int _starpu_pthread_cond_timedwait(starpu_pthread_cond_t *cond, starpu_pthread_mutex_t *mutex, const struct timespec *abstime, char *file, int line)
464 {
465  int p_ret = starpu_pthread_cond_timedwait(cond, mutex, abstime);
466  if (STARPU_UNLIKELY(p_ret != 0 && p_ret != ETIMEDOUT))
467  {
468  fprintf(stderr,
469  "%s:%d starpu_pthread_cond_timedwait: %s\n",
470  file, line, strerror(p_ret));
471  STARPU_ABORT();
472  }
473  return p_ret;
474 }
475 #endif
476 
477 /*
478  * Encapsulation of the starpu_pthread_barrier_* functions.
479  */
480 
481 #define STARPU_PTHREAD_BARRIER_INIT(barrier, attr, count) \
482  do { \
483  int p_ret = starpu_pthread_barrier_init((barrier), (attr), (count)); \
484  if (STARPU_UNLIKELY(p_ret)) \
485  { \
486  fprintf(stderr, \
487  "%s:%d starpu_pthread_barrier_init: %s\n", \
488  __FILE__, __LINE__, strerror(p_ret)); \
489  STARPU_ABORT(); \
490  } \
491  } \
492  while (0)
493 
494 #define STARPU_PTHREAD_BARRIER_DESTROY(barrier) \
495  do { \
496  int p_ret = starpu_pthread_barrier_destroy((barrier)); \
497  if (STARPU_UNLIKELY(p_ret)) \
498  { \
499  fprintf(stderr, \
500  "%s:%d starpu_pthread_barrier_destroy: %s\n", \
501  __FILE__, __LINE__, strerror(p_ret)); \
502  STARPU_ABORT(); \
503  } \
504  } \
505  while (0)
506 
507 #define STARPU_PTHREAD_BARRIER_WAIT(barrier) \
508  do { \
509  int p_ret = starpu_pthread_barrier_wait((barrier)); \
510  if (STARPU_UNLIKELY(!((p_ret == 0) || (p_ret == STARPU_PTHREAD_BARRIER_SERIAL_THREAD)))) \
511  { \
512  fprintf(stderr, \
513  "%s:%d starpu_pthread_barrier_wait: %s\n", \
514  __FILE__, __LINE__, strerror(p_ret)); \
515  STARPU_ABORT(); \
516  } \
517  } \
518  while (0)
519 #endif /* _MSC_VER */
520 
521 #endif /* __STARPU_THREAD_UTIL_H__ */
int starpu_pthread_rwlock_tryrdlock(starpu_pthread_rwlock_t *rwlock)
int starpu_pthread_rwlock_trywrlock(starpu_pthread_rwlock_t *rwlock)
int starpu_pthread_mutex_trylock(starpu_pthread_mutex_t *mutex)
int starpu_pthread_cond_timedwait(starpu_pthread_cond_t *cond, starpu_pthread_mutex_t *mutex, const struct timespec *abstime)
#define STARPU_UNLIKELY(expr)
Definition: starpu_util.h:65
#define STARPU_ABORT()
Definition: starpu_util.h:342