~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/include/asm-mips64/semaphore-helper.h

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * SMP- and interrupt-safe semaphores helper functions.
  3  *
  4  * (C) Copyright 1996 Linus Torvalds
  5  * (C) Copyright 1999 Andrea Arcangeli
  6  * (C) Copyright 1999 Ralf Baechle
  7  * (C) Copyright 1999 Silicon Graphics, Inc.
  8  */
  9 #ifndef _ASM_SEMAPHORE_HELPER_H
 10 #define _ASM_SEMAPHORE_HELPER_H
 11 
 12 /*
 13  * These two _must_ execute atomically wrt each other.
 14  */
 15 static inline void wake_one_more(struct semaphore * sem)
 16 {
 17         atomic_inc(&sem->waking);
 18 }
 19 
 20 static inline int
 21 waking_non_zero(struct semaphore *sem)
 22 {
 23         int ret, tmp;
 24 
 25         __asm__ __volatile__(
 26         "1:\tll\t%1, %2\n\t"
 27         "blez\t%1, 2f\n\t"
 28         "subu\t%0, %1, 1\n\t"
 29         "sc\t%0, %2\n\t"
 30         "beqz\t%0, 1b\n\t"
 31         "2:"
 32         ".text"
 33         : "=r" (ret), "=r" (tmp), "=m" (sem->waking)
 34         : "" (0));
 35 
 36         return ret;
 37 }
 38 
 39 /*
 40  * waking_non_zero_interruptible:
 41  *      1       got the lock
 42  *      0       go to sleep
 43  *      -EINTR  interrupted
 44  *
 45  * We must undo the sem->count down_interruptible decrement
 46  * simultaneously and atomicly with the sem->waking adjustment,
 47  * otherwise we can race with wake_one_more.
 48  *
 49  * This is accomplished by doing a 64-bit ll/sc on the 2 32-bit words.
 50  *
 51  * Pseudocode:
 52  *
 53  * If(sem->waking > 0) {
 54  *      Decrement(sem->waking)
 55  *      Return(SUCCESS)
 56  * } else If(segnal_pending(tsk)) {
 57  *      Increment(sem->count)
 58  *      Return(-EINTR)
 59  * } else {
 60  *      Return(SLEEP)
 61  * }
 62  */
 63 
 64 static inline int
 65 waking_non_zero_interruptible(struct semaphore *sem, struct task_struct *tsk)
 66 {
 67         long ret, tmp;
 68 
 69 #ifdef __MIPSEB__
 70 
 71         __asm__ __volatile__("
 72         .set    push
 73         .set    noat
 74 0:      lld     %1, %2
 75         li      %0, 0
 76         sll     $1, %1, 0
 77         blez    $1, 1f
 78         daddiu  %1, %1, -1
 79         li      %0, 1
 80         b       2f
 81 1:
 82         beqz    %3, 2f
 83         li      %0, %4
 84         dli     $1, 0x0000000100000000
 85         daddu   %1, %1, $1
 86 2:
 87         scd     %1, %2
 88         beqz    %1, 0b
 89         .set    pop"
 90         : "=&r" (ret), "=&r" (tmp), "=m" (*sem)
 91         : "r" (signal_pending(tsk)), "i" (-EINTR));
 92 
 93 #elif defined(__MIPSEL__)
 94 
 95         __asm__ __volatile__("
 96         .set    push
 97         .set    noat
 98 0:
 99         lld     %1, %2
100         li      %0, 0
101         blez    %1, 1f
102         dli     $1, 0x0000000100000000
103         dsubu   %1, %1, $1
104         li      %0, 1
105         b       2f
106 1:
107         beqz    %3, 2f
108         li      %0, %4
109         /* 
110          * It would be nice to assume that sem->count
111          * is != -1, but we will guard against that case
112          */
113         daddiu  $1, %1, 1
114         dsll32  $1, $1, 0
115         dsrl32  $1, $1, 0
116         dsrl32  %1, %1, 0
117         dsll32  %1, %1, 0
118         or      %1, %1, $1
119 2:
120         scd     %1, %2
121         beqz    %1, 0b
122         .set    pop"
123         : "=&r" (ret), "=&r" (tmp), "=m" (*sem)
124         : "r" (signal_pending(tsk)), "i" (-EINTR));
125 
126 #else
127 #error "MIPS but neither __MIPSEL__ nor __MIPSEB__?"
128 #endif
129 
130         return ret;
131 }
132 
133 /*
134  * waking_non_zero_trylock is unused.  we do everything in 
135  * down_trylock and let non-ll/sc hosts bounce around.
136  */
137 
138 static inline int
139 waking_non_zero_trylock(struct semaphore *sem)
140 {
141 #if WAITQUEUE_DEBUG
142         CHECK_MAGIC(sem->__magic);
143 #endif
144 
145         return 0;
146 }
147 
148 #endif /* _ASM_SEMAPHORE_HELPER_H */
149 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.