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