2 * include/asm-xtensa/spinlock.h
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
8 * Copyright (C) 2001 - 2005 Tensilica Inc.
11 #ifndef _XTENSA_SPINLOCK_H
12 #define _XTENSA_SPINLOCK_H
14 #include <asm/barrier.h>
15 #include <asm/processor.h>
20 * There is at most one owner of a spinlock. There are not different
21 * types of spinlock owners like there are for rwlocks (see below).
23 * When trying to obtain a spinlock, the function "spins" forever, or busy-
24 * waits, until the lock is obtained. When spinning, presumably some other
25 * owner will soon give up the spinlock making it available to others. Use
26 * the trylock functions to avoid spinning forever.
30 * 0 nobody owns the spinlock
31 * 1 somebody owns the spinlock
34 #define arch_spin_is_locked(x) ((x)->slock != 0)
36 static inline void arch_spin_unlock_wait(arch_spinlock_t
*lock
)
38 smp_cond_load_acquire(&lock
->slock
, !VAL
);
41 #define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock)
43 static inline void arch_spin_lock(arch_spinlock_t
*lock
)
49 " wsr %0, scompare1\n"
58 /* Returns 1 if the lock is obtained, 0 otherwise. */
60 static inline int arch_spin_trylock(arch_spinlock_t
*lock
)
66 " wsr %0, scompare1\n"
73 return tmp
== 0 ? 1 : 0;
76 static inline void arch_spin_unlock(arch_spinlock_t
*lock
)
91 * Read-write locks are really a more flexible spinlock. They allow
92 * multiple readers but only one writer. Write ownership is exclusive
93 * (i.e., all other readers and writers are blocked from ownership while
94 * there is a write owner). These rwlocks are unfair to writers. Writers
95 * can be starved for an indefinite time by readers.
99 * 0 nobody owns the rwlock
100 * >0 one or more readers own the rwlock
101 * (the positive value is the actual number of readers)
102 * 0x80000000 one writer owns the rwlock, no other writers, no readers
105 #define arch_write_can_lock(x) ((x)->lock == 0)
107 static inline void arch_write_lock(arch_rwlock_t
*rw
)
111 __asm__
__volatile__(
113 " wsr %0, scompare1\n"
116 " s32c1i %0, %1, 0\n"
123 /* Returns 1 if the lock is obtained, 0 otherwise. */
125 static inline int arch_write_trylock(arch_rwlock_t
*rw
)
129 __asm__
__volatile__(
131 " wsr %0, scompare1\n"
134 " s32c1i %0, %1, 0\n"
139 return tmp
== 0 ? 1 : 0;
142 static inline void arch_write_unlock(arch_rwlock_t
*rw
)
146 __asm__
__volatile__(
154 static inline void arch_read_lock(arch_rwlock_t
*rw
)
157 unsigned long result
;
159 __asm__
__volatile__(
160 "1: l32i %1, %2, 0\n"
162 " wsr %1, scompare1\n"
164 " s32c1i %0, %2, 0\n"
166 : "=&a" (result
), "=&a" (tmp
)
171 /* Returns 1 if the lock is obtained, 0 otherwise. */
173 static inline int arch_read_trylock(arch_rwlock_t
*rw
)
175 unsigned long result
;
178 __asm__
__volatile__(
182 " wsr %1, scompare1\n"
183 " s32c1i %0, %2, 0\n"
186 : "=&a" (result
), "=&a" (tmp
)
193 static inline void arch_read_unlock(arch_rwlock_t
*rw
)
195 unsigned long tmp1
, tmp2
;
197 __asm__
__volatile__(
198 "1: l32i %1, %2, 0\n"
200 " wsr %1, scompare1\n"
201 " s32c1i %0, %2, 0\n"
203 : "=&a" (tmp1
), "=&a" (tmp2
)
208 #define arch_read_lock_flags(lock, flags) arch_read_lock(lock)
209 #define arch_write_lock_flags(lock, flags) arch_write_lock(lock)
211 #endif /* _XTENSA_SPINLOCK_H */