]> Projects (at) Tadryanom (dot) Me - AdrOS.git/commitdiff
refactor: generic wait queue abstraction (waitqueue.h)
authorTulio A M Mendes <[email protected]>
Wed, 11 Feb 2026 22:32:55 +0000 (19:32 -0300)
committerTulio A M Mendes <[email protected]>
Fri, 13 Feb 2026 02:20:50 +0000 (23:20 -0300)
- include/waitqueue.h: reusable waitqueue_t with wq_init/push/pop/wake_one/wake_all
- src/kernel/tty.c: refactored to use waitqueue_t instead of ad-hoc arrays
- src/kernel/pty.c: refactored to use waitqueue_t instead of ad-hoc arrays
- Removed duplicate waitq_push/waitq_pop/waitq_empty/waitq_wake_one from both files
- cppcheck clean, 19/19 smoke tests pass

include/waitqueue.h [new file with mode: 0644]
src/kernel/pty.c
src/kernel/tty.c

diff --git a/include/waitqueue.h b/include/waitqueue.h
new file mode 100644 (file)
index 0000000..0177be9
--- /dev/null
@@ -0,0 +1,53 @@
+#ifndef WAITQUEUE_H
+#define WAITQUEUE_H
+
+#include <stdint.h>
+#include "process.h"
+
+#define WQ_CAPACITY 16
+
+typedef struct waitqueue {
+    struct process* entries[WQ_CAPACITY];
+    uint32_t head;
+    uint32_t tail;
+} waitqueue_t;
+
+static inline void wq_init(waitqueue_t* wq) {
+    wq->head = 0;
+    wq->tail = 0;
+}
+
+static inline int wq_empty(const waitqueue_t* wq) {
+    return wq->head == wq->tail;
+}
+
+static inline int wq_push(waitqueue_t* wq, struct process* p) {
+    uint32_t next = (wq->head + 1U) % WQ_CAPACITY;
+    if (next == wq->tail) return -1;
+    wq->entries[wq->head] = p;
+    wq->head = next;
+    return 0;
+}
+
+static inline struct process* wq_pop(waitqueue_t* wq) {
+    if (wq_empty(wq)) return NULL;
+    struct process* p = wq->entries[wq->tail];
+    wq->tail = (wq->tail + 1U) % WQ_CAPACITY;
+    return p;
+}
+
+static inline void wq_wake_one(waitqueue_t* wq) {
+    struct process* p = wq_pop(wq);
+    if (p && p->state == PROCESS_BLOCKED) {
+        p->state = PROCESS_READY;
+        sched_enqueue_ready(p);
+    }
+}
+
+static inline void wq_wake_all(waitqueue_t* wq) {
+    while (!wq_empty(wq)) {
+        wq_wake_one(wq);
+    }
+}
+
+#endif
index 14e1d019d417dcec9fd13b53d41fae3142771fad..617d62e7ae2d10dd6bd289627b9690f3c5a868fa 100644 (file)
@@ -2,6 +2,7 @@
 
 #include "errno.h"
 #include "process.h"
+#include "waitqueue.h"
 #include "spinlock.h"
 #include "uaccess.h"
 #include "utils.h"
@@ -11,7 +12,6 @@
 #include <stddef.h>
 
 #define PTY_BUF_CAP 1024
