From: Subrata M. <su...@li...> - 2008-03-14 20:44:46
|
Darren Hart wrote: > Subrata Modak wrote: >> >> >> Hi, >>> We have seen that prio_preempt testcase that is part of realtime >>> tests occasionally hangs. This can be easily recreated on a 8-cpu >>> system, but can be recreated on a 4-cpu system as well when run for >>> a number of iterations. >>> >>> The problem occurs because the first worker thread sometimes fails >>> to call cond_wait on the condvar through which the master thread >>> signals it to start. Since the first thread needs to start the chain >>> of signalling from then on, all other threads just sit in a >>> cond_wait without ever being woken up. >>> >>> The fix is to have a barrier to ensure that the first worker thread >>> doesn't miss the cond_signal. >>> >>> I have tested this patch by running 10s of thousands of iterations >>> of the testcase. Without the patch I can recreate the problem fairly >>> easily. >>> >>> Thanks, >>> Sripathi. >>> >>> Signed-off-by: Sripathi Kodi <sri...@in...> > > Acked-by: Darren Hart <dv...@us...> Thanks for the Ack. This has been merged. Regards-- Subrata > >>> >> >> Over to the Real Time Linux Community for comments :-) >> >> Regards-- >> Subrata >>> --- >>> ltp-full-20080229/testcases/realtime/func/prio-preempt/prio-preempt.c.org >>> >>> 2008-03-12 22:10:05.000000000 +0530 >>> +++ >>> ltp-full-20080229/testcases/realtime/func/prio-preempt/prio-preempt.c >>> 2008-03-12 22:14:02.000000000 +0530 >>> @@ -90,6 +90,8 @@ static int t_after_wait[NUM_WORKERS]; >>> static int ret = 0; >>> static int run_jvmsim=0; >>> >>> +pthread_barrier_t barrier; >>> + >>> void usage(void) >>> { >>> rt_help(); >>> @@ -184,6 +186,8 @@ void *worker_thread(void* arg) >>> >>> /* block */ >>> rc = pthread_mutex_lock(&mutex[tid]); >>> + if (tid == 0) >>> + pthread_barrier_wait(&barrier); >>> rc = pthread_cond_wait(&cond[tid], &mutex[tid]); >>> rc = pthread_mutex_unlock(&mutex[tid]); >>> >>> @@ -234,6 +238,8 @@ void *master_thread(void* arg) >>> { >>> int i, pri_boost; >>> >>> + pthread_barrier_init(&barrier, NULL, 2); >>> + >>> /* start interrupter thread */ >>> if (int_threads) { >>> pri_boost = 90; >>> @@ -270,6 +276,9 @@ void *master_thread(void* arg) >>> while (threads_running < NUM_WORKERS) >>> usleep(100); >>> >>> + /* Ensure the first worker has called cond_wait */ >>> + pthread_barrier_wait(&barrier); >>> + >>> printf("Signaling first thread\n"); >>> pthread_mutex_lock(&mutex[0]); >>> pthread_cond_signal(&cond[0]); >>> >>> >> >> > > |