typedef struct { volatile unsigned int locked; // 0 = unlocked, 1 = locked } spinlock_t; static inline void initlock(spinlock_t *lk) { lk->locked = 0; } static inline void acquire(spinlock_t *lk) { while (__sync_lock_test_and_set(&lk->locked, 1) != 0); // spin } static inline void release(spinlock_t *lk) { __sync_lock_release(&lk->locked); } #ifdef ATOMIC_MUTEX #include #include typedef struct { atomic_int flag; } mutex_t; void mutex_init(mutex_t *m) { atomic_store(&m->flag, 0); } void mutex_lock(mutex_t *m) { int expected; do { expected = 0; } while (!atomic_compare_exchange_weak(&m->flag, &expected, 1)); } void mutex_unlock(mutex_t *m) { atomic_store(&m->flag, 0); } #endif #ifdef ATOMIC_MUTEX_RISCV typedef struct { volatile int locked; } spinlock_t; void spinlock_init(spinlock_t *lk) { lk->locked = 0; } void spinlock_acquire(spinlock_t *lk) { int tmp; do { __asm__ volatile("amoswap.w %0, %1, (%2)" : "=r"(tmp) // old value in tmp : "r"(1), "r"(&lk->locked) // store 1 into memory : "memory"); } while (tmp != 0); // spin until old value was 0 } void spinlock_release(spinlock_t *lk) { __asm__ volatile("amoswap.w zero, %1, (%0)" : : "r"(&lk->locked), "r"(0) : "memory"); } #endif