[BZ #163]
authorUlrich Drepper <drepper@redhat.com>
Tue, 18 May 2004 20:18:14 +0000 (20:18 +0000)
committerUlrich Drepper <drepper@redhat.com>
Tue, 18 May 2004 20:18:14 +0000 (20:18 +0000)
Update.
2004-05-18  Petter Reinholdtsen  <pere@hungry.com>

* locales/sl_SI [LC_TIME]: Correct d_fmt date format from
'22.06.2003' to '22. 06. 2003'.  Change requested from Aleks
Reinhardt, and approved by the locale author Borka
Jerman-Blazic. [BZ #163]

27 files changed:
localedata/ChangeLog
localedata/locales/sl_SI
malloc/mtrace.pl
nptl/ChangeLog
nptl/DESIGN-condvar.txt
nptl/Makefile
nptl/pthread_cond_init.c
nptl/sysdeps/pthread/pthread_cond_broadcast.c
nptl/sysdeps/pthread/pthread_cond_timedwait.c
nptl/sysdeps/pthread/pthread_cond_wait.c
nptl/sysdeps/unix/sysv/linux/alpha/bits/pthreadtypes.h
nptl/sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h
nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S
nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S
nptl/sysdeps/unix/sysv/linux/ia64/bits/pthreadtypes.h
nptl/sysdeps/unix/sysv/linux/lowlevelcond.sym
nptl/sysdeps/unix/sysv/linux/powerpc/bits/pthreadtypes.h
nptl/sysdeps/unix/sysv/linux/s390/bits/pthreadtypes.h
nptl/sysdeps/unix/sysv/linux/sparc/bits/pthreadtypes.h
nptl/sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h
nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S
nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S
nptl/tst-cond16.c [new file with mode: 0644]
nptl/tst-cond17.c [new file with mode: 0644]
nptl/tst-cond18.c [new file with mode: 0644]

index 392a145..282abc1 100644 (file)
@@ -1,3 +1,10 @@
+2004-05-18  Petter Reinholdtsen  <pere@hungry.com>
+
+       * locales/sl_SI [LC_TIME]: Correct d_fmt date format from
+       '22.06.2003' to '22. 06. 2003'.  Change requested from Aleks
+       Reinhardt, and approved by the locale author Borka
+       Jerman-Blazic. [BZ #163]
+
 2004-05-17  Ulrich Drepper  <drepper@redhat.com>
 
        * SUPPORTED (SUPPORTED-LOCALES): Remove sr_YU locales.
index a40c0a2..b6aa4d0 100644 (file)
@@ -2176,7 +2176,7 @@ mon     "<U006A><U0061><U006E><U0075><U0061><U0072>";/
         "<U006E><U006F><U0076><U0065><U006D><U0062><U0065><U0072>";/
         "<U0064><U0065><U0063><U0065><U006D><U0062><U0065><U0072>"
 d_t_fmt "<U0025><U0061><U0020><U0025><U0064><U0020><U0025><U0062><U0020><U0025><U0059><U0020><U0025><U0054><U0020><U0025><U005A>"
-d_fmt   "<U0025><U0064><U002E><U0025><U006D><U002E><U0025><U0059>"
+d_fmt   "<U0025><U0064><U002E><U0020><U0025><U006D><U002E><U0020><U0025><U0059>"
 t_fmt   "<U0025><U0054>"
 am_pm   "";""
 t_fmt_ampm ""
index 60c0a11..2d12929 100644 (file)
@@ -30,7 +30,7 @@ sub usage {
     print "  --help       print this help, then exit\n";
     print "  --version    print version number, then exit\n";
     print "\n";
-    print "For bug reporting instructions, please see:\n"
+    print "For bug reporting instructions, please see:\n";
     print "<http://www.gnu.org/software/libc/bugs.html>.\n";
     exit 0;
 }
index 534f585..592f73b 100644 (file)
@@ -1,3 +1,48 @@
+2004-05-18  Jakub Jelinek  <jakub@redhat.com>
+
+       * Makefile (.NOTPARALLEL): Only serialize make check/xcheck, not
+       compilation.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
+       (__pthread_cond_timedwait): Avoid returning -ETIMEDOUT.
+       * sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h
+       (pthread_cond_t): Add __data.__broadcast_seq field.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
+       (FRAME_SIZE): Define.
+       (__pthread_cond_timedwait): Use it.  Store/check broadcast_seq.
+       Comment typo fixes.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S (FRAME_SIZE):
+       Define.
+       (__pthread_cond_wait): Use it.  Store/check broadcast_seq.  Comment
+       typo fixes.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S
+       (__pthread_cond_broadcast): Increment broadcast_seq.  Comment typo
+       fixes.
+
+2004-05-18  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/lowlevelcond.sym: Add broadcast_seq entry.
+       * sysdeps/unix/sysv/linux/alpha/bits/pthreadtypes.h (pthread_cond_t):
+       Add __broadcast_seq field.
+       * sysdeps/unix/sysv/linux/s390/bits/pthreadtypes.h: Likewise.
+       * sysdeps/unix/sysv/linux/powerpc/bits/pthreadtypes.h: Likewise.
+       * sysdeps/unix/sysv/linux/sparc/bits/pthreadtypes.h: Likewise.
+       * sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h: Likewise.
+       * sysdeps/unix/sysv/linux/ia64/bits/pthreadtypes.h: Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S: Mark
+       all waiters as woken with woken_seq and bump broadcast counter.
+       * sysdeps/pthread/pthread_cond_broadcast.c: Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S: Use new
+       __broadcast_seq field.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S: Likewise.
+       * sysdeps/pthread/pthread_cond_wait.c: Likewise.
+       * sysdeps/pthread/pthread_cond_timedwait.c: Likewise.
+       * pthread_cond_init.c: Initialize __broadcast_seq field.
+       * Makefile (tests): Add tst-cond17 and tst-cond18.
+       Add .NOTPARALLEL goal.
+       * tst-cond16.c: New file.  From Jakub.
+       * tst-cond17.c: New file.  From Jakub.
+       * tst-cond18.c: New file.  From Jakub.
+
 2004-05-16  Ulrich Drepper  <drepper@redhat.com>
 
        * sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S: Correct some
index cb0f59c..4845251 100644 (file)
@@ -23,16 +23,30 @@ struct pthread_cond_t {
 
      sequence number of last woken thread.
 
+   uint32_t broadcast_seq;
+
+}
+
+
+struct cv_data {
+
+   pthread_cond_t *cv;
+
+   uint32_t bc_seq
+
 }
 
 
 
-cleanup_handler(cv)
+cleanup_handler(cv_data)
 {
+  cv = cv_data->cv;
   lll_lock(cv->lock);
 
-  ++cv->wakeup_seq;
-  ++cv->woken_seq;
+  if (cv_data->bc_seq == cv->broadcast_seq) {
+    ++cv->wakeup_seq;
+    ++cv->woken_seq;
+  }
 
   /* make sure no signal gets lost.  */
   FUTEX_WAKE(cv->wakeup_seq, ALL);
@@ -50,12 +64,14 @@ cond_timedwait(cv, mutex, timeout):
 
    ++cv->total_seq;
    val = seq =  cv->wakeup_seq;
+   cv_data.bc = cv->broadcast_seq;
+   cv_data.cv = cv;
 
    while (1) {
 
      lll_unlock(cv->lock);
 
-     enable_async
+     enable_async(&cv_data);
 
      ret = FUTEX_WAIT(cv->wakeup_seq, val, timeout);
 
@@ -63,6 +79,9 @@ cond_timedwait(cv, mutex, timeout):
 
      lll_lock(cv->lock);
 
+     if (bc != cv->broadcast_seq)
+       goto bc_out;
+
      val = cv->wakeup_seq;
 
      if (val != seq && cv->woken_seq != val) {
@@ -78,6 +97,7 @@ cond_timedwait(cv, mutex, timeout):
 
    ++cv->woken_seq;
 
+ bc_out:
    lll_unlock(cv->lock);
 
    cleanup_pop
@@ -105,6 +125,8 @@ cond_broadcast(cv)
 
    if (cv->total_seq > cv->wakeup_seq) {
      cv->wakeup_seq = cv->total_seq;
+     cv->woken_seq = cv->total_seq;
+     ++cv->broadcast_seq;
      FUTEX_WAKE(cv->wakeup_seq, ALL);
    }
 
index a90c4ad..687a6a0 100644 (file)
@@ -194,7 +194,7 @@ tests = tst-attr1 tst-attr2 tst-attr3 \
        tst-spin1 tst-spin2 tst-spin3 \
        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-cond14 tst-cond15 \
+       tst-cond14 tst-cond15 tst-cond17 tst-cond18 \
        tst-rwlock1 tst-rwlock2 tst-rwlock3 tst-rwlock4 tst-rwlock5 \
        tst-rwlock6 tst-rwlock7 tst-rwlock8 tst-rwlock9 tst-rwlock10 \
        tst-rwlock11 tst-rwlock12 tst-rwlock13 \
@@ -576,3 +576,8 @@ tst-exec4-ARGS = $(built-program-cmd)
 $(objpfx)tst-execstack: $(libdl)
 $(objpfx)tst-execstack.out: $(objpfx)tst-execstack-mod.so
 LDFLAGS-tst-execstack = -Wl,-z,noexecstack
+
+# The tests here better do not run in parallel
+ifneq ($(filter %tests,$(MAKECMDGOALS)),)
+.NOTPARALLEL:
+endif
index bb7c6d6..d059da2 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -38,6 +38,7 @@ __pthread_cond_init (cond, cond_attr)
   cond->__data.__woken_seq = 0;
   cond->__data.__mutex = (icond_attr == NULL || (icond_attr->value & 1) == 0
                          ? NULL : (void *) ~0l);
+  cond->__data.__broadcast_seq = 0;
 
   return 0;
 }
index 44c3fe6..a42c579 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003.
 
@@ -40,6 +40,9 @@ __pthread_cond_broadcast (cond)
     {
       /* Yes.  Mark them all as woken.  */
       cond->__data.__wakeup_seq = cond->__data.__total_seq;
+      cond->__data.__woken_seq = cond->__data.__total_seq;
+      /* Signal that a broadcast happened.  */
+      ++cond->__data.__broadcast_seq;
 
       /* We are done.  */
       lll_mutex_unlock (cond->__data.__lock);
index a03f51e..96b1029 100644 (file)
@@ -36,6 +36,7 @@ struct _condvar_cleanup_buffer
   int oldtype;
   pthread_cond_t *cond;
   pthread_mutex_t *mutex;
+  unsigned int bc_seq;
 };
 
 int
@@ -85,6 +86,8 @@ __pthread_cond_timedwait (cond, mutex, abstime)
   unsigned long long int val;
   unsigned long long int seq;
   val = seq = cond->__data.__wakeup_seq;
+  /* Remember the broadcast counter.  */
+  cbuffer.bc_seq = cond->__data.__broadcast_seq;
 
   /* The futex syscall operates on a 32-bit word.  That is fine, we
      just use the low 32 bits of the sequence counter.  */
@@ -139,7 +142,12 @@ __pthread_cond_timedwait (cond, mutex, abstime)
        }
       /* Did we already time out?  */
       if (__builtin_expect (rt.tv_sec < 0, 0))
-       goto timeout;
+       {
+         if (cbuffer.bc_seq != cond->__data.__broadcast_seq)
+           goto bc_out;
+
+         goto timeout;
+       }
 
       /* Prepare to wait.  Release the condvar futex.  */
       lll_mutex_unlock (cond->__data.__lock);
@@ -157,6 +165,10 @@ __pthread_cond_timedwait (cond, mutex, abstime)
       /* We are going to look at shared data again, so get the lock.  */
       lll_mutex_lock(cond->__data.__lock);
 
+      /* If a broadcast happened, we are done.  */
+      if (cbuffer.bc_seq != cond->__data.__broadcast_seq)
+       goto bc_out;
+
       /* Check whether we are eligible for wakeup.  */
       val = cond->__data.__wakeup_seq;
       if (val != seq && cond->__data.__woken_seq != val)
@@ -178,6 +190,7 @@ __pthread_cond_timedwait (cond, mutex, abstime)
   /* Another thread woken up.  */
   ++cond->__data.__woken_seq;
 
+ bc_out:
   /* We are done with the condvar.  */
   lll_mutex_unlock (cond->__data.__lock);
 
index 01415bf..a05060a 100644 (file)
@@ -32,6 +32,7 @@ struct _condvar_cleanup_buffer
   int oldtype;
   pthread_cond_t *cond;
   pthread_mutex_t *mutex;
+  unsigned int bc_seq;
 };
 
 
@@ -45,10 +46,13 @@ __condvar_cleanup (void *arg)
   /* We are going to modify shared data.  */
   lll_mutex_lock (cbuffer->cond->__data.__lock);
 
-  /* This thread is not waiting anymore.  Adjust the sequence counters
-     appropriately.  */
-  ++cbuffer->cond->__data.__wakeup_seq;
-  ++cbuffer->cond->__data.__woken_seq;
+  if (cbuffer->bc_seq == cbuffer->cond->__data.__broadcast_seq)
+    {
+      /* This thread is not waiting anymore.  Adjust the sequence counters
+        appropriately.  */
+      ++cbuffer->cond->__data.__wakeup_seq;
+      ++cbuffer->cond->__data.__woken_seq;
+    }
 
   /* We are done.  */
   lll_mutex_unlock (cbuffer->cond->__data.__lock);
@@ -111,6 +115,8 @@ __pthread_cond_wait (cond, mutex)
   unsigned long long int val;
   unsigned long long int seq;
   val = seq = cond->__data.__wakeup_seq;
+  /* Remember the broadcast counter.  */
+  cbuffer.bc_seq = cond->__data.__broadcast_seq;
 
   /* The futex syscall operates on a 32-bit word.  That is fine, we
      just use the low 32 bits of the sequence counter.  */
@@ -137,6 +143,10 @@ __pthread_cond_wait (cond, mutex)
       /* Disable asynchronous cancellation.  */
       __pthread_disable_asynccancel (cbuffer.oldtype);
 
+      /* If a broadcast happened, we are done.  */
+      if (cbuffer.bc_seq != cond->__data.__broadcast_seq)
+       goto bc_out;
+
       /* We are going to look at shared data again, so get the lock.  */
       lll_mutex_lock (cond->__data.__lock);
 
@@ -148,6 +158,7 @@ __pthread_cond_wait (cond, mutex)
   /* Another thread woken up.  */
   ++cond->__data.__woken_seq;
 
+ bc_out:
   /* We are done with the condvar.  */
   lll_mutex_unlock (cond->__data.__lock);
 
index 0fed5cc..1bb2968 100644 (file)
@@ -81,6 +81,7 @@ typedef union
     unsigned long long int __wakeup_seq;
     unsigned long long int __woken_seq;
     void *__mutex;
+    unsigned int __broadcast_seq;
   } __data;
   char __size[__SIZEOF_PTHREAD_COND_T];
   long long int __align;
index f998138..9da84c6 100644 (file)
@@ -81,6 +81,7 @@ typedef union
     unsigned long long int __wakeup_seq;
     unsigned long long int __woken_seq;
     void *__mutex;
+    unsigned int __broadcast_seq;
   } __data;
   char __size[__SIZEOF_PTHREAD_COND_T];
   long long int __align;
index 8d09e22..456f3db 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -74,6 +74,9 @@ __pthread_cond_broadcast:
           woken up.  */
 3:     movl    %ecx, (%ebx)
        movl    %eax, 4(%ebx)
+       movl    %ecx, woken_seq-wakeup_seq(%ebx)
+       movl    %eax, woken_seq-wakeup_seq+4(%ebx)
+       addl    $1, broadcast_seq-wakeup_seq(%ebx)
 
        /* Get the address of the mutex used.  */
        movl    dep_mutex-wakeup_seq(%ebx), %edi
index acc5a6a..c0fd1a9 100644 (file)
@@ -83,15 +83,17 @@ __pthread_cond_timedwait:
        addl    $1, total_seq(%ebx)
        adcl    $0, total_seq+4(%ebx)
 
-#define FRAME_SIZE 20
+#define FRAME_SIZE 24
        subl    $FRAME_SIZE, %esp
 .Lsubl:
 
        /* Get and store current wakeup_seq value.  */
        movl    wakeup_seq(%ebx), %edi
        movl    wakeup_seq+4(%ebx), %edx
+       movl    broadcast_seq(%ebx), %eax
        movl    %edi, 12(%esp)
        movl    %edx, 16(%esp)
+       movl    %eax, 20(%esp)
 
        /* Get the current time.  */
 8:     movl    %ebx, %edx
@@ -139,7 +141,8 @@ __pthread_cond_timedwait:
        addl    $1000000000, %edx
        subl    $1, %ecx
 12:    testl   %ecx, %ecx
-       js      13f
+       movl    $-ETIMEDOUT, %esi
+       js      6f
 
        /* Store relative timeout.  */
 21:    movl    %ecx, 4(%esp)
@@ -184,7 +187,11 @@ __pthread_cond_timedwait:
 #endif
        jnz     5f
 
-6:     movl    woken_seq(%ebx), %eax
+6:     movl    broadcast_seq(%ebx), %eax
+       cmpl    20(%esp), %eax
+       jne     23f
+
+       movl    woken_seq(%ebx), %eax
        movl    woken_seq+4(%ebx), %ecx
 
        movl    wakeup_seq(%ebx), %edi
@@ -203,16 +210,19 @@ __pthread_cond_timedwait:
 15:    cmpl    $-ETIMEDOUT, %esi
        jne     8b
 
-13:    addl    $1, wakeup_seq(%ebx)
+       addl    $1, wakeup_seq(%ebx)
        adcl    $0, wakeup_seq+4(%ebx)
        movl    $ETIMEDOUT, %esi
        jmp     14f
 
+23:    xorl    %esi, %esi
+       jmp     24f
+
 9:     xorl    %esi, %esi
 14:    addl    $1, woken_seq(%ebx)
        adcl    $0, woken_seq+4(%ebx)
 
-       LOCK
+24:    LOCK
 #if cond_lock == 0
        subl    $1, (%ebx)
 #else
@@ -332,7 +342,8 @@ __pthread_cond_timedwait:
        addl    $1000000000, %edx
        subl    $1, %ecx
 20:    testl   %ecx, %ecx
-       js      13b
+       movl    $-ETIMEDOUT, %esi
+       js      6b
        jmp     21b
 #endif
        .size   __pthread_cond_timedwait, .-__pthread_cond_timedwait
@@ -372,13 +383,17 @@ __condvar_tw_cleanup:
 #endif
        call    __lll_mutex_lock_wait
 
-1:     addl    $1, wakeup_seq(%ebx)
+1:     movl    broadcast_seq(%ebx), %eax
+       cmpl    12(%esp), %eax
+       jne     3f
+
+       addl    $1, wakeup_seq(%ebx)
        adcl    $0, wakeup_seq+4(%ebx)
 
        addl    $1, woken_seq(%ebx)
        adcl    $0, woken_seq+4(%ebx)
 
-       LOCK
+3:     LOCK
 #if cond_lock == 0
        subl    $1, (%ebx)
 #else
index 08a0588..74e3172 100644 (file)
@@ -80,15 +80,17 @@ __pthread_cond_wait:
        addl    $1, total_seq(%ebx)
        adcl    $0, total_seq+4(%ebx)
 
-#define FRAME_SIZE 12
+#define FRAME_SIZE 16
        subl    $FRAME_SIZE, %esp
 .Lsubl:
 
        /* Get and store current wakeup_seq value.  */
        movl    wakeup_seq(%ebx), %edi
        movl    wakeup_seq+4(%ebx), %edx
+       movl    broadcast_seq(%ebx), %eax
        movl    %edi, 4(%esp)
        movl    %edx, 8(%esp)
+       movl    %eax, 12(%esp)
 
        /* Unlock.  */
 8:     LOCK
@@ -127,7 +129,11 @@ __pthread_cond_wait:
 #endif
        jnz     5f
 
-6:     movl    woken_seq(%ebx), %eax
+6:     movl    broadcast_seq(%ebx), %eax
+       cmpl    12(%esp), %eax
+       jne     16f
+
+       movl    woken_seq(%ebx), %eax
        movl    woken_seq+4(%ebx), %ecx
 
        movl    wakeup_seq(%ebx), %edi
@@ -146,7 +152,8 @@ __pthread_cond_wait:
 9:     addl    $1, woken_seq(%ebx)
        adcl    $0, woken_seq+4(%ebx)
 
-       LOCK
+       /* Unlock */
+16:    LOCK
 #if cond_lock == 0
        subl    $1, (%ebx)
 #else
@@ -264,13 +271,17 @@ __condvar_w_cleanup:
 #endif
        call    __lll_mutex_lock_wait
 
-1:     addl    $1, wakeup_seq(%ebx)
+1:     movl    broadcast_seq(%ebx), %eax
+       cmpl    12(%esp), %eax
+       jne     3f
+
+       addl    $1, wakeup_seq(%ebx)
        adcl    $0, wakeup_seq+4(%ebx)
 
        addl    $1, woken_seq(%ebx)
        adcl    $0, woken_seq+4(%ebx)
 
-       LOCK
+3:     LOCK
 #if cond_lock == 0
        subl    $1, (%ebx)
 #else
index e4c15d1..bdf3ee7 100644 (file)
@@ -81,6 +81,7 @@ typedef union
     unsigned long long int __wakeup_seq;
     unsigned long long int __woken_seq;
     void *__mutex;
+    unsigned int __broadcast_seq;
   } __data;
   char __size[__SIZEOF_PTHREAD_COND_T];
   long int __align;
