From: Tulio A M Mendes Date: Wed, 11 Feb 2026 22:32:55 +0000 (-0300) Subject: refactor: generic wait queue abstraction (waitqueue.h) X-Git-Url: https://projects.tadryanom.me/docs/static/gitweb.js?a=commitdiff_plain;h=4ba2edcceaa0271e4b21613e3ec2c9ccf5b446b5;p=AdrOS.git refactor: generic wait queue abstraction (waitqueue.h) - 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 --- diff --git a/include/waitqueue.h b/include/waitqueue.h new file mode 100644 index 0000000..0177be9 --- /dev/null +++ b/include/waitqueue.h @@ -0,0 +1,53 @@ +#ifndef WAITQUEUE_H +#define WAITQUEUE_H + +#include +#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 diff --git a/src/kernel/pty.c b/src/kernel/pty.c index 14e1d01..617d62e 100644 --- a/src/kernel/pty.c +++ b/src/kernel/pty.c @@ -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 #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); diff --git a/src/kernel/tty.c b/src/kernel/tty.c index e115a8d..e7a4d1e 100644 --- a/src/kernel/tty.c +++ b/src/kernel/tty.c @@ -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;