// Mark current process as exiting and notify/wake a waiter (if any).
void process_exit_notify(int status);
+// Enqueue a READY process into the active O(1) runqueue.
+// Must be called whenever a process transitions to PROCESS_READY from outside scheduler.c.
+void sched_enqueue_ready(struct process* p);
+
// Kill a process (minimal signals). Returns 0 on success or -errno.
int process_kill(uint32_t pid, int sig);
if (kbd_waiter) {
if (kbd_waiter->state == PROCESS_BLOCKED) {
kbd_waiter->state = PROCESS_READY;
+ sched_enqueue_ready(kbd_waiter);
}
kbd_waiter = NULL;
}
struct process* p = waitq_pop(q, head, tail);
if (p && p->state == PROCESS_BLOCKED) {
p->state = PROCESS_READY;
+ sched_enqueue_ready(p);
}
}
return NULL; // only idle task left
}
+void sched_enqueue_ready(struct process* p) {
+ if (!p) return;
+ uintptr_t flags = spin_lock_irqsave(&sched_lock);
+ if (p->state == PROCESS_READY) {
+ rq_enqueue(rq_active, p);
+ }
+ spin_unlock_irqrestore(&sched_lock, flags);
+}
+
void thread_wrapper(void (*fn)(void));
static struct process* process_find_locked(uint32_t pid) {
struct process* p = waitq_pop();
if (p && p->state == PROCESS_BLOCKED) {
p->state = PROCESS_READY;
+ sched_enqueue_ready(p);
}
}