linux/arch/alpha/include/asm/spinlock.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2#ifndef _ALPHA_SPINLOCK_H
   3#define _ALPHA_SPINLOCK_H
   4
   5#include <linux/kernel.h>
   6#include <asm/current.h>
   7#include <asm/barrier.h>
   8#include <asm/processor.h>
   9
  10/*
  11 * Simple spin lock operations.  There are two variants, one clears IRQ's
  12 * on the local processor, one does not.
  13 *
  14 * We make no fairness assumptions. They have a cost.
  15 */
  16
  17#define arch_spin_is_locked(x)  ((x)->lock != 0)
  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 void arch_read_lock(arch_rwlock_t *lock)
  58{
  59        long regx;
  60
  61        __asm__ __volatile__(
  62        "1:     ldl_l   %1,%0\n"
  63        "       blbs    %1,6f\n"
  64        "       subl    %1,2,%1\n"
  65        "       stl_c   %1,%0\n"
  66        "       beq     %1,6f\n"
  67        "       mb\n"
  68        ".subsection 2\n"
  69        "6:     ldl     %1,%0\n"
  70        "       blbs    %1,6b\n"
  71        "       br      1b\n"
  72        ".previous"
  73        : "=m" (*lock), "=&r" (regx)
  74        : "m" (*lock) : "memory");
  75}
  76
  77static inline void arch_write_lock(arch_rwlock_t *lock)
  78{
  79        long regx;
  80
  81        __asm__ __volatile__(
  82        "1:     ldl_l   %1,%0\n"
  83        "       bne     %1,6f\n"
  84        "       lda     %1,1\n"
  85        "       stl_c   %1,%0\n"
  86        "       beq     %1,6f\n"
  87        "       mb\n"
  88        ".subsection 2\n"
  89        "6:     ldl     %1,%0\n"
  90        "       bne     %1,6b\n"
  91        "       br      1b\n"
  92        ".previous"
  93        : "=m" (*lock), "=&r" (regx)
  94        : "m" (*lock) : "memory");
  95}
  96
  97static inline int arch_read_trylock(arch_rwlock_t * lock)
  98{
  99        long regx;
 100        int success;
 101
 102        __asm__ __volatile__(
 103        "1:     ldl_l   %1,%0\n"
 104        "       lda     %2,0\n"
 105        "       blbs    %1,2f\n"
 106        "       subl    %1,2,%2\n"
 107        "       stl_c   %2,%0\n"
 108        "       beq     %2,6f\n"
 109        "2:     mb\n"
 110        ".subsection 2\n"
 111        "6:     br      1b\n"
 112        ".previous"
 113        : "=m" (*lock), "=&r" (regx), "=&r" (success)
 114        : "m" (*lock) : "memory");
 115
 116        return success;
 117}
 118
 119static inline int arch_write_trylock(arch_rwlock_t * lock)
 120{
 121        long regx;
 122        int success;
 123
 124        __asm__ __volatile__(
 125        "1:     ldl_l   %1,%0\n"
 126        "       lda     %2,0\n"
 127        "       bne     %1,2f\n"
 128        "       lda     %2,1\n"
 129        "       stl_c   %2,%0\n"
 130        "       beq     %2,6f\n"
 131        "2:     mb\n"
 132        ".subsection 2\n"
 133        "6:     br      1b\n"
 134        ".previous"
 135        : "=m" (*lock), "=&r" (regx), "=&r" (success)
 136        : "m" (*lock) : "memory");
 137
 138        return success;
 139}
 140
 141static inline void arch_read_unlock(arch_rwlock_t * lock)
 142{
 143        long regx;
 144        __asm__ __volatile__(
 145        "       mb\n"
 146        "1:     ldl_l   %1,%0\n"
 147        "       addl    %1,2,%1\n"
 148        "       stl_c   %1,%0\n"
 149        "       beq     %1,6f\n"
 150        ".subsection 2\n"
 151        "6:     br      1b\n"
 152        ".previous"
 153        : "=m" (*lock), "=&r" (regx)
 154        : "m" (*lock) : "memory");
 155}
 156
 157static inline void arch_write_unlock(arch_rwlock_t * lock)
 158{
 159        mb();
 160        lock->lock = 0;
 161}
 162
 163#endif /* _ALPHA_SPINLOCK_H */
 164