linux/arch/alpha/include/asm/spinlock.h
<<
>>
Prefs
   1#ifndef _ALPHA_SPINLOCK_H
   2#define _ALPHA_SPINLOCK_H
   3
   4#include <linux/kernel.h>
   5#include <asm/current.h>
   6
   7/*
   8 * Simple spin lock operations.  There are two variants, one clears IRQ's
   9 * on the local processor, one does not.
  10 *
  11 * We make no fairness assumptions. They have a cost.
  12 */
  13
  14#define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock)
  15#define arch_spin_is_locked(x)  ((x)->lock != 0)
  16#define arch_spin_unlock_wait(x) \
  17                do { cpu_relax(); } while ((x)->lock)
  18
  19static inline int arch_spin_value_unlocked(arch_spinlock_t lock)
  20{
  21        return lock.lock == 0;
  22}
  23
  24static inline void arch_spin_unlock(arch_spinlock_t * lock)
  25{
  26        mb();
  27        lock->lock = 0;
  28}
  29
  30static inline void arch_spin_lock(arch_spinlock_t * lock)
  31{
  32        long tmp;
  33
  34        __asm__ __volatile__(
  35        "1:     ldl_l   %0,%1\n"
  36        "       bne     %0,2f\n"
  37        "       lda     %0,1\n"
  38        "       stl_c   %0,%1\n"
  39        "       beq     %0,2f\n"
  40        "       mb\n"
  41        ".subsection 2\n"
  42        "2:     ldl     %0,%1\n"
  43        "       bne     %0,2b\n"
  44        "       br      1b\n"
  45        ".previous"
  46        : "=&r" (tmp), "=m" (lock->lock)
  47        : "m"(lock->lock) : "memory");
  48}
  49
  50static inline int arch_spin_trylock(arch_spinlock_t *lock)
  51{
  52        return !test_and_set_bit(0, &lock->lock);
  53}
  54
  55/***********************************************************/
  56
  57static inline int arch_read_can_lock(arch_rwlock_t *lock)
  58{
  59        return (lock->lock & 1) == 0;
  60}
  61
  62static inline int arch_write_can_lock(arch_rwlock_t *lock)
  63{
  64        return lock->lock == 0;
  65}
  66
  67static inline void arch_read_lock(arch_rwlock_t *lock)
  68{
  69        long regx;
  70
  71        __asm__ __volatile__(
  72        "1:     ldl_l   %1,%0\n"
  73        "       blbs    %1,6f\n"
  74        "       subl    %1,2,%1\n"
  75        "       stl_c   %1,%0\n"
  76        "       beq     %1,6f\n"
  77        "       mb\n"
  78        ".subsection 2\n"
  79        "6:     ldl     %1,%0\n"
  80        "       blbs    %1,6b\n"
  81        "       br      1b\n"
  82        ".previous"
  83        : "=m" (*lock), "=&r" (regx)
  84        : "m" (*lock) : "memory");
  85}
  86
  87static inline void arch_write_lock(arch_rwlock_t *lock)
  88{
  89        long regx;
  90
  91        __asm__ __volatile__(
  92        "1:     ldl_l   %1,%0\n"
  93        "       bne     %1,6f\n"
  94        "       lda     %1,1\n"
  95        "       stl_c   %1,%0\n"
  96        "       beq     %1,6f\n"
  97        "       mb\n"
  98        ".subsection 2\n"
  99        "6:     ldl     %1,%0\n"
 100        "       bne     %1,6b\n"
 101        "       br      1b\n"
 102        ".previous"
 103        : "=m" (*lock), "=&r" (regx)
 104        : "m" (*lock) : "memory");
 105}
 106
 107static inline int arch_read_trylock(arch_rwlock_t * lock)
 108{
 109        long regx;
 110        int success;
 111
 112        __asm__ __volatile__(
 113        "1:     ldl_l   %1,%0\n"
 114        "       lda     %2,0\n"
 115        "       blbs    %1,2f\n"
 116        "       subl    %1,2,%2\n"
 117        "       stl_c   %2,%0\n"
 118        "       beq     %2,6f\n"
 119        "2:     mb\n"
 120        ".subsection 2\n"
 121        "6:     br      1b\n"
 122        ".previous"
 123        : "=m" (*lock), "=&r" (regx), "=&r" (success)
 124        : "m" (*lock) : "memory");
 125
 126        return success;
 127}
 128
 129static inline int arch_write_trylock(arch_rwlock_t * lock)
 130{
 131        long regx;
 132        int success;
 133
 134        __asm__ __volatile__(
 135        "1:     ldl_l   %1,%0\n"
 136        "       lda     %2,0\n"
 137        "       bne     %1,2f\n"
 138        "       lda     %2,1\n"
 139        "       stl_c   %2,%0\n"
 140        "       beq     %2,6f\n"
 141        "2:     mb\n"
 142        ".subsection 2\n"
 143        "6:     br      1b\n"
 144        ".previous"
 145        : "=m" (*lock), "=&r" (regx), "=&r" (success)
 146        : "m" (*lock) : "memory");
 147
 148        return success;
 149}
 150
 151static inline void arch_read_unlock(arch_rwlock_t * lock)
 152{
 153        long regx;
 154        __asm__ __volatile__(
 155        "       mb\n"
 156        "1:     ldl_l   %1,%0\n"
 157        "       addl    %1,2,%1\n"
 158        "       stl_c   %1,%0\n"
 159        "       beq     %1,6f\n"
 160        ".subsection 2\n"
 161        "6:     br      1b\n"
 162        ".previous"
 163        : "=m" (*lock), "=&r" (regx)
 164        : "m" (*lock) : "memory");
 165}
 166
 167static inline void arch_write_unlock(arch_rwlock_t * lock)
 168{
 169        mb();
 170        lock->lock = 0;
 171}
 172
 173#define arch_read_lock_flags(lock, flags) arch_read_lock(lock)
 174#define arch_write_lock_flags(lock, flags) arch_write_lock(lock)
 175
 176#endif /* _ALPHA_SPINLOCK_H */
 177