Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <mutex>
- // using std::mutex, std::unique_lock
- #include <condition_variable>
- // using std::condition_variable
- #include <future>
- // using std::async, std::future
- #include <stdexcept>
- // using std::invalid_argument
- #include <array>
- // using std::array
- namespace {
- class barrier
- {
- std::mutex mutex;
- int sequence_no, count;
- const int total_count;
- std::condition_variable condition;
- public:
- explicit barrier(int total_count)
- : sequence_no(), count(), total_count(total_count)
- {
- if(total_count < 1)
- throw std::invalid_argument("barrier(total_count < 1)");
- }
- void wait()
- {
- std::unique_lock<std::mutex> lock(mutex);
- if(! count) {
- /* we are the first thread to arrive here. Let's set up the barrier */
- ++sequence_no;
- count = total_count;
- }
- if(--count) {
- const int own_seq_no = sequence_no;
- auto is_complete = [own_seq_no, this]() noexcept -> bool {
- return this->count == 0 || this->sequence_no != own_seq_no;
- };
- condition.wait(lock, is_complete);
- }
- else {
- # ifdef WAKE_AFTER
- lock.unlock();
- # endif
- condition.notify_all();
- }
- }
- };
- void threadfun(barrier* shared_barrier, int iterations)
- {
- for(int i = 0; i < iterations; ++i)
- shared_barrier->wait();
- }
- }
- int main()
- {
- const int iterations = 1000;
- constexpr int threads = 16;
- std::array<std::future<void>, threads> futures;
- barrier shared_barrier(threads);
- for(std::future<void>& future: futures)
- future = std::async(std::launch::async, threadfun, &shared_barrier,
- iterations);
- for(std::future<void>& future: futures)
- future.get();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement