From 54854dd79228b33ffcc22d5646247c911b64d98c Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Sat, 7 Jul 2007 16:11:40 +0000 Subject: [PATCH] * Makefile (tests): Add tst-sem10. * tst-sem10.c: New file. * 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. --- nptl/ChangeLog | 13 ++++ nptl/Makefile | 2 +- .../unix/sysv/linux/i386/i486/sem_timedwait.S | 9 ++- .../sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S | 8 +- nptl/tst-sem10.c | 88 ++++++++++++++++++++++ 5 files changed, 111 insertions(+), 9 deletions(-) create mode 100644 nptl/tst-sem10.c diff --git a/nptl/ChangeLog b/nptl/ChangeLog index 15beed42ef..ea877d0374 100644 --- a/nptl/ChangeLog +++ b/nptl/ChangeLog @@ -1,3 +1,16 @@ +2007-05-25 Ulrich Drepper + + * Makefile (tests): Add tst-sem10. + * tst-sem10.c: New file. + +2007-05-25 Ulrich Drepper + Jakub Jelinek + + * 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-21 Jakub Jelinek * tst-robust9.c (do_test): Don't fail if ENABLE_PI and diff --git a/nptl/Makefile b/nptl/Makefile index f3142b64b0..95f72154e2 100644 --- a/nptl/Makefile +++ b/nptl/Makefile @@ -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-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 \ diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S b/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S index aa1f9f41ca..e42f2dc7df 100644 --- a/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S +++ b/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S @@ -79,10 +79,7 @@ sem_timedwait: jae 6f cfi_offset(3, -16) /* %ebx */ -7: call __pthread_enable_asynccancel - movl %eax, 8(%esp) - - xorl %ecx, %ecx +7: xorl %ecx, %ecx movl %esp, %ebx movl %ecx, %edx movl $SYS_gettimeofday, %eax @@ -105,6 +102,10 @@ sem_timedwait: movl %ecx, (%esp) /* Store relative timeout. */ movl %edx, 4(%esp) + + call __pthread_enable_asynccancel + movl %eax, 8(%esp) + movl 28(%esp), %ebx xorl %ecx, %ecx movl %esp, %esi diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S b/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S index 76a566b988..8c5c2a6974 100644 --- a/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S +++ b/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S @@ -73,10 +73,7 @@ sem_timedwait: cfi_offset(14, -24) /* %r14 */ jae 6f -7: call __pthread_enable_asynccancel - movl %eax, 16(%rsp) - - xorl %esi, %esi +7: xorl %esi, %esi movq %rsp, %rdi movq $VSYSCALL_ADDR_vgettimeofday, %rax callq *%rax @@ -99,6 +96,9 @@ sem_timedwait: movq %rdi, (%rsp) /* Store relative timeout. */ movq %rsi, 8(%rsp) + call __pthread_enable_asynccancel + movl %eax, 16(%rsp) + movq %rsp, %r10 movq %r12, %rdi xorl %esi, %esi diff --git a/nptl/tst-sem10.c b/nptl/tst-sem10.c new file mode 100644 index 0000000000..9f6e870a85 --- /dev/null +++ b/nptl/tst-sem10.c @@ -0,0 +1,88 @@ +/* Copyright (C) 2007 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Jakub Jelinek , 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 +#include +#include +#include +#include +#include +#include + + +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" -- 2.11.4.GIT