Skip to content

Instantly share code, notes, and snippets.

@cvtsi2sd
Created June 5, 2020 07:44
Show Gist options
  • Save cvtsi2sd/b9c534e6f447f35c781fc20deb3989b9 to your computer and use it in GitHub Desktop.
Save cvtsi2sd/b9c534e6f447f35c781fc20deb3989b9 to your computer and use it in GitHub Desktop.
#include <thread>
#include <mutex>
#include <condition_variable>
#include <stdio.h>
std::mutex mtx;
std::condition_variable cv;
// number of players
const int tot = 2;
// current turn
int turn = 0;
// moves done by each thread
int count[tot] = {};
// total moves
int tot_count = 0;
// total moves limit
const int limit = 100000;
void dump_status() {
printf("turn: %d\ncount[0]: %d\ncount[1]: %d\ntot_count: %d\n", turn, count[0], count[1], tot_count);
}
template<typename FnT>
void wait_or_die(int id, std::condition_variable &cv, std::unique_lock<std::mutex> &lk, FnT fn) {
const int timeout = 5;
if(!cv.wait_for(lk, std::chrono::seconds(timeout), fn)) {
printf("Wait expired in thread %d after %d seconds\nStatus dump:\n", id, timeout);
dump_status();
std::abort();
}
}
void thread_fn(int id) {
// initial sync - let in only who is at the right turn
{
std::unique_lock<std::mutex> lk(mtx);
while(turn != id) wait_or_die(id, cv, lk, [] { return true; });
}
for(;;) {
std::unique_lock<std::mutex> lk(mtx);
// "I was here"
count[id]++;
tot_count++;
// pass hand
turn = (turn + 1) % tot;
cv.notify_all();
// quit at the end
if(tot_count >= limit) break;
// wait for my turn
wait_or_die(id, cv, lk, [&] { return turn == id; });
}
}
int main() {
// play the game
std::thread thr(thread_fn, 1);
thread_fn(0);
// wait for exit
thr.join();
// summary
dump_status();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment