From a3dad7adaa957f8872267ce837366cb9ec7a93a9 Mon Sep 17 00:00:00 2001 From: Richard Qin Date: Wed, 13 May 2026 16:22:31 +0800 Subject: feat: implement WaitQueue class for blocking synchronization --- na/include/lume/wait.h | 22 ++++++++++++++++++++ na/include/lume/waitqueue.h | 50 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 na/include/lume/wait.h create mode 100644 na/include/lume/waitqueue.h (limited to 'na/include') diff --git a/na/include/lume/wait.h b/na/include/lume/wait.h new file mode 100644 index 0000000..02012ab --- /dev/null +++ b/na/include/lume/wait.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* Copyright (C) 2026 Richard Qin */ + +#pragma once + +/* + * POSIX waitpid / wait4 Constants + * Reference: docs/specs/syscall.md §9 + */ + +/* waitpid options */ +inline constexpr int WNOHANG = 1; +inline constexpr int WUNTRACED = 2; + +/* Exit status encoding (Linux-compatible) */ +static inline int WEXITSTATUS(int s) { return (s >> 8) & 0xFF; } +static inline bool WIFEXITED(int s) { return (s & 0x7F) == 0; } +static inline bool WIFSIGNALED(int s){ return (s & 0x7F) != 0 && (s & 0x7F) != 0x7F; } +static inline int WTERMSIG(int s) { return s & 0x7F; } + +/* Encode exit code into wstatus (normal exit) */ +static inline int W_EXITCODE(int code) { return (code & 0xFF) << 8; } diff --git a/na/include/lume/waitqueue.h b/na/include/lume/waitqueue.h new file mode 100644 index 0000000..dd5edfe --- /dev/null +++ b/na/include/lume/waitqueue.h @@ -0,0 +1,50 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* Copyright (C) 2026 Richard Qin */ + +#pragma once + +/* + * WaitQueue — blocking synchronization primitive + * + * A thread calls wq.sleep() to block itself until another thread + * (or interrupt handler) calls wq.wake_one() or wq.wake_all(). + * + * Implementation: intrusive doubly-linked list of sleeping tasks, + * protected by an internal spinlock. + * + * Reference: docs/specs/scheduler.md, docs/specs/task.md §5 + */ + +#include +#include +#include + +struct TaskControlBlock; + +class WaitQueue { +public: + void init(const char* name = "wq") { + head_.init(); + lock_.init(name); + } + + /* Block the current task on this queue. + * If external_lock is provided, it is released AFTER the task is + * added to the wait queue but BEFORE schedule() is called, + * to avoid lost wakeups. + * Returns after wake_one/wake_all unblocks this task. */ + void sleep(Spinlock* external_lock = nullptr); + + /* Wake the first (oldest) sleeping task. Returns true if a task was woken. */ + bool wake_one(); + + /* Wake all sleeping tasks. Returns the number of tasks woken. */ + int wake_all(); + + /* Check if any tasks are waiting. */ + bool is_empty() const { return head_.is_empty(); } + +private: + list_node head_; + Spinlock lock_; +}; -- cgit v1.2.3