Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:29:53

0001 #ifndef BOOST_COMPAT_LATCH_HPP_INCLUDED
0002 #define BOOST_COMPAT_LATCH_HPP_INCLUDED
0003 
0004 // Copyright 2023 Peter Dimov.
0005 // Copyright 2023 Christian Mazakas.
0006 // Distributed under the Boost Software License, Version 1.0.
0007 // https://www.boost.org/LICENSE_1_0.txt
0008 
0009 #include <boost/assert.hpp>
0010 
0011 #include <climits>
0012 #include <condition_variable>
0013 #include <mutex>
0014 
0015 namespace boost
0016 {
0017 namespace compat
0018 {
0019 
0020 class latch {
0021 private:
0022   std::ptrdiff_t n_;
0023   mutable std::mutex m_;
0024   mutable std::condition_variable cv_;
0025 
0026 public:
0027   explicit latch(std::ptrdiff_t expected) : n_{expected}, m_{}, cv_{} {
0028     BOOST_ASSERT(n_ >= 0);
0029     BOOST_ASSERT(n_ <= max());
0030   }
0031 
0032   latch(latch const &) = delete;
0033   latch &operator=(latch const &) = delete;
0034 
0035   ~latch() = default;
0036 
0037   void count_down(std::ptrdiff_t n = 1) {
0038     std::unique_lock<std::mutex> lk(m_);
0039     count_down_and_notify(lk, n);
0040   }
0041 
0042   bool try_wait() const noexcept {
0043     std::unique_lock<std::mutex> lk(m_);
0044     return is_ready();
0045   }
0046 
0047   void wait() const {
0048     std::unique_lock<std::mutex> lk(m_);
0049     wait_impl(lk);
0050   }
0051 
0052   void arrive_and_wait(std::ptrdiff_t n = 1) {
0053     std::unique_lock<std::mutex> lk(m_);
0054     bool should_wait = count_down_and_notify(lk, n);
0055     if (should_wait) {
0056       wait_impl(lk);
0057     }
0058   }
0059 
0060   static constexpr std::ptrdiff_t max() noexcept { return PTRDIFF_MAX; }
0061 
0062 private:
0063   bool is_ready() const { return n_ == 0; }
0064 
0065   bool count_down_and_notify(std::unique_lock<std::mutex> &lk,
0066                              std::ptrdiff_t n) {
0067     BOOST_ASSERT(n <= n_);
0068     n_ -= n;
0069     if (n_ == 0) {
0070       lk.unlock();
0071       cv_.notify_all();
0072       return false;
0073     }
0074 
0075     return true;
0076   }
0077 
0078   void wait_impl(std::unique_lock<std::mutex> &lk) const {
0079     cv_.wait(lk, [this] { return this->is_ready(); });
0080   }
0081 };
0082 
0083 } // namespace compat
0084 } // namespace boost
0085 
0086 #endif // #ifndef BOOST_COMPAT_LATCH_HPP_INCLUDED