Fast RTPS  Version 2.14.1
Fast RTPS
Loading...
Searching...
No Matches
TimedConditionVariable.hpp
1// Copyright 2018 Proyectos y Sistemas de Mantenimiento SL (eProsima).
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
19#ifndef _UTILS_TIMEDCONDITIONVARIABLE_HPP_
20#define _UTILS_TIMEDCONDITIONVARIABLE_HPP_
21#include <fastrtps/config.h>
22
23/*
24 NOTE: Windows implementation temporary disabled due to aleatory high CPU consumption when
25 calling _Cnd_timedwait function, making some tests to fail and very poor performance.
26 Related task: #6274
27
28 #if HAVE_STRICT_REALTIME && defined(_WIN32)
29 #include <thr/xthreads.h>
30
31 #define CLOCK_REALTIME 0
32 #define CV_INIT_(x) _Cnd_init(x)
33 #define CV_WAIT_(cv, x) _Cnd_wait(cv, (_Mtx_t)x)
34 #define CV_TIMEDWAIT_(cv, x, y) _Cnd_timedwait(cv, (_Mtx_t)x, (xtime*)y)
35 #define CV_SIGNAL_(cv) _Cnd_signal(cv)
36 #define CV_BROADCAST_(cv) _Cnd_broadcast(cv)
37 #define CV_T_ _Cnd_t
38
39 extern int clock_gettime(int, struct timespec* tv);
40 #elif HAVE_STRICT_REALTIME && defined(__unix__)
41 */
42#if HAVE_STRICT_REALTIME && defined(__unix__)
43#include <pthread.h>
44
45#define CV_INIT_(x) pthread_condattr_init(&cv_attr_); \
46 pthread_condattr_setclock(&cv_attr_, CLOCK_MONOTONIC); \
47 pthread_cond_init(x, &cv_attr_);
48#define CV_WAIT_(cv, x) pthread_cond_wait(&cv, x)
49#define CV_TIMEDWAIT_(cv, x, y) pthread_cond_timedwait(&cv, x, y)
50#define CV_SIGNAL_(cv) pthread_cond_signal(&cv)
51#define CV_BROADCAST_(cv) pthread_cond_broadcast(&cv)
52#define CV_T_ pthread_condattr_t cv_attr_; pthread_cond_t
53#else
54#include <condition_variable>
55#endif // if HAVE_STRICT_REALTIME && defined(__unix__)
56
57#include <mutex>
58#include <condition_variable>
59#include <chrono>
60#include <functional>
61
62namespace eprosima {
63namespace fastrtps {
64
65#if HAVE_STRICT_REALTIME && (/*defined(_WIN32) ||*/ defined(__unix__))
66
68{
69public:
70
72 {
73 CV_INIT_(&cv_);
74 }
75
76 template<typename Mutex>
77 void wait(
78 std::unique_lock<Mutex>& lock,
79 std::function<bool()> predicate)
80 {
81 while (!predicate())
82 {
83 CV_WAIT_(cv_, lock.mutex()->native_handle());
84 }
85 }
86
87 template<typename Mutex>
88 void wait(
89 std::unique_lock<Mutex>& lock)
90 {
91 CV_WAIT_(cv_, lock.mutex()->native_handle());
92 }
93
94 template<typename Mutex>
95 bool wait_for(
96 std::unique_lock<Mutex>& lock,
97 const std::chrono::nanoseconds& max_blocking_time,
98 std::function<bool()> predicate)
99 {
100 bool ret_value = true;
101 auto nsecs = max_blocking_time;
102 struct timespec max_wait = {
103 0, 0
104 };
105 clock_gettime(CLOCK_MONOTONIC, &max_wait);
106 nsecs = nsecs + std::chrono::nanoseconds(max_wait.tv_nsec);
107 auto secs = std::chrono::duration_cast<std::chrono::seconds>(nsecs);
108 nsecs -= secs;
109 max_wait.tv_sec += secs.count();
110 max_wait.tv_nsec = (long)nsecs.count();
111 while (ret_value && false == (ret_value = predicate()))
112 {
113 ret_value = (0 == CV_TIMEDWAIT_(cv_, lock.mutex()->native_handle(), &max_wait));
114 }
115
116 return ret_value;
117 }
118
119 template<typename Mutex>
120 std::cv_status wait_for(
121 std::unique_lock<Mutex>& lock,
122 const std::chrono::nanoseconds& max_blocking_time)
123 {
124 auto nsecs = max_blocking_time;
125 struct timespec max_wait = {
126 0, 0
127 };
128 clock_gettime(CLOCK_MONOTONIC, &max_wait);
129 nsecs = nsecs + std::chrono::nanoseconds(max_wait.tv_nsec);
130 auto secs = std::chrono::duration_cast<std::chrono::seconds>(nsecs);
131 nsecs -= secs;
132 max_wait.tv_sec += secs.count();
133 max_wait.tv_nsec = (long)nsecs.count();
134 return (CV_TIMEDWAIT_(cv_, lock.mutex()->native_handle(),
135 &max_wait) == 0) ? std::cv_status::no_timeout : std::cv_status::timeout;
136 }
137
138 template<typename Mutex>
139 bool wait_until(
140 std::unique_lock<Mutex>& lock,
141 const std::chrono::steady_clock::time_point& max_blocking_time,
142 std::function<bool()> predicate)
143 {
144 auto secs = std::chrono::time_point_cast<std::chrono::seconds>(max_blocking_time);
145 auto ns = std::chrono::time_point_cast<std::chrono::nanoseconds>(max_blocking_time) -
146 std::chrono::time_point_cast<std::chrono::nanoseconds>(secs);
147 struct timespec max_wait = {
148 secs.time_since_epoch().count(), ns.count()
149 };
150 bool ret_value = true;
151 while (ret_value && false == (ret_value = predicate()))
152 {
153 ret_value = (CV_TIMEDWAIT_(cv_, lock.mutex()->native_handle(), &max_wait) == 0);
154 }
155
156 return ret_value;
157 }
158
159 template<typename Mutex>
160 std::cv_status wait_until(
161 std::unique_lock<Mutex>& lock,
162 const std::chrono::steady_clock::time_point& max_blocking_time)
163 {
164 auto secs = std::chrono::time_point_cast<std::chrono::seconds>(max_blocking_time);
165 auto ns = std::chrono::time_point_cast<std::chrono::nanoseconds>(max_blocking_time) -
166 std::chrono::time_point_cast<std::chrono::nanoseconds>(secs);
167 struct timespec max_wait = {
168 secs.time_since_epoch().count(), ns.count()
169 };
170 return (CV_TIMEDWAIT_(cv_, lock.mutex()->native_handle(),
171 &max_wait) == 0) ? std::cv_status::no_timeout : std::cv_status::timeout;
172 }
173
174 void notify_one()
175 {
176 CV_SIGNAL_(cv_);
177 }
178
179 void notify_all()
180 {
181 CV_BROADCAST_(cv_);
182 }
183
184private:
185
186 CV_T_ cv_;
187};
188#else
189using TimedConditionVariable = std::condition_variable_any;
190#endif // HAVE_STRICT_REALTIME && (/*defined(_WIN32)*/ || defined(__unix__))
191
192} // namespace fastrtps
193} // namespace eprosima
194
195#endif // _UTILS_TIMEDCONDITIONVARIABLE_HPP_
std::condition_variable_any TimedConditionVariable
Definition TimedConditionVariable.hpp:189
eProsima namespace.
Definition LibrarySettingsAttributes.h:23