|
From: <sv...@va...> - 2011-07-30 09:40:45
|
Author: bart
Date: 2011-07-30 10:35:56 +0100 (Sat, 30 Jul 2011)
New Revision: 11951
Log:
drd: Make racing pthread_barrier_wait() calls trigger an error message instead
of an assertion failure. Also, make barrier tracing output more detailed.
Modified:
trunk/drd/drd_barrier.c
Modified: trunk/drd/drd_barrier.c
===================================================================
--- trunk/drd/drd_barrier.c 2011-07-30 09:29:20 UTC (rev 11950)
+++ trunk/drd/drd_barrier.c 2011-07-30 09:35:56 UTC (rev 11951)
@@ -164,7 +164,7 @@
" upon",
&bei);
} else {
- oset = p->oset[1 - p->pre_iteration];
+ oset = p->oset[1 - (p->pre_iteration & 1)];
VG_(OSetGen_ResetIter)(oset);
for ( ; (q = VG_(OSetGen_Next)(oset)) != 0; ) {
if (q->post_wait_sg && !DRD_(vc_lte)(&q->post_wait_sg->vc,
@@ -377,7 +377,7 @@
}
/* Clean up nodes associated with finished threads. */
- oset = p->oset[p->pre_iteration];
+ oset = p->oset[p->pre_iteration & 1];
tl_assert(oset);
VG_(OSetGen_ResetIter)(oset);
for ( ; (q = VG_(OSetGen_Next)(oset)) != 0; ) {
@@ -414,7 +414,7 @@
*/
if (--p->pre_waiters_left <= 0)
{
- p->pre_iteration = 1 - p->pre_iteration;
+ p->pre_iteration++;
p->pre_waiters_left = p->count;
}
}
@@ -456,24 +456,33 @@
if (! waited)
return;
- oset = p->oset[p->post_iteration];
+ oset = p->oset[p->post_iteration & 1];
q = VG_(OSetGen_Lookup)(oset, &word_tid);
- if (q == 0)
- {
+ if (p->pre_iteration - p->post_iteration > 1) {
BarrierErrInfo bei = { DRD_(thread_get_running_tid)(), p->a1, 0, 0 };
VG_(maybe_record_error)(VG_(get_running_tid)(),
BarrierErr,
VG_(get_IP)(VG_(get_running_tid)()),
+ "Number of concurrent pthread_barrier_wait()"
+ " calls exceeds the barrier count",
+ &bei);
+ } else if (q == NULL) {
+ BarrierErrInfo bei = { DRD_(thread_get_running_tid)(), p->a1, 0, 0 };
+ VG_(maybe_record_error)(VG_(get_running_tid)(),
+ BarrierErr,
+ VG_(get_IP)(VG_(get_running_tid)()),
"Error in barrier implementation"
" -- barrier_wait() started before"
" barrier_destroy() and finished after"
" barrier_destroy()",
&bei);
-
+ }
+ if (q == NULL) {
q = VG_(OSetGen_AllocNode)(oset, sizeof(*q));
DRD_(barrier_thread_initialize)(q, tid);
VG_(OSetGen_Insert)(oset, q);
tl_assert(VG_(OSetGen_Lookup)(oset, &word_tid) == q);
+ DRD_(thread_get_latest_segment)(&q->sg, tid);
}
/* Create a new segment and store a pointer to that segment. */
@@ -510,7 +519,7 @@
*/
if (--p->post_waiters_left <= 0)
{
- p->post_iteration = 1 - p->post_iteration;
+ p->post_iteration++;
p->post_waiters_left = p->count;
}
}
|