Mercurial > hg > CbC > CbC_gcc
comparison libgomp/config/linux/bar.c @ 0:a06113de4d67
first commit
author | kent <kent@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 17 Jul 2009 14:47:48 +0900 |
parents | |
children | 04ced10e8804 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:a06113de4d67 |
---|---|
1 /* Copyright (C) 2005, 2008, 2009 Free Software Foundation, Inc. | |
2 Contributed by Richard Henderson <rth@redhat.com>. | |
3 | |
4 This file is part of the GNU OpenMP Library (libgomp). | |
5 | |
6 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 the Free Software Foundation; either version 3, or (at your option) | |
9 any later version. | |
10 | |
11 Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY | |
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | |
13 FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
14 more details. | |
15 | |
16 Under Section 7 of GPL version 3, you are granted additional | |
17 permissions described in the GCC Runtime Library Exception, version | |
18 3.1, as published by the Free Software Foundation. | |
19 | |
20 You should have received a copy of the GNU General Public License and | |
21 a copy of the GCC Runtime Library Exception along with this program; | |
22 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see | |
23 <http://www.gnu.org/licenses/>. */ | |
24 | |
25 /* This is a Linux specific implementation of a barrier synchronization | |
26 mechanism for libgomp. This type is private to the library. This | |
27 implementation uses atomic instructions and the futex syscall. */ | |
28 | |
29 #include <limits.h> | |
30 #include "wait.h" | |
31 | |
32 | |
33 void | |
34 gomp_barrier_wait_end (gomp_barrier_t *bar, gomp_barrier_state_t state) | |
35 { | |
36 if (__builtin_expect ((state & 1) != 0, 0)) | |
37 { | |
38 /* Next time we'll be awaiting TOTAL threads again. */ | |
39 bar->awaited = bar->total; | |
40 atomic_write_barrier (); | |
41 bar->generation += 4; | |
42 futex_wake ((int *) &bar->generation, INT_MAX); | |
43 } | |
44 else | |
45 { | |
46 unsigned int generation = state; | |
47 | |
48 do | |
49 do_wait ((int *) &bar->generation, generation); | |
50 while (bar->generation == generation); | |
51 } | |
52 } | |
53 | |
54 void | |
55 gomp_barrier_wait (gomp_barrier_t *bar) | |
56 { | |
57 gomp_barrier_wait_end (bar, gomp_barrier_wait_start (bar)); | |
58 } | |
59 | |
60 /* Like gomp_barrier_wait, except that if the encountering thread | |
61 is not the last one to hit the barrier, it returns immediately. | |
62 The intended usage is that a thread which intends to gomp_barrier_destroy | |
63 this barrier calls gomp_barrier_wait, while all other threads | |
64 call gomp_barrier_wait_last. When gomp_barrier_wait returns, | |
65 the barrier can be safely destroyed. */ | |
66 | |
67 void | |
68 gomp_barrier_wait_last (gomp_barrier_t *bar) | |
69 { | |
70 gomp_barrier_state_t state = gomp_barrier_wait_start (bar); | |
71 if (state & 1) | |
72 gomp_barrier_wait_end (bar, state); | |
73 } | |
74 | |
75 void | |
76 gomp_team_barrier_wake (gomp_barrier_t *bar, int count) | |
77 { | |
78 futex_wake ((int *) &bar->generation, count == 0 ? INT_MAX : count); | |
79 } | |
80 | |
81 void | |
82 gomp_team_barrier_wait_end (gomp_barrier_t *bar, gomp_barrier_state_t state) | |
83 { | |
84 unsigned int generation; | |
85 | |
86 if (__builtin_expect ((state & 1) != 0, 0)) | |
87 { | |
88 /* Next time we'll be awaiting TOTAL threads again. */ | |
89 struct gomp_thread *thr = gomp_thread (); | |
90 struct gomp_team *team = thr->ts.team; | |
91 bar->awaited = bar->total; | |
92 atomic_write_barrier (); | |
93 if (__builtin_expect (team->task_count, 0)) | |
94 { | |
95 gomp_barrier_handle_tasks (state); | |
96 state &= ~1; | |
97 } | |
98 else | |
99 { | |
100 bar->generation = state + 3; | |
101 futex_wake ((int *) &bar->generation, INT_MAX); | |
102 return; | |
103 } | |
104 } | |
105 | |
106 generation = state; | |
107 do | |
108 { | |
109 do_wait ((int *) &bar->generation, generation); | |
110 if (__builtin_expect (bar->generation & 1, 0)) | |
111 gomp_barrier_handle_tasks (state); | |
112 if ((bar->generation & 2)) | |
113 generation |= 2; | |
114 } | |
115 while (bar->generation != state + 4); | |
116 } | |
117 | |
118 void | |
119 gomp_team_barrier_wait (gomp_barrier_t *bar) | |
120 { | |
121 gomp_team_barrier_wait_end (bar, gomp_barrier_wait_start (bar)); | |
122 } |