Fix Jenkins hang.
Summary: Jenkins would hang at a random time while running all the tests. The reason for that is a bug in skiplist implementation. Skiplist method find_or_larger was never ending and would continuously stay in the while loop because the next node (with the queried value) onto which it would try to jump would be marked as deleted and that would stop it from jumping on it, or ending on that node. Reviewers: buda, teon.banek, mislav.bradac Reviewed By: buda Subscribers: pullbot Differential Revision: https://phabricator.memgraph.io/D334
This commit is contained in:
parent
0a33a555a6
commit
b6c26a1a86
@ -794,8 +794,11 @@ class SkipList : private Lockable<lock_t> {
|
||||
int h = static_cast<int>(pred->height) - 1;
|
||||
|
||||
while (true) {
|
||||
// try to descend down first the next key on this layer overshoots
|
||||
for (; h >= 0 && less(item, node = pred->forward(h)); --h) {
|
||||
// try to descend down first while the next key on this layer overshoots
|
||||
// or the next key is marked for deletion
|
||||
for (; h >= 0 && (less(item, node = pred->forward(h)) ||
|
||||
(node && node->flags.is_marked()));
|
||||
--h) {
|
||||
}
|
||||
|
||||
// if we overshoot at every layer, item doesn't exist
|
||||
|
37
tests/concurrent/sl_hang.cpp
Normal file
37
tests/concurrent/sl_hang.cpp
Normal file
@ -0,0 +1,37 @@
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
#include "data_structures/concurrent/skiplist.hpp"
|
||||
|
||||
// Try to provoke find_or_larger to hang. This happened before and caused
|
||||
// Jenkins to stop responding. It is hard to recreate deterministically and this
|
||||
// is the best we can do without doing friend_tests or refactoring skiplist.
|
||||
TEST(SkipList, HangDuringFindOrLarger) {
|
||||
std::vector<std::thread> threads;
|
||||
SkipList<int> skiplist;
|
||||
const int num_of_threads = 8;
|
||||
const int iter = 100000;
|
||||
for (int i = 0; i < num_of_threads; ++i) {
|
||||
threads.emplace_back([&iter, &skiplist]() {
|
||||
auto accessor = skiplist.access();
|
||||
for (int i = 0; i < iter; ++i) accessor.insert(rand() % 3);
|
||||
});
|
||||
threads.emplace_back([&iter, &skiplist]() {
|
||||
auto accessor = skiplist.access();
|
||||
for (int i = 0; i < iter; ++i) accessor.remove(rand() % 3);
|
||||
});
|
||||
threads.emplace_back([&iter, &skiplist]() {
|
||||
auto accessor = skiplist.access();
|
||||
for (int i = 0; i < iter; ++i)
|
||||
accessor.find_or_larger<SkipList<int>::ConstIterator>(rand() % 3);
|
||||
});
|
||||
}
|
||||
for (auto &thread : threads) thread.join();
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
Loading…
Reference in New Issue
Block a user