index 1463e08..d0559da 100644 (file)
@@ -9,3 +9,4 @@ total_seq       offsetof (pthread_cond_t, __data.__total_seq)
 wakeup_seq     offsetof (pthread_cond_t, __data.__wakeup_seq)
 woken_seq      offsetof (pthread_cond_t, __data.__woken_seq)
 dep_mutex      offsetof (pthread_cond_t, __data.__mutex)
+broadcast_seq  offsetof (pthread_cond_t, __data.__broadcast_seq)
index d6d94cd..794d888 100644 (file)
@@ -101,6 +101,7 @@ typedef union
     unsigned long long int __wakeup_seq;
     unsigned long long int __woken_seq;
     void *__mutex;
+    unsigned int __broadcast_seq;
   } __data;
   char __size[__SIZEOF_PTHREAD_COND_T];
   long long int __align;
index e2606af..02b061b 100644 (file)
@@ -100,6 +100,7 @@ typedef union
     unsigned long long int __wakeup_seq;
     unsigned long long int __woken_seq;
     void *__mutex;
+    unsigned int __broadcast_seq;
   } __data;
   char __size[__SIZEOF_PTHREAD_COND_T];
   long long int __align;
index d123fd0..b0c1372 100644 (file)
@@ -101,6 +101,7 @@ typedef union
     unsigned long long int __wakeup_seq;
     unsigned long long int __woken_seq;
     void *__mutex;
+    unsigned int __broadcast_seq;
   } __data;
   char __size[__SIZEOF_PTHREAD_COND_T];
   long long int __align;
index 1b4820e..e29c775 100644 (file)
@@ -81,6 +81,7 @@ typedef union
     unsigned long long int __wakeup_seq;
     unsigned long long int __woken_seq;
     void *__mutex;
+    unsigned int __broadcast_seq;
   } __data;
   char __size[__SIZEOF_PTHREAD_COND_T];
   long int __align;
index 8e26681..6d29d76 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -63,6 +63,8 @@ __pthread_cond_broadcast:
        /* Cause all currently waiting threads to recognize they are
           woken up.  */
        movq    %rcx, (%rdi)
+       movq    %rcx, woken_seq-wakeup_seq(%rdi)
+       incl    broadcast_seq-wakeup_seq(%rdi)
 
        /* Get the address of the mutex used.  */
        movq    dep_mutex-wakeup_seq(%rdi), %r8
@@ -110,12 +112,12 @@ __pthread_cond_broadcast:
 #endif
        jmp     2b
 
-       /* Unlock in loop requires waekup.  */
+       /* Unlock in loop requires wakeup.  */
 5:     addq    $cond_lock-wakeup_seq, %rdi
        callq   __lll_mutex_unlock_wake
        jmp     6b
 
