- 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
--- /dev/null
+#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
#include "errno.h"
#include "process.h"
+#include "waitqueue.h"
#include "spinlock.h"
#include "uaccess.h"
#include "utils.h"
#include <stddef.h>
#define PTY_BUF_CAP 1024
-#define PTY_WAITQ_MAX 16
enum {
SIGTTIN = 21,
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;
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);
}
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;
}
}
}
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);
}
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;
}
}
}
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);
#include "keyboard.h"
#include "process.h"
+#include "waitqueue.h"
#include "spinlock.h"
#include "uart_console.h"
#include "uaccess.h"
#define TTY_LINE_MAX 256
#define TTY_CANON_BUF 1024
-#define TTY_WAITQ_MAX 16
static spinlock_t tty_lock = {0};
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};
}
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;
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();
}
}
- 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();
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,
canon_push(line_buf[i]);
}
line_len = 0;
- tty_wake_one();
+ wq_wake_one(&tty_wq);
spin_unlock_irqrestore(&tty_lock, flags);
return;
}
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);
}
canon_push('\n');
line_len = 0;
- tty_wake_one();
+ wq_wake_one(&tty_wq);
spin_unlock_irqrestore(&tty_lock, flags);
return;
}
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;