diff options
Diffstat (limited to 'nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S')
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S | 225 |
1 files changed, 159 insertions, 66 deletions
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S b/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S index 115c5292dd..936a4e3868 100644 --- a/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S +++ b/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S @@ -28,111 +28,204 @@ #define FUTEX_WAKE 1 - .globl __lll_lock_wait - .type __lll_lock_wait,@function - .hidden __lll_lock_wait + .globl __lll_mutex_lock_wait + .type __lll_mutex_lock_wait,@function + .hidden __lll_mutex_lock_wait .align 5 -__lll_lock_wait: +__lll_mutex_lock_wait: + mov.l r8, @-r15 mov r4, r6 - mov r5, r4 + mov r5, r8 mov #0, r7 /* No timeout. */ mov #FUTEX_WAIT, r5 -2: - add #-1, r6 /* account for the preceeded xadd. */ +1: + mov #2, r4 + cmp/eq r4, r6 + bt 3f + + mov #1, r3 + CMPXCHG (r3, @r8, r4, r2) + tst r2, r2 + bt 2f + +3: + mov r8, r4 mov #SYS_futex, r3 extu.b r3, r3 trapa #0x14 SYSCALL_INST_PAD - mov #-1, r3 - XADD (r3, @r4, r2) - tst r3, r3 - bf/s 2b - mov r2, r6 +2: + mov #0, r3 + mov #2, r4 + CMPXCHG (r3, @r8, r4, r2) + bf 1b - mov #-1, r1 - mov.l r1, @r4 - rts + mov.l @r15+, r8 + ret mov r2, r0 - .size __lll_lock_wait,.-__lll_lock_wait + .size __lll_mutex_lock_wait,.-__lll_mutex_lock_wait #ifdef NOT_IN_libc - .globl lll_unlock_wake_cb - .type lll_unlock_wake_cb,@function - .hidden lll_unlock_wake_cb + .globl __lll_mutex_timedlock_wait + .type __lll_mutex_timedlock_wait,@function + .hidden __lll_mutex_timedlock_wait .align 5 -lll_unlock_wake_cb: +__lll_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 + mov.l r9, @-r15 + mov.l r8, @-r15 + mov r4, r10 + mov r6, r9 + mov r5, r8 + + /* Stack frame for the timespec and timeval structs. */ + add #-8, r15 - .align 2 - mova 1f, r0 - mov r15, r1 - mov #-6, r15 -0: - mov.l @r4, r2 - add #1, r2 - mov.l r2, @r4 1: - mov r1, r15 - cmp/pl r2 - bf 2f + /* 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 5f /* Time is already up. */ + + mov.l r2, @r15 /* Store relative timeout. */ + mov.l r3, @(4,r15) + + mov #1, r3 + mov #2, r4 + CMPXCHG (r3, @r8, r4, r2) + bt 8f + + 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, r4 + +8: + mov #0, r3 + mov #2, r4 + CMPXCHG (r3, @r8, r4, r2) + bf 7f + +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 r4, r1 + bt 5f + bra 1b nop - .size lll_unlock_wake_cb,.-lll_unlock_wake_cb +3: + rts + mov #EINVAL, r0 +5: + bra 6b + mov #ETIMEDOUT, r0 + +.L1k: + .word 1000 + .align 2 +.L1g: + .long 1000000000 + + .size __lll_mutex_timedlock_wait,.-__lll_mutex_timedlock_wait #endif - .globl __lll_unlock_wake - .type __lll_unlock_wake,@function - .hidden __lll_unlock_wake -__lll_unlock_wake: -2: +#ifdef NOT_IN_libc + .globl lll_unlock_wake_cb + .type lll_unlock_wake_cb,@function + .hidden lll_unlock_wake_cb + .align 5 +lll_unlock_wake_cb: + DEC (@r4, r2) + tst r2, r2 + bt 1f + mov #FUTEX_WAKE, r5 mov #1, r6 /* Wake one thread. */ mov #0, r7 - mov.l r6, @r4 /* Stores 1. */ + mov.l r7, @r4 /* Stores 0. */ mov #SYS_futex, r3 extu.b r3, r3 trapa #0x14 SYSCALL_INST_PAD + +1: rts nop - .size __lll_unlock_wake,.-__lll_unlock_wake + .size lll_unlock_wake_cb,.-lll_unlock_wake_cb +#endif -#ifdef NOT_IN_libc - .globl __lll_wait_tid - .type __lll_wait_tid,@function - .hidden __lll_wait_tid -__lll_wait_tid: - mov.l @r4, r6 -1: - mov #FUTEX_WAIT, r5 + .globl __lll_mutex_unlock_wake + .type __lll_mutex_unlock_wake,@function + .hidden __lll_mutex_unlock_wake + .align 5 +__lll_mutex_unlock_wake: + mov #FUTEX_WAKE, r5 + mov #1, r6 /* Wake one thread. */ mov #0, r7 + mov.l r7, @r4 /* Stores 0. */ mov #SYS_futex, r3 extu.b r3, r3 trapa #0x14 SYSCALL_INST_PAD - - mov r0, r1 - - mov.l @r4, r0 - tst r0, r0 - bf/s 1b - mov r0, r6 rts nop - .size __lll_wait_tid,.-__lll_wait_tid + .size __lll_mutex_unlock_wake,.-__lll_mutex_unlock_wake +#ifdef NOT_IN_libc .globl __lll_timedwait_tid .type __lll_timedwait_tid,@function .hidden __lll_timedwait_tid + .align 5 __lll_timedwait_tid: mov.l r9, @-r15 mov.l r8, @-r15 mov r4, r8 mov r5, r9 + + /* Stack frame for the timespec and timeval structs. */ add #-8, r15 2: @@ -145,8 +238,8 @@ __lll_timedwait_tid: /* Compute relative timeout. */ mov.l @(4,r15), r0 - mov.w .L1k, r1 - dmulu.l r0, r1 /* Milli seconds to nano seconds. */ + mov.w .L1k2, r1 + dmulu.l r0, r1 /* Micro seconds to nano seconds. */ mov.l @r9, r2 mov.l @(4,r9), r3 mov.l @r15, r0 @@ -155,7 +248,7 @@ __lll_timedwait_tid: clrt subc r1, r3 bf 5f - mov.l .L1g, r1 + mov.l .L1g2, r1 add r1, r3 add #-1, r2 5: @@ -165,20 +258,21 @@ __lll_timedwait_tid: mov.l r2, @r15 /* Store relative timeout. */ mov.l r3, @(4,r15) - mov.l @r8, r6 - tst r6, r6 + mov.l @r8, r2 + tst r2, r2 bt 4f mov r8, r4 mov #FUTEX_WAIT, r5 + mov r2, r6 mov r15, r7 mov #SYS_futex, r3 extu.b r3, r3 trapa #0x14 SYSCALL_INST_PAD - mov.l @r8, r0 - tst r0, r0 + mov.l @r8, r2 + tst r2, r2 bf 1f 4: mov #0, r0 @@ -187,8 +281,8 @@ __lll_timedwait_tid: mov.l @r15+, r8 rts mov.l @r15+, r9 - 1: + /* Check whether the time expired. */ mov #-ETIMEDOUT, r1 cmp/eq r0, r1 bf 2b @@ -196,11 +290,10 @@ __lll_timedwait_tid: bra 3b mov #ETIMEDOUT, r0 -.L1k: +.L1k2: .word 1000 .align 2 -.L1g: +.L1g2: .long 1000000000 - .size __lll_timedwait_tid,.-__lll_timedwait_tid #endif |