diff --git a/app/playground/CMakeLists.txt b/app/playground/CMakeLists.txt index 6673f70..018b19b 100644 --- a/app/playground/CMakeLists.txt +++ b/app/playground/CMakeLists.txt @@ -1,4 +1,6 @@ -add_executable(playground main.cpp) +add_executable(playground + barrier.h barrier.cpp + main.cpp) # Example for adding the library to your app (as a cmake project dependency) -target_link_libraries(playground context_switcher) +target_link_libraries(playground context_switcher Threads::Threads) diff --git a/app/playground/barrier.cpp b/app/playground/barrier.cpp new file mode 100644 index 0000000..78b8ba2 --- /dev/null +++ b/app/playground/barrier.cpp @@ -0,0 +1,13 @@ +#include "barrier.h" + +barrier::barrier(const unsigned int count) : barrier_{} { + pthread_barrier_init(&barrier_, nullptr, count); +} + +barrier::~barrier() { + pthread_barrier_destroy(&barrier_); +} + +void barrier::wait() { + pthread_barrier_wait(&barrier_); +} diff --git a/app/playground/barrier.h b/app/playground/barrier.h new file mode 100644 index 0000000..88b5c0e --- /dev/null +++ b/app/playground/barrier.h @@ -0,0 +1,27 @@ + +#ifndef PLS_BARRIER_H +#define PLS_BARRIER_H + +#include + + +/** + * Provides standard barrier behaviour. + * `count` threads have to call `wait()` before any of the `wait()` calls returns, + * thus blocking all threads until everyone reached the barrier. + * + * PORTABILITY: + * Current implementation is based on pthreads. + */ +class barrier { + pthread_barrier_t barrier_; + + public: + explicit barrier(unsigned int count); + ~barrier(); + + void wait(); +}; + + +#endif //PLS_BARRIER_H diff --git a/app/playground/main.cpp b/app/playground/main.cpp index 74bfe91..93bf83f 100644 --- a/app/playground/main.cpp +++ b/app/playground/main.cpp @@ -1,7 +1,11 @@ #include #include +#include + +#include "barrier.h" #include "context_switcher/context_switcher.h" + using namespace context_switcher; using namespace std; @@ -10,17 +14,40 @@ const size_t STACK_SIZE = 512 * 32; const size_t NUM_STACKS = 4; char custom_stacks[NUM_STACKS][STACK_SIZE]; -volatile int result; - int main() { + context_switcher::continuation cont_t1, cont_main; + barrier bar{2}; + int error = 0; + + auto t1 = std::thread([&]() { + while (true) { + bar.wait(); + auto cont = enter_context(custom_stacks[0], STACK_SIZE, [&](continuation &&cont) { + error++; + cont_t1 = std::move(cont); + bar.wait(); + error++; + return std::move(cont_main); + }); + } + }); + + int count = 0; + while (true) { - context_switcher::continuation cont = enter_context(custom_stacks[0], STACK_SIZE, [](continuation &&main_cont) { -// main_cont = context_switcher::switch_context(std::move(main_cont)); - return std::move(main_cont); + count++; + if (count % 100 == 0) { + printf("%d\n", count); + } + bar.wait(); + auto cont = enter_context(custom_stacks[1], STACK_SIZE, [&](continuation &&cont) { + error++; + cont_main = std::move(cont); + bar.wait(); + error++; + return std::move(cont_t1); }); - -// cont = context_switcher::switch_context(std::move(cont)); - }; + } return 0; }