h5n1xp / CuriOS

Simple GUI based Operating System - Based upon my own Microcokernel, heavily inspired by the original 1980s AmigaOS (though somewhat simpler).
74 stars 4 forks source link

Resizing windows randomly causes lock ups #2

Closed h5n1xp closed 3 years ago

h5n1xp commented 3 years ago

The last remaining GUI issue is while resizing a window, when more than one resizable window is open causes random lockups.

I suspect something (like an uninitialised pointer or something) is crashing the Window Server (currently and incorrectly called the Input Task due to it's heritage). I have added some Non GUI based Crash Reporting code, so if the window server crashes then the Error is just printed directly to the screen (a Blue screen of death)... But still no error is thrown, the machine just locks up.

-Edit- Adding a high priority task which alternately writes a red and then black square directly to the frame buffer, so this can been seen running even if the window server crashes. This task also stops when the machine locks up, so this suggests the task lists are becoming corrupted.

h5n1xp commented 3 years ago

Found the issue.

The Ready task list count value is sometimes reporting 1 even when empty, probably due to the Reschedule() function being called from two separate interrupts. The Scheduler now checks that the list isn't empty before trying to schedule in a new task from it.

Now to think how to improve the Rescheduling so it can't be called from two separate interrupts.

h5n1xp commented 3 years ago

Found out why this was happening.

When a task node was moved from the waiting list to the ready list, I didn't record the pointer to the next node in the waiting list, and so the loop which was supposed to be walking the task waiting list accidentally then switched to the ready list! It’s surprising it ever worked.

h5n1xp commented 3 years ago

I should probably explain that the reason why resizing Windows caused a crash. This was because of the complex sequence of actions which must take place during the resizing operation. At no point in the operation must the window server and the task have different sizes for the window, otherwise they could be overwriting random memory.

When the user drags the resize gadget in the window decoration, a resize event message is sent to the task by the window server with the new desired size. The task must then call the ResizeWindow() function in the GUI library, with the new size. This function sends a message back to the window server (the window server is responsible for actually resizing the window), and then waits for the window server to reply (with just a signal, since a full message would be overkill here) confirming the window has been resized. This is done as a very formal transaction to ensure both the window server and the task have a consistent record of the window size.

As you can see three context switches are required to complete the operation, this naturally highlighted any issues with my task scheduling algorithm! 😁