Tool made to test syncronization mechanisms in a deterministic way that does not rely on OS scheduler.
Tests should be deterministic and reproducible.
A simple C++ lib for testing syncronization mechanisms.
Concurrency testing often poses challenges due to the non-deterministic nature of threads and synchronization mechanisms. The DeterministicConcurrency library aims to address these challenges by providing tools to create and manage deterministic concurrency scenarios, enabling precise and reliable testing.
While primarily designed for testing, the UserControlledScheduler can also serve as a framework to create synchronized thread pool-like structures for broader multithread applications.
The assumptions are:
UserControlledSchedulerautomatically creates a number ofstd::threadsequal to the number of arguments you pass its constructor; thesethreadsare lazy and each one of them must be allowed to terminate by theUserControlledScheduler.- To allow a
threadto finish, theUserControlledSchedulermust allow thesethreadsto proceed until they are in ajoinablestate.
I build and tested this lib with C++17. If for some reason, on some compilers, it doesn`t work on C++17+ please email me or open an issue.
This is an header only library but you can build the main.cpp which contains a simple test using:
$ cmake . -B build -DDC_COMPILE_MAIN=ON -G Ninja$ cmake --build buildYou can also generate the build files to build the tests with:
$ cmake . -B build -DDC_COMPILE_TESTS=ON -G NinjaUsing cmake you can include this lib using:
include(FetchContent)
FetchContent_Declare(
dc
GIT_REPOSITORY https://github.com/Sernior/deterministic-concurrency.git
GIT_TAG [TAG] #change with the tag you want to use
)
FetchContent_MakeAvailable(dc)At this point you should be able to link the library simply using:
target_link_libraries(your_stuff.cpp deterministic_concurrency)This is a snippet ready-to-use.
#include <iostream>
#include <DeterministicConcurrency>
void your_function(DeterministicConcurrency::thread_context* c, uint32_t a, uint32_t b) {
std::cout << "I'm writing " << a << "!\n";
c->switchContext();
std::cout << "I'm writing " << b << "!\n";
}
int main()
{
auto thread_0 = std::tuple{&your_function, 0, 2};
auto thread_1 = std::tuple{&your_function, 1, 3};
auto sch = DeterministicConcurrency::make_UserControlledScheduler(
thread_0, thread_1
);
sch.switchContextTo(1);
sch.switchContextTo(0);
sch.switchContextTo(0);
sch.switchContextTo(1);
sch.joinAll();
}The output of the above will be:
I'm writing 1!
I'm writing 0!
I'm writing 2!
I'm writing 3!
If you encounter any issues or would like to suggest new features, please don't hesitate to open an issue or get in touch with me at federignoli@hotmail.it.
Contributions are also welcome! Feel free to open pull requests to the main repository and assign me as a reviewer – I'll be sure to review them. Your help is greatly appreciated!
Distributed under the MIT License. See LICENSE.txt for more information.
The documentation is available at the following link: https://sernior.github.io/deterministic-concurrency/
Federico Abrignani - federignoli@hotmail.it
- Federico Abrignani (Author) - https://github.com/Sernior
- Paolo Di Giglio (Contributor) - https://github.com/pdigiglio
- Salvatore Martorana (Contributor) - https://github.com/SMartorana