1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-07-30 22:43:12 +03:00

* 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@redhat.com>
This commit is contained in:
Ulrich Drepper
2007-05-26 01:31:40 +00:00
parent 2af4e3e566
commit 3d2dd6ca71
19 changed files with 1089 additions and 198 deletions

View File

@ -1,3 +1,32 @@
2007-05-25 Ulrich Drepper <drepper@redhat.com>
* 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@redhat.com> 2007-05-25 Ulrich Drepper <drepper@redhat.com>
Jakub Jelinek <jakub@redhat.com> Jakub Jelinek <jakub@redhat.com>

View File

@ -218,7 +218,7 @@ tests = tst-typesizes \
tst-once1 tst-once2 tst-once3 tst-once4 \ tst-once1 tst-once2 tst-once3 tst-once4 \
tst-key1 tst-key2 tst-key3 tst-key4 \ tst-key1 tst-key2 tst-key3 tst-key4 \
tst-sem1 tst-sem2 tst-sem3 tst-sem4 tst-sem5 tst-sem6 tst-sem7 \ 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-barrier1 tst-barrier2 tst-barrier3 tst-barrier4 \
tst-align tst-align2 tst-align3 \ tst-align tst-align2 tst-align3 \
tst-basic1 tst-basic2 tst-basic3 tst-basic4 tst-basic5 tst-basic6 \ tst-basic1 tst-basic2 tst-basic3 tst-basic4 tst-basic5 tst-basic6 \

View File

@ -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. This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@ -27,11 +27,11 @@ __new_sem_getvalue (sem, sval)
sem_t *sem; sem_t *sem;
int *sval; int *sval;
{ {
struct sem *isem = (struct sem *) sem; struct new_sem *isem = (struct new_sem *) sem;
/* XXX Check for valid SEM parameter. */ /* XXX Check for valid SEM parameter. */
*sval = isem->count; *sval = isem->value;
return 0; return 0;
} }

View File

@ -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. This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@ -22,6 +22,7 @@
#include <lowlevellock.h> #include <lowlevellock.h>
#include <shlib-compat.h> #include <shlib-compat.h>
#include "semaphoreP.h" #include "semaphoreP.h"
#include <kernel-features.h>
int int
@ -38,18 +39,50 @@ __new_sem_init (sem, pshared, value)
} }
/* Map to the internal type. */ /* 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. */ /* Use the values the user provided. */
isem->count = value; 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 isem->nwaiters = 0;
use needs no special preparation. */
return 0; return 0;
} }
versioned_symbol (libpthread, __new_sem_init, sem_init, GLIBC_2_1); versioned_symbol (libpthread, __new_sem_init, sem_init, GLIBC_2_1);
#if SHLIB_COMPAT(libpthread, GLIBC_2_0, 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); compat_symbol (libpthread, __old_sem_init, sem_init, GLIBC_2_0);
#endif #endif

View File

@ -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. This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@ -304,12 +304,14 @@ sem_open (const char *name, int oflag, ...)
/* Create the initial file content. */ /* Create the initial file content. */
sem_t initsem; sem_t initsem;
struct sem *iinitsem = (struct sem *) &initsem; struct new_sem *iinitsem = (struct new_sem *) &initsem;
iinitsem->count = value; iinitsem->value = value;
iinitsem->private = 0;
iinitsem->nwaiters = 0;
/* Initialize the remaining bytes as well. */ /* Initialize the remaining bytes as well. */
memset ((char *) &initsem + sizeof (struct sem), '\0', memset ((char *) &initsem + sizeof (struct new_sem), '\0',
sizeof (sem_t) - sizeof (struct sem)); sizeof (sem_t) - sizeof (struct new_sem));
tmpfname = (char *) alloca (mountpoint.dirlen + 6 + 1); tmpfname = (char *) alloca (mountpoint.dirlen + 6 + 1);
char *xxxxxx = __mempcpy (tmpfname, mountpoint.dir, mountpoint.dirlen); char *xxxxxx = __mempcpy (tmpfname, mountpoint.dir, mountpoint.dirlen);

View File

