summaryrefslogtreecommitdiff
path: root/na/include
diff options
context:
space:
mode:
authorRichard Qin <richard.qin.x@gmail.com>2026-05-13 16:22:31 +0800
committerRichard Qin <richard.qin.x@gmail.com>2026-05-13 16:22:31 +0800
commita3dad7adaa957f8872267ce837366cb9ec7a93a9 (patch)
treebeaefbd5b047dd09e010f7909ae421833b4bc36e /na/include
parente7314f76d9edfbee2f676fad90ae6a727403263f (diff)
downloadlume-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.h22
-rw-r--r--na/include/lume/waitqueue.h50
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_;
+};