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

TOMOYO Linux Cross Reference
Linux/include/asm-sparc64/spinlock.h

Version: ~ [ linux-5.10-rc1 ] ~ [ linux-5.9.1 ] ~ [ linux-5.8.16 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.72 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.152 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.202 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.240 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.240 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.85 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /* spinlock.h: 64-bit Sparc spinlock support.
  2  *
  3  * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
  4  */
  5 
  6 #ifndef __SPARC64_SPINLOCK_H
  7 #define __SPARC64_SPINLOCK_H
  8 
  9 #include <linux/config.h>
 10 
 11 #ifndef __ASSEMBLY__
 12 
 13 /* To get debugging spinlocks which detect and catch
 14  * deadlock situations, set CONFIG_DEBUG_SPINLOCK
 15  * and rebuild your kernel.
 16  */
 17 
 18 /* All of these locking primitives are expected to work properly
 19  * even in an RMO memory model, which currently is what the kernel
 20  * runs in.
 21  *
 22  * There is another issue.  Because we play games to save cycles
 23  * in the non-contention case, we need to be extra careful about
 24  * branch targets into the "spinning" code.  They live in their
 25  * own section, but the newer V9 branches have a shorter range
 26  * than the traditional 32-bit sparc branch variants.  The rule
 27  * is that the branches that go into and out of the spinner sections
 28  * must be pre-V9 branches.
 29  */
 30 
 31 #ifndef CONFIG_DEBUG_SPINLOCK
 32 
 33 typedef unsigned char spinlock_t;
 34 #define SPIN_LOCK_UNLOCKED      0
 35 
 36 #define spin_lock_init(lock)    (*((unsigned char *)(lock)) = 0)
 37 #define spin_is_locked(lock)    (*((volatile unsigned char *)(lock)) != 0)
 38 
 39 #define spin_unlock_wait(lock)  \
 40 do {    membar("#LoadLoad");    \
 41 } while(*((volatile unsigned char *)lock))
 42 
 43 static __inline__ void _raw_spin_lock(spinlock_t *lock)
 44 {
 45         __asm__ __volatile__(
 46 "1:     ldstub          [%0], %%g7\n"
 47 "       brnz,pn         %%g7, 2f\n"
 48 "        membar         #StoreLoad | #StoreStore\n"
 49 "       .subsection     2\n"
 50 "2:     ldub            [%0], %%g7\n"
 51 "       brnz,pt         %%g7, 2b\n"
 52 "        membar         #LoadLoad\n"
 53 "       b,a,pt          %%xcc, 1b\n"
 54 "       .previous\n"
 55         : /* no outputs */
 56         : "r" (lock)
 57         : "g7", "memory");
 58 }
 59 
 60 static __inline__ int _raw_spin_trylock(spinlock_t *lock)
 61 {
 62         unsigned int result;
 63         __asm__ __volatile__("ldstub [%1], %0\n\t"
 64                              "membar #StoreLoad | #StoreStore"
 65                              : "=r" (result)
 66                              : "r" (lock)
 67                              : "memory");
 68         return (result == 0);
 69 }
 70 
 71 static __inline__ void _raw_spin_unlock(spinlock_t *lock)
 72 {
 73         __asm__ __volatile__("membar    #StoreStore | #LoadStore\n\t"
 74                              "stb       %%g0, [%0]"
 75                              : /* No outputs */
 76                              : "r" (lock)
 77                              : "memory");
 78 }
 79 
 80 #else /* !(CONFIG_DEBUG_SPINLOCK) */
 81 
 82 typedef struct {
 83         unsigned char lock;
 84         unsigned int owner_pc, owner_cpu;
 85 } spinlock_t;
 86 #define SPIN_LOCK_UNLOCKED (spinlock_t) { 0, 0, 0xff }
 87 #define spin_lock_init(__lock)  \
 88 do {    (__lock)->lock = 0; \
 89         (__lock)->owner_pc = 0; \
 90         (__lock)->owner_cpu = 0xff; \
 91 } while(0)
 92 #define spin_is_locked(__lock)  (*((volatile unsigned char *)(&((__lock)->lock))) != 0)
 93 #define spin_unlock_wait(__lock)        \
 94 do { \
 95         membar("#LoadLoad"); \
 96 } while(*((volatile unsigned char *)(&((__lock)->lock))))
 97 
 98 extern void _do_spin_lock (spinlock_t *lock, char *str);
 99 extern void _do_spin_unlock (spinlock_t *lock);
100 extern int _spin_trylock (spinlock_t *lock);
101 
102 #define _raw_spin_trylock(lp)   _spin_trylock(lp)
103 #define _raw_spin_lock(lock)    _do_spin_lock(lock, "spin_lock")
104 #define _raw_spin_unlock(lock)  _do_spin_unlock(lock)
105 
106 #endif /* CONFIG_DEBUG_SPINLOCK */
107 
108 /* Multi-reader locks, these are much saner than the 32-bit Sparc ones... */
109 
110 #ifndef CONFIG_DEBUG_SPINLOCK
111 
112 typedef unsigned int rwlock_t;
113 #define RW_LOCK_UNLOCKED        0
114 #define rwlock_init(lp) do { *(lp) = RW_LOCK_UNLOCKED; } while(0)
115 #define rwlock_is_locked(x) (*(x) != RW_LOCK_UNLOCKED)
116 
117 extern void __read_lock(rwlock_t *);
118 extern void __read_unlock(rwlock_t *);
119 extern void __write_lock(rwlock_t *);
120 extern void __write_unlock(rwlock_t *);
121 extern int __write_trylock(rwlock_t *);
122 
123 #define _raw_read_lock(p)       __read_lock(p)
124 #define _raw_read_unlock(p)     __read_unlock(p)
125 #define _raw_write_lock(p)      __write_lock(p)
126 #define _raw_write_unlock(p)    __write_unlock(p)
127 #define _raw_write_trylock(p)   __write_trylock(p)
128 
129 #else /* !(CONFIG_DEBUG_SPINLOCK) */
130 
131 typedef struct {
132         unsigned long lock;
133         unsigned int writer_pc, writer_cpu;
134         unsigned int reader_pc[4];
135 } rwlock_t;
136 #define RW_LOCK_UNLOCKED        (rwlock_t) { 0, 0, 0xff, { 0, 0, 0, 0 } }
137 #define rwlock_init(lp) do { *(lp) = RW_LOCK_UNLOCKED; } while(0)
138 #define rwlock_is_locked(x) ((x)->lock != 0)
139 
140 extern void _do_read_lock(rwlock_t *rw, char *str);
141 extern void _do_read_unlock(rwlock_t *rw, char *str);
142 extern void _do_write_lock(rwlock_t *rw, char *str);
143 extern void _do_write_unlock(rwlock_t *rw);
144 
145 #define _raw_read_lock(lock) \
146 do {    unsigned long flags; \
147         local_irq_save(flags); \
148         _do_read_lock(lock, "read_lock"); \
149         local_irq_restore(flags); \
150 } while(0)
151 
152 #define _raw_read_unlock(lock) \
153 do {    unsigned long flags; \
154         local_irq_save(flags); \
155         _do_read_unlock(lock, "read_unlock"); \
156         local_irq_restore(flags); \
157 } while(0)
158 
159 #define _raw_write_lock(lock) \
160 do {    unsigned long flags; \
161         local_irq_save(flags); \
162         _do_write_lock(lock, "write_lock"); \
163         local_irq_restore(flags); \
164 } while(0)
165 
166 #define _raw_write_unlock(lock) \
167 do {    unsigned long flags; \
168         local_irq_save(flags); \
169         _do_write_unlock(lock); \
170         local_irq_restore(flags); \
171 } while(0)
172 
173 #endif /* CONFIG_DEBUG_SPINLOCK */
174 
175 #endif /* !(__ASSEMBLY__) */
176 
177 #endif /* !(__SPARC64_SPINLOCK_H) */
178 

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

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp