annotate libgomp/team.c @ 158:494b0b89df80 default tip

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 18:13:55 +0900
parents 1830386684a0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1 /* Copyright (C) 2005-2020 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
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
26 /* This file handles the maintenance of threads in response to team
0
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 pthread_attr_t gomp_thread_attr;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
36
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
37 /* This key is for the thread destructor. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
38 pthread_key_t gomp_thread_destructor;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
39
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 /* This is the libgomp per-thread data structure. */
111
kono
parents: 19
diff changeset
42 #if defined HAVE_TLS || defined USE_EMUTLS
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
43 __thread struct gomp_thread gomp_tls_data;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
44 #else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
45 pthread_key_t gomp_tls_key;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
46 #endif
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
47
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 /* This structure is used to communicate across pthread_create. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
50
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
51 struct gomp_thread_start_data
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
52 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
53 void (*fn) (void *);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
54 void *fn_data;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
55 struct gomp_team_state ts;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
56 struct gomp_task *task;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
57 struct gomp_thread_pool *thread_pool;
111
kono
parents: 19
diff changeset
58 unsigned int place;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
59 bool nested;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
60 pthread_t handle;
0
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;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
92 #ifdef GOMP_NEEDS_THREAD_HANDLE
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
93 thr->handle = data->handle;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
94 #endif
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
95
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
96 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
97
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
98 /* Make thread pool local. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
99 pool = thr->thread_pool;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
100
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
101 if (data->nested)
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 struct gomp_team *team = thr->ts.team;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
104 struct gomp_task *task = thr->task;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
105
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
106 gomp_barrier_wait (&team->barrier);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
107
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
108 local_fn (local_data);
111
kono
parents: 19
diff changeset
109 gomp_team_barrier_wait_final (&team->barrier);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
110 gomp_finish_task (task);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
111 gomp_barrier_wait_last (&team->barrier);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
112 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
113 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
114 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
115 pool->threads[thr->ts.team_id] = thr;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
116
111
kono
parents: 19
diff changeset
117 gomp_simple_barrier_wait (&pool->threads_dock);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
118 do
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 struct gomp_team *team = thr->ts.team;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
121 struct gomp_task *task = thr->task;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
122
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
123 local_fn (local_data);
111
kono
parents: 19
diff changeset
124 gomp_team_barrier_wait_final (&team->barrier);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
125 gomp_finish_task (task);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
126
111
kono
parents: 19
diff changeset
127 gomp_simple_barrier_wait (&pool->threads_dock);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
128
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
129 local_fn = thr->fn;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
130 local_data = thr->data;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
131 thr->fn = NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
132 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
133 while (local_fn);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
134 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
135
19
58ad6c70ea60 update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents: 0
diff changeset
136 gomp_sem_destroy (&thr->release);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
137 pthread_detach (pthread_self ());
111
kono
parents: 19
diff changeset
138 thr->thread_pool = NULL;
kono
parents: 19
diff changeset
139 thr->task = NULL;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
140 return NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
141 }
111
kono
parents: 19
diff changeset
142 #endif
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
143
111
kono
parents: 19
diff changeset
144 static inline struct gomp_team *
kono
parents: 19
diff changeset
145 get_last_team (unsigned nthreads)
kono
parents: 19
diff changeset
146 {
kono
parents: 19
diff changeset
147 struct gomp_thread *thr = gomp_thread ();
kono
parents: 19
diff changeset
148 if (thr->ts.team == NULL)
kono
parents: 19
diff changeset
149 {
kono
parents: 19
diff changeset
150 struct gomp_thread_pool *pool = gomp_get_thread_pool (thr, nthreads);
kono
parents: 19
diff changeset
151 struct gomp_team *last_team = pool->last_team;
kono
parents: 19
diff changeset
152 if (last_team != NULL && last_team->nthreads == nthreads)
kono
parents: 19
diff changeset
153 {
kono
parents: 19
diff changeset
154 pool->last_team = NULL;
kono
parents: 19
diff changeset
155 return last_team;
kono
parents: 19
diff changeset
156 }
kono
parents: 19
diff changeset
157 }
kono
parents: 19
diff changeset
158 return NULL;
kono
parents: 19
diff changeset
159 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
160
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
161 /* Create a new team data structure. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
162
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
163 struct gomp_team *
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
164 gomp_new_team (unsigned nthreads)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
165 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
166 struct gomp_team *team;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
167 int i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
168
111
kono
parents: 19
diff changeset
169 team = get_last_team (nthreads);
kono
parents: 19
diff changeset
170 if (team == NULL)
kono
parents: 19
diff changeset
171 {
kono
parents: 19
diff changeset
172 size_t extra = sizeof (team->ordered_release[0])
kono
parents: 19
diff changeset
173 + sizeof (team->implicit_task[0]);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
174 team = team_malloc (sizeof (*team) + nthreads * extra);
111
kono
parents: 19
diff changeset
175
kono
parents: 19
diff changeset
176 #ifndef HAVE_SYNC_BUILTINS
kono
parents: 19
diff changeset
177 gomp_mutex_init (&team->work_share_list_free_lock);
kono
parents: 19
diff changeset
178 #endif
kono
parents: 19
diff changeset
179 gomp_barrier_init (&team->barrier, nthreads);
kono
parents: 19
diff changeset
180 gomp_mutex_init (&team->task_lock);
kono
parents: 19
diff changeset
181
kono
parents: 19
diff changeset
182 team->nthreads = nthreads;
kono
parents: 19
diff changeset
183 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
184
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
185 team->work_share_chunk = 8;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
186 #ifdef HAVE_SYNC_BUILTINS
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
187 team->single_count = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
188 #endif
111
kono
parents: 19
diff changeset
189 team->work_shares_to_free = &team->work_shares[0];
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
190 gomp_init_work_share (&team->work_shares[0], 0, nthreads);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
191 team->work_shares[0].next_alloc = NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
192 team->work_share_list_free = NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
193 team->work_share_list_alloc = &team->work_shares[1];
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
194 for (i = 1; i < 7; i++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
195 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
196 team->work_shares[i].next_free = NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
197
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
198 gomp_sem_init (&team->master_release, 0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
199 team->ordered_release = (void *) &team->implicit_task[nthreads];
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
200 team->ordered_release[0] = &team->master_release;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
201
111
kono
parents: 19
diff changeset
202 priority_queue_init (&team->task_queue);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
203 team->task_count = 0;
111
kono
parents: 19
diff changeset
204 team->task_queued_count = 0;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
205 team->task_running_count = 0;
111
kono
parents: 19
diff changeset
206 team->work_share_cancelled = 0;
kono
parents: 19
diff changeset
207 team->team_cancelled = 0;
0
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 return team;
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
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
212
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
213 /* Free a team data structure. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
214
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
215 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
216 free_team (struct gomp_team *team)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
217 {
111
kono
parents: 19
diff changeset
218 #ifndef HAVE_SYNC_BUILTINS
kono
parents: 19
diff changeset
219 gomp_mutex_destroy (&team->work_share_list_free_lock);
kono
parents: 19
diff changeset
220 #endif
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
221 gomp_barrier_destroy (&team->barrier);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
222 gomp_mutex_destroy (&team->task_lock);
111
kono
parents: 19
diff changeset
223 priority_queue_free (&team->task_queue);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
224 team_free (team);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
225 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
226
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
227 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
228 gomp_free_pool_helper (void *thread_pool)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
229 {
111
kono
parents: 19
diff changeset
230 struct gomp_thread *thr = gomp_thread ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
231 struct gomp_thread_pool *pool
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
232 = (struct gomp_thread_pool *) thread_pool;
111
kono
parents: 19
diff changeset
233 gomp_simple_barrier_wait_last (&pool->threads_dock);
kono
parents: 19
diff changeset
234 gomp_sem_destroy (&thr->release);
kono
parents: 19
diff changeset
235 thr->thread_pool = NULL;
kono
parents: 19
diff changeset
236 thr->task = NULL;
kono
parents: 19
diff changeset
237 #ifdef LIBGOMP_USE_PTHREADS
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
238 pthread_detach (pthread_self ());
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
239 pthread_exit (NULL);
111
kono
parents: 19
diff changeset
240 #elif defined(__nvptx__)
kono
parents: 19
diff changeset
241 asm ("exit;");
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
242 #elif defined(__AMDGCN__)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
243 asm ("s_dcache_wb\n\t"
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
244 "s_endpgm");
111
kono
parents: 19
diff changeset
245 #else
kono
parents: 19
diff changeset
246 #error gomp_free_pool_helper must terminate the thread
kono
parents: 19
diff changeset
247 #endif
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
248 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
249
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
250 /* Free a thread pool and release its threads. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
251
111
kono
parents: 19
diff changeset
252 void
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
253 gomp_free_thread (void *arg __attribute__((unused)))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
254 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
255 struct gomp_thread *thr = gomp_thread ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
256 struct gomp_thread_pool *pool = thr->thread_pool;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
257 if (pool)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
258 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
259 if (pool->threads_used > 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
260 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
261 int i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
262 for (i = 1; i < pool->threads_used; i++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
263 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
264 struct gomp_thread *nthr = pool->threads[i];
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
265 nthr->fn = gomp_free_pool_helper;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
266 nthr->data = pool;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
267 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
268 /* This barrier undocks threads docked on pool->threads_dock. */
111
kono
parents: 19
diff changeset
269 gomp_simple_barrier_wait (&pool->threads_dock);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
270 /* 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
271 in gomp_free_pool_helper. */
111
kono
parents: 19
diff changeset
272 gomp_simple_barrier_wait (&pool->threads_dock);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
273 /* Now it is safe to destroy the barrier and free the pool. */
111
kono
parents: 19
diff changeset
274 gomp_simple_barrier_destroy (&pool->threads_dock);
kono
parents: 19
diff changeset
275
kono
parents: 19
diff changeset
276 #ifdef HAVE_SYNC_BUILTINS
kono
parents: 19
diff changeset
277 __sync_fetch_and_add (&gomp_managed_threads,
kono
parents: 19
diff changeset
278 1L - pool->threads_used);
kono
parents: 19
diff changeset
279 #else
kono
parents: 19
diff changeset
280 gomp_mutex_lock (&gomp_managed_threads_lock);
kono
parents: 19
diff changeset
281 gomp_managed_threads -= pool->threads_used - 1L;
kono
parents: 19
diff changeset
282 gomp_mutex_unlock (&gomp_managed_threads_lock);
kono
parents: 19
diff changeset
283 #endif
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
284 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
285 if (pool->last_team)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
286 free_team (pool->last_team);
111
kono
parents: 19
diff changeset
287 #ifndef __nvptx__
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
288 team_free (pool->threads);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
289 team_free (pool);
111
kono
parents: 19
diff changeset
290 #endif
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
291 thr->thread_pool = NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
292 }
111
kono
parents: 19
diff changeset
293 if (thr->ts.level == 0 && __builtin_expect (thr->ts.team != NULL, 0))
kono
parents: 19
diff changeset
294 gomp_team_end ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
295 if (thr->task != NULL)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
296 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
297 struct gomp_task *task = thr->task;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
298 gomp_end_task ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
299 free (task);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
300 }
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
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
303 /* Launch a team. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
304
111
kono
parents: 19
diff changeset
305 #ifdef LIBGOMP_USE_PTHREADS
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
306 void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
307 gomp_team_start (void (*fn) (void *), void *data, unsigned nthreads,
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
308 unsigned flags, struct gomp_team *team,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
309 struct gomp_taskgroup *taskgroup)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
310 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
311 struct gomp_thread_start_data *start_data;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
312 struct gomp_thread *thr, *nthr;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
313 struct gomp_task *task;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
314 struct gomp_task_icv *icv;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
315 bool nested;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
316 struct gomp_thread_pool *pool;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
317 unsigned i, n, old_threads_used = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
318 pthread_attr_t thread_attr, *attr;
111
kono
parents: 19
diff changeset
319 unsigned long nthreads_var;
kono
parents: 19
diff changeset
320 char bind, bind_var;
kono
parents: 19
diff changeset
321 unsigned int s = 0, rest = 0, p = 0, k = 0;
kono
parents: 19
diff changeset
322 unsigned int affinity_count = 0;
kono
parents: 19
diff changeset
323 struct gomp_thread **affinity_thr = NULL;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
324 bool force_display = false;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
325
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
326 thr = gomp_thread ();
111
kono
parents: 19
diff changeset
327 nested = thr->ts.level;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
328 pool = thr->thread_pool;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
329 task = thr->task;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
330 icv = task ? &task->icv : &gomp_global_icv;
111
kono
parents: 19
diff changeset
331 if (__builtin_expect (gomp_places_list != NULL, 0) && thr->place == 0)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
332 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
333 gomp_init_affinity ();
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
334 if (__builtin_expect (gomp_display_affinity_var, 0) && nthreads == 1)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
335 gomp_display_affinity_thread (gomp_thread_self (), &thr->ts,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
336 thr->place);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
337 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
338
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
339 /* 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
340 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
341 orphaned work share construct. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
342 team->prev_ts = thr->ts;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
343
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
344 thr->ts.team = team;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
345 thr->ts.team_id = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
346 ++thr->ts.level;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
347 if (nthreads > 1)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
348 ++thr->ts.active_level;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
349 thr->ts.work_share = &team->work_shares[0];
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
350 thr->ts.last_work_share = NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
351 #ifdef HAVE_SYNC_BUILTINS
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
352 thr->ts.single_count = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
353 #endif
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
354 thr->ts.static_trip = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
355 thr->task = &team->implicit_task[0];
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
356 #ifdef GOMP_NEEDS_THREAD_HANDLE
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
357 thr->handle = pthread_self ();
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
358 #endif
111
kono
parents: 19
diff changeset
359 nthreads_var = icv->nthreads_var;
kono
parents: 19
diff changeset
360 if (__builtin_expect (gomp_nthreads_var_list != NULL, 0)
kono
parents: 19
diff changeset
361 && thr->ts.level < gomp_nthreads_var_list_len)
kono
parents: 19
diff changeset
362 nthreads_var = gomp_nthreads_var_list[thr->ts.level];
kono
parents: 19
diff changeset
363 bind_var = icv->bind_var;
kono
parents: 19
diff changeset
364 if (bind_var != omp_proc_bind_false && (flags & 7) != omp_proc_bind_false)
kono
parents: 19
diff changeset
365 bind_var = flags & 7;
kono
parents: 19
diff changeset
366 bind = bind_var;
kono
parents: 19
diff changeset
367 if (__builtin_expect (gomp_bind_var_list != NULL, 0)
kono
parents: 19
diff changeset
368 && thr->ts.level < gomp_bind_var_list_len)
kono
parents: 19
diff changeset
369 bind_var = gomp_bind_var_list[thr->ts.level];
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
370 gomp_init_task (thr->task, task, icv);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
371 thr->task->taskgroup = taskgroup;
111
kono
parents: 19
diff changeset
372 team->implicit_task[0].icv.nthreads_var = nthreads_var;
kono
parents: 19
diff changeset
373 team->implicit_task[0].icv.bind_var = bind_var;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
374
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
375 if (nthreads == 1)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
376 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
377
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
378 i = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
379
111
kono
parents: 19
diff changeset
380 if (__builtin_expect (gomp_places_list != NULL, 0))
kono
parents: 19
diff changeset
381 {
kono
parents: 19
diff changeset
382 /* Depending on chosen proc_bind model, set subpartition
kono
parents: 19
diff changeset
383 for the master thread and initialize helper variables
kono
parents: 19
diff changeset
384 P and optionally S, K and/or REST used by later place
kono
parents: 19
diff changeset
385 computation for each additional thread. */
kono
parents: 19
diff changeset
386 p = thr->place - 1;
kono
parents: 19
diff changeset
387 switch (bind)
kono
parents: 19
diff changeset
388 {
kono
parents: 19
diff changeset
389 case omp_proc_bind_true:
kono
parents: 19
diff changeset
390 case omp_proc_bind_close:
kono
parents: 19
diff changeset
391 if (nthreads > thr->ts.place_partition_len)
kono
parents: 19
diff changeset
392 {
kono
parents: 19
diff changeset
393 /* T > P. S threads will be placed in each place,
kono
parents: 19
diff changeset
394 and the final REM threads placed one by one
kono
parents: 19
diff changeset
395 into the already occupied places. */
kono
parents: 19
diff changeset
396 s = nthreads / thr->ts.place_partition_len;
kono
parents: 19
diff changeset
397 rest = nthreads % thr->ts.place_partition_len;
kono
parents: 19
diff changeset
398 }
kono
parents: 19
diff changeset
399 else
kono
parents: 19
diff changeset
400 s = 1;
kono
parents: 19
diff changeset
401 k = 1;
kono
parents: 19
diff changeset
402 break;
kono
parents: 19
diff changeset
403 case omp_proc_bind_master:
kono
parents: 19
diff changeset
404 /* Each thread will be bound to master's place. */
kono
parents: 19
diff changeset
405 break;
kono
parents: 19
diff changeset
406 case omp_proc_bind_spread:
kono
parents: 19
diff changeset
407 if (nthreads <= thr->ts.place_partition_len)
kono
parents: 19
diff changeset
408 {
kono
parents: 19
diff changeset
409 /* T <= P. Each subpartition will have in between s
kono
parents: 19
diff changeset
410 and s+1 places (subpartitions starting at or
kono
parents: 19
diff changeset
411 after rest will have s places, earlier s+1 places),
kono
parents: 19
diff changeset
412 each thread will be bound to the first place in
kono
parents: 19
diff changeset
413 its subpartition (except for the master thread
kono
parents: 19
diff changeset
414 that can be bound to another place in its
kono
parents: 19
diff changeset
415 subpartition). */
kono
parents: 19
diff changeset
416 s = thr->ts.place_partition_len / nthreads;
kono
parents: 19
diff changeset
417 rest = thr->ts.place_partition_len % nthreads;
kono
parents: 19
diff changeset
418 rest = (s + 1) * rest + thr->ts.place_partition_off;
kono
parents: 19
diff changeset
419 if (p < rest)
kono
parents: 19
diff changeset
420 {
kono
parents: 19
diff changeset
421 p -= (p - thr->ts.place_partition_off) % (s + 1);
kono
parents: 19
diff changeset
422 thr->ts.place_partition_len = s + 1;
kono
parents: 19
diff changeset
423 }
kono
parents: 19
diff changeset
424 else
kono
parents: 19
diff changeset
425 {
kono
parents: 19
diff changeset
426 p -= (p - rest) % s;
kono
parents: 19
diff changeset
427 thr->ts.place_partition_len = s;
kono
parents: 19
diff changeset
428 }
kono
parents: 19
diff changeset
429 thr->ts.place_partition_off = p;
kono
parents: 19
diff changeset
430 }
kono
parents: 19
diff changeset
431 else
kono
parents: 19
diff changeset
432 {
kono
parents: 19
diff changeset
433 /* T > P. Each subpartition will have just a single
kono
parents: 19
diff changeset
434 place and we'll place between s and s+1
kono
parents: 19
diff changeset
435 threads into each subpartition. */
kono
parents: 19
diff changeset
436 s = nthreads / thr->ts.place_partition_len;
kono
parents: 19
diff changeset
437 rest = nthreads % thr->ts.place_partition_len;
kono
parents: 19
diff changeset
438 thr->ts.place_partition_off = p;
kono
parents: 19
diff changeset
439 thr->ts.place_partition_len = 1;
kono
parents: 19
diff changeset
440 k = 1;
kono
parents: 19
diff changeset
441 }
kono
parents: 19
diff changeset
442 break;
kono
parents: 19
diff changeset
443 }
kono
parents: 19
diff changeset
444 }
kono
parents: 19
diff changeset
445 else
kono
parents: 19
diff changeset
446 bind = omp_proc_bind_false;
kono
parents: 19
diff changeset
447
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
448 /* 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
449 regions. This appears to be implied by the semantics of
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
450 threadprivate variables, but perhaps that's reading too much into
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
451 things. Certainly it does prevent any locking problems, since
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
452 only the initial program thread will modify gomp_threads. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
453 if (!nested)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
454 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
455 old_threads_used = pool->threads_used;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
456
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
457 if (nthreads <= old_threads_used)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
458 n = nthreads;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
459 else if (old_threads_used == 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
460 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
461 n = 0;
111
kono
parents: 19
diff changeset
462 gomp_simple_barrier_init (&pool->threads_dock, nthreads);
0
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 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
465 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
466 n = old_threads_used;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
467
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
468 /* Increase the barrier threshold to make sure all new
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
469 threads arrive before the team is released. */
111
kono
parents: 19
diff changeset
470 gomp_simple_barrier_reinit (&pool->threads_dock, nthreads);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
471 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
472
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
473 /* 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
474 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
475 team will exit. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
476 pool->threads_used = nthreads;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
477
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
478 /* 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
479 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
480 make no effort to expand gomp_threads_size geometrically. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
481 if (nthreads >= pool->threads_size)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
482 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
483 pool->threads_size = nthreads + 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
484 pool->threads
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
485 = gomp_realloc (pool->threads,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
486 pool->threads_size
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
487 * sizeof (struct gomp_thread *));
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
488 /* Add current (master) thread to threads[]. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
489 pool->threads[0] = thr;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
490 }
111
kono
parents: 19
diff changeset
491
kono
parents: 19
diff changeset
492 /* Release existing idle threads. */
kono
parents: 19
diff changeset
493 for (; i < n; ++i)
kono
parents: 19
diff changeset
494 {
kono
parents: 19
diff changeset
495 unsigned int place_partition_off = thr->ts.place_partition_off;
kono
parents: 19
diff changeset
496 unsigned int place_partition_len = thr->ts.place_partition_len;
kono
parents: 19
diff changeset
497 unsigned int place = 0;
kono
parents: 19
diff changeset
498 if (__builtin_expect (gomp_places_list != NULL, 0))
kono
parents: 19
diff changeset
499 {
kono
parents: 19
diff changeset
500 switch (bind)
kono
parents: 19
diff changeset
501 {
kono
parents: 19
diff changeset
502 case omp_proc_bind_true:
kono
parents: 19
diff changeset
503 case omp_proc_bind_close:
kono
parents: 19
diff changeset
504 if (k == s)
kono
parents: 19
diff changeset
505 {
kono
parents: 19
diff changeset
506 ++p;
kono
parents: 19
diff changeset
507 if (p == (team->prev_ts.place_partition_off
kono
parents: 19
diff changeset
508 + team->prev_ts.place_partition_len))
kono
parents: 19
diff changeset
509 p = team->prev_ts.place_partition_off;
kono
parents: 19
diff changeset
510 k = 1;
kono
parents: 19
diff changeset
511 if (i == nthreads - rest)
kono
parents: 19
diff changeset
512 s = 1;
kono
parents: 19
diff changeset
513 }
kono
parents: 19
diff changeset
514 else
kono
parents: 19
diff changeset
515 ++k;
kono
parents: 19
diff changeset
516 break;
kono
parents: 19
diff changeset
517 case omp_proc_bind_master:
kono
parents: 19
diff changeset
518 break;
kono
parents: 19
diff changeset
519 case omp_proc_bind_spread:
kono
parents: 19
diff changeset
520 if (k == 0)
kono
parents: 19
diff changeset
521 {
kono
parents: 19
diff changeset
522 /* T <= P. */
kono
parents: 19
diff changeset
523 if (p < rest)
kono
parents: 19
diff changeset
524 p += s + 1;
kono
parents: 19
diff changeset
525 else
kono
parents: 19
diff changeset
526 p += s;
kono
parents: 19
diff changeset
527 if (p == (team->prev_ts.place_partition_off
kono
parents: 19
diff changeset
528 + team->prev_ts.place_partition_len))
kono
parents: 19
diff changeset
529 p = team->prev_ts.place_partition_off;
kono
parents: 19
diff changeset
530 place_partition_off = p;
kono
parents: 19
diff changeset
531 if (p < rest)
kono
parents: 19
diff changeset
532 place_partition_len = s + 1;
kono
parents: 19
diff changeset
533 else
kono
parents: 19
diff changeset
534 place_partition_len = s;
kono
parents: 19
diff changeset
535 }
kono
parents: 19
diff changeset
536 else
kono
parents: 19
diff changeset
537 {
kono
parents: 19
diff changeset
538 /* T > P. */
kono
parents: 19
diff changeset
539 if (k == s)
kono
parents: 19
diff changeset
540 {
kono
parents: 19
diff changeset
541 ++p;
kono
parents: 19
diff changeset
542 if (p == (team->prev_ts.place_partition_off
kono
parents: 19
diff changeset
543 + team->prev_ts.place_partition_len))
kono
parents: 19
diff changeset
544 p = team->prev_ts.place_partition_off;
kono
parents: 19
diff changeset
545 k = 1;
kono
parents: 19
diff changeset
546 if (i == nthreads - rest)
kono
parents: 19
diff changeset
547 s = 1;
kono
parents: 19
diff changeset
548 }
kono
parents: 19
diff changeset
549 else
kono
parents: 19
diff changeset
550 ++k;
kono
parents: 19
diff changeset
551 place_partition_off = p;
kono
parents: 19
diff changeset
552 place_partition_len = 1;
kono
parents: 19
diff changeset
553 }
kono
parents: 19
diff changeset
554 break;
kono
parents: 19
diff changeset
555 }
kono
parents: 19
diff changeset
556 if (affinity_thr != NULL
kono
parents: 19
diff changeset
557 || (bind != omp_proc_bind_true
kono
parents: 19
diff changeset
558 && pool->threads[i]->place != p + 1)
kono
parents: 19
diff changeset
559 || pool->threads[i]->place <= place_partition_off
kono
parents: 19
diff changeset
560 || pool->threads[i]->place > (place_partition_off
kono
parents: 19
diff changeset
561 + place_partition_len))
kono
parents: 19
diff changeset
562 {
kono
parents: 19
diff changeset
563 unsigned int l;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
564 force_display = true;
111
kono
parents: 19
diff changeset
565 if (affinity_thr == NULL)
kono
parents: 19
diff changeset
566 {
kono
parents: 19
diff changeset
567 unsigned int j;
kono
parents: 19
diff changeset
568
kono
parents: 19
diff changeset
569 if (team->prev_ts.place_partition_len > 64)
kono
parents: 19
diff changeset
570 affinity_thr
kono
parents: 19
diff changeset
571 = gomp_malloc (team->prev_ts.place_partition_len
kono
parents: 19
diff changeset
572 * sizeof (struct gomp_thread *));
kono
parents: 19
diff changeset
573 else
kono
parents: 19
diff changeset
574 affinity_thr
kono
parents: 19
diff changeset
575 = gomp_alloca (team->prev_ts.place_partition_len
kono
parents: 19
diff changeset
576 * sizeof (struct gomp_thread *));
kono
parents: 19
diff changeset
577 memset (affinity_thr, '\0',
kono
parents: 19
diff changeset
578 team->prev_ts.place_partition_len
kono
parents: 19
diff changeset
579 * sizeof (struct gomp_thread *));
kono
parents: 19
diff changeset
580 for (j = i; j < old_threads_used; j++)
kono
parents: 19
diff changeset
581 {
kono
parents: 19
diff changeset
582 if (pool->threads[j]->place
kono
parents: 19
diff changeset
583 > team->prev_ts.place_partition_off
kono
parents: 19
diff changeset
584 && (pool->threads[j]->place
kono
parents: 19
diff changeset
585 <= (team->prev_ts.place_partition_off
kono
parents: 19
diff changeset
586 + team->prev_ts.place_partition_len)))
kono
parents: 19
diff changeset
587 {
kono
parents: 19
diff changeset
588 l = pool->threads[j]->place - 1
kono
parents: 19
diff changeset
589 - team->prev_ts.place_partition_off;
kono
parents: 19
diff changeset
590 pool->threads[j]->data = affinity_thr[l];
kono
parents: 19
diff changeset
591 affinity_thr[l] = pool->threads[j];
kono
parents: 19
diff changeset
592 }
kono
parents: 19
diff changeset
593 pool->threads[j] = NULL;
kono
parents: 19
diff changeset
594 }
kono
parents: 19
diff changeset
595 if (nthreads > old_threads_used)
kono
parents: 19
diff changeset
596 memset (&pool->threads[old_threads_used],
kono
parents: 19
diff changeset
597 '\0', ((nthreads - old_threads_used)
kono
parents: 19
diff changeset
598 * sizeof (struct gomp_thread *)));
kono
parents: 19
diff changeset
599 n = nthreads;
kono
parents: 19
diff changeset
600 affinity_count = old_threads_used - i;
kono
parents: 19
diff changeset
601 }
kono
parents: 19
diff changeset
602 if (affinity_count == 0)
kono
parents: 19
diff changeset
603 break;
kono
parents: 19
diff changeset
604 l = p;
kono
parents: 19
diff changeset
605 if (affinity_thr[l - team->prev_ts.place_partition_off]
kono
parents: 19
diff changeset
606 == NULL)
kono
parents: 19
diff changeset
607 {
kono
parents: 19
diff changeset
608 if (bind != omp_proc_bind_true)
kono
parents: 19
diff changeset
609 continue;
kono
parents: 19
diff changeset
610 for (l = place_partition_off;
kono
parents: 19
diff changeset
611 l < place_partition_off + place_partition_len;
kono
parents: 19
diff changeset
612 l++)
kono
parents: 19
diff changeset
613 if (affinity_thr[l - team->prev_ts.place_partition_off]
kono
parents: 19
diff changeset
614 != NULL)
kono
parents: 19
diff changeset
615 break;
kono
parents: 19
diff changeset
616 if (l == place_partition_off + place_partition_len)
kono
parents: 19
diff changeset
617 continue;
kono
parents: 19
diff changeset
618 }
kono
parents: 19
diff changeset
619 nthr = affinity_thr[l - team->prev_ts.place_partition_off];
kono
parents: 19
diff changeset
620 affinity_thr[l - team->prev_ts.place_partition_off]
kono
parents: 19
diff changeset
621 = (struct gomp_thread *) nthr->data;
kono
parents: 19
diff changeset
622 affinity_count--;
kono
parents: 19
diff changeset
623 pool->threads[i] = nthr;
kono
parents: 19
diff changeset
624 }
kono
parents: 19
diff changeset
625 else
kono
parents: 19
diff changeset
626 nthr = pool->threads[i];
kono
parents: 19
diff changeset
627 place = p + 1;
kono
parents: 19
diff changeset
628 }
kono
parents: 19
diff changeset
629 else
kono
parents: 19
diff changeset
630 nthr = pool->threads[i];
kono
parents: 19
diff changeset
631 nthr->ts.team = team;
kono
parents: 19
diff changeset
632 nthr->ts.work_share = &team->work_shares[0];
kono
parents: 19
diff changeset
633 nthr->ts.last_work_share = NULL;
kono
parents: 19
diff changeset
634 nthr->ts.team_id = i;
kono
parents: 19
diff changeset
635 nthr->ts.level = team->prev_ts.level + 1;
kono
parents: 19
diff changeset
636 nthr->ts.active_level = thr->ts.active_level;
kono
parents: 19
diff changeset
637 nthr->ts.place_partition_off = place_partition_off;
kono
parents: 19
diff changeset
638 nthr->ts.place_partition_len = place_partition_len;
kono
parents: 19
diff changeset
639 #ifdef HAVE_SYNC_BUILTINS
kono
parents: 19
diff changeset
640 nthr->ts.single_count = 0;
kono
parents: 19
diff changeset
641 #endif
kono
parents: 19
diff changeset
642 nthr->ts.static_trip = 0;
kono
parents: 19
diff changeset
643 nthr->task = &team->implicit_task[i];
kono
parents: 19
diff changeset
644 nthr->place = place;
kono
parents: 19
diff changeset
645 gomp_init_task (nthr->task, task, icv);
kono
parents: 19
diff changeset
646 team->implicit_task[i].icv.nthreads_var = nthreads_var;
kono
parents: 19
diff changeset
647 team->implicit_task[i].icv.bind_var = bind_var;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
648 nthr->task->taskgroup = taskgroup;
111
kono
parents: 19
diff changeset
649 nthr->fn = fn;
kono
parents: 19
diff changeset
650 nthr->data = data;
kono
parents: 19
diff changeset
651 team->ordered_release[i] = &nthr->release;
kono
parents: 19
diff changeset
652 }
kono
parents: 19
diff changeset
653
kono
parents: 19
diff changeset
654 if (__builtin_expect (affinity_thr != NULL, 0))
kono
parents: 19
diff changeset
655 {
kono
parents: 19
diff changeset
656 /* If AFFINITY_THR is non-NULL just because we had to
kono
parents: 19
diff changeset
657 permute some threads in the pool, but we've managed
kono
parents: 19
diff changeset
658 to find exactly as many old threads as we'd find
kono
parents: 19
diff changeset
659 without affinity, we don't need to handle this
kono
parents: 19
diff changeset
660 specially anymore. */
kono
parents: 19
diff changeset
661 if (nthreads <= old_threads_used
kono
parents: 19
diff changeset
662 ? (affinity_count == old_threads_used - nthreads)
kono
parents: 19
diff changeset
663 : (i == old_threads_used))
kono
parents: 19
diff changeset
664 {
kono
parents: 19
diff changeset
665 if (team->prev_ts.place_partition_len > 64)
kono
parents: 19
diff changeset
666 free (affinity_thr);
kono
parents: 19
diff changeset
667 affinity_thr = NULL;
kono
parents: 19
diff changeset
668 affinity_count = 0;
kono
parents: 19
diff changeset
669 }
kono
parents: 19
diff changeset
670 else
kono
parents: 19
diff changeset
671 {
kono
parents: 19
diff changeset
672 i = 1;
kono
parents: 19
diff changeset
673 /* We are going to compute the places/subpartitions
kono
parents: 19
diff changeset
674 again from the beginning. So, we need to reinitialize
kono
parents: 19
diff changeset
675 vars modified by the switch (bind) above inside
kono
parents: 19
diff changeset
676 of the loop, to the state they had after the initial
kono
parents: 19
diff changeset
677 switch (bind). */
kono
parents: 19
diff changeset
678 switch (bind)
kono
parents: 19
diff changeset
679 {
kono
parents: 19
diff changeset
680 case omp_proc_bind_true:
kono
parents: 19
diff changeset
681 case omp_proc_bind_close:
kono
parents: 19
diff changeset
682 if (nthreads > thr->ts.place_partition_len)
kono
parents: 19
diff changeset
683 /* T > P. S has been changed, so needs
kono
parents: 19
diff changeset
684 to be recomputed. */
kono
parents: 19
diff changeset
685 s = nthreads / thr->ts.place_partition_len;
kono
parents: 19
diff changeset
686 k = 1;
kono
parents: 19
diff changeset
687 p = thr->place - 1;
kono
parents: 19
diff changeset
688 break;
kono
parents: 19
diff changeset
689 case omp_proc_bind_master:
kono
parents: 19
diff changeset
690 /* No vars have been changed. */
kono
parents: 19
diff changeset
691 break;
kono
parents: 19
diff changeset
692 case omp_proc_bind_spread:
kono
parents: 19
diff changeset
693 p = thr->ts.place_partition_off;
kono
parents: 19
diff changeset
694 if (k != 0)
kono
parents: 19
diff changeset
695 {
kono
parents: 19
diff changeset
696 /* T > P. */
kono
parents: 19
diff changeset
697 s = nthreads / team->prev_ts.place_partition_len;
kono
parents: 19
diff changeset
698 k = 1;
kono
parents: 19
diff changeset
699 }
kono
parents: 19
diff changeset
700 break;
kono
parents: 19
diff changeset
701 }
kono
parents: 19
diff changeset
702
kono
parents: 19
diff changeset
703 /* Increase the barrier threshold to make sure all new
kono
parents: 19
diff changeset
704 threads and all the threads we're going to let die
kono
parents: 19
diff changeset
705 arrive before the team is released. */
kono
parents: 19
diff changeset
706 if (affinity_count)
kono
parents: 19
diff changeset
707 gomp_simple_barrier_reinit (&pool->threads_dock,
kono
parents: 19
diff changeset
708 nthreads + affinity_count);
kono
parents: 19
diff changeset
709 }
kono
parents: 19
diff changeset
710 }
kono
parents: 19
diff changeset
711
kono
parents: 19
diff changeset
712 if (i == nthreads)
kono
parents: 19
diff changeset
713 goto do_release;
kono
parents: 19
diff changeset
714
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
715 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
716
111
kono
parents: 19
diff changeset
717 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
718 {
111
kono
parents: 19
diff changeset
719 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
720
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
721 if (old_threads_used == 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
722 --diff;
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 #ifdef HAVE_SYNC_BUILTINS
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
725 __sync_fetch_and_add (&gomp_managed_threads, diff);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
726 #else
111
kono
parents: 19
diff changeset
727 gomp_mutex_lock (&gomp_managed_threads_lock);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
728 gomp_managed_threads += diff;
111
kono
parents: 19
diff changeset
729 gomp_mutex_unlock (&gomp_managed_threads_lock);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
730 #endif
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
731 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
732
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
733 attr = &gomp_thread_attr;
111
kono
parents: 19
diff changeset
734 if (__builtin_expect (gomp_places_list != NULL, 0))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
735 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
736 size_t stacksize;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
737 pthread_attr_init (&thread_attr);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
738 if (! pthread_attr_getstacksize (&gomp_thread_attr, &stacksize))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
739 pthread_attr_setstacksize (&thread_attr, stacksize);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
740 attr = &thread_attr;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
741 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
742
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
743 start_data = gomp_alloca (sizeof (struct gomp_thread_start_data)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
744 * (nthreads - i));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
745
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
746 /* Launch new threads. */
111
kono
parents: 19
diff changeset
747 for (; i < nthreads; ++i)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
748 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
749 int err;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
750
111
kono
parents: 19
diff changeset
751 start_data->ts.place_partition_off = thr->ts.place_partition_off;
kono
parents: 19
diff changeset
752 start_data->ts.place_partition_len = thr->ts.place_partition_len;
kono
parents: 19
diff changeset
753 start_data->place = 0;
kono
parents: 19
diff changeset
754 if (__builtin_expect (gomp_places_list != NULL, 0))
kono
parents: 19
diff changeset
755 {
kono
parents: 19
diff changeset
756 switch (bind)
kono
parents: 19
diff changeset
757 {
kono
parents: 19
diff changeset
758 case omp_proc_bind_true:
kono
parents: 19
diff changeset
759 case omp_proc_bind_close:
kono
parents: 19
diff changeset
760 if (k == s)
kono
parents: 19
diff changeset
761 {
kono
parents: 19
diff changeset
762 ++p;
kono
parents: 19
diff changeset
763 if (p == (team->prev_ts.place_partition_off
kono
parents: 19
diff changeset
764 + team->prev_ts.place_partition_len))
kono
parents: 19
diff changeset
765 p = team->prev_ts.place_partition_off;
kono
parents: 19
diff changeset
766 k = 1;
kono
parents: 19
diff changeset
767 if (i == nthreads - rest)
kono
parents: 19
diff changeset
768 s = 1;
kono
parents: 19
diff changeset
769 }
kono
parents: 19
diff changeset
770 else
kono
parents: 19
diff changeset
771 ++k;
kono
parents: 19
diff changeset
772 break;
kono
parents: 19
diff changeset
773 case omp_proc_bind_master:
kono
parents: 19
diff changeset
774 break;
kono
parents: 19
diff changeset
775 case omp_proc_bind_spread:
kono
parents: 19
diff changeset
776 if (k == 0)
kono
parents: 19
diff changeset
777 {
kono
parents: 19
diff changeset
778 /* T <= P. */
kono
parents: 19
diff changeset
779 if (p < rest)
kono
parents: 19
diff changeset
780 p += s + 1;
kono
parents: 19
diff changeset
781 else
kono
parents: 19
diff changeset
782 p += s;
kono
parents: 19
diff changeset
783 if (p == (team->prev_ts.place_partition_off
kono
parents: 19
diff changeset
784 + team->prev_ts.place_partition_len))
kono
parents: 19
diff changeset
785 p = team->prev_ts.place_partition_off;
kono
parents: 19
diff changeset
786 start_data->ts.place_partition_off = p;
kono
parents: 19
diff changeset
787 if (p < rest)
kono
parents: 19
diff changeset
788 start_data->ts.place_partition_len = s + 1;
kono
parents: 19
diff changeset
789 else
kono
parents: 19
diff changeset
790 start_data->ts.place_partition_len = s;
kono
parents: 19
diff changeset
791 }
kono
parents: 19
diff changeset
792 else
kono
parents: 19
diff changeset
793 {
kono
parents: 19
diff changeset
794 /* T > P. */
kono
parents: 19
diff changeset
795 if (k == s)
kono
parents: 19
diff changeset
796 {
kono
parents: 19
diff changeset
797 ++p;
kono
parents: 19
diff changeset
798 if (p == (team->prev_ts.place_partition_off
kono
parents: 19
diff changeset
799 + team->prev_ts.place_partition_len))
kono
parents: 19
diff changeset
800 p = team->prev_ts.place_partition_off;
kono
parents: 19
diff changeset
801 k = 1;
kono
parents: 19
diff changeset
802 if (i == nthreads - rest)
kono
parents: 19
diff changeset
803 s = 1;
kono
parents: 19
diff changeset
804 }
kono
parents: 19
diff changeset
805 else
kono
parents: 19
diff changeset
806 ++k;
kono
parents: 19
diff changeset
807 start_data->ts.place_partition_off = p;
kono
parents: 19
diff changeset
808 start_data->ts.place_partition_len = 1;
kono
parents: 19
diff changeset
809 }
kono
parents: 19
diff changeset
810 break;
kono
parents: 19
diff changeset
811 }
kono
parents: 19
diff changeset
812 start_data->place = p + 1;
kono
parents: 19
diff changeset
813 if (affinity_thr != NULL && pool->threads[i] != NULL)
kono
parents: 19
diff changeset
814 continue;
kono
parents: 19
diff changeset
815 gomp_init_thread_affinity (attr, p);
kono
parents: 19
diff changeset
816 }
kono
parents: 19
diff changeset
817
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
818 start_data->fn = fn;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
819 start_data->fn_data = data;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
820 start_data->ts.team = team;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
821 start_data->ts.work_share = &team->work_shares[0];
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
822 start_data->ts.last_work_share = NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
823 start_data->ts.team_id = i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
824 start_data->ts.level = team->prev_ts.level + 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
825 start_data->ts.active_level = thr->ts.active_level;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
826 #ifdef HAVE_SYNC_BUILTINS
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
827 start_data->ts.single_count = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
828 #endif
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
829 start_data->ts.static_trip = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
830 start_data->task = &team->implicit_task[i];
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
831 gomp_init_task (start_data->task, task, icv);
111
kono
parents: 19
diff changeset
832 team->implicit_task[i].icv.nthreads_var = nthreads_var;
kono
parents: 19
diff changeset
833 team->implicit_task[i].icv.bind_var = bind_var;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
834 start_data->task->taskgroup = taskgroup;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
835 start_data->thread_pool = pool;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
836 start_data->nested = nested;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
837
111
kono
parents: 19
diff changeset
838 attr = gomp_adjust_thread_attr (attr, &thread_attr);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
839 err = pthread_create (&start_data->handle, attr, gomp_thread_start,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
840 start_data);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
841 start_data++;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
842 if (err != 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
843 gomp_fatal ("Thread creation failed: %s", strerror (err));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
844 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
845
111
kono
parents: 19
diff changeset
846 if (__builtin_expect (attr == &thread_attr, 0))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
847 pthread_attr_destroy (&thread_attr);
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 do_release:
111
kono
parents: 19
diff changeset
850 if (nested)
kono
parents: 19
diff changeset
851 gomp_barrier_wait (&team->barrier);
kono
parents: 19
diff changeset
852 else
kono
parents: 19
diff changeset
853 gomp_simple_barrier_wait (&pool->threads_dock);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
854
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
855 /* Decrease the barrier threshold to match the number of threads
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
856 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
857 threads should be exiting. Note that we arrange for this test
111
kono
parents: 19
diff changeset
858 to never be true for nested teams. If AFFINITY_COUNT is non-zero,
kono
parents: 19
diff changeset
859 the barrier as well as gomp_managed_threads was temporarily
kono
parents: 19
diff changeset
860 set to NTHREADS + AFFINITY_COUNT. For NTHREADS < OLD_THREADS_COUNT,
kono
parents: 19
diff changeset
861 AFFINITY_COUNT if non-zero will be always at least
kono
parents: 19
diff changeset
862 OLD_THREADS_COUNT - NTHREADS. */
kono
parents: 19
diff changeset
863 if (__builtin_expect (nthreads < old_threads_used, 0)
kono
parents: 19
diff changeset
864 || __builtin_expect (affinity_count, 0))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
865 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
866 long diff = (long) nthreads - (long) old_threads_used;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
867
111
kono
parents: 19
diff changeset
868 if (affinity_count)
kono
parents: 19
diff changeset
869 diff = -affinity_count;
kono
parents: 19
diff changeset
870
kono
parents: 19
diff changeset
871 gomp_simple_barrier_reinit (&pool->threads_dock, nthreads);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
872
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
873 #ifdef HAVE_SYNC_BUILTINS
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
874 __sync_fetch_and_add (&gomp_managed_threads, diff);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
875 #else
111
kono
parents: 19
diff changeset
876 gomp_mutex_lock (&gomp_managed_threads_lock);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
877 gomp_managed_threads += diff;
111
kono
parents: 19
diff changeset
878 gomp_mutex_unlock (&gomp_managed_threads_lock);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
879 #endif
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
880 }
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
881 if (__builtin_expect (gomp_display_affinity_var, 0))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
882 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
883 if (nested
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
884 || nthreads != old_threads_used
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
885 || force_display)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
886 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
887 gomp_display_affinity_thread (gomp_thread_self (), &thr->ts,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
888 thr->place);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
889 if (nested)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
890 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
891 start_data -= nthreads - 1;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
892 for (i = 1; i < nthreads; ++i)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
893 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
894 gomp_display_affinity_thread (
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
895 #ifdef LIBGOMP_USE_PTHREADS
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
896 start_data->handle,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
897 #else
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
898 gomp_thread_self (),
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
899 #endif
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
900 &start_data->ts,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
901 start_data->place);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
902 start_data++;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
903 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
904 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
905 else
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
906 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
907 for (i = 1; i < nthreads; ++i)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
908 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
909 gomp_thread_handle handle
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
910 = gomp_thread_to_pthread_t (pool->threads[i]);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
911 gomp_display_affinity_thread (handle, &pool->threads[i]->ts,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
912 pool->threads[i]->place);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
913 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
914 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
915 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
916 }
111
kono
parents: 19
diff changeset
917 if (__builtin_expect (affinity_thr != NULL, 0)
kono
parents: 19
diff changeset
918 && team->prev_ts.place_partition_len > 64)
kono
parents: 19
diff changeset
919 free (affinity_thr);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
920 }
111
kono
parents: 19
diff changeset
921 #endif
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
922
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 /* 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
925 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
926
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
927 void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
928 gomp_team_end (void)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
929 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
930 struct gomp_thread *thr = gomp_thread ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
931 struct gomp_team *team = thr->ts.team;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
932
111
kono
parents: 19
diff changeset
933 /* This barrier handles all pending explicit threads.
kono
parents: 19
diff changeset
934 As #pragma omp cancel parallel might get awaited count in
kono
parents: 19
diff changeset
935 team->barrier in a inconsistent state, we need to use a different
kono
parents: 19
diff changeset
936 counter here. */
kono
parents: 19
diff changeset
937 gomp_team_barrier_wait_final (&team->barrier);
kono
parents: 19
diff changeset
938 if (__builtin_expect (team->team_cancelled, 0))
kono
parents: 19
diff changeset
939 {
kono
parents: 19
diff changeset
940 struct gomp_work_share *ws = team->work_shares_to_free;
kono
parents: 19
diff changeset
941 do
kono
parents: 19
diff changeset
942 {
kono
parents: 19
diff changeset
943 struct gomp_work_share *next_ws = gomp_ptrlock_get (&ws->next_ws);
kono
parents: 19
diff changeset
944 if (next_ws == NULL)
kono
parents: 19
diff changeset
945 gomp_ptrlock_set (&ws->next_ws, ws);
kono
parents: 19
diff changeset
946 gomp_fini_work_share (ws);
kono
parents: 19
diff changeset
947 ws = next_ws;
kono
parents: 19
diff changeset
948 }
kono
parents: 19
diff changeset
949 while (ws != NULL);
kono
parents: 19
diff changeset
950 }
kono
parents: 19
diff changeset
951 else
kono
parents: 19
diff changeset
952 gomp_fini_work_share (thr->ts.work_share);
0
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 gomp_end_task ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
955 thr->ts = team->prev_ts;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
956
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
957 if (__builtin_expect (thr->ts.level != 0, 0))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
958 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
959 #ifdef HAVE_SYNC_BUILTINS
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
960 __sync_fetch_and_add (&gomp_managed_threads, 1L - team->nthreads);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
961 #else
111
kono
parents: 19
diff changeset
962 gomp_mutex_lock (&gomp_managed_threads_lock);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
963 gomp_managed_threads -= team->nthreads - 1L;
111
kono
parents: 19
diff changeset
964 gomp_mutex_unlock (&gomp_managed_threads_lock);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
965 #endif
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
966 /* This barrier has gomp_barrier_wait_last counterparts
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
967 and ensures the team can be safely destroyed. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
968 gomp_barrier_wait (&team->barrier);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
969 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
970
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
971 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
972 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
973 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
974 do
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
975 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
976 struct gomp_work_share *next_ws = ws->next_alloc;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
977 free (ws);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
978 ws = next_ws;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
979 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
980 while (ws != NULL);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
981 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
982 gomp_sem_destroy (&team->master_release);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
983
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
984 if (__builtin_expect (thr->ts.team != NULL, 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
985 || __builtin_expect (team->nthreads == 1, 0))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
986 free_team (team);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
987 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
988 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
989 struct gomp_thread_pool *pool = thr->thread_pool;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
990 if (pool->last_team)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
991 free_team (pool->last_team);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
992 pool->last_team = team;
111
kono
parents: 19
diff changeset
993 gomp_release_thread_pool (pool);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
994 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
995 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
996
111
kono
parents: 19
diff changeset
997 #ifdef LIBGOMP_USE_PTHREADS
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
998
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
999 /* Constructors for this file. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1000
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1001 static void __attribute__((constructor))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1002 initialize_team (void)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1003 {
111
kono
parents: 19
diff changeset
1004 #if !defined HAVE_TLS && !defined USE_EMUTLS
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1005 static struct gomp_thread initial_thread_tls_data;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1006
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1007 pthread_key_create (&gomp_tls_key, NULL);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1008 pthread_setspecific (gomp_tls_key, &initial_thread_tls_data);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1009 #endif
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1010
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1011 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
1012 gomp_fatal ("could not create thread pool destructor.");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1013 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1014
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1015 static void __attribute__((destructor))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1016 team_destructor (void)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1017 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1018 /* Without this dlclose on libgomp could lead to subsequent
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1019 crashes. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1020 pthread_key_delete (gomp_thread_destructor);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1021 }
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1022
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1023 /* Similar to gomp_free_pool_helper, but don't detach itself,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1024 gomp_pause_host will pthread_join those threads. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1025
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1026 static void
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1027 gomp_pause_pool_helper (void *thread_pool)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1028 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1029 struct gomp_thread *thr = gomp_thread ();
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1030 struct gomp_thread_pool *pool
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1031 = (struct gomp_thread_pool *) thread_pool;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1032 gomp_simple_barrier_wait_last (&pool->threads_dock);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1033 gomp_sem_destroy (&thr->release);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1034 thr->thread_pool = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1035 thr->task = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1036 pthread_exit (NULL);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1037 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1038
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1039 /* Free a thread pool and release its threads. Return non-zero on
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1040 failure. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1041
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1042 int
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1043 gomp_pause_host (void)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1044 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1045 struct gomp_thread *thr = gomp_thread ();
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1046 struct gomp_thread_pool *pool = thr->thread_pool;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1047 if (thr->ts.level)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1048 return -1;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1049 if (pool)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1050 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1051 if (pool->threads_used > 0)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1052 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1053 int i;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1054 pthread_t *thrs
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1055 = gomp_alloca (sizeof (pthread_t) * pool->threads_used);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1056 for (i = 1; i < pool->threads_used; i++)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1057 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1058 struct gomp_thread *nthr = pool->threads[i];
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1059 nthr->fn = gomp_pause_pool_helper;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1060 nthr->data = pool;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1061 thrs[i] = gomp_thread_to_pthread_t (nthr);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1062 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1063 /* This barrier undocks threads docked on pool->threads_dock. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1064 gomp_simple_barrier_wait (&pool->threads_dock);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1065 /* And this waits till all threads have called gomp_barrier_wait_last
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1066 in gomp_pause_pool_helper. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1067 gomp_simple_barrier_wait (&pool->threads_dock);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1068 /* Now it is safe to destroy the barrier and free the pool. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1069 gomp_simple_barrier_destroy (&pool->threads_dock);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1070
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1071 #ifdef HAVE_SYNC_BUILTINS
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1072 __sync_fetch_and_add (&gomp_managed_threads,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1073 1L - pool->threads_used);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1074 #else
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1075 gomp_mutex_lock (&gomp_managed_threads_lock);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1076 gomp_managed_threads -= pool->threads_used - 1L;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1077 gomp_mutex_unlock (&gomp_managed_threads_lock);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1078 #endif
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1079 for (i = 1; i < pool->threads_used; i++)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1080 pthread_join (thrs[i], NULL);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1081 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1082 if (pool->last_team)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1083 free_team (pool->last_team);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1084 #ifndef __nvptx__
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1085 team_free (pool->threads);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1086 team_free (pool);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1087 #endif
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1088 thr->thread_pool = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1089 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1090 return 0;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1091 }
111
kono
parents: 19
diff changeset
1092 #endif
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1093
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1094 struct gomp_task_icv *
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1095 gomp_new_icv (void)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1096 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1097 struct gomp_thread *thr = gomp_thread ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1098 struct gomp_task *task = gomp_malloc (sizeof (struct gomp_task));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1099 gomp_init_task (task, NULL, &gomp_global_icv);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1100 thr->task = task;
111
kono
parents: 19
diff changeset
1101 #ifdef LIBGOMP_USE_PTHREADS
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1102 pthread_setspecific (gomp_thread_destructor, thr);
111
kono
parents: 19
diff changeset
1103 #endif
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1104 return &task->icv;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1105 }