Files

45 lines
1.7 KiB
C

#ifndef FROSTBYTE_SPINLOCK_H
#define FROSTBYTE_SPINLOCK_H
#include "types.h"
/*
* SpinLock: an interrupt-safe mutual-exclusion lock for state shared between
* thread context and interrupt handlers (irq0/irq1 currently run with
* interrupts re-enabled per pic.c, so a naive "just disable interrupts"
* critical section is not enough once two handlers can nest).
*
* Acquire disables interrupts and spins on an atomic test-and-set before
* returning; release restores whatever the interrupt flag was at the
* matching acquire. This is correct and SMP-ready even though frostbyte is
* currently single-core: on one core, acquiring an already-held lock is a
* bug (it would spin forever with interrupts off), so spinLockTryAcquire is
* provided for call sites -- and tests -- that need to observe contention
* without deadlocking.
*/
typedef struct SpinLock {
volatile uint32 locked;
} SpinLock;
void spinLockInit(SpinLock* lock);
/* Disables interrupts, then spins until the lock is acquired. Returns the
interrupt flag as it was immediately before this call, to be passed back
to spinLockRelease unchanged (callers must not interleave two different
locks' flags). */
uint64 spinLockAcquire(SpinLock* lock);
/* Non-blocking. On success (true), interrupts are disabled and *savedFlags
holds the pre-call flag word, exactly as spinLockAcquire would leave
things. On failure (false) nothing is touched -- interrupts are left
exactly as the caller had them. */
bool spinLockTryAcquire(SpinLock* lock, uint64* savedFlags);
/* flags must be the value spinLockAcquire/spinLockTryAcquire handed back. */
void spinLockRelease(SpinLock* lock, uint64 flags);
bool spinLockIsLocked(const SpinLock* lock);
#endif