summaryrefslogtreecommitdiff
path: root/Kernel/ThreadBlockers.cpp
AgeCommit message (Collapse)Author
2022-04-01Everywhere: Run clang-formatIdan Horowitz
2022-03-17Kernel: Use default constructors/destructorsLenny Maiorani
https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#cother-other-default-operation-rules "The compiler is more likely to get the default semantics right and you cannot implement these functions better than the compiler."
2022-01-30Kernel: Move Thread::block<BlockerType>() out of the Thread.h headerAndreas Kling
This function is large and unwieldy and forces Thread.h to #include a bunch of things. The only reason it was in the header is because we need to instantiate a blocker based on the templated BlockerType. We actually keep block<BlockerType>() in the header, but move the bulk of the function body out of line into Thread::block_impl(). To preserve destructor ordering, we add Blocker::finalize() which is called where we'd previously destroy the Blocker.
2021-12-30Kernel: Add some implied auto qualifiersHendiadyoin1
2021-12-21AK+Everywhere: Replace __builtin bit functionsNick Johnson
In order to reduce our reliance on __builtin_{ffs, clz, ctz, popcount}, this commit removes all calls to these functions and replaces them with the equivalent functions in AK/BuiltinWrappers.h.
2021-12-12Kernel+LibC: Implement sigtimedwait()Idan Horowitz
This includes a new Thread::Blocker called SignalBlocker which blocks until a signal of a matching type is pending. The current Blocker implementation in the Kernel is very complicated, but cleaning it up is a different yak for a different day.
2021-11-08Kernel: Replace KResult and KResultOr<T> with Error and ErrorOr<T>Andreas Kling
We now use AK::Error and AK::ErrorOr<T> in both kernel and userspace! This was a slightly tedious refactoring that took a long time, so it's not unlikely that some bugs crept in. Nevertheless, it does pass basic functionality testing, and it's just real nice to finally see the same pattern in all contexts. :^)
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-05Kernel: Rename FileBlocker::unblock() => unblock_if_conditions_are_met()Andreas Kling
Since this may not actually unblock, the old name was very confusing.
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-29Kernel: Strongly typed user & group ID'sAndreas Kling
Prior to this change, both uid_t and gid_t were typedef'ed to `u32`. This made it easy to use them interchangeably. Let's not allow that. This patch adds UserID and GroupID using the AK::DistinctNumeric mechanism we've already been employing for pid_t/ProcessID.
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: 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: 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 FutexBlockerAndreas Kling
Same deal as WaitQueueBlocker, we can get the blocked thread from Blocker::thread() now, so there's no need to register the current thread as custom data.
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: 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: Remove unnecessary spinlock in ~Thread::Blocker()Andreas Kling
Instead, just VERIFY that nobody is holding the blocker's internal lock.
2021-08-23Kernel: Rename some BlockerSets to foo_blocker_setAndreas Kling
Cleanup after renaming BlockCondition to BlockerSet.
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: 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-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-19Kernel: Make Process::current() return a Process& instead of Process*Idan Horowitz
This has several benefits: 1) We no longer just blindly derefence a null pointer in various places 2) We will get nicer runtime error messages if the current process does turn out to be null in the call location 3) GCC no longer complains about possible nullptr dereferences when compiling without KUBSAN
2021-08-06Kernel: Make AsyncDeviceRequest::name() return StringViewAndreas Kling
2021-07-16Kernel: Fix bogus check in Thread::WaitBlockCondition::finalize()Andreas Kling
I botched this in 859e5741ffd3c5be57a3c3ef4c08c6372e2ff35c, the check was supposed to be with Process::is_kernel_process(). This fixes an issue with zombie processes hanging around forever. Thanks tomuta for spotting it! :^)
2021-07-14Kernel: Fix Process use-after-free in Thread finalizationAndreas Kling
We leak a ref() onto every user process when constructing them, either via Process::create_user_process(), or via Process::sys$fork(). This ref() is balanced by a corresponding unref() in Thread::WaitBlockCondition::finalize(). Since kernel processes don't have a leaked ref() on them, this led to an extra Process::unref() on kernel processes during finalization. This happened during every boot, with the `init_stage2` process. Found by turning off kfree() scrubbing. :^)
2021-06-07Kernel: Fix error propagation if Thread::WaitBlocker constructor failsBrian Gianforcaro
There is logic at the end of the constructor that sets m_should_block to false if we encountered errors. We were missing this step due to the erroneous early return, the code then ended up waiting and then asserting on unblock since the WaitBlocker is in a invalid state. This fix is to not return early, and let normal control flow handle it. Fixes: #7857 Verified with `stress-ng --yield=10` locally.
2021-05-05Kernel: Modify TimeManagement::current_time(..) API so it can't fail. (#6869)Brian Gianforcaro
The fact that current_time can "fail" makes its use a bit awkward. All callers in the Kernel are trusted besides syscalls, so assert that they never get there, and make sure all current callers perform validation of the clock_id with TimeManagement::is_valid_clock_id(). I have fuzzed this change locally for a bit to make sure I didn't miss any obvious regression.
2021-04-29Everywhere: Use "the SerenityOS developers." in copyright headersLinus Groh
We had some inconsistencies before: - Sometimes "The", sometimes "the" - Sometimes trailing ".", sometimes no trailing "." I picked the most common one (lowecase "the", trailing ".") and applied it to all copyright headers. By using the exact same string everywhere we can ensure nothing gets missed during a global search (and replace), and that these inconsistencies are not spread any further (as copyright headers are commonly copied to new files).
2021-04-27Kernel: Simplify BlockTimeout constructorJelle Raaijmakers
2021-04-22Everything: Move to SPDX license identifiers in all files.Brian Gianforcaro
SPDX License Identifiers are a more compact / standardized way of representing file license information. See: https://spdx.dev/resources/use/#identifiers This was done with the `ambr` search and replace tool. ambr --no-parent-ignore --key-from-file --rep-from-file key.txt rep.txt *
2021-03-15Kernel: Fix sys$select() not marking fd's after blocking was avoidedAndreas Kling
In case multiple file descriptors in the `fd_set` were already readable and/or writable when calling Thread::block<SelectBlocker>(), we would only mark the first fd in the output sets instead of all relevant fd's. The short-circuit code path when blocking isn't necessary must ensure that unblock flags are collected for all file descriptors, not just the first one encountered. Fixes #5795.
2021-03-08Kernel: Add bitwise operators for Thread::FileBlocker::BlockFlags enumBrian Gianforcaro
Switch to using type-safe bitwise operators for the BlockFlags class, this cleans up a lot of boilerplate casts which are necessary when the enum is declared as `enum class`.
2021-03-02Kernel: Make sockets use AK::TimeBen Wiederhake
2021-03-02Kernel: Make TimeManagement use AK::Time internallyBen Wiederhake
I don't dare touch the multi-threading logic and locking mechanism, so it stays timespec for now. However, this could and should be changed to AK::Time, and I bet it will simplify the "increment_time_since_boot()" code.
2021-03-02Kernel: Make Thread use AK::Time internallyBen Wiederhake
This commit is very invasive, because Thread likes to take a pointer and write to it. This means that translating between timespec/timeval/Time would have been more difficult than just changing everything that hands a raw pointer to Thread, in bulk.
2021-02-23Everywhere: Rename ASSERT => VERIFYAndreas Kling
(...and ASSERT_NOT_REACHED => VERIFY_NOT_REACHED) Since all of these checks are done in release builds as well, let's rename them to VERIFY to prevent confusion, as everyone is used to assertions being compiled out in release. We can introduce a new ASSERT macro that is specifically for debug checks, but I'm doing this wholesale conversion first since we've accumulated thousands of these already, and it's not immediately obvious which ones are suitable for ASSERT.
2021-02-21Kernel: Use uniform initialization instead of memset for a few stack buffer.Brian Gianforcaro
Raw memset is relatively easy to mess up, avoid it when there are better alternatives provided by the compiler in modern C++.
2021-02-08Everywhere: Replace dbgln<flag>(...) with dbgln_if(flag, ...)AnotherTest
Replacement made by `find Kernel Userland -name '*.h' -o -name '*.cpp' | sed -i -Ee 's/dbgln\b<(\w+)>\(/dbgln_if(\1, /g'`
2021-01-26Meta: Split debug defines into multiple headers.asynts
The following script was used to make these changes: #!/bin/bash set -e tmp=$(mktemp -d) echo "tmp=$tmp" find Kernel \( -name '*.cpp' -o -name '*.h' \) | sort > $tmp/Kernel.files find . \( -path ./Toolchain -prune -o -path ./Build -prune -o -path ./Kernel -prune \) -o \( -name '*.cpp' -o -name '*.h' \) -print | sort > $tmp/EverythingExceptKernel.files cat $tmp/Kernel.files | xargs grep -Eho '[A-Z0-9_]+_DEBUG' | sort | uniq > $tmp/Kernel.macros cat $tmp/EverythingExceptKernel.files | xargs grep -Eho '[A-Z0-9_]+_DEBUG' | sort | uniq > $tmp/EverythingExceptKernel.macros comm -23 $tmp/Kernel.macros $tmp/EverythingExceptKernel.macros > $tmp/Kernel.unique comm -1 $tmp/Kernel.macros $tmp/EverythingExceptKernel.macros > $tmp/EverythingExceptKernel.unique cat $tmp/Kernel.unique | awk '{ print "#cmakedefine01 "$1 }' > $tmp/Kernel.header cat $tmp/EverythingExceptKernel.unique | awk '{ print "#cmakedefine01 "$1 }' > $tmp/EverythingExceptKernel.header for macro in $(cat $tmp/Kernel.unique) do cat $tmp/Kernel.files | xargs grep -l $macro >> $tmp/Kernel.new-includes ||: done cat $tmp/Kernel.new-includes | sort > $tmp/Kernel.new-includes.sorted for macro in $(cat $tmp/EverythingExceptKernel.unique) do cat $tmp/Kernel.files | xargs grep -l $macro >> $tmp/Kernel.old-includes ||: done cat $tmp/Kernel.old-includes | sort > $tmp/Kernel.old-includes.sorted comm -23 $tmp/Kernel.new-includes.sorted $tmp/Kernel.old-includes.sorted > $tmp/Kernel.includes.new comm -13 $tmp/Kernel.new-includes.sorted $tmp/Kernel.old-includes.sorted > $tmp/Kernel.includes.old comm -12 $tmp/Kernel.new-includes.sorted $tmp/Kernel.old-includes.sorted > $tmp/Kernel.includes.mixed for file in $(cat $tmp/Kernel.includes.new) do sed -i -E 's/#include <AK\/Debug\.h>/#include <Kernel\/Debug\.h>/' $file done for file in $(cat $tmp/Kernel.includes.mixed) do echo "mixed include in $file, requires manual editing." done
2021-01-25Everywhere: Debug macros instead of constexpr.asynts
This was done with the following script: find . \( -name '*.cpp' -o -name '*.h' -o -name '*.in' \) -not -path './Toolchain/*' -not -path './Build/*' -exec sed -i -E 's/dbgln<debug_([a-z_]+)>/dbgln<\U\1_DEBUG>/' {} \; find . \( -name '*.cpp' -o -name '*.h' -o -name '*.in' \) -not -path './Toolchain/*' -not -path './Build/*' -exec sed -i -E 's/if constexpr \(debug_([a-z0-9_]+)/if constexpr \(\U\1_DEBUG/' {} \;
2021-01-25Everywhere: Remove unnecessary debug comments.asynts
It would be tempting to uncomment these statements, but that won't work with the new changes. This was done with the following commands: find . \( -name '*.cpp' -o -name '*.h' -o -name '*.in' \) -not -path './Toolchain/*' -not -path './Build/*' -exec awk -i inplace '$0 !~ /\/\/#define/ { if (!toggle) { print; } else { toggle = !toggle } } ; $0 ~/\/\/#define/ { toggle = 1 }' {} \; find . \( -name '*.cpp' -o -name '*.h' -o -name '*.in' \) -not -path './Toolchain/*' -not -path './Build/*' -exec awk -i inplace '$0 !~ /\/\/ #define/ { if (!toggle) { print; } else { toggle = !toggle } } ; $0 ~/\/\/ #define/ { toggle = 1 }' {} \;
2021-01-22Everywhere: Replace a bundle of dbg with dbgln.asynts
These changes are arbitrarily divided into multiple commits to make it easier to find potentially introduced bugs with git bisect.
2021-01-22Everywhere: Fix typosLinus Groh