StarPU Handbook
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) do { \
32  int p_ret = starpu_pthread_create_on((name), (thread), (attr), (routine), (arg), (where)); \
33  if (STARPU_UNLIKELY(p_ret != 0)) { \
34  fprintf(stderr, \
35  "%s:%d starpu_pthread_create_on: %s\n", \
36  __FILE__, __LINE__, strerror(p_ret)); \
37  STARPU_ABORT(); \
38  } \
39 } while (0)
40 
41 #define STARPU_PTHREAD_CREATE(thread, attr, routine, arg) do { \
42  int p_ret = starpu_pthread_create((thread), (attr), (routine), (arg)); \
43  if (STARPU_UNLIKELY(p_ret != 0)) { \
44  fprintf(stderr, \
45  "%s:%d starpu_pthread_create: %s\n", \
46  __FILE__, __LINE__, strerror(p_ret)); \
47  STARPU_ABORT(); \
48  } \
49 } while (0)
50 
51 #define STARPU_PTHREAD_JOIN(thread, retval) do { \
52  int p_ret = starpu_pthread_join((thread), (retval)); \
53  if (STARPU_UNLIKELY(p_ret != 0)) { \
54  fprintf(stderr, \
55  "%s:%d starpu_pthread_join: %s\n", \
56  __FILE__, __LINE__, strerror(p_ret)); \
57  STARPU_ABORT(); \
58  } \
59 } while (0)
60 
61 /*
62  * Encapsulation of the starpu_pthread_mutex_* functions.
63  */
64 
65 #define STARPU_PTHREAD_MUTEX_INIT(mutex, attr) do { \
66  int p_ret = starpu_pthread_mutex_init((mutex), (attr)); \
67  if (STARPU_UNLIKELY(p_ret)) { \
68  fprintf(stderr, \
69  "%s:%d starpu_pthread_mutex_init: %s\n", \
70  __FILE__, __LINE__, strerror(p_ret)); \
71  STARPU_ABORT(); \
72  } \
73 } while (0)
74 
75 #define STARPU_PTHREAD_MUTEX_DESTROY(mutex) do { \
76  int p_ret = starpu_pthread_mutex_destroy(mutex); \
77  if (STARPU_UNLIKELY(p_ret)) { \
78  fprintf(stderr, \
79  "%s:%d starpu_pthread_mutex_destroy: %s\n", \
80  __FILE__, __LINE__, strerror(p_ret)); \
81  STARPU_ABORT(); \
82  } \
83 } while(0)
84 
85 #ifdef STARPU_DEBUG
86 #define _STARPU_CHECK_NOT_SCHED_MUTEX(mutex, file, line) \
87  starpu_pthread_mutex_check_sched((mutex), file, line)
88 #else
89 #define _STARPU_CHECK_NOT_SCHED_MUTEX(mutex, file, line)
90 #endif
91 
92 #define STARPU_PTHREAD_MUTEX_LOCK(mutex) do { \
93  int p_ret = starpu_pthread_mutex_lock(mutex); \
94  if (STARPU_UNLIKELY(p_ret)) { \
95  fprintf(stderr, \
96  "%s:%d starpu_pthread_mutex_lock: %s\n", \
97  __FILE__, __LINE__, strerror(p_ret)); \
98  STARPU_ABORT(); \
99  } \
100  _STARPU_CHECK_NOT_SCHED_MUTEX(mutex, __FILE__, __LINE__); \
101 } while (0)
102 
103 #define STARPU_PTHREAD_MUTEX_LOCK_SCHED(mutex) do { \
104  int p_ret = starpu_pthread_mutex_lock_sched(mutex); \
105  if (STARPU_UNLIKELY(p_ret)) { \
106  fprintf(stderr, \
107  "%s:%d starpu_pthread_mutex_lock_sched: %s\n", \
108  __FILE__, __LINE__, strerror(p_ret)); \
109  STARPU_ABORT(); \
110  } \
111 } while (0)
112 
113 #define STARPU_PTHREAD_MUTEX_TRYLOCK(mutex) \
114  _starpu_pthread_mutex_trylock(mutex, __FILE__, __LINE__)
115 static STARPU_INLINE
116 int _starpu_pthread_mutex_trylock(starpu_pthread_mutex_t *mutex, char *file, int line)
117 {
118  int p_ret = starpu_pthread_mutex_trylock(mutex);
119  if (STARPU_UNLIKELY(p_ret != 0 && p_ret != EBUSY)) {
120  fprintf(stderr,
121  "%s:%d starpu_pthread_mutex_trylock: %s\n",
122  file, line, strerror(p_ret));
123  STARPU_ABORT();
124  }
125  _STARPU_CHECK_NOT_SCHED_MUTEX(mutex, file, line);
126  return p_ret;
127 }
128 
129 #define STARPU_PTHREAD_MUTEX_TRYLOCK_SCHED(mutex) \
130  _starpu_pthread_mutex_trylock_sched(mutex, __FILE__, __LINE__)
131 static STARPU_INLINE
132 int _starpu_pthread_mutex_trylock_sched(starpu_pthread_mutex_t *mutex, char *file, int line)
133 {
134  int p_ret = starpu_pthread_mutex_trylock_sched(mutex);
135  if (STARPU_UNLIKELY(p_ret != 0 && p_ret != EBUSY)) {
136  fprintf(stderr,
137  "%s:%d starpu_pthread_mutex_trylock_sched: %s\n",
138  file, line, strerror(p_ret));
139  STARPU_ABORT();
140  }
141  return p_ret;
142 }
143 
144 #define STARPU_PTHREAD_MUTEX_UNLOCK(mutex) do { \
145  _STARPU_CHECK_NOT_SCHED_MUTEX(mutex, __FILE__, __LINE__); \
146  int p_ret = starpu_pthread_mutex_unlock(mutex); \
147  if (STARPU_UNLIKELY(p_ret)) { \
148  fprintf(stderr, \
149  "%s:%d starpu_pthread_mutex_unlock: %s\n", \
150  __FILE__, __LINE__, strerror(p_ret)); \
151  STARPU_ABORT(); \
152  } \
153 } while (0)
154 
155 #define STARPU_PTHREAD_MUTEX_UNLOCK_SCHED(mutex) do { \
156  int p_ret = starpu_pthread_mutex_unlock_sched(mutex); \
157  if (STARPU_UNLIKELY(p_ret)) { \
158  fprintf(stderr, \
159  "%s:%d starpu_pthread_mutex_unlock_sched: %s\n", \
160  __FILE__, __LINE__, strerror(p_ret)); \
161  STARPU_ABORT(); \
162  } \
163 } while (0)
164 
165 /*
166  * Encapsulation of the starpu_pthread_key_* functions.
167  */
168 #define STARPU_PTHREAD_KEY_CREATE(key, destr) do { \
169  int p_ret = starpu_pthread_key_create((key), (destr)); \
170  if (STARPU_UNLIKELY(p_ret != 0)) { \
171  fprintf(stderr, \
172  "%s:%d starpu_pthread_key_create: %s\n", \
173  __FILE__, __LINE__, strerror(p_ret)); \
174  } \
175 } while (0)
176 
177 #define STARPU_PTHREAD_KEY_DELETE(key) do { \
178  int p_ret = starpu_pthread_key_delete((key)); \
179  if (STARPU_UNLIKELY(p_ret != 0)) { \
180  fprintf(stderr, \
181  "%s:%d starpu_pthread_key_delete: %s\n", \
182  __FILE__, __LINE__, strerror(p_ret)); \
183  } \
184 } while (0)
185 
186 #define STARPU_PTHREAD_SETSPECIFIC(key, ptr) do { \
187  int p_ret = starpu_pthread_setspecific((key), (ptr)); \
188  if (STARPU_UNLIKELY(p_ret != 0)) { \
189  fprintf(stderr, \
190  "%s:%d starpu_pthread_setspecific: %s\n", \
191  __FILE__, __LINE__, strerror(p_ret)); \
192  }; \
193 } while (0)
194 
195 #define STARPU_PTHREAD_GETSPECIFIC(key) starpu_pthread_getspecific((key))
196 
197 /*
198  * Encapsulation of the starpu_pthread_rwlock_* functions.
199  */
200 #define STARPU_PTHREAD_RWLOCK_INIT(rwlock, attr) do { \
201  int p_ret = starpu_pthread_rwlock_init((rwlock), (attr)); \
202  if (STARPU_UNLIKELY(p_ret)) { \
203  fprintf(stderr, \
204  "%s:%d starpu_pthread_rwlock_init: %s\n", \
205  __FILE__, __LINE__, strerror(p_ret)); \
206  STARPU_ABORT(); \
207  } \
208 } while (0)
209 
210 #define STARPU_PTHREAD_RWLOCK_RDLOCK(rwlock) do { \
211  int p_ret = starpu_pthread_rwlock_rdlock(rwlock); \
212  if (STARPU_UNLIKELY(p_ret)) { \
213  fprintf(stderr, \
214  "%s:%d starpu_pthread_rwlock_rdlock: %s\n", \
215  __FILE__, __LINE__, strerror(p_ret)); \
216  STARPU_ABORT(); \
217  } \
218 } while (0)
219 
220 #define STARPU_PTHREAD_RWLOCK_TRYRDLOCK(rwlock) \
221  _starpu_pthread_rwlock_tryrdlock(rwlock, __FILE__, __LINE__)
222 static STARPU_INLINE
223 int _starpu_pthread_rwlock_tryrdlock(starpu_pthread_rwlock_t *rwlock, char *file, int line)
224 {
225  int p_ret = starpu_pthread_rwlock_tryrdlock(rwlock);
226  if (STARPU_UNLIKELY(p_ret != 0 && p_ret != EBUSY)) {
227  fprintf(stderr,
228  "%s:%d starpu_pthread_rwlock_tryrdlock: %s\n",
229  file, line, strerror(p_ret));
230  STARPU_ABORT();
231  }
232  return p_ret;
233 }
234 
235 #define STARPU_PTHREAD_RWLOCK_WRLOCK(rwlock) do { \
236  int p_ret = starpu_pthread_rwlock_wrlock(rwlock); \
237  if (STARPU_UNLIKELY(p_ret)) { \
238  fprintf(stderr, \
239  "%s:%d starpu_pthread_rwlock_wrlock: %s\n", \
240  __FILE__, __LINE__, strerror(p_ret)); \
241  STARPU_ABORT(); \
242  } \
243 } while (0)
244 
245 #define STARPU_PTHREAD_RWLOCK_TRYWRLOCK(rwlock) \
246  _starpu_pthread_rwlock_trywrlock(rwlock, __FILE__, __LINE__)
247 static STARPU_INLINE
248 int _starpu_pthread_rwlock_trywrlock(starpu_pthread_rwlock_t *rwlock, char *file, int line)
249 {
250  int p_ret = starpu_pthread_rwlock_trywrlock(rwlock);
251  if (STARPU_UNLIKELY(p_ret != 0 && p_ret != EBUSY)) {
252  fprintf(stderr,
253  "%s:%d starpu_pthread_rwlock_trywrlock: %s\n",
254  file, line, strerror(p_ret));
255  STARPU_ABORT();
256  }
257  return p_ret;
258 }
259 
260 #define STARPU_PTHREAD_RWLOCK_UNLOCK(rwlock) do { \
261  int p_ret = starpu_pthread_rwlock_unlock(rwlock); \
262  if (STARPU_UNLIKELY(p_ret)) { \
263  fprintf(stderr, \
264  "%s:%d starpu_pthread_rwlock_unlock: %s\n", \
265  __FILE__, __LINE__, strerror(p_ret)); \
266  STARPU_ABORT(); \
267  } \
268 } while (0)
269 
270 #define STARPU_PTHREAD_RWLOCK_DESTROY(rwlock) do { \
271  int p_ret = starpu_pthread_rwlock_destroy(rwlock); \
272  if (STARPU_UNLIKELY(p_ret)) { \
273  fprintf(stderr, \
274  "%s:%d starpu_pthread_rwlock_destroy: %s\n", \
275  __FILE__, __LINE__, strerror(p_ret)); \
276  STARPU_ABORT(); \
277  } \
278 } while (0)
279 
280 /*
281  * Encapsulation of the starpu_pthread_cond_* functions.
282  */
283 #define STARPU_PTHREAD_COND_INIT(cond, attr) do { \
284  int p_ret = starpu_pthread_cond_init((cond), (attr)); \
285  if (STARPU_UNLIKELY(p_ret)) { \
286  fprintf(stderr, \
287  "%s:%d starpu_pthread_cond_init: %s\n", \
288  __FILE__, __LINE__, strerror(p_ret)); \
289  STARPU_ABORT(); \
290  } \
291 } while (0)
292 
293 #define STARPU_PTHREAD_COND_DESTROY(cond) do { \
294  int p_ret = starpu_pthread_cond_destroy(cond); \
295  if (STARPU_UNLIKELY(p_ret)) { \
296  fprintf(stderr, \
297  "%s:%d starpu_pthread_cond_destroy: %s\n", \
298  __FILE__, __LINE__, strerror(p_ret)); \
299  STARPU_ABORT(); \
300  } \
301 } while (0)
302 
303 #define STARPU_PTHREAD_COND_SIGNAL(cond) do { \
304  int p_ret = starpu_pthread_cond_signal(cond); \
305  if (STARPU_UNLIKELY(p_ret)) { \
306  fprintf(stderr, \
307  "%s:%d starpu_pthread_cond_signal: %s\n", \
308  __FILE__, __LINE__, strerror(p_ret)); \
309  STARPU_ABORT(); \
310  } \
311 } while (0)
312 
313 #define STARPU_PTHREAD_COND_BROADCAST(cond) do { \
314  int p_ret = starpu_pthread_cond_broadcast(cond); \
315  if (STARPU_UNLIKELY(p_ret)) { \
316  fprintf(stderr, \
317  "%s:%d starpu_pthread_cond_broadcast: %s\n", \
318  __FILE__, __LINE__, strerror(p_ret)); \
319  STARPU_ABORT(); \
320  } \
321 } while (0)
322 
323 #define STARPU_PTHREAD_COND_WAIT(cond, mutex) do { \
324  int p_ret = starpu_pthread_cond_wait((cond), (mutex)); \
325  if (STARPU_UNLIKELY(p_ret)) { \
326  fprintf(stderr, \
327  "%s:%d starpu_pthread_cond_wait: %s\n", \
328  __FILE__, __LINE__, strerror(p_ret)); \
329  STARPU_ABORT(); \
330  } \
331 } while (0)
332 
333 /* pthread_cond_timedwait not yet available on windows, but we don't run simgrid there anyway */
334 #ifdef STARPU_SIMGRID
335 #define STARPU_PTHREAD_COND_TIMEDWAIT(cond, mutex, abstime) \
336  _starpu_pthread_cond_timedwait(cond, mutex, abstime, __FILE__, __LINE__)
337 static STARPU_INLINE
338 int _starpu_pthread_cond_timedwait(starpu_pthread_cond_t *cond, starpu_pthread_mutex_t *mutex, const struct timespec *abstime, char *file, int line)
339 {
340  int p_ret = starpu_pthread_cond_timedwait(cond, mutex, abstime);
341  if (STARPU_UNLIKELY(p_ret != 0 && p_ret != ETIMEDOUT)) {
342  fprintf(stderr,
343  "%s:%d starpu_pthread_cond_timedwait: %s\n",
344  file, line, strerror(p_ret));
345  STARPU_ABORT();
346  }
347  return p_ret;
348 }
349 #endif
350 
351 /*
352  * Encapsulation of the starpu_pthread_barrier_* functions.
353  */
354 
355 #define STARPU_PTHREAD_BARRIER_INIT(barrier, attr, count) do { \
356  int p_ret = starpu_pthread_barrier_init((barrier), (attr), (count)); \
357  if (STARPU_UNLIKELY(p_ret)) { \
358  fprintf(stderr, \
359  "%s:%d starpu_pthread_barrier_init: %s\n", \
360  __FILE__, __LINE__, strerror(p_ret)); \
361  STARPU_ABORT(); \
362  } \
363 } while (0)
364 
365 #define STARPU_PTHREAD_BARRIER_DESTROY(barrier) do { \
366  int p_ret = starpu_pthread_barrier_destroy((barrier)); \
367  if (STARPU_UNLIKELY(p_ret)) { \
368  fprintf(stderr, \
369  "%s:%d starpu_pthread_barrier_destroy: %s\n", \
370  __FILE__, __LINE__, strerror(p_ret)); \
371  STARPU_ABORT(); \
372  } \
373 } while (0)
374 
375 #define STARPU_PTHREAD_BARRIER_WAIT(barrier) do { \
376  int p_ret = starpu_pthread_barrier_wait((barrier)); \
377  if (STARPU_UNLIKELY(!((p_ret == 0) || (p_ret == STARPU_PTHREAD_BARRIER_SERIAL_THREAD)))) { \
378  fprintf(stderr, \
379  "%s:%d starpu_pthread_barrier_wait: %s\n", \
380  __FILE__, __LINE__, strerror(p_ret)); \
381  STARPU_ABORT(); \
382  } \
383 } while (0)
384 #endif /* _MSC_VER */
385 
386 #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:66
#define STARPU_ABORT()
Definition: starpu_util.h:246