From 4e7989e2a9ea04b40e55a98274d4e2b147e8b34b Mon Sep 17 00:00:00 2001 From: Stepan Usatiuk Date: Sun, 14 Apr 2024 12:44:52 +0200 Subject: [PATCH] Get rid of skiplist multimap, for now it's a bit broken --- src/arch/x86/task.cpp | 39 ++-- src/kernel/templates/SkipList.hpp | 6 +- src/unit-tests/templates/SkipListTest.cpp | 233 +++++++++++++++++----- 3 files changed, 215 insertions(+), 63 deletions(-) diff --git a/src/arch/x86/task.cpp b/src/arch/x86/task.cpp index 761a393d6..c5194d47f 100644 --- a/src/arch/x86/task.cpp +++ b/src/arch/x86/task.cpp @@ -54,9 +54,9 @@ CV TasksToFree_cv; List::Node *> TasksToFree; // Waiting -Mutex WaitingTasks_mlock; -CV WaitingTasks_cv; -SkipListMultiMap::Node *> WaitingTasks; +Mutex WaitingTasks_mlock; +CV WaitingTasks_cv; +SkipListMap::Node *>> WaitingTasks; static std::atomic initialized = false; @@ -218,7 +218,10 @@ void Scheduler::sleep_self(uint64_t diff) { { WaitingTasks_mlock.lock(); assert(cur_task() != nullptr); - WaitingTasks.emplace(wake_time, extract_running_task_node()); + if (auto found = WaitingTasks.find(wake_time); found != WaitingTasks.end()) + found->second.emplace_back(extract_running_task_node()); + else + WaitingTasks.emplace(std::make_pair(wake_time, std::move(Vector::Node *>{extract_running_task_node()}))); Scheduler::self_block(WaitingTasks_mlock); } } @@ -235,21 +238,33 @@ static void task_waker() { { WaitingTasks_mlock.lock(); - while (WaitingTasks.begin() != WaitingTasks.end() && WaitingTasks.begin()->first <= micros && WaitingTasks.begin()->second->val->state() != Task::TaskState::TS_RUNNING) { - auto node = WaitingTasks.begin(); + while (WaitingTasks.begin() != WaitingTasks.end() && WaitingTasks.begin()->first <= micros) { + auto node = WaitingTasks.begin(); + auto tasks = node->second; - auto task = node->second; + bool ok = true; + for (const auto &task: tasks) { + if (task->val->state() == Task::TaskState::TS_RUNNING) { + ok = false; + break; + } + } + if (!ok) break; + + Vector::Node *> to_wake = std::move(tasks); WaitingTasks.erase(node); WaitingTasks_mlock.unlock(); - task->val->_sleep_until = 0; - task->val->_state = Task::TaskState::TS_RUNNING; + for (auto &task: to_wake) { + task->val->_sleep_until = 0; + task->val->_state = Task::TaskState::TS_RUNNING; - { - SpinlockLockNoInt l(NextTasks_lock); - NextTasks.emplace_front(task); + { + SpinlockLockNoInt l(NextTasks_lock); + NextTasks.emplace_front(task); + } } WaitingTasks_mlock.lock(); diff --git a/src/kernel/templates/SkipList.hpp b/src/kernel/templates/SkipList.hpp index 3d42225f0..fd423f4f4 100644 --- a/src/kernel/templates/SkipList.hpp +++ b/src/kernel/templates/SkipList.hpp @@ -587,8 +587,8 @@ public: template> using SkipListMap = SkipListMapBase; -//FIXME: erase is probably janky with this -template> -using SkipListMultiMap = SkipListMapBase; +//FIXME: erase is janky with this +// template> +// using SkipListMultiMap = SkipListMapBase; #endif \ No newline at end of file diff --git a/src/unit-tests/templates/SkipListTest.cpp b/src/unit-tests/templates/SkipListTest.cpp index 543765c64..5883df55d 100644 --- a/src/unit-tests/templates/SkipListTest.cpp +++ b/src/unit-tests/templates/SkipListTest.cpp @@ -40,51 +40,188 @@ TYPED_TEST(SkipListTestFixture, PlaceAdd) { test1.emplace(78, "test78"); ASSERT_EQ(test1.find(78)->second, "test78"); } -TYPED_TEST(SkipListTestFixture, MultiMapTest) { - SkipListMultiMap test1; - - test1.emplace(5, "test5"); - test1.emplace(999, "test999"); - test1.emplace(5, "test5"); - test1.emplace(1, "test1"); - test1.emplace(999, "test999"); - - ASSERT_EQ(test1.find(5)->second, "test5"); - ASSERT_EQ(test1.find(1)->second, "test1"); - ASSERT_EQ(test1.find(999)->second, "test999"); - - test1.erase(1); - ASSERT_EQ(test1.find(1), test1.cend()); - test1.emplace(87, "test87"); - ASSERT_EQ(test1.find(87)->second, "test87"); - - test1.emplace(78, "test78"); - ASSERT_EQ(test1.find(78)->second, "test78"); - - ASSERT_EQ(test1.find(5)->second, "test5"); - ASSERT_EQ(test1.find(999)->second, "test999"); - test1.erase(5); - test1.erase(999); - ASSERT_EQ(test1.find(5)->second, "test5"); - ASSERT_EQ(test1.find(999)->second, "test999"); - test1.erase(5); - test1.erase(999); - ASSERT_EQ(test1.find(5), test1.end()); - ASSERT_EQ(test1.find(999), test1.end()); - - auto r1 = test1.emplace(999, "test9991"); - ASSERT_TRUE(r1.second); - ASSERT_EQ(r1.first->second, "test9991"); - auto r2 = test1.emplace(999, "test9992"); - ASSERT_TRUE(r2.second); - ASSERT_EQ(r2.first->second, "test9992"); - auto r3 = test1.emplace(999, "test9993"); - ASSERT_TRUE(r3.second); - ASSERT_EQ(r3.first->second, "test9993"); - - test1.erase(r2.first); - ASSERT_TRUE(r1.second); - ASSERT_EQ(r1.first->second, "test9991"); - ASSERT_TRUE(r3.second); - ASSERT_EQ(r3.first->second, "test9993"); -} +// TYPED_TEST(SkipListTestFixture, MultiMapTest) { +// SkipListMultiMap test1; +// +// test1.emplace(5, "test5"); +// test1.emplace(999, "test999"); +// test1.emplace(5, "test5"); +// test1.emplace(1, "test1"); +// test1.emplace(999, "test999"); +// +// ASSERT_EQ(test1.find(5)->second, "test5"); +// ASSERT_EQ(test1.find(1)->second, "test1"); +// ASSERT_EQ(test1.find(999)->second, "test999"); +// +// test1.erase(1); +// ASSERT_EQ(test1.find(1), test1.cend()); +// test1.emplace(87, "test87"); +// ASSERT_EQ(test1.find(87)->second, "test87"); +// +// test1.emplace(78, "test78"); +// ASSERT_EQ(test1.find(78)->second, "test78"); +// +// ASSERT_EQ(test1.find(5)->second, "test5"); +// ASSERT_EQ(test1.find(999)->second, "test999"); +// test1.erase(5); +// test1.erase(999); +// ASSERT_EQ(test1.find(5)->second, "test5"); +// ASSERT_EQ(test1.find(999)->second, "test999"); +// test1.erase(5); +// test1.erase(999); +// ASSERT_EQ(test1.find(5), test1.end()); +// ASSERT_EQ(test1.find(999), test1.end()); +// +// auto r1 = test1.emplace(999, "test9991"); +// ASSERT_TRUE(r1.second); +// ASSERT_EQ(r1.first->second, "test9991"); +// auto r2 = test1.emplace(999, "test9992"); +// ASSERT_TRUE(r2.second); +// ASSERT_EQ(r2.first->second, "test9992"); +// auto r3 = test1.emplace(999, "test9993"); +// ASSERT_TRUE(r3.second); +// ASSERT_EQ(r3.first->second, "test9993"); +// +// test1.erase(r2.first); +// ASSERT_TRUE(r1.second); +// ASSERT_EQ(r1.first->second, "test9991"); +// ASSERT_TRUE(r3.second); +// ASSERT_EQ(r3.first->second, "test9993"); +// } +// +// TYPED_TEST(SkipListTestFixture, MultiMapEraseTest) { +// SkipListMultiMap test1; +// +// test1.emplace(5, "test5"); +// test1.emplace(999, "test999"); +// test1.emplace(5, "test5"); +// test1.emplace(1, "test1"); +// test1.emplace(999, "test999"); +// +// ASSERT_EQ(test1.find(5)->second, "test5"); +// ASSERT_EQ(test1.find(1)->second, "test1"); +// ASSERT_EQ(test1.find(999)->second, "test999"); +// +// test1.erase(1); +// ASSERT_EQ(test1.find(1), test1.cend()); +// test1.emplace(87, "test87"); +// ASSERT_EQ(test1.find(87)->second, "test87"); +// +// test1.emplace(78, "test78"); +// ASSERT_EQ(test1.find(78)->second, "test78"); +// +// ASSERT_EQ(test1.find(5)->second, "test5"); +// ASSERT_EQ(test1.find(999)->second, "test999"); +// test1.erase(5); +// test1.erase(999); +// ASSERT_EQ(test1.find(5)->second, "test5"); +// ASSERT_EQ(test1.find(999)->second, "test999"); +// test1.erase(5); +// test1.erase(999); +// ASSERT_EQ(test1.find(5), test1.end()); +// ASSERT_EQ(test1.find(999), test1.end()); +// +// { +// auto r1 = test1.emplace(999, "test9991"); +// ASSERT_TRUE(r1.second); +// ASSERT_EQ(r1.first->second, "test9991"); +// auto r2 = test1.emplace(999, "test9992"); +// ASSERT_TRUE(r2.second); +// ASSERT_EQ(r2.first->second, "test9992"); +// auto r3 = test1.emplace(999, "test9993"); +// ASSERT_TRUE(r3.second); +// ASSERT_EQ(r3.first->second, "test9993"); +// +// test1.erase(r2.first); +// ASSERT_TRUE(r1.second); +// ASSERT_EQ(r1.first->second, "test9991"); +// ASSERT_TRUE(r3.second); +// ASSERT_EQ(r3.first->second, "test9993"); +// } +// test1.emplace(5, "test5"); +// test1.emplace(999, "test999"); +// test1.emplace(5, "test5"); +// test1.emplace(1, "test1"); +// test1.emplace(999, "test999"); +// { +// auto r1 = test1.emplace(500, "t"); +// ASSERT_TRUE(r1.second); +// ASSERT_EQ(r1.first->second, "t"); +// auto r2 = test1.emplace(500, "t"); +// ASSERT_TRUE(r2.second); +// ASSERT_EQ(r2.first->second, "t"); +// auto r3 = test1.emplace(500, "t"); +// ASSERT_TRUE(r3.second); +// ASSERT_EQ(r3.first->second, "t"); +// +// test1.erase(r2.first); +// ASSERT_EQ(r1.first->second, "t"); +// ASSERT_EQ(r3.first->second, "t"); +// test1.erase(r3.first); +// ASSERT_EQ(r1.first->second, "t"); +// ASSERT_EQ(test1.find(500), r1.first); +// test1.erase(r1.first); +// ASSERT_EQ(test1.find(500), test1.end()); +// } +// { +// auto r1 = test1.emplace(500, "t"); +// ASSERT_TRUE(r1.second); +// ASSERT_EQ(r1.first->second, "t"); +// auto r2 = test1.emplace(500, "t"); +// ASSERT_TRUE(r2.second); +// ASSERT_EQ(r2.first->second, "t"); +// auto r3 = test1.emplace(500, "t"); +// ASSERT_TRUE(r3.second); +// ASSERT_EQ(r3.first->second, "t"); +// +// test1.erase(r2.first); +// ASSERT_EQ(r1.first->second, "t"); +// ASSERT_EQ(r3.first->second, "t"); +// test1.erase(r1.first); +// ASSERT_EQ(r3.first->second, "t"); +// ASSERT_EQ(test1.find(500), r3.first); +// test1.erase(r3.first); +// ASSERT_EQ(test1.find(500), test1.end()); +// } +// +// { +// auto r1 = test1.emplace(500, "t"); +// ASSERT_TRUE(r1.second); +// ASSERT_EQ(r1.first->second, "t"); +// auto r2 = test1.emplace(500, "t"); +// ASSERT_TRUE(r2.second); +// ASSERT_EQ(r2.first->second, "t"); +// auto r3 = test1.emplace(500, "t"); +// ASSERT_TRUE(r3.second); +// ASSERT_EQ(r3.first->second, "t"); +// +// test1.erase(r1.first); +// ASSERT_EQ(r2.first->second, "t"); +// ASSERT_EQ(r3.first->second, "t"); +// test1.erase(r2.first); +// ASSERT_EQ(r3.first->second, "t"); +// ASSERT_EQ(test1.find(500), r3.first); +// test1.erase(r3.first); +// ASSERT_EQ(test1.find(500), test1.end()); +// } +// { +// auto r1 = test1.emplace(500, "t"); +// ASSERT_TRUE(r1.second); +// ASSERT_EQ(r1.first->second, "t"); +// auto r2 = test1.emplace(500, "t"); +// ASSERT_TRUE(r2.second); +// ASSERT_EQ(r2.first->second, "t"); +// auto r3 = test1.emplace(500, "t"); +// ASSERT_TRUE(r3.second); +// ASSERT_EQ(r3.first->second, "t"); +// +// test1.erase(r3.first); +// ASSERT_EQ(r1.first->second, "t"); +// ASSERT_EQ(r2.first->second, "t"); +// test1.erase(r1.first); +// ASSERT_EQ(r2.first->second, "t"); +// ASSERT_EQ(test1.find(500), r2.first); +// test1.erase(r2.first); +// ASSERT_EQ(test1.find(500), test1.end()); +// } +// }