Skip to content

Feature/keyboard blocking#182

Merged
Galfurian merged 22 commits intodevelopfrom
feature/keyboard-blocking
Mar 6, 2026
Merged

Feature/keyboard blocking#182
Galfurian merged 22 commits intodevelopfrom
feature/keyboard-blocking

Conversation

@Galfurian
Copy link
Copy Markdown
Member

No description provided.

@Galfurian Galfurian linked an issue Feb 27, 2026 that may be closed by this pull request
Galfurian and others added 17 commits February 27, 2026 16:57
…very

- Update sleep_on() to track which wait queue a task is sleeping on via task->waiting_on field
- Update wake_up_all() to clear waiting_on field when removing task from wait queue
- Update sys_kill() to properly remove task from its wait queue before re-enqueueing to runqueue
- This prevents tasks from being on both wait queue and runqueue simultaneously, which was causing the shell to hang after child process execution
The issue was that sys_waitpid() was returning 0 when no zombie child existed,
causing userspace waitpid() to busy-wait in an infinite loop. When SIGCHLD
arrived, the default signal handler just ignored it, so the busy-wait continued.

Changes:
- Add waitpid_queue wait queue for processes blocked in waitpid()
- Modify sys_waitpid() to sleep on waitpid_queue when no zombie exists (unless WNOHANG)
- Modify do_exit() to wake_up_all() processes sleeping in waitpid_queue
- Return -EINTR from sys_waitpid after waking from signal
- Fix userspace waitpid() to:
  * Properly check WNOHANG with bitwise & (was using logical &&)
  * Retry on -EINTR (signal interrupted the sleep)
  * Handle error cases correctly

Now the shell properly blocks in waitpid() and is woken up when the child exits.
The sleep_on() function had a path that would reuse an existing wait_queue_entry
if the task was already on the queue. This caused issues because:

1. If the task was woken and the entry deallocated, stale pointers could remain
2. The check would return early without allocating a fresh entry
3. This could lead to the task not actually sleeping (early return)

Solution:
- Remove the entry-reuse optimization completely
- Always allocate a fresh entry for each sleep_on() call
- This ensures tasks actually sleep when added to the queue
- Fixes the shell hanging after child process execution

Also added missing clearing of waiting_on field when allocation fails.
- Add safety checks in scheduler_enqueue_task and scheduler_dequeue_task to detect and prevent double-enqueue/dequeue bugs
- Implement __dump_runqueue function for debugging scheduler state
- Remove verbose debug logging from enqueue/dequeue operations
- Change log levels from DEBUG to NOTICE in scheduler, process, timer, and wait modules
- Enhance shell status handling using environment variables instead of globals
- Add comprehensive syslog debugging in shell for command execution and signal handling
- Update VSCode editor settings for consistent formatting
- re-enqueue task on sleep timer expiry after removing wait queue entry\n- clear waiting_on when waking from sleep timeout\n- make RR selection robust when current task is dequeued\n- guard runtime stats update to runnable queued current task
- clear waiting_on when removing wait queue entries\n- enqueue task back to runqueue after wake-up if not already queued\n- prevent TASK_RUNNING tasks from being lost outside scheduler runqueue
Separate concerns: subsystems manage wait queues, scheduler manages state.
wake_up_process() now only handles task state transitions and runqueue placement.
Each subsystem removes its entries before calling wake_up_process().
Stopped tasks now just change state to TASK_STOPPED while remaining on the
runqueue. Scheduler naturally skips non-running tasks. SIGCONT simply
transitions state back to TASK_RUNNING. Eliminates unnecessary stopped_queue
wait queue infrastructure.
SIGKILL cannot be caught or ignored, so stopped tasks (TASK_STOPPED)
must be woken to TASK_RUNNING state when they receive SIGKILL. Without
this, a stopped process receiving kill -9 would never be scheduled to
process the fatal signal.

This partially addresses issue #143 by ensuring stopped tasks can be
killed. SIGCONT already wakes stopped tasks via handle_stop_signal().
@Galfurian Galfurian merged commit 8b8b31e into develop Mar 6, 2026
8 checks passed
@Galfurian Galfurian deleted the feature/keyboard-blocking branch March 6, 2026 16:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Kill does not affect tasks that are not scheduled fgets() returns prematurely in non-canonical input mode Implement passive waiting for waitpid

1 participant