/* * @author xamidev * @brief Spinlock implementation * @license GPL-3.0-only */ #include #include #include #include /* * spinlock_acquire - Lock a lock * @lock: pointer to desired spinlock * * Saves the RFLAGS register, then acquires a lock. * Pause instruction is used to ease the CPU. */ void spinlock_acquire(struct spinlock_t* lock) { uint64_t rflags; asm volatile("pushfq ; pop %0 ; cli" : "=rm"(rflags) : : "memory"); while (__atomic_test_and_set(&lock->locked, __ATOMIC_ACQUIRE)) { __builtin_ia32_pause(); } lock->rflags = rflags; } /* * spinlock_release - Unlock a lock * @lock: pointer to desired spinlock * * Gets saved RFLAGS register from the lock and * unlocks it (clears locked state). * RFLAGS is then restored. */ void spinlock_release(struct spinlock_t* lock) { uint64_t rflags = lock->rflags; __atomic_clear(&lock->locked, __ATOMIC_RELEASE); asm volatile("push %0 ; popfq" : : "rm"(rflags) : "memory"); }