blob: 0e2e80c7946f0edbe4ee53ecea04acd28cf2d911 [file] [log] [blame]
sewardj85642922008-01-14 11:54:56 +00001/*
2 This file is part of drd, a data race detector.
3
4 Copyright (C) 2006-2008 Bart Van Assche
5 bart.vanassche@gmail.com
6
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2 of the
10 License, or (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20 02111-1307, USA.
21
22 The GNU General Public License is contained in the file COPYING.
23*/
24
25
26#include "drd_barrier.h"
bart28230a32008-02-29 17:27:03 +000027#include "drd_clientobj.h"
sewardj85642922008-01-14 11:54:56 +000028#include "drd_error.h"
29#include "drd_suppression.h"
sewardj85642922008-01-14 11:54:56 +000030#include "pub_tool_errormgr.h" // VG_(maybe_record_error)()
31#include "pub_tool_libcassert.h" // tl_assert()
32#include "pub_tool_libcprint.h" // VG_(printf)()
33#include "pub_tool_machine.h" // VG_(get_IP)()
34#include "pub_tool_mallocfree.h" // VG_(malloc)(), VG_(free)()
35#include "pub_tool_oset.h"
36#include "pub_tool_threadstate.h" // VG_(get_running_tid)()
37
38
barta8cf7652009-02-15 11:00:29 +000039/* Type definitions. */
sewardj85642922008-01-14 11:54:56 +000040
bart8ddef882008-03-09 08:48:01 +000041/** Information associated with one thread participating in a barrier. */
bartbebc5d62008-02-24 18:42:53 +000042struct barrier_thread_info
43{
44 UWord tid; // A DrdThreadId
45 Word iteration; // iteration of last pthread_barrier_wait()
46 // call thread tid participated in.
barta2b6e1b2008-03-17 18:32:39 +000047 Segment* sg[2]; // Segments of the last two
bartbebc5d62008-02-24 18:42:53 +000048 // pthread_barrier() calls by thread tid.
sewardj85642922008-01-14 11:54:56 +000049};
50
51
barta8cf7652009-02-15 11:00:29 +000052/* Local functions. */
bart28230a32008-02-29 17:27:03 +000053
barta8cf7652009-02-15 11:00:29 +000054static void DRD_(barrier_cleanup)(struct barrier_info* p);
55static const char* DRD_(barrier_get_typename)(struct barrier_info* const p);
56static const char* DRD_(barrier_type_name)(const BarrierT bt);
bart28230a32008-02-29 17:27:03 +000057
58
barta8cf7652009-02-15 11:00:29 +000059/* Local variables. */
sewardj85642922008-01-14 11:54:56 +000060
barta8cf7652009-02-15 11:00:29 +000061static Bool DRD_(s_trace_barrier) = False;
62static ULong DRD_(s_barrier_segment_creation_count);
sewardj85642922008-01-14 11:54:56 +000063
64
barta8cf7652009-02-15 11:00:29 +000065/* Function definitions. */
sewardj85642922008-01-14 11:54:56 +000066
barta8cf7652009-02-15 11:00:29 +000067void DRD_(barrier_set_trace)(const Bool trace_barrier)
sewardj85642922008-01-14 11:54:56 +000068{
barta8cf7652009-02-15 11:00:29 +000069 DRD_(s_trace_barrier) = trace_barrier;
sewardj85642922008-01-14 11:54:56 +000070}
71
bartbebc5d62008-02-24 18:42:53 +000072/** Initialize the structure *p with the specified thread ID and iteration
73 * information. */
barta8cf7652009-02-15 11:00:29 +000074static
75void DRD_(barrier_thread_initialize)(struct barrier_thread_info* const p,
76 const DrdThreadId tid,
77 const Word iteration)
sewardj85642922008-01-14 11:54:56 +000078{
79 p->tid = tid;
80 p->iteration = iteration;
barta2b6e1b2008-03-17 18:32:39 +000081 p->sg[0] = 0;
82 p->sg[1] = 0;
sewardj85642922008-01-14 11:54:56 +000083}
84
bartbebc5d62008-02-24 18:42:53 +000085/** Deallocate the memory that was allocated in barrier_thread_initialize(). */
barta8cf7652009-02-15 11:00:29 +000086static void DRD_(barrier_thread_destroy)(struct barrier_thread_info* const p)
sewardj85642922008-01-14 11:54:56 +000087{
bart22f74572008-07-07 08:17:55 +000088 tl_assert(p);
bart62ada3f2009-02-14 17:19:58 +000089 DRD_(sg_put)(p->sg[0]);
90 DRD_(sg_put)(p->sg[1]);
sewardj85642922008-01-14 11:54:56 +000091}
92
bartbebc5d62008-02-24 18:42:53 +000093/** Initialize the structure *p with the specified client-side barrier address,
94 * barrier object size and number of participants in each barrier. */
sewardj85642922008-01-14 11:54:56 +000095static
barta8cf7652009-02-15 11:00:29 +000096void DRD_(barrier_initialize)(struct barrier_info* const p,
97 const Addr barrier,
98 const BarrierT barrier_type,
99 const Word count)
sewardj85642922008-01-14 11:54:56 +0000100{
101 tl_assert(barrier != 0);
bart0268dfa2008-03-11 20:10:21 +0000102 tl_assert(barrier_type == pthread_barrier || barrier_type == gomp_barrier);
bart28230a32008-02-29 17:27:03 +0000103 tl_assert(p->a1 == barrier);
sewardj85642922008-01-14 11:54:56 +0000104
barta8cf7652009-02-15 11:00:29 +0000105 p->cleanup = (void(*)(DrdClientobj*))DRD_(barrier_cleanup);
bart306527d2008-03-12 17:23:07 +0000106 p->barrier_type = barrier_type;
bartbebc5d62008-02-24 18:42:53 +0000107 p->count = count;
108 p->pre_iteration = 0;
109 p->post_iteration = 0;
110 p->pre_waiters_left = count;
111 p->post_waiters_left = count;
sewardj85642922008-01-14 11:54:56 +0000112 tl_assert(sizeof(((struct barrier_thread_info*)0)->tid) == sizeof(Word));
113 tl_assert(sizeof(((struct barrier_thread_info*)0)->tid)
114 >= sizeof(DrdThreadId));
sewardj9c606bd2008-09-18 18:12:50 +0000115 p->oset = VG_(OSetGen_Create)(0, 0, VG_(malloc), "drd.barrier.bi.1",
116 VG_(free));
sewardj85642922008-01-14 11:54:56 +0000117}
118
bart195e41f2009-02-15 11:34:57 +0000119/**
120 * Deallocate the memory allocated by barrier_initialize() and in p->oset.
121 * Called by clientobj_destroy().
bart28230a32008-02-29 17:27:03 +0000122 */
barta8cf7652009-02-15 11:00:29 +0000123void DRD_(barrier_cleanup)(struct barrier_info* p)
sewardj85642922008-01-14 11:54:56 +0000124{
125 struct barrier_thread_info* q;
126
127 tl_assert(p);
128
bart306527d2008-03-12 17:23:07 +0000129 if (p->pre_waiters_left != p->count)
bart28230a32008-02-29 17:27:03 +0000130 {
bart3b1ee452008-02-29 19:28:15 +0000131 BarrierErrInfo bei = { p->a1 };
132 VG_(maybe_record_error)(VG_(get_running_tid)(),
133 BarrierErr,
134 VG_(get_IP)(VG_(get_running_tid)()),
135 "Destruction of barrier that is being waited"
136 " upon",
137 &bei);
bart28230a32008-02-29 17:27:03 +0000138 }
sewardj85642922008-01-14 11:54:56 +0000139
140 VG_(OSetGen_ResetIter)(p->oset);
141 for ( ; (q = VG_(OSetGen_Next)(p->oset)) != 0; )
142 {
barta8cf7652009-02-15 11:00:29 +0000143 DRD_(barrier_thread_destroy)(q);
sewardj85642922008-01-14 11:54:56 +0000144 }
145 VG_(OSetGen_Destroy)(p->oset);
sewardj85642922008-01-14 11:54:56 +0000146}
147
bartbebc5d62008-02-24 18:42:53 +0000148/** Look up the client-side barrier address barrier in s_barrier[]. If not
149 * found, add it. */
sewardj85642922008-01-14 11:54:56 +0000150static
151struct barrier_info*
barta8cf7652009-02-15 11:00:29 +0000152DRD_(barrier_get_or_allocate)(const Addr barrier,
153 const BarrierT barrier_type, const Word count)
sewardj85642922008-01-14 11:54:56 +0000154{
bart28230a32008-02-29 17:27:03 +0000155 struct barrier_info *p;
sewardj85642922008-01-14 11:54:56 +0000156
bart0268dfa2008-03-11 20:10:21 +0000157 tl_assert(barrier_type == pthread_barrier || barrier_type == gomp_barrier);
158
bart28230a32008-02-29 17:27:03 +0000159 tl_assert(offsetof(DrdClientobj, barrier) == 0);
bart195e41f2009-02-15 11:34:57 +0000160 p = &(DRD_(clientobj_get)(barrier, ClientBarrier)->barrier);
bart28230a32008-02-29 17:27:03 +0000161 if (p == 0)
sewardj85642922008-01-14 11:54:56 +0000162 {
bart195e41f2009-02-15 11:34:57 +0000163 p = &(DRD_(clientobj_add)(barrier, ClientBarrier)->barrier);
barta8cf7652009-02-15 11:00:29 +0000164 DRD_(barrier_initialize)(p, barrier, barrier_type, count);
sewardj85642922008-01-14 11:54:56 +0000165 }
bart28230a32008-02-29 17:27:03 +0000166 return p;
167}
168
169/** Look up the address of the information associated with the client-side
170 * barrier object. */
barta8cf7652009-02-15 11:00:29 +0000171static struct barrier_info* DRD_(barrier_get)(const Addr barrier)
bart28230a32008-02-29 17:27:03 +0000172{
173 tl_assert(offsetof(DrdClientobj, barrier) == 0);
bart195e41f2009-02-15 11:34:57 +0000174 return &(DRD_(clientobj_get)(barrier, ClientBarrier)->barrier);
sewardj85642922008-01-14 11:54:56 +0000175}
176
bartbebc5d62008-02-24 18:42:53 +0000177/** Initialize a barrier with client address barrier, client size size, and
bart28230a32008-02-29 17:27:03 +0000178 * where count threads participate in each barrier.
179 * Called before pthread_barrier_init().
180 */
barta8cf7652009-02-15 11:00:29 +0000181void DRD_(barrier_init)(const Addr barrier,
182 const BarrierT barrier_type, const Word count,
183 const Bool reinitialization)
sewardj85642922008-01-14 11:54:56 +0000184{
bart306527d2008-03-12 17:23:07 +0000185 struct barrier_info* p;
186
187 tl_assert(barrier_type == pthread_barrier || barrier_type == gomp_barrier);
188
bartfcff0b92008-11-17 17:35:26 +0000189 if (count == 0)
190 {
191 BarrierErrInfo bei = { barrier };
192 VG_(maybe_record_error)(VG_(get_running_tid)(),
193 BarrierErr,
194 VG_(get_IP)(VG_(get_running_tid)()),
195 "pthread_barrier_init: 'count' argument is zero",
196 &bei);
197 }
198
bartd9e39ec2008-06-28 15:03:26 +0000199 if (! reinitialization && barrier_type == pthread_barrier)
200 {
barta8cf7652009-02-15 11:00:29 +0000201 p = DRD_(barrier_get)(barrier);
bartd9e39ec2008-06-28 15:03:26 +0000202 if (p)
203 {
204 BarrierErrInfo bei = { barrier };
205 VG_(maybe_record_error)(VG_(get_running_tid)(),
206 BarrierErr,
207 VG_(get_IP)(VG_(get_running_tid)()),
bartfcff0b92008-11-17 17:35:26 +0000208 "Barrier reinitialization",
bartd9e39ec2008-06-28 15:03:26 +0000209 &bei);
210 }
211 }
barta8cf7652009-02-15 11:00:29 +0000212 p = DRD_(barrier_get_or_allocate)(barrier, barrier_type, count);
bart306527d2008-03-12 17:23:07 +0000213
barta8cf7652009-02-15 11:00:29 +0000214 if (DRD_(s_trace_barrier))
bart3b1ee452008-02-29 19:28:15 +0000215 {
bart306527d2008-03-12 17:23:07 +0000216 if (reinitialization)
217 {
218 VG_(message)(Vg_UserMsg,
barta2b6e1b2008-03-17 18:32:39 +0000219 "[%d/%d] barrier_reinit %s 0x%lx count %ld -> %ld",
bart306527d2008-03-12 17:23:07 +0000220 VG_(get_running_tid)(),
221 thread_get_running_tid(),
barta8cf7652009-02-15 11:00:29 +0000222 DRD_(barrier_get_typename)(p),
bart306527d2008-03-12 17:23:07 +0000223 barrier,
224 p->count,
225 count);
226 }
227 else
228 {
229 VG_(message)(Vg_UserMsg,
230 "[%d/%d] barrier_init %s 0x%lx",
231 VG_(get_running_tid)(),
232 thread_get_running_tid(),
barta8cf7652009-02-15 11:00:29 +0000233 DRD_(barrier_get_typename)(p),
bart306527d2008-03-12 17:23:07 +0000234 barrier);
235 }
bart3b1ee452008-02-29 19:28:15 +0000236 }
bart306527d2008-03-12 17:23:07 +0000237
238 if (reinitialization && p->count != count)
239 {
240 if (p->pre_waiters_left != p->count || p->post_waiters_left != p->count)
241 {
bart195a3982008-07-01 13:15:31 +0000242 BarrierErrInfo bei = { p->a1 };
243 VG_(maybe_record_error)(VG_(get_running_tid)(),
244 BarrierErr,
245 VG_(get_IP)(VG_(get_running_tid)()),
246 "Reinitialization of barrier with active"
247 " waiters",
248 &bei);
bart306527d2008-03-12 17:23:07 +0000249 }
250 p->count = count;
251 }
sewardj85642922008-01-14 11:54:56 +0000252}
253
bart28230a32008-02-29 17:27:03 +0000254/** Called after pthread_barrier_destroy(). */
barta8cf7652009-02-15 11:00:29 +0000255void DRD_(barrier_destroy)(const Addr barrier, const BarrierT barrier_type)
sewardj85642922008-01-14 11:54:56 +0000256{
bart72b751c2008-03-01 13:44:24 +0000257 struct barrier_info* p;
258
barta8cf7652009-02-15 11:00:29 +0000259 p = DRD_(barrier_get)(barrier);
bart306527d2008-03-12 17:23:07 +0000260
barta8cf7652009-02-15 11:00:29 +0000261 if (DRD_(s_trace_barrier))
bart3b1ee452008-02-29 19:28:15 +0000262 {
263 VG_(message)(Vg_UserMsg,
bart306527d2008-03-12 17:23:07 +0000264 "[%d/%d] barrier_destroy %s 0x%lx",
bart3b1ee452008-02-29 19:28:15 +0000265 VG_(get_running_tid)(),
266 thread_get_running_tid(),
barta8cf7652009-02-15 11:00:29 +0000267 DRD_(barrier_get_typename)(p),
bart72b751c2008-03-01 13:44:24 +0000268 barrier);
bart3b1ee452008-02-29 19:28:15 +0000269 }
bart72b751c2008-03-01 13:44:24 +0000270
bart72b751c2008-03-01 13:44:24 +0000271 if (p == 0)
272 {
273 GenericErrInfo GEI;
274 VG_(maybe_record_error)(VG_(get_running_tid)(),
275 GenericErr,
276 VG_(get_IP)(VG_(get_running_tid)()),
277 "Not a barrier",
278 &GEI);
279 return;
280 }
281
bart195a3982008-07-01 13:15:31 +0000282 if (p->pre_waiters_left != p->count || p->post_waiters_left != p->count)
283 {
284 BarrierErrInfo bei = { p->a1 };
285 VG_(maybe_record_error)(VG_(get_running_tid)(),
286 BarrierErr,
287 VG_(get_IP)(VG_(get_running_tid)()),
288 "Destruction of a barrier with active waiters",
289 &bei);
290 }
291
bart195e41f2009-02-15 11:34:57 +0000292 DRD_(clientobj_remove)(p->a1, ClientBarrier);
sewardj85642922008-01-14 11:54:56 +0000293}
294
bart28230a32008-02-29 17:27:03 +0000295/** Called before pthread_barrier_wait(). */
barta8cf7652009-02-15 11:00:29 +0000296void DRD_(barrier_pre_wait)(const DrdThreadId tid, const Addr barrier,
297 const BarrierT barrier_type)
sewardj85642922008-01-14 11:54:56 +0000298{
299 struct barrier_info* p;
300 struct barrier_thread_info* q;
301 const UWord word_tid = tid;
302
barta8cf7652009-02-15 11:00:29 +0000303 p = DRD_(barrier_get)(barrier);
bartc68bd602008-03-16 10:04:58 +0000304 if (p == 0 && barrier_type == gomp_barrier)
305 {
bart654013c2008-06-23 12:41:00 +0000306 VG_(message)(Vg_UserMsg, "");
bartc68bd602008-03-16 10:04:58 +0000307 VG_(message)(Vg_UserMsg,
308 "Please verify whether gcc has been configured"
309 " with option --disable-linux-futex.");
310 VG_(message)(Vg_UserMsg,
311 "See also the section about OpenMP in the DRD manual.");
bart654013c2008-06-23 12:41:00 +0000312 VG_(message)(Vg_UserMsg, "");
bartc68bd602008-03-16 10:04:58 +0000313 }
sewardj85642922008-01-14 11:54:56 +0000314 tl_assert(p);
315
barta8cf7652009-02-15 11:00:29 +0000316 if (DRD_(s_trace_barrier))
sewardj85642922008-01-14 11:54:56 +0000317 {
bart3b1ee452008-02-29 19:28:15 +0000318 VG_(message)(Vg_UserMsg,
barta2b6e1b2008-03-17 18:32:39 +0000319 "[%d/%d] barrier_pre_wait %s 0x%lx iteration %ld",
bart3b1ee452008-02-29 19:28:15 +0000320 VG_(get_running_tid)(),
321 thread_get_running_tid(),
barta8cf7652009-02-15 11:00:29 +0000322 DRD_(barrier_get_typename)(p),
bart3b1ee452008-02-29 19:28:15 +0000323 barrier,
324 p->pre_iteration);
sewardj85642922008-01-14 11:54:56 +0000325 }
326
sewardj85642922008-01-14 11:54:56 +0000327 q = VG_(OSetGen_Lookup)(p->oset, &word_tid);
328 if (q == 0)
329 {
330 q = VG_(OSetGen_AllocNode)(p->oset, sizeof(*q));
barta8cf7652009-02-15 11:00:29 +0000331 DRD_(barrier_thread_initialize)(q, tid, p->pre_iteration);
sewardj85642922008-01-14 11:54:56 +0000332 VG_(OSetGen_Insert)(p->oset, q);
333 tl_assert(VG_(OSetGen_Lookup)(p->oset, &word_tid) == q);
334 }
barta2b6e1b2008-03-17 18:32:39 +0000335 thread_get_latest_segment(&q->sg[p->pre_iteration], tid);
bartbebc5d62008-02-24 18:42:53 +0000336
337 if (--p->pre_waiters_left <= 0)
338 {
339 p->pre_iteration = 1 - p->pre_iteration;
340 p->pre_waiters_left = p->count;
341 }
sewardj85642922008-01-14 11:54:56 +0000342}
343
bart28230a32008-02-29 17:27:03 +0000344/** Called after pthread_barrier_wait(). */
barta8cf7652009-02-15 11:00:29 +0000345void DRD_(barrier_post_wait)(const DrdThreadId tid, const Addr barrier,
346 const BarrierT barrier_type, const Bool waited)
sewardj85642922008-01-14 11:54:56 +0000347{
bart3b1ee452008-02-29 19:28:15 +0000348 struct barrier_info* p;
sewardj85642922008-01-14 11:54:56 +0000349
barta8cf7652009-02-15 11:00:29 +0000350 p = DRD_(barrier_get)(barrier);
bartbebc5d62008-02-24 18:42:53 +0000351
barta8cf7652009-02-15 11:00:29 +0000352 if (DRD_(s_trace_barrier))
sewardj85642922008-01-14 11:54:56 +0000353 {
bart3b1ee452008-02-29 19:28:15 +0000354 VG_(message)(Vg_UserMsg,
barta2b6e1b2008-03-17 18:32:39 +0000355 "[%d/%d] barrier_post_wait %s 0x%lx iteration %ld",
bart3b1ee452008-02-29 19:28:15 +0000356 VG_(get_running_tid)(),
357 tid,
barta8cf7652009-02-15 11:00:29 +0000358 p ? DRD_(barrier_get_typename)(p) : "(?)",
bart3b1ee452008-02-29 19:28:15 +0000359 barrier,
bart306527d2008-03-12 17:23:07 +0000360 p ? p->post_iteration : -1);
sewardj85642922008-01-14 11:54:56 +0000361 }
362
bart306527d2008-03-12 17:23:07 +0000363 /* If p == 0, this means that the barrier has been destroyed after */
364 /* *_barrier_wait() returned and before this function was called. Just */
365 /* return in that case. */
366 if (p == 0)
367 return;
368
sewardj85642922008-01-14 11:54:56 +0000369 if (waited)
370 {
371 const UWord word_tid = tid;
372 struct barrier_thread_info* q;
373 struct barrier_thread_info* r;
374
sewardj85642922008-01-14 11:54:56 +0000375 q = VG_(OSetGen_Lookup)(p->oset, &word_tid);
bart195a3982008-07-01 13:15:31 +0000376 if (q == 0)
377 {
378 BarrierErrInfo bei = { p->a1 };
379 VG_(maybe_record_error)(VG_(get_running_tid)(),
380 BarrierErr,
381 VG_(get_IP)(VG_(get_running_tid)()),
382 "Error in barrier implementation"
383 " -- barrier_wait() started before"
384 " barrier_destroy() and finished after"
385 " barrier_destroy()",
386 &bei);
387
388 q = VG_(OSetGen_AllocNode)(p->oset, sizeof(*q));
barta8cf7652009-02-15 11:00:29 +0000389 DRD_(barrier_thread_initialize)(q, tid, p->pre_iteration);
bart195a3982008-07-01 13:15:31 +0000390 VG_(OSetGen_Insert)(p->oset, q);
391 tl_assert(VG_(OSetGen_Lookup)(p->oset, &word_tid) == q);
392 }
sewardj85642922008-01-14 11:54:56 +0000393 VG_(OSetGen_ResetIter)(p->oset);
394 for ( ; (r = VG_(OSetGen_Next)(p->oset)) != 0; )
395 {
396 if (r != q)
397 {
barta2b6e1b2008-03-17 18:32:39 +0000398 tl_assert(r->sg[p->post_iteration]);
399 thread_combine_vc2(tid, &r->sg[p->post_iteration]->vc);
sewardj85642922008-01-14 11:54:56 +0000400 }
401 }
bartbebc5d62008-02-24 18:42:53 +0000402
403 thread_new_segment(tid);
barta8cf7652009-02-15 11:00:29 +0000404 DRD_(s_barrier_segment_creation_count)++;
bartbebc5d62008-02-24 18:42:53 +0000405
406 if (--p->post_waiters_left <= 0)
407 {
408 p->post_iteration = 1 - p->post_iteration;
409 p->post_waiters_left = p->count;
410 }
sewardj85642922008-01-14 11:54:56 +0000411 }
412}
413
bartbebc5d62008-02-24 18:42:53 +0000414/** Call this function when thread tid stops to exist. */
barta8cf7652009-02-15 11:00:29 +0000415void DRD_(barrier_thread_delete)(const DrdThreadId tid)
sewardj85642922008-01-14 11:54:56 +0000416{
bart28230a32008-02-29 17:27:03 +0000417 struct barrier_info* p;
sewardj85642922008-01-14 11:54:56 +0000418
bart195e41f2009-02-15 11:34:57 +0000419 DRD_(clientobj_resetiter)();
420 for ( ; (p = &(DRD_(clientobj_next)(ClientBarrier)->barrier)) != 0; )
sewardj85642922008-01-14 11:54:56 +0000421 {
bart28230a32008-02-29 17:27:03 +0000422 struct barrier_thread_info* q;
423 const UWord word_tid = tid;
424 q = VG_(OSetGen_Remove)(p->oset, &word_tid);
bart7f912c02008-07-07 08:45:55 +0000425 /* q is only non-zero if the barrier object has been used by thread tid
426 * after the barrier_init() call and before the thread finished.
427 */
bart22f74572008-07-07 08:17:55 +0000428 if (q)
429 {
barta8cf7652009-02-15 11:00:29 +0000430 DRD_(barrier_thread_destroy)(q);
bart22f74572008-07-07 08:17:55 +0000431 VG_(OSetGen_FreeNode)(p->oset, q);
432 }
sewardj85642922008-01-14 11:54:56 +0000433 }
434}
bart306527d2008-03-12 17:23:07 +0000435
barta8cf7652009-02-15 11:00:29 +0000436static const char* DRD_(barrier_get_typename)(struct barrier_info* const p)
bart306527d2008-03-12 17:23:07 +0000437{
438 tl_assert(p);
439
barta8cf7652009-02-15 11:00:29 +0000440 return DRD_(barrier_type_name)(p->barrier_type);
bart306527d2008-03-12 17:23:07 +0000441}
442
barta8cf7652009-02-15 11:00:29 +0000443static const char* DRD_(barrier_type_name)(const BarrierT bt)
bart306527d2008-03-12 17:23:07 +0000444{
445 switch (bt)
446 {
447 case pthread_barrier:
448 return "pthread barrier";
449 case gomp_barrier:
450 return "gomp barrier";
451 }
452 return "?";
453}
bart6bbefaf2008-04-19 15:16:45 +0000454
barta8cf7652009-02-15 11:00:29 +0000455ULong DRD_(get_barrier_segment_creation_count)(void)
bart6bbefaf2008-04-19 15:16:45 +0000456{
barta8cf7652009-02-15 11:00:29 +0000457 return DRD_(s_barrier_segment_creation_count);
bart6bbefaf2008-04-19 15:16:45 +0000458}