@ -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. This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@ -60,8 +60,10 @@ extern int __sem_search (const void *a, const void *b) attribute_hidden;
/* Prototypes of functions with multiple interfaces. */ /* Prototypes of functions with multiple interfaces. */
extern int __new_sem_init (sem_t *sem, int pshared, unsigned int value); 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_destroy (sem_t *sem);
extern int __new_sem_post (sem_t *sem); extern int __new_sem_post (sem_t *sem);
extern int __new_sem_wait (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_trywait (sem_t *sem);
extern int __new_sem_getvalue (sem_t *sem, int *sval); extern int __new_sem_getvalue (sem_t *sem, int *sval);

View File

@ -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. # This file is part of the GNU C Library.
# Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. # Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@ -25,7 +25,8 @@ libpthread-sysdep_routines += pt-fork pthread_mutex_cond_lock
gen-as-const-headers += lowlevelcond.sym lowlevelrwlock.sym \ gen-as-const-headers += lowlevelcond.sym lowlevelrwlock.sym \
lowlevelbarrier.sym unwindbuf.sym \ lowlevelbarrier.sym unwindbuf.sym \
lowlevelrobustlock.sym pthread-pi-defines.sym lowlevelrobustlock.sym pthread-pi-defines.sym \
structsem.sym
endif endif
ifeq ($(subdir),posix) ifeq ($(subdir),posix)

View File

@ -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. This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@ -20,6 +20,7 @@
#include <sysdep.h> #include <sysdep.h>
#include <shlib-compat.h> #include <shlib-compat.h>
#include <pthread-errnos.h> #include <pthread-errnos.h>
#include <structsem.h>
#ifndef UP #ifndef UP
# define LOCK lock # define LOCK lock
@ -40,19 +41,26 @@ __new_sem_post:
pushl %ebx pushl %ebx
movl 8(%esp), %ebx movl 8(%esp), %ebx
movl $1, %edx
LOCK LOCK
xaddl %edx, (%ebx) #if VALUE == 0
addl $1, (%ebx)
#else
addl $1, VALUE(%ebx)
#endif
cmpl $0, NWAITERS(%ebx)
je 2f
movl $SYS_futex, %eax movl $SYS_futex, %eax
movl $FUTEX_WAKE, %ecx movl $FUTEX_WAKE, %ecx
addl $1, %edx movl $1, %edx
ENTER_KERNEL ENTER_KERNEL
testl %eax, %eax testl %eax, %eax
js 1f js 1f
xorl %eax, %eax 2: xorl %eax, %eax
popl %ebx popl %ebx
ret ret

View File

@ -20,6 +20,7 @@
#include <sysdep.h> #include <sysdep.h>
#include <shlib-compat.h> #include <shlib-compat.h>
#include <pthread-errnos.h> #include <pthread-errnos.h>
#include <structsem.h>
#ifndef UP #ifndef UP
# define LOCK lock # define LOCK lock
@ -32,19 +33,18 @@
#define FUTEX_WAKE 1 #define FUTEX_WAKE 1
#if VALUE != 0
# error "code needs to be rewritten for VALUE != 0"
#endif
.text .text
.globl sem_timedwait .globl sem_timedwait
.type sem_timedwait,@function .type sem_timedwait,@function
.align 16 .align 16
cfi_startproc
sem_timedwait: sem_timedwait:
/* First check for cancellation. */ .LSTARTCODE:
movl %gs:CANCELHANDLING, %eax
andl $0xfffffff9, %eax
cmpl $8, %eax
je 10f
movl 4(%esp), %ecx movl 4(%esp), %ecx
movl (%ecx), %eax movl (%ecx), %eax
@ -61,24 +61,24 @@ sem_timedwait:
/* Check whether the timeout value is valid. */ /* Check whether the timeout value is valid. */
1: pushl %esi 1: pushl %esi
cfi_adjust_cfa_offset(4) .Lpush_esi:
pushl %edi pushl %edi
cfi_adjust_cfa_offset(4) .Lpush_edi:
pushl %ebx pushl %ebx
cfi_adjust_cfa_offset(4) .Lpush_ebx:
subl $12, %esp subl $12, %esp
cfi_adjust_cfa_offset(12) .Lsub_esp:
movl 32(%esp), %edi movl 32(%esp), %edi
cfi_offset(7, -12) /* %edi */
/* Check for invalid nanosecond field. */ /* Check for invalid nanosecond field. */
cmpl $1000000000, 4(%edi) cmpl $1000000000, 4(%edi)
movl $EINVAL, %esi movl $EINVAL, %esi
cfi_offset(6, -8) /* %esi */
jae 6f jae 6f
cfi_offset(3, -16) /* %ebx */ LOCK
incl NWAITERS(%ecx)
7: xorl %ecx, %ecx 7: xorl %ecx, %ecx
movl %esp, %ebx movl %esp, %ebx
movl %ecx, %edx movl %ecx, %edx
@ -103,10 +103,11 @@ sem_timedwait:
movl %ecx, (%esp) /* Store relative timeout. */ movl %ecx, (%esp) /* Store relative timeout. */
movl %edx, 4(%esp) movl %edx, 4(%esp)
.LcleanupSTART:
call __pthread_enable_asynccancel call __pthread_enable_asynccancel
movl %eax, 8(%esp) movl %eax, 8(%esp)
movl 28(%esp), %ebx movl 28(%esp), %ebx /* Load semaphore address. */
xorl %ecx, %ecx xorl %ecx, %ecx
movl %esp, %esi movl %esp, %esi
movl $SYS_futex, %eax movl $SYS_futex, %eax
@ -116,6 +117,7 @@ sem_timedwait:
movl 8(%esp), %eax movl 8(%esp), %eax
call __pthread_disable_asynccancel call __pthread_disable_asynccancel
.LcleanupEND:
testl %esi, %esi testl %esi, %esi
je 9f je 9f
@ -131,24 +133,22 @@ sem_timedwait:
cmpxchgl %ecx, (%ebx) cmpxchgl %ecx, (%ebx)
jne 8b jne 8b
addl $12, %esp
cfi_adjust_cfa_offset(-12)
xorl %eax, %eax xorl %eax, %eax
10: LOCK
decl NWAITERS(%ebx)
addl $12, %esp
.Ladd_esp:
popl %ebx popl %ebx
cfi_adjust_cfa_offset(-4) .Lpop_ebx:
cfi_restore(3)
popl %edi popl %edi
cfi_adjust_cfa_offset(-4) .Lpop_edi:
cfi_restore(7)
popl %esi popl %esi
cfi_adjust_cfa_offset(-4) .Lpop_esi:
cfi_restore(6)
ret ret
cfi_adjust_cfa_offset(24) .Lafter_ret:
cfi_offset(6, -8) /* %esi */
cfi_offset(7, -12) /* %edi */
cfi_offset(3, -16) /* %ebx */
3: negl %esi 3: negl %esi
6: 6:
#ifdef PIC #ifdef PIC
@ -172,25 +172,163 @@ sem_timedwait:
movl %esi, (%eax) movl %esi, (%eax)
#endif #endif
addl $12, %esp movl 28(%esp), %ebx /* Load semaphore address. */
cfi_adjust_cfa_offset(-12)
orl $-1, %eax orl $-1, %eax
popl %ebx jmp 10b
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
LOCK
orl $0x10, %gs:CANCELHANDLING
movl %gs:CLEANUP_JMP_BUF, %eax
jmp HIDDEN_JUMPTARGET (__pthread_unwind)
cfi_endproc
.size sem_timedwait,.-sem_timedwait .size sem_timedwait,.-sem_timedwait
.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_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

View File

@ -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. This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@ -20,6 +20,7 @@
#include <sysdep.h> #include <sysdep.h>
#include <shlib-compat.h> #include <shlib-compat.h>
#include <pthread-errnos.h> #include <pthread-errnos.h>
#include <structsem.h>
#ifndef UP #ifndef UP
# define LOCK lock # define LOCK lock
@ -31,19 +32,253 @@
#define FUTEX_WAKE 1 #define FUTEX_WAKE 1
#if VALUE != 0
# error "code needs to be rewritten for VALUE != 0"
#endif
.text .text
.globl __new_sem_wait .globl __new_sem_wait
.type __new_sem_wait,@function .type __new_sem_wait,@function
.align 16 .align 16
cfi_startproc
__new_sem_wait: __new_sem_wait:
/* First check for cancellation. */ .LSTARTCODE:
movl %gs:CANCELHANDLING, %eax pushl %ebx
andl $0xfffffff9, %eax .Lpush_ebx:
cmpl $8, %eax pushl %esi
je 5f .Lpush_esi:
subl $4, %esp
.Lsub_esp:
movl 16(%esp), %ebx
movl (%ebx), %eax
2: testl %eax, %eax
je 1f
leal -1(%eax), %edx
LOCK
cmpxchgl %edx, (%ebx)
jne 2b
7: xorl %eax, %eax
9: movl 4(%esp), %esi
movl 8(%esp), %ebx
addl $12, %esp
.Ladd_esp:
ret
.Lafter_ret:
1: LOCK
incl NWAITERS(%ebx)
.LcleanupSTART:
6: 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
.LcleanupEND:
testl %esi, %esi
je 3f
cmpl $-EWOULDBLOCK, %esi
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 $8f, %ebx
8:
#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 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 pushl %ebx
cfi_adjust_cfa_offset(4) cfi_adjust_cfa_offset(4)
pushl %esi pushl %esi
@ -52,9 +287,9 @@ __new_sem_wait:
cfi_adjust_cfa_offset(4) cfi_adjust_cfa_offset(4)
movl 16(%esp), %ebx movl 16(%esp), %ebx
cfi_offset(3, -8) /* %ebx */ cfi_offset(ebx, -8)
cfi_offset(6, -12) /* %esi */ cfi_offset(esi, -12)
3: movl (%ebx), %eax 3: movl (%ebx), %eax
2: testl %eax, %eax 2: testl %eax, %eax
je 1f je 1f
@ -65,17 +300,17 @@ __new_sem_wait:
jne 2b jne 2b
xorl %eax, %eax xorl %eax, %eax
movl 4(%esp), %esi 5: movl 4(%esp), %esi
cfi_restore(6)
movl 8(%esp), %ebx movl 8(%esp), %ebx
cfi_restore(3)
addl $12, %esp addl $12, %esp
cfi_restore(ebx)
cfi_restore(esi)
cfi_adjust_cfa_offset(-12) cfi_adjust_cfa_offset(-12)
ret ret
cfi_adjust_cfa_offset(12) cfi_adjust_cfa_offset(12)
cfi_offset(3, -8) /* %ebx */ cfi_offset(ebx, -8)
cfi_offset(6, -12) /* %esi */ cfi_offset(esi, -12)
1: call __pthread_enable_asynccancel 1: call __pthread_enable_asynccancel
movl %eax, (%esp) movl %eax, (%esp)
@ -115,25 +350,8 @@ __new_sem_wait:
movl %esi, (%eax) movl %esi, (%eax)
#endif #endif
orl $-1, %eax orl $-1, %eax
movl 4(%esp), %esi jmp 5b
cfi_restore(6)
movl 8(%esp), %ebx
cfi_restore(3)
addl $12, %esp
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_endproc cfi_endproc
.size __new_sem_wait,.-__new_sem_wait .size __old_sem_wait,.-__old_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
compat_symbol(libpthread, __old_sem_wait, sem_wait, GLIBC_2_0) compat_symbol(libpthread, __old_sem_wait, sem_wait, GLIBC_2_0)
#endif #endif

View File

@ -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. This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@ -137,9 +137,16 @@ struct pthread_key_struct
/* Semaphore variable structure. */ /* 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;
}; };

View File

@ -1,5 +1,5 @@
/* sem_post -- post to a POSIX semaphore. Generic futex-using version. /* 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. This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@redhat.com>, 2003. Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
@ -28,11 +28,34 @@
int int
__new_sem_post (sem_t *sem) __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 *futex = (int *) sem;
int nr = atomic_increment_val (futex); 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) if (__builtin_expect (err, 0) < 0)
{ {
__set_errno (-err); __set_errno (-err);
@ -40,8 +63,5 @@ __new_sem_post (sem_t *sem)
} }
return 0; 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); compat_symbol (libpthread, __old_sem_post, sem_post, GLIBC_2_0);
#endif #endif

View File

@ -1,5 +1,5 @@
/* sem_timedwait -- wait on a semaphore. Generic futex-using version. /* 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. This file is part of the GNU C Library.
Contributed by Paul Mackerras <paulus@au.ibm.com>, 2003. Contributed by Paul Mackerras <paulus@au.ibm.com>, 2003.
@ -28,28 +28,39 @@
#include <shlib-compat.h> #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 int
sem_timedwait (sem_t *sem, const struct timespec *abstime) sem_timedwait (sem_t *sem, const struct timespec *abstime)
{ {
/* First check for cancellation. */ struct new_sem *isem = (struct new_sem *) sem;
CANCELLATION_P (THREAD_SELF);
int *futex = (int *) sem;
int val;
int err; 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); __set_errno (EINVAL);
if (val > 0) return -1;
return 0;
} }
err = -EINVAL; atomic_increment (&isem->nwaiters);
if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
goto error_return;
do pthread_cleanup_push (__sem_wait_cleanup, isem);
while (1)
{ {
struct timeval tv; struct timeval tv;
struct timespec rt; struct timespec rt;
@ -70,7 +81,11 @@ sem_timedwait (sem_t *sem, const struct timespec *abstime)
/* Already timed out? */ /* Already timed out? */
err = -ETIMEDOUT; err = -ETIMEDOUT;
if (sec < 0) if (sec < 0)
goto error_return; {
__set_errno (ETIMEDOUT);
err = -1;
break;
}
/* Do wait. */ /* Do wait. */
rt.tv_sec = sec; rt.tv_sec = sec;
@ -79,21 +94,28 @@ sem_timedwait (sem_t *sem, const struct timespec *abstime)
/* Enable asynchronous cancellation. Required by the standard. */ /* Enable asynchronous cancellation. Required by the standard. */
int oldtype = __pthread_enable_asynccancel (); 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. */ /* Disable asynchronous cancellation. */
__pthread_disable_asynccancel (oldtype); __pthread_disable_asynccancel (oldtype);
if (err != 0 && err != -EWOULDBLOCK) 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: atomic_decrement (&isem->nwaiters);
__set_errno (-err);
return -1; return err;
} }

