diff options
Diffstat (limited to 'libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S')
-rw-r--r-- | libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S | 184 |
1 files changed, 138 insertions, 46 deletions
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S index 5812488b2..3e117564f 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S @@ -1,4 +1,4 @@ -/* Copyright (C) 2003, 2004 Free Software Foundation, Inc. +/* Copyright (C) 2003, 2004, 2006, 2007 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 @@ -17,16 +17,13 @@ 02111-1307 USA. */ #include <sysdep.h> +#include <lowlevellock.h> #include <lowlevelcond.h> #include <pthread-errnos.h> +#include <bits/kernel-features.h> +#include <tcb-offsets.h> #include "lowlevel-atomic.h" -#define SYS_gettimeofday __NR_gettimeofday - -#define FUTEX_WAIT 0 -#define FUTEX_WAKE 1 - - .text /* int pthread_cond_timedwait (pthread_cond_t *cond, pthread_mutex_t *mutex, @@ -119,7 +116,7 @@ __pthread_cond_timedwait: mov.l @(cond_futex,r8), r0 add r2, r0 mov.l r0, @(cond_futex,r8) - mov #(1 << clock_bits), r2 + mov #(1 << nwaiters_shift), r2 mov.l @(cond_nwaiters,r8), r0 add r2, r0 mov.l r0, @(cond_nwaiters,r8) @@ -135,7 +132,7 @@ __pthread_cond_timedwait: #ifdef __NR_clock_gettime /* Get the clock number. */ mov.l @(cond_nwaiters,r8), r4 - mov #((1 << clock_bits) - 1), r0 + mov #((1 << nwaiters_shift) - 1), r0 and r0, r4 /* Only clocks 0 and 1 are allowed. Both are handled in the kernel. */ @@ -163,7 +160,7 @@ __pthread_cond_timedwait: mov r15, r4 add #16, r4 mov #0, r5 - mov #SYS_gettimeofday, r3 + mov #__NR_gettimeofday, r3 trapa #0x12 SYSCALL_INST_PAD @@ -181,7 +178,7 @@ __pthread_cond_timedwait: mov r15, r4 add #16, r4 mov #0, r5 - mov #SYS_gettimeofday, r3 + mov #__NR_gettimeofday, r3 trapa #0x12 SYSCALL_INST_PAD @@ -233,7 +230,22 @@ __pthread_cond_timedwait: mov r15, r7 add #16, r7 - mov #FUTEX_WAIT, r5 + mov.l @(dep_mutex,r8), r0 + cmp/eq #-1, r0 + bt/s 99f + mov #FUTEX_WAIT, r5 +#ifdef __ASSUME_PRIVATE_FUTEX + mov #(FUTEX_WAIT|FUTEX_PRIVATE_FLAG), r5 + extu.b r5, r5 +#else + stc gbr, r1 + mov.w .Lpfoff, r2 + add r2, r1 + mov.l @r1, r5 + mov #FUTEX_WAIT, r0 + or r0, r5 +#endif +99: mov.l @(8,r15), r6 mov r8, r4 add #cond_futex, r4 @@ -322,7 +334,7 @@ __pthread_cond_timedwait: mov.l r1,@(woken_seq+4,r8) 24: - mov #(1 << clock_bits), r2 + mov #(1 << nwaiters_shift), r2 mov.l @(cond_nwaiters,r8),r0 sub r2, r0 mov.l r0,@(cond_nwaiters,r8) @@ -334,7 +346,7 @@ __pthread_cond_timedwait: not r0, r0 cmp/eq #0, r0 bf/s 25f - mov #((1 << clock_bits) - 1), r1 + mov #((1 << nwaiters_shift) - 1), r1 not r1, r1 mov.l @(cond_nwaiters,r8),r0 tst r1, r0 @@ -342,7 +354,22 @@ __pthread_cond_timedwait: mov r8, r4 add #cond_nwaiters, r4 - mov #FUTEX_WAKE, r5 + mov.l @(dep_mutex,r8), r0 + cmp/eq #-1, r0 + bt/s 99f + mov #FUTEX_WAKE, r5 +#ifdef __ASSUME_PRIVATE_FUTEX + mov #(FUTEX_WAKE|FUTEX_PRIVATE_FLAG), r5 + extu.b r5, r5 +#else + stc gbr, r1 + mov.w .Lpfoff, r2 + add r2, r1 + mov.l @r1, r5 + mov #FUTEX_WAKE, r0 + or r0, r5 +#endif +99: mov #1, r6 mov #0, r7 mov #SYS_futex, r3 @@ -382,6 +409,10 @@ __pthread_cond_timedwait: rts mov.l @r15+, r8 +#ifndef __ASSUME_PRIVATE_FUTEX +.Lpfoff: + .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE +#endif .L1k: .word 1000 .align 2 @@ -402,10 +433,17 @@ __pthread_cond_timedwait: #if cond_lock != 0 add #cond_lock, r5 #endif - mov.l .Lmwait2, r1 + mov.l @(dep_mutex,r8), r0 + cmp/eq #-1, r0 + bf/s 99f + mov #LLL_PRIVATE, r6 + mov #LLL_SHARED, r6 +99: + extu.b r6, r6 + mov.l .Lwait2, r1 bsrf r1 mov r2, r4 -.Lmwait2b: +.Lwait2b: bra 2b nop @@ -415,10 +453,16 @@ __pthread_cond_timedwait: #if cond_lock != 0 add #cond_lock, r4 #endif - mov.l .Lmwake2, r1 + mov.l @(dep_mutex,r8), r0 + cmp/eq #-1, r0 + bf/s 99f + mov #LLL_PRIVATE, r5 + mov #LLL_SHARED, r5 +99: + mov.l .Lmwait2, r1 bsrf r1 - nop -.Lmwake2b: + extu.b r5, r5 +.Lmwait2b: bra 4b nop @@ -428,10 +472,17 @@ __pthread_cond_timedwait: #if cond_lock != 0 add #cond_lock, r5 #endif - mov.l .Lmwait3, r1 + mov.l @(dep_mutex,r8), r0 + cmp/eq #-1, r0 + bf/s 99f + mov #LLL_PRIVATE, r6 + mov #LLL_SHARED, r6 +99: + extu.b r6, r6 + mov.l .Lwait3, r1 bsrf r1 mov r2, r4 -.Lmwait3b: +.Lwait3b: bra 6b nop @@ -441,10 +492,16 @@ __pthread_cond_timedwait: #if cond_lock != 0 add #cond_lock, r4 #endif - mov.l .Lmwake3, r1 + mov.l @(dep_mutex,r8), r0 + cmp/eq #-1, r0 + bf/s 99f + mov #LLL_PRIVATE, r5 + mov #LLL_SHARED, r5 +99: + mov.l .Lmwait3, r1 bsrf r1 - nop -.Lmwake3b: + extu.b r5, r5 +.Lmwait3b: bra 11b nop @@ -463,25 +520,31 @@ __pthread_cond_timedwait: #if cond_lock != 0 add #cond_lock, r4 #endif - mov.l .Lmwake4, r1 + mov.l @(dep_mutex,r8), r0 + cmp/eq #-1, r0 + bf/s 99f + mov #LLL_PRIVATE, r5 + mov #LLL_SHARED, r5 +99: + mov.l .Lmwait4, r1 bsrf r1 - nop -.Lmwake4b: + extu.b r5, r5 +.Lmwait4b: 17: bra 18b mov.l @(24,r15), r0 .align 2 +.Lwait2: + .long __lll_lock_wait-.Lwait2b .Lmwait2: - .long __lll_mutex_lock_wait-.Lmwait2b -.Lmwake2: - .long __lll_mutex_unlock_wake-.Lmwake2b + .long __lll_unlock_wake-.Lmwait2b +.Lwait3: + .long __lll_lock_wait-.Lwait3b .Lmwait3: - .long __lll_mutex_lock_wait-.Lmwait3b -.Lmwake3: - .long __lll_mutex_unlock_wake-.Lmwake3b -.Lmwake4: - .long __lll_mutex_unlock_wake-.Lmwake4b + .long __lll_unlock_wake-.Lmwait3b +.Lmwait4: + .long __lll_unlock_wake-.Lmwait4b .size __pthread_cond_timedwait, .-__pthread_cond_timedwait weak_alias (__pthread_cond_timedwait, pthread_cond_timedwait) @@ -505,10 +568,17 @@ __condvar_tw_cleanup: #if cond_lock != 0 add #cond_lock, r5 #endif - mov.l .Lmwait5, r1 + mov.l @(dep_mutex,r8), r0 + cmp/eq #-1, r0 + bf/s 99f + mov #LLL_PRIVATE, r6 + mov #LLL_SHARED, r6 +99: + extu.b r6, r6 + mov.l .Lwait5, r1 bsrf r1 mov r2, r4 -.Lmwait5b: +.Lwait5b: 1: mov.l @(broadcast_seq,r8), r0 @@ -519,6 +589,21 @@ __condvar_tw_cleanup: mov #1, r2 mov #0, r3 + /* We increment the wakeup_seq counter only if it is lower than + total_seq. If this is not the case the thread was woken and + then canceled. In this case we ignore the signal. */ + mov.l @(total_seq+4,r8), r0 + mov.l @(wakeup_seq+4,r8), r1 + cmp/hi r1, r0 + bt/s 6f + cmp/hi r0, r1 + bt 7f + mov.l @(total_seq,r8), r0 + mov.l @(wakeup_seq,r8), r1 + cmp/hs r0, r1 + bt 7f + +6: clrt mov.l @(wakeup_seq,r8),r0 mov.l @(wakeup_seq+4,r8),r1 @@ -530,6 +615,7 @@ __condvar_tw_cleanup: add r2, r0 mov.l r0,@(cond_futex,r8) +7: clrt mov.l @(woken_seq,r8),r0 mov.l @(woken_seq+4,r8),r1 @@ -539,7 +625,7 @@ __condvar_tw_cleanup: mov.l r1,@(woken_seq+4,r8) 3: - mov #(1 << clock_bits), r2 + mov #(1 << nwaiters_shift), r2 mov.l @(cond_nwaiters,r8),r0 sub r2, r0 mov.l r0,@(cond_nwaiters,r8) @@ -552,7 +638,7 @@ __condvar_tw_cleanup: not r0, r0 cmp/eq #0, r0 bf/s 4f - mov #((1 << clock_bits) - 1), r1 + mov #((1 << nwaiters_shift) - 1), r1 not r1, r1 mov.l @(cond_nwaiters,r8),r0 tst r1, r0 @@ -582,10 +668,16 @@ __condvar_tw_cleanup: #if cond_lock != 0 add #cond_lock, r4 #endif - mov.l .Lmwake5, r1 + mov.l @(dep_mutex,r8), r0 + cmp/eq #-1, r0 + bf/s 99f + mov #LLL_PRIVATE, r5 + mov #LLL_SHARED, r5 +99: + mov.l .Lmwait5, r1 bsrf r1 - nop -.Lmwake5b: + extu.b r5, r5 +.Lmwait5b: 2: /* Wake up all waiters to make sure no signal gets lost. */ @@ -618,10 +710,10 @@ __condvar_tw_cleanup: sleep .align 2 +.Lwait5: + .long __lll_lock_wait-.Lwait5b .Lmwait5: - .long __lll_mutex_lock_wait-.Lmwait5b -.Lmwake5: - .long __lll_mutex_unlock_wake-.Lmwake5b + .long __lll_unlock_wake-.Lmwait5b .Lmlocki5: .long __pthread_mutex_cond_lock-.Lmlocki5b .Lresume: |