9 #ifndef LIBPMEMOBJ_CPP_CONDVARIABLE_HPP
10 #define LIBPMEMOBJ_CPP_CONDVARIABLE_HPP
13 #include <condition_variable>
17 #include <libpmemobj/thread.h>
36 typedef std::chrono::system_clock clock_type;
51 if ((pop = pmemobj_pool_by_ptr(&pcond)) ==
nullptr)
53 1, std::generic_category(),
54 "Persistent condition variable not from persistent memory.");
56 pmemobj_cond_zero(pop, &pcond);
75 PMEMobjpool *pop = pmemobj_pool_by_ptr(
this);
76 if (
int ret = pmemobj_cond_signal(pop, &this->pcond))
77 throw detail::exception_with_errormsg<lock_error>(
78 ret, std::system_category(),
79 "Error notifying one on a condition variable.");
90 PMEMobjpool *pop = pmemobj_pool_by_ptr(
this);
91 if (
int ret = pmemobj_cond_broadcast(pop, &this->pcond))
92 throw detail::exception_with_errormsg<lock_error>(
93 ret, std::system_category(),
94 "Error notifying all on a condition variable.");
115 this->wait_impl(lock);
135 template <
typename Lock>
139 this->wait_impl(*lock.mutex());
161 template <
typename Predicate>
165 this->wait_impl(lock, std::move(pred));
189 template <
typename Lock,
typename Predicate>
191 wait(Lock &lock, Predicate pred)
193 this->wait_impl(*lock.mutex(), std::move(pred));
217 template <
typename Clock,
typename Duration>
220 const std::chrono::time_point<Clock, Duration> &timeout)
222 return this->wait_until_impl(lock, timeout);
248 template <
typename Lock,
typename Clock,
typename Duration>
251 const std::chrono::time_point<Clock, Duration> &timeout)
253 return this->wait_until_impl(*lock.mutex(), timeout);
278 template <
typename Clock,
typename Duration,
typename Predicate>
281 const std::chrono::time_point<Clock, Duration> &timeout,
284 return this->wait_until_impl(lock, timeout, std::move(pred));
311 template <
typename Lock,
typename Clock,
typename Duration,
315 const std::chrono::time_point<Clock, Duration> &timeout,
318 return this->wait_until_impl(*lock.mutex(), timeout,
345 template <
typename Lock,
typename Rep,
typename Period>
347 wait_for(Lock &lock,
const std::chrono::duration<Rep, Period> &rel_time)
349 return this->wait_until_impl(*lock.mutex(),
350 clock_type::now() + rel_time);
377 template <
typename Lock,
typename Rep,
typename Period,
380 wait_for(Lock &lock,
const std::chrono::duration<Rep, Period> &rel_time,
383 return this->wait_until_impl(*lock.mutex(),
384 clock_type::now() + rel_time,
409 template <
typename Rep,
typename Period>
412 const std::chrono::duration<Rep, Period> &rel_time)
414 return this->wait_until_impl(lock,
415 clock_type::now() + rel_time);
440 template <
typename Rep,
typename Period,
typename Predicate>
443 const std::chrono::duration<Rep, Period> &rel_time,
446 return this->wait_until_impl(lock, clock_type::now() + rel_time,
476 wait_impl(
mutex &lock)
478 PMEMobjpool *pop = pmemobj_pool_by_ptr(
this);
479 if (
int ret = pmemobj_cond_wait(pop, &this->pcond,
481 throw detail::exception_with_errormsg<lock_error>(
482 ret, std::system_category(),
483 "Error waiting on a condition variable.");
489 template <
typename Predicate>
491 wait_impl(
mutex &lock, Predicate pred)
500 template <
typename Clock,
typename Duration>
504 const std::chrono::time_point<Clock, Duration> &abs_timeout)
506 PMEMobjpool *pop = pmemobj_pool_by_ptr(
this);
509 const typename Clock::time_point their_now = Clock::now();
510 const clock_type::time_point my_now = clock_type::now();
511 const auto delta = abs_timeout - their_now;
512 const auto my_rel = my_now + delta;
516 auto ret = pmemobj_cond_timedwait(pop, &this->pcond,
517 lock.native_handle(), &ts);
520 return std::cv_status::no_timeout;
521 else if (ret == ETIMEDOUT)
522 return std::cv_status::timeout;
524 throw detail::exception_with_errormsg<lock_error>(
525 ret, std::system_category(),
526 "Error waiting on a condition variable.");
532 template <
typename Clock,
typename Duration,
typename Predicate>
536 const std::chrono::time_point<Clock, Duration> &abs_timeout,
540 if (this->wait_until_impl(lock, abs_timeout) ==
541 std::cv_status::timeout)
Custom lock error class.
Definition: pexceptions.hpp:121
Persistent memory resident condition variable.
Definition: condition_variable.hpp:35
~condition_variable()=default
Defaulted destructor.
void wait(Lock &lock, Predicate pred)
Makes the current thread block until the condition variable is notified.
Definition: condition_variable.hpp:191
condition_variable & operator=(const condition_variable &)=delete
Deleted assignment operator.
condition_variable(const condition_variable &)=delete
Deleted copy constructor.
condition_variable()
Default constructor.
Definition: condition_variable.hpp:48
native_handle_type native_handle() noexcept
Access a native handle to this condition variable.
Definition: condition_variable.hpp:456
PMEMcond * native_handle_type
The handle typedef to the underlying basic type.
Definition: condition_variable.hpp:40
bool wait_for(Lock &lock, const std::chrono::duration< Rep, Period > &rel_time, Predicate pred)
Makes the current thread block until the condition variable is notified or the specified amount of ti...
Definition: condition_variable.hpp:380
std::cv_status wait_for(Lock &lock, const std::chrono::duration< Rep, Period > &rel_time)
Makes the current thread block until the condition variable is notified, the specified amount of time...
Definition: condition_variable.hpp:347
bool wait_for(mutex &lock, const std::chrono::duration< Rep, Period > &rel_time, Predicate pred)
Makes the current thread block until the condition variable is notified or the specified amount of ti...
Definition: condition_variable.hpp:442
void notify_all()
Notify and unblock all threads waiting on *this condition.
Definition: condition_variable.hpp:88
std::cv_status wait_until(Lock &lock, const std::chrono::time_point< Clock, Duration > &timeout)
Makes the current thread block until the condition variable is notified, a specific time is reached o...
Definition: condition_variable.hpp:250
bool wait_until(mutex &lock, const std::chrono::time_point< Clock, Duration > &timeout, Predicate pred)
Makes the current thread block until the condition variable is notified or a specific time is reached...
Definition: condition_variable.hpp:280
void wait(mutex &lock, Predicate pred)
Makes the current thread block until the condition variable is notified.
Definition: condition_variable.hpp:163
std::cv_status wait_for(mutex &lock, const std::chrono::duration< Rep, Period > &rel_time)
Makes the current thread block until the condition variable is notified, the specified amount of time...
Definition: condition_variable.hpp:411
void notify_one()
Notify and unblock one thread waiting on *this condition.
Definition: condition_variable.hpp:73
void wait(Lock &lock)
Makes the current thread block until the condition variable is notified or it is woken up by some oth...
Definition: condition_variable.hpp:137
void wait(mutex &lock)
Makes the current thread block until the condition variable is notified or it is woken up by some oth...
Definition: condition_variable.hpp:113
bool wait_until(Lock &lock, const std::chrono::time_point< Clock, Duration > &timeout, Predicate pred)
Makes the current thread block until the condition variable is notified or a specific time is reached...
Definition: condition_variable.hpp:314
std::cv_status wait_until(mutex &lock, const std::chrono::time_point< Clock, Duration > &timeout)
Makes the current thread block until the condition variable is notified, a specific time is reached o...
Definition: condition_variable.hpp:219
Persistent memory resident mutex implementation.
Definition: mutex.hpp:33
native_handle_type native_handle() noexcept
Access a native handle to this condition variable.
Definition: mutex.hpp:134
Commonly used conversions.
timespec timepoint_to_timespec(const std::chrono::time_point< Clock, Duration > &timepoint)
Convert std::chrono::time_point to posix timespec.
Definition: conversions.hpp:30
Persistent memory namespace.
Definition: allocation_flag.hpp:15