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

TOMOYO Linux Cross Reference
Linux/arch/sparc/include/asm/spinlock_64.h

Version: ~ [ linux-5.6 ] ~ [ linux-5.5.13 ] ~ [ linux-5.4.28 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.113 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.174 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.217 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.217 ] ~ [ 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.82 ] ~ [ 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-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ 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 #ifndef __ASSEMBLY__
 10 
 11 #include <asm/processor.h>
 12 #include <asm/barrier.h>
 13 
 14 /* To get debugging spinlocks which detect and catch
 15  * deadlock situations, set CONFIG_DEBUG_SPINLOCK
 16  * and rebuild your kernel.
 17  */
 18 
 19 /* Because we play games to save cycles in the non-contention case, we
 20  * need to be extra careful about branch targets into the "spinning"
 21  * code.  They live in their own section, but the newer V9 branches
 22  * have a shorter range than the traditional 32-bit sparc branch
 23  * variants.  The rule is that the branches that go into and out of
 24  * the spinner sections must be pre-V9 branches.
 25  */
 26 
 27 #define arch_spin_is_locked(lp) ((lp)->lock != 0)
 28 
 29 static inline void arch_spin_unlock_wait(arch_spinlock_t *lock)
 30 {
 31         smp_cond_load_acquire(&lock->lock, !VAL);
 32 }
 33 
 34 static inline void arch_spin_lock(arch_spinlock_t *lock)
 35 {
 36         unsigned long tmp;
 37 
 38         __asm__ __volatile__(
 39 "1:     ldstub          [%1], %0\n"
 40 "       brnz,pn         %0, 2f\n"
 41 "        nop\n"
 42 "       .subsection     2\n"
 43 "2:     ldub            [%1], %0\n"
 44 "       brnz,pt         %0, 2b\n"
 45 "        nop\n"
 46 "       ba,a,pt         %%xcc, 1b\n"
 47 "       .previous"
 48         : "=&r" (tmp)
 49         : "r" (lock)
 50         : "memory");
 51 }
 52 
 53 static inline int arch_spin_trylock(arch_spinlock_t *lock)
 54 {
 55         unsigned long result;
 56 
 57         __asm__ __volatile__(
 58 "       ldstub          [%1], %0\n"
 59         : "=r" (result)
 60         : "r" (lock)
 61         : "memory");
 62 
 63         return (result == 0UL);
 64 }
 65 
 66 static inline void arch_spin_unlock(arch_spinlock_t *lock)
 67 {
 68         __asm__ __volatile__(
 69 "       stb             %%g0, [%0]"
 70         : /* No outputs */
 71         : "r" (lock)
 72         : "memory");
 73 }
 74 
 75 static inline void arch_spin_lock_flags(arch_spinlock_t *lock, unsigned long flags)
 76 {
 77         unsigned long tmp1, tmp2;
 78 
 79         __asm__ __volatile__(
 80 "1:     ldstub          [%2], %0\n"
 81 "       brnz,pn         %0, 2f\n"
 82 "        nop\n"
 83 "       .subsection     2\n"
 84 "2:     rdpr            %%pil, %1\n"
 85 "       wrpr            %3, %%pil\n"
 86 "3:     ldub            [%2], %0\n"
 87 "       brnz,pt         %0, 3b\n"
 88 "        nop\n"
 89 "       ba,pt           %%xcc, 1b\n"
 90 "        wrpr           %1, %%pil\n"
 91 "       .previous"
 92         : "=&r" (tmp1), "=&r" (tmp2)
 93         : "r"(lock), "r"(flags)
 94         : "memory");
 95 }
 96 
 97 /* Multi-reader locks, these are much saner than the 32-bit Sparc ones... */
 98 
 99 static inline void arch_read_lock(arch_rwlock_t *lock)
100 {
101         unsigned long tmp1, tmp2;
102 
103         __asm__ __volatile__ (
104 "1:     ldsw            [%2], %0\n"
105 "       brlz,pn         %0, 2f\n"
106 "4:      add            %0, 1, %1\n"
107 "       cas             [%2], %0, %1\n"
108 "       cmp             %0, %1\n"
109 "       bne,pn          %%icc, 1b\n"
110 "        nop\n"
111 "       .subsection     2\n"
112 "2:     ldsw            [%2], %0\n"
113 "       brlz,pt         %0, 2b\n"
114 "        nop\n"
115 "       ba,a,pt         %%xcc, 4b\n"
116 "       .previous"
117         : "=&r" (tmp1), "=&r" (tmp2)
118         : "r" (lock)
119         : "memory");
120 }
121 
122 static inline int arch_read_trylock(arch_rwlock_t *lock)
123 {
124         int tmp1, tmp2;
125 
126         __asm__ __volatile__ (
127 "1:     ldsw            [%2], %0\n"
128 "       brlz,a,pn       %0, 2f\n"
129 "        mov            0, %0\n"
130 "       add             %0, 1, %1\n"
131 "       cas             [%2], %0, %1\n"
132 "       cmp             %0, %1\n"
133 "       bne,pn          %%icc, 1b\n"
134 "        mov            1, %0\n"
135 "2:"
136         : "=&r" (tmp1), "=&r" (tmp2)
137         : "r" (lock)
138         : "memory");
139 
140         return tmp1;
141 }
142 
143 static inline void arch_read_unlock(arch_rwlock_t *lock)
144 {
145         unsigned long tmp1, tmp2;
146 
147         __asm__ __volatile__(
148 "1:     lduw    [%2], %0\n"
149 "       sub     %0, 1, %1\n"
150 "       cas     [%2], %0, %1\n"
151 "       cmp     %0, %1\n"
152 "       bne,pn  %%xcc, 1b\n"
153 "        nop"
154         : "=&r" (tmp1), "=&r" (tmp2)
155         : "r" (lock)
156         : "memory");
157 }
158 
159 static inline void arch_write_lock(arch_rwlock_t *lock)
160 {
161         unsigned long mask, tmp1, tmp2;
162 
163         mask = 0x80000000UL;
164 
165         __asm__ __volatile__(
166 "1:     lduw            [%2], %0\n"
167 "       brnz,pn         %0, 2f\n"
168 "4:      or             %0, %3, %1\n"
169 "       cas             [%2], %0, %1\n"
170 "       cmp             %0, %1\n"
171 "       bne,pn          %%icc, 1b\n"
172 "        nop\n"
173 "       .subsection     2\n"
174 "2:     lduw            [%2], %0\n"
175 "       brnz,pt         %0, 2b\n"
176 "        nop\n"
177 "       ba,a,pt         %%xcc, 4b\n"
178 "       .previous"
179         : "=&r" (tmp1), "=&r" (tmp2)
180         : "r" (lock), "r" (mask)
181         : "memory");
182 }
183 
184 static inline void arch_write_unlock(arch_rwlock_t *lock)
185 {
186         __asm__ __volatile__(
187 "       stw             %%g0, [%0]"
188         : /* no outputs */
189         : "r" (lock)
190         : "memory");
191 }
192 
193 static inline int arch_write_trylock(arch_rwlock_t *lock)
194 {
195         unsigned long mask, tmp1, tmp2, result;
196 
197         mask = 0x80000000UL;
198 
199         __asm__ __volatile__(
200 "       mov             0, %2\n"
201 "1:     lduw            [%3], %0\n"
202 "       brnz,pn         %0, 2f\n"
203 "        or             %0, %4, %1\n"
204 "       cas             [%3], %0, %1\n"
205 "       cmp             %0, %1\n"
206 "       bne,pn          %%icc, 1b\n"
207 "        nop\n"
208 "       mov             1, %2\n"
209 "2:"
210         : "=&r" (tmp1), "=&r" (tmp2), "=&r" (result)
211         : "r" (lock), "r" (mask)
212         : "memory");
213 
214         return result;
215 }
216 
217 #define arch_read_lock_flags(p, f) arch_read_lock(p)
218 #define arch_write_lock_flags(p, f) arch_write_lock(p)
219 
220 #define arch_read_can_lock(rw)          (!((rw)->lock & 0x80000000UL))
221 #define arch_write_can_lock(rw) (!(rw)->lock)
222 
223 #define arch_spin_relax(lock)   cpu_relax()
224 #define arch_read_relax(lock)   cpu_relax()
225 #define arch_write_relax(lock)  cpu_relax()
226 
227 #endif /* !(__ASSEMBLY__) */
228 
229 #endif /* !(__SPARC64_SPINLOCK_H) */
230 

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