-       /* Unlock in loop requires waekup.  */
+       /* Unlock in loop requires wakeup.  */
 7:     addq    $cond_lock-wakeup_seq, %rdi
        callq   __lll_mutex_unlock_wake
        subq    $cond_lock-wakeup_seq, %rdi
index f6b6ab2..80cbf7e 100644 (file)
@@ -51,7 +51,8 @@ __pthread_cond_timedwait:
 .Lpush_r13:
        pushq   %r14
 .Lpush_r14:
-       subq    $80, %rsp
+#define FRAME_SIZE 80
+       subq    $FRAME_SIZE, %rsp
 .Lsubq:
        /* Stack frame:
 
@@ -67,6 +68,8 @@ __pthread_cond_timedwait:
                    +--------------------------+
           rsp +  8 | condvar pointer          |
                    +--------------------------+
+          rsp +  4 | old broadcast_seq value  |
+                   +--------------------------+
           rsp +  0 | old cancellation mode    |
                    +--------------------------+
        */
@@ -116,7 +119,9 @@ __pthread_cond_timedwait:
        /* Get and store current wakeup_seq value.  */
        movq    8(%rsp), %rdi
        movq    wakeup_seq(%rdi), %r12
+       movl    broadcast_seq(%rdi), %edx
        movq    %r12, 40(%rsp)
