voron

experimental ARM OS
git clone git://git.2f30.org/voron
Log | Files | Refs | README | LICENSE

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 */