When using pthread_barrier_wait, it is important that barriers are called the correct number of times. That is - the same number given as the count when initializing the barrier. There was a do-while loop around elevate_barrier in the med priority thread. On most machines, it actually never looped. On threads with enough processors (nehalem for example), there was a racy situation in which the high priority thread could come out of the finish barrier, and before it could set high_has_run = 0, the medium priority thread would test the value and call the elevate barrier an extra time. This patch removes the bogus loop and related state variables and fixes the hang. Signed-off-by: John Kacur <jkacur@xxxxxxxxxx> --- src/pi_tests/pi_stress.c | 22 +++++++--------------- 1 files changed, 7 insertions(+), 15 deletions(-) diff --git a/src/pi_tests/pi_stress.c b/src/pi_tests/pi_stress.c index f4b43ed..6f1a309 100644 --- a/src/pi_tests/pi_stress.c +++ b/src/pi_tests/pi_stress.c @@ -201,8 +201,6 @@ struct group_parameters { int loop; /* boolean, loop or not, connected to shutdown */ /* state variables */ - volatile int high_has_run; - volatile int low_unlocked; volatile int watchdog; /* total number of inversions performed */ @@ -703,7 +701,6 @@ void *low_priority(void *arg) } /* wait for priority boost */ debug("low_priority[%d]: entering elevated wait\n", p->id); - p->low_unlocked = 0; /* prevent race with med_priority */ status = pthread_barrier_wait(&p->elevate_barrier); if (status && status != PTHREAD_BARRIER_SERIAL_THREAD) { error @@ -711,7 +708,6 @@ void *low_priority(void *arg) p->id, status); return NULL; } - p->low_unlocked = 1; /* release the mutex */ debug("low_priority[%d]: unlocking mutex\n", p->id); @@ -812,15 +808,12 @@ void *med_priority(void *arg) return NULL; } debug("med_priority[%d]: entering elevate state\n", p->id); - do { - status = pthread_barrier_wait(&p->elevate_barrier); - if (status && status != PTHREAD_BARRIER_SERIAL_THREAD) { - error - ("med_priority[%d]: pthread_barrier_wait(elevate): %x", - p->id, status); - return NULL; - } - } while (!p->high_has_run && !p->low_unlocked); + status = pthread_barrier_wait(&p->elevate_barrier); + if (status && status != PTHREAD_BARRIER_SERIAL_THREAD) { + error ("med_priority[%d]: pthread_barrier_wait(elevate): %x", p->id, status); + return NULL; + } + debug("med_priority[%d]: entering finish state\n", p->id); status = pthread_barrier_wait(&p->finish_barrier); if (status && status != PTHREAD_BARRIER_SERIAL_THREAD) { @@ -906,7 +899,6 @@ void *high_priority(void *arg) } pthread_mutex_unlock(&shutdown_mtx); } - p->high_has_run = 0; debug("high_priority[%d]: entering start state (%d)\n", p->id, count++); status = pthread_barrier_wait(&p->start_barrier); @@ -928,7 +920,7 @@ void *high_priority(void *arg) debug("high_priority[%d]: locking mutex\n", p->id); pthread_mutex_lock(&p->mutex); debug("high_priority[%d]: got mutex\n", p->id); - p->high_has_run = 1; + debug("high_priority[%d]: unlocking mutex\n", p->id); pthread_mutex_unlock(&p->mutex); debug("high_priority[%d]: entering finish state\n", p->id); -- 1.6.2.5 -- To unsubscribe from this list: send the line "unsubscribe linux-rt-users" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html