Poseidon : Concurrency issues in chunked_vec.hpp::store() . [ and probably chunked_vec.hpp::erase() too ]
1) Issue: "Chunked_vec.hpp::store()" or "Chunked_vec.hpp::store_at()" and similar methods are not thread safe.
2) Line num : https://dbgit.prakinf.tu-ilmenau.de/code/poseidon_core/-/blob/null_values/src/storage/chunked_vec.hpp#L369
3) Scenario : Try to create node in two different threads/transactions.
4) How to reproduce the issue ?
Steps : Added the following Test case at beginning of "../../test/transaction_test.cpp" ( commented-out all remaining test cases)
TEST_CASE("Test two concurrent Txns by trying to create node" "[transaction]") {
#ifdef USE_PMDK
auto pop = prepare_pool();
auto gdb = create_graph_db(pop);
#else
auto gdb = create_graph_db();
#endif
node::id_t nid1 = 0,nid2 = 0;
// Thread 1: Add node
auto t1 = std::thread( [&] () {
auto tx = gdb->begin_transaction();
nid1 = gdb->add_node("New Actor",
{{"name", boost::any(std::string("Mark Wahlberg"))},
{"age", boost::any(48)}});
gdb->commit_transaction();
});
// Thread 2: concurrently add node
auto t2 = std::thread([&] () {
auto tx = gdb->begin_transaction();
nid2 = gdb->add_node("Actor",
{{"name", boost::any(std::string("Peter"))},
{"age", boost::any(22)}});
gdb->commit_transaction();
});
t1.join();
t2.join();
gdb->dump();
#ifdef USE_PMDK
drop_graph_db(pop, gdb);
#endif
} // Test case ends
5) Output : Below is a debug output
arth0746@dbpmem:~/06june_poseidon_test_concurr_issue/poseidon_core/build/test$ ./transaction_test
Txid: 1591470227122702065, Pos:0, Num chunks: 1,cap :18724 //<== Transaction-1 is assigned offset 0 in Pmem
Txid: 1591470227122702446, Pos:0, Num chunks: 2,cap :18724 //<== Transaction-2 is also assigned offset 0 in Pmem
transaction_test: /usr/local/include/libpmemobj++/container/vector.hpp:2150: void
pmem::obj::vector::construct_at_end(pmem::obj::vector::size_type, Args&& ...) [with Args = {const
pmem::obj::persistent_ptr<chunk<property_set, 16384> >&}; T = pmem::obj::persistent_ptr<chunk<property_set, 16384> >;
pmem::obj::vector::size_type = long unsigned int]: Assertion `_capacity >= count + _size' failed.
Aborted (core dumped)
6) Issue Description : From the above output we can see, At line https://dbgit.prakinf.tu-ilmenau.de/code/poseidon_core/-/blob/null_values/src/storage/chunked_vec.hpp#L385
1.Both Txn-1 and Txn-2, calls "offset_t pos = ch->first_available();" and gets same "offset_t pos: 0" for both nodes "New Actor" and "Actor".
2.Also both transactions creates a new chunk and thus 2 chunks are created (instead of one). A simple call to num_chunks() would give this information.
Finally, the program crashes with a "segmentation fault" arising from line : https://dbgit.prakinf.tu-ilmenau.de/code/poseidon_core/-/blob/null_values/src/storage/chunked_vec.hpp#L120
Is this Test case Wrong ? Please ignore the issue if wrong. Can't two or n-concurrent threads/transactions create nodes ?
7) Why running transaction_tests now ?
I found this issue while working on the currently assigned task "Design Strict 2-phase locking" and "A driver to evaluate con-Current Transactions" and this issue is blocking it.