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.
This commit is contained in:
@@ -14,33 +14,12 @@ namespace Kernel
|
||||
class BaseMutex;
|
||||
class Thread;
|
||||
class ThreadBlocker;
|
||||
struct SchedulerQueueNode;
|
||||
|
||||
class SchedulerQueue
|
||||
{
|
||||
public:
|
||||
struct Node
|
||||
{
|
||||
Node(Thread* thread)
|
||||
: thread(thread)
|
||||
{}
|
||||
|
||||
Thread* const thread;
|
||||
|
||||
Node* next { nullptr };
|
||||
Node* prev { nullptr };
|
||||
|
||||
uint64_t wake_time_ns { static_cast<uint64_t>(-1) };
|
||||
|
||||
ThreadBlocker* blocker { nullptr };
|
||||
Node* block_chain_next { nullptr };
|
||||
Node* block_chain_prev { nullptr };
|
||||
|
||||
ProcessorID processor_id { PROCESSOR_NONE };
|
||||
bool blocked { false };
|
||||
|
||||
uint64_t last_start_ns { 0 };
|
||||
uint64_t time_used_ns { 0 };
|
||||
};
|
||||
using Node = SchedulerQueueNode;
|
||||
|
||||
public:
|
||||
void add_thread_to_back(Node*);
|
||||
|
||||
35
kernel/include/kernel/SchedulerQueueNode.h
Normal file
35
kernel/include/kernel/SchedulerQueueNode.h
Normal file
@@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
|
||||
#include <kernel/ProcessorID.h>
|
||||
#include <kernel/Lock/SpinLock.h>
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
|
||||
class Thread;
|
||||
class ThreadBlocker;
|
||||
|
||||
struct SchedulerQueueNode
|
||||
{
|
||||
SchedulerQueueNode(Thread* thread)
|
||||
: thread(thread)
|
||||
{}
|
||||
|
||||
Thread* const thread;
|
||||
|
||||
SchedulerQueueNode* next { nullptr };
|
||||
SchedulerQueueNode* prev { nullptr };
|
||||
|
||||
uint64_t wake_time_ns { static_cast<uint64_t>(-1) };
|
||||
|
||||
SpinLock blocker_lock;
|
||||
ThreadBlocker* blocker { nullptr };
|
||||
|
||||
ProcessorID processor_id { PROCESSOR_NONE };
|
||||
bool blocked { false };
|
||||
|
||||
uint64_t last_start_ns { 0 };
|
||||
uint64_t time_used_ns { 0 };
|
||||
};
|
||||
|
||||
}
|
||||
@@ -33,7 +33,9 @@ namespace Kernel
|
||||
|
||||
private:
|
||||
SpinLock m_lock;
|
||||
SchedulerQueue::Node* m_block_chain { nullptr };
|
||||
|
||||
SchedulerQueue::Node* m_block_chain[32] {};
|
||||
size_t m_block_chain_length { 0 };
|
||||
|
||||
friend class Scheduler;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user