Kernel: Fix race condition when blocking threads

If thread was blocked, but had not reached block queue, you might
already get an unblock request which would fail on an assertion.

If blocked thread was load balanced to another processor and unblocked
simultaneously, there was a race condition.
This commit is contained in:
Bananymous 2024-08-05 16:58:10 +03:00
parent e72424e01a
commit 0a7c316ffb
1 changed files with 7 additions and 2 deletions

View File

@ -330,10 +330,12 @@ namespace Kernel
{ {
if (!node->blocked) if (!node->blocked)
return; return;
if (node != m_current)
m_block_queue.remove_node(node); m_block_queue.remove_node(node);
if (node->blocker) if (node->blocker)
node->blocker->remove_blocked_thread(node); node->blocker->remove_blocked_thread(node);
node->blocked = false; node->blocked = false;
if (node != m_current)
m_run_queue.add_thread_to_back(node); m_run_queue.add_thread_to_back(node);
} }
else else
@ -467,6 +469,9 @@ namespace Kernel
break; break;
if (thread_info.node == m_current || thread_info.queue == nullptr) if (thread_info.node == m_current || thread_info.queue == nullptr)
continue; continue;
// FIXME: allow load balancing with blocked threads, with this algorithm there is a race condition
if (thread_info.node->blocked)
continue;
auto least_loaded_id = find_least_loaded_processor(); auto least_loaded_id = find_least_loaded_processor();
if (least_loaded_id == Processor::current_id()) if (least_loaded_id == Processor::current_id())