PMDK C++ bindings 1.13.0
This is the C++ bindings documentation for PMDK's libpmemobj.
Loading...
Searching...
No Matches
condition_variable.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: BSD-3-Clause
2/* Copyright 2016-2020, Intel Corporation */
3
9#ifndef LIBPMEMOBJ_CPP_CONDVARIABLE_HPP
10#define LIBPMEMOBJ_CPP_CONDVARIABLE_HPP
11
12#include <chrono>
13#include <condition_variable>
14
17#include <libpmemobj/thread.h>
18
19namespace pmem
20{
21
22namespace obj
23{
24
34 typedef std::chrono::system_clock clock_type;
35
36public:
38 typedef PMEMcond *native_handle_type;
39
47 {
48 PMEMobjpool *pop;
49 if ((pop = pmemobj_pool_by_ptr(&pcond)) == nullptr)
50 throw pmem::lock_error(
51 1, std::generic_category(),
52 "Persistent condition variable not from persistent memory.");
53
54 pmemobj_cond_zero(pop, &pcond);
55 }
56
61
70 void
72 {
73 PMEMobjpool *pop = pmemobj_pool_by_ptr(this);
74 if (int ret = pmemobj_cond_signal(pop, &this->pcond))
75 throw pmem::lock_error(
76 ret, std::system_category(),
77 "Error notifying one on a condition variable.")
78 .with_pmemobj_errormsg();
79 }
80
86 void
88 {
89 PMEMobjpool *pop = pmemobj_pool_by_ptr(this);
90 if (int ret = pmemobj_cond_broadcast(pop, &this->pcond))
91 throw pmem::lock_error(
92 ret, std::system_category(),
93 "Error notifying all on a condition variable.")
94 .with_pmemobj_errormsg();
95 }
96
112 void
113 wait(mutex &lock)
114 {
115 this->wait_impl(lock);
116 }
117
135 template <typename Lock>
136 void
137 wait(Lock &lock)
138 {
139 this->wait_impl(*lock.mutex());
140 }
141
161 template <typename Predicate>
162 void
163 wait(mutex &lock, Predicate pred)
164 {
165 this->wait_impl(lock, std::move(pred));
166 }
167
189 template <typename Lock, typename Predicate>
190 void
191 wait(Lock &lock, Predicate pred)
192 {
193 this->wait_impl(*lock.mutex(), std::move(pred));
194 }
195
217 template <typename Clock, typename Duration>
218 std::cv_status
220 const std::chrono::time_point<Clock, Duration> &timeout)
221 {
222 return this->wait_until_impl(lock, timeout);
223 }
224
248 template <typename Lock, typename Clock, typename Duration>
249 std::cv_status
250 wait_until(Lock &lock,
251 const std::chrono::time_point<Clock, Duration> &timeout)
252 {
253 return this->wait_until_impl(*lock.mutex(), timeout);
254 }
255
278 template <typename Clock, typename Duration, typename Predicate>
279 bool
281 const std::chrono::time_point<Clock, Duration> &timeout,
282 Predicate pred)
283 {
284 return this->wait_until_impl(lock, timeout, std::move(pred));
285 }
286
311 template <typename Lock, typename Clock, typename Duration,
312 typename Predicate>
313 bool
314 wait_until(Lock &lock,
315 const std::chrono::time_point<Clock, Duration> &timeout,
316 Predicate pred)
317 {
318 return this->wait_until_impl(*lock.mutex(), timeout,
319 std::move(pred));
320 }
321
345 template <typename Lock, typename Rep, typename Period>
346 std::cv_status
347 wait_for(Lock &lock, const std::chrono::duration<Rep, Period> &rel_time)
348 {
349 return this->wait_until_impl(*lock.mutex(),
350 clock_type::now() + rel_time);
351 }
352
377 template <typename Lock, typename Rep, typename Period,
378 typename Predicate>
379 bool
380 wait_for(Lock &lock, const std::chrono::duration<Rep, Period> &rel_time,
381 Predicate pred)
382 {
383 return this->wait_until_impl(*lock.mutex(),
384 clock_type::now() + rel_time,
385 std::move(pred));
386 }
387
409 template <typename Rep, typename Period>
410 std::cv_status
412 const std::chrono::duration<Rep, Period> &rel_time)
413 {
414 return this->wait_until_impl(lock,
415 clock_type::now() + rel_time);
416 }
417
440 template <typename Rep, typename Period, typename Predicate>
441 bool
443 const std::chrono::duration<Rep, Period> &rel_time,
444 Predicate pred)
445 {
446 return this->wait_until_impl(lock, clock_type::now() + rel_time,
447 std::move(pred));
448 }
449
456 native_handle() noexcept
457 {
458 return &this->pcond;
459 }
460
465
470
471private:
475 void
477 {
478 PMEMobjpool *pop = pmemobj_pool_by_ptr(this);
479 if (int ret = pmemobj_cond_wait(pop, &this->pcond,
480 lock.native_handle()))
481 throw pmem::lock_error(
482 ret, std::system_category(),
483 "Error waiting on a condition variable.")
484 .with_pmemobj_errormsg();
485 }
486
490 template <typename Predicate>
491 void
492 wait_impl(mutex &lock, Predicate pred)
493 {
494 while (!pred())
495 this->wait(lock);
496 }
497
501 template <typename Clock, typename Duration>
502 std::cv_status
504 mutex &lock,
505 const std::chrono::time_point<Clock, Duration> &abs_timeout)
506 {
507 PMEMobjpool *pop = pmemobj_pool_by_ptr(this);
508
509 /* convert to my clock */
510 const typename Clock::time_point their_now = Clock::now();
511 const clock_type::time_point my_now = clock_type::now();
512 const auto delta = abs_timeout - their_now;
513 const auto my_rel = my_now + delta;
514
515 struct timespec ts = detail::timepoint_to_timespec(my_rel);
516
517 auto ret = pmemobj_cond_timedwait(pop, &this->pcond,
518 lock.native_handle(), &ts);
519
520 if (ret == 0)
521 return std::cv_status::no_timeout;
522 else if (ret == ETIMEDOUT)
523 return std::cv_status::timeout;
524 else
525 throw pmem::lock_error(
526 ret, std::system_category(),
527 "Error waiting on a condition variable.")
528 .with_pmemobj_errormsg();
529 }
530
534 template <typename Clock, typename Duration, typename Predicate>
535 bool
537 mutex &lock,
538 const std::chrono::time_point<Clock, Duration> &abs_timeout,
539 Predicate pred)
540 {
541 while (!pred())
542 if (this->wait_until_impl(lock, abs_timeout) ==
543 std::cv_status::timeout)
544 return pred();
545 return true;
546 }
547
549 PMEMcond pcond;
550};
551
552} /* namespace obj */
553
554} /* namespace pmem */
555
556#endif /* LIBPMEMOBJ_CPP_CONDVARIABLE_HPP */
Custom lock error class.
Definition: pexceptions.hpp:100
Persistent memory resident condition variable.
Definition: condition_variable.hpp:33
~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(const condition_variable &)=delete
Deleted copy constructor.
PMEMcond pcond
A POSIX style PMEM-resident condition variable.
Definition: condition_variable.hpp:549
void wait_impl(mutex &lock, Predicate pred)
Internal implementation of the wait call.
Definition: condition_variable.hpp:492
condition_variable()
Default constructor.
Definition: condition_variable.hpp:46
native_handle_type native_handle() noexcept
Access a native handle to this condition variable.
Definition: condition_variable.hpp:456
bool wait_until_impl(mutex &lock, const std::chrono::time_point< Clock, Duration > &abs_timeout, Predicate pred)
Internal implementation of the wait_until call.
Definition: condition_variable.hpp:536
PMEMcond * native_handle_type
The handle typedef to the underlying basic type.
Definition: condition_variable.hpp:38
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:87
condition_variable & operator=(const condition_variable &)=delete
Deleted assignment operator.
std::cv_status wait_until_impl(mutex &lock, const std::chrono::time_point< Clock, Duration > &abs_timeout)
Internal implementation of the wait_until call.
Definition: condition_variable.hpp:503
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:71
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
void wait_impl(mutex &lock)
Internal implementation of the wait call.
Definition: condition_variable.hpp:476
Persistent memory resident mutex implementation.
Definition: mutex.hpp:31
native_handle_type native_handle() noexcept
Access a native handle to this condition variable.
Definition: mutex.hpp:132
Commonly used conversions.
Pmem-resident mutex.
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