summaryrefslogtreecommitdiff
path: root/Kernel/Thread.h
AgeCommit message (Collapse)Author
2021-09-10AK+Everywhere: Reduce the number of template parameters of IntrusiveListAli Mohammad Pur
This makes the user-facing type only take the node member pointer, and lets the compiler figure out the other needed types from that.
2021-09-07Kernel: Rename FileDescription => OpenFileDescriptionAndreas Kling
Dr. POSIX really calls these "open file description", not just "file description", so let's call them exactly that. :^)
2021-09-07Kernel: Specify a lock rank for Thread::m_lockBrian Gianforcaro
2021-09-07Kernel/Locking: Add lock rank tracking per thread to find deadlocksBrian Gianforcaro
This change adds a static lock hierarchy / ranking to the Kernel with the goal of reducing / finding deadlocks when running with SMP enabled. We have seen quite a few lock ordering deadlocks (locks taken in a different order, on two different code paths). As we properly annotate locks in the system, then these facilities will find these locking protocol violations automatically The `LockRank` enum documents the various locks in the system and their rank. The implementation guarantees that a thread holding one or more locks of a lower rank cannot acquire an additional lock with rank that is greater or equal to any of the currently held locks.
2021-09-07Kernel: Track when a thread is in the middle of crashingBrian Gianforcaro
There are certain checks that we should skip if the system is crashing. The system can avoid stack overflow during crash, or even triple faulting while while handling issues that can causes recursive panics or aborts.
2021-09-06Kernel: Make Threads always have a nameAndreas Kling
We previously allowed Thread to exist in a state where its m_name was null, and had to work around that in various places. This patch removes that possibility and forces those who would create a thread (or change the name of one) to provide a NonnullOwnPtr<KString> with the name.
2021-09-05Kernel: Make all Spinlocks use u8 for storage, remove templateBrian Gianforcaro
The default template argument is only used in one place, and it looks like it was probably just an oversight. The rest of the Kernel code all uses u8 as the type. So lets make that the default and remove the unused template argument, as there doesn't seem to be a reason to allow the size to be customizable.
2021-09-05AK+Kernel: Move KResult.h to Kernel/API for userspace accesssin-ack
This commit moves the KResult and KResultOr objects to Kernel/API to signify that they may now be freely used by userspace code at points where a syscall-related error result is to be expected. It also exposes KResult and KResultOr to the global namespace to make it nicer to use for userspace code.
2021-09-05Kernel: Declare type aliases with "using" instead of "typedef"Brian Gianforcaro
This is the idiomatic way to declare type aliases in modern C++. Flagged by Sonar Cloud as a "Code Smell", but I happen to agree with this particular one. :^)
2021-09-05Kernel: Rename FileBlocker::unblock() => unblock_if_conditions_are_met()Andreas Kling
Since this may not actually unblock, the old name was very confusing.
2021-09-04Kernel: Rename Thread::clone() => try_clone() and propagate errorsAndreas Kling
2021-08-29Kernel: Rename Spinlock::is_owned_by_current_thread()Andreas Kling
...to is_owned_by_current_processor(). As Tom pointed out, this is much more accurate. :^)
2021-08-29Kernel: {Mutex,Spinlock}::own_lock() => is_locked_by_current_thread()Andreas Kling
Rename these API's to make it more clear what they are checking.
2021-08-28Kernel: Acquire reference to waitee before trying to block in sys$waitidAndrew Kaster
Previously, we would try to acquire a reference to the all processes lock or other contended resources while holding both the scheduler lock and the thread's blocker lock. This could lead to a deadlock if we actually have to block on those other resources.
2021-08-24Kernel: Remove confusing nested scope in Thread::block()Andreas Kling
There was a nested scope here that didn't actually scope anything meaningfully, so just get rid of it.
2021-08-24Kernel: Use TemporaryChange to update Thread::m_in_blockAndreas Kling
Let's use an RAII helper to avoid having to update this on every path out of block(). Note that this extends the time under `m_in_block == true` by a little but that should be harmless.
2021-08-24Kernel: Simplify Blockers so they don't need a "should block" flagAndreas Kling
The `m_should_block` member variable that many of the Thread::Blocker subclasses had was really only used to carry state from the constructor to the immediate-unblock-without-blocking escape hatch. This patch refactors the blockers so that we don't need to hold on to this flag after setup_blocker(), and instead the return value from setup_blocker() is the authority on whether the unblock conditions are already met.
2021-08-24Kernel: Remove unused BlockTimeout::m_should_blockAndreas Kling
This was assigned but never read.
2021-08-24Kernel: Remove unused Thread::Blocker::should_block() virtualAndreas Kling
This was previously used after construction to check for early unblock conditions that couldn't be communicated from the constructor. Now that we've moved early unblock checks from the constructor into setup_blocker(), we don't need should_block() anymore.
2021-08-24Kernel: Move Blocker setup out from constructors into setup_blocker()Andreas Kling
Instead of registering with blocker sets and whatnot in the various Blocker subclass constructors, this patch moves such initialization to a separate setup_blocker() virtual. setup_blocker() returns false if there's no need to actually block the thread. This allows us to bail earlier in Thread::block().
2021-08-24Kernel: Don't register thread as custom data for WaitQueueBlockerAndreas Kling
When adding a WaitQueueBlocker to a WaitQueue, it stored the blocked thread in the registration's custom "void* data" slot. This was only used to print the Thread* in some debug logging. Now that Blocker always knows its origin Thread, we can simply add a Blocker::thread() accessor and then get the blocked Thread& from there. No need to register custom data.
2021-08-24Kernel: Make Thread::Blocker::m_thread a NonnullRefPtr<Thread>Andreas Kling
There's no harm in the blocker always knowing which thread it originated from. It also simplifies some logic since we don't need to think about it ever being null.
2021-08-24Kernel: Simplify unregistering a Blocker from a BlockerSetAndreas Kling
The BlockerSet stores its blockers along with a "void* data" that may contain some blocker-specific context relevant to the specific blocker registration (for example, SelectBlocker stores a pointer to the relevant entry in an array of SelectBlocker::FDInfo structs.) When unregistering a blocker from a set, we don't need to key the blocker by both the Blocker* and the data. Just the Blocker* is enough, since all registrations for that blocker need to be removed anyway as the blocker is about to be destroyed. So we stop passing the "void* data" to BlockerSet::remove_blocker(), which also allows us to remove the now-unneeded Blocker::m_block_data.
2021-08-23Kernel: Make Thread::m_block_timer a NonnullRefPtrAndreas Kling
Every thread has a block timer, so let's encode that in the type.
2021-08-23Kernel: Rename Blocker::not_blocking(bool) to something more descriptiveAndreas Kling
Namely, will_unblock_immediately_without_blocking(Reason). This virtual function is called on a blocker *before any block occurs*, if it turns out that we don't need to block the thread after all. This can happens for one of two reasons: - UnblockImmediatelyReason::UnblockConditionAlreadyMet We don't need to block the thread because the condition for unblocking it is already met. - UnblockImmediatelyReason::TimeoutInThePast We don't need to block the thread because a timeout was specified and that timeout is already in the past. This patch does not introduce any behavior changes, it's only meant to clarify this part of the blocking logic.
2021-08-23Kernel: Rename some BlockerSets to foo_blocker_setAndreas Kling
Cleanup after renaming BlockCondition to BlockerSet.
2021-08-23Kernel: Make Thread::Blocker non-copyable and non-movableAndreas Kling
2021-08-23Kernel: Rename QueueBlocker => WaitQueueBlockerAndreas Kling
This is a Thread::Blocker that blocks on a WaitQueue, so let's call it a WaitQueueBlocker to improve clarity. :^)
2021-08-23Kernel: Rename BlockerSet::unblock() to something more accurateAndreas Kling
Namely, unblock_all_blockers_whose_conditions_are_met(). The old name made it sound like things were getting unblocked no matter what, but that's not actually the case. What this actually does is iterate through the set of blockers, unblocking those whose conditions are met. So give it a (very) verbose name that errs on the side of descriptiveness.
2021-08-23Kernel: VERIFY that nobody is holding lock in ~BlockerSet()Andreas Kling
By the time we end up destroying a BlockerSet, we don't need to take the internal spinlock. And nobody else should be holding it either. So replace the SpinlockLocker with a VERIFY().
2021-08-23Kernel: Rename Thread::BlockCondition to BlockerSetAndreas Kling
This class represents a set of Thread::Blocker objects attached to something that those blockers are waiting on.
2021-08-23Kernel: Mark Thread::Blocker leaf subclasses finalAndreas Kling
2021-08-23Kernel: Mark BlockCondition subclasses as finalAndreas Kling
2021-08-23Kernel: Add VERIFY(!m_in_block) when entering Thread::block()Andreas Kling
2021-08-23Kernel: Convert Processor::in_irq() to static current_in_irq()Andreas Kling
This closes the race window between Processor::current() and a context switch happening before in_irq().
2021-08-23Kernel: Fix some trivial clang-tidy warnings in Thread.{cpp,h}Andreas Kling
2021-08-22Kernel: Rename ScopedSpinlock => SpinlockLockerAndreas Kling
This matches MutexLocker, and doesn't sound like it's a lock itself.
2021-08-22Kernel: Rename SpinLock => SpinlockAndreas Kling
2021-08-22Kernel: Rename SpinLockProtectedValue<T> => SpinLockProtected<T>Andreas Kling
2021-08-19Kernel: Consolidate a bunch of i386/x86_64 code pathsAndreas Kling
Add some arch-specific getters and setters that allow us to merge blocks that were previously specific to either ARCH(I386) or ARCH(X86_64).
2021-08-17Kernel: Port Thread to ListedRefCountedAndreas Kling
2021-08-15Kernel: Lock thread list while in Thread::unref()Andreas Kling
This patch does three things: - Convert the global thread list from a HashMap to an IntrusiveList - Combine the thread list and its lock into a SpinLockProtectedValue - Customize Thread::unref() so it locks the list while unreffing This closes the same race window for Thread as @sin-ack's recent changes did for Process. Note that the HashMap->IntrusiveList conversion means that we lose O(1) lookups, but the majority of clients of this list are doing traversal, not lookup. Once we have an intrusive hashing solution, we should port this to use that, but for now, this gets rid of heap allocations during a sensitive time.
2021-08-13Kernel: Convert lock debug APIs to east constBrian Gianforcaro
2021-08-13Kernel: Reduce LOCK_DEBUG ifdefs by utilizing Kernel::LockLocationBrian Gianforcaro
The LOCK_DEBUG conditional code is pretty ugly for a feature that we only use rarely. We can remove a significant amount of this code by utilizing a zero sized fake type when not building in LOCK_DEBUG mode. This lets us keep the same API, but just let the compiler optimize it away when don't actually care about the location the caller came from.
2021-08-12Kernel: Steer away from heap allocations for ProcFS process dataLiav A
Instead, use more static patterns to acquire that sort of data.
2021-08-10Kernel: Fix kernel panic when blocking on the process' big lockGunnar Beutner
Another thread might end up marking the blocking thread as holding the lock before it gets a chance to finish invoking the scheduler.
2021-08-10Kernel/SMP: Skip thread registers in core dump if there is no trap frameAndreas Kling
We can only get thread registers if there's a trap frame.
2021-08-10Kernel/SMP: Make entering/leaving critical sections multi-processor safeAndreas Kling
By making these functions static we close a window where we could get preempted after calling Processor::current() and move to another processor. Co-authored-by: Tom <tomut@yahoo.com>
2021-08-07Kernel: Port process thread lists to SpinLockProtectedValueAndreas Kling
I had to move the thread list out of the protected base area of Process so that it could live with its lock (which needs to be mutable). Ideally it would live in the protected area, so maybe we can figure out a way to do that later.
2021-08-07Kernel: Move LockMode into Locking/Jean-Baptiste Boric