[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[commits] r2290 - in /fsf/trunk/libc: ./ io/bits/ nptl/ nptl/sysdeps/unix/sysv/linux/ nptl/sysdeps/unix/sysv/linux/i386/i486/ nptl/sys...
- To: commits@xxxxxxxxxx
- Subject: [commits] r2290 - in /fsf/trunk/libc: ./ io/bits/ nptl/ nptl/sysdeps/unix/sysv/linux/ nptl/sysdeps/unix/sysv/linux/i386/i486/ nptl/sys...
- From: eglibc@xxxxxxxxxx
- Date: Sat, 26 May 2007 07:02:21 -0000
Author: eglibc
Date: Sat May 26 00:02:20 2007
New Revision: 2290
Log:
Import glibc-mainline for 2007-05-26
Added:
fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/structsem.sym
fsf/trunk/libc/nptl/tst-sem10.c
fsf/trunk/libc/nptl/tst-sem11.c
fsf/trunk/libc/nptl/tst-sem12.c
Modified:
fsf/trunk/libc/ChangeLog
fsf/trunk/libc/io/bits/fcntl2.h
fsf/trunk/libc/nptl/ChangeLog
fsf/trunk/libc/nptl/Makefile
fsf/trunk/libc/nptl/sem_getvalue.c
fsf/trunk/libc/nptl/sem_init.c
fsf/trunk/libc/nptl/sem_open.c
fsf/trunk/libc/nptl/semaphoreP.h
fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/Makefile
fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_post.S
fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S
fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_wait.S
fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/internaltypes.h
fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sem_post.c
fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sem_timedwait.c
fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sem_wait.c
fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/x86_64/sem_post.S
fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S
fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S
fsf/trunk/libc/nptl/tst-typesizes.c
Modified: fsf/trunk/libc/ChangeLog
==============================================================================
--- fsf/trunk/libc/ChangeLog (original)
+++ fsf/trunk/libc/ChangeLog Sat May 26 00:02:20 2007
@@ -1,3 +1,20 @@
+2007-05-25 Jakub Jelinek <jakub@xxxxxxxxxx>
+
+ * io/bits/fcntl2.h (__open_2): Add nonnull attribute.
+ (open): Fix comment typos. Don't call __open_2 if flags
+ is a compile time constant without O_CREAT.
+ (__open64_2): Add nonnull attribute.
+ (open64): Fix comment typos. Don't call __open64_2 if flags
+ is a compile time constant without O_CREAT.
+ (__openat_2): Add nonnull attribute, fix nonnull attribute
+ on redirect.
+ (openat): Fix comment typos. Don't call __openat_2 if flags
+ is a compile time constant without O_CREAT.
+ (__openat64_2): Add nonnull attribute, fix nonnull attribute
+ on redirect.
+ (openat64): Fix comment typos. Don't call __openat64_2 if flags
+ is a compile time constant without O_CREAT.
+
2007-05-24 Ulrich Drepper <drepper@xxxxxxxxxx>
* Makerules (sysd-rules): Define PTW for ptw-* files.
Modified: fsf/trunk/libc/io/bits/fcntl2.h
==============================================================================
--- fsf/trunk/libc/io/bits/fcntl2.h (original)
+++ fsf/trunk/libc/io/bits/fcntl2.h Sat May 26 00:02:20 2007
@@ -24,7 +24,7 @@
/* Check that calls to open and openat with O_CREAT set have an
appropriate third/fourth parameter. */
#ifndef __USE_FILE_OFFSET64
-extern int __open_2 (__const char *__path, int __oflag);
+extern int __open_2 (__const char *__path, int __oflag) __nonnull ((1));
#else
extern int __REDIRECT (__open_2, (__const char *__file, int __oflag),
__open64_2) __nonnull ((1));
@@ -33,22 +33,27 @@
#define open(fname, flags, ...) \
({ int ___r; \
/* If the compiler complains about an invalid type, excess elements, etc \
- in the initialization this means a paraleter of the wrong type has \
+ in the initialization this means a parameter of the wrong type has \
been passed to open. */ \
int ___arr[] = { __VA_ARGS__ }; \
if (__builtin_constant_p (flags) && ((flags) & O_CREAT) != 0) \
{ \
- /* If the compile complains about the size of this array type the \
- the mode parameter is missing since O_CREAT has been used. */ \
+ /* If the compiler complains about the size of this array type the \
+ mode parameter is missing since O_CREAT has been used. */ \
typedef int __open_missing_mode[((flags) & O_CREAT) != 0 \
? ((long int) sizeof (___arr) \
- (long int) sizeof (int)) : 1]; \
} \
if (sizeof (___arr) == 0) \
- ___r = __open_2 (fname, flags); \
+ { \
+ if (__builtin_constant_p (flags) && ((flags) & O_CREAT) == 0) \
+ ___r = open (fname, flags); \
+ else \
+ ___r = __open_2 (fname, flags); \
+ } \
else \
{ \
- /* If the compile complains about the size of this array type too \
+ /* If the compiler complains about the size of this array type too \
many parameters have been passed to open. */ \
typedef int __open_too_many_args[-(sizeof (___arr) > sizeof (int))]; \
___r = open (fname, flags, ___arr[0]); \
@@ -58,27 +63,32 @@
#ifdef __USE_LARGEFILE64
-extern int __open64_2 (__const char *__path, int __oflag);
+extern int __open64_2 (__const char *__path, int __oflag) __nonnull ((1));
# define open64(fname, flags, ...) \
({ int ___r; \
/* If the compiler complains about an invalid type, excess elements, etc \
- in the initialization this means a paraleter of the wrong type has \
+ in the initialization this means a parameter of the wrong type has \
been passed to open64. */ \
int ___arr[] = { __VA_ARGS__ }; \
if (__builtin_constant_p (flags) && ((flags) & O_CREAT) != 0) \
{ \
- /* If the compile complains about the size of this array type the \
- the mode parameter is missing since O_CREAT has been used. */ \
+ /* If the compiler complains about the size of this array type the \
+ mode parameter is missing since O_CREAT has been used. */ \
typedef int __open_missing_mode[((flags) & O_CREAT) != 0 \
? ((long int) sizeof (___arr) \
- (long int) sizeof (int)) : 1]; \
} \
if (sizeof (___arr) == 0) \
- ___r = __open64_2 (fname, flags); \
+ { \
+ if (__builtin_constant_p (flags) && ((flags) & O_CREAT) == 0) \
+ ___r = open64 (fname, flags); \
+ else \
+ ___r = __open64_2 (fname, flags); \
+ } \
else \
{ \
- /* If the compile complains about the size of this array type too \
+ /* If the compiler complains about the size of this array type too \
many parameters have been passed to open64. */ \
typedef int __open_too_many_args[-(sizeof (___arr) > sizeof (int))]; \
___r = open64 (fname, flags, ___arr[0]); \
@@ -89,32 +99,38 @@
#ifdef __USE_ATFILE
# ifndef __USE_FILE_OFFSET64
-extern int __openat_2 (int __fd, __const char *__path, int __oflag);
+extern int __openat_2 (int __fd, __const char *__path, int __oflag)
+ __nonnull ((2));
# else
extern int __REDIRECT (__openat_2, (int __fd, __const char *__file,
int __oflag), __openat64_2)
- __nonnull ((1));
+ __nonnull ((2));
# endif
# define openat(fd, fname, flags, ...) \
({ int ___r; \
/* If the compiler complains about an invalid type, excess elements, etc \
- in the initialization this means a paraleter of the wrong type has \
+ in the initialization this means a parameter of the wrong type has \
been passed to openat. */ \
int ___arr[] = { __VA_ARGS__ }; \
if (__builtin_constant_p (flags) && ((flags) & O_CREAT) != 0) \
{ \
- /* If the compile complains about the size of this array type the \
- the mode parameter is missing since O_CREAT has been used. */ \
+ /* If the compiler complains about the size of this array type the \
+ mode parameter is missing since O_CREAT has been used. */ \
typedef int __open_missing_mode[((flags) & O_CREAT) != 0 \
? ((long int) sizeof (___arr) \
- (long int) sizeof (int)) : 1]; \
} \
if (sizeof (___arr) == 0) \
- ___r = __openat_2 (fd, fname, flags); \
+ { \
+ if (__builtin_constant_p (flags) && ((flags) & O_CREAT) == 0) \
+ ___r = openat (fd, fname, flags); \
+ else \
+ ___r = __openat_2 (fd, fname, flags); \
+ } \
else \
{ \
- /* If the compile complains about the size of this array type too \
+ /* If the compiler complains about the size of this array type too \
many parameters have been passed to openat. */ \
typedef int __open_too_many_args[-(sizeof (___arr) > sizeof (int))]; \
___r = openat (fd, fname, flags, ___arr[0]); \
@@ -124,28 +140,34 @@
# ifdef __USE_LARGEFILE64
-extern int __openat64_2 (int __fd, __const char *__path, int __oflag);
+extern int __openat64_2 (int __fd, __const char *__path, int __oflag)
+ __nonnull ((2));
# define openat64(fd, fname, flags, ...) \
({ int ___r; \
/* If the compiler complains about an invalid type, excess elements, etc \
- in the initialization this means a paraleter of the wrong type has \
+ in the initialization this means a parameter of the wrong type has \
been passed to openat64. */ \
int ___arr[] = { __VA_ARGS__ }; \
if (__builtin_constant_p (flags) && ((flags) & O_CREAT) != 0) \
{ \
- /* If the compile complains about the size of this array type the \
- the mode parameter is missing since O_CREAT has been used. */ \
+ /* If the compiler complains about the size of this array type the \
+ mode parameter is missing since O_CREAT has been used. */ \
typedef int __open_missing_mode[((flags) & O_CREAT) != 0 \
? ((long int) sizeof (___arr) \
- (long int) sizeof (int)) : 1]; \
} \
if (sizeof (___arr) == 0) \
- ___r = __openat64_2 (fd, fname, flags); \
+ { \
+ if (__builtin_constant_p (flags) && ((flags) & O_CREAT) == 0) \
+ ___r = openat64 (fd, fname, flags); \
+ else \
+ ___r = __openat64_2 (fd, fname, flags); \
+ } \
else \
{ \
- /* If the compile complains about the size of this array type too \
- many parameters have been passed to openat. */ \
+ /* If the compiler complains about the size of this array type too \
+ many parameters have been passed to openat64. */ \
typedef int __open_too_many_args[-(sizeof (___arr) > sizeof (int))]; \
___r = openat64 (fd, fname, flags, ___arr[0]); \
} \
Modified: fsf/trunk/libc/nptl/ChangeLog
==============================================================================
--- fsf/trunk/libc/nptl/ChangeLog (original)
+++ fsf/trunk/libc/nptl/ChangeLog Sat May 26 00:02:20 2007
@@ -1,4 +1,49 @@
-2007-04-24 Jakub Jelinek <jakub@xxxxxxxxxx>
+2007-05-25 Ulrich Drepper <drepper@xxxxxxxxxx>
+
+ * sysdeps/unix/sysv/linux/i386/i486/sem_post.S: Add private futex
+ support.
+ * sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S: Likewise.
+ * sysdeps/unix/sysv/linux/i386/i486/sem_wait.S: Likewise.
+ * sysdeps/unix/sysv/linux/x86_64/sem_post.S: Likewise.
+ * sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S: Likewise.
+ * sysdeps/unix/sysv/linux/x86_64/sem_wait.S: Likewise.
+
+ * semaphoreP.h: Declare __old_sem_init and __old_sem_wait.
+ * sem_init.c (__new_sem_init): Rewrite to initialize all three
+ fields in the structure.
+ (__old_sem_init): New function.
+ * sem_open.c: Initialize all fields of the structure.
+ * sem_getvalue.c: Adjust for renamed element.
+ * sysdeps/unix/sysv/linux/Makefile [subdir=nptl]
+ (gen-as-const-headers): Add structsem.sym.
+ * sysdeps/unix/sysv/linux/structsem.sym: New file.
+ * sysdeps/unix/sysv/linux/internaltypes.h: Rename struct sem to
+ struct new_sem. Add struct old_sem.
+ * sysdeps/unix/sysv/linux/sem_post.c: Wake only when there are waiters.
+ * sysdeps/unix/sysv/linux/i386/i486/sem_post.S: Likewise.
+ * sysdeps/unix/sysv/linux/x86_64/sem_post.S: Likewise.
+ * sysdeps/unix/sysv/linux/sem_wait.c: Indicate that there are waiters.
+ * sysdeps/unix/sysv/linux/i386/i486/sem_wait.S: Likewise.
+ * sysdeps/unix/sysv/linux/x86_64/sem_wait.S: Likewise.
+ * sysdeps/unix/sysv/linux/sem_timedwait.c: Likewise.
+ * sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S: Likewise.
+ * sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S: Likewise.
+ * Makefile (tests): Add tst-sem10, tst-sem11, tst-sem12.
+ * tst-sem10.c: New file.
+ * tst-sem11.c: New file.
+ * tst-sem12.c: New file.
+ * tst-typesizes.c: Test struct new_sem and struct old_sem instead
+ of struct sem.
+
+2007-05-25 Ulrich Drepper <drepper@xxxxxxxxxx>
+ Jakub Jelinek <jakub@xxxxxxxxxx>
+
+ * sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S (sem_timedwait):
+ Move __pthread_enable_asynccancel right before futex syscall.
+ * sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S (sem_timedwait):
+ Likewise.
+
+2007-05-24 Jakub Jelinek <jakub@xxxxxxxxxx>
* sysdeps/i386/tls.h (THREAD_SET_PRIVATE_FUTEX,
THREAD_COPY_PRIVATE_FUTEX): Define.
Modified: fsf/trunk/libc/nptl/Makefile
==============================================================================
--- fsf/trunk/libc/nptl/Makefile (original)
+++ fsf/trunk/libc/nptl/Makefile Sat May 26 00:02:20 2007
@@ -218,7 +218,7 @@
tst-once1 tst-once2 tst-once3 tst-once4 \
tst-key1 tst-key2 tst-key3 tst-key4 \
tst-sem1 tst-sem2 tst-sem3 tst-sem4 tst-sem5 tst-sem6 tst-sem7 \
- tst-sem8 tst-sem9 \
+ tst-sem8 tst-sem9 tst-sem10 tst-sem11 tst-sem12 \
tst-barrier1 tst-barrier2 tst-barrier3 tst-barrier4 \
tst-align tst-align2 tst-align3 \
tst-basic1 tst-basic2 tst-basic3 tst-basic4 tst-basic5 tst-basic6 \
Modified: fsf/trunk/libc/nptl/sem_getvalue.c
==============================================================================
--- fsf/trunk/libc/nptl/sem_getvalue.c (original)
+++ fsf/trunk/libc/nptl/sem_getvalue.c Sat May 26 00:02:20 2007
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@xxxxxxxxxx>, 2002.
@@ -27,11 +27,11 @@
sem_t *sem;
int *sval;
{
- struct sem *isem = (struct sem *) sem;
+ struct new_sem *isem = (struct new_sem *) sem;
/* XXX Check for valid SEM parameter. */
- *sval = isem->count;
+ *sval = isem->value;
return 0;
}
Modified: fsf/trunk/libc/nptl/sem_init.c
==============================================================================
--- fsf/trunk/libc/nptl/sem_init.c (original)
+++ fsf/trunk/libc/nptl/sem_init.c Sat May 26 00:02:20 2007
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@xxxxxxxxxx>, 2002.
@@ -22,6 +22,7 @@
#include <lowlevellock.h>
#include <shlib-compat.h>
#include "semaphoreP.h"
+#include <kernel-features.h>
int
@@ -38,18 +39,50 @@
}
/* Map to the internal type. */
- struct sem *isem = (struct sem *) sem;
+ struct new_sem *isem = (struct new_sem *) sem;
- /* Use the value the user provided. */
- isem->count = value;
+ /* Use the values the user provided. */
+ isem->value = value;
+#ifdef __ASSUME_PRIVATE_FUTEX
+ isem->private = pshared ? 0 : FUTEX_PRIVATE_FLAG;
+#else
+ isem->private = pshared ? 0 : THREAD_GETMEM (THREAD_SELF,
+ header.private_futex);
+#endif
- /* We can completely ignore the PSHARED parameter since inter-process
- use needs no special preparation. */
+ isem->nwaiters = 0;
return 0;
}
versioned_symbol (libpthread, __new_sem_init, sem_init, GLIBC_2_1);
+
+
+
#if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1)
-strong_alias (__new_sem_init, __old_sem_init)
+int
+attribute_compat_text_section
+__old_sem_init (sem, pshared, value)
+ sem_t *sem;
+ int pshared;
+ unsigned int value;
+{
+ /* Parameter sanity check. */
+ if (__builtin_expect (value > SEM_VALUE_MAX, 0))
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ /* Map to the internal type. */
+ struct old_sem *isem = (struct old_sem *) sem;
+
+ /* Use the value the user provided. */
+ isem->value = value;
+
+ /* We cannot store the PSHARED attribute. So we always use the
+ operations needed for shared semaphores. */
+
+ return 0;
+}
compat_symbol (libpthread, __old_sem_init, sem_init, GLIBC_2_0);
#endif
Modified: fsf/trunk/libc/nptl/sem_open.c
==============================================================================
--- fsf/trunk/libc/nptl/sem_open.c (original)
+++ fsf/trunk/libc/nptl/sem_open.c Sat May 26 00:02:20 2007
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2006, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@xxxxxxxxxx>, 2002.
@@ -304,12 +304,14 @@
/* Create the initial file content. */
sem_t initsem;
- struct sem *iinitsem = (struct sem *) &initsem;
- iinitsem->count = value;
+ struct new_sem *iinitsem = (struct new_sem *) &initsem;
+ iinitsem->value = value;
+ iinitsem->private = 0;
+ iinitsem->nwaiters = 0;
/* Initialize the remaining bytes as well. */
- memset ((char *) &initsem + sizeof (struct sem), '\0',
- sizeof (sem_t) - sizeof (struct sem));
+ memset ((char *) &initsem + sizeof (struct new_sem), '\0',
+ sizeof (sem_t) - sizeof (struct new_sem));
tmpfname = (char *) alloca (mountpoint.dirlen + 6 + 1);
char *xxxxxx = __mempcpy (tmpfname, mountpoint.dir, mountpoint.dirlen);
Modified: fsf/trunk/libc/nptl/semaphoreP.h
==============================================================================
--- fsf/trunk/libc/nptl/semaphoreP.h (original)
+++ fsf/trunk/libc/nptl/semaphoreP.h Sat May 26 00:02:20 2007
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2006, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@xxxxxxxxxx>, 2002.
@@ -60,8 +60,10 @@
/* Prototypes of functions with multiple interfaces. */
extern int __new_sem_init (sem_t *sem, int pshared, unsigned int value);
+extern int __old_sem_init (sem_t *sem, int pshared, unsigned int value);
extern int __new_sem_destroy (sem_t *sem);
extern int __new_sem_post (sem_t *sem);
extern int __new_sem_wait (sem_t *sem);
+extern int __old_sem_wait (sem_t *sem);
extern int __new_sem_trywait (sem_t *sem);
extern int __new_sem_getvalue (sem_t *sem, int *sval);
Modified: fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/Makefile
==============================================================================
--- fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/Makefile (original)
+++ fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/Makefile Sat May 26 00:02:20 2007
@@ -1,4 +1,4 @@
-# Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+# Copyright (C) 2002,2003,2004,2005,2006,2007 Free Software Foundation, Inc.
# This file is part of the GNU C Library.
# Contributed by Ulrich Drepper <drepper@xxxxxxxxxx>, 2002.
@@ -25,7 +25,8 @@
gen-as-const-headers += lowlevelcond.sym lowlevelrwlock.sym \
lowlevelbarrier.sym unwindbuf.sym \
- lowlevelrobustlock.sym pthread-pi-defines.sym
+ lowlevelrobustlock.sym pthread-pi-defines.sym \
+ structsem.sym
endif
ifeq ($(subdir),posix)
Modified: fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_post.S
==============================================================================
--- fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_post.S (original)
+++ fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_post.S Sat May 26 00:02:20 2007
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@xxxxxxxxxx>, 2002.
@@ -20,6 +20,7 @@
#include <sysdep.h>
#include <shlib-compat.h>
#include <pthread-errnos.h>
+#include <structsem.h>
#ifndef UP
# define LOCK lock
@@ -40,19 +41,27 @@
pushl %ebx
movl 8(%esp), %ebx
+
+ LOCK
+#if VALUE == 0
+ addl $1, (%ebx)
+#else
+ addl $1, VALUE(%ebx)
+#endif
+
+ cmpl $0, NWAITERS(%ebx)
+ je 2f
+
+ movl $FUTEX_WAKE, %ecx
+ orl PRIVATE(%ebx), %ecx
movl $1, %edx
- LOCK
- xaddl %edx, (%ebx)
-
movl $SYS_futex, %eax
- movl $FUTEX_WAKE, %ecx
- addl $1, %edx
ENTER_KERNEL
testl %eax, %eax
js 1f
- xorl %eax, %eax
+2: xorl %eax, %eax
popl %ebx
ret
Modified: fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S
==============================================================================
--- fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S (original)
+++ fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S Sat May 26 00:02:20 2007
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@xxxxxxxxxx>, 2002.
@@ -20,6 +20,7 @@
#include <sysdep.h>
#include <shlib-compat.h>
#include <pthread-errnos.h>
+#include <structsem.h>
#ifndef UP
# define LOCK lock
@@ -29,7 +30,12 @@
#define SYS_gettimeofday __NR_gettimeofday
#define SYS_futex 240
-#define FUTEX_WAKE 1
+#define FUTEX_WAIT 0
+
+
+#if VALUE != 0
+# error "code needs to be rewritten for VALUE != 0"
+#endif
.text
@@ -37,14 +43,8 @@
.globl sem_timedwait
.type sem_timedwait,@function
.align 16
- cfi_startproc
sem_timedwait:
- /* First check for cancellation. */
- movl %gs:CANCELHANDLING, %eax
- andl $0xfffffff9, %eax
- cmpl $8, %eax
- je 10f
-
+.LSTARTCODE:
movl 4(%esp), %ecx
movl (%ecx), %eax
@@ -61,28 +61,25 @@
/* Check whether the timeout value is valid. */
1: pushl %esi
- cfi_adjust_cfa_offset(4)
+.Lpush_esi:
pushl %edi
- cfi_adjust_cfa_offset(4)
+.Lpush_edi:
pushl %ebx
- cfi_adjust_cfa_offset(4)
+.Lpush_ebx:
subl $12, %esp
- cfi_adjust_cfa_offset(12)
+.Lsub_esp:
movl 32(%esp), %edi
- cfi_offset(7, -12) /* %edi */
/* Check for invalid nanosecond field. */
cmpl $1000000000, 4(%edi)
movl $EINVAL, %esi
- cfi_offset(6, -8) /* %esi */
jae 6f
- cfi_offset(3, -16) /* %ebx */
-7: call __pthread_enable_asynccancel
- movl %eax, 8(%esp)
-
- xorl %ecx, %ecx
+ LOCK
+ incl NWAITERS(%ecx)
+
+7: xorl %ecx, %ecx
movl %esp, %ebx
movl %ecx, %edx
movl $SYS_gettimeofday, %eax
@@ -105,16 +102,27 @@
movl %ecx, (%esp) /* Store relative timeout. */
movl %edx, 4(%esp)
- movl 28(%esp), %ebx
- xorl %ecx, %ecx
+
+.LcleanupSTART:
+ call __pthread_enable_asynccancel
+ movl %eax, 8(%esp)
+
+ movl 28(%esp), %ebx /* Load semaphore address. */
+#if FUTEX_WAIT == 0
+ movl PRIVATE(%ebx), %ecx
+#else
+ movl $FUTEX_WAIT, %ecx
+ orl PRIVATE(%ebx), %ecx
+#endif
movl %esp, %esi
+ xorl %edx, %edx
movl $SYS_futex, %eax
- xorl %edx, %edx
ENTER_KERNEL
movl %eax, %esi
movl 8(%esp), %eax
call __pthread_disable_asynccancel
+.LcleanupEND:
testl %esi, %esi
je 9f
@@ -130,24 +138,22 @@
cmpxchgl %ecx, (%ebx)
jne 8b
+ xorl %eax, %eax
+
+10: LOCK
+ decl NWAITERS(%ebx)
+
addl $12, %esp
- cfi_adjust_cfa_offset(-12)
- xorl %eax, %eax
+.Ladd_esp:
popl %ebx
- cfi_adjust_cfa_offset(-4)
- cfi_restore(3)
+.Lpop_ebx:
popl %edi
- cfi_adjust_cfa_offset(-4)
- cfi_restore(7)
+.Lpop_edi:
popl %esi
- cfi_adjust_cfa_offset(-4)
- cfi_restore(6)
+.Lpop_esi:
ret
- cfi_adjust_cfa_offset(24)
- cfi_offset(6, -8) /* %esi */
- cfi_offset(7, -12) /* %edi */
- cfi_offset(3, -16) /* %ebx */
+.Lafter_ret:
3: negl %esi
6:
#ifdef PIC
@@ -171,25 +177,163 @@
movl %esi, (%eax)
#endif
- addl $12, %esp
- cfi_adjust_cfa_offset(-12)
+ movl 28(%esp), %ebx /* Load semaphore address. */
orl $-1, %eax
- popl %ebx
- cfi_adjust_cfa_offset(-4)
- cfi_restore(3)
- popl %edi
- cfi_adjust_cfa_offset(-4)
- cfi_restore(7)
- popl %esi
- cfi_adjust_cfa_offset(-4)
- cfi_restore(6)
- ret
-
-10: /* Canceled. */
- movl $0xffffffff, %gs:RESULT
+ jmp 10b
+ .size sem_timedwait,.-sem_timedwait
+
+
+ .type sem_wait_cleanup,@function
+sem_wait_cleanup:
LOCK
- orl $0x10, %gs:CANCELHANDLING
- movl %gs:CLEANUP_JMP_BUF, %eax
- jmp HIDDEN_JUMPTARGET (__pthread_unwind)
- cfi_endproc
- .size sem_timedwait,.-sem_timedwait
+ decl NWAITERS(%ebx)
+ movl %eax, (%esp)
+.LcallUR:
+ call _Unwind_Resume@PLT
+ hlt
+.LENDCODE:
+ .size sem_wait_cleanup,.-sem_wait_cleanup
+
+
+ .section .gcc_except_table,"a",@progbits
+.LexceptSTART:
+ .byte 0xff # @LPStart format (omit)
+ .byte 0xff # @TType format (omit)
+ .byte 0x01 # call-site format
+ # DW_EH_PE_uleb128
+ .uleb128 .Lcstend-.Lcstbegin
+.Lcstbegin:
+ .uleb128 .LcleanupSTART-.LSTARTCODE
+ .uleb128 .LcleanupEND-.LcleanupSTART
+ .uleb128 sem_wait_cleanup-.LSTARTCODE
+ .uleb128 0
+ .uleb128 .LcallUR-.LSTARTCODE
+ .uleb128 .LENDCODE-.LcallUR
+ .uleb128 0
+ .uleb128 0
+.Lcstend:
+
+
+ .section .eh_frame,"a",@progbits
+.LSTARTFRAME:
+ .long .LENDCIE-.LSTARTCIE # Length of the CIE.
+.LSTARTCIE:
+ .long 0 # CIE ID.
+ .byte 1 # Version number.
+#ifdef SHARED
+ .string "zPLR" # NUL-terminated augmentation
+ # string.
+#else
+ .string "zPL" # NUL-terminated augmentation
+ # string.
+#endif
+ .uleb128 1 # Code alignment factor.
+ .sleb128 -4 # Data alignment factor.
+ .byte 8 # Return address register
+ # column.
+#ifdef SHARED
+ .uleb128 7 # Augmentation value length.
+ .byte 0x9b # Personality: DW_EH_PE_pcrel
+ # + DW_EH_PE_sdata4
+ # + DW_EH_PE_indirect
+ .long DW.ref.__gcc_personality_v0-.
+ .byte 0x1b # LSDA Encoding: DW_EH_PE_pcrel
+ # + DW_EH_PE_sdata4.
+ .byte 0x1b # FDE Encoding: DW_EH_PE_pcrel
+ # + DW_EH_PE_sdata4.
+#else
+ .uleb128 6 # Augmentation value length.
+ .byte 0x0 # Personality: absolute
+ .long __gcc_personality_v0
+ .byte 0x0 # LSDA Encoding: absolute
+#endif
+ .byte 0x0c # DW_CFA_def_cfa
+ .uleb128 4
+ .uleb128 4
+ .byte 0x88 # DW_CFA_offset, column 0x10
+ .uleb128 1
+ .align 4
+.LENDCIE:
+
+ .long .LENDFDE-.LSTARTFDE # Length of the FDE.
+.LSTARTFDE:
+ .long .LSTARTFDE-.LSTARTFRAME # CIE pointer.
+#ifdef SHARED
+ .long .LSTARTCODE-. # PC-relative start address
+ # of the code.
+#else
+ .long .LSTARTCODE # Start address of the code.
+#endif
+ .long .LENDCODE-.LSTARTCODE # Length of the code.
+ .uleb128 4 # Augmentation size
+#ifdef SHARED
+ .long .LexceptSTART-.
+#else
+ .long .LexceptSTART
+#endif
+
+ .byte 4 # DW_CFA_advance_loc4
+ .long .Lpush_esi-.LSTARTCODE
+ .byte 14 # DW_CFA_def_cfa_offset
+ .uleb128 8
+ .byte 0x86 # DW_CFA_offset %esi
+ .uleb128 2
+ .byte 4 # DW_CFA_advance_loc4
+ .long .Lpush_edi-.Lpush_esi
+ .byte 14 # DW_CFA_def_cfa_offset
+ .uleb128 12
+ .byte 0x87 # DW_CFA_offset %edi
+ .uleb128 3
+ .byte 4 # DW_CFA_advance_loc4
+ .long .Lpush_ebx-.Lpush_edi
+ .byte 14 # DW_CFA_def_cfa_offset
+ .uleb128 16
+ .byte 0x83 # DW_CFA_offset %ebx
+ .uleb128 4
+ .byte 4 # DW_CFA_advance_loc4
+ .long .Lsub_esp-.Lpush_ebx
+ .byte 14 # DW_CFA_def_cfa_offset
+ .uleb128 28
+ .byte 4 # DW_CFA_advance_loc4
+ .long .Ladd_esp-.Lsub_esp
+ .byte 14 # DW_CFA_def_cfa_offset
+ .uleb128 16
+ .byte 4 # DW_CFA_advance_loc4
+ .long .Lpop_ebx-.Ladd_esp
+ .byte 14 # DW_CFA_def_cfa_offset
+ .uleb128 12
+ .byte 0xc3 # DW_CFA_restore %ebx
+ .byte 4 # DW_CFA_advance_loc4
+ .long .Lpop_edi-.Lpop_ebx
+ .byte 14 # DW_CFA_def_cfa_offset
+ .uleb128 8
+ .byte 0xc7 # DW_CFA_restore %edi
+ .byte 4 # DW_CFA_advance_loc4
+ .long .Lpop_esi-.Lpop_edi
+ .byte 14 # DW_CFA_def_cfa_offset
+ .uleb128 4
+ .byte 0xc6 # DW_CFA_restore %esi
+ .byte 4 # DW_CFA_advance_loc4
+ .long .Lafter_ret-.Lpop_esi
+ .byte 14 # DW_CFA_def_cfa_offset
+ .uleb128 28
+ .byte 0x86 # DW_CFA_offset %esi
+ .uleb128 2
+ .byte 0x87 # DW_CFA_offset %edi
+ .uleb128 3
+ .byte 0x83 # DW_CFA_offset %ebx
+ .uleb128 4
+ .align 4
+.LENDFDE:
+
+
+#ifdef SHARED
+ .hidden DW.ref.__gcc_personality_v0
+ .weak DW.ref.__gcc_personality_v0
+ .section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits
+ .align 4
+ .type DW.ref.__gcc_personality_v0, @object
+ .size DW.ref.__gcc_personality_v0, 4
+DW.ref.__gcc_personality_v0:
+ .long __gcc_personality_v0
+#endif
Modified: fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_wait.S
==============================================================================
--- fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_wait.S (original)
+++ fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_wait.S Sat May 26 00:02:20 2007
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@xxxxxxxxxx>, 2002.
@@ -20,6 +20,7 @@
#include <sysdep.h>
#include <shlib-compat.h>
#include <pthread-errnos.h>
+#include <structsem.h>
#ifndef UP
# define LOCK lock
@@ -28,34 +29,30 @@
#endif
#define SYS_futex 240
-#define FUTEX_WAKE 1
-
+#define FUTEX_WAIT 0
+
+
+#if VALUE != 0
+# error "code needs to be rewritten for VALUE != 0"
+#endif
.text
.globl __new_sem_wait
.type __new_sem_wait,@function
.align 16
- cfi_startproc
__new_sem_wait:
- /* First check for cancellation. */
- movl %gs:CANCELHANDLING, %eax
- andl $0xfffffff9, %eax
- cmpl $8, %eax
- je 5f
-
+.LSTARTCODE:
pushl %ebx
- cfi_adjust_cfa_offset(4)
+.Lpush_ebx:
pushl %esi
- cfi_adjust_cfa_offset(4)
+.Lpush_esi:
subl $4, %esp
- cfi_adjust_cfa_offset(4)
+.Lsub_esp:
movl 16(%esp), %ebx
- cfi_offset(3, -8) /* %ebx */
-
- cfi_offset(6, -12) /* %esi */
-3: movl (%ebx), %eax
+
+ movl (%ebx), %eax
2: testl %eax, %eax
je 1f
@@ -63,42 +60,66 @@
LOCK
cmpxchgl %edx, (%ebx)
jne 2b
- xorl %eax, %eax
-
- movl 4(%esp), %esi
- cfi_restore(6)
+7: xorl %eax, %eax
+
+9: movl 4(%esp), %esi
movl 8(%esp), %ebx
- cfi_restore(3)
addl $12, %esp
- cfi_adjust_cfa_offset(-12)
+.Ladd_esp:
ret
- cfi_adjust_cfa_offset(12)
- cfi_offset(3, -8) /* %ebx */
- cfi_offset(6, -12) /* %esi */
-1: call __pthread_enable_asynccancel
+.Lafter_ret:
+1: LOCK
+ incl NWAITERS(%ebx)
+
+.LcleanupSTART:
+6: call __pthread_enable_asynccancel
movl %eax, (%esp)
+#if FUTEX_WAIT == 0
+ movl PRIVATE(%ebx), %ecx
+#else
+ movl $FUTEX_WAIT, %ecx
+ orl PRIVATE(%ebx), %ecx
+#endif
xorl %esi, %esi
+ xorl %edx, %edx
movl $SYS_futex, %eax
- movl %esi, %ecx
- movl %esi, %edx
ENTER_KERNEL
movl %eax, %esi
movl (%esp), %eax
call __pthread_disable_asynccancel
+.LcleanupEND:
testl %esi, %esi
- je 3b
+ je 3f
cmpl $-EWOULDBLOCK, %esi
- je 3b
+ jne 4f
+
+3:
+ movl (%ebx), %eax
+5: testl %eax, %eax
+ je 6b
+
+ leal -1(%eax), %edx
+ LOCK
+ cmpxchgl %edx, (%ebx)
+ jne 5b
+
+ LOCK
+ decl NWAITERS(%ebx)
+ jmp 7b
+
+4: LOCK
+ decl NWAITERS(%ebx)
+
negl %esi
#ifdef PIC
call __i686.get_pc_thunk.bx
#else
- movl $4f, %ebx
-4:
+ movl $8f, %ebx
+8:
#endif
addl $_GLOBAL_OFFSET_TABLE_, %ebx
#if USE___THREAD
@@ -115,25 +136,227 @@
movl %esi, (%eax)
#endif
orl $-1, %eax
- movl 4(%esp), %esi
- cfi_restore(6)
+
+ jmp 9b
+ .size __new_sem_wait,.-__new_sem_wait
+ versioned_symbol(libpthread, __new_sem_wait, sem_wait, GLIBC_2_1)
+
+
+ .type sem_wait_cleanup,@function
+sem_wait_cleanup:
+ LOCK
+ decl NWAITERS(%ebx)
+ movl %eax, (%esp)
+.LcallUR:
+ call _Unwind_Resume@PLT
+ hlt
+.LENDCODE:
+ .size sem_wait_cleanup,.-sem_wait_cleanup
+
+
+ .section .gcc_except_table,"a",@progbits
+.LexceptSTART:
+ .byte 0xff # @LPStart format (omit)
+ .byte 0xff # @TType format (omit)
+ .byte 0x01 # call-site format
+ # DW_EH_PE_uleb128
+ .uleb128 .Lcstend-.Lcstbegin
+.Lcstbegin:
+ .uleb128 .LcleanupSTART-.LSTARTCODE
+ .uleb128 .LcleanupEND-.LcleanupSTART
+ .uleb128 sem_wait_cleanup-.LSTARTCODE
+ .uleb128 0
+ .uleb128 .LcallUR-.LSTARTCODE
+ .uleb128 .LENDCODE-.LcallUR
+ .uleb128 0
+ .uleb128 0
+.Lcstend:
+
+
+ .section .eh_frame,"a",@progbits
+.LSTARTFRAME:
+ .long .LENDCIE-.LSTARTCIE # Length of the CIE.
+.LSTARTCIE:
+ .long 0 # CIE ID.
+ .byte 1 # Version number.
+#ifdef SHARED
+ .string "zPLR" # NUL-terminated augmentation
+ # string.
+#else
+ .string "zPL" # NUL-terminated augmentation
+ # string.
+#endif
+ .uleb128 1 # Code alignment factor.
+ .sleb128 -4 # Data alignment factor.
+ .byte 8 # Return address register
+ # column.
+#ifdef SHARED
+ .uleb128 7 # Augmentation value length.
+ .byte 0x9b # Personality: DW_EH_PE_pcrel
+ # + DW_EH_PE_sdata4
+ # + DW_EH_PE_indirect
+ .long DW.ref.__gcc_personality_v0-.
+ .byte 0x1b # LSDA Encoding: DW_EH_PE_pcrel
+ # + DW_EH_PE_sdata4.
+ .byte 0x1b # FDE Encoding: DW_EH_PE_pcrel
+ # + DW_EH_PE_sdata4.
+#else
+ .uleb128 6 # Augmentation value length.
+ .byte 0x0 # Personality: absolute
+ .long __gcc_personality_v0
+ .byte 0x0 # LSDA Encoding: absolute
+#endif
+ .byte 0x0c # DW_CFA_def_cfa
+ .uleb128 4
+ .uleb128 4
+ .byte 0x88 # DW_CFA_offset, column 0x10
+ .uleb128 1
+ .align 4
+.LENDCIE:
+
+ .long .LENDFDE-.LSTARTFDE # Length of the FDE.
+.LSTARTFDE:
+ .long .LSTARTFDE-.LSTARTFRAME # CIE pointer.
+#ifdef SHARED
+ .long .LSTARTCODE-. # PC-relative start address
+ # of the code.
+#else
+ .long .LSTARTCODE # Start address of the code.
+#endif
+ .long .LENDCODE-.LSTARTCODE # Length of the code.
+ .uleb128 4 # Augmentation size
+#ifdef SHARED
+ .long .LexceptSTART-.
+#else
+ .long .LexceptSTART
+#endif
+
+ .byte 4 # DW_CFA_advance_loc4
+ .long .Lpush_ebx-.LSTARTCODE
+ .byte 14 # DW_CFA_def_cfa_offset
+ .uleb128 8
+ .byte 0x83 # DW_CFA_offset %ebx
+ .uleb128 2
+ .byte 4 # DW_CFA_advance_loc4
+ .long .Lpush_esi-.Lpush_ebx
+ .byte 14 # DW_CFA_def_cfa_offset
+ .uleb128 12
+ .byte 0x86 # DW_CFA_offset %esi
+ .uleb128 3
+ .byte 4 # DW_CFA_advance_loc4
+ .long .Lsub_esp-.Lpush_esi
+ .byte 14 # DW_CFA_def_cfa_offset
+ .uleb128 16
+ .byte 4 # DW_CFA_advance_loc4
+ .long .Ladd_esp-.Lsub_esp
+ .byte 14 # DW_CFA_def_cfa_offset
+ .uleb128 4
+ .byte 0xc3 # DW_CFA_restore %ebx
+ .byte 0xc6 # DW_CFA_restore %esi
+ .byte 4 # DW_CFA_advance_loc4
+ .long .Lafter_ret-.Ladd_esp
+ .byte 14 # DW_CFA_def_cfa_offset
+ .uleb128 16
+ .byte 0x83 # DW_CFA_offset %ebx
+ .uleb128 2
+ .byte 0x86 # DW_CFA_offset %esi
+ .uleb128 3
+ .align 4
+.LENDFDE:
+
+
+#ifdef SHARED
+ .hidden DW.ref.__gcc_personality_v0
+ .weak DW.ref.__gcc_personality_v0
+ .section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits
+ .align 4
+ .type DW.ref.__gcc_personality_v0, @object
+ .size DW.ref.__gcc_personality_v0, 4
+DW.ref.__gcc_personality_v0:
+ .long __gcc_personality_v0
+#endif
+
+
+#if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1)
+ .section ".text.compat", "ax"
+ .global __old_sem_wait
+ .type __old_sem_wait,@function
+ .align 16
+ cfi_startproc
+__old_sem_wait:
+ pushl %ebx
+ cfi_adjust_cfa_offset(4)
+ pushl %esi
+ cfi_adjust_cfa_offset(4)
+ subl $4, %esp
+ cfi_adjust_cfa_offset(4)
+
+ movl 16(%esp), %ebx
+ cfi_offset(ebx, -8)
+
+ cfi_offset(esi, -12)
+3: movl (%ebx), %eax
+2: testl %eax, %eax
+ je 1f
+
+ leal -1(%eax), %edx
+ LOCK
+ cmpxchgl %edx, (%ebx)
+ jne 2b
+ xorl %eax, %eax
+
+5: movl 4(%esp), %esi
movl 8(%esp), %ebx
- cfi_restore(3)
addl $12, %esp
+ cfi_restore(ebx)
+ cfi_restore(esi)
cfi_adjust_cfa_offset(-12)
ret
-5: /* Canceled. */
- movl $0xffffffff, %gs:RESULT
- LOCK
- orl $0x10, %gs:CANCELHANDLING
- movl %gs:CLEANUP_JMP_BUF, %eax
- jmp HIDDEN_JUMPTARGET (__pthread_unwind)
+ cfi_adjust_cfa_offset(12)
+ cfi_offset(ebx, -8)
+ cfi_offset(esi, -12)
+1: call __pthread_enable_asynccancel
+ movl %eax, (%esp)
+
+ xorl %esi, %esi
+ movl $SYS_futex, %eax
+ movl %esi, %ecx
+ movl %esi, %edx
+ ENTER_KERNEL
+ movl %eax, %esi
+
+ movl (%esp), %eax
+ call __pthread_disable_asynccancel
+
+ testl %esi, %esi
+ je 3b
+ cmpl $-EWOULDBLOCK, %esi
+ je 3b
+ negl %esi
+#ifdef PIC
+ call __i686.get_pc_thunk.bx
+#else
+ movl $4f, %ebx
+4:
+#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 %esi, (%edx)
+# else
+ movl errno@gotntpoff(%ebx), %edx
+ movl %esi, %gs:(%edx)
+# endif
+#else
+ call __errno_location@plt
+ movl %esi, (%eax)
+#endif
+ orl $-1, %eax
+ jmp 5b
cfi_endproc
- .size __new_sem_wait,.-__new_sem_wait
- versioned_symbol(libpthread, __new_sem_wait, sem_wait, GLIBC_2_1)
-#if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1)
- .global __old_sem_wait
-__old_sem_wait = __new_sem_wait
+ .size __old_sem_wait,.-__old_sem_wait
compat_symbol(libpthread, __old_sem_wait, sem_wait, GLIBC_2_0)
#endif
Modified: fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/internaltypes.h
==============================================================================
--- fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/internaltypes.h (original)
+++ fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/internaltypes.h Sat May 26 00:02:20 2007
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@xxxxxxxxxx>, 2002.
@@ -137,9 +137,16 @@
/* Semaphore variable structure. */
-struct sem
+struct new_sem
{
- unsigned int count;
+ unsigned int value;
+ int private;
+ unsigned long int nwaiters;
+};
+
+struct old_sem
+{
+ unsigned int value;
};
Modified: fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sem_post.c
==============================================================================
--- fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sem_post.c (original)
+++ fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sem_post.c Sat May 26 00:02:20 2007
@@ -1,5 +1,5 @@
/* sem_post -- post to a POSIX semaphore. Generic futex-using version.
- Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2004, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@xxxxxxxxxx>, 2003.
@@ -29,10 +29,33 @@
int
__new_sem_post (sem_t *sem)
{
+ struct new_sem *isem = (struct new_sem *) sem;
+
+ int nr = atomic_increment_val (&isem->value);
+ atomic_full_barrier ();
+ if (isem->nwaiters > 0)
+ {
+ int err = lll_futex_wake (&isem->value, 1);
+ if (__builtin_expect (err, 0) < 0)
+ {
+ __set_errno (-err);
+ return -1;
+ }
+ }
+ return 0;
+}
+versioned_symbol (libpthread, __new_sem_post, sem_post, GLIBC_2_1);
+
+
+#if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_1)
+int
+attribute_compat_text_section
+__old_sem_post (sem_t *sem)
+{
int *futex = (int *) sem;
int nr = atomic_increment_val (futex);
- int err = lll_futex_wake (futex, nr);
+ int err = lll_futex_wake (futex, 1);
if (__builtin_expect (err, 0) < 0)
{
__set_errno (-err);
@@ -40,8 +63,5 @@
}
return 0;
}
-versioned_symbol (libpthread, __new_sem_post, sem_post, GLIBC_2_1);
-#if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_1)
-strong_alias (__new_sem_post, __old_sem_post)
compat_symbol (libpthread, __old_sem_post, sem_post, GLIBC_2_0);
#endif
Modified: fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sem_timedwait.c
==============================================================================
--- fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sem_timedwait.c (original)
+++ fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sem_timedwait.c Sat May 26 00:02:20 2007
@@ -1,5 +1,5 @@
/* sem_timedwait -- wait on a semaphore. Generic futex-using version.
- Copyright (C) 2003 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Paul Mackerras <paulus@xxxxxxxxxx>, 2003.
@@ -28,28 +28,39 @@
#include <shlib-compat.h>
+extern void __sem_wait_cleanup (void *arg) attribute_hidden;
+
+
+void
+attribute_hidden
+__sem_wait_cleanup (void *arg)
+{
+ struct new_sem *isem = (struct new_sem *) arg;
+
+ atomic_decrement (&isem->nwaiters);
+}
+
+
int
sem_timedwait (sem_t *sem, const struct timespec *abstime)
{
- /* First check for cancellation. */
- CANCELLATION_P (THREAD_SELF);
-
- int *futex = (int *) sem;
- int val;
+ struct new_sem *isem = (struct new_sem *) sem;
int err;
- if (*futex > 0)
+ if (atomic_decrement_if_positive (&isem->value) > 0)
+ return 0;
+
+ if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
{
- val = atomic_decrement_if_positive (futex);
- if (val > 0)
- return 0;
+ __set_errno (EINVAL);
+ return -1;
}
- err = -EINVAL;
- if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
- goto error_return;
+ atomic_increment (&isem->nwaiters);
- do
+ pthread_cleanup_push (__sem_wait_cleanup, isem);
+
+ while (1)
{
struct timeval tv;
struct timespec rt;
@@ -70,7 +81,11 @@
/* Already timed out? */
err = -ETIMEDOUT;
if (sec < 0)
- goto error_return;
+ {
+ __set_errno (ETIMEDOUT);
+ err = -1;
+ break;
+ }
/* Do wait. */
rt.tv_sec = sec;
@@ -79,21 +94,28 @@
/* Enable asynchronous cancellation. Required by the standard. */
int oldtype = __pthread_enable_asynccancel ();
- err = lll_futex_timed_wait (futex, 0, &rt);
+ err = lll_futex_timed_wait (&isem->value, 0, &rt);
/* Disable asynchronous cancellation. */
__pthread_disable_asynccancel (oldtype);
if (err != 0 && err != -EWOULDBLOCK)
- goto error_return;
+ {
+ __set_errno (-err);
+ err = -1;
+ break;
+ }
- val = atomic_decrement_if_positive (futex);
+ if (atomic_decrement_if_positive (&isem->value) > 0)
+ {
+ err = 0;
+ break;
+ }
}
- while (val <= 0);
- return 0;
+ pthread_cleanup_pop (0);
- error_return:
- __set_errno (-err);
- return -1;
+ atomic_decrement (&isem->nwaiters);
+
+ return err;
}
Modified: fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sem_wait.c
==============================================================================
--- fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sem_wait.c (original)
+++ fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sem_wait.c Sat May 26 00:02:20 2007
@@ -28,8 +28,65 @@
#include <shlib-compat.h>
+void
+attribute_hidden
+__sem_wait_cleanup (void *arg)
+{
+ struct new_sem *isem = (struct new_sem *) arg;
+
+ atomic_decrement (&isem->nwaiters);
+}
+
+
int
__new_sem_wait (sem_t *sem)
+{
+ struct new_sem *isem = (struct new_sem *) sem;
+ int err;
+
+ if (atomic_decrement_if_positive (&isem->value) > 0)
+ return 0;
+
+ atomic_increment (&isem->nwaiters);
+
+ pthread_cleanup_push (__sem_wait_cleanup, isem);
+
+ while (1)
+ {
+ /* Enable asynchronous cancellation. Required by the standard. */
+ int oldtype = __pthread_enable_asynccancel ();
+
+ err = lll_futex_wait (&isem->value, 0);
+
+ /* Disable asynchronous cancellation. */
+ __pthread_disable_asynccancel (oldtype);
+
+ if (err != 0 && err != -EWOULDBLOCK)
+ {
+ __set_errno (-err);
+ err = -1;
+ }
+
+ if (atomic_decrement_if_positive (&isem->value) > 0)
+ {
+ err = 0;
+ break;
+ }
+ }
+
+ pthread_cleanup_pop (0);
+
+ atomic_decrement (&isem->nwaiters);
+
+ return err;
+}
+versioned_symbol (libpthread, __new_sem_wait, sem_wait, GLIBC_2_1);
+
+
+#if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_1)
+int
+attribute_compat_text_section
+__old_sem_wait (sem_t *sem)
{
int *futex = (int *) sem;
int err;
@@ -53,8 +110,5 @@
return -1;
}
-versioned_symbol (libpthread, __new_sem_wait, sem_wait, GLIBC_2_1);
-#if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_1)
-strong_alias (__new_sem_wait, __old_sem_wait)
compat_symbol (libpthread, __old_sem_wait, sem_wait, GLIBC_2_0);
#endif
Added: fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/structsem.sym
==============================================================================
--- fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/structsem.sym (added)
+++ fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/structsem.sym Sat May 26 00:02:20 2007
@@ -1,0 +1,10 @@
+#include <stddef.h>
+#include <sched.h>
+#include <bits/pthreadtypes.h>
+#include "internaltypes.h"
+
+--
+
+VALUE offsetof (struct new_sem, value)
+PRIVATE offsetof (struct new_sem, private)
+NWAITERS offsetof (struct new_sem, nwaiters)
Modified: fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/x86_64/sem_post.S
==============================================================================
--- fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/x86_64/sem_post.S (original)
+++ fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/x86_64/sem_post.S Sat May 26 00:02:20 2007
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@xxxxxxxxxx>, 2002.
@@ -20,6 +20,7 @@
#include <sysdep.h>
#include <shlib-compat.h>
#include <pthread-errnos.h>
+#include <structsem.h>
#ifndef UP
# define LOCK lock
@@ -37,19 +38,26 @@
.type sem_post,@function
.align 16
sem_post:
- movl $1, %edx
LOCK
- xaddl %edx, (%rdi)
+#if VALUE == 0
+ addl $1, (%rdi)
+#else
+ addl $1, VALUE(%rdi)
+#endif
+
+ cmpq $0, NWAITERS(%rdi)
+ je 2f
movl $SYS_futex, %eax
movl $FUTEX_WAKE, %esi
- incl %edx
+ orl PRIVATE(%rdi), %esi
+ movl $1, %edx
syscall
testq %rax, %rax
js 1f
- xorl %eax, %eax
+2: xorl %eax, %eax
retq
1:
Modified: fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S
==============================================================================
--- fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S (original)
+++ fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S Sat May 26 00:02:20 2007
@@ -20,6 +20,7 @@
#include <sysdep.h>
#include <shlib-compat.h>
#include <pthread-errnos.h>
+#include <structsem.h>
#ifndef UP
# define LOCK lock
@@ -28,6 +29,7 @@
#endif
#define SYS_futex 202
+#define FUTEX_WAIT 0
/* For the calculation see asm/vsyscall.h. */
#define VSYSCALL_ADDR_vgettimeofday 0xffffffffff600000
@@ -38,15 +40,23 @@
.globl sem_timedwait
.type sem_timedwait,@function
.align 16
- cfi_startproc
sem_timedwait:
+.LSTARTCODE:
+#if VALUE == 0
movl (%rdi), %eax
+#else
+ movl VALUE(%rdi), %eax
+#endif
2: testl %eax, %eax
je 1f
leaq -1(%rax), %rdx
LOCK
+#if VALUE == 0
cmpxchgl %edx, (%rdi)
+#else
+ cmpxchgl %edx, VALUE(%rdi)
+#endif
jne 2b
xorl %eax, %eax
@@ -54,29 +64,26 @@
/* Check whether the timeout value is valid. */
1: pushq %r12
- cfi_adjust_cfa_offset(8)
+.Lpush_r12:
pushq %r13
- cfi_adjust_cfa_offset(8)
+.Lpush_r13:
pushq %r14
- cfi_adjust_cfa_offset(8)
+.Lpush_r14:
subq $24, %rsp
- cfi_adjust_cfa_offset(24)
+.Lsubq:
movq %rdi, %r12
- cfi_offset(12, -16) /* %r12 */
movq %rsi, %r13
- cfi_offset(13, -24) /* %r13 */
/* Check for invalid nanosecond field. */
cmpq $1000000000, 8(%r13)
movl $EINVAL, %r14d
- cfi_offset(14, -24) /* %r14 */
jae 6f
-7: call __pthread_enable_asynccancel
- movl %eax, 16(%rsp)
-
- xorl %esi, %esi
+ LOCK
+ addq $1, NWAITERS(%r12)
+
+7: xorl %esi, %esi
movq %rsp, %rdi
movq $VSYSCALL_ADDR_vgettimeofday, %rax
callq *%rax
@@ -99,9 +106,22 @@
movq %rdi, (%rsp) /* Store relative timeout. */
movq %rsi, 8(%rsp)
+.LcleanupSTART:
+ call __pthread_enable_asynccancel
+ movl %eax, 16(%rsp)
+
movq %rsp, %r10
+#if VALUE == 0
movq %r12, %rdi
- xorl %esi, %esi
+#else
+ leaq VALUE(%r12), %rdi
+#endif
+#if FUTEX_WAIT == 0
+ movl PRIVATE(%rdi), %esi
+#else
+ movl $FUTEX_WAIT, %esi
+ orl PRIVATE(%rdi), %esi
+#endif
movl $SYS_futex, %eax
xorl %edx, %edx
syscall
@@ -109,39 +129,47 @@
movl 16(%rsp), %edi
call __pthread_disable_asynccancel
+.LcleanupEND:
testq %r14, %r14
je 9f
cmpq $-EWOULDBLOCK, %r14
jne 3f
-9: movl (%r12), %eax
+9:
+#if VALUE == 0
+ movl (%r12), %eax
+#else
+ movl VALUE(%r12), %eax
+#endif
8: testl %eax, %eax
je 7b
leaq -1(%rax), %rcx
LOCK
+#if VALUE == 0
cmpxchgl %ecx, (%r12)
+#else
+ cmpxchgl %ecx, VALUE(%r12)
+#endif
jne 8b
xorl %eax, %eax
-10: addq $24, %rsp
- cfi_adjust_cfa_offset(-24)
+
+10: LOCK
+ subq $1, NWAITERS(%r12)
+
+ addq $24, %rsp
+.Laddq:
popq %r14
- cfi_adjust_cfa_offset(-8)
- cfi_restore(14)
+.Lpop_r14:
popq %r13
- cfi_adjust_cfa_offset(-8)
- cfi_restore(13)
+.Lpop_r13:
popq %r12
- cfi_adjust_cfa_offset(-8)
- cfi_restore(12)
+.Lpop_r12:
retq
- cfi_adjust_cfa_offset(48)
- cfi_offset(12, -16) /* %r12 */
- cfi_offset(13, -24) /* %r13 */
- cfi_offset(14, -32) /* %r14 */
+.Lafter_retq:
3: negq %r14
6:
#if USE___THREAD
@@ -154,5 +182,159 @@
orl $-1, %eax
jmp 10b
- cfi_endproc
.size sem_timedwait,.-sem_timedwait
+
+
+ .type sem_timedwait_cleanup,@function
+sem_timedwait_cleanup:
+ LOCK
+ subq $1, NWAITERS(%r12)
+ movq %rax, %rdi
+.LcallUR:
+ call _Unwind_Resume@PLT
+ hlt
+.LENDCODE:
+ .size sem_timedwait_cleanup,.-sem_timedwait_cleanup
+
+
+ .section .gcc_except_table,"a",@progbits
+.LexceptSTART:
+ .byte 0xff # @LPStart format (omit)
+ .byte 0xff # @TType format (omit)
+ .byte 0x01 # call-site format
+ # DW_EH_PE_uleb128
+ .uleb128 .Lcstend-.Lcstbegin
+.Lcstbegin:
+ .uleb128 .LcleanupSTART-.LSTARTCODE
+ .uleb128 .LcleanupEND-.LcleanupSTART
+ .uleb128 sem_timedwait_cleanup-.LSTARTCODE
+ .uleb128 0
+ .uleb128 .LcallUR-.LSTARTCODE
+ .uleb128 .LENDCODE-.LcallUR
+ .uleb128 0
+ .uleb128 0
+.Lcstend:
+
+
+ .section .eh_frame,"a",@progbits
+.LSTARTFRAME:
+ .long .LENDCIE-.LSTARTCIE # Length of the CIE.
+.LSTARTCIE:
+ .long 0 # CIE ID.
+ .byte 1 # Version number.
+#ifdef SHARED
+ .string "zPLR" # NUL-terminated augmentation
+ # string.
+#else
+ .string "zPL" # NUL-terminated augmentation
+ # string.
+#endif
+ .uleb128 1 # Code alignment factor.
+ .sleb128 -8 # Data alignment factor.
+ .byte 16 # Return address register
+ # column.
+#ifdef SHARED
+ .uleb128 7 # Augmentation value length.
+ .byte 0x9b # Personality: DW_EH_PE_pcrel
+ # + DW_EH_PE_sdata4
+ # + DW_EH_PE_indirect
+ .long DW.ref.__gcc_personality_v0-.
+ .byte 0x1b # LSDA Encoding: DW_EH_PE_pcrel
+ # + DW_EH_PE_sdata4.
+ .byte 0x1b # FDE Encoding: DW_EH_PE_pcrel
+ # + DW_EH_PE_sdata4.
+#else
+ .uleb128 10 # Augmentation value length.
+ .byte 0x0 # Personality: absolute
+ .quad __gcc_personality_v0
+ .byte 0x0 # LSDA Encoding: absolute
+#endif
+ .byte 0x0c # DW_CFA_def_cfa
+ .uleb128 7
+ .uleb128 8
+ .byte 0x90 # DW_CFA_offset, column 0x10
+ .uleb128 1
+ .align 8
+.LENDCIE:
+
+ .long .LENDFDE-.LSTARTFDE # Length of the FDE.
+.LSTARTFDE:
+ .long .LSTARTFDE-.LSTARTFRAME # CIE pointer.
+#ifdef SHARED
+ .long .LSTARTCODE-. # PC-relative start address
+ # of the code.
+ .long .LENDCODE-.LSTARTCODE # Length of the code.
+ .uleb128 4 # Augmentation size
+ .long .LexceptSTART-.
+#else
+ .quad .LSTARTCODE # Start address of the code.
+ .quad .LENDCODE-.LSTARTCODE # Length of the code.
+ .uleb128 8 # Augmentation size
+ .quad .LexceptSTART
+#endif
+
+ .byte 4 # DW_CFA_advance_loc4
+ .long .Lpush_r12-.LSTARTCODE
+ .byte 14 # DW_CFA_def_cfa_offset
+ .uleb128 16
+ .byte 0x8c # DW_CFA_offset %r12
+ .uleb128 2
+ .byte 4 # DW_CFA_advance_loc4
+ .long .Lpush_r13-.Lpush_r12
+ .byte 14 # DW_CFA_def_cfa_offset
+ .uleb128 24
+ .byte 0x8d # DW_CFA_offset %r13
+ .uleb128 3
+ .byte 4 # DW_CFA_advance_loc4
+ .long .Lpush_r14-.Lpush_r13
+ .byte 14 # DW_CFA_def_cfa_offset
+ .uleb128 32
+ .byte 0x8e # DW_CFA_offset %r14
+ .uleb128 4
+ .byte 4 # DW_CFA_advance_loc4
+ .long .Lsubq-.Lpush_r14
+ .byte 14 # DW_CFA_def_cfa_offset
+ .uleb128 56
+ .byte 4 # DW_CFA_advance_loc4
+ .long .Laddq-.Lsubq
+ .byte 14 # DW_CFA_def_cfa_offset
+ .uleb128 32
+ .byte 4 # DW_CFA_advance_loc4
+ .long .Lpop_r14-.Laddq
+ .byte 14 # DW_CFA_def_cfa_offset
+ .uleb128 24
+ .byte 0xce # DW_CFA_restore %r14
+ .byte 4 # DW_CFA_advance_loc4
+ .long .Lpop_r13-.Lpop_r14
+ .byte 14 # DW_CFA_def_cfa_offset
+ .uleb128 16
+ .byte 0xcd # DW_CFA_restore %r13
+ .byte 4 # DW_CFA_advance_loc4
+ .long .Lpop_r12-.Lpop_r13
+ .byte 14 # DW_CFA_def_cfa_offset
+ .uleb128 8
+ .byte 0xcc # DW_CFA_restore %r12
+ .byte 4 # DW_CFA_advance_loc4
+ .long .Lafter_retq-.Lpop_r12
+ .byte 14 # DW_CFA_def_cfa_offset
+ .uleb128 56
+ .byte 0x8c # DW_CFA_offset %r12
+ .uleb128 2
+ .byte 0x8d # DW_CFA_offset %r13
+ .uleb128 3
+ .byte 0x8e # DW_CFA_offset %r14
+ .uleb128 4
+ .align 8
+.LENDFDE:
+
+
+#ifdef SHARED
+ .hidden DW.ref.__gcc_personality_v0
+ .weak DW.ref.__gcc_personality_v0
+ .section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits
+ .align 8
+ .type DW.ref.__gcc_personality_v0, @object
+ .size DW.ref.__gcc_personality_v0, 8
+DW.ref.__gcc_personality_v0:
+ .quad __gcc_personality_v0
+#endif
Modified: fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S
==============================================================================
--- fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S (original)
+++ fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S Sat May 26 00:02:20 2007
@@ -20,6 +20,7 @@
#include <sysdep.h>
#include <shlib-compat.h>
#include <pthread-errnos.h>
+#include <structsem.h>
#ifndef UP
# define LOCK lock
@@ -28,6 +29,7 @@
#endif
#define SYS_futex 202
+#define FUTEX_WAIT 0
.text
@@ -35,57 +37,93 @@
.globl sem_wait
.type sem_wait,@function
.align 16
- cfi_startproc
sem_wait:
+.LSTARTCODE:
pushq %r12
- cfi_adjust_cfa_offset(8)
- cfi_offset(12, -16)
+.Lpush_r12:
pushq %r13
- cfi_adjust_cfa_offset(8)
+.Lpush_r13:
movq %rdi, %r13
- cfi_offset(13, -24)
-
-3: movl (%r13), %eax
+
+#if VALUE == 0
+ movl (%r13), %eax
+#else
+ movl VALUE(%r13), %eax
+#endif
2: testl %eax, %eax
je 1f
- leaq -1(%rax), %rdx
- LOCK
+ leal -1(%rax), %edx
+ LOCK
+#if VALUE == 0
cmpxchgl %edx, (%r13)
+#else
+ cmpxchgl %edx, VALUE(%r13)
+#endif
jne 2b
- xorl %eax, %eax
-
- popq %r13
- cfi_adjust_cfa_offset(-8)
- cfi_restore(13)
+
+7: xorl %eax, %eax
+
+9: popq %r13
+.Lpop_r13:
popq %r12
- cfi_adjust_cfa_offset(-8)
- cfi_restore(12)
+.Lpop_r12:
retq
- cfi_adjust_cfa_offset(16)
- cfi_offset(12, -16)
- cfi_offset(13, -24)
-1: call __pthread_enable_asynccancel
+.Lafter_retq:
+1: LOCK
+ addq $1, NWAITERS(%r13)
+
+.LcleanupSTART:
+6: call __pthread_enable_asynccancel
movl %eax, %r8d
xorq %r10, %r10
movl $SYS_futex, %eax
movq %r13, %rdi
- movq %r10, %rsi
- movq %r10, %rdx
+#if FUTEX_WAIT == 0
+ movl PRIVATE(%rdi), %esi
+#else
+ movl $FUTEX_WAIT, %esi
+ orl PRIVATE(%rdi), %esi
+#endif
+ xorl %edx, %edx
syscall
movq %rax, %r12
movl %r8d, %edi
call __pthread_disable_asynccancel
+.LcleanupEND:
testq %r12, %r12
- je 3b
+ je 3f
cmpq $-EWOULDBLOCK, %r12
- je 3b
- negq %r12
+ jne 4f
+
+3:
+#if VALUE == 0
+ movl (%r13), %eax
+#else
+ movl VALUE(%r13), %eax
+#endif
+5: testl %eax, %eax
+ je 6b
+
+ leal -1(%rax), %edx
+ LOCK
+#if VALUE == 0
+ cmpxchgl %edx, (%r13)
+#else
+ cmpxchgl %edx, VALUE(%r13)
+#endif
+ jne 5b
+
+ LOCK
+ subq $1, NWAITERS(%r13)
+ jmp 7b
+
+4: negq %r12
#if USE___THREAD
movq errno@gottpoff(%rip), %rdx
movl %r12d, %fs:(%rdx)
@@ -95,13 +133,142 @@
#endif
orl $-1, %eax
- popq %r13
- cfi_adjust_cfa_offset(-8)
- cfi_restore(13)
- popq %r12
- cfi_adjust_cfa_offset(-8)
- cfi_restore(12)
-
- retq
- cfi_endproc
+ LOCK
+ subq $1, NWAITERS(%r13)
+
+ jmp 9b
.size sem_wait,.-sem_wait
+
+
+ .type sem_wait_cleanup,@function
+sem_wait_cleanup:
+ LOCK
+ subq $1, NWAITERS(%r13)
+ movq %rax, %rdi
+.LcallUR:
+ call _Unwind_Resume@PLT
+ hlt
+.LENDCODE:
+ .size sem_wait_cleanup,.-sem_wait_cleanup
+
+
+ .section .gcc_except_table,"a",@progbits
+.LexceptSTART:
+ .byte 0xff # @LPStart format (omit)
+ .byte 0xff # @TType format (omit)
+ .byte 0x01 # call-site format
+ # DW_EH_PE_uleb128
+ .uleb128 .Lcstend-.Lcstbegin
+.Lcstbegin:
+ .uleb128 .LcleanupSTART-.LSTARTCODE
+ .uleb128 .LcleanupEND-.LcleanupSTART
+ .uleb128 sem_wait_cleanup-.LSTARTCODE
+ .uleb128 0
+ .uleb128 .LcallUR-.LSTARTCODE
+ .uleb128 .LENDCODE-.LcallUR
+ .uleb128 0
+ .uleb128 0
+.Lcstend:
+
+
+ .section .eh_frame,"a",@progbits
+.LSTARTFRAME:
+ .long .LENDCIE-.LSTARTCIE # Length of the CIE.
+.LSTARTCIE:
+ .long 0 # CIE ID.
+ .byte 1 # Version number.
+#ifdef SHARED
+ .string "zPLR" # NUL-terminated augmentation
+ # string.
+#else
+ .string "zPL" # NUL-terminated augmentation
+ # string.
+#endif
+ .uleb128 1 # Code alignment factor.
+ .sleb128 -8 # Data alignment factor.
+ .byte 16 # Return address register
+ # column.
+#ifdef SHARED
+ .uleb128 7 # Augmentation value length.
+ .byte 0x9b # Personality: DW_EH_PE_pcrel
+ # + DW_EH_PE_sdata4
+ # + DW_EH_PE_indirect
+ .long DW.ref.__gcc_personality_v0-.
+ .byte 0x1b # LSDA Encoding: DW_EH_PE_pcrel
+ # + DW_EH_PE_sdata4.
+ .byte 0x1b # FDE Encoding: DW_EH_PE_pcrel
+ # + DW_EH_PE_sdata4.
+#else
+ .uleb128 10 # Augmentation value length.
+ .byte 0x0 # Personality: absolute
+ .quad __gcc_personality_v0
+ .byte 0x0 # LSDA Encoding: absolute
+#endif
+ .byte 0x0c # DW_CFA_def_cfa
+ .uleb128 7
+ .uleb128 8
+ .byte 0x90 # DW_CFA_offset, column 0x10
+ .uleb128 1
+ .align 8
+.LENDCIE:
+
+ .long .LENDFDE-.LSTARTFDE # Length of the FDE.
+.LSTARTFDE:
+ .long .LSTARTFDE-.LSTARTFRAME # CIE pointer.
+#ifdef SHARED
+ .long .LSTARTCODE-. # PC-relative start address
+ # of the code.
+ .long .LENDCODE-.LSTARTCODE # Length of the code.
+ .uleb128 4 # Augmentation size
+ .long .LexceptSTART-.
+#else
+ .quad .LSTARTCODE # Start address of the code.
+ .quad .LENDCODE-.LSTARTCODE # Length of the code.
+ .uleb128 8 # Augmentation size
+ .quad .LexceptSTART
+#endif
+
+ .byte 4 # DW_CFA_advance_loc4
+ .long .Lpush_r12-.LSTARTCODE
+ .byte 14 # DW_CFA_def_cfa_offset
+ .uleb128 16
+ .byte 0x8c # DW_CFA_offset %r12
+ .uleb128 2
+ .byte 4 # DW_CFA_advance_loc4
+ .long .Lpush_r13-.Lpush_r12
+ .byte 14 # DW_CFA_def_cfa_offset
+ .uleb128 24
+ .byte 0x8d # DW_CFA_offset %r13
+ .uleb128 3
+ .byte 4 # DW_CFA_advance_loc4
+ .long .Lpop_r13-.Lpush_r13
+ .byte 14 # DW_CFA_def_cfa_offset
+ .uleb128 16
+ .byte 0xcd # DW_CFA_restore %r13
+ .byte 4 # DW_CFA_advance_loc4
+ .long .Lpop_r12-.Lpop_r13
+ .byte 14 # DW_CFA_def_cfa_offset
+ .uleb128 8
+ .byte 0xcc # DW_CFA_restore %r12
+ .byte 4 # DW_CFA_advance_loc4
+ .long .Lafter_retq-.Lpop_r12
+ .byte 14 # DW_CFA_def_cfa_offset
+ .uleb128 24
+ .byte 0x8c # DW_CFA_offset %r12
+ .uleb128 2
+ .byte 0x8d # DW_CFA_offset %r13
+ .uleb128 3
+ .align 8
+.LENDFDE:
+
+
+#ifdef SHARED
+ .hidden DW.ref.__gcc_personality_v0
+ .weak DW.ref.__gcc_personality_v0
+ .section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits
+ .align 8
+ .type DW.ref.__gcc_personality_v0, @object
+ .size DW.ref.__gcc_personality_v0, 8
+DW.ref.__gcc_personality_v0:
+ .quad __gcc_personality_v0
+#endif
Added: fsf/trunk/libc/nptl/tst-sem10.c
==============================================================================
--- fsf/trunk/libc/nptl/tst-sem10.c (added)
+++ fsf/trunk/libc/nptl/tst-sem10.c Sat May 26 00:02:20 2007
@@ -1,0 +1,88 @@
+/* Copyright (C) 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@xxxxxxxxxx>, 2007.
+
+ 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 <semaphore.h>
+#include <stdio.h>
+#include <time.h>
+#include <unistd.h>
+#include <sys/time.h>
+
+
+static int
+do_test (void)
+{
+ sem_t s;
+ if (sem_init (&s, 0, 0) == -1)
+ {
+ puts ("sem_init failed");
+ return 1;
+ }
+
+ struct timeval tv;
+ if (gettimeofday (&tv, NULL) != 0)
+ {
+ puts ("gettimeofday failed");
+ return 1;
+ }
+
+ struct timespec ts;
+ TIMEVAL_TO_TIMESPEC (&tv, &ts);
+
+ /* Set ts to yesterday. */
+ ts.tv_sec -= 86400;
+
+ int type_before;
+ if (pthread_setcanceltype (PTHREAD_CANCEL_DEFERRED, &type_before) != 0)
+ {
+ puts ("first pthread_setcanceltype failed");
+ return 1;
+ }
+
+ errno = 0;
+ if (TEMP_FAILURE_RETRY (sem_timedwait (&s, &ts)) != -1)
+ {
+ puts ("sem_timedwait succeeded");
+ return 1;
+ }
+ if (errno != ETIMEDOUT)
+ {
+ printf ("sem_timedwait return errno = %d instead of ETIMEDOUT\n",
+ errno);
+ return 1;
+ }
+
+ int type_after;
+ if (pthread_setcanceltype (PTHREAD_CANCEL_DEFERRED, &type_after) != 0)
+ {
+ puts ("second pthread_setcanceltype failed");
+ return 1;
+ }
+ if (type_after != PTHREAD_CANCEL_DEFERRED)
+ {
+ puts ("sem_timedwait changed cancellation type");
+ return 1;
+ }
+
+ return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
Added: fsf/trunk/libc/nptl/tst-sem11.c
==============================================================================
--- fsf/trunk/libc/nptl/tst-sem11.c (added)
+++ fsf/trunk/libc/nptl/tst-sem11.c Sat May 26 00:02:20 2007
@@ -1,0 +1,76 @@
+#include <semaphore.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <internaltypes.h>
+
+#ifndef SEM_WAIT
+# define SEM_WAIT(s) sem_wait (s)
+#endif
+
+static void *
+tf (void *arg)
+{
+#ifdef PREPARE
+ PREPARE
+#endif
+ SEM_WAIT (arg);
+ return NULL;
+}
+
+int
+main (void)
+{
+ int tries = 5;
+ pthread_t th;
+ sem_t s;
+ again:
+ if (sem_init (&s, 0, 0) != 0)
+ {
+ puts ("sem_init failed");
+ return 1;
+ }
+
+ struct new_sem *is = (struct new_sem *) &s;
+
+ if (is->nwaiters != 0)
+ {
+ puts ("nwaiters not initialized");
+ return 1;
+ }
+
+ if (pthread_create (&th, NULL, tf, &s) != 0)
+ {
+ puts ("pthread_create failed");
+ return 1;
+ }
+
+ sleep (1);
+
+ if (pthread_cancel (th) != 0)
+ {
+ puts ("pthread_cancel failed");
+ return 1;
+ }
+
+ void *r;
+ if (pthread_join (th, &r) != 0)
+ {
+ puts ("pthread_join failed");
+ return 1;
+ }
+ if (r != PTHREAD_CANCELED && --tries > 0)
+ {
+ /* Maybe we get the scheduling right the next time. */
+ sem_destroy (&s);
+ goto again;
+ }
+
+ if (is->nwaiters != 0)
+ {
+ puts ("nwaiters not reset");
+ return 1;
+ }
+
+ return 0;
+}
Added: fsf/trunk/libc/nptl/tst-sem12.c
==============================================================================
--- fsf/trunk/libc/nptl/tst-sem12.c (added)
+++ fsf/trunk/libc/nptl/tst-sem12.c Sat May 26 00:02:20 2007
@@ -1,0 +1,14 @@
+#include <time.h>
+#include <sys/time.h>
+
+
+#define PREPARE \
+ struct timespec ts; \
+ struct timeval tv; \
+ gettimeofday (&tv, NULL); \
+ TIMEVAL_TO_TIMESPEC (&tv, &ts); \
+ ts.tv_sec += 60;
+
+#define SEM_WAIT(s) sem_timedwait (s, &ts)
+
+#include "tst-sem11.c"
Modified: fsf/trunk/libc/nptl/tst-typesizes.c
==============================================================================
--- fsf/trunk/libc/nptl/tst-typesizes.c (original)
+++ fsf/trunk/libc/nptl/tst-typesizes.c Sat May 26 00:02:20 2007
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2005, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@xxxxxxxxxx>, 2005.
@@ -59,7 +59,8 @@
TEST_TYPE2 (pthread_rwlockattr_t, struct pthread_rwlockattr);
TEST_TYPE2 (pthread_barrier_t, struct pthread_barrier);
TEST_TYPE2 (pthread_barrierattr_t, struct pthread_barrierattr);
- TEST_TYPE2 (sem_t, struct sem);
+ TEST_TYPE2 (sem_t, struct new_sem);
+ TEST_TYPE2 (sem_t, struct old_sem);
return result;
}