+       movl    %edx, 4(%rsp)
 
        /* Get the current time.  */
 8:
@@ -160,7 +165,8 @@ __pthread_cond_timedwait:
        decq    %rcx
 12:    testq   %rcx, %rcx
        movq    8(%rsp), %rdi
-       js      13f
+       movq    $-ETIMEDOUT, %r14
+       js      6f
 
        /* Store relative timeout.  */
 21:    movq    %rcx, 24(%rsp)
@@ -201,10 +207,15 @@ __pthread_cond_timedwait:
 #endif
        jne     5f
 
-6:     movq    woken_seq(%rdi), %rax
+6:     movl    broadcast_seq(%rdi), %edx
+
+       movq    woken_seq(%rdi), %rax
 
        movq    wakeup_seq(%rdi), %r12
 
+       cmpl    4(%rsp), %edx
+       jne     23f
+
        cmpq    40(%rsp), %r12
        jbe     15f
 
@@ -218,10 +229,13 @@ __pthread_cond_timedwait:
        movq    $ETIMEDOUT, %r14
        jmp     14f
 
+23:    xorq    %r14, %r14
+       jmp     24f
+
 9:     xorq    %r14, %r14
 14:    incq    woken_seq(%rdi)
 
-       LOCK
+24:    LOCK
 #if cond_lock == 0
        decl    (%rdi)
 #else
