Files
banan-os/kernel/include/kernel/ThreadBlocker.h
Bananymous 92e4078287 Kernel: Rewrite ThreadBlocker
This gets rid of a very old bug where kernel panics when thread is being
woken up and unblocked at the same time on different cores. This
required adding a new lock to SchedulerQueue::Node and adding a cap to
how many threads a threadblocker can simultaneously block. I don't think
I ever block more than five threads on the same ThreadBlocker so this
should be fine.
2025-07-02 00:17:42 +03:00

44 lines
1.0 KiB
C++

#pragma once
#include <BAN/Math.h>
#include <kernel/Lock/SpinLock.h>
#include <kernel/Scheduler.h>
namespace Kernel
{
class ThreadBlocker
{
public:
void block_indefinite(BaseMutex*);
void block_with_timeout_ns(uint64_t timeout_ns, BaseMutex*);
void block_with_wake_time_ns(uint64_t wake_time_ns, BaseMutex*);
void unblock();
void block_with_timeout_ms(uint64_t timeout_ms, BaseMutex* mutex)
{
ASSERT(!BAN::Math::will_multiplication_overflow<uint64_t>(timeout_ms, 1'000'000));
return block_with_timeout_ns(timeout_ms * 1'000'000, mutex);
}
void block_with_wake_time_ms(uint64_t wake_time_ms, BaseMutex* mutex)
{
ASSERT(!BAN::Math::will_multiplication_overflow<uint64_t>(wake_time_ms, 1'000'000));
return block_with_wake_time_ns(wake_time_ms * 1'000'000, mutex);
}
private:
void add_thread_to_block_queue(SchedulerQueue::Node*);
void remove_blocked_thread(SchedulerQueue::Node*);
private:
SpinLock m_lock;
SchedulerQueue::Node* m_block_chain[32] {};
size_t m_block_chain_length { 0 };
friend class Scheduler;
};
}