Mercurial > hg > CbC > CbC_gcc
annotate libgomp/sections.c @ 63:b7f97abdc517 gcc-4.6-20100522
update gcc from gcc-4.5.0 to gcc-4.6
author | ryoma <e075725@ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 24 May 2010 12:47:05 +0900 |
parents | a06113de4d67 |
children | 04ced10e8804 |
rev | line source |
---|---|
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1 /* Copyright (C) 2005, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. |
0 | 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 file handles the SECTIONS construct. */ | |
26 | |
27 #include "libgomp.h" | |
28 | |
29 | |
30 /* Initialize the given work share construct from the given arguments. */ | |
31 | |
32 static inline void | |
33 gomp_sections_init (struct gomp_work_share *ws, unsigned count) | |
34 { | |
35 ws->sched = GFS_DYNAMIC; | |
36 ws->chunk_size = 1; | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
37 ws->end = count + 1L; |
0 | 38 ws->incr = 1; |
39 ws->next = 1; | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
40 #ifdef HAVE_SYNC_BUILTINS |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
41 /* Prepare things to make each iteration faster. */ |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
42 if (sizeof (long) > sizeof (unsigned)) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
43 ws->mode = 1; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
44 else |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
45 { |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
46 struct gomp_thread *thr = gomp_thread (); |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
47 struct gomp_team *team = thr->ts.team; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
48 long nthreads = team ? team->nthreads : 1; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
49 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
50 ws->mode = ((nthreads | ws->end) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
51 < 1UL << (sizeof (long) * __CHAR_BIT__ / 2 - 1)); |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
52 } |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
53 #else |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
54 ws->mode = 0; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
55 #endif |
0 | 56 } |
57 | |
58 /* This routine is called when first encountering a sections construct | |
59 that is not bound directly to a parallel construct. The first thread | |
60 that arrives will create the work-share construct; subsequent threads | |
61 will see the construct exists and allocate work from it. | |
62 | |
63 COUNT is the number of sections in this construct. | |
64 | |
65 Returns the 1-based section number for this thread to perform, or 0 if | |
66 all work was assigned to other threads prior to this thread's arrival. */ | |
67 | |
68 unsigned | |
69 GOMP_sections_start (unsigned count) | |
70 { | |
71 struct gomp_thread *thr = gomp_thread (); | |
72 long s, e, ret; | |
73 | |
74 if (gomp_work_share_start (false)) | |
75 { | |
76 gomp_sections_init (thr->ts.work_share, count); | |
77 gomp_work_share_init_done (); | |
78 } | |
79 | |
80 #ifdef HAVE_SYNC_BUILTINS | |
81 if (gomp_iter_dynamic_next (&s, &e)) | |
82 ret = s; | |
83 else | |
84 ret = 0; | |
85 #else | |
86 gomp_mutex_lock (&thr->ts.work_share->lock); | |
87 if (gomp_iter_dynamic_next_locked (&s, &e)) | |
88 ret = s; | |
89 else | |
90 ret = 0; | |
91 gomp_mutex_unlock (&thr->ts.work_share->lock); | |
92 #endif | |
93 | |
94 return ret; | |
95 } | |
96 | |
97 /* This routine is called when the thread completes processing of the | |
98 section currently assigned to it. If the work-share construct is | |
99 bound directly to a parallel construct, then the construct may have | |
100 been set up before the parallel. In which case, this may be the | |
101 first iteration for the thread. | |
102 | |
103 Returns the 1-based section number for this thread to perform, or 0 if | |
104 all work was assigned to other threads prior to this thread's arrival. */ | |
105 | |
106 unsigned | |
107 GOMP_sections_next (void) | |
108 { | |
109 long s, e, ret; | |
110 | |
111 #ifdef HAVE_SYNC_BUILTINS | |
112 if (gomp_iter_dynamic_next (&s, &e)) | |
113 ret = s; | |
114 else | |
115 ret = 0; | |
116 #else | |
117 struct gomp_thread *thr = gomp_thread (); | |
118 | |
119 gomp_mutex_lock (&thr->ts.work_share->lock); | |
120 if (gomp_iter_dynamic_next_locked (&s, &e)) | |
121 ret = s; | |
122 else | |
123 ret = 0; | |
124 gomp_mutex_unlock (&thr->ts.work_share->lock); | |
125 #endif | |
126 | |
127 return ret; | |
128 } | |
129 | |
130 /* This routine pre-initializes a work-share construct to avoid one | |
131 synchronization once we get into the loop. */ | |
132 | |
133 void | |
134 GOMP_parallel_sections_start (void (*fn) (void *), void *data, | |
135 unsigned num_threads, unsigned count) | |
136 { | |
137 struct gomp_team *team; | |
138 | |
139 num_threads = gomp_resolve_num_threads (num_threads, count); | |
140 team = gomp_new_team (num_threads); | |
141 gomp_sections_init (&team->work_shares[0], count); | |
142 gomp_team_start (fn, data, num_threads, team); | |
143 } | |
144 | |
145 /* The GOMP_section_end* routines are called after the thread is told | |
146 that all sections are complete. This first version synchronizes | |
147 all threads; the nowait version does not. */ | |
148 | |
149 void | |
150 GOMP_sections_end (void) | |
151 { | |
152 gomp_work_share_end (); | |
153 } | |
154 | |
155 void | |
156 GOMP_sections_end_nowait (void) | |
157 { | |
158 gomp_work_share_end_nowait (); | |
159 } |