From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 5316 invoked by alias); 1 Jul 2010 12:49:56 -0000 Received: (qmail 5298 invoked by uid 22791); 1 Jul 2010 12:49:55 -0000 X-SWARE-Spam-Status: No, hits=-5.6 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_HI,SPF_HELO_PASS,TW_DD,TW_FN,TW_JN,TW_OV,TW_RW,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 01 Jul 2010 12:49:49 +0000 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o61CnmFq003910 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Thu, 1 Jul 2010 08:49:48 -0400 Received: from hase.home (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o61CnkIM007866 for ; Thu, 1 Jul 2010 08:49:47 -0400 From: Andreas Schwab To: libc-hacker@sourceware.org Subject: [PATCH] Work around kernel rejecting valid absolute timestamps X-Yow: Life is selling REVOLUTIONARY HAIR PRODUCTS! Date: Thu, 01 Jul 2010 12:49:00 -0000 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.2 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Mailing-List: contact libc-hacker-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-hacker-owner@sourceware.org X-SW-Source: 2010-07/txt/msg00000.txt.bz2 2010-07-01 Andreas Schwab * Makefile (tests): Add tst-abstime. * tst-abstime.c: New file. * sysdeps/unix/sysv/linux/i386/i486/lowlevellock.S (__lll_timedlock_wait): Check for timestamp before the Epoch. * sysdeps/unix/sysv/linux/x86_64/lowlevellock.S (__lll_timedlock_wait): Likewise. * sysdeps/unix/sysv/linux/x86_64/lowlevelrobustlock.S (__lll_robust_timedlock_wait): Likewise. * sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S (__pthread_cond_timedwait): Likewise. * sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S (pthread_rwlock_timedrdlock): Likewise. * sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S (pthread_rwlock_timedwrlock): Likewise. * sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S (sem_timedwait): Likewise. --- nptl/Makefile | 1 + .../unix/sysv/linux/i386/i486/lowlevellock.S | 10 +++- nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S | 9 ++- .../unix/sysv/linux/x86_64/lowlevelrobustlock.S | 10 +++- .../sysv/linux/x86_64/pthread_cond_timedwait.S | 4 + .../sysv/linux/x86_64/pthread_rwlock_timedrdlock.S | 3 + .../sysv/linux/x86_64/pthread_rwlock_timedwrlock.S | 3 + .../sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S | 5 ++ nptl/tst-abstime.c | 65 ++++++++++++++++++++ 9 files changed, 104 insertions(+), 6 deletions(-) create mode 100644 nptl/tst-abstime.c diff --git a/nptl/Makefile b/nptl/Makefile index f21167d..7a9509b 100644 --- a/nptl/Makefile +++ b/nptl/Makefile @@ -256,6 +256,7 @@ tests = tst-typesizes \ tst-sched1 \ tst-backtrace1 \ tst-oddstacklimit \ + tst-abstime \ tst-vfork1 tst-vfork2 tst-vfork1x tst-vfork2x \ tst-getpid1 tst-getpid2 tst-getpid3 \ tst-initializers1 $(patsubst %,tst-initializers1-%,c89 gnu89 c99 gnu99) diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i486/lowlevellock.S b/nptl/sysdeps/unix/sysv/linux/i386/i486/lowlevellock.S index 7578c7e..4db8991 100644 --- a/nptl/sysdeps/unix/sysv/linux/i386/i486/lowlevellock.S +++ b/nptl/sysdeps/unix/sysv/linux/i386/i486/lowlevellock.S @@ -1,4 +1,5 @@ -/* Copyright (C) 2002-2004, 2006, 2007, 2009 Free Software Foundation, Inc. +/* Copyright (C) 2002-2004, 2006, 2007, 2009, 2010 + Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 2002. @@ -198,7 +199,10 @@ __lll_timedlock_wait: cmpl %edx, %eax jne 2f -1: movl $SYS_futex, %eax +1: cmpl $0, (%esi) + js 8f + + movl $SYS_futex, %eax movl $2, %edx ENTER_KERNEL @@ -222,6 +226,8 @@ __lll_timedlock_wait: cfi_adjust_cfa_offset(-4) cfi_restore(%ebp) ret +8: movl $ETIMEDOUT, %eax + jmp 7b # ifndef __ASSUME_FUTEX_CLOCK_REALTIME .Lreltmo: diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S b/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S index 8de9cf4..60b8c41 100644 --- a/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S +++ b/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S @@ -180,7 +180,10 @@ __lll_timedlock_wait: cmpl %edx, %eax jne 2f -1: movl $SYS_futex, %eax +1: cmpq $0, (%r10) + js 5f + + movl $SYS_futex, %eax movl $2, %edx syscall @@ -197,10 +200,12 @@ __lll_timedlock_wait: negl %edx 3: movl %edx, %eax - popq %r9 +6: popq %r9 cfi_adjust_cfa_offset(-8) cfi_restore(%r9) retq +5: movl $ETIMEDOUT, %eax + jmp 6b # ifndef __ASSUME_FUTEX_CLOCK_REALTIME .Lreltmo: diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevelrobustlock.S b/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevelrobustlock.S index 02db0a4..ed91b28 100644 --- a/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevelrobustlock.S +++ b/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevelrobustlock.S @@ -1,4 +1,4 @@ -/* Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2009 +/* Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 2002. @@ -146,7 +146,10 @@ __lll_robust_timedlock_wait: movq $0, %rcx /* Must use mov to avoid changing cc. */ jnz 6f -5: movl $SYS_futex, %eax +5: cmpq $0, (%r10) + js 7f + + movl $SYS_futex, %eax syscall movl %eax, %ecx @@ -168,6 +171,9 @@ __lll_robust_timedlock_wait: cfi_adjust_cfa_offset(8) cfi_rel_offset(%r9, 0) +7: movl $ETIMEDOUT, %eax + jmp 3b + /* Check whether the time expired. */ 2: cmpl $-ETIMEDOUT, %ecx je 4f diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S index be14fc8..093e660 100644 --- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S +++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S @@ -144,6 +144,10 @@ __pthread_cond_timedwait: movq %r9, 24(%rsp) movl %edx, 4(%rsp) + cmpq $0, (%r13) + movq $-ETIMEDOUT, %r14 + js 36f + 38: movl cond_futex(%rdi), %r12d /* Unlock. */ diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S index 23b218a..22a4744 100644 --- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S +++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S @@ -102,6 +102,9 @@ pthread_rwlock_timedrdlock: je .Lreltmo #endif + cmpq $0, (%r13) + js 16f /* Time is already up. */ + movl $FUTEX_PRIVATE_FLAG|FUTEX_WAIT_BITSET|FUTEX_CLOCK_REALTIME, %esi xorl PSHARED(%r12), %esi movq %r13, %r10 diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S index cd867b6..41ba8f0 100644 --- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S +++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S @@ -99,6 +99,9 @@ pthread_rwlock_timedwrlock: je .Lreltmo #endif + cmpq $0, (%r13) + js 16f /* Time is already up. */ + movl $FUTEX_PRIVATE_FLAG|FUTEX_WAIT_BITSET|FUTEX_CLOCK_REALTIME, %esi xorl PSHARED(%r12), %esi movq %r13, %r10 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 0291beb..e2e970e 100644 --- a/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S +++ b/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S @@ -87,6 +87,10 @@ sem_timedwait: LOCK addq $1, NWAITERS(%rdi) + cmpq $0, (%r13) + movq $-ETIMEDOUT, %r9 + js 4f + .LcleanupSTART: 13: call __pthread_enable_asynccancel movl %eax, %r8d @@ -144,6 +148,7 @@ sem_timedwait: cfi_adjust_cfa_offset(8) 3: negq %r9 +4: #if USE___THREAD movq errno@gottpoff(%rip), %rdx movl %r9d, %fs:(%rdx) diff --git a/nptl/tst-abstime.c b/nptl/tst-abstime.c new file mode 100644 index 0000000..73105f7 --- /dev/null +++ b/nptl/tst-abstime.c @@ -0,0 +1,65 @@ +/* Copyright (C) 2010 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Schwab , 2010. + + 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 + +pthread_cond_t c = PTHREAD_COND_INITIALIZER; +pthread_mutex_t m1 = PTHREAD_MUTEX_INITIALIZER; +pthread_mutex_t m2 = PTHREAD_MUTEX_INITIALIZER; +pthread_rwlock_t rw1 = PTHREAD_RWLOCK_INITIALIZER; +pthread_rwlock_t rw2 = PTHREAD_RWLOCK_INITIALIZER; + +static void * +th (void *arg) +{ + int r; + struct timespec t = { -2, 0 }; + + r = pthread_mutex_timedlock (&m1, &t); + assert (r == ETIMEDOUT); + r = pthread_rwlock_timedrdlock (&rw1, &t); + assert (r == ETIMEDOUT); + r = pthread_rwlock_timedwrlock (&rw2, &t); + assert (r == ETIMEDOUT); + return 0; +} + +int +do_test (void) +{ + int r; + struct timespec t = { -2, 0 }; + pthread_t pth; + + pthread_mutex_lock (&m1); + pthread_rwlock_wrlock (&rw1); + pthread_rwlock_rdlock (&rw2); + pthread_mutex_lock (&m2); + pthread_create (&pth, 0, th, 0); + r = pthread_cond_timedwait (&c, &m2, &t); + assert (r == ETIMEDOUT); + pthread_join (pth, 0); + return 0; +} + + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" -- 1.7.1 -- Andreas Schwab, schwab@redhat.com GPG Key fingerprint = D4E8 DBE3 3813 BB5D FA84 5EC7 45C6 250E 6F00 984E "And now for something completely different."