spinlock.h
来自「linux 内核源代码」· C头文件 代码 · 共 251 行
H
251 行
/* spinlock.h: 64-bit Sparc spinlock support. * * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) */#ifndef __SPARC64_SPINLOCK_H#define __SPARC64_SPINLOCK_H#include <linux/threads.h> /* For NR_CPUS */#ifndef __ASSEMBLY__/* To get debugging spinlocks which detect and catch * deadlock situations, set CONFIG_DEBUG_SPINLOCK * and rebuild your kernel. *//* All of these locking primitives are expected to work properly * even in an RMO memory model, which currently is what the kernel * runs in. * * There is another issue. Because we play games to save cycles * in the non-contention case, we need to be extra careful about * branch targets into the "spinning" code. They live in their * own section, but the newer V9 branches have a shorter range * than the traditional 32-bit sparc branch variants. The rule * is that the branches that go into and out of the spinner sections * must be pre-V9 branches. */#define __raw_spin_is_locked(lp) ((lp)->lock != 0)#define __raw_spin_unlock_wait(lp) \ do { rmb(); \ } while((lp)->lock)static inline void __raw_spin_lock(raw_spinlock_t *lock){ unsigned long tmp; __asm__ __volatile__("1: ldstub [%1], %0\n"" membar #StoreLoad | #StoreStore\n"" brnz,pn %0, 2f\n"" nop\n"" .subsection 2\n""2: ldub [%1], %0\n"" membar #LoadLoad\n"" brnz,pt %0, 2b\n"" nop\n"" ba,a,pt %%xcc, 1b\n"" .previous" : "=&r" (tmp) : "r" (lock) : "memory");}static inline int __raw_spin_trylock(raw_spinlock_t *lock){ unsigned long result; __asm__ __volatile__(" ldstub [%1], %0\n"" membar #StoreLoad | #StoreStore" : "=r" (result) : "r" (lock) : "memory"); return (result == 0UL);}static inline void __raw_spin_unlock(raw_spinlock_t *lock){ __asm__ __volatile__(" membar #StoreStore | #LoadStore\n"" stb %%g0, [%0]" : /* No outputs */ : "r" (lock) : "memory");}static inline void __raw_spin_lock_flags(raw_spinlock_t *lock, unsigned long flags){ unsigned long tmp1, tmp2; __asm__ __volatile__("1: ldstub [%2], %0\n"" membar #StoreLoad | #StoreStore\n"" brnz,pn %0, 2f\n"" nop\n"" .subsection 2\n""2: rdpr %%pil, %1\n"" wrpr %3, %%pil\n""3: ldub [%2], %0\n"" membar #LoadLoad\n"" brnz,pt %0, 3b\n"" nop\n"" ba,pt %%xcc, 1b\n"" wrpr %1, %%pil\n"" .previous" : "=&r" (tmp1), "=&r" (tmp2) : "r"(lock), "r"(flags) : "memory");}/* Multi-reader locks, these are much saner than the 32-bit Sparc ones... */static void inline __read_lock(raw_rwlock_t *lock){ unsigned long tmp1, tmp2; __asm__ __volatile__ ("1: ldsw [%2], %0\n"" brlz,pn %0, 2f\n""4: add %0, 1, %1\n"" cas [%2], %0, %1\n"" cmp %0, %1\n"" membar #StoreLoad | #StoreStore\n"" bne,pn %%icc, 1b\n"" nop\n"" .subsection 2\n""2: ldsw [%2], %0\n"" membar #LoadLoad\n"" brlz,pt %0, 2b\n"" nop\n"" ba,a,pt %%xcc, 4b\n"" .previous" : "=&r" (tmp1), "=&r" (tmp2) : "r" (lock) : "memory");}static int inline __read_trylock(raw_rwlock_t *lock){ int tmp1, tmp2; __asm__ __volatile__ ("1: ldsw [%2], %0\n"" brlz,a,pn %0, 2f\n"" mov 0, %0\n"" add %0, 1, %1\n"" cas [%2], %0, %1\n"" cmp %0, %1\n"" membar #StoreLoad | #StoreStore\n"" bne,pn %%icc, 1b\n"" mov 1, %0\n""2:" : "=&r" (tmp1), "=&r" (tmp2) : "r" (lock) : "memory"); return tmp1;}static void inline __read_unlock(raw_rwlock_t *lock){ unsigned long tmp1, tmp2; __asm__ __volatile__(" membar #StoreLoad | #LoadLoad\n""1: lduw [%2], %0\n"" sub %0, 1, %1\n"" cas [%2], %0, %1\n"" cmp %0, %1\n"" bne,pn %%xcc, 1b\n"" nop" : "=&r" (tmp1), "=&r" (tmp2) : "r" (lock) : "memory");}static void inline __write_lock(raw_rwlock_t *lock){ unsigned long mask, tmp1, tmp2; mask = 0x80000000UL; __asm__ __volatile__("1: lduw [%2], %0\n"" brnz,pn %0, 2f\n""4: or %0, %3, %1\n"" cas [%2], %0, %1\n"" cmp %0, %1\n"" membar #StoreLoad | #StoreStore\n"" bne,pn %%icc, 1b\n"" nop\n"" .subsection 2\n""2: lduw [%2], %0\n"" membar #LoadLoad\n"" brnz,pt %0, 2b\n"" nop\n"" ba,a,pt %%xcc, 4b\n"" .previous" : "=&r" (tmp1), "=&r" (tmp2) : "r" (lock), "r" (mask) : "memory");}static void inline __write_unlock(raw_rwlock_t *lock){ __asm__ __volatile__(" membar #LoadStore | #StoreStore\n"" stw %%g0, [%0]" : /* no outputs */ : "r" (lock) : "memory");}static int inline __write_trylock(raw_rwlock_t *lock){ unsigned long mask, tmp1, tmp2, result; mask = 0x80000000UL; __asm__ __volatile__(" mov 0, %2\n""1: lduw [%3], %0\n"" brnz,pn %0, 2f\n"" or %0, %4, %1\n"" cas [%3], %0, %1\n"" cmp %0, %1\n"" membar #StoreLoad | #StoreStore\n"" bne,pn %%icc, 1b\n"" nop\n"" mov 1, %2\n""2:" : "=&r" (tmp1), "=&r" (tmp2), "=&r" (result) : "r" (lock), "r" (mask) : "memory"); return result;}#define __raw_read_lock(p) __read_lock(p)#define __raw_read_trylock(p) __read_trylock(p)#define __raw_read_unlock(p) __read_unlock(p)#define __raw_write_lock(p) __write_lock(p)#define __raw_write_unlock(p) __write_unlock(p)#define __raw_write_trylock(p) __write_trylock(p)#define __raw_read_can_lock(rw) (!((rw)->lock & 0x80000000UL))#define __raw_write_can_lock(rw) (!(rw)->lock)#define _raw_spin_relax(lock) cpu_relax()#define _raw_read_relax(lock) cpu_relax()#define _raw_write_relax(lock) cpu_relax()#endif /* !(__ASSEMBLY__) */#endif /* !(__SPARC64_SPINLOCK_H) */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?