annotate libgomp/team.c @ 111:04ced10e8804

gcc 7
author kono
date Fri, 27 Oct 2017 22:46:09 +0900
parents 58ad6c70ea60
children 84e7813d76e9
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents: 19
diff changeset
1 /* Copyright (C) 2005-2017 Free Software Foundation, Inc.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2 Contributed by Richard Henderson <rth@redhat.com>.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3
111
kono
parents: 19
diff changeset
4 This file is part of the GNU Offloading and Multi Processing Library
kono
parents: 19
diff changeset
5 (libgomp).
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
6
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
7 Libgomp is free software; you can redistribute it and/or modify it
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
8 under the terms of the GNU General Public License as published by
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
9 the Free Software Foundation; either version 3, or (at your option)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
10 any later version.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
11
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
12 Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
14 FOR A PARTICULAR PURPOSE. See the GNU General Public License for
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
15 more details.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
16
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
17 Under Section 7 of GPL version 3, you are granted additional
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
18 permissions described in the GCC Runtime Library Exception, version
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
19 3.1, as published by the Free Software Foundation.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
20
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
21 You should have received a copy of the GNU General Public License and
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
22 a copy of the GCC Runtime Library Exception along with this program;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
23 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
24 <http://www.gnu.org/licenses/>. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
25
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
26 /* This file handles the maintainence of threads in response to team
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
27 creation and termination. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
28
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
29 #include "libgomp.h"
111
kono
parents: 19
diff changeset
30 #include "pool.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
31 #include <stdlib.h>
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
32 #include <string.h>
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
33
111
kono
parents: 19
diff changeset
34 #ifdef LIBGOMP_USE_PTHREADS
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
35 /* This attribute contains PTHREAD_CREATE_DETACHED. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
36 pthread_attr_t gomp_thread_attr;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
37
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
38 /* This key is for the thread destructor. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
39 pthread_key_t gomp_thread_destructor;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
40
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
41
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
42 /* This is the libgomp per-thread data structure. */
111
kono
parents: 19
diff changeset
43 #if defined HAVE_TLS || defined USE_EMUTLS
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
44 __thread struct gomp_thread gomp_tls_data;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
45 #else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
46 pthread_key_t gomp_tls_key;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
47 #endif
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
48
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
49
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
50 /* This structure is used to communicate across pthread_create. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
51
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
52 struct gomp_thread_start_data
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
53 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
54 void (*fn) (void *);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
55 void *fn_data;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
56 struct gomp_team_state ts;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
57 struct gomp_task *task;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
58 struct gomp_thread_pool *thread_pool;
111
kono
parents: 19
diff changeset
59 unsigned int place;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
60 bool nested;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
61 };
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
62
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
63
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
64 /* This function is a pthread_create entry point. This contains the idle
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
65 loop in which a thread waits to be called up to become part of a team. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
66
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
67 static void *
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
68 gomp_thread_start (void *xdata)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
69 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
70 struct gomp_thread_start_data *data = xdata;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
71 struct gomp_thread *thr;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
72 struct gomp_thread_pool *pool;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
73 void (*local_fn) (void *);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
74 void *local_data;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
75
111
kono
parents: 19
diff changeset
76 #if defined HAVE_TLS || defined USE_EMUTLS
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
77 thr = &gomp_tls_data;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
78 #else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
79 struct gomp_thread local_thr;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
80 thr = &local_thr;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
81 pthread_setspecific (gomp_tls_key, thr);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
82 #endif
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
83 gomp_sem_init (&thr->release, 0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
84
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
85 /* Extract what we need from data. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
86 local_fn = data->fn;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
87 local_data = data->fn_data;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
88 thr->thread_pool = data->thread_pool;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
89 thr->ts = data->ts;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
90 thr->task = data->task;
111
kono
parents: 19
diff changeset
91 thr->place = data->place;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
92
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
93 thr->ts.team->ordered_release[thr->ts.team_id] = &thr->release;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
94
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
95 /* Make thread pool local. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
96 pool = thr->thread_pool;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
97
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
98 if (data->nested)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
99 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
100 struct gomp_team *team = thr->ts.team;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
101 struct gomp_task *task = thr->task;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
102
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
103 gomp_barrier_wait (&team->barrier);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
104
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
105 local_fn (local_data);
111
kono
parents: 19
diff changeset
106 gomp_team_barrier_wait_final (&team->barrier);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
107 gomp_finish_task (task);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
108 gomp_barrier_wait_last (&team->barrier);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
109 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
110 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
111 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
112 pool->threads[thr->ts.team_id] = thr;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
113
111
kono
parents: 19
diff changeset
114 gomp_simple_barrier_wait (&pool->threads_dock);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
115 do
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
116 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
117 struct gomp_team *team = thr->ts.team;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
118 struct gomp_task *task = thr->task;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
119
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
120 local_fn (local_data);
111
kono
parents: 19
diff changeset
121 gomp_team_barrier_wait_final (&team->barrier);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
122 gomp_finish_task (task);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
123
111
kono
parents: 19
diff changeset
124 gomp_simple_barrier_wait (&pool->threads_dock);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
125
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
126 local_fn = thr->fn;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
127 local_data = thr->data;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
128 thr->fn = NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
129 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
130 while (local_fn);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
131 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
132
19
58ad6c70ea60 update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents: 0
diff changeset
133 gomp_sem_destroy (&thr->release);
111
kono
parents: 19
diff changeset
134 thr->thread_pool = NULL;
kono
parents: 19
diff changeset
135 thr->task = NULL;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
136 return NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
137 }
111
kono
parents: 19
diff changeset
138 #endif
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
139
111
kono
parents: 19
diff changeset
140 static inline struct gomp_team *
kono
parents: 19
diff changeset
141 get_last_team (unsigned nthreads)
kono
parents: 19
diff changeset
142 {
kono
parents: 19
diff changeset
143 struct gomp_thread *thr = gomp_thread ();
kono
parents: 19
diff changeset
144 if (thr->ts.team == NULL)
kono
parents: 19
diff changeset
145 {
kono
parents: 19
diff changeset
146 struct gomp_thread_pool *pool = gomp_get_thread_pool (thr, nthreads);
kono
parents: 19
diff changeset
147 struct gomp_team *last_team = pool->last_team;
kono
parents: 19
diff changeset
148 if (last_team != NULL && last_team->nthreads == nthreads)
kono
parents: 19
diff changeset
149 {
kono
parents: 19
diff changeset
150 pool->last_team = NULL;
kono
parents: 19
diff changeset
151 return last_team;
kono
parents: 19
diff changeset
152 }
kono
parents: 19
diff changeset
153 }
kono
parents: 19
diff changeset
154 return NULL;
kono
parents: 19
diff changeset
155 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
156
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
157 /* Create a new team data structure. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
158
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
159 struct gomp_team *
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
160 gomp_new_team (unsigned nthreads)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
161 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
162 struct gomp_team *team;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
163 int i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
164
111
kono
parents: 19
diff changeset
165 team = get_last_team (nthreads);
kono
parents: 19
diff changeset
166 if (team == NULL)
kono
parents: 19
diff changeset
167 {
kono
parents: 19
diff changeset
168 size_t extra = sizeof (team->ordered_release[0])
kono
parents: 19
diff changeset
169 + sizeof (team->implicit_task[0]);
kono
parents: 19
diff changeset
170 team = gomp_malloc (sizeof (*team) + nthreads * extra);
kono
parents: 19
diff changeset
171
kono
parents: 19
diff changeset
172 #ifndef HAVE_SYNC_BUILTINS
kono
parents: 19
diff changeset
173 gomp_mutex_init (&team->work_share_list_free_lock);
kono
parents: 19
diff changeset
174 #endif
kono
parents: 19
diff changeset
175 gomp_barrier_init (&team->barrier, nthreads);
kono
parents: 19
diff changeset
176 gomp_mutex_init (&team->task_lock);
kono
parents: 19
diff changeset
177
kono
parents: 19
diff changeset
178 team->nthreads = nthreads;
kono
parents: 19
diff changeset
179 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
180
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
181 team->work_share_chunk = 8;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
182 #ifdef HAVE_SYNC_BUILTINS
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
183 team->single_count = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
184 #endif
111
kono
parents: 19
diff changeset
185 team->work_shares_to_free = &team->work_shares[0];
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
186 gomp_init_work_share (&team->work_shares[0], false, nthreads);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
187 team->work_shares[0].next_alloc = NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
188 team->work_share_list_free = NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
189 team->work_share_list_alloc = &team->work_shares[1];
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
190 for (i = 1; i < 7; i++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
191 team->work_shares[i].next_free = &team->work_shares[i + 1];
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
192 team->work_shares[i].next_free = NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
193
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
194 gomp_sem_init (&team->master_release, 0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
195 team->ordered_release = (void *) &team->implicit_task[nthreads];
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
196 team->ordered_release[0] = &team->master_release;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
197
111
kono
parents: 19
diff changeset
198 priority_queue_init (&team->task_queue);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
199 team->task_count = 0;
111
kono
parents: 19
diff changeset
200 team->task_queued_count = 0;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
201 team->task_running_count = 0;
111
kono
parents: 19
diff changeset
202 team->work_share_cancelled = 0;
kono
parents: 19
diff changeset
203 team->team_cancelled = 0;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
204
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
205 return team;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
206 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
207
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
208
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
209 /* Free a team data structure. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
210
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
211 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
212 free_team (struct gomp_team *team)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
213 {
111
kono
parents: 19
diff changeset
214 #ifndef HAVE_SYNC_BUILTINS
kono
parents: 19
diff changeset
215 gomp_mutex_destroy (&team->work_share_list_free_lock);
kono
parents: 19
diff changeset
216 #endif
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
217 gomp_barrier_destroy (&team->barrier);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
218 gomp_mutex_destroy (&team->task_lock);
111
kono
parents: 19
diff changeset
219 priority_queue_free (&team->task_queue);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
220 free (team);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
221 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
222
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
223 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
224 gomp_free_pool_helper (void *thread_pool)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
225 {
111
kono
parents: 19
diff changeset
226 struct gomp_thread *thr = gomp_thread ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
227 struct gomp_thread_pool *pool
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
228 = (struct gomp_thread_pool *) thread_pool;
111
kono
parents: 19
diff changeset
229 gomp_simple_barrier_wait_last (&pool->threads_dock);
kono
parents: 19
diff changeset
230 gomp_sem_destroy (&thr->release);
kono
parents: 19
diff changeset
231 thr->thread_pool = NULL;
kono
parents: 19
diff changeset
232 thr->task = NULL;
kono
parents: 19
diff changeset
233 #ifdef LIBGOMP_USE_PTHREADS
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
234 pthread_exit (NULL);
111
kono
parents: 19
diff changeset
235 #elif defined(__nvptx__)
kono
parents: 19
diff changeset
236 asm ("exit;");
kono
parents: 19
diff changeset
237 #else
kono
parents: 19
diff changeset
238 #error gomp_free_pool_helper must terminate the thread
kono
parents: 19
diff changeset
239 #endif
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
240 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
241
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
242 /* Free a thread pool and release its threads. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
243
111
kono
parents: 19
diff changeset
244 void
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
245 gomp_free_thread (void *arg __attribute__((unused)))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
246 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
247 struct gomp_thread *thr = gomp_thread ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
248 struct gomp_thread_pool *pool = thr->thread_pool;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
249 if (pool)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
250 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
251 if (pool->threads_used > 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
252 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
253 int i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
254 for (i = 1; i < pool->threads_used; i++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
255 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
256 struct gomp_thread *nthr = pool->threads[i];
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
257 nthr->fn = gomp_free_pool_helper;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
258 nthr->data = pool;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
259 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
260 /* This barrier undocks threads docked on pool->threads_dock. */
111
kono
parents: 19
diff changeset
261 gomp_simple_barrier_wait (&pool->threads_dock);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
262 /* And this waits till all threads have called gomp_barrier_wait_last
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
263 in gomp_free_pool_helper. */
111
kono
parents: 19
diff changeset
264 gomp_simple_barrier_wait (&pool->threads_dock);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
265 /* Now it is safe to destroy the barrier and free the pool. */
111
kono
parents: 19
diff changeset
266 gomp_simple_barrier_destroy (&pool->threads_dock);
kono
parents: 19
diff changeset
267
kono
parents: 19
diff changeset
268 #ifdef HAVE_SYNC_BUILTINS
kono
parents: 19
diff changeset
269 __sync_fetch_and_add (&gomp_managed_threads,
kono
parents: 19
diff changeset
270 1L - pool->threads_used);
kono
parents: 19
diff changeset
271 #else
kono
parents: 19
diff changeset
272 gomp_mutex_lock (&gomp_managed_threads_lock);
kono
parents: 19
diff changeset
273 gomp_managed_threads -= pool->threads_used - 1L;
kono
parents: 19
diff changeset
274 gomp_mutex_unlock (&gomp_managed_threads_lock);
kono
parents: 19
diff changeset
275 #endif
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
276 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
277 if (pool->last_team)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
278 free_team (pool->last_team);
111
kono
parents: 19
diff changeset
279 #ifndef __nvptx__
kono
parents: 19
diff changeset
280 free (pool->threads);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
281 free (pool);
111
kono
parents: 19
diff changeset
282 #endif
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
283 thr->thread_pool = NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
284 }
111
kono
parents: 19
diff changeset
285 if (thr->ts.level == 0 && __builtin_expect (thr->ts.team != NULL, 0))
kono
parents: 19
diff changeset
286 gomp_team_end ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
287 if (thr->task != NULL)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
288 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
289 struct gomp_task *task = thr->task;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
290 gomp_end_task ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
291 free (task);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
292 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
293 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
294
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
295 /* Launch a team. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
296
111
kono
parents: 19
diff changeset
297 #ifdef LIBGOMP_USE_PTHREADS
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
298 void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
299 gomp_team_start (void (*fn) (void *), void *data, unsigned nthreads,
111
kono
parents: 19
diff changeset
300 unsigned flags, struct gomp_team *team)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
301 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
302 struct gomp_thread_start_data *start_data;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
303 struct gomp_thread *thr, *nthr;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
304 struct gomp_task *task;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
305 struct gomp_task_icv *icv;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
306 bool nested;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
307 struct gomp_thread_pool *pool;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
308 unsigned i, n, old_threads_used = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
309 pthread_attr_t thread_attr, *attr;
111
kono
parents: 19
diff changeset
310 unsigned long nthreads_var;
kono
parents: 19
diff changeset
311 char bind, bind_var;
kono
parents: 19
diff changeset
312 unsigned int s = 0, rest = 0, p = 0, k = 0;
kono
parents: 19
diff changeset
313 unsigned int affinity_count = 0;
kono
parents: 19
diff changeset
314 struct gomp_thread **affinity_thr = NULL;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
315
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
316 thr = gomp_thread ();
111
kono
parents: 19
diff changeset
317 nested = thr->ts.level;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
318 pool = thr->thread_pool;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
319 task = thr->task;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
320 icv = task ? &task->icv : &gomp_global_icv;
111
kono
parents: 19
diff changeset
321 if (__builtin_expect (gomp_places_list != NULL, 0) && thr->place == 0)
kono
parents: 19
diff changeset
322 gomp_init_affinity ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
323
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
324 /* Always save the previous state, even if this isn't a nested team.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
325 In particular, we should save any work share state from an outer
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
326 orphaned work share construct. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
327 team->prev_ts = thr->ts;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
328
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
329 thr->ts.team = team;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
330 thr->ts.team_id = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
331 ++thr->ts.level;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
332 if (nthreads > 1)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
333 ++thr->ts.active_level;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
334 thr->ts.work_share = &team->work_shares[0];
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
335 thr->ts.last_work_share = NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
336 #ifdef HAVE_SYNC_BUILTINS
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
337 thr->ts.single_count = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
338 #endif
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
339 thr->ts.static_trip = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
340 thr->task = &team->implicit_task[0];
111
kono
parents: 19
diff changeset
341 nthreads_var = icv->nthreads_var;
kono
parents: 19
diff changeset
342 if (__builtin_expect (gomp_nthreads_var_list != NULL, 0)
kono
parents: 19
diff changeset
343 && thr->ts.level < gomp_nthreads_var_list_len)
kono
parents: 19
diff changeset
344 nthreads_var = gomp_nthreads_var_list[thr->ts.level];
kono
parents: 19
diff changeset
345 bind_var = icv->bind_var;
kono
parents: 19
diff changeset
346 if (bind_var != omp_proc_bind_false && (flags & 7) != omp_proc_bind_false)
kono
parents: 19
diff changeset
347 bind_var = flags & 7;
kono
parents: 19
diff changeset
348 bind = bind_var;
kono
parents: 19
diff changeset
349 if (__builtin_expect (gomp_bind_var_list != NULL, 0)
kono
parents: 19
diff changeset
350 && thr->ts.level < gomp_bind_var_list_len)
kono
parents: 19
diff changeset
351 bind_var = gomp_bind_var_list[thr->ts.level];
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
352 gomp_init_task (thr->task, task, icv);
111
kono
parents: 19
diff changeset
353 team->implicit_task[0].icv.nthreads_var = nthreads_var;
kono
parents: 19
diff changeset
354 team->implicit_task[0].icv.bind_var = bind_var;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
355
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
356 if (nthreads == 1)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
357 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
358
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
359 i = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
360
111
kono
parents: 19
diff changeset
361 if (__builtin_expect (gomp_places_list != NULL, 0))
kono
parents: 19
diff changeset
362 {
kono
parents: 19
diff changeset
363 /* Depending on chosen proc_bind model, set subpartition
kono
parents: 19
diff changeset
364 for the master thread and initialize helper variables
kono
parents: 19
diff changeset
365 P and optionally S, K and/or REST used by later place
kono
parents: 19
diff changeset
366 computation for each additional thread. */
kono
parents: 19
diff changeset
367 p = thr->place - 1;
kono
parents: 19
diff changeset
368 switch (bind)
kono
parents: 19
diff changeset
369 {
kono
parents: 19
diff changeset
370 case omp_proc_bind_true:
kono
parents: 19
diff changeset
371 case omp_proc_bind_close:
kono
parents: 19
diff changeset
372 if (nthreads > thr->ts.place_partition_len)
kono
parents: 19
diff changeset
373 {
kono
parents: 19
diff changeset
374 /* T > P. S threads will be placed in each place,
kono
parents: 19
diff changeset
375 and the final REM threads placed one by one
kono
parents: 19
diff changeset
376 into the already occupied places. */
kono
parents: 19
diff changeset
377 s = nthreads / thr->ts.place_partition_len;
kono
parents: 19
diff changeset
378 rest = nthreads % thr->ts.place_partition_len;
kono
parents: 19
diff changeset
379 }
kono
parents: 19
diff changeset
380 else
kono
parents: 19
diff changeset
381 s = 1;
kono
parents: 19
diff changeset
382 k = 1;
kono
parents: 19
diff changeset
383 break;
kono
parents: 19
diff changeset
384 case omp_proc_bind_master:
kono
parents: 19
diff changeset
385 /* Each thread will be bound to master's place. */
kono
parents: 19
diff changeset
386 break;
kono
parents: 19
diff changeset
387 case omp_proc_bind_spread:
kono
parents: 19
diff changeset
388 if (nthreads <= thr->ts.place_partition_len)
kono
parents: 19
diff changeset
389 {
kono
parents: 19
diff changeset
390 /* T <= P. Each subpartition will have in between s
kono
parents: 19
diff changeset
391 and s+1 places (subpartitions starting at or
kono
parents: 19
diff changeset
392 after rest will have s places, earlier s+1 places),
kono
parents: 19
diff changeset
393 each thread will be bound to the first place in
kono
parents: 19
diff changeset
394 its subpartition (except for the master thread
kono
parents: 19
diff changeset
395 that can be bound to another place in its
kono
parents: 19
diff changeset
396 subpartition). */
kono
parents: 19
diff changeset
397 s = thr->ts.place_partition_len / nthreads;
kono
parents: 19
diff changeset
398 rest = thr->ts.place_partition_len % nthreads;
kono
parents: 19
diff changeset
399 rest = (s + 1) * rest + thr->ts.place_partition_off;
kono
parents: 19
diff changeset
400 if (p < rest)
kono
parents: 19
diff changeset
401 {
kono
parents: 19
diff changeset
402 p -= (p - thr->ts.place_partition_off) % (s + 1);
kono
parents: 19
diff changeset
403 thr->ts.place_partition_len = s + 1;
kono
parents: 19
diff changeset
404 }
kono
parents: 19
diff changeset
405 else
kono
parents: 19
diff changeset
406 {
kono
parents: 19
diff changeset
407 p -= (p - rest) % s;
kono
parents: 19
diff changeset
408 thr->ts.place_partition_len = s;
kono
parents: 19
diff changeset
409 }
kono
parents: 19
diff changeset
410 thr->ts.place_partition_off = p;
kono
parents: 19
diff changeset
411 }
kono
parents: 19
diff changeset
412 else
kono
parents: 19
diff changeset
413 {
kono
parents: 19
diff changeset
414 /* T > P. Each subpartition will have just a single
kono
parents: 19
diff changeset
415 place and we'll place between s and s+1
kono
parents: 19
diff changeset
416 threads into each subpartition. */
kono
parents: 19
diff changeset
417 s = nthreads / thr->ts.place_partition_len;
kono
parents: 19
diff changeset
418 rest = nthreads % thr->ts.place_partition_len;
kono
parents: 19
diff changeset
419 thr->ts.place_partition_off = p;
kono
parents: 19
diff changeset
420 thr->ts.place_partition_len = 1;
kono
parents: 19
diff changeset
421 k = 1;
kono
parents: 19
diff changeset
422 }
kono
parents: 19
diff changeset
423 break;
kono
parents: 19
diff changeset
424 }
kono
parents: 19
diff changeset
425 }
kono
parents: 19
diff changeset
426 else
kono
parents: 19
diff changeset
427 bind = omp_proc_bind_false;
kono
parents: 19
diff changeset
428
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
429 /* We only allow the reuse of idle threads for non-nested PARALLEL
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
430 regions. This appears to be implied by the semantics of
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
431 threadprivate variables, but perhaps that's reading too much into
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
432 things. Certainly it does prevent any locking problems, since
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
433 only the initial program thread will modify gomp_threads. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
434 if (!nested)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
435 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
436 old_threads_used = pool->threads_used;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
437
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
438 if (nthreads <= old_threads_used)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
439 n = nthreads;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
440 else if (old_threads_used == 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
441 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
442 n = 0;
111
kono
parents: 19
diff changeset
443 gomp_simple_barrier_init (&pool->threads_dock, nthreads);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
444 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
445 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
446 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
447 n = old_threads_used;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
448
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
449 /* Increase the barrier threshold to make sure all new
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
450 threads arrive before the team is released. */
111
kono
parents: 19
diff changeset
451 gomp_simple_barrier_reinit (&pool->threads_dock, nthreads);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
452 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
453
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
454 /* Not true yet, but soon will be. We're going to release all
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
455 threads from the dock, and those that aren't part of the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
456 team will exit. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
457 pool->threads_used = nthreads;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
458
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
459 /* If necessary, expand the size of the gomp_threads array. It is
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
460 expected that changes in the number of threads are rare, thus we
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
461 make no effort to expand gomp_threads_size geometrically. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
462 if (nthreads >= pool->threads_size)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
463 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
464 pool->threads_size = nthreads + 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
465 pool->threads
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
466 = gomp_realloc (pool->threads,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
467 pool->threads_size
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
468 * sizeof (struct gomp_thread_data *));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
469 }
111
kono
parents: 19
diff changeset
470
kono
parents: 19
diff changeset
471 /* Release existing idle threads. */
kono
parents: 19
diff changeset
472 for (; i < n; ++i)
kono
parents: 19
diff changeset
473 {
kono
parents: 19
diff changeset
474 unsigned int place_partition_off = thr->ts.place_partition_off;
kono
parents: 19
diff changeset
475 unsigned int place_partition_len = thr->ts.place_partition_len;
kono
parents: 19
diff changeset
476 unsigned int place = 0;
kono
parents: 19
diff changeset
477 if (__builtin_expect (gomp_places_list != NULL, 0))
kono
parents: 19
diff changeset
478 {
kono
parents: 19
diff changeset
479 switch (bind)
kono
parents: 19
diff changeset
480 {
kono
parents: 19
diff changeset
481 case omp_proc_bind_true:
kono
parents: 19
diff changeset
482 case omp_proc_bind_close:
kono
parents: 19
diff changeset
483 if (k == s)
kono
parents: 19
diff changeset
484 {
kono
parents: 19
diff changeset
485 ++p;
kono
parents: 19
diff changeset
486 if (p == (team->prev_ts.place_partition_off
kono
parents: 19
diff changeset
487 + team->prev_ts.place_partition_len))
kono
parents: 19
diff changeset
488 p = team->prev_ts.place_partition_off;
kono
parents: 19
diff changeset
489 k = 1;
kono
parents: 19
diff changeset
490 if (i == nthreads - rest)
kono
parents: 19
diff changeset
491 s = 1;
kono
parents: 19
diff changeset
492 }
kono
parents: 19
diff changeset
493 else
kono
parents: 19
diff changeset
494 ++k;
kono
parents: 19
diff changeset
495 break;
kono
parents: 19
diff changeset
496 case omp_proc_bind_master:
kono
parents: 19
diff changeset
497 break;
kono
parents: 19
diff changeset
498 case omp_proc_bind_spread:
kono
parents: 19
diff changeset
499 if (k == 0)
kono
parents: 19
diff changeset
500 {
kono
parents: 19
diff changeset
501 /* T <= P. */
kono
parents: 19
diff changeset
502 if (p < rest)
kono
parents: 19
diff changeset
503 p += s + 1;
kono
parents: 19
diff changeset
504 else
kono
parents: 19
diff changeset
505 p += s;
kono
parents: 19
diff changeset
506 if (p == (team->prev_ts.place_partition_off
kono
parents: 19
diff changeset
507 + team->prev_ts.place_partition_len))
kono
parents: 19
diff changeset
508 p = team->prev_ts.place_partition_off;
kono
parents: 19
diff changeset
509 place_partition_off = p;
kono
parents: 19
diff changeset
510 if (p < rest)
kono
parents: 19
diff changeset
511 place_partition_len = s + 1;
kono
parents: 19
diff changeset
512 else
kono
parents: 19
diff changeset
513 place_partition_len = s;
kono
parents: 19
diff changeset
514 }
kono
parents: 19
diff changeset
515 else
kono
parents: 19
diff changeset
516 {
kono
parents: 19
diff changeset
517 /* T > P. */
kono
parents: 19
diff changeset
518 if (k == s)
kono
parents: 19
diff changeset
519 {
kono
parents: 19
diff changeset
520 ++p;
kono
parents: 19
diff changeset
521 if (p == (team->prev_ts.place_partition_off
kono
parents: 19
diff changeset
522 + team->prev_ts.place_partition_len))
kono
parents: 19
diff changeset
523 p = team->prev_ts.place_partition_off;
kono
parents: 19
diff changeset
524 k = 1;
kono
parents: 19
diff changeset
525 if (i == nthreads - rest)
kono
parents: 19
diff changeset
526 s = 1;
kono
parents: 19
diff changeset
527 }
kono
parents: 19
diff changeset
528 else
kono
parents: 19
diff changeset
529 ++k;
kono
parents: 19
diff changeset
530 place_partition_off = p;
kono
parents: 19
diff changeset
531 place_partition_len = 1;
kono
parents: 19
diff changeset
532 }
kono
parents: 19
diff changeset
533 break;
kono
parents: 19
diff changeset
534 }
kono
parents: 19
diff changeset
535 if (affinity_thr != NULL
kono
parents: 19
diff changeset
536 || (bind != omp_proc_bind_true
kono
parents: 19
diff changeset
537 && pool->threads[i]->place != p + 1)
kono
parents: 19
diff changeset
538 || pool->threads[i]->place <= place_partition_off
kono
parents: 19
diff changeset
539 || pool->threads[i]->place > (place_partition_off
kono
parents: 19
diff changeset
540 + place_partition_len))
kono
parents: 19
diff changeset
541 {
kono
parents: 19
diff changeset
542 unsigned int l;
kono
parents: 19
diff changeset
543 if (affinity_thr == NULL)
kono
parents: 19
diff changeset
544 {
kono
parents: 19
diff changeset
545 unsigned int j;
kono
parents: 19
diff changeset
546
kono
parents: 19
diff changeset
547 if (team->prev_ts.place_partition_len > 64)
kono
parents: 19
diff changeset
548 affinity_thr
kono
parents: 19
diff changeset
549 = gomp_malloc (team->prev_ts.place_partition_len
kono
parents: 19
diff changeset
550 * sizeof (struct gomp_thread *));
kono
parents: 19
diff changeset
551 else
kono
parents: 19
diff changeset
552 affinity_thr
kono
parents: 19
diff changeset
553 = gomp_alloca (team->prev_ts.place_partition_len
kono
parents: 19
diff changeset
554 * sizeof (struct gomp_thread *));
kono
parents: 19
diff changeset
555 memset (affinity_thr, '\0',
kono
parents: 19
diff changeset
556 team->prev_ts.place_partition_len
kono
parents: 19
diff changeset
557 * sizeof (struct gomp_thread *));
kono
parents: 19
diff changeset
558 for (j = i; j < old_threads_used; j++)
kono
parents: 19
diff changeset
559 {
kono
parents: 19
diff changeset
560 if (pool->threads[j]->place
kono
parents: 19
diff changeset
561 > team->prev_ts.place_partition_off
kono
parents: 19
diff changeset
562 && (pool->threads[j]->place
kono
parents: 19
diff changeset
563 <= (team->prev_ts.place_partition_off
kono
parents: 19
diff changeset
564 + team->prev_ts.place_partition_len)))
kono
parents: 19
diff changeset
565 {
kono
parents: 19
diff changeset
566 l = pool->threads[j]->place - 1
kono
parents: 19
diff changeset
567 - team->prev_ts.place_partition_off;
kono
parents: 19
diff changeset
568 pool->threads[j]->data = affinity_thr[l];
kono
parents: 19
diff changeset
569 affinity_thr[l] = pool->threads[j];
kono
parents: 19
diff changeset
570 }
kono
parents: 19
diff changeset
571 pool->threads[j] = NULL;
kono
parents: 19
diff changeset
572 }
kono
parents: 19
diff changeset
573 if (nthreads > old_threads_used)
kono
parents: 19
diff changeset
574 memset (&pool->threads[old_threads_used],
kono
parents: 19
diff changeset
575 '\0', ((nthreads - old_threads_used)
kono
parents: 19
diff changeset
576 * sizeof (struct gomp_thread *)));
kono
parents: 19
diff changeset
577 n = nthreads;
kono
parents: 19
diff changeset
578 affinity_count = old_threads_used - i;
kono
parents: 19
diff changeset
579 }
kono
parents: 19
diff changeset
580 if (affinity_count == 0)
kono
parents: 19
diff changeset
581 break;
kono
parents: 19
diff changeset
582 l = p;
kono
parents: 19
diff changeset
583 if (affinity_thr[l - team->prev_ts.place_partition_off]
kono
parents: 19
diff changeset
584 == NULL)
kono
parents: 19
diff changeset
585 {
kono
parents: 19
diff changeset
586 if (bind != omp_proc_bind_true)
kono
parents: 19
diff changeset
587 continue;
kono
parents: 19
diff changeset
588 for (l = place_partition_off;
kono
parents: 19
diff changeset
589 l < place_partition_off + place_partition_len;
kono
parents: 19
diff changeset
590 l++)
kono
parents: 19
diff changeset
591 if (affinity_thr[l - team->prev_ts.place_partition_off]
kono
parents: 19
diff changeset
592 != NULL)
kono
parents: 19
diff changeset
593 break;
kono
parents: 19
diff changeset
594 if (l == place_partition_off + place_partition_len)
kono
parents: 19
diff changeset
595 continue;
kono
parents: 19
diff changeset
596 }
kono
parents: 19
diff changeset
597 nthr = affinity_thr[l - team->prev_ts.place_partition_off];
kono
parents: 19
diff changeset
598 affinity_thr[l - team->prev_ts.place_partition_off]
kono
parents: 19
diff changeset
599 = (struct gomp_thread *) nthr->data;
kono
parents: 19
diff changeset
600 affinity_count--;
kono
parents: 19
diff changeset
601 pool->threads[i] = nthr;
kono
parents: 19
diff changeset
602 }
kono
parents: 19
diff changeset
603 else
kono
parents: 19
diff changeset
604 nthr = pool->threads[i];
kono
parents: 19
diff changeset
605 place = p + 1;
kono
parents: 19
diff changeset
606 }
kono
parents: 19
diff changeset
607 else
kono
parents: 19
diff changeset
608 nthr = pool->threads[i];
kono
parents: 19
diff changeset
609 nthr->ts.team = team;
kono
parents: 19
diff changeset
610 nthr->ts.work_share = &team->work_shares[0];
kono
parents: 19
diff changeset
611 nthr->ts.last_work_share = NULL;
kono
parents: 19
diff changeset
612 nthr->ts.team_id = i;
kono
parents: 19
diff changeset
613 nthr->ts.level = team->prev_ts.level + 1;
kono
parents: 19
diff changeset
614 nthr->ts.active_level = thr->ts.active_level;
kono
parents: 19
diff changeset
615 nthr->ts.place_partition_off = place_partition_off;
kono
parents: 19
diff changeset
616 nthr->ts.place_partition_len = place_partition_len;
kono
parents: 19
diff changeset
617 #ifdef HAVE_SYNC_BUILTINS
kono
parents: 19
diff changeset
618 nthr->ts.single_count = 0;
kono
parents: 19
diff changeset
619 #endif
kono
parents: 19
diff changeset
620 nthr->ts.static_trip = 0;
kono
parents: 19
diff changeset
621 nthr->task = &team->implicit_task[i];
kono
parents: 19
diff changeset
622 nthr->place = place;
kono
parents: 19
diff changeset
623 gomp_init_task (nthr->task, task, icv);
kono
parents: 19
diff changeset
624 team->implicit_task[i].icv.nthreads_var = nthreads_var;
kono
parents: 19
diff changeset
625 team->implicit_task[i].icv.bind_var = bind_var;
kono
parents: 19
diff changeset
626 nthr->fn = fn;
kono
parents: 19
diff changeset
627 nthr->data = data;
kono
parents: 19
diff changeset
628 team->ordered_release[i] = &nthr->release;
kono
parents: 19
diff changeset
629 }
kono
parents: 19
diff changeset
630
kono
parents: 19
diff changeset
631 if (__builtin_expect (affinity_thr != NULL, 0))
kono
parents: 19
diff changeset
632 {
kono
parents: 19
diff changeset
633 /* If AFFINITY_THR is non-NULL just because we had to
kono
parents: 19
diff changeset
634 permute some threads in the pool, but we've managed
kono
parents: 19
diff changeset
635 to find exactly as many old threads as we'd find
kono
parents: 19
diff changeset
636 without affinity, we don't need to handle this
kono
parents: 19
diff changeset
637 specially anymore. */
kono
parents: 19
diff changeset
638 if (nthreads <= old_threads_used
kono
parents: 19
diff changeset
639 ? (affinity_count == old_threads_used - nthreads)
kono
parents: 19
diff changeset
640 : (i == old_threads_used))
kono
parents: 19
diff changeset
641 {
kono
parents: 19
diff changeset
642 if (team->prev_ts.place_partition_len > 64)
kono
parents: 19
diff changeset
643 free (affinity_thr);
kono
parents: 19
diff changeset
644 affinity_thr = NULL;
kono
parents: 19
diff changeset
645 affinity_count = 0;
kono
parents: 19
diff changeset
646 }
kono
parents: 19
diff changeset
647 else
kono
parents: 19
diff changeset
648 {
kono
parents: 19
diff changeset
649 i = 1;
kono
parents: 19
diff changeset
650 /* We are going to compute the places/subpartitions
kono
parents: 19
diff changeset
651 again from the beginning. So, we need to reinitialize
kono
parents: 19
diff changeset
652 vars modified by the switch (bind) above inside
kono
parents: 19
diff changeset
653 of the loop, to the state they had after the initial
kono
parents: 19
diff changeset
654 switch (bind). */
kono
parents: 19
diff changeset
655 switch (bind)
kono
parents: 19
diff changeset
656 {
kono
parents: 19
diff changeset
657 case omp_proc_bind_true:
kono
parents: 19
diff changeset
658 case omp_proc_bind_close:
kono
parents: 19
diff changeset
659 if (nthreads > thr->ts.place_partition_len)
kono
parents: 19
diff changeset
660 /* T > P. S has been changed, so needs
kono
parents: 19
diff changeset
661 to be recomputed. */
kono
parents: 19
diff changeset
662 s = nthreads / thr->ts.place_partition_len;
kono
parents: 19
diff changeset
663 k = 1;
kono
parents: 19
diff changeset
664 p = thr->place - 1;
kono
parents: 19
diff changeset
665 break;
kono
parents: 19
diff changeset
666 case omp_proc_bind_master:
kono
parents: 19
diff changeset
667 /* No vars have been changed. */
kono
parents: 19
diff changeset
668 break;
kono
parents: 19
diff changeset
669 case omp_proc_bind_spread:
kono
parents: 19
diff changeset
670 p = thr->ts.place_partition_off;
kono
parents: 19
diff changeset
671 if (k != 0)
kono
parents: 19
diff changeset
672 {
kono
parents: 19
diff changeset
673 /* T > P. */
kono
parents: 19
diff changeset
674 s = nthreads / team->prev_ts.place_partition_len;
kono
parents: 19
diff changeset
675 k = 1;
kono
parents: 19
diff changeset
676 }
kono
parents: 19
diff changeset
677 break;
kono
parents: 19
diff changeset
678 }
kono
parents: 19
diff changeset
679
kono
parents: 19
diff changeset
680 /* Increase the barrier threshold to make sure all new
kono
parents: 19
diff changeset
681 threads and all the threads we're going to let die
kono
parents: 19
diff changeset
682 arrive before the team is released. */
kono
parents: 19
diff changeset
683 if (affinity_count)
kono
parents: 19
diff changeset
684 gomp_simple_barrier_reinit (&pool->threads_dock,
kono
parents: 19
diff changeset
685 nthreads + affinity_count);
kono
parents: 19
diff changeset
686 }
kono
parents: 19
diff changeset
687 }
kono
parents: 19
diff changeset
688
kono
parents: 19
diff changeset
689 if (i == nthreads)
kono
parents: 19
diff changeset
690 goto do_release;
kono
parents: 19
diff changeset
691
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
692 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
693
111
kono
parents: 19
diff changeset
694 if (__builtin_expect (nthreads + affinity_count > old_threads_used, 0))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
695 {
111
kono
parents: 19
diff changeset
696 long diff = (long) (nthreads + affinity_count) - (long) old_threads_used;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
697
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
698 if (old_threads_used == 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
699 --diff;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
700
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
701 #ifdef HAVE_SYNC_BUILTINS
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
702 __sync_fetch_and_add (&gomp_managed_threads, diff);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
703 #else
111
kono
parents: 19
diff changeset
704 gomp_mutex_lock (&gomp_managed_threads_lock);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
705 gomp_managed_threads += diff;
111
kono
parents: 19
diff changeset
706 gomp_mutex_unlock (&gomp_managed_threads_lock);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
707 #endif
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
708 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
709
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
710 attr = &gomp_thread_attr;
111
kono
parents: 19
diff changeset
711 if (__builtin_expect (gomp_places_list != NULL, 0))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
712 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
713 size_t stacksize;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
714 pthread_attr_init (&thread_attr);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
715 pthread_attr_setdetachstate (&thread_attr, PTHREAD_CREATE_DETACHED);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
716 if (! pthread_attr_getstacksize (&gomp_thread_attr, &stacksize))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
717 pthread_attr_setstacksize (&thread_attr, stacksize);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
718 attr = &thread_attr;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
719 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
720
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
721 start_data = gomp_alloca (sizeof (struct gomp_thread_start_data)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
722 * (nthreads-i));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
723
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
724 /* Launch new threads. */
111
kono
parents: 19
diff changeset
725 for (; i < nthreads; ++i)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
726 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
727 pthread_t pt;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
728 int err;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
729
111
kono
parents: 19
diff changeset
730 start_data->ts.place_partition_off = thr->ts.place_partition_off;
kono
parents: 19
diff changeset
731 start_data->ts.place_partition_len = thr->ts.place_partition_len;
kono
parents: 19
diff changeset
732 start_data->place = 0;
kono
parents: 19
diff changeset
733 if (__builtin_expect (gomp_places_list != NULL, 0))
kono
parents: 19
diff changeset
734 {
kono
parents: 19
diff changeset
735 switch (bind)
kono
parents: 19
diff changeset
736 {
kono
parents: 19
diff changeset
737 case omp_proc_bind_true:
kono
parents: 19
diff changeset
738 case omp_proc_bind_close:
kono
parents: 19
diff changeset
739 if (k == s)
kono
parents: 19
diff changeset
740 {
kono
parents: 19
diff changeset
741 ++p;
kono
parents: 19
diff changeset
742 if (p == (team->prev_ts.place_partition_off
kono
parents: 19
diff changeset
743 + team->prev_ts.place_partition_len))
kono
parents: 19
diff changeset
744 p = team->prev_ts.place_partition_off;
kono
parents: 19
diff changeset
745 k = 1;
kono
parents: 19
diff changeset
746 if (i == nthreads - rest)
kono
parents: 19
diff changeset
747 s = 1;
kono
parents: 19
diff changeset
748 }
kono
parents: 19
diff changeset
749 else
kono
parents: 19
diff changeset
750 ++k;
kono
parents: 19
diff changeset
751 break;
kono
parents: 19
diff changeset
752 case omp_proc_bind_master:
kono
parents: 19
diff changeset
753 break;
kono
parents: 19
diff changeset
754 case omp_proc_bind_spread:
kono
parents: 19
diff changeset
755 if (k == 0)
kono
parents: 19
diff changeset
756 {
kono
parents: 19
diff changeset
757 /* T <= P. */
kono
parents: 19
diff changeset
758 if (p < rest)
kono
parents: 19
diff changeset
759 p += s + 1;
kono
parents: 19
diff changeset
760 else
kono
parents: 19
diff changeset
761 p += s;
kono
parents: 19
diff changeset
762 if (p == (team->prev_ts.place_partition_off
kono
parents: 19
diff changeset
763 + team->prev_ts.place_partition_len))
kono
parents: 19
diff changeset
764 p = team->prev_ts.place_partition_off;
kono
parents: 19
diff changeset
765 start_data->ts.place_partition_off = p;
kono
parents: 19
diff changeset
766 if (p < rest)
kono
parents: 19
diff changeset
767 start_data->ts.place_partition_len = s + 1;
kono
parents: 19
diff changeset
768 else
kono
parents: 19
diff changeset
769 start_data->ts.place_partition_len = s;
kono
parents: 19
diff changeset
770 }
kono
parents: 19
diff changeset
771 else
kono
parents: 19
diff changeset
772 {
kono
parents: 19
diff changeset
773 /* T > P. */
kono
parents: 19
diff changeset
774 if (k == s)
kono
parents: 19
diff changeset
775 {
kono
parents: 19
diff changeset
776 ++p;
kono
parents: 19
diff changeset
777 if (p == (team->prev_ts.place_partition_off
kono
parents: 19
diff changeset
778 + team->prev_ts.place_partition_len))
kono
parents: 19
diff changeset
779 p = team->prev_ts.place_partition_off;
kono
parents: 19
diff changeset
780 k = 1;
kono
parents: 19
diff changeset
781 if (i == nthreads - rest)
kono
parents: 19
diff changeset
782 s = 1;
kono
parents: 19
diff changeset
783 }
kono
parents: 19
diff changeset
784 else
kono
parents: 19
diff changeset
785 ++k;
kono
parents: 19
diff changeset
786 start_data->ts.place_partition_off = p;
kono
parents: 19
diff changeset
787 start_data->ts.place_partition_len = 1;
kono
parents: 19
diff changeset
788 }
kono
parents: 19
diff changeset
789 break;
kono
parents: 19
diff changeset
790 }
kono
parents: 19
diff changeset
791 start_data->place = p + 1;
kono
parents: 19
diff changeset
792 if (affinity_thr != NULL && pool->threads[i] != NULL)
kono
parents: 19
diff changeset
793 continue;
kono
parents: 19
diff changeset
794 gomp_init_thread_affinity (attr, p);
kono
parents: 19
diff changeset
795 }
kono
parents: 19
diff changeset
796
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
797 start_data->fn = fn;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
798 start_data->fn_data = data;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
799 start_data->ts.team = team;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
800 start_data->ts.work_share = &team->work_shares[0];
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
801 start_data->ts.last_work_share = NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
802 start_data->ts.team_id = i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
803 start_data->ts.level = team->prev_ts.level + 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
804 start_data->ts.active_level = thr->ts.active_level;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
805 #ifdef HAVE_SYNC_BUILTINS
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
806 start_data->ts.single_count = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
807 #endif
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
808 start_data->ts.static_trip = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
809 start_data->task = &team->implicit_task[i];
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
810 gomp_init_task (start_data->task, task, icv);
111
kono
parents: 19
diff changeset
811 team->implicit_task[i].icv.nthreads_var = nthreads_var;
kono
parents: 19
diff changeset
812 team->implicit_task[i].icv.bind_var = bind_var;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
813 start_data->thread_pool = pool;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
814 start_data->nested = nested;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
815
111
kono
parents: 19
diff changeset
816 attr = gomp_adjust_thread_attr (attr, &thread_attr);
kono
parents: 19
diff changeset
817 err = pthread_create (&pt, attr, gomp_thread_start, start_data++);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
818 if (err != 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
819 gomp_fatal ("Thread creation failed: %s", strerror (err));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
820 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
821
111
kono
parents: 19
diff changeset
822 if (__builtin_expect (attr == &thread_attr, 0))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
823 pthread_attr_destroy (&thread_attr);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
824
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
825 do_release:
111
kono
parents: 19
diff changeset
826 if (nested)
kono
parents: 19
diff changeset
827 gomp_barrier_wait (&team->barrier);
kono
parents: 19
diff changeset
828 else
kono
parents: 19
diff changeset
829 gomp_simple_barrier_wait (&pool->threads_dock);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
830
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
831 /* Decrease the barrier threshold to match the number of threads
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
832 that should arrive back at the end of this team. The extra
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
833 threads should be exiting. Note that we arrange for this test
111
kono
parents: 19
diff changeset
834 to never be true for nested teams. If AFFINITY_COUNT is non-zero,
kono
parents: 19
diff changeset
835 the barrier as well as gomp_managed_threads was temporarily
kono
parents: 19
diff changeset
836 set to NTHREADS + AFFINITY_COUNT. For NTHREADS < OLD_THREADS_COUNT,
kono
parents: 19
diff changeset
837 AFFINITY_COUNT if non-zero will be always at least
kono
parents: 19
diff changeset
838 OLD_THREADS_COUNT - NTHREADS. */
kono
parents: 19
diff changeset
839 if (__builtin_expect (nthreads < old_threads_used, 0)
kono
parents: 19
diff changeset
840 || __builtin_expect (affinity_count, 0))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
841 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
842 long diff = (long) nthreads - (long) old_threads_used;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
843
111
kono
parents: 19
diff changeset
844 if (affinity_count)
kono
parents: 19
diff changeset
845 diff = -affinity_count;
kono
parents: 19
diff changeset
846
kono
parents: 19
diff changeset
847 gomp_simple_barrier_reinit (&pool->threads_dock, nthreads);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
848
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
849 #ifdef HAVE_SYNC_BUILTINS
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
850 __sync_fetch_and_add (&gomp_managed_threads, diff);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
851 #else
111
kono
parents: 19
diff changeset
852 gomp_mutex_lock (&gomp_managed_threads_lock);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
853 gomp_managed_threads += diff;
111
kono
parents: 19
diff changeset
854 gomp_mutex_unlock (&gomp_managed_threads_lock);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
855 #endif
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
856 }
111
kono
parents: 19
diff changeset
857 if (__builtin_expect (affinity_thr != NULL, 0)
kono
parents: 19
diff changeset
858 && team->prev_ts.place_partition_len > 64)
kono
parents: 19
diff changeset
859 free (affinity_thr);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
860 }
111
kono
parents: 19
diff changeset
861 #endif
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
862
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
863
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
864 /* Terminate the current team. This is only to be called by the master
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
865 thread. We assume that we must wait for the other threads. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
866
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
867 void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
868 gomp_team_end (void)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
869 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
870 struct gomp_thread *thr = gomp_thread ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
871 struct gomp_team *team = thr->ts.team;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
872
111
kono
parents: 19
diff changeset
873 /* This barrier handles all pending explicit threads.
kono
parents: 19
diff changeset
874 As #pragma omp cancel parallel might get awaited count in
kono
parents: 19
diff changeset
875 team->barrier in a inconsistent state, we need to use a different
kono
parents: 19
diff changeset
876 counter here. */
kono
parents: 19
diff changeset
877 gomp_team_barrier_wait_final (&team->barrier);
kono
parents: 19
diff changeset
878 if (__builtin_expect (team->team_cancelled, 0))
kono
parents: 19
diff changeset
879 {
kono
parents: 19
diff changeset
880 struct gomp_work_share *ws = team->work_shares_to_free;
kono
parents: 19
diff changeset
881 do
kono
parents: 19
diff changeset
882 {
kono
parents: 19
diff changeset
883 struct gomp_work_share *next_ws = gomp_ptrlock_get (&ws->next_ws);
kono
parents: 19
diff changeset
884 if (next_ws == NULL)
kono
parents: 19
diff changeset
885 gomp_ptrlock_set (&ws->next_ws, ws);
kono
parents: 19
diff changeset
886 gomp_fini_work_share (ws);
kono
parents: 19
diff changeset
887 ws = next_ws;
kono
parents: 19
diff changeset
888 }
kono
parents: 19
diff changeset
889 while (ws != NULL);
kono
parents: 19
diff changeset
890 }
kono
parents: 19
diff changeset
891 else
kono
parents: 19
diff changeset
892 gomp_fini_work_share (thr->ts.work_share);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
893
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
894 gomp_end_task ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
895 thr->ts = team->prev_ts;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
896
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
897 if (__builtin_expect (thr->ts.team != NULL, 0))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
898 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
899 #ifdef HAVE_SYNC_BUILTINS
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
900 __sync_fetch_and_add (&gomp_managed_threads, 1L - team->nthreads);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
901 #else
111
kono
parents: 19
diff changeset
902 gomp_mutex_lock (&gomp_managed_threads_lock);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
903 gomp_managed_threads -= team->nthreads - 1L;
111
kono
parents: 19
diff changeset
904 gomp_mutex_unlock (&gomp_managed_threads_lock);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
905 #endif
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
906 /* This barrier has gomp_barrier_wait_last counterparts
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
907 and ensures the team can be safely destroyed. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
908 gomp_barrier_wait (&team->barrier);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
909 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
910
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
911 if (__builtin_expect (team->work_shares[0].next_alloc != NULL, 0))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
912 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
913 struct gomp_work_share *ws = team->work_shares[0].next_alloc;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
914 do
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
915 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
916 struct gomp_work_share *next_ws = ws->next_alloc;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
917 free (ws);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
918 ws = next_ws;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
919 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
920 while (ws != NULL);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
921 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
922 gomp_sem_destroy (&team->master_release);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
923
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
924 if (__builtin_expect (thr->ts.team != NULL, 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
925 || __builtin_expect (team->nthreads == 1, 0))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
926 free_team (team);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
927 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
928 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
929 struct gomp_thread_pool *pool = thr->thread_pool;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
930 if (pool->last_team)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
931 free_team (pool->last_team);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
932 pool->last_team = team;
111
kono
parents: 19
diff changeset
933 gomp_release_thread_pool (pool);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
934 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
935 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
936
111
kono
parents: 19
diff changeset
937 #ifdef LIBGOMP_USE_PTHREADS
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
938
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
939 /* Constructors for this file. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
940
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
941 static void __attribute__((constructor))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
942 initialize_team (void)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
943 {
111
kono
parents: 19
diff changeset
944 #if !defined HAVE_TLS && !defined USE_EMUTLS
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
945 static struct gomp_thread initial_thread_tls_data;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
946
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
947 pthread_key_create (&gomp_tls_key, NULL);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
948 pthread_setspecific (gomp_tls_key, &initial_thread_tls_data);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
949 #endif
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
950
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
951 if (pthread_key_create (&gomp_thread_destructor, gomp_free_thread) != 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
952 gomp_fatal ("could not create thread pool destructor.");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
953 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
954
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
955 static void __attribute__((destructor))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
956 team_destructor (void)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
957 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
958 /* Without this dlclose on libgomp could lead to subsequent
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
959 crashes. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
960 pthread_key_delete (gomp_thread_destructor);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
961 }
111
kono
parents: 19
diff changeset
962 #endif
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
963
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
964 struct gomp_task_icv *
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
965 gomp_new_icv (void)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
966 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
967 struct gomp_thread *thr = gomp_thread ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
968 struct gomp_task *task = gomp_malloc (sizeof (struct gomp_task));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
969 gomp_init_task (task, NULL, &gomp_global_icv);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
970 thr->task = task;
111
kono
parents: 19
diff changeset
971 #ifdef LIBGOMP_USE_PTHREADS
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
972 pthread_setspecific (gomp_thread_destructor, thr);
111
kono
parents: 19
diff changeset
973 #endif
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
974 return &task->icv;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
975 }