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

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

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

  1 #ifdef __KERNEL__
  2 #ifndef _PPC_SEMAPHORE_HELPER_H
  3 #define _PPC_SEMAPHORE_HELPER_H
  4 
  5 /*
  6  * SMP- and interrupt-safe semaphores..
  7  *
  8  * (C) Copyright 1996 Linus Torvalds
  9  * Adapted for PowerPC by Gary Thomas and Paul Mackerras
 10  */
 11 
 12 #include <asm/atomic.h>
 13 
 14 /*
 15  * These two (wake_one_more and waking_non_zero) _must_ execute
 16  * atomically wrt each other.
 17  *
 18  * This is trivially done with load with reservation and
 19  * store conditional on the ppc.
 20  */
 21 
 22 static inline void wake_one_more(struct semaphore * sem)
 23 {
 24         atomic_inc(&sem->waking);
 25 }
 26 
 27 static inline int waking_non_zero(struct semaphore *sem)
 28 {
 29         int ret, tmp;
 30 
 31         /* Atomic decrement sem->waking iff it is > 0 */
 32         __asm__ __volatile__(
 33                 "1:     lwarx %1,0,%2\n"        /* tmp = sem->waking */
 34                 "       cmpwi 0,%1,0\n"         /* test tmp */
 35                 "       addic %1,%1,-1\n"       /* --tmp */
 36                 "       ble- 2f\n"              /* exit if tmp was <= 0 */
 37                 "       stwcx. %1,0,%2\n"       /* update sem->waking */
 38                 "       bne- 1b\n"              /* try again if update failed*/
 39                 "       li %0,1\n"              /* ret = 1 */
 40                 "2:"
 41                 : "=r" (ret), "=&r" (tmp)
 42                 : "r" (&sem->waking), "" (0)
 43                 : "cr0", "memory");
 44 
 45         return ret;
 46 }
 47 /*
 48  * waking_non_zero_interruptible:
 49  *      1       got the lock
 50  *      0       go to sleep
 51  *      -EINTR  interrupted
 52  */
 53 static inline int waking_non_zero_interruptible(struct semaphore *sem,
 54                                                 struct task_struct *tsk)
 55 {
 56         int ret, tmp;
 57 
 58         /* Atomic decrement sem->waking iff it is > 0 */
 59         __asm__ __volatile__(
 60                 "1:     lwarx %1,0,%2\n"        /* tmp = sem->waking */
 61                 "       cmpwi 0,%1,0\n"         /* test tmp */
 62                 "       addic %1,%1,-1\n"       /* --tmp */
 63                 "       ble- 2f\n"              /* exit if tmp was <= 0 */
 64                 "       stwcx. %1,0,%2\n"       /* update sem->waking */
 65                 "       bne- 1b\n"              /* try again if update failed*/
 66                 "       li %0,1\n"              /* ret = 1 */
 67                 "2:"
 68                 : "=r" (ret), "=&r" (tmp)
 69                 : "r" (&sem->waking), "" (0)
 70                 : "cr0", "memory");
 71 
 72         if (ret == 0 && signal_pending(tsk)) {
 73                 atomic_inc(&sem->count);
 74                 ret = -EINTR;
 75         }
 76         return ret;
 77 }
 78 
 79 /*
 80  * waking_non_zero_trylock:
 81  *      1       failed to lock
 82  *      0       got the lock
 83  */
 84 static inline int waking_non_zero_trylock(struct semaphore *sem)
 85 {
 86         int ret, tmp;
 87 
 88         /* Atomic decrement sem->waking iff it is > 0 */
 89         __asm__ __volatile__(
 90                 "1:     lwarx %1,0,%2\n"        /* tmp = sem->waking */
 91                 "       cmpwi 0,%1,0\n"         /* test tmp */
 92                 "       addic %1,%1,-1\n"       /* --tmp */
 93                 "       ble- 2f\n"              /* exit if tmp was <= 0 */
 94                 "       stwcx. %1,0,%2\n"       /* update sem->waking */
 95                 "       bne- 1b\n"              /* try again if update failed*/
 96                 "       li %0,0\n"              /* ret = 0 */
 97                 "2:"
 98                 : "=r" (ret), "=&r" (tmp)
 99                 : "r" (&sem->waking), "" (1)
100                 : "cr0", "memory");
101 
102         if (ret)
103                 atomic_inc(&sem->count);
104 
105         return ret;
106 }
107 
108 #endif /* _PPC_SEMAPHORE_HELPER_H */
109 #endif /* __KERNEL__ */
110 

~ [ 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.