View File

@ -28,8 +28,65 @@
#include <shlib-compat.h> #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 int
__new_sem_wait (sem_t *sem) __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 *futex = (int *) sem;
int err; int err;
@ -53,8 +110,5 @@ __new_sem_wait (sem_t *sem)
return -1; 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); compat_symbol (libpthread, __old_sem_wait, sem_wait, GLIBC_2_0);
#endif #endif

View File

@ -0,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)

View File

@ -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. This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@ -20,6 +20,7 @@
#include <sysdep.h> #include <sysdep.h>
#include <shlib-compat.h> #include <shlib-compat.h>
#include <pthread-errnos.h> #include <pthread-errnos.h>
#include <structsem.h>
#ifndef UP #ifndef UP
# define LOCK lock # define LOCK lock
@ -37,19 +38,25 @@
.type sem_post,@function .type sem_post,@function
.align 16 .align 16
sem_post: sem_post:
movl $1, %edx
LOCK 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 $SYS_futex, %eax
movl $FUTEX_WAKE, %esi movl $FUTEX_WAKE, %esi
incl %edx movl $1, %edx
syscall syscall
testq %rax, %rax testq %rax, %rax
js 1f js 1f
xorl %eax, %eax 2: xorl %eax, %eax
retq retq
1: 1:

View File

@ -20,6 +20,7 @@
#include <sysdep.h> #include <sysdep.h>
#include <shlib-compat.h> #include <shlib-compat.h>
#include <pthread-errnos.h> #include <pthread-errnos.h>
#include <structsem.h>
#ifndef UP #ifndef UP
# define LOCK lock # define LOCK lock
@ -28,6 +29,7 @@
#endif #endif
#define SYS_futex 202 #define SYS_futex 202
#define FUTEX_WAIT 0
/* For the calculation see asm/vsyscall.h. */ /* For the calculation see asm/vsyscall.h. */
#define VSYSCALL_ADDR_vgettimeofday 0xffffffffff600000 #define VSYSCALL_ADDR_vgettimeofday 0xffffffffff600000
@ -38,15 +40,23 @@
.globl sem_timedwait .globl sem_timedwait
.type sem_timedwait,@function .type sem_timedwait,@function
.align 16 .align 16
cfi_startproc
sem_timedwait: sem_timedwait:
.LSTARTCODE:
#if VALUE == 0
movl (%rdi), %eax movl (%rdi), %eax
#else
movl VALUE(%rdi), %eax
#endif
2: testl %eax, %eax 2: testl %eax, %eax
je 1f je 1f
leaq -1(%rax), %rdx leaq -1(%rax), %rdx
LOCK LOCK
#if VALUE == 0
cmpxchgl %edx, (%rdi) cmpxchgl %edx, (%rdi)
#else
cmpxchgl %edx, VALUE(%rdi)
#endif
jne 2b jne 2b
xorl %eax, %eax xorl %eax, %eax
@ -54,25 +64,25 @@ sem_timedwait:
/* Check whether the timeout value is valid. */ /* Check whether the timeout value is valid. */
1: pushq %r12 1: pushq %r12
cfi_adjust_cfa_offset(8) .Lpush_r12:
pushq %r13 pushq %r13
cfi_adjust_cfa_offset(8) .Lpush_r13:
pushq %r14 pushq %r14
cfi_adjust_cfa_offset(8) .Lpush_r14:
subq $24, %rsp subq $24, %rsp
cfi_adjust_cfa_offset(24) .Lsubq:
movq %rdi, %r12 movq %rdi, %r12
cfi_offset(12, -16) /* %r12 */
movq %rsi, %r13 movq %rsi, %r13
cfi_offset(13, -24) /* %r13 */
/* Check for invalid nanosecond field. */ /* Check for invalid nanosecond field. */
cmpq $1000000000, 8(%r13) cmpq $1000000000, 8(%r13)
movl $EINVAL, %r14d movl $EINVAL, %r14d
cfi_offset(14, -24) /* %r14 */
jae 6f jae 6f
LOCK
addq $1, NWAITERS(%r12)
7: xorl %esi, %esi 7: xorl %esi, %esi
movq %rsp, %rdi movq %rsp, %rdi
movq $VSYSCALL_ADDR_vgettimeofday, %rax movq $VSYSCALL_ADDR_vgettimeofday, %rax
@ -96,12 +106,17 @@ sem_timedwait:
movq %rdi, (%rsp) /* Store relative timeout. */ movq %rdi, (%rsp) /* Store relative timeout. */
movq %rsi, 8(%rsp) movq %rsi, 8(%rsp)
.LcleanupSTART:
call __pthread_enable_asynccancel call __pthread_enable_asynccancel
movl %eax, 16(%rsp) movl %eax, 16(%rsp)
movq %rsp, %r10 movq %rsp, %r10
#if VALUE == 0
movq %r12, %rdi movq %r12, %rdi
xorl %esi, %esi #else
leaq VALUE(%r12), %rdi
#endif
movl $FUTEX_WAIT, %esi
movl $SYS_futex, %eax movl $SYS_futex, %eax
xorl %edx, %edx xorl %edx, %edx
syscall syscall
@ -109,39 +124,47 @@ sem_timedwait:
movl 16(%rsp), %edi movl 16(%rsp), %edi
call __pthread_disable_asynccancel call __pthread_disable_asynccancel
.LcleanupEND:
testq %r14, %r14 testq %r14, %r14
je 9f je 9f
cmpq $-EWOULDBLOCK, %r14 cmpq $-EWOULDBLOCK, %r14
jne 3f jne 3f
9: movl (%r12), %eax 9:
#if VALUE == 0
movl (%r12), %eax
#else
movl VALUE(%r12), %eax
#endif
8: testl %eax, %eax 8: testl %eax, %eax
je 7b je 7b
leaq -1(%rax), %rcx leaq -1(%rax), %rcx
LOCK LOCK
#if VALUE == 0
cmpxchgl %ecx, (%r12) cmpxchgl %ecx, (%r12)
#else
cmpxchgl %ecx, VALUE(%r12)
#endif
jne 8b jne 8b
xorl %eax, %eax xorl %eax, %eax
10: addq $24, %rsp
cfi_adjust_cfa_offset(-24) 10: LOCK
subq $1, NWAITERS(%r12)
addq $24, %rsp
.Laddq:
popq %r14 popq %r14
cfi_adjust_cfa_offset(-8) .Lpop_r14:
cfi_restore(14)
popq %r13 popq %r13
cfi_adjust_cfa_offset(-8) .Lpop_r13:
cfi_restore(13)
popq %r12 popq %r12
cfi_adjust_cfa_offset(-8) .Lpop_r12:
cfi_restore(12)
retq retq
cfi_adjust_cfa_offset(48) .Lafter_retq:
cfi_offset(12, -16) /* %r12 */
cfi_offset(13, -24) /* %r13 */
cfi_offset(14, -32) /* %r14 */
3: negq %r14 3: negq %r14
6: 6:
#if USE___THREAD #if USE___THREAD
@ -154,5 +177,159 @@ sem_timedwait:
orl $-1, %eax orl $-1, %eax
jmp 10b jmp 10b
cfi_endproc
.size sem_timedwait,.-sem_timedwait .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

