void synchronize(std::size_t generation_value, Lock& l, char const* function_name = "base_and_gate<>::synchronize", error_code& ec= throws) { HPX_ASSERT_OWNS_LOCK(l); if (generation_value < generation_) { HPX_THROWS_IF(ec, hpx::invalid_status, function_name, "sequencing error, generational counter too small"); return; } // make sure this set operation has not arrived ahead of time if (!test_condition(generation_value)) { conditional_trigger c; manage_condition cond(*this, c); future<void> f = cond.get_future(util::bind( &base_trigger::test_condition, this, generation_value)); { hpx::util::unlock_guard<Lock> ul(l); f.get(); } // make sure lock gets re-acquired } if (&ec != &throws) ec = make_success_code(); }
cv_status wait_until(std::unique_lock<mutex>& lock, util::steady_time_point const& abs_time, error_code& ec = throws) { HPX_ASSERT_OWNS_LOCK(lock); util::ignore_while_checking<std::unique_lock<mutex> > il(&lock); std::unique_lock<mutex_type> l(mtx_); util::unlock_guard<std::unique_lock<mutex> > unlock(lock); threads::thread_state_ex_enum const reason = cond_.wait_until(l, abs_time, ec); // We need to ignore our internal mutex for the user provided lock // being able to be reacquired without a lock held during suspension // error. We can't use RAII here since the guard object would get // destructed before the unlock_guard. hpx::util::ignore_lock(&mtx_); if (ec) return cv_status::error; // if the timer has hit, the waiting period timed out return (reason == threads::wait_timeout) ? //-V110 cv_status::timeout : cv_status::no_timeout; }
std::int64_t signal_all(std::unique_lock<mutex_type> l) { HPX_ASSERT_OWNS_LOCK(l); std::int64_t count = static_cast<std::int64_t>(cond_.size(l)); signal(std::move(l), count); return count; }
void wait(Lock& lock, Predicate pred, error_code& ec = throws) { HPX_ASSERT_OWNS_LOCK(lock); while (!pred()) { wait(lock); } }
void wait(std::unique_lock<mutex_type>& l, std::int64_t count) { HPX_ASSERT_OWNS_LOCK(l); while (value_ < count) { cond_.wait(l, "counting_semaphore::wait"); } value_ -= count; }
void wait(std::unique_lock<mutex>& lock, Predicate pred, error_code& ec = throws) { HPX_ASSERT_OWNS_LOCK(lock); while (!pred()) { wait(lock); } }
void wait(std::unique_lock<mutex>& lock, error_code& ec = throws) { HPX_ASSERT_OWNS_LOCK(lock); util::ignore_all_while_checking ignore_lock; std::unique_lock<mutex_type> l(mtx_); util::unlock_guard<std::unique_lock<mutex> > unlock(lock); cond_.wait(std::move(l), ec); }
bool try_wait(std::unique_lock<mutex_type>& l, std::int64_t count = 1) { HPX_ASSERT_OWNS_LOCK(l); if (!(value_ < count)) { // enter wait_locked only if there are sufficient credits // available wait(l, count); return true; } return false; }
bool wait_until(Lock& lock, util::steady_time_point const& abs_time, Predicate pred, error_code& ec = throws) { HPX_ASSERT_OWNS_LOCK(lock); while (!pred()) { if (wait_until(lock, abs_time, ec) == cv_status::timeout) return pred(); } return true; }
void wait(std::unique_lock<mutex>& lock, error_code& ec = throws) { HPX_ASSERT_OWNS_LOCK(lock); util::ignore_while_checking<std::unique_lock<mutex> > il(&lock); std::unique_lock<mutex_type> l(mtx_); util::unlock_guard<std::unique_lock<mutex> > unlock(lock); cond_.wait(l, ec); // We need to ignore our internal mutex for the user provided lock // being able to be reacquired without a lock held during suspension // error. We can't use RAII here since the guard object would get // destructed before the unlock_guard. hpx::util::ignore_lock(&mtx_); }
gid_type split_credits_for_gid_locked( std::unique_lock<gid_type::mutex_type>& l, gid_type& id) { HPX_ASSERT_OWNS_LOCK(l); std::uint16_t log2credits = get_log2credit_from_gid(id); HPX_ASSERT(log2credits > 0); gid_type newid = id; // strips lock-bit set_log2credit_for_gid(id, log2credits-1); set_credit_split_mask_for_gid(id); set_log2credit_for_gid(newid, log2credits-1); set_credit_split_mask_for_gid(newid); return newid; }
void signal(std::unique_lock<mutex_type> l, std::int64_t count) { HPX_ASSERT_OWNS_LOCK(l); mutex_type* mtx = l.mutex(); // release no more threads than we get resources value_ += count; for (std::int64_t i = 0; value_ >= 0 && i < count; ++i) { // notify_one() returns false if no more threads are // waiting if (!cond_.notify_one(std::move(l))) break; l = std::unique_lock<mutex_type>(*mtx); } }
cv_status wait_until(std::unique_lock<mutex>& lock, util::steady_time_point const& abs_time, error_code& ec = throws) { HPX_ASSERT_OWNS_LOCK(lock); util::ignore_all_while_checking ignore_lock; std::unique_lock<mutex_type> l(mtx_); util::unlock_guard<std::unique_lock<mutex> > unlock(lock); threads::thread_state_ex_enum const reason = cond_.wait_until(std::move(l), abs_time, ec); if (ec) return cv_status::error; // if the timer has hit, the waiting period timed out return (reason == threads::wait_timeout) ? //-V110 cv_status::timeout : cv_status::no_timeout; }