mirror of
https://github.com/JannisHeydemann/BoredOS.git
synced 2026-05-30 02:16:58 +00:00
CheckP: smp support
This commit is contained in:
62
src/sys/spinlock.h
Normal file
62
src/sys/spinlock.h
Normal file
@@ -0,0 +1,62 @@
|
||||
// Copyright (c) 2023-2026 Chris (boreddevnl)
|
||||
// This software is released under the GNU General Public License v3.0. See LICENSE file for details.
|
||||
// This header needs to maintain in any file it is present in, as per the GPL license terms.
|
||||
#ifndef SPINLOCK_H
|
||||
#define SPINLOCK_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// Simple test-and-set spinlock for x86_64 SMP.
|
||||
// Uses 'lock xchg' for acquire and a plain store for release.
|
||||
// Includes 'pause' to reduce bus contention while spinning.
|
||||
|
||||
typedef volatile uint32_t spinlock_t;
|
||||
|
||||
#define SPINLOCK_INIT 0
|
||||
|
||||
static inline void spinlock_acquire(spinlock_t *lock) {
|
||||
while (1) {
|
||||
// Try to set the lock from 0 -> 1
|
||||
uint32_t prev;
|
||||
asm volatile("lock xchgl %0, %1"
|
||||
: "=r"(prev), "+m"(*lock)
|
||||
: "0"((uint32_t)1)
|
||||
: "memory");
|
||||
if (prev == 0) return; // We got the lock
|
||||
// Spin with pause (reduces power and bus traffic)
|
||||
while (*lock) {
|
||||
asm volatile("pause" ::: "memory");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void spinlock_release(spinlock_t *lock) {
|
||||
asm volatile("" ::: "memory"); // compiler barrier
|
||||
*lock = 0;
|
||||
}
|
||||
|
||||
// Try to acquire without blocking. Returns 1 if acquired, 0 if not.
|
||||
static inline int spinlock_try(spinlock_t *lock) {
|
||||
uint32_t prev;
|
||||
asm volatile("lock xchgl %0, %1"
|
||||
: "=r"(prev), "+m"(*lock)
|
||||
: "0"((uint32_t)1)
|
||||
: "memory");
|
||||
return (prev == 0);
|
||||
}
|
||||
|
||||
// IRQ-safe spinlock: saves flags, disables interrupts, then acquires.
|
||||
// Use when the lock may be contended from interrupt context.
|
||||
static inline uint64_t spinlock_acquire_irqsave(spinlock_t *lock) {
|
||||
uint64_t flags;
|
||||
asm volatile("pushfq; pop %0; cli" : "=r"(flags) :: "memory");
|
||||
spinlock_acquire(lock);
|
||||
return flags;
|
||||
}
|
||||
|
||||
static inline void spinlock_release_irqrestore(spinlock_t *lock, uint64_t flags) {
|
||||
spinlock_release(lock);
|
||||
asm volatile("push %0; popfq" : : "r"(flags) : "memory");
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user