Commit graph

64 commits

Author SHA1 Message Date
Timon Kruiper
e8aff0c1c8 Kernel: Use InterruptsState in Spinlock code
This commit updates the lock function from Spinlock and
RecursiveSpinlock to return the InterruptsState of the processor,
instead of the processor flags. The unlock functions would only look at
the interrupt flag of the processor flags, so we now use the
InterruptsState enum to clarify the intent, and such that we can use the
same Spinlock code for the aarch64 build.

To not break the build, all the call sites are updated aswell.
2022-08-26 12:51:57 +02:00
Anthony Iacono
f86b671de2 Kernel: Use Process::credentials() and remove user ID/group ID helpers
Move away from using the group ID/user ID helpers in the process to
allow for us to take advantage of the immutable credentials instead.
2022-08-22 12:46:32 +02:00
Andreas Kling
11eee67b85 Kernel: Make self-contained locking smart pointers their own classes
Until now, our kernel has reimplemented a number of AK classes to
provide automatic internal locking:

- RefPtr
- NonnullRefPtr
- WeakPtr
- Weakable

This patch renames the Kernel classes so that they can coexist with
the original AK classes:

- RefPtr => LockRefPtr
- NonnullRefPtr => NonnullLockRefPtr
- WeakPtr => LockWeakPtr
- Weakable => LockWeakable

The goal here is to eventually get rid of the Lock* classes in favor of
using external locking.
2022-08-20 17:20:43 +02:00
Idan Horowitz
3a80b25ed6 Kernel: Support F_SETLKW in fcntl 2022-07-21 16:39:22 +02:00
Idan Horowitz
275e5cdb64 Kernel: Report POLLNVAL events in sys$poll instead of returning EBADF
As required by Dr. Posix.
2022-07-10 14:24:34 +02:00
Tim Schumacher
edbffb3c7a Kernel: Unblock SignalBlocker if a signal was just unmarked as pending
When updating the signal mask, there is a small frame where we might set
up the receiving process for handing the signal and therefore remove
that signal from the list of pending signals before SignalBlocker has a
chance to block. In turn, this might cause SignalBlocker to never notice
that the signal arrives and it will never unblock once blocked.

