From e90b72ec3082588b296956730bd2930cf8d5d671 Mon Sep 17 00:00:00 2001 From: Richard Qin Date: Fri, 10 Jul 2026 11:31:46 +0800 Subject: refactor: promote new architecture to repository root Archive the deprecated implementation under lume-legacy, make the new kernel the default root-level build, and update repository entry points without changing kernel behavior. --- src/kernel/spinlock.cc | 199 ------------------------------------------------- 1 file changed, 199 deletions(-) delete mode 100644 src/kernel/spinlock.cc (limited to 'src/kernel/spinlock.cc') diff --git a/src/kernel/spinlock.cc b/src/kernel/spinlock.cc deleted file mode 100644 index aadce21..0000000 --- a/src/kernel/spinlock.cc +++ /dev/null @@ -1,199 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (C) 2026 Richard QIn - */ -#include "kernel/spinlock.h" -#include "kernel/riscv.h" -#include "kernel/cpu.h" -#include "kernel/proc_def.h" -#include "drivers/uart.h" - -extern struct cpu cpus[]; - -namespace ProcManager -{ - void sleep(void *chan, Spinlock *lk); - void wakeup(void *chan); -} - -// Interrupt Depth Management -void push_off(void); -void pop_off(void); - -// // Get the pointer of the current CPU -// // Depends on r_tp() in riscv.h to read the tp register -// struct cpu *mycpu() -// { -// int id = r_tp(); -// return &cpus[id]; -// } - -// Get the current process -// Must be called with interrupts disabled, or read atomically in a safe manner -struct Proc *myproc() -{ - push_off(); - struct cpu *c = mycpu(); - struct Proc *p = c->proc; - pop_off(); - return p; -} - -// Spinlock Implementation - -void Spinlock::init(const char *lock_name) -{ - name = lock_name; - locked = 0; - cpu = nullptr; -} - -void Spinlock::acquire() -{ - push_off(); // Disable interrupts: prevent deadlocks (interrupt handler requests a lock that is already held) - - if (holding()) - { - Drivers::uart_puts("panic: recursive acquire "); - Drivers::uart_puts(name); - Drivers::uart_puts("\n"); - while (1) - ; - } - - // Atomic Exchange - // __ATOMIC_ACQUIRE: Ensures that reads and writes after the acquire are not reordered before the acquire - while (__atomic_exchange_n(&locked, 1, __ATOMIC_ACQUIRE)) - { - // Busy-wait (Spinning) - // Optimization: Read-only, no writes, reducing cache coherence traffic - while (__atomic_load_n(&locked, __ATOMIC_RELAXED) == 1) - { - asm volatile("nop"); // RISC-V indicates that the CPU is in a spin state - } - } - - // Record holder - cpu = mycpu(); -} - -void Spinlock::release() -{ - if (!holding()) - { - Drivers::uart_puts("panic: release not holding\n"); - while (1) - ; - } - - cpu = nullptr; - - // Atomic Store - // __ATOMIC_RELEASE: Ensures all reads and writes before the Release are completed - __atomic_store_n(&locked, 0, __ATOMIC_RELEASE); - - pop_off(); -} - -// Check if the current CPU holds the lock -bool Spinlock::holding() -{ - // Interrupt checks must be disabled, otherwise a process switch may occur causing CPU fluctuations. - int r; - push_off(); - r = (locked && cpu == mycpu()); - pop_off(); - return r; -} - - -// Mutex Implementation (Sleep Locks) - -void Mutex::init(const char *lock_name) -{ - name = lock_name; - locked = 0; - pid = 0; - lk.init("mutex_internal"); -} - -void Mutex::acquire() -{ - lk.acquire(); // Acquire the internal lock to protect the locked field - - while (locked) - { - // Lock is held, preparing to sleep - // Atomicity contract of sleep(): - // 1. Mark the current process as SLEEPING - // 2. Release lk (so others can operate on locked) - // 3. Switch CPU (context switch) - // 4. After being woken up, reacquire the lk lock and return - ProcManager::sleep(this, &lk); - } - - locked = 1; - pid = myproc()->pid; - - lk.release(); -} - -void Mutex::release() -{ - lk.acquire(); - - locked = 0; - pid = 0; - - // Wake up all processes sleeping on this lock (chan = this) - ProcManager::wakeup(this); - - lk.release(); -} - -bool Mutex::holding() -{ - lk.acquire(); // Must use a lock when reading to prevent race conditions. - bool r = locked && (pid == myproc()->pid); - lk.release(); - return r; -} - -// Interrupt Depth Management - -void push_off(void) -{ - int old = intr_get(); - intr_off(); - - struct cpu *c = mycpu(); - - if (c->noff == 0) - c->intena = old; - - c->noff += 1; -} - -void pop_off(void) -{ - struct cpu *c = mycpu(); - - if (intr_get()) - { - Drivers::uart_puts("panic: pop_off - interruptible\n"); - while (1) - ; - } - if (c->noff < 1) - { - Drivers::uart_puts("panic: pop_off count\n"); - while (1) - ; - } - - c->noff -= 1; - - // An interrupt is only truly enabled when the nesting level returns to zero and the outermost layer allows interrupts. - if (c->noff == 0 && c->intena) - intr_on(); -} \ No newline at end of file -- cgit v1.2.3