* 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>
Jakub Jelinek <jakub@redhat.com>

View File

@ -218,7 +218,7 @@ tests = tst-typesizes \
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 \

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.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@ -27,11 +27,11 @@ __new_sem_getvalue (sem, sval)
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;
}

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.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@ -22,6 +22,7 @@
#include <lowlevellock.h>
#include <shlib-compat.h>
#include "semaphoreP.h"
#include <kernel-features.h>
int
@ -38,18 +39,50 @@ __new_sem_init (sem, pshared, value)
}
/* 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

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.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@ -304,12 +304,14 @@ sem_open (const char *name, int oflag, ...)
/* 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);

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.
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. */
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);

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.
# 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 \
lowlevelbarrier.sym unwindbuf.sym \
lowlevelrobustlock.sym pthread-pi-defines.sym
lowlevelrobustlock.sym pthread-pi-defines.sym \
structsem.sym
endif
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.
Contributed by Ulrich Drepper <drepper@redhat.com>, 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,26 @@ __new_sem_post:
pushl %ebx
movl 8(%esp), %ebx
movl $1, %edx
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 $FUTEX_WAKE, %ecx
addl $1, %edx
movl $1, %edx
ENTER_KERNEL
testl %eax, %eax
js 1f
xorl %eax, %eax
2: xorl %eax, %eax
popl %ebx
ret

View File

@ -20,6 +20,7 @@
#include <sysdep.h>
#include <shlib-compat.h>
#include <pthread-errnos.h>
#include <structsem.h>
#ifndef UP
# define LOCK lock
@ -32,19 +33,18 @@
#define FUTEX_WAKE 1
#if VALUE != 0
# error "code needs to be rewritten for VALUE != 0"
#endif
.text
.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,24 +61,24 @@ sem_timedwait:
/* 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 */
LOCK
incl NWAITERS(%ecx)
7: xorl %ecx, %ecx
movl %esp, %ebx
movl %ecx, %edx
@ -103,10 +103,11 @@ sem_timedwait:
movl %ecx, (%esp) /* Store relative timeout. */
movl %edx, 4(%esp)
.LcleanupSTART:
call __pthread_enable_asynccancel
movl %eax, 8(%esp)
movl 28(%esp), %ebx
movl 28(%esp), %ebx /* Load semaphore address. */
xorl %ecx, %ecx
movl %esp, %esi
movl $SYS_futex, %eax
@ -116,6 +117,7 @@ sem_timedwait:
movl 8(%esp), %eax
call __pthread_disable_asynccancel
.LcleanupEND:
testl %esi, %esi
je 9f
@ -131,24 +133,22 @@ sem_timedwait:
cmpxchgl %ecx, (%ebx)
jne 8b
addl $12, %esp
cfi_adjust_cfa_offset(-12)
xorl %eax, %eax
10: LOCK
decl NWAITERS(%ebx)
addl $12, %esp
.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
@ -172,25 +172,163 @@ sem_timedwait:
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
LOCK
orl $0x10, %gs:CANCELHANDLING
movl %gs:CLEANUP_JMP_BUF, %eax
jmp HIDDEN_JUMPTARGET (__pthread_unwind)
cfi_endproc
jmp 10b
.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.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@ -20,6 +20,7 @@
#include <sysdep.h>
#include <shlib-compat.h>
#include <pthread-errnos.h>
#include <structsem.h>
#ifndef UP
# define LOCK lock
@ -31,19 +32,253 @@
#define FUTEX_WAKE 1
#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
.Lpush_ebx:
pushl %esi
.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
cfi_adjust_cfa_offset(4)
pushl %esi
@ -52,9 +287,9 @@ __new_sem_wait:
cfi_adjust_cfa_offset(4)
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
2: testl %eax, %eax
je 1f
@ -65,17 +300,17 @@ __new_sem_wait:
jne 2b
xorl %eax, %eax
movl 4(%esp), %esi
cfi_restore(6)
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
cfi_adjust_cfa_offset(12)
cfi_offset(3, -8) /* %ebx */
cfi_offset(6, -12) /* %esi */
cfi_offset(ebx, -8)
cfi_offset(esi, -12)
1: call __pthread_enable_asynccancel
movl %eax, (%esp)
@ -115,25 +350,8 @@ __new_sem_wait:
movl %esi, (%eax)
#endif
orl $-1, %eax
movl 4(%esp), %esi
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)
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

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.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@ -137,9 +137,16 @@ struct pthread_key_struct
/* 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.
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@redhat.com>, 2003.
@ -28,11 +28,34 @@
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 @@ __new_sem_post (sem_t *sem)
}
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

View File

@ -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@au.ibm.com>, 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 @@ sem_timedwait (sem_t *sem, const struct timespec *abstime)
/* 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 @@ sem_timedwait (sem_t *sem, const struct timespec *abstime)
/* 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;
}

View File

@ -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 @@ __new_sem_wait (sem_t *sem)
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

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.
Contributed by Ulrich Drepper <drepper@redhat.com>, 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,25 @@
.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
movl $1, %edx
syscall
testq %rax, %rax
js 1f
xorl %eax, %eax
2: xorl %eax, %eax
retq
1:

View File

@ -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,25 +64,25 @@ sem_timedwait:
/* 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
LOCK
addq $1, NWAITERS(%r12)
7: xorl %esi, %esi
movq %rsp, %rdi
movq $VSYSCALL_ADDR_vgettimeofday, %rax
@ -96,12 +106,17 @@ sem_timedwait:
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
movl $FUTEX_WAIT, %esi
movl $SYS_futex, %eax
xorl %edx, %edx
syscall
@ -109,39 +124,47 @@ sem_timedwait:
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 +177,159 @@ sem_timedwait:
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

View File

@ -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,88 @@
.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
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
movl $FUTEX_WAIT, %esi
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 +128,142 @@ sem_wait:
#endif
orl $-1, %eax
popq %r13
cfi_adjust_cfa_offset(-8)
cfi_restore(13)
popq %r12
cfi_adjust_cfa_offset(-8)
cfi_restore(12)
LOCK
subq $1, NWAITERS(%r13)
retq
cfi_endproc
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

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.
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_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;
}