]> git.proxmox.com Git - ceph.git/blame - ceph/src/common/condition_variable_debug.h
import quincy beta 17.1.0
[ceph.git] / ceph / src / common / condition_variable_debug.h
CommitLineData
11fdf7f2
TL
1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2// vim: ts=8 sw=2 smarttab
3
4#pragma once
5
6#include <condition_variable>
7#include <ctime>
8#include <pthread.h>
9#include "common/ceph_time.h"
10
11namespace ceph {
12
13namespace mutex_debug_detail {
14 template<bool> class mutex_debug_impl;
15}
16
17class condition_variable_debug {
18 using mutex_debug = mutex_debug_detail::mutex_debug_impl<false>;
19
20 pthread_cond_t cond;
21 mutex_debug* waiter_mutex;
22
23 condition_variable_debug&
24 operator=(const condition_variable_debug&) = delete;
25 condition_variable_debug(const condition_variable_debug&) = delete;
26
27public:
28 condition_variable_debug();
29 ~condition_variable_debug();
30 void wait(std::unique_lock<mutex_debug>& lock);
31 template<class Predicate>
32 void wait(std::unique_lock<mutex_debug>& lock, Predicate pred) {
33 while (!pred()) {
34 wait(lock);
35 }
36 }
37 template<class Clock, class Duration>
38 std::cv_status wait_until(
39 std::unique_lock<mutex_debug>& lock,
40 const std::chrono::time_point<Clock, Duration>& when) {
20effc67
TL
41 if constexpr (Clock::is_steady) {
42 // convert from mono_clock to real_clock
43 auto real_when = ceph::real_clock::now();
44 const auto delta = when - Clock::now();
45 real_when += std::chrono::ceil<typename Clock::duration>(delta);
46 timespec ts = ceph::real_clock::to_timespec(real_when);
47 return _wait_until(lock.mutex(), &ts);
48 } else {
49 timespec ts = Clock::to_timespec(when);
50 return _wait_until(lock.mutex(), &ts);
51 }
11fdf7f2
TL
52 }
53 template<class Rep, class Period>
54 std::cv_status wait_for(
55 std::unique_lock<mutex_debug>& lock,
56 const std::chrono::duration<Rep, Period>& awhile) {
57 ceph::real_time when{ceph::real_clock::now()};
58 when += awhile;
59 timespec ts = ceph::real_clock::to_timespec(when);
60 return _wait_until(lock.mutex(), &ts);
61 }
9f95a23c
TL
62 template<class Rep, class Period, class Pred>
63 bool wait_for(
64 std::unique_lock<mutex_debug>& lock,
65 const std::chrono::duration<Rep, Period>& awhile,
66 Pred pred) {
67 ceph::real_time when{ceph::real_clock::now()};
68 when += awhile;
69 timespec ts = ceph::real_clock::to_timespec(when);
70 while (!pred()) {
71 if ( _wait_until(lock.mutex(), &ts) == std::cv_status::timeout) {
72 return pred();
73 }
74 }
75 return true;
76 }
11fdf7f2
TL
77 void notify_one();
78 void notify_all(bool sloppy = false);
79private:
80 std::cv_status _wait_until(mutex_debug* mutex, timespec* ts);
81};
82
83} // namespace ceph