* pthread-errnos.sym: Add EOVERFLOW.
authorUlrich Drepper <drepper@redhat.com>
Thu, 10 Jan 2008 18:34:43 +0000 (18:34 +0000)
committerUlrich Drepper <drepper@redhat.com>
Thu, 10 Jan 2008 18:34:43 +0000 (18:34 +0000)
* sysdeps/unix/sysv/linux/structsem.sym: Add SEM_VALUE_MAX.
* sysdeps/unix/sysv/linux/sem_post.c: Don't overflow value field.
* sysdeps/unix/sysv/linux/i386/i486/sem_post.S: Likewise.
* sysdeps/unix/sysv/linux/x86_64/sem_post.S: Likewise.

malloc/malloc.c
nptl/ChangeLog
nptl/pthread-errnos.sym
nptl/sysdeps/unix/sysv/linux/i386/i486/sem_post.S
nptl/sysdeps/unix/sysv/linux/sem_post.c
nptl/sysdeps/unix/sysv/linux/structsem.sym
nptl/sysdeps/unix/sysv/linux/x86_64/sem_post.S

index 17dd0a9..e00eb0f 100644 (file)
@@ -3781,7 +3781,8 @@ public_mEMALIGn(size_t alignment, size_t bytes)
       }
 #endif
     }
-  }
+  } else
+    (void)mutex_unlock(&ar_ptr->mutex);
   assert(!p || chunk_is_mmapped(mem2chunk(p)) ||
         ar_ptr == arena_for_chunk(mem2chunk(p)));
   return p;
index ec83434..9c37906 100644 (file)
@@ -1,3 +1,11 @@
+2008-01-10  Ulrich Drepper  <drepper@redhat.com>
+
+       * pthread-errnos.sym: Add EOVERFLOW.
+       * sysdeps/unix/sysv/linux/structsem.sym: Add SEM_VALUE_MAX.
+       * sysdeps/unix/sysv/linux/sem_post.c: Don't overflow value field.
+       * sysdeps/unix/sysv/linux/i386/i486/sem_post.S: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/sem_post.S: Likewise.
+
 2007-12-14  Ulrich Drepper  <drepper@redhat.com>
 
        * sysdeps/x86_64/pthreaddef.h (ARCH_RETRY_MMAP): Take additional
index 2bb4d0d..0975b7a 100644 (file)
@@ -8,5 +8,6 @@ EDEADLK         EDEADLK
 EINTR          EINTR
 EINVAL         EINVAL
 ENOSYS         ENOSYS
+EOVERFLOW      EOVERFLOW
 ETIMEDOUT      ETIMEDOUT
 EWOULDBLOCK    EWOULDBLOCK
index ac045b6..2edcdde 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2005, 2007, 2008 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -34,12 +34,21 @@ __new_sem_post:
 
        movl    8(%esp), %ebx
 
+#if VALUE == 0
+       movl    (%ebx), %eax
+#else
+       movl    VALUE(%ebx), %eax
+#endif
+0:     cmpl    $SEM_VALUE_MAX, %eax
+       je      3f
+       leal    1(%eax), %edx
        LOCK
 #if VALUE == 0
-       addl    $1, (%ebx)
+       cmpxchgl %edx, (%ebx)
 #else
-       addl    $1, VALUE(%ebx)
+       cmpxchgl %edx, VALUE(%ebx)
 #endif
+       jnz     0b
 
        cmpl    $0, NWAITERS(%ebx)
        je      2f
@@ -82,6 +91,32 @@ __new_sem_post:
        orl     $-1, %eax
        popl    %ebx
        ret
+
+3:
+#ifdef PIC
+       call    __i686.get_pc_thunk.bx
+#else
+       movl    $5f, %ebx
+5:
+#endif
+       addl    $_GLOBAL_OFFSET_TABLE_, %ebx
+#if USE___THREAD
+# ifdef NO_TLS_DIRECT_SEG_REFS
+       movl    errno@gotntpoff(%ebx), %edx
+       addl    %gs:0, %edx
+       movl    $EOVERFLOW, (%edx)
+# else
+       movl    errno@gotntpoff(%ebx), %edx
+       movl    $EOVERFLOW, %gs:(%edx)
+# endif
+#else
+       call    __errno_location@plt
+       movl    $EOVERFLOW, (%eax)
+#endif
+
+       orl     $-1, %eax
+       popl    %ebx
+       ret
        .size   __new_sem_post,.-__new_sem_post
        versioned_symbol(libpthread, __new_sem_post, sem_post, GLIBC_2_1)
 #if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1)
index 25b676f..58b226f 100644 (file)
@@ -1,5 +1,5 @@
 /* sem_post -- post to a POSIX semaphore.  Generic futex-using version.
-   Copyright (C) 2003, 2004, 2007 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004, 2007, 2008 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
 
@@ -31,7 +31,18 @@ __new_sem_post (sem_t *sem)
 {
   struct new_sem *isem = (struct new_sem *) sem;
 
-  int nr = atomic_increment_val (&isem->value);
+  __typeof (isem->value) cur;
+  do
+    {
+      cur = isem->value;
+      if (isem->value == SEM_VALUE_MAX)
+       {
+         __set_errno (EOVERFLOW);
+         return -1;
+       }
+    }
+  while (atomic_compare_and_exchange_bool_acq (&isem->value, cur + 1, cur));
+
   atomic_full_barrier ();
   if (isem->nwaiters > 0)
     {
index 4f32c68..0e2a15f 100644 (file)
@@ -1,3 +1,4 @@
+#include <limits.h>
 #include <stddef.h>
 #include <sched.h>
 #include <bits/pthreadtypes.h>
@@ -8,3 +9,4 @@
 VALUE          offsetof (struct new_sem, value)
 PRIVATE                offsetof (struct new_sem, private)
 NWAITERS       offsetof (struct new_sem, nwaiters)
+SEM_VALUE_MAX  SEM_VALUE_MAX
index adbbcdf..b4014c6 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2005, 2007, 2008 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
        .type   sem_post,@function
        .align  16
 sem_post:
+#if VALUE == 0
+       movl    (%rdi), %eax
+#else
+       movl    VALUE(%rdi), %eax
+#endif
+0:     cmpl    $SEM_VALUE_MAX, %eax
+       je      3f
+       leal    1(%eax), %esi
        LOCK
 #if VALUE == 0
-       addl    $1, (%rdi)
+       cmpxchgl %esi, (%rdi)
 #else
-       addl    $1, VALUE(%rdi)
+       cmpxchgl %esi, VALUE(%rdi)
 #endif
+       jnz     0b
 
        cmpq    $0, NWAITERS(%rdi)
        je      2f
@@ -54,13 +63,28 @@ sem_post:
 
 1:
 #if USE___THREAD
-       movq    errno@gottpoff(%rip), %rdx
-       movl    $EINVAL, %fs:(%rdx)
+       movl    $EINVAL, %eax
 #else
        callq   __errno_location@plt
-       movl    $EINVAL, (%rax)
+       movl    $EINVAL, %edx
 #endif
+       jmp     4f
 
+3:
+#if USE___THREAD
+       movl    $EOVERFLOW, %eax
+#else
+       callq   __errno_location@plt
+       movl    $EOVERFLOW, %edx
+#endif
+
+4:
+#if USE___THREAD
+       movq    errno@gottpoff(%rip), %rdx
+       movl    %eax, %fs:(%rdx)
+#else
+       movl    %edx, (%rax)
+#endif
        orl     $-1, %eax
        retq
        .size   sem_post,.-sem_post