* sysdeps/unix/sysv/linux/sh/lowlevellock.h: Add lll_robust_mutex_* cvs/fedora-glibc-20060217T1609
authorUlrich Drepper <drepper@redhat.com>
Fri, 17 Feb 2006 15:37:51 +0000 (15:37 +0000)
committerUlrich Drepper <drepper@redhat.com>
Fri, 17 Feb 2006 15:37:51 +0000 (15:37 +0000)
definitions.
* sysdeps/unix/sysv/linux/sh/lowlevelrobustlock.S: New file.

nptl/ChangeLog
nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h
nptl/sysdeps/unix/sysv/linux/sh/lowlevelrobustlock.S [new file with mode: 0644]

index f2ca430..aa206eb 100644 (file)
@@ -1,3 +1,9 @@
+2006-02-17  Kaz Kojima  <kkojima@rr.iij4u.or.jp>
+
+       * sysdeps/unix/sysv/linux/sh/lowlevellock.h: Add lll_robust_mutex_*
+       definitions.
+       * sysdeps/unix/sysv/linux/sh/lowlevelrobustlock.S: New file.
+
 2006-02-17  Ulrich Drepper  <drepper@redhat.com>
 
        * sysdeps/unix/sysv/linux/x86_64/lowlevellock.h
index e3e3777..92f93cd 100644 (file)
@@ -62,6 +62,28 @@ extern int __lll_mutex_unlock_wake (int *__futex) attribute_hidden;
        : "r0", "r1", "r2", "t", "memory"); \
      __result; })
 
+#define lll_robust_mutex_trylock(futex, id)    \
+  ({ unsigned char __result; \
+     __asm __volatile ("\
+       .align 2\n\
+       mova 1f,r0\n\
+       nop\n\
+       mov r15,r1\n\
+       mov #-8,r15\n\
+     0: mov.l @%1,r2\n\
+       cmp/eq r2,%3\n\
+       bf 1f\n\
+       mov.l %2,@%1\n\
+     1: mov r1,r15\n\
+       mov #-1,%0\n\
+       negc %0,%0"\
+       : "=r" (__result) \
+       : "r" (&(futex)), \
+         "r" (id), \
+         "r" (LLL_MUTEX_LOCK_INITIALIZER) \
+       : "r0", "r1", "r2", "t", "memory"); \
+     __result; })
+
 #define lll_mutex_cond_trylock(futex) \
   ({ unsigned char __result; \
      __asm __volatile ("\
@@ -102,6 +124,25 @@ extern int __lll_mutex_unlock_wake (int *__futex) attribute_hidden;
            if (__result) \
              __lll_mutex_lock_wait (__result, __futex); })
 
+#define lll_robust_mutex_lock(futex, id)                   \
+  ({ int __result, val, *__futex = &(futex); \
+     __asm __volatile ("\
+       .align 2\n\
+       mova 1f,r0\n\
+       nop\n\
+       mov r15,r1\n\
+       mov #-8,r15\n\
+      0: mov.l @%2,%0\n\
+       tst %0,%0\n\
+       bf 1f\n\
+       mov.l %1,@%2\n\
+      1: mov r1,r15"\
+       : "=&r" (__result) : "r" (id), "r" (__futex) \
+       : "r0", "r1", "t", "memory"); \
+     if (__result) \
+       __result = __lll_robust_mutex_lock_wait (__result, __futex); \
+     __result; })
+
 /* Special version of lll_mutex_lock which causes the unlock function to
    always wakeup waiters.  */
 #define lll_mutex_cond_lock(futex) \
@@ -122,6 +163,25 @@ extern int __lll_mutex_unlock_wake (int *__futex) attribute_hidden;
            if (__result) \
              __lll_mutex_lock_wait (__result, __futex); })
 
