diff options
| author | Richard Qin <richard.qin.x@gmail.com> | 2026-05-13 16:22:31 +0800 |
|---|---|---|
| committer | Richard Qin <richard.qin.x@gmail.com> | 2026-05-13 16:22:31 +0800 |
| commit | a3dad7adaa957f8872267ce837366cb9ec7a93a9 (patch) | |
| tree | beaefbd5b047dd09e010f7909ae421833b4bc36e /na/include | |
| parent | e7314f76d9edfbee2f676fad90ae6a727403263f (diff) | |
| download | lume-a3dad7adaa957f8872267ce837366cb9ec7a93a9.tar.gz lume-a3dad7adaa957f8872267ce837366cb9ec7a93a9.tar.xz | |
feat: implement WaitQueue class for blocking synchronization
Diffstat (limited to 'na/include')
| -rw-r--r-- | na/include/lume/wait.h | 22 | ||||
| -rw-r--r-- | na/include/lume/waitqueue.h | 50 |
2 files changed, 72 insertions, 0 deletions
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 <lume/types.h> +#include <lume/list.h> +#include <kernel/sync/spinlock.h> + +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_; +}; |
