diff options
author | Ulrich Drepper <drepper@redhat.com> | 2003-07-12 01:29:23 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2003-07-12 01:29:23 +0000 |
commit | 4a17085f1589c5451d031995534e00e763364fb0 (patch) | |
tree | 7c4d50a5c79d4d8a6adbe7f4729929bd20daaff6 /nptl | |
parent | 6080ecdf3cfc34b45bdfc7669f03359adc77d959 (diff) | |
download | glibc-4a17085f1589c5451d031995534e00e763364fb0.tar.gz glibc-4a17085f1589c5451d031995534e00e763364fb0.tar.xz glibc-4a17085f1589c5451d031995534e00e763364fb0.zip |
Update.
2003-07-12 Kaz Kojima <kkojima@rr.iij4u.or.jp> * sysdeps/unix/sysv/linux/sh/socket.S: Save and restore the PR register across CENABLE and CDISABLE.
Diffstat (limited to 'nptl')
-rw-r--r-- | nptl/ChangeLog | 20 | ||||
-rw-r--r-- | nptl/sysdeps/sh/tcb-offsets.sym | 10 | ||||
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S | 88 | ||||
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S | 61 | ||||
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S | 7 | ||||
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S | 7 | ||||
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S | 9 | ||||
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S | 9 | ||||
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/sh/sem_timedwait.S | 64 | ||||
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/sh/sem_wait.S | 58 | ||||
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h | 7 |
11 files changed, 258 insertions, 82 deletions
diff --git a/nptl/ChangeLog b/nptl/ChangeLog index f00ba09057..56a38b28fa 100644 --- a/nptl/ChangeLog +++ b/nptl/ChangeLog @@ -1,3 +1,23 @@ +2003-07-12 Kaz Kojima <kkojima@rr.iij4u.or.jp> + + * sysdeps/sh/tcb-offsets.sym: Add RESULT, TID, CANCELHANDLING and + CLEANUP_JMP_BUF. + * sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S: Use more + registers as variables. Call __pthread_mutex_unlock_usercnt. + * sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S: Likewise. + * sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S: Store TID + not self pointer in __writer. Compare with TID to determine + deadlocks. + * sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S: Likewise. + * sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S: + Likewise. + * sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S: + Likewise. + * sysdeps/unix/sysv/linux/sh/sem_wait.S: Add cancellation support. + * sysdeps/unix/sysv/linux/sh/sem_timedwait.S: Likewise. + * sysdeps/unix/sysv/linux/sh/sysdep-cancel.h: Define all the nice + macros also when compiling librt. + 2003-07-11 Jakub Jelinek <jakub@redhat.com> * Makefile (CFLAGS-pthread_once.c): Add -fexceptions diff --git a/nptl/sysdeps/sh/tcb-offsets.sym b/nptl/sysdeps/sh/tcb-offsets.sym index fcc549fed7..e96daf980f 100644 --- a/nptl/sysdeps/sh/tcb-offsets.sym +++ b/nptl/sysdeps/sh/tcb-offsets.sym @@ -1,6 +1,10 @@ #include <sysdep.h> #include <tls.h> -MULTIPLE_THREADS_OFFSET offsetof (struct pthread, header.multiple_threads) -TLS_PRE_TCB_SIZE sizeof (struct pthread) -MUTEX_FUTEX offsetof (pthread_mutex_t, __data.__lock) +RESULT offsetof (struct pthread, result) +TID offsetof (struct pthread, tid) +CANCELHANDLING offsetof (struct pthread, cancelhandling) +CLEANUP_JMP_BUF offsetof (struct pthread, cleanup_jmp_buf) +MULTIPLE_THREADS_OFFSET offsetof (struct pthread, header.multiple_threads) +TLS_PRE_TCB_SIZE sizeof (struct pthread) +MUTEX_FUTEX offsetof (pthread_mutex_t, __data.__lock) diff --git a/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S b/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S index 5de20dd799..e519bf6461 100644 --- a/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S +++ b/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S @@ -36,15 +36,17 @@ .type __pthread_cond_timedwait, @function .align 5 __pthread_cond_timedwait: - mov.l r12, @-r15 - mov.l r10, @-r15 - mov.l r9, @-r15 mov.l r8, @-r15 + mov.l r9, @-r15 + mov.l r10, @-r15 + mov.l r11, @-r15 + mov.l r12, @-r15 + mov.l r13, @-r15 sts.l pr, @-r15 add #-64, r15 mov r4, r8 mov r5, r9 - mov r6, r10 + mov r6, r13 /* Get internal lock. */ mov #1, r3 @@ -64,13 +66,16 @@ __pthread_cond_timedwait: /* Unlock the mutex. */ mov.l .Lmunlock1, r1 + mov #0, r5 bsrf r1 mov r9, r4 .Lmunlock1b: tst r0, r0 - bf 16f - + bt 0f + bra 16f + nop +0: mov #1, r2 mov #0, r3 @@ -93,7 +98,11 @@ __pthread_cond_timedwait: mov.l .Lccleanup1, r5 #endif mov r15, r4 - add #36, r4 + add #32, r4 + + /* Prepare structure passed to cancellation handler. */ + mov.l r8, @(4,r15) + mov.l r9, @(8,r15) mov.l .Lccpush1, r1 bsrf r1 @@ -101,13 +110,8 @@ __pthread_cond_timedwait: .Lccpush1b: /* Get and store current wakeup_seq value. */ - mov.l @(wakeup_seq,r8), r0 - mov.l @(wakeup_seq+4,r8), r1 - mov.l r0, @(20,r15) - mov.l r1, @(24,r15) - /* Prepare structure passed to cancellation handler. */ - mov.l r9, @r15 - mov.l r8, @(4,r15) + mov.l @(wakeup_seq,r8), r10 + mov.l @(wakeup_seq+4,r8), r11 /* Unlock. */ 8: @@ -125,23 +129,23 @@ __pthread_cond_timedwait: bsrf r1 nop .Lenable1b: - mov.l r0, @(8,r15) + mov.l r0, @r15 /* Get current time. */ mov r15, r4 - add #12, r4 + add #16, r4 mov #0, r5 mov #SYS_gettimeofday, r3 trapa #0x12 SYSCALL_INST_PAD /* Compute relative timeout. */ - mov.l @(16,r15), r0 + mov.l @(20,r15), r0 mov.w .L1k, r1 dmulu.l r0, r1 /* Milli seconds to nano seconds. */ - mov.l @r10, r2 - mov.l @(4,r10), r3 - mov.l @(12,r15), r0 + mov.l @r13, r2 + mov.l @(4,r13), r3 + mov.l @(16,r15), r0 sts macl, r1 sub r0, r2 clrt @@ -155,24 +159,24 @@ __pthread_cond_timedwait: bf 13f /* Time is already up. */ /* Store relative timeout. */ - mov.l r2, @(12,r15) - mov.l r3, @(16,r15) + mov.l r2, @(16,r15) + mov.l r3, @(20,r15) mov r15, r7 - add #12, r7 + add #16, r7 mov #FUTEX_WAIT, r5 - mov.l @(20,r15), r6 + mov r10, r6 mov r8, r4 add #wakeup_seq, r4 mov #SYS_futex, r3 extu.b r3, r3 trapa #0x14 SYSCALL_INST_PAD - mov.l r0, @(28,r15) + mov.l r0, @(12,r15) mov.l .Ldisable1, r1 bsrf r1 - mov.l @(8,r15), r4 + mov.l @r15, r4 .Ldisable1b: /* Lock. */ @@ -191,14 +195,12 @@ __pthread_cond_timedwait: mov.l @(wakeup_seq,r8), r2 mov.l @(wakeup_seq+4,r8), r3 - mov.l @(24,r15), r5 - cmp/hi r5, r3 + cmp/hi r11, r3 bt 7f - cmp/hi r3, r5 + cmp/hi r3, r11 bt 15f - mov.l @(20,r15), r5 - cmp/hs r2, r5 + cmp/hs r2, r10 bt 15f 7: cmp/hi r1, r3 @@ -208,7 +210,7 @@ __pthread_cond_timedwait: cmp/hi r0, r2 bt 9f 15: - mov.l @(28,r15),r0 + mov.l @(12,r15),r0 cmp/eq #-ETIMEDOUT, r0 bf 8b 13: @@ -224,11 +226,11 @@ __pthread_cond_timedwait: mov.l r1,@(wakeup_seq+4,r8) mov #ETIMEDOUT, r0 bra 14f - mov.l r0, @(32,r15) + mov.l r0, @(24,r15) 9: mov #0, r0 - mov.l r0, @(32,r15) + mov.l r0, @(24,r15) 14: mov #1, r2 mov #0, r3 @@ -252,7 +254,7 @@ __pthread_cond_timedwait: 11: /* Remove cancellation handler. */ mov r15, r4 - add #36, r4 + add #32, r4 mov.l .Lcpop1, r1 bsrf r1 mov #0, r5 @@ -267,23 +269,25 @@ __pthread_cond_timedwait: /* We return the result of the mutex_lock operation if it failed. */ tst r0, r0 bf 18f - mov.l @(32,r15), r0 + mov.l @(24,r15), r0 18: add #64, r15 lds.l @r15+, pr - mov.l @r15+, r8 - mov.l @r15+, r9 + mov.l @r15+, r13 + mov.l @r15+, r12 + mov.l @r15+, r11 mov.l @r15+, r10 + mov.l @r15+, r9 rts - mov.l @r15+, r12 + mov.l @r15+, r8 ret .L1k: .word 1000 .align 2 .Lmunlock1: - .long __pthread_mutex_unlock_internal-.Lmunlock1b + .long __pthread_mutex_unlock_usercnt-.Lmunlock1b #ifdef PIC .Lgot1: .long _GLOBAL_OFFSET_TABLE_ @@ -360,7 +364,7 @@ __pthread_cond_timedwait: 16: /* The initial unlocking of the mutex failed. */ - mov.l r0, @(32,r15) + mov.l r0, @(24,r15) #if cond_lock != 0 DEC (@(cond_lock,r8), r2) #else @@ -379,7 +383,7 @@ __pthread_cond_timedwait: .Lmwake4b: 17: bra 18b - mov.l @(32,r15), r0 + mov.l @(24,r15), r0 .align 2 .Lmwait2: diff --git a/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S b/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S index f4f0edb0e6..06b0f6243a 100644 --- a/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S +++ b/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S @@ -133,9 +133,11 @@ __condvar_cleanup: .type __pthread_cond_wait, @function .align 5 __pthread_cond_wait: - mov.l r12, @-r15 - mov.l r9, @-r15 mov.l r8, @-r15 + mov.l r9, @-r15 + mov.l r10, @-r15 + mov.l r11, @-r15 + mov.l r12, @-r15 sts.l pr, @-r15 add #-48, r15 mov r4, r8 @@ -149,21 +151,27 @@ __pthread_cond_wait: XADD (r3, @r8, r2) #endif tst r2, r2 - bf 1f + bt 2f + bra 1f + nop +2: /* Store the reference to the mutex. If there is already a different value in there this is a bad user bug. */ mov.l r9, @(dep_mutex,r8) /* Unlock the mutex. */ mov.l .Lmunlock0, r1 + mov #0, r5 bsrf r1 mov r9, r4 .Lmunlock0b: tst r0, r0 - bf 12f - + bt 0f + bra 12f + nop +0: mov #1, r2 mov #0, r3 @@ -186,7 +194,11 @@ __pthread_cond_wait: mov.l .Lccleanup0, r5 #endif mov r15, r4 - add #20, r4 + add #16, r4 + + /* Prepare structure passed to cancellation handler. */ + mov.l r8, @(4,r15) + mov.l r9, @(8,r15) mov.l .Lccpush0, r1 bsrf r1 @@ -194,13 +206,8 @@ __pthread_cond_wait: .Lccpush0b: /* Get and store current wakeup_seq value. */ - mov.l @(wakeup_seq,r8), r0 - mov.l @(wakeup_seq+4,r8), r1 - mov.l r0, @(12,r15) - mov.l r1, @(16,r15) - /* Prepare structure passed to cancellation handler. */ - mov.l r9, @r15 - mov.l r8, @(4,r15) + mov.l @(wakeup_seq,r8), r10 + mov.l @(wakeup_seq+4,r8), r11 8: /* Unlock. */ @@ -216,11 +223,11 @@ __pthread_cond_wait: bsrf r1 nop .Lenable0b: - mov.l r0, @(8,r15) + mov.l r0, @r15 mov #0, r7 mov #FUTEX_WAIT, r5 - mov.l @(12,r15), r6 + mov r10, r6 mov r8, r4 add #wakeup_seq, r4 mov #SYS_futex, r3 @@ -230,7 +237,7 @@ __pthread_cond_wait: mov.l .Ldisable0, r1 bsrf r1 - mov.l @(8,r15), r4 + mov.l @r15, r4 .Ldisable0b: /* Lock. */ @@ -249,14 +256,12 @@ __pthread_cond_wait: mov.l @(wakeup_seq,r8), r2 mov.l @(wakeup_seq+4,r8), r3 - mov.l @(16,r15), r5 - cmp/hi r5, r3 + cmp/hi r11, r3 bt 7f - cmp/hi r3, r5 + cmp/hi r3, r11 bt 8b - mov.l @(12,r15), r5 - cmp/hs r2, r5 + cmp/hs r2, r10 bt 8b 7: cmp/hi r1, r3 @@ -288,7 +293,7 @@ __pthread_cond_wait: 11: /* Remove cancellation handler. */ mov r15, r4 - add #20, r4 + add #16, r4 mov.l .Lcpop0, r1 bsrf r1 mov #0, r5 @@ -304,14 +309,16 @@ __pthread_cond_wait: 14: add #48, r15 lds.l @r15+, pr - mov.l @r15+, r8 + mov.l @r15+, r12 + mov.l @r15+, r11 + mov.l @r15+, r10 mov.l @r15+, r9 rts - mov.l @r15+, r12 + mov.l @r15+, r8 .align 2 .Lmunlock0: - .long __pthread_mutex_unlock_internal-.Lmunlock0b + .long __pthread_mutex_unlock_usercnt-.Lmunlock0b #ifdef PIC .Lgot0: .long _GLOBAL_OFFSET_TABLE_ @@ -385,7 +392,7 @@ __pthread_cond_wait: 12: /* The initial unlocking of the mutex failed. */ - mov.l r0, @-r15 + mov.l r0, @(12,r15) #if cond_lock != 0 DEC (@(cond_lock,r8), r2) #else @@ -405,7 +412,7 @@ __pthread_cond_wait: 13: bra 14b - mov.l @r15+, r0 + mov.l @(12,r15), r0 .align 2 .Lmwait0: diff --git a/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S b/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S index 14da24ec86..bee9e9625e 100644 --- a/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S +++ b/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S @@ -19,6 +19,7 @@ #include <sysdep.h> #include <lowlevelrwlock.h> #include <pthread-errnos.h> +#include <tcb-offsets.h> #include "lowlevel-atomic.h" #define SYS_futex 240 @@ -137,12 +138,18 @@ __pthread_rwlock_rdlock: nop 14: stc gbr, r1 + mov.w .Ltidoff, r2 + add r2, r1 + mov.l @r1, r1 cmp/eq r1, r0 bf 3b /* Deadlock detected. */ bra 9b mov #EDEADLK, r3 +.Ltidoff: + .word TID - TLS_PRE_TCB_SIZE + 6: mov r8, r4 #if MUTEX != 0 diff --git a/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S b/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S index 5f1c1f739a..b43b576ef6 100644 --- a/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S +++ b/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S @@ -19,6 +19,7 @@ #include <sysdep.h> #include <lowlevelrwlock.h> #include <pthread-errnos.h> +#include <tcb-offsets.h> #include "lowlevel-atomic.h" #define SYS_gettimeofday __NR_gettimeofday @@ -196,12 +197,18 @@ pthread_rwlock_timedrdlock: nop 14: stc gbr, r1 + mov.w .Ltidoff, r2 + add r2, r1 + mov.l @r1, r1 cmp/eq r1, r0 bf 3b /* Deadlock detected. */ bra 9b mov #EDEADLK, r3 +.Ltidoff: + .word TID - TLS_PRE_TCB_SIZE + 6: mov r8, r4 #if MUTEX != 0 diff --git a/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S b/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S index 36febf484e..14008279e3 100644 --- a/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S +++ b/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S @@ -19,6 +19,7 @@ #include <sysdep.h> #include <lowlevelrwlock.h> #include <pthread-errnos.h> +#include <tcb-offsets.h> #include "lowlevel-atomic.h" #define SYS_gettimeofday __NR_gettimeofday @@ -154,6 +155,8 @@ pthread_rwlock_timedwrlock: 5: mov #0, r3 stc gbr, r0 + mov.w .Ltidoff, r1 + mov.l @(r0,r1), r0 mov.l r0, @(WRITER,r8) 9: #if MUTEX == 0 @@ -193,6 +196,9 @@ pthread_rwlock_timedwrlock: nop 14: stc gbr, r1 + mov.w .Ltidoff, r2 + add r2, r1 + mov.l @r1, r1 cmp/eq r1, r0 bf 3b bra 9b @@ -209,6 +215,9 @@ pthread_rwlock_timedwrlock: bra 7b mov #0, r3 +.Ltidoff: + .word TID - TLS_PRE_TCB_SIZE + 4: /* Overflow. */ mov.l @(WRITERS_QUEUED,r8), r1 diff --git a/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S b/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S index b923c8846b..7b1fbcfa14 100644 --- a/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S +++ b/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S @@ -19,6 +19,7 @@ #include <sysdep.h> #include <lowlevelrwlock.h> #include <pthread-errnos.h> +#include <tcb-offsets.h> #include "lowlevel-atomic.h" #define SYS_futex 240 @@ -99,6 +100,8 @@ __pthread_rwlock_wrlock: 5: mov #0, r3 stc gbr, r0 + mov.w .Ltidoff, r1 + mov.l @(r0,r1), r0 mov.l r0, @(WRITER,r8) 9: #if MUTEX == 0 @@ -130,6 +133,9 @@ __pthread_rwlock_wrlock: nop 14: stc gbr, r1 + mov.w .Ltidoff, r2 + add r2, r1 + mov.l @r1, r1 cmp/eq r1, r0 bf 3b bra 9b @@ -146,6 +152,9 @@ __pthread_rwlock_wrlock: bra 7b mov #0, r3 +.Ltidoff: + .word TID - TLS_PRE_TCB_SIZE + 4: mov.l @(WRITERS_QUEUED,r8), r1 add #-1, r1 diff --git a/nptl/sysdeps/unix/sysv/linux/sh/sem_timedwait.S b/nptl/sysdeps/unix/sysv/linux/sh/sem_timedwait.S index b6d4d4c886..4832d4f358 100644 --- a/nptl/sysdeps/unix/sysv/linux/sh/sem_timedwait.S +++ b/nptl/sysdeps/unix/sysv/linux/sh/sem_timedwait.S @@ -19,6 +19,7 @@ #include <sysdep.h> #include <shlib-compat.h> #include <pthread-errnos.h> +#include <tcb-offsets.h> #include "lowlevel-atomic.h" @@ -33,6 +34,15 @@ .type sem_timedwait,@function .align 5 sem_timedwait: + /* First check for cancellation. */ + stc gbr, r0 + mov.w .Lchand, r1 + mov.l @(r0,r1), r0 + mov #0xf9, r1 + and r1, r0 + cmp/eq #8, r0 + bt 10f + mov.l @r4, r0 2: tst r0, r0 @@ -48,9 +58,10 @@ sem_timedwait: 1: /* Check whether the timeout value is valid. */ - mov.l r12, @-r15 - mov.l r9, @-r15 mov.l r8, @-r15 + mov.l r9, @-r15 + mov.l r10, @-r15 + mov.l r12, @-r15 sts.l pr, @-r15 add #-8, r15 mov r4, r8 @@ -63,6 +74,12 @@ sem_timedwait: bt/s 6f mov #EINVAL, r0 7: + mov.l .Lenable0, r1 + bsrf r1 + nop +.Lenable0b: + mov r0, r10 + /* Compute relative timeout. */ mov r15, r4 mov #0, r5 @@ -102,6 +119,13 @@ sem_timedwait: trapa #0x14 SYSCALL_INST_PAD + mov.l .Ldisable0, r1 + mov r10, r4 + bsrf r1 + mov r0, r10 +.Ldisable0b: + mov r10, r0 + tst r0, r0 bt 9f cmp/eq #-EWOULDBLOCK, r0 @@ -121,9 +145,10 @@ sem_timedwait: add #8, r15 lds.l @r15+, pr - mov.l @r15+, r8 - mov.l @r15+, r9 mov.l @r15+, r12 + mov.l @r15+, r10 + mov.l @r15+, r9 + mov.l @r15+, r8 rts mov #0, r0 @@ -150,14 +175,35 @@ sem_timedwait: #endif add #8, r15 lds.l @r15+, pr - mov.l @r15+, r8 - mov.l @r15+, r9 mov.l @r15+, r12 + mov.l @r15+, r10 + mov.l @r15+, r9 + mov.l @r15+, r8 rts mov #-1, r0 +10: + /* Canceled. */ + stc gbr, r0 + mov.w .Lresult, r1 + mov #-1, r2 + mov.l r2, @(r0,r1) + mov.w .Lchand, r0 + or.b #0x10, @(r0,gbr) + stc gbr, r0 + mov.w .Lclbuf, r1 + mov.l .Lunwind, r2 + jmp @r2 + mov.l @(r0,r1), r4 + .L1k: .word 1000 +.Lchand: + .word CANCELHANDLING - TLS_PRE_TCB_SIZE +.Lresult: + .word RESULT - TLS_PRE_TCB_SIZE +.Lclbuf: + .word CLEANUP_JMP_BUF - TLS_PRE_TCB_SIZE .align 2 .L1g: .long 1000000000 @@ -170,4 +216,10 @@ sem_timedwait: .Lerrloc2: .long __errno_location@PLT-(.Lerrloc2b+2-.) #endif +.Lenable0: + .long __pthread_enable_asynccancel-.Lenable0b +.Ldisable0: + .long __pthread_disable_asynccancel-.Ldisable0b +.Lunwind: + .long __pthread_unwind .size sem_timedwait,.-sem_timedwait diff --git a/nptl/sysdeps/unix/sysv/linux/sh/sem_wait.S b/nptl/sysdeps/unix/sysv/linux/sh/sem_wait.S index 49b76c6d8c..8a55394c29 100644 --- a/nptl/sysdeps/unix/sysv/linux/sh/sem_wait.S +++ b/nptl/sysdeps/unix/sysv/linux/sh/sem_wait.S @@ -19,6 +19,7 @@ #include <sysdep.h> #include <shlib-compat.h> #include <pthread-errnos.h> +#include <tcb-offsets.h> #include "lowlevel-atomic.h" @@ -33,8 +34,18 @@ .type __new_sem_wait,@function .align 5 __new_sem_wait: - mov.l r12, @-r15 + /* First check for cancellation. */ + stc gbr, r0 + mov.w .Lchand, r1 + mov.l @(r0,r1), r0 + mov #0xf9, r1 + and r1, r0 + cmp/eq #8, r0 + bt 5f + mov.l r8, @-r15 + mov.l r10, @-r15 + mov.l r12, @-r15 sts.l pr, @-r15 mov r4, r8 3: @@ -48,12 +59,19 @@ __new_sem_wait: CMPXCHG (r4, @r8, r3, r2) bf 2b lds.l @r15+, pr - mov.l @r15+, r8 mov.l @r15+, r12 + mov.l @r15+, r10 + mov.l @r15+, r8 rts mov #0, r0 1: + mov.l .Lenable0, r1 + bsrf r1 + nop +.Lenable0b: + mov r0, r10 + mov r8, r4 mov #FUTEX_WAIT, r5 mov #0, r6 @@ -63,6 +81,13 @@ __new_sem_wait: trapa #0x14 SYSCALL_INST_PAD + mov.l .Ldisable0, r1 + mov r10, r4 + bsrf r1 + mov r0, r10 +.Ldisable0b: + mov r10, r0 + tst r0, r0 bt 3b cmp/eq #-EWOULDBLOCK, r0 @@ -88,11 +113,32 @@ __new_sem_wait: mov.l r8, @r0 #endif lds.l @r15+, pr - mov.l @r15+, r8 mov.l @r15+, r12 + mov.l @r15+, r10 + mov.l @r15+, r8 rts mov #-1, r0 +5: + /* Canceled. */ + stc gbr, r0 + mov.w .Lresult, r1 + mov #-1, r2 + mov.l r2, @(r0,r1) + mov.w .Lchand, r0 + or.b #0x10, @(r0,gbr) + stc gbr, r0 + mov.w .Lclbuf, r1 + mov.l .Lunwind, r2 + jmp @r2 + mov.l @(r0,r1), r4 + +.Lchand: + .word CANCELHANDLING - TLS_PRE_TCB_SIZE +.Lresult: + .word RESULT - TLS_PRE_TCB_SIZE +.Lclbuf: + .word CLEANUP_JMP_BUF - TLS_PRE_TCB_SIZE .align 2 .Lgot0: .long _GLOBAL_OFFSET_TABLE_ @@ -103,5 +149,11 @@ __new_sem_wait: .Lerrloc0: .long __errno_location@PLT-(.Lerrloc0b+2-.) #endif +.Lenable0: + .long __pthread_enable_asynccancel-.Lenable0b +.Ldisable0: + .long __pthread_disable_asynccancel-.Ldisable0b +.Lunwind: + .long __pthread_unwind .size __new_sem_wait,.-__new_sem_wait versioned_symbol(libpthread, __new_sem_wait, sem_wait, GLIBC_2_1) diff --git a/nptl/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h b/nptl/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h index b7dcfc8c43..b783c98108 100644 --- a/nptl/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h +++ b/nptl/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h @@ -90,9 +90,14 @@ # ifdef IS_IN_libpthread # define __local_enable_asynccancel __pthread_enable_asynccancel # define __local_disable_asynccancel __pthread_disable_asynccancel -# else +# elif !defined NOT_IN_libc # define __local_enable_asynccancel __libc_enable_asynccancel # define __local_disable_asynccancel __libc_disable_asynccancel +# elif defined IS_IN_librt +# define __local_enable_asynccancel __librt_enable_asynccancel +# define __local_disable_asynccancel __librt_disable_asynccancel +# else +# error Unsupported library # endif # define CENABLE \ |