Track the currently handled signal separately and include it when
determining if SignalBlocker should be unblocking.
2022-07-08 22:27:38 +00:00
Idan Horowitz
086969277e Everywhere: Run clang-format 2022-04-01 21:24:45 +01:00
Lenny Maiorani
190cf1507b Kernel: Use default constructors/destructors
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-03-17 00:51:36 -07:00
Andreas Kling
f469fb47b8 Kernel: Move Thread::block<BlockerType>() out of the Thread.h header
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.
2022-01-30 16:21:59 +01:00
Hendiadyoin1
04d75f4ff9 Kernel: Add some implied auto qualifiers 2021-12-30 14:32:17 +01:00
Nick Johnson
08e4a1a4dc AK+Everywhere: Replace __builtin bit functions
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-21 22:13:51 +01:00
Idan Horowitz
762e047ec9 Kernel+LibC: Implement sigtimedwait()
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-12-12 08:34:19 +02:00
Andreas Kling
79fa9765ca Kernel: Replace KResult and KResultOr<T> with Error and ErrorOr<T>
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-11-08 01:10:53 +01:00
Andreas Kling
4a9c18afb9 Kernel: Rename FileDescription => OpenFileDescription
Dr. POSIX really calls these "open file description", not just
"file description", so let's call them exactly that. :^)
2021-09-07 13:53:14 +02:00
Andreas Kling
e851a77346 Kernel: Rename FileBlocker::unblock() => unblock_if_conditions_are_met()
Since this may not actually unblock, the old name was very confusing.
2021-09-05 01:10:56 +02:00
Andreas Kling
68bf6db673 Kernel: Rename Spinlock::is_owned_by_current_thread()
...to is_owned_by_current_processor(). As Tom pointed out, this is
much more accurate. :^)
2021-08-29 22:19:42 +02:00
Andreas Kling
0b4671add7 Kernel: {Mutex,Spinlock}::own_lock() => is_locked_by_current_thread()
Rename these API's to make it more clear what they are checking.
2021-08-29 12:53:11 +02:00
Andreas Kling
ae197deb6b Kernel: Strongly typed user & group ID's
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-29 01:09:19 +02:00
Andrew Kaster
54161bf5b4 Kernel: Acquire reference to waitee before trying to block in sys$waitid
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-28 20:53:38 +02:00
Andreas Kling
0c1d41cc8a Kernel: Simplify Blockers so they don't need a "should block" flag
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-24 16:37:28 +02:00
Andreas Kling
adbf472ca7 Kernel: Remove unused BlockTimeout::m_should_block
This was assigned but never read.
2021-08-24 16:37:28 +02:00
Andreas Kling
82c3cc4640 Kernel: Move Blocker setup out from constructors into setup_blocker()
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-24 16:37:28 +02:00
Andreas Kling
b012170d69 Kernel: Don't register thread as custom data for FutexBlocker
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-24 01:57:11 +02:00
Andreas Kling
2c74533ba6 Kernel: Don't register thread as custom data for WaitQueueBlocker
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-24 01:57:11 +02:00
Andreas Kling
a58c4bbcf5 Kernel: Make Thread::Blocker::m_thread a NonnullRefPtr<Thread>
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-24 01:57:11 +02:00
Andreas Kling
c351945474 Kernel: Simplify unregistering a Blocker from a BlockerSet
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-24 01:57:11 +02:00
Andreas Kling
7006cb82bd Kernel: Rename Blocker::not_blocking(bool) to something more descriptive
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-23 02:13:04 +02:00
Andreas Kling
39474830a9 Kernel: Remove unnecessary spinlock in ~Thread::Blocker()
Instead, just VERIFY that nobody is holding the blocker's internal lock.
2021-08-23 01:45:31 +02:00
Andreas Kling
e51a5e2d5d Kernel: Rename some BlockerSets to foo_blocker_set
Cleanup after renaming BlockCondition to BlockerSet.
2021-08-23 01:42:04 +02:00
Andreas Kling
40bc378d81 Kernel: Rename QueueBlocker => WaitQueueBlocker
This is a Thread::Blocker that blocks on a WaitQueue, so let's call it
a WaitQueueBlocker to improve clarity. :^)
2021-08-23 00:10:33 +02:00
Andreas Kling
b30081b49a Kernel: Rename BlockerSet::unblock() to something more accurate
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-23 00:02:09 +02:00
Andreas Kling
85546af417 Kernel: Rename Thread::BlockCondition to BlockerSet
This class represents a set of Thread::Blocker objects attached to
something that those blockers are waiting on.
2021-08-23 00:02:09 +02:00
Andreas Kling
c922a7da09 Kernel: Rename ScopedSpinlock => SpinlockLocker
This matches MutexLocker, and doesn't sound like it's a lock itself.
2021-08-22 03:34:10 +02:00
Andreas Kling
55adace359 Kernel: Rename SpinLock => Spinlock 2021-08-22 03:34:10 +02:00
Idan Horowitz
cf271183b4 Kernel: Make Process::current() return a Process& instead of Process*
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-19 23:49:53 +02:00
Andreas Kling
066d3281b5 Kernel: Make AsyncDeviceRequest::name() return StringView 2021-08-06 00:37:47 +02:00
Andreas Kling
3108aa0a6b Kernel: Fix bogus check in Thread::WaitBlockCondition::finalize()
I botched this in 859e5741ff, 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-16 15:18:47 +02:00
Andreas Kling
859e5741ff Kernel: Fix Process use-after-free in Thread finalization
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-07-14 22:36:29 +02:00
Brian Gianforcaro
77f4f6e0de Kernel: Fix error propagation if Thread::WaitBlocker constructor fails
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-06-07 09:43:30 +02:00
Brian Gianforcaro
11306d7121
Kernel: Modify TimeManagement::current_time(..) API so it can't fail. (#6869)
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-05-05 18:51:06 +02:00
Linus Groh
649d2faeab Everywhere: Use "the SerenityOS developers." in copyright headers
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-29 00:59:26 +02:00
Jelle Raaijmakers
c3cff7d70a Kernel: Simplify BlockTimeout constructor 2021-04-27 09:19:55 +02:00
Brian Gianforcaro
1682f0b760 Everything: Move to SPDX license identifiers in all files.
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-04-22 11:22:27 +02:00
Andreas Kling
a7b5a58509 Kernel: Fix sys$select() not marking fd's after blocking was avoided
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-15 21:21:52 +01:00
Brian Gianforcaro
5f6ab77352 Kernel: Add bitwise operators for Thread::FileBlocker::BlockFlags enum
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-08 18:47:40 +01:00
Ben Wiederhake
5c15ca7b84 Kernel: Make sockets use AK::Time 2021-03-02 08:36:08 +01:00
Ben Wiederhake
c040e64b7d Kernel: Make TimeManagement use AK::Time internally
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-02 08:36:08 +01:00
Ben Wiederhake
2b6546c40a Kernel: Make Thread use AK::Time internally
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-03-02 08:36:08 +01:00
Andreas Kling
5d180d1f99 Everywhere: Rename ASSERT => VERIFY
(...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-23 20:56:54 +01:00
Brian Gianforcaro
cbd8f78cce Kernel: Use uniform initialization instead of memset for a few stack buffer.
Raw memset is relatively easy to mess up, avoid it when there are
better alternatives provided by the compiler in modern C++.
2021-02-21 11:52:47 +01:00