-#define PTY_WAITQ_MAX 16
 
 enum {
     SIGTTIN = 21,
@@ -32,13 +32,8 @@ struct pty_pair {
     uint32_t s2m_head;
     uint32_t s2m_tail;
 
-    struct process* m2s_waitq[PTY_WAITQ_MAX];
-    uint32_t m2s_wq_head;
-    uint32_t m2s_wq_tail;
-
-    struct process* s2m_waitq[PTY_WAITQ_MAX];
-    uint32_t s2m_wq_head;
-    uint32_t s2m_wq_tail;
+    waitqueue_t m2s_wq;
+    waitqueue_t s2m_wq;
 
     uint32_t session_id;
     uint32_t fg_pgrp;
@@ -77,28 +72,6 @@ static int rb_pop(uint8_t* buf, uint32_t* head, uint32_t* tail, uint8_t* out) {
     return 1;
 }
 
-static int waitq_push(struct process** q, uint32_t* head, uint32_t* tail, struct process* p) {
-    uint32_t next = (*head + 1U) % PTY_WAITQ_MAX;
-    if (next == *tail) return -1;
-    q[*head] = p;
-    *head = next;
-    return 0;
-}
-
-static struct process* waitq_pop(struct process** q, uint32_t* head, uint32_t* tail) {
-    if (*head == *tail) return NULL;
-    struct process* p = q[*tail];
-    *tail = (*tail + 1U) % PTY_WAITQ_MAX;
-    return p;
-}
-
-static void waitq_wake_one(struct process** q, uint32_t* head, uint32_t* tail) {
-    struct process* p = waitq_pop(q, head, tail);
-    if (p && p->state == PROCESS_BLOCKED) {
-        p->state = PROCESS_READY;
-        sched_enqueue_ready(p);
-    }
-}
 
 static uint32_t pty_master_read_fn(fs_node_t* node, uint32_t offset, uint32_t size, uint8_t* buffer);
 static uint32_t pty_master_write_fn(fs_node_t* node, uint32_t offset, uint32_t size, const uint8_t* buffer);
@@ -248,7 +221,7 @@ int pty_master_read_idx(int idx, void* kbuf, uint32_t len) {
         }
 
         if (current_process) {
-            if (waitq_push(p->s2m_waitq, &p->s2m_wq_head, &p->s2m_wq_tail, current_process) == 0) {
+            if (wq_push(&p->s2m_wq, current_process) == 0) {
                 current_process->state = PROCESS_BLOCKED;
             }
         }
@@ -292,7 +265,7 @@ int pty_master_write_idx(int idx, const void* kbuf, uint32_t len) {
     }
 
     if (to_write) {
-        waitq_wake_one(p->m2s_waitq, &p->m2s_wq_head, &p->m2s_wq_tail);
+        wq_wake_one(&p->m2s_wq);
     }
 
     spin_unlock_irqrestore(&pty_lock, flags);
@@ -324,7 +297,7 @@ int pty_slave_read_idx(int idx, void* kbuf, uint32_t len) {
         }
 
         if (current_process) {
-            if (waitq_push(p->m2s_waitq, &p->m2s_wq_head, &p->m2s_wq_tail, current_process) == 0) {
+            if (wq_push(&p->m2s_wq, current_process) == 0) {
                 current_process->state = PROCESS_BLOCKED;
             }
         }
@@ -354,7 +327,7 @@ int pty_slave_write_idx(int idx, const void* kbuf, uint32_t len) {
     }
 
     if (to_write) {
-        waitq_wake_one(p->s2m_waitq, &p->s2m_wq_head, &p->s2m_wq_tail);
+        wq_wake_one(&p->s2m_wq);
     }
 
     spin_unlock_irqrestore(&pty_lock, flags);
index e115a8d73eb4b969753ff10fadd6ba10257d091e..e7a4d1e384890fb31fb08871cecd8dda545c110d 100644 (file)
@@ -2,6 +2,7 @@
 
 #include "keyboard.h"
 #include "process.h"
+#include "waitqueue.h"
 #include "spinlock.h"
 #include "uart_console.h"
 #include "uaccess.h"
@@ -12,7 +13,6 @@
 
 #define TTY_LINE_MAX 256
 #define TTY_CANON_BUF 1024
-#define TTY_WAITQ_MAX 16
 
 static spinlock_t tty_lock = {0};
 
@@ -23,9 +23,7 @@ static char canon_buf[TTY_CANON_BUF];
 static uint32_t canon_head = 0;
 static uint32_t canon_tail = 0;
 
-static struct process* waitq[TTY_WAITQ_MAX];
-static uint32_t waitq_head = 0;
-static uint32_t waitq_tail = 0;
+static waitqueue_t tty_wq;
 
 static uint32_t tty_lflag = TTY_ICANON | TTY_ECHO | TTY_ISIG;
 static uint8_t tty_cc[NCCS] = {0, 0, 0, 0, 1, 0, 0, 0};
@@ -48,7 +46,6 @@ static int canon_empty(void) {
 }
 
 static uint32_t canon_count(void);
-static int waitq_push(struct process* p);
 
 int tty_write_kbuf(const void* kbuf, uint32_t len) {
     if (!kbuf) return -EFAULT;
@@ -104,7 +101,7 @@ int tty_read_kbuf(void* kbuf, uint32_t len) {
                 spin_unlock_irqrestore(&tty_lock, flags);
                 return rc;
             }
-            if (waitq_push(current_process) == 0)
+            if (wq_push(&tty_wq, current_process) == 0)
                 current_process->state = PROCESS_BLOCKED;
             spin_unlock_irqrestore(&tty_lock, flags);
             hal_cpu_enable_interrupts();
@@ -152,7 +149,7 @@ int tty_read_kbuf(void* kbuf, uint32_t len) {
             }
         }
 
-        if (waitq_push(current_process) == 0)
+        if (wq_push(&tty_wq, current_process) == 0)
             current_process->state = PROCESS_BLOCKED;
         spin_unlock_irqrestore(&tty_lock, flags);
         hal_cpu_enable_interrupts();
@@ -185,32 +182,6 @@ static void canon_push(char c) {
     canon_head = next;
 }
 
-static int waitq_empty(void) {
-    return waitq_head == waitq_tail;
-}
-
-static int waitq_push(struct process* p) {
-    uint32_t next = (waitq_head + 1U) % TTY_WAITQ_MAX;
-    if (next == waitq_tail) return -1;
-    waitq[waitq_head] = p;
-    waitq_head = next;
-    return 0;
-}
-
-static struct process* waitq_pop(void) {
-    if (waitq_empty()) return NULL;
-    struct process* p = waitq[waitq_tail];
-    waitq_tail = (waitq_tail + 1U) % TTY_WAITQ_MAX;
-    return p;
-}
-
-static void tty_wake_one(void) {
-    struct process* p = waitq_pop();
-    if (p && p->state == PROCESS_BLOCKED) {
-        p->state = PROCESS_READY;
-        sched_enqueue_ready(p);
-    }
-}
 
 enum {
     TTY_TCGETS = 0x5401,
@@ -343,7 +314,7 @@ void tty_input_char(char c) {
             canon_push(line_buf[i]);
         }
         line_len = 0;
-        tty_wake_one();
+        wq_wake_one(&tty_wq);
         spin_unlock_irqrestore(&tty_lock, flags);
         return;
     }
@@ -351,7 +322,7 @@ void tty_input_char(char c) {
     if ((lflag & TTY_ICANON) == 0) {
         if (c == '\r') c = '\n';
         canon_push(c);
-        tty_wake_one();
+        wq_wake_one(&tty_wq);
         if (lflag & TTY_ECHO) {
             uart_put_char(c);
         }
@@ -383,7 +354,7 @@ void tty_input_char(char c) {
         canon_push('\n');
         line_len = 0;
 
-        tty_wake_one();
+        wq_wake_one(&tty_wq);
         spin_unlock_irqrestore(&tty_lock, flags);
         return;
     }
@@ -408,7 +379,7 @@ void tty_init(void) {
     spinlock_init(&tty_lock);
     line_len = 0;
     canon_head = canon_tail = 0;
-    waitq_head = waitq_tail = 0;
+    wq_init(&tty_wq);
     tty_session_id = 0;
     tty_fg_pgrp = 0;