summaryrefslogtreecommitdiff
path: root/Kernel/WaitQueue.cpp
AgeCommit message (Collapse)Author
2020-07-06Kernel: Enhance WaitQueue to remember pending wakesTom
If WaitQueue::wake_all, WaitQueue::wake_one, or WaitQueue::wake_n is called but nobody is currently waiting, we should remember that fact and prevent someone from waiting after such a request. This solves a race condition where the Finalizer thread is notified to finalize a thread, but it is not (yet) waiting on this queue. Fixes #2693
2020-07-06Kernel: Add a SpinLock to the WaitQueueTom
We need to be able to prevent a WaitQueue from being modified by another CPU. So, add a SpinLock to it. Because this pushes some other class over the 64 byte limit, we also need to add another 128-byte bucket to the slab allocator.
2020-07-03Kernel: Fix signal deliveryTom
When delivering urgent signals to the current thread we need to check if we should be unblocked, and if not we need to yield to another process. We also need to make sure that we suppress context switches during Process::exec() so that we don't clobber the registers that it sets up (eip mainly) by a context switch. To be able to do that we add the concept of a critical section, which are similar to Process::m_in_irq but different in that they can be requested at any time. Calls to Scheduler::yield and Scheduler::donate_to will return instantly without triggering a context switch, but the processor will then asynchronously trigger a context switch once the critical section is left.
2020-07-01Kernel: Implement software context switching and Processor structureTom
Moving certain globals into a new Processor structure for each CPU allows us to eventually run an instance of the scheduler on each CPU.
2020-04-26Kernel: Implement FUTEX_WAKE of arbitrary count.Brian Gianforcaro
Previously we just woke all waiters no matter how many were requested. Fix this by implementing WaitQueue::wake_n(..).
2020-02-26Kernel: Allow process with multiple threads to call exec and exitCristian-Bogdan SIRB
This allows a process wich has more than 1 thread to call exec, even from a thread. This kills all the other threads, but it won't wait for them to finish, just makes sure that they are not in a running/runable state. In the case where a thread does exec, the new program PID will be the thread TID, to keep the PID == TID in the new process. This introduces a new function inside the Process class, kill_threads_except_self which is called on exit() too (exit with multiple threads wasn't properly working either). Inside the Lock class, there is the need for a new function, clear_waiters, which removes all the waiters from the Process::big_lock. This is needed since after a exit/exec, there should be no other threads waiting for this lock, the threads should be simply killed. Only queued threads should wait for this lock at this point, since blocked threads are handled in set_should_die.
2020-02-16Kernel: Move all code into the Kernel namespaceAndreas Kling
2020-01-18Meta: Add license header to source filesAndreas Kling
As suggested by Joshua, this commit adds the 2-clause BSD license as a comment block to the top of every source file. For the first pass, I've just added myself for simplicity. I encourage everyone to add themselves as copyright holders of any file they've added or modified in some significant way. If I've added myself in error somewhere, feel free to replace it with the appropriate copyright holder instead. Going forward, all new source files should include a license header.
2020-01-12Kernel: Fix Lock racing to the WaitQueueAndreas Kling
There was a time window between releasing Lock::m_lock and calling into the lock's WaitQueue where someone else could take m_lock and bring two threads into a deadlock situation. Fix this issue by holding Lock::m_lock until interrupts are disabled by either Thread::wait_on() or WaitQueue::wake_one().
2019-12-22Kernel: Use IntrusiveList to make WaitQueue allocation-free :^)Andreas Kling
2019-12-08Kernel: Break out of the idle loop on WaitQueue wake instead of on IRQAndreas Kling
Now that we have proper wait queues to drive waiter wakeup, we can use the wake actions to break out of the scheduler's idle loop when we've got a thread to run.
2019-12-01Kernel: Use a dedicated thread state for wait-queued threadsAndreas Kling
Instead of using the generic block mechanism, wait-queued threads now go into the special Queued state. This fixes an issue where signal dispatch would unblock a wait-queued thread (because signal dispatch unblocks blocked threads) and cause confusion since the thread only expected to be awoken by the queue.
2019-12-01Kernel: Add a WaitQueue for Thread queueing/waking and use it for LockAndreas Kling
The kernel's Lock class now uses a proper wait queue internally instead of just having everyone wake up regularly to try to acquire the lock. We also keep the donation mechanism, so that whenever someone tries to take the lock and fails, that thread donates the remainder of its timeslice to the current lock holder. After unlocking a Lock, the unlocking thread calls WaitQueue::wake_one, which unblocks the next thread in queue.