Files
pepperOS/src/sched/spinlock.c
2026-03-18 11:48:33 +01:00

44 lines
1.0 KiB
C

/*
* @author xamidev <xamidev@riseup.net>
* @brief Spinlock implementation
* @license GPL-3.0-only
*/
#include <stdatomic.h>
#include <stdbool.h>
#include <kernel.h>
#include <sched/spinlock.h>
/*
* 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");
}