Mercurial > hg > CbC > CbC_gcc
comparison libgomp/config/linux/bar.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, 2008, 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. |
36 /* Make sure total/generation is in a mostly read cacheline, while | 37 /* Make sure total/generation is in a mostly read cacheline, while |
37 awaited in a separate cacheline. */ | 38 awaited in a separate cacheline. */ |
38 unsigned total __attribute__((aligned (64))); | 39 unsigned total __attribute__((aligned (64))); |
39 unsigned generation; | 40 unsigned generation; |
40 unsigned awaited __attribute__((aligned (64))); | 41 unsigned awaited __attribute__((aligned (64))); |
42 unsigned awaited_final; | |
41 } gomp_barrier_t; | 43 } gomp_barrier_t; |
44 | |
42 typedef unsigned int gomp_barrier_state_t; | 45 typedef unsigned int gomp_barrier_state_t; |
46 | |
47 /* The generation field contains a counter in the high bits, with a few | |
48 low bits dedicated to flags. Note that TASK_PENDING and WAS_LAST can | |
49 share space because WAS_LAST is never stored back to generation. */ | |
50 #define BAR_TASK_PENDING 1 | |
51 #define BAR_WAS_LAST 1 | |
52 #define BAR_WAITING_FOR_TASK 2 | |
53 #define BAR_CANCELLED 4 | |
54 #define BAR_INCR 8 | |
43 | 55 |
44 static inline void gomp_barrier_init (gomp_barrier_t *bar, unsigned count) | 56 static inline void gomp_barrier_init (gomp_barrier_t *bar, unsigned count) |
45 { | 57 { |
46 bar->total = count; | 58 bar->total = count; |
47 bar->awaited = count; | 59 bar->awaited = count; |
60 bar->awaited_final = count; | |
48 bar->generation = 0; | 61 bar->generation = 0; |
49 } | 62 } |
50 | 63 |
51 static inline void gomp_barrier_reinit (gomp_barrier_t *bar, unsigned count) | 64 static inline void gomp_barrier_reinit (gomp_barrier_t *bar, unsigned count) |
52 { | 65 { |
53 __sync_fetch_and_add (&bar->awaited, count - bar->total); | 66 __atomic_add_fetch (&bar->awaited, count - bar->total, MEMMODEL_ACQ_REL); |
54 bar->total = count; | 67 bar->total = count; |
55 } | 68 } |
56 | 69 |
57 static inline void gomp_barrier_destroy (gomp_barrier_t *bar) | 70 static inline void gomp_barrier_destroy (gomp_barrier_t *bar) |
58 { | 71 { |
60 | 73 |
61 extern void gomp_barrier_wait (gomp_barrier_t *); | 74 extern void gomp_barrier_wait (gomp_barrier_t *); |
62 extern void gomp_barrier_wait_last (gomp_barrier_t *); | 75 extern void gomp_barrier_wait_last (gomp_barrier_t *); |
63 extern void gomp_barrier_wait_end (gomp_barrier_t *, gomp_barrier_state_t); | 76 extern void gomp_barrier_wait_end (gomp_barrier_t *, gomp_barrier_state_t); |
64 extern void gomp_team_barrier_wait (gomp_barrier_t *); | 77 extern void gomp_team_barrier_wait (gomp_barrier_t *); |
78 extern void gomp_team_barrier_wait_final (gomp_barrier_t *); | |
65 extern void gomp_team_barrier_wait_end (gomp_barrier_t *, | 79 extern void gomp_team_barrier_wait_end (gomp_barrier_t *, |
66 gomp_barrier_state_t); | 80 gomp_barrier_state_t); |
81 extern bool gomp_team_barrier_wait_cancel (gomp_barrier_t *); | |
82 extern bool gomp_team_barrier_wait_cancel_end (gomp_barrier_t *, | |
83 gomp_barrier_state_t); | |
67 extern void gomp_team_barrier_wake (gomp_barrier_t *, int); | 84 extern void gomp_team_barrier_wake (gomp_barrier_t *, int); |
85 struct gomp_team; | |
86 extern void gomp_team_barrier_cancel (struct gomp_team *); | |
68 | 87 |
69 static inline gomp_barrier_state_t | 88 static inline gomp_barrier_state_t |
70 gomp_barrier_wait_start (gomp_barrier_t *bar) | 89 gomp_barrier_wait_start (gomp_barrier_t *bar) |
71 { | 90 { |
72 unsigned int ret = bar->generation & ~3; | 91 unsigned int ret = __atomic_load_n (&bar->generation, MEMMODEL_ACQUIRE); |
73 /* Do we need any barrier here or is __sync_add_and_fetch acting | 92 ret &= -BAR_INCR | BAR_CANCELLED; |
74 as the needed LoadLoad barrier already? */ | 93 /* A memory barrier is needed before exiting from the various forms |
75 ret += __sync_add_and_fetch (&bar->awaited, -1) == 0; | 94 of gomp_barrier_wait, to satisfy OpenMP API version 3.1 section |
95 2.8.6 flush Construct, which says there is an implicit flush during | |
96 a barrier region. This is a convenient place to add the barrier, | |
97 so we use MEMMODEL_ACQ_REL here rather than MEMMODEL_ACQUIRE. */ | |
98 if (__atomic_add_fetch (&bar->awaited, -1, MEMMODEL_ACQ_REL) == 0) | |
99 ret |= BAR_WAS_LAST; | |
100 return ret; | |
101 } | |
102 | |
103 static inline gomp_barrier_state_t | |
104 gomp_barrier_wait_cancel_start (gomp_barrier_t *bar) | |
105 { | |
106 return gomp_barrier_wait_start (bar); | |
107 } | |
108 | |
109 /* This is like gomp_barrier_wait_start, except it decrements | |
110 bar->awaited_final rather than bar->awaited and should be used | |
111 for the gomp_team_end barrier only. */ | |
112 static inline gomp_barrier_state_t | |
113 gomp_barrier_wait_final_start (gomp_barrier_t *bar) | |
114 { | |
115 unsigned int ret = __atomic_load_n (&bar->generation, MEMMODEL_ACQUIRE); | |
116 ret &= -BAR_INCR | BAR_CANCELLED; | |
117 /* See above gomp_barrier_wait_start comment. */ | |
118 if (__atomic_add_fetch (&bar->awaited_final, -1, MEMMODEL_ACQ_REL) == 0) | |
119 ret |= BAR_WAS_LAST; | |
76 return ret; | 120 return ret; |
77 } | 121 } |
78 | 122 |
79 static inline bool | 123 static inline bool |
80 gomp_barrier_last_thread (gomp_barrier_state_t state) | 124 gomp_barrier_last_thread (gomp_barrier_state_t state) |
81 { | 125 { |
82 return state & 1; | 126 return state & BAR_WAS_LAST; |
83 } | 127 } |
84 | 128 |
85 /* All the inlines below must be called with team->task_lock | 129 /* All the inlines below must be called with team->task_lock |
86 held. */ | 130 held. */ |
87 | 131 |
88 static inline void | 132 static inline void |
89 gomp_team_barrier_set_task_pending (gomp_barrier_t *bar) | 133 gomp_team_barrier_set_task_pending (gomp_barrier_t *bar) |
90 { | 134 { |
91 bar->generation |= 1; | 135 bar->generation |= BAR_TASK_PENDING; |
92 } | 136 } |
93 | 137 |
94 static inline void | 138 static inline void |
95 gomp_team_barrier_clear_task_pending (gomp_barrier_t *bar) | 139 gomp_team_barrier_clear_task_pending (gomp_barrier_t *bar) |
96 { | 140 { |
97 bar->generation &= ~1; | 141 bar->generation &= ~BAR_TASK_PENDING; |
98 } | 142 } |
99 | 143 |
100 static inline void | 144 static inline void |
101 gomp_team_barrier_set_waiting_for_tasks (gomp_barrier_t *bar) | 145 gomp_team_barrier_set_waiting_for_tasks (gomp_barrier_t *bar) |
102 { | 146 { |
103 bar->generation |= 2; | 147 bar->generation |= BAR_WAITING_FOR_TASK; |
104 } | 148 } |
105 | 149 |
106 static inline bool | 150 static inline bool |
107 gomp_team_barrier_waiting_for_tasks (gomp_barrier_t *bar) | 151 gomp_team_barrier_waiting_for_tasks (gomp_barrier_t *bar) |
108 { | 152 { |
109 return (bar->generation & 2) != 0; | 153 return (bar->generation & BAR_WAITING_FOR_TASK) != 0; |
154 } | |
155 | |
156 static inline bool | |
157 gomp_team_barrier_cancelled (gomp_barrier_t *bar) | |
158 { | |
159 return __builtin_expect ((bar->generation & BAR_CANCELLED) != 0, 0); | |
110 } | 160 } |
111 | 161 |
112 static inline void | 162 static inline void |
113 gomp_team_barrier_done (gomp_barrier_t *bar, gomp_barrier_state_t state) | 163 gomp_team_barrier_done (gomp_barrier_t *bar, gomp_barrier_state_t state) |
114 { | 164 { |
115 bar->generation = (state & ~3) + 4; | 165 bar->generation = (state & -BAR_INCR) + BAR_INCR; |
116 } | 166 } |
117 | 167 |
118 #endif /* GOMP_BARRIER_H */ | 168 #endif /* GOMP_BARRIER_H */ |