Get rid of skiplist multimap, for now it's a bit broken

This commit is contained in:
2024-04-14 12:44:52 +02:00
parent 99a3b66439
commit 4e7989e2a9
3 changed files with 215 additions and 63 deletions

View File

@@ -56,7 +56,7 @@ List<List<Task *>::Node *> TasksToFree;
// Waiting // Waiting
Mutex WaitingTasks_mlock; Mutex WaitingTasks_mlock;
CV WaitingTasks_cv; CV WaitingTasks_cv;
SkipListMultiMap<uint64_t, List<Task *>::Node *> WaitingTasks; SkipListMap<uint64_t, Vector<List<Task *>::Node *>> WaitingTasks;
static std::atomic<bool> initialized = false; static std::atomic<bool> initialized = false;
@@ -218,7 +218,10 @@ void Scheduler::sleep_self(uint64_t diff) {
{ {
WaitingTasks_mlock.lock(); WaitingTasks_mlock.lock();
assert(cur_task() != nullptr); 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<List<Task *>::Node *>{extract_running_task_node()})));
Scheduler::self_block(WaitingTasks_mlock); Scheduler::self_block(WaitingTasks_mlock);
} }
} }
@@ -235,15 +238,26 @@ static void task_waker() {
{ {
WaitingTasks_mlock.lock(); WaitingTasks_mlock.lock();
while (WaitingTasks.begin() != WaitingTasks.end() && WaitingTasks.begin()->first <= micros && WaitingTasks.begin()->second->val->state() != Task::TaskState::TS_RUNNING) { while (WaitingTasks.begin() != WaitingTasks.end() && WaitingTasks.begin()->first <= micros) {
auto node = WaitingTasks.begin(); 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<List<Task *>::Node *> to_wake = std::move(tasks);
WaitingTasks.erase(node); WaitingTasks.erase(node);
WaitingTasks_mlock.unlock(); WaitingTasks_mlock.unlock();
for (auto &task: to_wake) {
task->val->_sleep_until = 0; task->val->_sleep_until = 0;
task->val->_state = Task::TaskState::TS_RUNNING; task->val->_state = Task::TaskState::TS_RUNNING;
@@ -251,6 +265,7 @@ static void task_waker() {
SpinlockLockNoInt l(NextTasks_lock); SpinlockLockNoInt l(NextTasks_lock);
NextTasks.emplace_front(task); NextTasks.emplace_front(task);
} }
}
WaitingTasks_mlock.lock(); WaitingTasks_mlock.lock();
} }

View File

@@ -587,8 +587,8 @@ public:
template<typename K, typename V, typename CmpBase = std::less<K>> template<typename K, typename V, typename CmpBase = std::less<K>>
using SkipListMap = SkipListMapBase<false, K, V, CmpBase>; using SkipListMap = SkipListMapBase<false, K, V, CmpBase>;
//FIXME: erase is probably janky with this //FIXME: erase is janky with this
template<typename K, typename V, typename CmpBase = std::less<K>> // template<typename K, typename V, typename CmpBase = std::less<K>>
using SkipListMultiMap = SkipListMapBase<true, K, V, CmpBase>; // using SkipListMultiMap = SkipListMapBase<true, K, V, CmpBase>;
#endif #endif

View File

@@ -40,51 +40,188 @@ TYPED_TEST(SkipListTestFixture, PlaceAdd) {
test1.emplace(78, "test78"); test1.emplace(78, "test78");
ASSERT_EQ(test1.find(78)->second, "test78"); ASSERT_EQ(test1.find(78)->second, "test78");
} }
TYPED_TEST(SkipListTestFixture, MultiMapTest) { // TYPED_TEST(SkipListTestFixture, MultiMapTest) {
SkipListMultiMap<int, TypeParam> test1; // SkipListMultiMap<int, TypeParam> test1;
//
test1.emplace(5, "test5"); // test1.emplace(5, "test5");
test1.emplace(999, "test999"); // test1.emplace(999, "test999");
test1.emplace(5, "test5"); // test1.emplace(5, "test5");
test1.emplace(1, "test1"); // test1.emplace(1, "test1");
test1.emplace(999, "test999"); // test1.emplace(999, "test999");
//
ASSERT_EQ(test1.find(5)->second, "test5"); // ASSERT_EQ(test1.find(5)->second, "test5");
ASSERT_EQ(test1.find(1)->second, "test1"); // ASSERT_EQ(test1.find(1)->second, "test1");
ASSERT_EQ(test1.find(999)->second, "test999"); // ASSERT_EQ(test1.find(999)->second, "test999");
//
test1.erase(1); // test1.erase(1);
ASSERT_EQ(test1.find(1), test1.cend()); // ASSERT_EQ(test1.find(1), test1.cend());
test1.emplace(87, "test87"); // test1.emplace(87, "test87");
ASSERT_EQ(test1.find(87)->second, "test87"); // ASSERT_EQ(test1.find(87)->second, "test87");
//
test1.emplace(78, "test78"); // test1.emplace(78, "test78");
ASSERT_EQ(test1.find(78)->second, "test78"); // ASSERT_EQ(test1.find(78)->second, "test78");
//
ASSERT_EQ(test1.find(5)->second, "test5"); // ASSERT_EQ(test1.find(5)->second, "test5");
ASSERT_EQ(test1.find(999)->second, "test999"); // ASSERT_EQ(test1.find(999)->second, "test999");
test1.erase(5); // test1.erase(5);
test1.erase(999); // test1.erase(999);
ASSERT_EQ(test1.find(5)->second, "test5"); // ASSERT_EQ(test1.find(5)->second, "test5");
ASSERT_EQ(test1.find(999)->second, "test999"); // ASSERT_EQ(test1.find(999)->second, "test999");
test1.erase(5); // test1.erase(5);
test1.erase(999); // test1.erase(999);
ASSERT_EQ(test1.find(5), test1.end()); // ASSERT_EQ(test1.find(5), test1.end());
ASSERT_EQ(test1.find(999), test1.end()); // ASSERT_EQ(test1.find(999), test1.end());
//
auto r1 = test1.emplace(999, "test9991"); // auto r1 = test1.emplace(999, "test9991");
ASSERT_TRUE(r1.second); // ASSERT_TRUE(r1.second);
ASSERT_EQ(r1.first->second, "test9991"); // ASSERT_EQ(r1.first->second, "test9991");
auto r2 = test1.emplace(999, "test9992"); // auto r2 = test1.emplace(999, "test9992");
ASSERT_TRUE(r2.second); // ASSERT_TRUE(r2.second);
ASSERT_EQ(r2.first->second, "test9992"); // ASSERT_EQ(r2.first->second, "test9992");
auto r3 = test1.emplace(999, "test9993"); // auto r3 = test1.emplace(999, "test9993");
ASSERT_TRUE(r3.second); // ASSERT_TRUE(r3.second);
ASSERT_EQ(r3.first->second, "test9993"); // ASSERT_EQ(r3.first->second, "test9993");
//
test1.erase(r2.first); // test1.erase(r2.first);
ASSERT_TRUE(r1.second); // ASSERT_TRUE(r1.second);
ASSERT_EQ(r1.first->second, "test9991"); // ASSERT_EQ(r1.first->second, "test9991");
ASSERT_TRUE(r3.second); // ASSERT_TRUE(r3.second);
ASSERT_EQ(r3.first->second, "test9993"); // ASSERT_EQ(r3.first->second, "test9993");
} // }
//
// TYPED_TEST(SkipListTestFixture, MultiMapEraseTest) {
// SkipListMultiMap<int, TypeParam> 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());
// }
// }