1 /* 2 * Copyright (C) 2015-2017 Alibaba Group Holding Limited 3 */ 4 5 #ifndef K_SPIN_LOCK_H 6 #define K_SPIN_LOCK_H 7 8 #ifdef __cplusplus 9 extern "C" { 10 #endif 11 12 /** @addtogroup aos_rhino spinlock 13 * Spinlock can be used for mutual exclusion between multi-cores. 14 * 15 * @{ 16 */ 17 18 /** 19 * spinlock object 20 */ 21 typedef struct { 22 volatile uint32_t owner; /* cpu index of owner */ 23 } kspinlock_t; 24 25 /* Be careful nested spin lock is not supported */ 26 #if (RHINO_CONFIG_CPU_NUM > 1) 27 28 /** 29 * Waiting for all cores. 30 * Can only be used once for multi-core synchronization after initialization. 31 * 32 * @param[in] NULL 33 * 34 * @return NULL 35 */ 36 extern void k_wait_allcores(void); 37 38 39 #define KRHINO_SPINLOCK_FREE_VAL 0xB33FFFFFu 40 41 /** 42 * Lock a spinlock, recursive locking is allowed. 43 * 44 * @param[in] lock the spinlock 45 * 46 * @return NULL 47 */ 48 #define krhino_spin_lock(lock) do { \ 49 cpu_spin_lock((lock)); \ 50 } while (0) \ 51 52 /** 53 * Unlock a spinlock, recursive locking is allowed. 54 * 55 * @param[in] lock the spinlock 56 * 57 * @return NULL 58 */ 59 #define krhino_spin_unlock(lock) do { \ 60 cpu_spin_unlock((lock)); \ 61 } while (0) 62 63 /** 64 * Lock a spinlock and mask interrupt, recursive locking is allowed. 65 * 66 * @param[in] lock the spinlock 67 * @param[out] flags the irq status before locking 68 * 69 * @return NULL 70 */ 71 #define krhino_spin_lock_irq_save(lock, flags) do { \ 72 flags = cpu_intrpt_save(); \ 73 cpu_spin_lock((lock)); \ 74 } while (0) 75 76 /** 77 * Unlock a spinlock and restore interrupt masking status, recursive locking is allowed. 78 * 79 * @param[in] lock the spinlock 80 * @param[in] flags the irq status before locking 81 * 82 * @return NULL 83 */ 84 #define krhino_spin_unlock_irq_restore(lock, flags) do { \ 85 cpu_spin_unlock((lock)); \ 86 cpu_intrpt_restore(flags); \ 87 } while (0) 88 89 /** 90 * Init a spinlock. 91 * 92 * @param[in] lock the spinlock 93 * 94 * @return NULL 95 */ 96 #define krhino_spin_lock_init(lock) do { \ 97 kspinlock_t *s = (kspinlock_t *)(lock); \ 98 s->owner = KRHINO_SPINLOCK_FREE_VAL; \ 99 } while(0) 100 #else 101 /* single-core spinlock */ 102 #define krhino_spin_lock(lock) krhino_sched_disable(); 103 #define krhino_spin_unlock(lock) krhino_sched_enable(); 104 105 #define krhino_spin_lock_irq_save(lock, flags) do { \ 106 (void)lock; \ 107 flags = cpu_intrpt_save(); \ 108 } while (0) 109 110 #define krhino_spin_unlock_irq_restore(lock, flags) do { \ 111 (void)lock; \ 112 cpu_intrpt_restore(flags); \ 113 } while (0) 114 115 #define krhino_spin_lock_init(lock) 116 #endif /* RHINO_CONFIG_CPU_NUM > 1 */ 117 118 /** @} */ 119 120 #ifdef __cplusplus 121 } 122 #endif 123 124 #endif /* K_SPIN_LOCK_H */ 125 126