From c68d0fa2d88fc2134a38d99e7e944828384a7671 Mon Sep 17 00:00:00 2001 From: Austin Foxley Date: Sat, 17 Oct 2009 12:26:24 -0700 Subject: libpthread/nptl: core of the "Native Posix Threading Library" for uClibc targetting arm,sh,i386,mips,sparc for now Signed-off-by: Austin Foxley --- .../sysv/linux/sh/pthread_rwlock_timedwrlock.S | 265 +++++++++++++++++++++ 1 file changed, 265 insertions(+) create mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S (limited to 'libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S') diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S new file mode 100644 index 000000000..6284140a6 --- /dev/null +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S @@ -0,0 +1,265 @@ +/* Copyright (C) 2003 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 +#include +#include +#include +#include "lowlevel-atomic.h" + +#define SYS_gettimeofday __NR_gettimeofday +#define FUTEX_WAIT 0 +#define FUTEX_WAKE 1 + + + .text + + .globl pthread_rwlock_timedwrlock + .type pthread_rwlock_timedwrlock,@function + .align 5 +pthread_rwlock_timedwrlock: + mov.l r12, @-r15 + mov.l r10, @-r15 + mov.l r9, @-r15 + mov.l r8, @-r15 + sts.l pr, @-r15 + add #-8, r15 + mov r4, r8 + mov r5, r9 + + /* Get the lock. */ + mov #0, r3 + mov #1, r4 +#if MUTEX == 0 + CMPXCHG (r3, @r8, r4, r2) +#else + CMPXCHG (r3, @(MUTEX,r8), r4, r2) +#endif + bf 1f +2: + mov.l @(WRITER,r8), r0 + tst r0, r0 + bf 14f + mov.l @(NR_READERS,r8), r0 + tst r0, r0 + bt 5f +3: + /* Check the value of the timeout parameter. */ + mov.l .L1g1, r1 + mov.l @(4,r9), r0 + cmp/hs r1, r0 + bt 19f + + mov.l @(WRITERS_QUEUED,r8), r0 + add #1, r0 + mov.l r0, @(WRITERS_QUEUED,r8) + tst r0, r0 + bt 4f + + mov.l @(WRITERS_WAKEUP,r8), r10 + +#if MUTEX == 0 + DEC (@r8, r2) +#else + DEC (@(MUTEX,r8), r2) +#endif + tst r2, r2 + bf 10f + +11: + /* Get current time. */ + mov r15, r4 + mov #0, r5 + mov #SYS_gettimeofday, r3 + trapa #0x12 + SYSCALL_INST_PAD + + mov.l @(4,r15), r0 + mov.w .L1k1, r1 + dmulu.l r0, r1 /* Milli 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 15f + mov.l .L1g1, r1 + add r1, r3 + add #-1, r2 +15: + cmp/pz r2 + bf 16f /* Time is already up. */ + + /* Store relative timeout. */ + mov.l r2, @r15 + mov.l r3, @(4,r15) + + /* Futex call. */ + mov r15, r7 + mov #FUTEX_WAIT, r5 + mov r10, r6 + mov r8, r4 + add #WRITERS_WAKEUP, r4 + mov #SYS_futex, r3 + extu.b r3, r3 + trapa #0x14 + SYSCALL_INST_PAD + mov r0, r3 + +17: + /* Reget the lock. */ + mov #0, r5 + mov #1, r4 +#if MUTEX == 0 + CMPXCHG (r5, @r8, r4, r2) +#else + CMPXCHG (r5, @(MUTEX,r8), r4, r2) +#endif + bf 12f + +13: + mov.l @(WRITERS_QUEUED,r8), r0 + add #-1, r0 + mov.l r0, @(WRITERS_QUEUED,r8) + mov #-ETIMEDOUT, r0 + cmp/eq r0, r3 + bf 2b + +18: + bra 9f + mov #ETIMEDOUT, r3 + +19: + bra 9f + mov #EINVAL, r3 + +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 + DEC (@r8, r2) +#else + DEC (@(MUTEX,r8), r2) +#endif + tst r2, r2 + bf 6f +7: + add #8,r15 + lds.l @r15+, pr + mov.l @r15+, r8 + mov.l @r15+, r9 + mov.l @r15+, r10 + mov.l @r15+, r12 + rts + mov r3, r0 + +.L1k1: + .word 1000 + .align 2 +.L1g1: + .long 1000000000 + +1: + mov r8, r5 +#if MUTEX != 0 + add #MUTEX, r5 +#endif + mov r2, r4 + mov.l .Lwait6, r1 + bsrf r1 + nop +.Lwait6b: + bra 2b + nop +14: + stc gbr, r1 + mov.w .Ltidoff, r2 + add r2, r1 + mov.l @r1, r1 + cmp/eq r1, r0 + bf 3b + bra 9b + mov #EDEADLK, r3 +6: + mov r8, r4 +#if MUTEX != 0 + add #MUTEX, r4 +#endif + mov.l .Lwake6, r1 + bsrf r1 + nop +.Lwake6b: + bra 7b + mov #0, r3 + +.Ltidoff: + .word TID - TLS_PRE_TCB_SIZE + +4: + /* Overflow. */ + mov.l @(WRITERS_QUEUED,r8), r1 + add #-1, r1 + mov.l r1, @(WRITERS_QUEUED,r8) + bra 9b + mov #EAGAIN, r3 + +10: + mov r8, r4 +#if MUTEX != 0 + add #MUTEX, r4 +#endif + mov.l .Lwake7, r1 + bsrf r1 + nop +.Lwake7b: + bra 11b + nop + +12: + mov r8, r5 +#if MUTEX != 0 + add #MUTEX, r5 +#endif + mov r2, r4 + mov.l .Lwait7, r1 + bsrf r1 + nop +.Lwait7b: + bra 13b + nop + +16: + bra 17b + mov #-ETIMEDOUT, r3 + + .align 2 +.Lwait6: + .long __lll_mutex_lock_wait-.Lwait6b +.Lwake6: + .long __lll_mutex_unlock_wake-.Lwake6b +.Lwait7: + .long __lll_mutex_lock_wait-.Lwait7b +.Lwake7: + .long __lll_mutex_unlock_wake-.Lwake7b + .size pthread_rwlock_timedwrlock,.-pthread_rwlock_timedwrlock -- cgit v1.2.3