Mercurial > hg > CbC > CbC_gcc
comparison libgomp/config/linux/sem.h @ 111:04ced10e8804
gcc 7
author | kono |
---|---|
date | Fri, 27 Oct 2017 22:46:09 +0900 |
parents | a06113de4d67 |
children | 84e7813d76e9 |
comparison
equal
deleted
inserted
replaced
68:561a7518be6b | 111:04ced10e8804 |
---|---|
1 /* Copyright (C) 2005, 2009 Free Software Foundation, Inc. | 1 /* Copyright (C) 2005-2017 Free Software Foundation, Inc. |
2 Contributed by Richard Henderson <rth@redhat.com>. | 2 Contributed by Richard Henderson <rth@redhat.com>. |
3 | 3 |
4 This file is part of the GNU OpenMP Library (libgomp). | 4 This file is part of the GNU Offloading and Multi Processing Library |
5 (libgomp). | |
5 | 6 |
6 Libgomp is free software; you can redistribute it and/or modify it | 7 Libgomp is free software; you can redistribute it and/or modify it |
7 under the terms of the GNU General Public License as published by | 8 under the terms of the GNU General Public License as published by |
8 the Free Software Foundation; either version 3, or (at your option) | 9 the Free Software Foundation; either version 3, or (at your option) |
9 any later version. | 10 any later version. |
22 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see | 23 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see |
23 <http://www.gnu.org/licenses/>. */ | 24 <http://www.gnu.org/licenses/>. */ |
24 | 25 |
25 /* This is a Linux specific implementation of a semaphore synchronization | 26 /* This is a Linux specific implementation of a semaphore synchronization |
26 mechanism for libgomp. This type is private to the library. This | 27 mechanism for libgomp. This type is private to the library. This |
27 implementation uses atomic instructions and the futex syscall. */ | 28 counting semaphore implementation uses atomic instructions and the |
29 futex syscall, and a single 32-bit int to store semaphore state. | |
30 The low 31 bits are the count, the top bit is a flag set when some | |
31 threads may be waiting. */ | |
28 | 32 |
29 #ifndef GOMP_SEM_H | 33 #ifndef GOMP_SEM_H |
30 #define GOMP_SEM_H 1 | 34 #define GOMP_SEM_H 1 |
31 | 35 |
36 #include <limits.h> /* For INT_MIN */ | |
37 | |
32 typedef int gomp_sem_t; | 38 typedef int gomp_sem_t; |
39 #define SEM_WAIT INT_MIN | |
40 #define SEM_INC 1 | |
33 | 41 |
34 static inline void gomp_sem_init (gomp_sem_t *sem, int value) | 42 extern void gomp_sem_wait_slow (gomp_sem_t *, int); |
43 extern void gomp_sem_post_slow (gomp_sem_t *); | |
44 | |
45 static inline void | |
46 gomp_sem_init (gomp_sem_t *sem, int value) | |
35 { | 47 { |
36 *sem = value; | 48 *sem = value * SEM_INC; |
37 } | 49 } |
38 | 50 |
39 extern void gomp_sem_wait_slow (gomp_sem_t *); | 51 static inline void |
40 static inline void gomp_sem_wait (gomp_sem_t *sem) | 52 gomp_sem_destroy (gomp_sem_t *sem) |
41 { | |
42 if (!__sync_bool_compare_and_swap (sem, 1, 0)) | |
43 gomp_sem_wait_slow (sem); | |
44 } | |
45 | |
46 extern void gomp_sem_post_slow (gomp_sem_t *); | |
47 static inline void gomp_sem_post (gomp_sem_t *sem) | |
48 { | |
49 if (!__sync_bool_compare_and_swap (sem, 0, 1)) | |
50 gomp_sem_post_slow (sem); | |
51 } | |
52 | |
53 static inline void gomp_sem_destroy (gomp_sem_t *sem) | |
54 { | 53 { |
55 } | 54 } |
56 | 55 |
56 static inline void | |
57 gomp_sem_wait (gomp_sem_t *sem) | |
58 { | |
59 int count = *sem; | |
60 | |
61 while ((count & ~SEM_WAIT) != 0) | |
62 if (__atomic_compare_exchange_n (sem, &count, count - SEM_INC, true, | |
63 MEMMODEL_ACQUIRE, MEMMODEL_RELAXED)) | |
64 return; | |
65 gomp_sem_wait_slow (sem, count); | |
66 } | |
67 | |
68 static inline void | |
69 gomp_sem_post (gomp_sem_t *sem) | |
70 { | |
71 int count = *sem; | |
72 | |
73 /* Clear SEM_WAIT here so that if there are no more waiting threads | |
74 we transition back to the uncontended state that does not make | |
75 futex syscalls. If there are waiting threads then when one is | |
76 awoken it will set SEM_WAIT again, so other waiting threads are | |
77 woken on a future gomp_sem_post. Furthermore, the awoken thread | |
78 will wake other threads in case gomp_sem_post was called again | |
79 before it had time to set SEM_WAIT. */ | |
80 while (!__atomic_compare_exchange_n (sem, &count, | |
81 (count + SEM_INC) & ~SEM_WAIT, true, | |
82 MEMMODEL_RELEASE, MEMMODEL_RELAXED)) | |
83 continue; | |
84 | |
85 if (__builtin_expect (count & SEM_WAIT, 0)) | |
86 gomp_sem_post_slow (sem); | |
87 } | |
57 #endif /* GOMP_SEM_H */ | 88 #endif /* GOMP_SEM_H */ |