View File

@ -20,6 +20,7 @@
#include <sysdep.h> #include <sysdep.h>
#include <shlib-compat.h> #include <shlib-compat.h>
#include <pthread-errnos.h> #include <pthread-errnos.h>
#include <structsem.h>
#ifndef UP #ifndef UP
# define LOCK lock # define LOCK lock
@ -28,6 +29,7 @@
#endif #endif
#define SYS_futex 202 #define SYS_futex 202
#define FUTEX_WAIT 0
.text .text
@ -35,57 +37,88 @@
.globl sem_wait .globl sem_wait
.type sem_wait,@function .type sem_wait,@function
.align 16 .align 16
cfi_startproc
sem_wait: sem_wait:
.LSTARTCODE:
pushq %r12 pushq %r12
cfi_adjust_cfa_offset(8) .Lpush_r12:
cfi_offset(12, -16)
pushq %r13 pushq %r13
cfi_adjust_cfa_offset(8) .Lpush_r13:
movq %rdi, %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 2: testl %eax, %eax
je 1f je 1f
leaq -1(%rax), %rdx leal -1(%rax), %edx
LOCK LOCK
#if VALUE == 0
cmpxchgl %edx, (%r13) cmpxchgl %edx, (%r13)
#else
cmpxchgl %edx, VALUE(%r13)
#endif
jne 2b jne 2b
xorl %eax, %eax
popq %r13 7: xorl %eax, %eax
cfi_adjust_cfa_offset(-8)
cfi_restore(13) 9: popq %r13
.Lpop_r13:
popq %r12 popq %r12
cfi_adjust_cfa_offset(-8) .Lpop_r12:
cfi_restore(12)
retq retq
cfi_adjust_cfa_offset(16) .Lafter_retq:
cfi_offset(12, -16) 1: LOCK
cfi_offset(13, -24) addq $1, NWAITERS(%r13)
1: call __pthread_enable_asynccancel
.LcleanupSTART:
6: call __pthread_enable_asynccancel
movl %eax, %r8d movl %eax, %r8d
xorq %r10, %r10 xorq %r10, %r10
movl $SYS_futex, %eax movl $SYS_futex, %eax
movq %r13, %rdi movq %r13, %rdi
movq %r10, %rsi movl $FUTEX_WAIT, %esi
movq %r10, %rdx xorl %edx, %edx
syscall syscall
movq %rax, %r12 movq %rax, %r12
movl %r8d, %edi movl %r8d, %edi
call __pthread_disable_asynccancel call __pthread_disable_asynccancel
.LcleanupEND:
testq %r12, %r12 testq %r12, %r12
je 3b je 3f
cmpq $-EWOULDBLOCK, %r12 cmpq $-EWOULDBLOCK, %r12
je 3b jne 4f
negq %r12
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 #if USE___THREAD
movq errno@gottpoff(%rip), %rdx movq errno@gottpoff(%rip), %rdx
movl %r12d, %fs:(%rdx) movl %r12d, %fs:(%rdx)
@ -95,13 +128,142 @@ sem_wait:
#endif #endif
orl $-1, %eax orl $-1, %eax
popq %r13 LOCK
cfi_adjust_cfa_offset(-8) subq $1, NWAITERS(%r13)
cfi_restore(13)
popq %r12
cfi_adjust_cfa_offset(-8)
cfi_restore(12)
retq jmp 9b
cfi_endproc
.size sem_wait,.-sem_wait .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

View File

@ -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. This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2005. Contributed by Ulrich Drepper <drepper@redhat.com>, 2005.
@ -59,7 +59,8 @@ do_test (void)
TEST_TYPE2 (pthread_rwlockattr_t, struct pthread_rwlockattr); TEST_TYPE2 (pthread_rwlockattr_t, struct pthread_rwlockattr);
TEST_TYPE2 (pthread_barrier_t, struct pthread_barrier); TEST_TYPE2 (pthread_barrier_t, struct pthread_barrier);
TEST_TYPE2 (pthread_barrierattr_t, struct pthread_barrierattr); 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; return result;
} }