1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 12:38:12 +00:00

Kernel: Remove an allocation when blocking a thread

When blocking a thread with a timeout we would previously allocate
a Timer object. This removes the allocation for that Timer object.
This commit is contained in:
Gunnar Beutner 2021-05-20 00:41:51 +02:00 committed by Andreas Kling
parent 96b75af5d1
commit 7557f2db90
5 changed files with 42 additions and 23 deletions

View file

@ -791,7 +791,7 @@ public:
// Relaxed semantics are fine for timeout_unblocked because we
// synchronize on the spin locks already.
Atomic<bool, AK::MemoryOrder::memory_order_relaxed> timeout_unblocked(false);
RefPtr<Timer> timer;
bool timer_was_added = false;
{
switch (state()) {
case Thread::Stopped:
@ -817,7 +817,7 @@ public:
if (!block_timeout.is_infinite()) {
// Process::kill_all_threads may be called at any time, which will mark all
// threads to die. In that case
timer = TimerQueue::the().add_timer_without_id(block_timeout.clock_id(), block_timeout.absolute_time(), [&]() {
timer_was_added = TimerQueue::the().add_timer_without_id(*m_block_timer, block_timeout.clock_id(), block_timeout.absolute_time(), [&]() {
VERIFY(!Processor::current().in_irq());
VERIFY(!g_scheduler_lock.own_lock());
VERIFY(!m_block_lock.own_lock());
@ -827,7 +827,7 @@ public:
if (m_blocker && timeout_unblocked.exchange(true) == false)
unblock();
});
if (!timer) {
if (!timer_was_added) {
// Timeout is already in the past
blocker.not_blocking(true);
m_blocker = nullptr;
@ -890,11 +890,11 @@ public:
// to clean up now while we're still holding m_lock
auto result = blocker.end_blocking({}, did_timeout); // calls was_unblocked internally
if (timer && !did_timeout) {
if (timer_was_added && !did_timeout) {
// Cancel the timer while not holding any locks. This allows
// the timer function to complete before we remove it
// (e.g. if it's on another processor)
TimerQueue::the().cancel_timer(timer.release_nonnull());
TimerQueue::the().cancel_timer(*m_block_timer);
}
if (previous_locked != LockMode::Unlocked) {
// NOTE: this may trigger another call to Thread::block(), so
@ -1131,7 +1131,7 @@ public:
}
private:
Thread(NonnullRefPtr<Process>, NonnullOwnPtr<Region> kernel_stack_region);
Thread(NonnullRefPtr<Process>, NonnullOwnPtr<Region>, NonnullRefPtr<Timer>);
IntrusiveListNode<Thread> m_process_thread_list_node;
int m_runnable_priority { -1 };
@ -1269,6 +1269,8 @@ private:
Atomic<bool> m_have_any_unmasked_pending_signals { false };
Atomic<u32> m_nested_profiler_calls { 0 };
RefPtr<Timer> m_block_timer;
void yield_without_holding_big_lock();
void donate_without_holding_big_lock(RefPtr<Thread>&, const char*);
void yield_while_not_holding_big_lock();