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/work_queue.c
Normal file
62
src/sys/work_queue.c
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.
|
||||
#include "work_queue.h"
|
||||
#include "spinlock.h"
|
||||
|
||||
extern void serial_write(const char *str);
|
||||
|
||||
#define WORK_QUEUE_SIZE 64
|
||||
|
||||
static work_item_t work_queue[WORK_QUEUE_SIZE];
|
||||
static volatile int wq_head = 0;
|
||||
static volatile int wq_tail = 0;
|
||||
static spinlock_t wq_lock = SPINLOCK_INIT;
|
||||
|
||||
void work_queue_submit(work_fn_t fn, void *arg) {
|
||||
if (!fn) return;
|
||||
|
||||
uint64_t flags = spinlock_acquire_irqsave(&wq_lock);
|
||||
int next_tail = (wq_tail + 1) % WORK_QUEUE_SIZE;
|
||||
if (next_tail == wq_head) {
|
||||
// Queue full — drop the work item
|
||||
spinlock_release_irqrestore(&wq_lock, flags);
|
||||
return;
|
||||
}
|
||||
work_queue[wq_tail].fn = fn;
|
||||
work_queue[wq_tail].arg = arg;
|
||||
wq_tail = next_tail;
|
||||
spinlock_release_irqrestore(&wq_lock, flags);
|
||||
}
|
||||
|
||||
bool work_queue_drain_one(void) {
|
||||
uint64_t flags = spinlock_acquire_irqsave(&wq_lock);
|
||||
if (wq_head == wq_tail) {
|
||||
spinlock_release_irqrestore(&wq_lock, flags);
|
||||
return false;
|
||||
}
|
||||
work_item_t item = work_queue[wq_head];
|
||||
wq_head = (wq_head + 1) % WORK_QUEUE_SIZE;
|
||||
spinlock_release_irqrestore(&wq_lock, flags);
|
||||
|
||||
// Execute outside the lock
|
||||
if (item.fn) {
|
||||
item.fn(item.arg);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void work_queue_drain_loop(void) {
|
||||
while (1) {
|
||||
// Try to drain all pending work
|
||||
while (work_queue_drain_one()) {
|
||||
// Keep draining
|
||||
}
|
||||
|
||||
// No work — halt the CPU until an interrupt wakes us.
|
||||
// With legacy PIC, APs don't receive timer interrupts, so they'll
|
||||
// sleep until an IPI is sent (e.g., when work is submitted).
|
||||
// This is ideal: APs use 0% CPU when idle.
|
||||
asm volatile("sti; hlt; cli");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user