Initial Commit
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
#include "spinlock.h"
|
||||
|
||||
void spinlock_init(spinlock_t *lock) {
|
||||
atomic_flag_clear(&lock->flag);
|
||||
}
|
||||
|
||||
void spinlock_acquire_or_wait(spinlock_t *lock) {
|
||||
while (atomic_flag_test_and_set_explicit(&lock->flag, memory_order_acquire))
|
||||
asm volatile("pause" ::: "memory");
|
||||
}
|
||||
|
||||
void spinlock_drop(spinlock_t *lock) {
|
||||
atomic_flag_clear_explicit(&lock->flag, memory_order_release);
|
||||
}
|
||||
|
||||
void spinlock_acquire_irqsave(spinlock_t *lock, uint64_t *flags) {
|
||||
uint64_t f;
|
||||
asm volatile("pushfq; pop %0; cli" : "=r"(f) :: "memory");
|
||||
*flags = f;
|
||||
spinlock_acquire_or_wait(lock);
|
||||
}
|
||||
|
||||
void spinlock_release_irqrestore(spinlock_t *lock, uint64_t flags) {
|
||||
spinlock_drop(lock);
|
||||
asm volatile("push %0; popfq" :: "r"(flags) : "memory", "cc");
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
#include <stdatomic.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct {
|
||||
atomic_flag flag;
|
||||
} spinlock_t;
|
||||
|
||||
#define SPINLOCK_INIT ((spinlock_t){ .flag = ATOMIC_FLAG_INIT })
|
||||
|
||||
void spinlock_init(spinlock_t *lock);
|
||||
void spinlock_acquire_or_wait(spinlock_t *lock);
|
||||
void spinlock_drop(spinlock_t *lock);
|
||||
|
||||
// Old IRQ-safe API still available for compatibility
|
||||
void spinlock_acquire_irqsave(spinlock_t *lock, uint64_t *flags);
|
||||
void spinlock_release_irqrestore(spinlock_t *lock, uint64_t flags);
|
||||
Reference in New Issue
Block a user