From 29c0e5a0d8b8cf05a79a65236d202f608e025267 Mon Sep 17 00:00:00 2001 From: John Jones Date: Tue, 22 Jan 2019 21:11:46 -0500 Subject: [PATCH] Test to demonstrate fc::mutex and fc::thread --- tests/thread/thread_tests.cpp | 64 +++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/tests/thread/thread_tests.cpp b/tests/thread/thread_tests.cpp index a1f3d1b47..222547196 100644 --- a/tests/thread/thread_tests.cpp +++ b/tests/thread/thread_tests.cpp @@ -2,6 +2,11 @@ #include #include +#include +#include +#include + +#include using namespace fc; @@ -92,4 +97,63 @@ BOOST_AUTO_TEST_CASE(reschedules_yielded_task) BOOST_CHECK_EQUAL(10, reschedule_count); } +/**** + * Attempt to have fc::threads use fc::mutex when yield() causes a context switch + */ +BOOST_AUTO_TEST_CASE( yield_with_mutex ) +{ + // set up thread pool + uint16_t num_threads = 5; + std::vector thread_collection; + for(uint16_t i = 0; i < num_threads; i++) + thread_collection.push_back(new fc::thread("My" + std::to_string(i))); + + // the function that will give a thread something to do + fc::mutex my_mutex; + volatile uint32_t my_mutable = 0; + auto my_func = ([&my_mutable, &my_mutex] () + { + // grab the mutex + my_mutex.lock(); + // get the prior value + uint32_t old_value = my_mutable; + // modify the value + my_mutable++; + // yield + fc::yield(); + // test to see if the mutex is recursive + my_mutex.lock(); + // return the value to the original + my_mutable--; + my_mutex.unlock(); + // verify the original still matches + if (old_value != my_mutable) + BOOST_FAIL("Values do not match"); + my_mutex.unlock(); + }); + + // the loop that gives threads the work + uint16_t thread_counter = 0; + uint32_t num_loops = 50000; + std::vector> futures(num_loops); + for(uint32_t i = 0; i < num_loops; ++i) + { + futures[i] = thread_collection[thread_counter]->async(my_func); + ++thread_counter; + if (thread_counter == num_threads) + thread_counter = 0; + } + + // now wait for each to finish + for(uint32_t i = 0; i < num_loops; ++i) + futures[i].wait(); + + // clean up the thread pointers + for(uint16_t i = 0; i < num_threads; i++) + delete thread_collection[i]; + + // verify that evertying worked + BOOST_CHECK_EQUAL(0u, my_mutable); +} + BOOST_AUTO_TEST_SUITE_END()