mirror of git://sourceware.org/git/glibc.git
[BZ #3123]
2006-09-08 Ulrich Drepper <drepper@redhat.com> [BZ #3123] * sysdeps/pthread/pthread_cond_wait.c (__condvar_cleanup): Don't increment WAKEUP_SEQ if this would increase the value beyond TOTAL_SEQ. * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.c: Likewise. * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.c: Likewise. * sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.c: Likewise. * Makefile (tests): Add tst-cond22. * tst-cond22.c: New file.
This commit is contained in:
parent
469615bdd4
commit
346e6ad401
|
@ -1,3 +1,14 @@
|
||||||
|
2006-09-08 Ulrich Drepper <drepper@redhat.com>
|
||||||
|
|
||||||
|
[BZ #3123]
|
||||||
|
* sysdeps/pthread/pthread_cond_wait.c (__condvar_cleanup): Don't
|
||||||
|
increment WAKEUP_SEQ if this would increase the value beyond TOTAL_SEQ.
|
||||||
|
* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.c: Likewise.
|
||||||
|
* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.c: Likewise.
|
||||||
|
* sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.c: Likewise.
|
||||||
|
* Makefile (tests): Add tst-cond22.
|
||||||
|
* tst-cond22.c: New file.
|
||||||
|
|
||||||
2006-09-05 Ulrich Drepper <drepper@redhat.com>
|
2006-09-05 Ulrich Drepper <drepper@redhat.com>
|
||||||
|
|
||||||
[BZ #3124]
|
[BZ #3124]
|
||||||
|
|
|
@ -207,7 +207,7 @@ tests = tst-typesizes \
|
||||||
tst-cond1 tst-cond2 tst-cond3 tst-cond4 tst-cond5 tst-cond6 tst-cond7 \
|
tst-cond1 tst-cond2 tst-cond3 tst-cond4 tst-cond5 tst-cond6 tst-cond7 \
|
||||||
tst-cond8 tst-cond9 tst-cond10 tst-cond11 tst-cond12 tst-cond13 \
|
tst-cond8 tst-cond9 tst-cond10 tst-cond11 tst-cond12 tst-cond13 \
|
||||||
tst-cond14 tst-cond15 tst-cond16 tst-cond17 tst-cond18 tst-cond19 \
|
tst-cond14 tst-cond15 tst-cond16 tst-cond17 tst-cond18 tst-cond19 \
|
||||||
tst-cond20 tst-cond21 \
|
tst-cond20 tst-cond21 tst-cond22 \
|
||||||
tst-robust1 tst-robust2 tst-robust3 tst-robust4 tst-robust5 \
|
tst-robust1 tst-robust2 tst-robust3 tst-robust4 tst-robust5 \
|
||||||
tst-robust6 tst-robust7 tst-robust8 \
|
tst-robust6 tst-robust7 tst-robust8 \
|
||||||
tst-robustpi1 tst-robustpi2 tst-robustpi3 tst-robustpi4 \
|
tst-robustpi1 tst-robustpi2 tst-robustpi3 tst-robustpi4 \
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
|
/* Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc.
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003.
|
Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003.
|
||||||
|
|
||||||
|
@ -50,7 +50,11 @@ __condvar_cleanup (void *arg)
|
||||||
if (cbuffer->bc_seq == cbuffer->cond->__data.__broadcast_seq)
|
if (cbuffer->bc_seq == cbuffer->cond->__data.__broadcast_seq)
|
||||||
{
|
{
|
||||||
/* This thread is not waiting anymore. Adjust the sequence counters
|
/* This thread is not waiting anymore. Adjust the sequence counters
|
||||||
appropriately. */
|
appropriately. We do not increment WAKEUP_SEQ if this would
|
||||||
|
bump it over the value of TOTAL_SEQ> This can happen if a thread
|
||||||
|
was woken and then canceled. */
|
||||||
|
if (cbuffer->cond->__data.__wakeup_seq
|
||||||
|
< cbuffer->cond->__data.__total_seq)
|
||||||
++cbuffer->cond->__data.__wakeup_seq;
|
++cbuffer->cond->__data.__wakeup_seq;
|
||||||
++cbuffer->cond->__data.__woken_seq;
|
++cbuffer->cond->__data.__woken_seq;
|
||||||
++cbuffer->cond->__data.__futex;
|
++cbuffer->cond->__data.__futex;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
|
/* Copyright (C) 2002, 2003, 2004, 2006 Free Software Foundation, Inc.
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
|
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
|
||||||
|
|
||||||
|
@ -406,10 +406,21 @@ __condvar_tw_cleanup:
|
||||||
cmpl 20(%esp), %eax
|
cmpl 20(%esp), %eax
|
||||||
jne 3f
|
jne 3f
|
||||||
|
|
||||||
addl $1, wakeup_seq(%ebx)
|
/* We increment the woken_seq counter only if it is lower than
|
||||||
|
total_seq. If this is not the case the thread was woken and
|
||||||
|
then canceled. In this case we ignore the signal. */
|
||||||
|
movl total_seq(%ebx), %eax
|
||||||
|
movl total_seq+4(%ebx), %edi
|
||||||
|
cmpl wakeup_seq+4(%ebx), %edi
|
||||||
|
jb 6f
|
||||||
|
ja 7f
|
||||||
|
cmpl wakeup_seq(%ebx), %eax
|
||||||
|
jbe 7f
|
||||||
|
|
||||||
|
6: addl $1, wakeup_seq(%ebx)
|
||||||
adcl $0, wakeup_seq+4(%ebx)
|
adcl $0, wakeup_seq+4(%ebx)
|
||||||
|
|
||||||
addl $1, cond_futex(%ebx)
|
7: addl $1, cond_futex(%ebx)
|
||||||
|
|
||||||
addl $1, woken_seq(%ebx)
|
addl $1, woken_seq(%ebx)
|
||||||
adcl $0, woken_seq+4(%ebx)
|
adcl $0, woken_seq+4(%ebx)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
|
/* Copyright (C) 2002, 2003, 2004, 2006 Free Software Foundation, Inc.
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
|
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
|
||||||
|
|
||||||
|
@ -297,11 +297,21 @@ __condvar_w_cleanup:
|
||||||
cmpl 12(%esp), %eax
|
cmpl 12(%esp), %eax
|
||||||
jne 3f
|
jne 3f
|
||||||
|
|
||||||
addl $1, wakeup_seq(%ebx)
|
/* We increment the woken_seq counter only if it is lower than
|
||||||
|
total_seq. If this is not the case the thread was woken and
|
||||||
|
then canceled. In this case we ignore the signal. */
|
||||||
|
movl total_seq(%ebx), %eax
|
||||||
|
movl total_seq+4(%ebx), %edi
|
||||||
|
cmpl wakeup_seq+4(%ebx), %edi
|
||||||
|
jb 6f
|
||||||
|
ja 7f
|
||||||
|
cmpl wakeup_seq(%ebx), %eax
|
||||||
|
jbe 7f
|
||||||
|
|
||||||
|
6: addl $1, wakeup_seq(%ebx)
|
||||||
adcl $0, wakeup_seq+4(%ebx)
|
adcl $0, wakeup_seq+4(%ebx)
|
||||||
|
|
||||||
addl $1, cond_futex(%ebx)
|
7: addl $1, cond_futex(%ebx)
|
||||||
|
|
||||||
addl $1, woken_seq(%ebx)
|
addl $1, woken_seq(%ebx)
|
||||||
adcl $0, woken_seq+4(%ebx)
|
adcl $0, woken_seq+4(%ebx)
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
|
/* Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
|
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
|
||||||
|
|
||||||
|
@ -67,8 +67,14 @@ __condvar_cleanup:
|
||||||
cmpl 4(%r8), %edx
|
cmpl 4(%r8), %edx
|
||||||
jne 3f
|
jne 3f
|
||||||
|
|
||||||
|
/* We increment the woken_seq counter only if it is lower than
|
||||||
|
total_seq. If this is not the case the thread was woken and
|
||||||
|
then canceled. In this case we ignore the signal. */
|
||||||
|
movq total_seq(%rdi), %rax
|
||||||
|
cmpq wakeup_seq(%rdi), %rax
|
||||||
|
jbe 6f
|
||||||
incq wakeup_seq(%rdi)
|
incq wakeup_seq(%rdi)
|
||||||
incq woken_seq(%rdi)
|
6: incq woken_seq(%rdi)
|
||||||
incl cond_futex(%rdi)
|
incl cond_futex(%rdi)
|
||||||
|
|
||||||
3: subl $(1 << clock_bits), cond_nwaiters(%rdi)
|
3: subl $(1 << clock_bits), cond_nwaiters(%rdi)
|
||||||
|
|
|
@ -0,0 +1,153 @@
|
||||||
|
#include <pthreadP.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
|
||||||
|
static pthread_barrier_t b;
|
||||||
|
static pthread_cond_t c = PTHREAD_COND_INITIALIZER;
|
||||||
|
static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
cl (void *arg)
|
||||||
|
{
|
||||||
|
pthread_mutex_unlock (&m);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void *
|
||||||
|
tf (void *arg)
|
||||||
|
{
|
||||||
|
if (pthread_mutex_lock (&m) != 0)
|
||||||
|
{
|
||||||
|
printf ("%s: mutex_lock failed\n", __func__);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
int e = pthread_barrier_wait (&b);
|
||||||
|
if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
|
||||||
|
{
|
||||||
|
printf ("%s: barrier_wait failed\n", __func__);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
pthread_cleanup_push (cl, NULL);
|
||||||
|
if (pthread_cond_wait (&c, &m) != 0)
|
||||||
|
{
|
||||||
|
printf ("%s: cond_wait failed\n", __func__);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
pthread_cleanup_pop (0);
|
||||||
|
if (pthread_mutex_unlock (&m) != 0)
|
||||||
|
{
|
||||||
|
printf ("%s: mutex_unlock failed\n", __func__);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
do_test (void)
|
||||||
|
{
|
||||||
|
int status = 0;
|
||||||
|
|
||||||
|
if (pthread_barrier_init (&b, NULL, 2) != 0)
|
||||||
|
{
|
||||||
|
puts ("barrier_init failed");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_t th;
|
||||||
|
if (pthread_create (&th, NULL, tf, NULL) != 0)
|
||||||
|
{
|
||||||
|
puts ("1st create failed");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
int e = pthread_barrier_wait (&b);
|
||||||
|
if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
|
||||||
|
{
|
||||||
|
puts ("1st barrier_wait failed");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (pthread_mutex_lock (&m) != 0)
|
||||||
|
{
|
||||||
|
puts ("1st mutex_lock failed");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (pthread_cond_signal (&c) != 0)
|
||||||
|
{
|
||||||
|
puts ("1st cond_signal failed");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (pthread_cancel (th) != 0)
|
||||||
|
{
|
||||||
|
puts ("cancel failed");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (pthread_mutex_unlock (&m) != 0)
|
||||||
|
{
|
||||||
|
puts ("1st mutex_unlock failed");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
void *res;
|
||||||
|
if (pthread_join (th, &res) != 0)
|
||||||
|
{
|
||||||
|
puts ("1st join failed");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (res != PTHREAD_CANCELED)
|
||||||
|
{
|
||||||
|
puts ("first thread not canceled");
|
||||||
|
status = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf ("cond = { %d, %x, %lld, %lld, %lld, %p, %u, %u }\n",
|
||||||
|
c.__data.__lock, c.__data.__futex, c.__data.__total_seq,
|
||||||
|
c.__data.__wakeup_seq, c.__data.__woken_seq, c.__data.__mutex,
|
||||||
|
c.__data.__nwaiters, c.__data.__broadcast_seq);
|
||||||
|
|
||||||
|
if (pthread_create (&th, NULL, tf, NULL) != 0)
|
||||||
|
{
|
||||||
|
puts ("2nd create failed");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
e = pthread_barrier_wait (&b);
|
||||||
|
if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
|
||||||
|
{
|
||||||
|
puts ("2nd barrier_wait failed");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (pthread_mutex_lock (&m) != 0)
|
||||||
|
{
|
||||||
|
puts ("2nd mutex_lock failed");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (pthread_cond_signal (&c) != 0)
|
||||||
|
{
|
||||||
|
puts ("2nd cond_signal failed");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (pthread_mutex_unlock (&m) != 0)
|
||||||
|
{
|
||||||
|
puts ("2nd mutex_unlock failed");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (pthread_join (th, &res) != 0)
|
||||||
|
{
|
||||||
|
puts ("2nd join failed");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (res != NULL)
|
||||||
|
{
|
||||||
|
puts ("2nd thread canceled");
|
||||||
|
status = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf ("cond = { %d, %x, %lld, %lld, %lld, %p, %u, %u }\n",
|
||||||
|
c.__data.__lock, c.__data.__futex, c.__data.__total_seq,
|
||||||
|
c.__data.__wakeup_seq, c.__data.__woken_seq, c.__data.__mutex,
|
||||||
|
c.__data.__nwaiters, c.__data.__broadcast_seq);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define TEST_FUNCTION do_test ()
|
||||||
|
#include "../test-skeleton.c"
|
Loading…
Reference in New Issue