+#define lll_robust_mutex_cond_lock(futex, id)      \
+  ({ int __result, val, *__futex = &(futex); \
+     __asm __volatile ("\
+       .align 2\n\
+       mova 1f,r0\n\
+       nop\n\
+       mov r15,r1\n\
+       mov #-8,r15\n\
+     0: mov.l @%2,%0\n\
+       tst %0,%0\n\
+       bf 1f\n\
+       mov.l %1,@%2\n\
+     1: mov r1,r15"\
+       : "=&r" (__result) : "r" (id | FUTEX_WAITERS), "r" (__futex) \
+       : "r0", "r1", "t", "memory"); \
+      if (__result) \
+       __result = __lll_robust_mutex_lock_wait (__result, __futex); \
+      __result; })
+
 #define lll_mutex_timedlock(futex, timeout) \
   ({ int __result, val, *__futex = &(futex); \
      __asm __volatile ("\
@@ -141,6 +201,26 @@ extern int __lll_mutex_unlock_wake (int *__futex) attribute_hidden;
       __result = __lll_mutex_timedlock_wait (__result, __futex, timeout); \
     __result; })
 
+#define lll_robust_mutex_timedlock(futex, timeout, id) \
+  ({ int __result, val, *__futex = &(futex); \
+     __asm __volatile ("\
+       .align 2\n\
+       mova 1f,r0\n\
+       nop\n\
+       mov r15,r1\n\
+       mov #-8,r15\n\
+     0: mov.l @%2,%0\n\
+       tst %0,%0\n\
+       bf 1f\n\
+       mov.l %1,@%2\n\
+     1: mov r1,r15"\
+       : "=&r" (__result) : "r" (id), "r" (__futex) \
+       : "r0", "r1", "t", "memory"); \
+    if (__result) \
+      __result = __lll_robust_mutex_timedlock_wait (__result, __futex, \
+                                                   timeout);          \
+    __result; })
+
 #define lll_mutex_unlock(futex) \
   (void) ({ int __result, *__futex = &(futex); \
            __asm __volatile ("\
@@ -157,6 +237,37 @@ extern int __lll_mutex_unlock_wake (int *__futex) attribute_hidden;
            if (__result) \
              __lll_mutex_unlock_wake (__futex); })
 
+#define lll_robust_mutex_unlock(futex) \
+  (void) ({ int __result, *__futex = &(futex); \
+           __asm __volatile ("\
+               .align 2\n\
+               mova 1f,r0\n\
+               mov r15,r1\n\
+               mov #-6,r15\n\
+            0: mov.l @%1,%0\n\
+               and %2,%0\n\
+               mov.l %0,@%1\n\
+            1: mov r1,r15"\
+               : "=&r" (__result) : "r" (__futex), "r" (FUTEX_TID_MASK) \
+               : "r0", "r1", "memory");        \
+           if (__result) \
+             __lll_mutex_unlock_wake (__futex); })
+
+#define lll_robust_mutex_dead(futex) \
+  (void) ({ int __ignore, *__futex = &(futex); \
+           __asm __volatile ("\
+               .align 2\n\
+               mova 1f,r0\n\
+               mov r15,r1\n\
+               mov #-6,r15\n\
+            0: mov.l @%1,%0\n\
+               or %2,%0\n\
+               mov.l %0,@%1\n\
+            1: mov r1,r15"\
+               : "=&r" (__ignore) : "r" (__futex), "r" (FUTEX_OWNER_DIED) \
+               : "r0", "r1", "memory");        \
+           lll_futex_wake (__futex, 1); })
+
 #define lll_mutex_islocked(futex) \
   (futex != 0)
 
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/lowlevelrobustlock.S b/nptl/sysdeps/unix/sysv/linux/sh/lowlevelrobustlock.S
new file mode 100644 (file)
index 0000000..c57d3cf
--- /dev/null
@@ -0,0 +1,224 @@
+/* Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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 <sysdep.h>
+#include <pthread-errnos.h>
+#include <lowlevelrobustlock.h>
+#include "lowlevel-atomic.h"
+
+       .text
+
+#define SYS_gettimeofday       __NR_gettimeofday
+#define SYS_futex              240
+#define FUTEX_WAIT             0
+#define FUTEX_WAKE             1
+#define FUTEX_WAITERS          0x80000000
+#define FUTEX_OWNER_DIED       0x40000000
+
+
+       .globl  __lll_robust_mutex_lock_wait
+       .type   __lll_robust_mutex_lock_wait,@function
+       .hidden __lll_robust_mutex_lock_wait
+       .align  5
+       cfi_startproc
+__lll_robust_mutex_lock_wait:
+       mov.l   r8, @-r15
+       cfi_adjust_cfa_offset(4)
+       cfi_rel_offset (r8, 0)
+       mov     r5, r8
+       mov     #0, r7          /* No timeout.  */
+       mov     #FUTEX_WAIT, r5
+
+4:
+       mov     r4, r6
+       mov.l   .L_FUTEX_WAITERS, r0
+       or      r0, r6
+       shlr    r0              /* r0 = FUTEX_OWNER_DIED */
+       tst     r0, r4
+       bf/s    3f
+        cmp/eq r4, r6
+       bt      1f
+
+       CMPXCHG (r4, @r8, r6, r2)
+       bf      2f
+
+1:
+       mov     r8, r4
+       mov     #SYS_futex, r3
+       extu.b  r3, r3
+       trapa   #0x14
+       SYSCALL_INST_PAD
+
+       mov.l   @r8, r2
+
+2:
+       tst     r2, r2
+       bf/s    4b
+        mov    r2, r4
+
+       stc     gbr, r1
+       mov.w   .Ltidoff, r2
+       add     r2, r1
+       mov.l   @r1, r6
+       mov     #0, r3
+       CMPXCHG (r3, @r8, r6, r4)
+       bf      4b
+       mov     #0, r4
+
+3:
+       mov.l   @r15+, r8
+       ret
+        mov    r4, r0
+       cfi_endproc
+       .align  2
+.L_FUTEX_WAITERS:
+       .long   FUTEX_WAITERS
+.Ltidoff:
+       .word   TID - TLS_PRE_TCB_SIZE
+       .size   __lll_robust_mutex_lock_wait,.-__lll_robust_mutex_lock_wait
+
+
+       .globl  __lll_robust_mutex_timedlock_wait
+       .type   __lll_robust_mutex_timedlock_wait,@function
+       .hidden __lll_robust_mutex_timedlock_wait
+       .align  5
+       cfi_startproc
+__lll_robust_mutex_timedlock_wait:
+       /* Check for a valid timeout value.  */
+       mov.l   @(4,r6), r1
+       mov.l   .L1g, r0
+       cmp/hs  r0, r1
+       bt      3f
+
+       mov.l   r10, @-r15
+       cfi_adjust_cfa_offset(4)
+       cfi_rel_offset (r10, 0)
+       mov.l   r9, @-r15
+       cfi_adjust_cfa_offset(4)
+       cfi_rel_offset (r9, 0)
+       mov.l   r8, @-r15
+       cfi_adjust_cfa_offset(4)
+       cfi_rel_offset (r8, 0)
+       mov     r4, r10
+       mov     r6, r9
+       mov     r5, r8
+
+       /* Stack frame for the timespec and timeval structs.  */
+       add     #-8, r15
+       cfi_adjust_cfa_offset(8)
+
+1:
+       /* Get current time.  */
+       mov     r15, r4
+       mov     #0, r5
+       mov     #SYS_gettimeofday, r3
+       trapa   #0x12
+       SYSCALL_INST_PAD
+
+       /* Compute relative timeout.  */
+       mov.l   @(4,r15), r0
+       mov.w   .L1k, r1
+       dmulu.l r0, r1          /* Micro seconds to nano seconds.  */
+       mov.l   @r9, r2
+       mov.l   @(4,r9), r3
+       mov.l   @r15, r0
+       sts     macl, r1
+       sub     r0, r2
+       clrt
+       subc    r1, r3
+       bf      4f
+       mov.l   .L1g, r1
+       add     r1, r3
+       add     #-1, r2
+4:
+       cmp/pz  r2
+       bf      8f              /* Time is already up.  */
+
+       mov.l   r2, @r15        /* Store relative timeout.  */
+       mov.l   r3, @(4,r15)
+
+       mov     r10, r6
+       mov.l   .L_FUTEX_WAITERS2, r0
+       or      r0, r6
+       shlr    r0              /* r0 = FUTEX_OWNER_DIED */
+       tst     r0, r4
+       bf/s    6f
+        cmp/eq r4, r6
+       bt      2f
+
+       CMPXCHG (r4, @r8, r6, r2)
+       bf/s    5f
+        mov    #0, r5
+
+2:
+       mov     r8, r4
+       mov     #FUTEX_WAIT, r5
+       mov     r10, r6
+       mov     r15, r7
+       mov     #SYS_futex, r3
+       extu.b  r3, r3
+       trapa   #0x14
+       SYSCALL_INST_PAD
+       mov     r0, r5
+
+       mov.l   @r8, r2
+
+5:
+       tst     r2, r2
+       bf/s    7f
+        mov    r2, r10
+
+       stc     gbr, r1
+       mov.w   .Ltidoff2, r2
+       add     r2, r1
+       mov.l   @r1, r4
+       mov     #0, r3
+       CMPXCHG (r3, @r8, r4, r10)
+       bf      7f
+       mov     #0, r0
+
+6:
+       add     #8, r15
+       mov.l   @r15+, r8
+       mov.l   @r15+, r9
+       rts
+        mov.l  @r15+, r10
+
+7:
+       /* Check whether the time expired.  */
+       mov     #-ETIMEDOUT, r1
+       cmp/eq  r5, r1
+       bf      1b
+
+8:
+       bra     6b
+        mov    #ETIMEDOUT, r0
+3:
+       rts
+        mov    #EINVAL, r0
+       cfi_endproc
+       .align  2
+.L_FUTEX_WAITERS2:
+       .long   FUTEX_WAITERS
+.L1g:
+       .long   1000000000
+.Ltidoff2:
+       .word   TID - TLS_PRE_TCB_SIZE
+.L1k:
+       .word   1000
+       .size   __lll_robust_mutex_timedlock_wait,.-__lll_robust_mutex_timedlock_wait