@@ -239,7 +253,7 @@ __pthread_cond_timedwait:
        testq   %rax, %rax
        cmoveq  %r14, %rax
 
-18:    addq    $80, %rsp
+18:    addq    $FRAME_SIZE, %rsp
 .Laddq:
        popq    %r14
 .Lpop_r14:
@@ -259,7 +273,7 @@ __pthread_cond_timedwait:
        callq   __lll_mutex_lock_wait
        jmp     2b
 
-       /* Unlock in loop requires waekup.  */
+       /* Unlock in loop requires wakeup.  */
 3:
 #if cond_lock != 0
        addq    $cond_lock, %rdi
@@ -278,7 +292,7 @@ __pthread_cond_timedwait:
 #endif
        jmp     6b
 
-       /* Unlock after loop requires waekup.  */
+       /* Unlock after loop requires wakeup.  */
 10:
 #if cond_lock != 0
        addq    $cond_lock, %rdi
@@ -325,7 +339,8 @@ __pthread_cond_timedwait:
        decq    %rcx
 20:    testq   %rcx, %rcx
        movq    8(%rsp), %rdi
-       js      13b
+       movq    $-ETIMEDOUT, %r14
+       js      6b
        jmp     21b
 #endif
 .LENDCODE:
@@ -394,7 +409,7 @@ versioned_symbol (libpthread, __pthread_cond_timedwait, pthread_cond_timedwait,
        .uleb128 4
        .byte   0x40+.Lsubq-.Lpush_r14          # DW_CFA_advance_loc+N
        .byte   14                              # DW_CFA_def_cfa_offset
-       .uleb128 112
+       .uleb128 32+FRAME_SIZE
        .byte   3                               # DW_CFA_advance_loc2
        .2byte  .Laddq-.Lsubq
        .byte   14                              # DW_CFA_def_cfa_offset
@@ -413,7 +428,7 @@ versioned_symbol (libpthread, __pthread_cond_timedwait, pthread_cond_timedwait,
        .byte   0xcc                            # DW_CFA_restore %r12
        .byte   0x40+.LSbl1-.Lpop_r12           # DW_CFA_advance_loc+N
        .byte   14                              # DW_CFA_def_cfa_offset
-       .uleb128 112
+       .uleb128 32+FRAME_SIZE
        .byte   0x8c                            # DW_CFA_offset %r12
        .uleb128 2
        .byte   0x8d                            # DW_CFA_offset %r13
index e572874..065eb11 100644 (file)
@@ -61,11 +61,15 @@ __condvar_cleanup:
        subq    $cond_lock, %rdi
 #endif
 
-1:     incq    wakeup_seq(%rdi)
+1:     movl    broadcast_seq(%rdi), %edx
+       cmpl    4(%r8), %edx
+       jne     3f
+
+       incq    wakeup_seq(%rdi)
 
        incq    woken_seq(%rdi)
 
-       LOCK
+3:     LOCK
 #if cond_lock == 0
        decl    (%rdi)
 #else
@@ -99,20 +103,23 @@ __pthread_cond_wait:
 .LSTARTCODE:
        pushq   %r12
 .Lpush_r12:
-       subq    $64, %rsp
+#define FRAME_SIZE 64
+       subq    $FRAME_SIZE, %rsp
 .Lsubq:
        /* Stack frame:
 
           rsp + 64
                    +--------------------------+
           rsp + 32 | cleanup buffer           |
-                   +--------------------------+
+                   +--------------------------+
           rsp + 24 | old wake_seq value       |
                    +--------------------------+
           rsp + 16 | mutex pointer            |
                    +--------------------------+
           rsp +  8 | condvar pointer          |
                    +--------------------------+
+          rsp +  4 | old broadcast_seq value  |
+                   +--------------------------+
           rsp +  0 | old cancellation mode    |
                    +--------------------------+
        */
@@ -161,7 +168,9 @@ __pthread_cond_wait:
        /* Get and store current wakeup_seq value.  */
        movq    8(%rsp), %rdi
        movq    wakeup_seq(%rdi), %r12
+       movl    broadcast_seq(%rdi), %edx
        movq    %r12, 24(%rsp)
+       movl    %edx, 4(%rsp)
 
        /* Unlock.  */
 8:     LOCK
@@ -198,10 +207,15 @@ __pthread_cond_wait:
 #endif
        jnz     5f
 
-6:     movq    woken_seq(%rdi), %rax
+6:     movl    broadcast_seq(%rdi), %edx
+
+       movq    woken_seq(%rdi), %rax
 
        movq    wakeup_seq(%rdi), %r12
 
+       cmpl    4(%rsp), %edx
+       jne     16f
+
        cmpq    24(%rsp), %r12
        jbe     8b
 
@@ -210,7 +224,8 @@ __pthread_cond_wait:
 
        incq    woken_seq(%rdi)
 
-       LOCK
+       /* Unlock */
+16:    LOCK
 #if cond_lock == 0
        decl    (%rdi)
 #else
@@ -224,7 +239,7 @@ __pthread_cond_wait:
 
        movq    16(%rsp), %rdi
        callq   __pthread_mutex_cond_lock
-14:    addq    $64, %rsp
+14:    addq    $FRAME_SIZE, %rsp
 .Laddq:
 
        popq    %r12
@@ -242,7 +257,7 @@ __pthread_cond_wait:
        callq   __lll_mutex_lock_wait
        jmp     2b
 
-       /* Unlock in loop requires waekup.  */
+       /* Unlock in loop requires wakeup.  */
 3:
 #if cond_lock != 0
        addq    $cond_lock, %rdi
@@ -343,7 +358,7 @@ versioned_symbol (libpthread, __pthread_cond_wait, pthread_cond_wait,
        .uleb128 2
        .byte   0x40+.Lsubq-.Lpush_r12          # DW_CFA_advance_loc+N
        .byte   14                              # DW_CFA_def_cfa_offset
-       .uleb128 80
+       .uleb128 16+FRAME_SIZE
        .byte   2                               # DW_CFA_advance_loc1
        .byte   .Laddq-.Lsubq
        .byte   14                              # DW_CFA_def_cfa_offset
diff --git a/nptl/tst-cond16.c b/nptl/tst-cond16.c
new file mode 100644 (file)
index 0000000..00c27ec
--- /dev/null
@@ -0,0 +1,105 @@
+/* Copyright (C) 2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Jakub Jelinek <jakub@redhat.com>, 2004.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <errno.h>
+#include <pthread.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+pthread_cond_t cv = PTHREAD_COND_INITIALIZER;
+pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
+bool n, exiting;
+FILE *f;
+int count;
+
+void *
+tf (void *dummy)
+{
+  bool loop = true;
+
+  while (loop)
+    {
+      pthread_mutex_lock (&lock);
+      while (n && !exiting)
+       pthread_cond_wait (&cv, &lock);
+      n = true;
+      pthread_mutex_unlock (&lock);
+
+      fputs (".", f);
+
+      pthread_mutex_lock (&lock);
+      n = false;
+      if (exiting)
+       loop = false;
+#ifdef UNLOCK_AFTER_BROADCAST
+      pthread_cond_broadcast (&cv);
+      pthread_mutex_unlock (&lock);
+#else
+      pthread_mutex_unlock (&lock);
+      pthread_cond_broadcast (&cv);
+#endif
+    }
+
+  return NULL;
+}
+
+int
+do_test (void)
+{
+  f = fopen ("/dev/null", "w");
+  if (f == NULL)
+    {
+      printf ("couldn't open /dev/null, %m\n");
+      return 1;
+    }
+
+  count = sysconf (_SC_NPROCESSORS_ONLN);
+  if (count <= 0)
+    count = 1;
+  count *= 4;
+
+  pthread_t th[count];
+  int i, ret;
+  for (i = 0; i < count; ++i)
+    if ((ret = pthread_create (&th[i], NULL, tf, NULL)) != 0)
+      {
+       errno = ret;
+       printf ("pthread_create %d failed: %m\n", i);
+       return 1;
+      }
+
+  struct timespec ts = { .tv_sec = 20, .tv_nsec = 0 };
+  while (nanosleep (&ts, &ts) != 0);
+
+  pthread_mutex_lock (&lock);
+  exiting = true;
+  pthread_mutex_unlock (&lock);
+
+  for (i = 0; i < count; ++i)
+    pthread_join (th[i], NULL);
+
+  fclose (f);
+  return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#define TIMEOUT 40
+#include "../test-skeleton.c"
diff --git a/nptl/tst-cond17.c b/nptl/tst-cond17.c
new file mode 100644 (file)
index 0000000..0586fa5
--- /dev/null
@@ -0,0 +1,2 @@
+#define UNLOCK_AFTER_BROADCAST 1
+#include "tst-cond16.c"
diff --git a/nptl/tst-cond18.c b/nptl/tst-cond18.c
new file mode 100644 (file)
index 0000000..9fd81d2
--- /dev/null
@@ -0,0 +1,117 @@
+/* Copyright (C) 2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Jakub Jelinek <jakub@redhat.com>, 2004.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+
+pthread_cond_t cv = PTHREAD_COND_INITIALIZER;
+pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
+bool exiting;
+int fd, count, spins, nn;
+
+void *
+tf (void *id)
+{
+  pthread_mutex_lock (&lock);
+
+  if ((long) id == 0)
+    {
+      while (!exiting)
+       {
+         if ((spins++ % 1000) == 0)
+           write (fd, ".", 1);
+         pthread_mutex_unlock (&lock);
+
+         pthread_mutex_lock (&lock);
+         int njobs = rand () % (count + 1);
+         nn = njobs;
+         if ((rand () % 30) == 0)
+           pthread_cond_broadcast (&cv);
+         else
+           while (njobs--)
+             pthread_cond_signal (&cv);
+       }
+
+      pthread_cond_broadcast (&cv);
+    }
+  else
+    {
+      while (!exiting)
+       {
+         while (!nn && !exiting)
+           pthread_cond_wait (&cv, &lock);
+         --nn;
+         pthread_mutex_unlock (&lock);
+
+         pthread_mutex_lock (&lock);
+       }
+    }
+
+  pthread_mutex_unlock (&lock);
+  return NULL;
+}
+
+int
+do_test (void)
+{
+  fd = open ("/dev/null", O_WRONLY);
+  if (fd < 0)
+    {
+      printf ("couldn't open /dev/null, %m\n");
+      return 1;
+    }
+
+  count = sysconf (_SC_NPROCESSORS_ONLN);
+  if (count <= 0)
+    count = 1;
+  count *= 8;
+
+  pthread_t th[count + 1];
+  int i, ret;
+
+  for (i = 0; i <= count; ++i)
+    if ((ret = pthread_create (&th[i], NULL, tf, (void *) (long) i)) != 0)
+      {
+       errno = ret;
+       printf ("pthread_create %d failed: %m\n", i);
+       return 1;
+      }
+
+  struct timespec ts = { .tv_sec = 20, .tv_nsec = 0 };
+  while (nanosleep (&ts, &ts) != 0);
+
+  pthread_mutex_lock (&lock);
+  exiting = true;
+  pthread_mutex_unlock (&lock);
+
+  for (i = 0; i < count; ++i)
+    pthread_join (th[i], NULL);
+
+  close (fd);
+  return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#define TIMEOUT 40
+#include "../test-skeleton.c"