spinlock.h (1063B)
1 #ifndef __SPINLOCK_H 2 #define __SPINLOCK_H 3 4 #include <io.h> 5 6 typedef struct { 7 u32 lock; 8 } spinlock_t; 9 10 #define SPINLOCK_INIT { 0 } 11 12 static inline void 13 spinlock_lock(spinlock_t *sl) 14 { 15 asm volatile ( 16 "1: \n\t" 17 "ldrex v1, [%0] \n\t" 18 "teq v1, #0 \n\t" 19 /* wait for event if it's locked */ 20 "wfene \n\t" 21 "bne 1b \n\t" 22 "strex v1, %1, [%0] \n\t" 23 "teq v1, #0 \n\t" 24 "bne 1b \n\t" 25 : 26 : "r" (&sl->lock), "r" (0x80000000) 27 : "v1", "memory", "cc" 28 ); 29 dmb(); 30 } 31 32 static inline void 33 spinlock_unlock(spinlock_t *sl) 34 { 35 dmb(); 36 sl->lock = 0; 37 dsb(); 38 /* signal event */ 39 asm volatile("sev" : : : "memory"); 40 } 41 42 /* returns 1 if locked and 0 if not */ 43 static inline int 44 spinlock_trylock(spinlock_t *sl) 45 { 46 unsigned int tmp; 47 48 asm volatile ( 49 "ldrex %0, [%1] \n\t" 50 "teq %0, #0 \n\t" 51 "strexeq %0, %2, [%1] \n\t" 52 : "=&r" (tmp) 53 : "r" (&sl->lock), "r" (0x80000000) 54 : "memory", "cc" 55 ); 56 57 if (tmp == 0) { 58 dmb(); 59 return 1; 60 } else 61 return 0; 62 } 63 64 static inline void 65 spinlock_init(spinlock_t *sl) 66 { 67 sl->lock = 0; 68 } 69 70 #endif /* __SPINLOCK_H */