[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#551903: libc6-i686 pthread_cond_wait fails to reacquire mutex upon cancellation



On Sat, Jun 05, 2010 at 06:39:24PM +0200, Aurelien Jarno wrote:
> On Fri, Jun 04, 2010 at 11:25:28AM +0200, Aurelien Jarno wrote:
> > Aurelien Jarno a écrit :
> > > On Thu, Jun 03, 2010 at 10:09:45PM +0300, Rémi Denis-Courmont wrote:
> > >> Le jeudi 3 juin 2010 22:00:13 Aurelien Jarno, vous avez écrit :
> > >>> I have found a machine with almost the same CPU, the only difference
> > >>> being the speed (3.00 GHz instead of 2.80 GHz). I am unable to reproduce
> > >>> the problem, I have run the testcase more than 200000 times over last
> > >>> night.
> > >> With SMT ("HyperThread") support?
> > > 
> > > Yes, with HyperThreading enabled.
> > > 
> > >>> Maybe the problem is actually not in the GNU libc. What kernel are you
> > >>> running?
> > >> Normally, I use upstream 2.6.32.15 at the moment.
> > >> But I also hit the bug with Debian 2.6.32-5-686.
> > >>
> > > 
> > > I tried on a 2.6.26 kernel, I'll try to reproduce it with this kernel.
> > > 
> > 
> > I tried on a 2.6.32-5-686 kernel, and it hasn't failed in more than
> > 300000 loops. There is probably something different on your system
> > causing the issue.
> > 
> 
> I have modified a bit the testcase so that it runs in a loop, and I
> removed all timing functions (see attached file). I am able to reproduce
> the problem in some conditions:

This time it is.

-- 
Aurelien Jarno	                        GPG: 1024D/F1BCDB73
aurelien@aurel32.net                 http://www.aurel32.net
/* gcc -O2 -Wall -lpthread condfail.c */
#define _GNU_SOURCE 1
#undef NDEBUG
#include <pthread.h>
#include <time.h>
#include <assert.h>
#include <stdio.h>

static pthread_cond_t wait = PTHREAD_COND_INITIALIZER;
static pthread_mutex_t lock = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
static long long int i=0;

static void cleanup_lock(void *lock)
{
	int val;

	i++;
	val = pthread_mutex_unlock(lock);
	if (val != 0) {
		printf("failed after %lli iterations\n", i);
	        assert (0);
	}
}

static void *entry(void *barrier)
{
	pthread_mutex_lock(&lock);
	pthread_cleanup_push(cleanup_lock, &lock);
	pthread_barrier_wait(barrier);
	for (;;)
		pthread_cond_wait(&wait, &lock);
	pthread_cleanup_pop(0);
	assert(0);
}

int main (void)
{
	for(;;) {

		pthread_t th;
		pthread_barrier_t barrier;

		pthread_barrier_init(&barrier, NULL, 2);
		pthread_create(&th, NULL, entry, &barrier);
		pthread_barrier_wait(&barrier);
		pthread_barrier_destroy(&barrier);

		pthread_cancel(th);
		pthread_mutex_lock(&lock);
		pthread_mutex_unlock(&lock);
		pthread_join(th, NULL);
	}
	return 0;
}

Reply to: