blob: 1807f5d14b9bb0061f2817ccea1721da4a34389a [file] [log] [blame]
sewardj85642922008-01-14 11:54:56 +00001/*
bart86562bd2009-02-16 19:43:56 +00002 This file is part of drd, a thread error detector.
sewardj85642922008-01-14 11:54:56 +00003
bart86562bd2009-02-16 19:43:56 +00004 Copyright (C) 2006-2009 Bart Van Assche <bart.vanassche@gmail.com>.
sewardj85642922008-01-14 11:54:56 +00005
6 This program is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License as
8 published by the Free Software Foundation; either version 2 of the
9 License, or (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307, USA.
20
21 The GNU General Public License is contained in the file COPYING.
22*/
23
24
25#include "drd_barrier.h"
bart28230a32008-02-29 17:27:03 +000026#include "drd_clientobj.h"
sewardj85642922008-01-14 11:54:56 +000027#include "drd_error.h"
28#include "drd_suppression.h"
sewardj85642922008-01-14 11:54:56 +000029#include "pub_tool_errormgr.h" // VG_(maybe_record_error)()
30#include "pub_tool_libcassert.h" // tl_assert()
31#include "pub_tool_libcprint.h" // VG_(printf)()
32#include "pub_tool_machine.h" // VG_(get_IP)()
33#include "pub_tool_mallocfree.h" // VG_(malloc)(), VG_(free)()
34#include "pub_tool_oset.h"
35#include "pub_tool_threadstate.h" // VG_(get_running_tid)()
36
37
barta8cf7652009-02-15 11:00:29 +000038/* Type definitions. */
sewardj85642922008-01-14 11:54:56 +000039
bart8ddef882008-03-09 08:48:01 +000040/** Information associated with one thread participating in a barrier. */
bartbebc5d62008-02-24 18:42:53 +000041struct barrier_thread_info
42{
43 UWord tid; // A DrdThreadId
44 Word iteration; // iteration of last pthread_barrier_wait()
45 // call thread tid participated in.
barta2b6e1b2008-03-17 18:32:39 +000046 Segment* sg[2]; // Segments of the last two
bartbebc5d62008-02-24 18:42:53 +000047 // pthread_barrier() calls by thread tid.
sewardj85642922008-01-14 11:54:56 +000048};
49
50
barta8cf7652009-02-15 11:00:29 +000051/* Local functions. */
bart28230a32008-02-29 17:27:03 +000052
barta8cf7652009-02-15 11:00:29 +000053static void DRD_(barrier_cleanup)(struct barrier_info* p);
54static const char* DRD_(barrier_get_typename)(struct barrier_info* const p);
55static const char* DRD_(barrier_type_name)(const BarrierT bt);
bart28230a32008-02-29 17:27:03 +000056
57
barta8cf7652009-02-15 11:00:29 +000058/* Local variables. */
sewardj85642922008-01-14 11:54:56 +000059
barta8cf7652009-02-15 11:00:29 +000060static Bool DRD_(s_trace_barrier) = False;
61static ULong DRD_(s_barrier_segment_creation_count);
sewardj85642922008-01-14 11:54:56 +000062
63
barta8cf7652009-02-15 11:00:29 +000064/* Function definitions. */
sewardj85642922008-01-14 11:54:56 +000065
barta8cf7652009-02-15 11:00:29 +000066void DRD_(barrier_set_trace)(const Bool trace_barrier)
sewardj85642922008-01-14 11:54:56 +000067{
barta8cf7652009-02-15 11:00:29 +000068 DRD_(s_trace_barrier) = trace_barrier;
sewardj85642922008-01-14 11:54:56 +000069}
70
bartbebc5d62008-02-24 18:42:53 +000071/** Initialize the structure *p with the specified thread ID and iteration
72 * information. */
barta8cf7652009-02-15 11:00:29 +000073static
74void DRD_(barrier_thread_initialize)(struct barrier_thread_info* const p,
75 const DrdThreadId tid,
76 const Word iteration)
sewardj85642922008-01-14 11:54:56 +000077{
78 p->tid = tid;
79 p->iteration = iteration;
barta2b6e1b2008-03-17 18:32:39 +000080 p->sg[0] = 0;
81 p->sg[1] = 0;
sewardj85642922008-01-14 11:54:56 +000082}
83
bartbebc5d62008-02-24 18:42:53 +000084/** Deallocate the memory that was allocated in barrier_thread_initialize(). */
barta8cf7652009-02-15 11:00:29 +000085static void DRD_(barrier_thread_destroy)(struct barrier_thread_info* const p)
sewardj85642922008-01-14 11:54:56 +000086{
bart22f74572008-07-07 08:17:55 +000087 tl_assert(p);
bart62ada3f2009-02-14 17:19:58 +000088 DRD_(sg_put)(p->sg[0]);
89 DRD_(sg_put)(p->sg[1]);
sewardj85642922008-01-14 11:54:56 +000090}
91
bartbebc5d62008-02-24 18:42:53 +000092/** Initialize the structure *p with the specified client-side barrier address,
93 * barrier object size and number of participants in each barrier. */
sewardj85642922008-01-14 11:54:56 +000094static
barta8cf7652009-02-15 11:00:29 +000095void DRD_(barrier_initialize)(struct barrier_info* const p,
96 const Addr barrier,
97 const BarrierT barrier_type,
98 const Word count)
sewardj85642922008-01-14 11:54:56 +000099{
100 tl_assert(barrier != 0);
bart0268dfa2008-03-11 20:10:21 +0000101 tl_assert(barrier_type == pthread_barrier || barrier_type == gomp_barrier);
bart28230a32008-02-29 17:27:03 +0000102 tl_assert(p->a1 == barrier);
sewardj85642922008-01-14 11:54:56 +0000103
barta8cf7652009-02-15 11:00:29 +0000104 p->cleanup = (void(*)(DrdClientobj*))DRD_(barrier_cleanup);
bart306527d2008-03-12 17:23:07 +0000105 p->barrier_type = barrier_type;
bartbebc5d62008-02-24 18:42:53 +0000106 p->count = count;
107 p->pre_iteration = 0;
108 p->post_iteration = 0;
109 p->pre_waiters_left = count;
110 p->post_waiters_left = count;
sewardj85642922008-01-14 11:54:56 +0000111 tl_assert(sizeof(((struct barrier_thread_info*)0)->tid) == sizeof(Word));
112 tl_assert(sizeof(((struct barrier_thread_info*)0)->tid)
113 >= sizeof(DrdThreadId));
sewardj9c606bd2008-09-18 18:12:50 +0000114 p->oset = VG_(OSetGen_Create)(0, 0, VG_(malloc), "drd.barrier.bi.1",
115 VG_(free));
sewardj85642922008-01-14 11:54:56 +0000116}
117
bart195e41f2009-02-15 11:34:57 +0000118/**
119 * Deallocate the memory allocated by barrier_initialize() and in p->oset.
120 * Called by clientobj_destroy().
bart28230a32008-02-29 17:27:03 +0000121 */
barta8cf7652009-02-15 11:00:29 +0000122void DRD_(barrier_cleanup)(struct barrier_info* p)
sewardj85642922008-01-14 11:54:56 +0000123{
124 struct barrier_thread_info* q;
125
126 tl_assert(p);
127
bart306527d2008-03-12 17:23:07 +0000128 if (p->pre_waiters_left != p->count)
bart28230a32008-02-29 17:27:03 +0000129 {
bart3b1ee452008-02-29 19:28:15 +0000130 BarrierErrInfo bei = { p->a1 };
131 VG_(maybe_record_error)(VG_(get_running_tid)(),
132 BarrierErr,
133 VG_(get_IP)(VG_(get_running_tid)()),
134 "Destruction of barrier that is being waited"
135 " upon",
136 &bei);
bart28230a32008-02-29 17:27:03 +0000137 }
sewardj85642922008-01-14 11:54:56 +0000138
139 VG_(OSetGen_ResetIter)(p->oset);
140 for ( ; (q = VG_(OSetGen_Next)(p->oset)) != 0; )
141 {
barta8cf7652009-02-15 11:00:29 +0000142 DRD_(barrier_thread_destroy)(q);
sewardj85642922008-01-14 11:54:56 +0000143 }
144 VG_(OSetGen_Destroy)(p->oset);
sewardj85642922008-01-14 11:54:56 +0000145}
146
bartbebc5d62008-02-24 18:42:53 +0000147/** Look up the client-side barrier address barrier in s_barrier[]. If not
148 * found, add it. */
sewardj85642922008-01-14 11:54:56 +0000149static
150struct barrier_info*
barta8cf7652009-02-15 11:00:29 +0000151DRD_(barrier_get_or_allocate)(const Addr barrier,
152 const BarrierT barrier_type, const Word count)
sewardj85642922008-01-14 11:54:56 +0000153{
bart28230a32008-02-29 17:27:03 +0000154 struct barrier_info *p;
sewardj85642922008-01-14 11:54:56 +0000155
bart0268dfa2008-03-11 20:10:21 +0000156 tl_assert(barrier_type == pthread_barrier || barrier_type == gomp_barrier);
157
bart28230a32008-02-29 17:27:03 +0000158 tl_assert(offsetof(DrdClientobj, barrier) == 0);
bart195e41f2009-02-15 11:34:57 +0000159 p = &(DRD_(clientobj_get)(barrier, ClientBarrier)->barrier);
bart28230a32008-02-29 17:27:03 +0000160 if (p == 0)
sewardj85642922008-01-14 11:54:56 +0000161 {
bart195e41f2009-02-15 11:34:57 +0000162 p = &(DRD_(clientobj_add)(barrier, ClientBarrier)->barrier);
barta8cf7652009-02-15 11:00:29 +0000163 DRD_(barrier_initialize)(p, barrier, barrier_type, count);
sewardj85642922008-01-14 11:54:56 +0000164 }
bart28230a32008-02-29 17:27:03 +0000165 return p;
166}
167
168/** Look up the address of the information associated with the client-side
169 * barrier object. */
barta8cf7652009-02-15 11:00:29 +0000170static struct barrier_info* DRD_(barrier_get)(const Addr barrier)
bart28230a32008-02-29 17:27:03 +0000171{
172 tl_assert(offsetof(DrdClientobj, barrier) == 0);
bart195e41f2009-02-15 11:34:57 +0000173 return &(DRD_(clientobj_get)(barrier, ClientBarrier)->barrier);
sewardj85642922008-01-14 11:54:56 +0000174}
175
bartbebc5d62008-02-24 18:42:53 +0000176/** Initialize a barrier with client address barrier, client size size, and
bart28230a32008-02-29 17:27:03 +0000177 * where count threads participate in each barrier.
178 * Called before pthread_barrier_init().
179 */
barta8cf7652009-02-15 11:00:29 +0000180void DRD_(barrier_init)(const Addr barrier,
181 const BarrierT barrier_type, const Word count,
182 const Bool reinitialization)
sewardj85642922008-01-14 11:54:56 +0000183{
bart306527d2008-03-12 17:23:07 +0000184 struct barrier_info* p;
185
186 tl_assert(barrier_type == pthread_barrier || barrier_type == gomp_barrier);
187
bartfcff0b92008-11-17 17:35:26 +0000188 if (count == 0)
189 {
190 BarrierErrInfo bei = { barrier };
191 VG_(maybe_record_error)(VG_(get_running_tid)(),
192 BarrierErr,
193 VG_(get_IP)(VG_(get_running_tid)()),
194 "pthread_barrier_init: 'count' argument is zero",
195 &bei);
196 }
197
bartd9e39ec2008-06-28 15:03:26 +0000198 if (! reinitialization && barrier_type == pthread_barrier)
199 {
barta8cf7652009-02-15 11:00:29 +0000200 p = DRD_(barrier_get)(barrier);
bartd9e39ec2008-06-28 15:03:26 +0000201 if (p)
202 {
203 BarrierErrInfo bei = { barrier };
204 VG_(maybe_record_error)(VG_(get_running_tid)(),
205 BarrierErr,
206 VG_(get_IP)(VG_(get_running_tid)()),
bartfcff0b92008-11-17 17:35:26 +0000207 "Barrier reinitialization",
bartd9e39ec2008-06-28 15:03:26 +0000208 &bei);
209 }
210 }
barta8cf7652009-02-15 11:00:29 +0000211 p = DRD_(barrier_get_or_allocate)(barrier, barrier_type, count);
bart306527d2008-03-12 17:23:07 +0000212
barta8cf7652009-02-15 11:00:29 +0000213 if (DRD_(s_trace_barrier))
bart3b1ee452008-02-29 19:28:15 +0000214 {
bart306527d2008-03-12 17:23:07 +0000215 if (reinitialization)
216 {
217 VG_(message)(Vg_UserMsg,
barta2b6e1b2008-03-17 18:32:39 +0000218 "[%d/%d] barrier_reinit %s 0x%lx count %ld -> %ld",
bart306527d2008-03-12 17:23:07 +0000219 VG_(get_running_tid)(),
bart62a784c2009-02-15 13:11:14 +0000220 DRD_(thread_get_running_tid)(),
barta8cf7652009-02-15 11:00:29 +0000221 DRD_(barrier_get_typename)(p),
bart306527d2008-03-12 17:23:07 +0000222 barrier,
223 p->count,
224 count);
225 }
226 else
227 {
228 VG_(message)(Vg_UserMsg,
229 "[%d/%d] barrier_init %s 0x%lx",
230 VG_(get_running_tid)(),
bart62a784c2009-02-15 13:11:14 +0000231 DRD_(thread_get_running_tid)(),
barta8cf7652009-02-15 11:00:29 +0000232 DRD_(barrier_get_typename)(p),
bart306527d2008-03-12 17:23:07 +0000233 barrier);
234 }
bart3b1ee452008-02-29 19:28:15 +0000235 }
bart306527d2008-03-12 17:23:07 +0000236
237 if (reinitialization && p->count != count)
238 {
239 if (p->pre_waiters_left != p->count || p->post_waiters_left != p->count)
240 {
bart195a3982008-07-01 13:15:31 +0000241 BarrierErrInfo bei = { p->a1 };
242 VG_(maybe_record_error)(VG_(get_running_tid)(),
243 BarrierErr,
244 VG_(get_IP)(VG_(get_running_tid)()),
245 "Reinitialization of barrier with active"
246 " waiters",
247 &bei);
bart306527d2008-03-12 17:23:07 +0000248 }
249 p->count = count;
250 }
sewardj85642922008-01-14 11:54:56 +0000251}
252
bart28230a32008-02-29 17:27:03 +0000253/** Called after pthread_barrier_destroy(). */
barta8cf7652009-02-15 11:00:29 +0000254void DRD_(barrier_destroy)(const Addr barrier, const BarrierT barrier_type)
sewardj85642922008-01-14 11:54:56 +0000255{
bart72b751c2008-03-01 13:44:24 +0000256 struct barrier_info* p;
257
barta8cf7652009-02-15 11:00:29 +0000258 p = DRD_(barrier_get)(barrier);
bart306527d2008-03-12 17:23:07 +0000259
barta8cf7652009-02-15 11:00:29 +0000260 if (DRD_(s_trace_barrier))
bart3b1ee452008-02-29 19:28:15 +0000261 {
262 VG_(message)(Vg_UserMsg,
bart306527d2008-03-12 17:23:07 +0000263 "[%d/%d] barrier_destroy %s 0x%lx",
bart3b1ee452008-02-29 19:28:15 +0000264 VG_(get_running_tid)(),
bart62a784c2009-02-15 13:11:14 +0000265 DRD_(thread_get_running_tid)(),
barta8cf7652009-02-15 11:00:29 +0000266 DRD_(barrier_get_typename)(p),
bart72b751c2008-03-01 13:44:24 +0000267 barrier);
bart3b1ee452008-02-29 19:28:15 +0000268 }
bart72b751c2008-03-01 13:44:24 +0000269
bart72b751c2008-03-01 13:44:24 +0000270 if (p == 0)
271 {
272 GenericErrInfo GEI;
273 VG_(maybe_record_error)(VG_(get_running_tid)(),
274 GenericErr,
275 VG_(get_IP)(VG_(get_running_tid)()),
276 "Not a barrier",
277 &GEI);
278 return;
279 }
280
bart195a3982008-07-01 13:15:31 +0000281 if (p->pre_waiters_left != p->count || p->post_waiters_left != p->count)
282 {
283 BarrierErrInfo bei = { p->a1 };
284 VG_(maybe_record_error)(VG_(get_running_tid)(),
285 BarrierErr,
286 VG_(get_IP)(VG_(get_running_tid)()),
287 "Destruction of a barrier with active waiters",
288 &bei);
289 }
290
bart195e41f2009-02-15 11:34:57 +0000291 DRD_(clientobj_remove)(p->a1, ClientBarrier);
sewardj85642922008-01-14 11:54:56 +0000292}
293
bart28230a32008-02-29 17:27:03 +0000294/** Called before pthread_barrier_wait(). */
barta8cf7652009-02-15 11:00:29 +0000295void DRD_(barrier_pre_wait)(const DrdThreadId tid, const Addr barrier,
296 const BarrierT barrier_type)
sewardj85642922008-01-14 11:54:56 +0000297{
298 struct barrier_info* p;
299 struct barrier_thread_info* q;
300 const UWord word_tid = tid;
301
barta8cf7652009-02-15 11:00:29 +0000302 p = DRD_(barrier_get)(barrier);
bartc68bd602008-03-16 10:04:58 +0000303 if (p == 0 && barrier_type == gomp_barrier)
304 {
bart654013c2008-06-23 12:41:00 +0000305 VG_(message)(Vg_UserMsg, "");
bartc68bd602008-03-16 10:04:58 +0000306 VG_(message)(Vg_UserMsg,
307 "Please verify whether gcc has been configured"
308 " with option --disable-linux-futex.");
309 VG_(message)(Vg_UserMsg,
310 "See also the section about OpenMP in the DRD manual.");
bart654013c2008-06-23 12:41:00 +0000311 VG_(message)(Vg_UserMsg, "");
bartc68bd602008-03-16 10:04:58 +0000312 }
sewardj85642922008-01-14 11:54:56 +0000313 tl_assert(p);
314
barta8cf7652009-02-15 11:00:29 +0000315 if (DRD_(s_trace_barrier))
sewardj85642922008-01-14 11:54:56 +0000316 {
bart3b1ee452008-02-29 19:28:15 +0000317 VG_(message)(Vg_UserMsg,
barta2b6e1b2008-03-17 18:32:39 +0000318 "[%d/%d] barrier_pre_wait %s 0x%lx iteration %ld",
bart3b1ee452008-02-29 19:28:15 +0000319 VG_(get_running_tid)(),
bart62a784c2009-02-15 13:11:14 +0000320 DRD_(thread_get_running_tid)(),
barta8cf7652009-02-15 11:00:29 +0000321 DRD_(barrier_get_typename)(p),
bart3b1ee452008-02-29 19:28:15 +0000322 barrier,
323 p->pre_iteration);
sewardj85642922008-01-14 11:54:56 +0000324 }
325
sewardj85642922008-01-14 11:54:56 +0000326 q = VG_(OSetGen_Lookup)(p->oset, &word_tid);
327 if (q == 0)
328 {
329 q = VG_(OSetGen_AllocNode)(p->oset, sizeof(*q));
barta8cf7652009-02-15 11:00:29 +0000330 DRD_(barrier_thread_initialize)(q, tid, p->pre_iteration);
sewardj85642922008-01-14 11:54:56 +0000331 VG_(OSetGen_Insert)(p->oset, q);
332 tl_assert(VG_(OSetGen_Lookup)(p->oset, &word_tid) == q);
333 }
bart62a784c2009-02-15 13:11:14 +0000334 DRD_(thread_get_latest_segment)(&q->sg[p->pre_iteration], tid);
bartbebc5d62008-02-24 18:42:53 +0000335
336 if (--p->pre_waiters_left <= 0)
337 {
338 p->pre_iteration = 1 - p->pre_iteration;
339 p->pre_waiters_left = p->count;
340 }
sewardj85642922008-01-14 11:54:56 +0000341}
342
bart28230a32008-02-29 17:27:03 +0000343/** Called after pthread_barrier_wait(). */
barta8cf7652009-02-15 11:00:29 +0000344void DRD_(barrier_post_wait)(const DrdThreadId tid, const Addr barrier,
345 const BarrierT barrier_type, const Bool waited)
sewardj85642922008-01-14 11:54:56 +0000346{
bart3b1ee452008-02-29 19:28:15 +0000347 struct barrier_info* p;
sewardj85642922008-01-14 11:54:56 +0000348
barta8cf7652009-02-15 11:00:29 +0000349 p = DRD_(barrier_get)(barrier);
bartbebc5d62008-02-24 18:42:53 +0000350
barta8cf7652009-02-15 11:00:29 +0000351 if (DRD_(s_trace_barrier))
sewardj85642922008-01-14 11:54:56 +0000352 {
bart3b1ee452008-02-29 19:28:15 +0000353 VG_(message)(Vg_UserMsg,
barta2b6e1b2008-03-17 18:32:39 +0000354 "[%d/%d] barrier_post_wait %s 0x%lx iteration %ld",
bart3b1ee452008-02-29 19:28:15 +0000355 VG_(get_running_tid)(),
356 tid,
barta8cf7652009-02-15 11:00:29 +0000357 p ? DRD_(barrier_get_typename)(p) : "(?)",
bart3b1ee452008-02-29 19:28:15 +0000358 barrier,
bart306527d2008-03-12 17:23:07 +0000359 p ? p->post_iteration : -1);
sewardj85642922008-01-14 11:54:56 +0000360 }
361
bart306527d2008-03-12 17:23:07 +0000362 /* If p == 0, this means that the barrier has been destroyed after */
363 /* *_barrier_wait() returned and before this function was called. Just */
364 /* return in that case. */
365 if (p == 0)
366 return;
367
sewardj85642922008-01-14 11:54:56 +0000368 if (waited)
369 {
370 const UWord word_tid = tid;
371 struct barrier_thread_info* q;
372 struct barrier_thread_info* r;
373
sewardj85642922008-01-14 11:54:56 +0000374 q = VG_(OSetGen_Lookup)(p->oset, &word_tid);
bart195a3982008-07-01 13:15:31 +0000375 if (q == 0)
376 {
377 BarrierErrInfo bei = { p->a1 };
378 VG_(maybe_record_error)(VG_(get_running_tid)(),
379 BarrierErr,
380 VG_(get_IP)(VG_(get_running_tid)()),
381 "Error in barrier implementation"
382 " -- barrier_wait() started before"
383 " barrier_destroy() and finished after"
384 " barrier_destroy()",
385 &bei);
386
387 q = VG_(OSetGen_AllocNode)(p->oset, sizeof(*q));
barta8cf7652009-02-15 11:00:29 +0000388 DRD_(barrier_thread_initialize)(q, tid, p->pre_iteration);
bart195a3982008-07-01 13:15:31 +0000389 VG_(OSetGen_Insert)(p->oset, q);
390 tl_assert(VG_(OSetGen_Lookup)(p->oset, &word_tid) == q);
391 }
sewardj85642922008-01-14 11:54:56 +0000392 VG_(OSetGen_ResetIter)(p->oset);
393 for ( ; (r = VG_(OSetGen_Next)(p->oset)) != 0; )
394 {
395 if (r != q)
396 {
barta2b6e1b2008-03-17 18:32:39 +0000397 tl_assert(r->sg[p->post_iteration]);
bart62a784c2009-02-15 13:11:14 +0000398 DRD_(thread_combine_vc2)(tid, &r->sg[p->post_iteration]->vc);
sewardj85642922008-01-14 11:54:56 +0000399 }
400 }
bartbebc5d62008-02-24 18:42:53 +0000401
bart62a784c2009-02-15 13:11:14 +0000402 DRD_(thread_new_segment)(tid);
barta8cf7652009-02-15 11:00:29 +0000403 DRD_(s_barrier_segment_creation_count)++;
bartbebc5d62008-02-24 18:42:53 +0000404
405 if (--p->post_waiters_left <= 0)
406 {
407 p->post_iteration = 1 - p->post_iteration;
408 p->post_waiters_left = p->count;
409 }
sewardj85642922008-01-14 11:54:56 +0000410 }
411}
412
bartbebc5d62008-02-24 18:42:53 +0000413/** Call this function when thread tid stops to exist. */
barta8cf7652009-02-15 11:00:29 +0000414void DRD_(barrier_thread_delete)(const DrdThreadId tid)
sewardj85642922008-01-14 11:54:56 +0000415{
bart28230a32008-02-29 17:27:03 +0000416 struct barrier_info* p;
sewardj85642922008-01-14 11:54:56 +0000417
bart195e41f2009-02-15 11:34:57 +0000418 DRD_(clientobj_resetiter)();
419 for ( ; (p = &(DRD_(clientobj_next)(ClientBarrier)->barrier)) != 0; )
sewardj85642922008-01-14 11:54:56 +0000420 {
bart28230a32008-02-29 17:27:03 +0000421 struct barrier_thread_info* q;
422 const UWord word_tid = tid;
423 q = VG_(OSetGen_Remove)(p->oset, &word_tid);
bart7f912c02008-07-07 08:45:55 +0000424 /* q is only non-zero if the barrier object has been used by thread tid
425 * after the barrier_init() call and before the thread finished.
426 */
bart22f74572008-07-07 08:17:55 +0000427 if (q)
428 {
barta8cf7652009-02-15 11:00:29 +0000429 DRD_(barrier_thread_destroy)(q);
bart22f74572008-07-07 08:17:55 +0000430 VG_(OSetGen_FreeNode)(p->oset, q);
431 }
sewardj85642922008-01-14 11:54:56 +0000432 }
433}
bart306527d2008-03-12 17:23:07 +0000434
barta8cf7652009-02-15 11:00:29 +0000435static const char* DRD_(barrier_get_typename)(struct barrier_info* const p)
bart306527d2008-03-12 17:23:07 +0000436{
437 tl_assert(p);
438
barta8cf7652009-02-15 11:00:29 +0000439 return DRD_(barrier_type_name)(p->barrier_type);
bart306527d2008-03-12 17:23:07 +0000440}
441
barta8cf7652009-02-15 11:00:29 +0000442static const char* DRD_(barrier_type_name)(const BarrierT bt)
bart306527d2008-03-12 17:23:07 +0000443{
444 switch (bt)
445 {
446 case pthread_barrier:
447 return "pthread barrier";
448 case gomp_barrier:
449 return "gomp barrier";
450 }
451 return "?";
452}
bart6bbefaf2008-04-19 15:16:45 +0000453
barta8cf7652009-02-15 11:00:29 +0000454ULong DRD_(get_barrier_segment_creation_count)(void)
bart6bbefaf2008-04-19 15:16:45 +0000455{
barta8cf7652009-02-15 11:00:29 +0000456 return DRD_(s_barrier_segment_creation_count);
bart6bbefaf2008-04-19 15:16:45 +0000457}