1 | #ifdef _WIN32 |
2 | #include <windows.h> |
3 | #else |
4 | #include <sys/time.h> |
5 | #endif |
6 | |
7 | #include "boost/bind/bind.hpp" |
8 | #include "boost/chrono.hpp" |
9 | #include "boost/chrono/ceil.hpp" |
10 | #include "boost/date_time.hpp" |
11 | #include "boost/thread/concurrent_queues/sync_priority_queue.hpp" |
12 | #include "boost/thread/concurrent_queues/sync_timed_queue.hpp" |
13 | #include "boost/thread/future.hpp" |
14 | #include "boost/thread/mutex.hpp" |
15 | #include "boost/thread/recursive_mutex.hpp" |
16 | #include "boost/thread/shared_lock_guard.hpp" |
17 | #include "boost/thread/shared_mutex.hpp" |
18 | #include "boost/thread/thread.hpp" |
19 | |
20 | #include <iomanip> |
21 | #ifdef TEST_CPP14_FEATURES |
22 | #include <future> |
23 | #include <mutex> |
24 | #include <shared_mutex> |
25 | #include <thread> |
26 | #endif |
27 | |
28 | /******************************************************************************/ |
29 | |
30 | /* |
31 | * Summary: |
32 | * |
33 | * This code tests the behavior of time-related functions in the presence of |
34 | * system clock changes (jumps). It requires root/Administrator privileges in |
35 | * order to run because it changes the system clock. NTP should also be disabled |
36 | * while running this code so that NTP can't change the system clock. |
37 | * |
38 | * Each function to be tested is executed five times. The amount of time the |
39 | * function waits before returning is measured against the amount of time the |
40 | * function was expected to wait. If the difference exceeds a threshold value |
41 | * (defined below) then the test fails. |
42 | * |
43 | * The following values are intentially: |
44 | * - more than 200 milliseconds |
45 | * - more than 200 milliseconds apart |
46 | * - not a multiple of 100 milliseconds |
47 | * - not a multiple of each other |
48 | * - don't sum or diff to a multiple of 100 milliseconds |
49 | */ |
50 | const long long s_waitMs = 580; |
51 | const long long s_shortJumpMs = 230; |
52 | const long long s_longJumpMs = 870; // Causes additional, unavoidable failures when BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC is disabled |
53 | const long long s_sleepBeforeJumpMs = 110; |
54 | |
55 | #ifdef _WIN32 |
56 | const long long s_maxEarlyErrorMs = 10 |
57 | + 100; // Windows is unpredictable, especially in a VM, so allow extra time if the function returns early |
58 | const long long s_maxLateErrorMs = 110 // due to polling, functions may not return for up to 100 milliseconds after they are supposed to |
59 | + 100; // Windows is slow, especially in a VM, so allow extra time for the functions to return |
60 | #else |
61 | const long long s_maxEarlyErrorMs = 10; |
62 | const long long s_maxLateErrorMs = 110; // Due to polling, functions may not return for up to 100 milliseconds after they are supposed to |
63 | #endif |
64 | |
65 | int g_numTestsRun = 0; |
66 | int g_numTestsPassed = 0; |
67 | int g_numTestsFailed = 0; |
68 | |
69 | /******************************************************************************/ |
70 | |
71 | // A custom clock based off the system clock but with a different epoch. |
72 | |
73 | namespace custom |
74 | { |
75 | class custom_boost_clock |
76 | { |
77 | public: |
78 | typedef boost::chrono::microseconds duration; // intentionally not nanoseconds |
79 | typedef duration::rep rep; |
80 | typedef duration::period period; |
81 | typedef boost::chrono::time_point<custom_boost_clock> time_point; |
82 | static bool is_steady; |
83 | |
84 | static time_point now(); |
85 | }; |
86 | |
87 | bool custom_boost_clock::is_steady = false; |
88 | |
89 | custom_boost_clock::time_point custom_boost_clock::now() |
90 | { |
91 | return time_point(boost::chrono::ceil<duration>(d: boost::chrono::system_clock::now().time_since_epoch()) - boost::chrono::hours(10 * 365 * 24)); |
92 | } |
93 | |
94 | #ifdef TEST_CPP14_FEATURES |
95 | class custom_std_clock |
96 | { |
97 | public: |
98 | typedef std::chrono::microseconds duration; // intentionally not nanoseconds |
99 | typedef duration::rep rep; |
100 | typedef duration::period period; |
101 | typedef std::chrono::time_point<custom_std_clock> time_point; |
102 | static bool is_steady; |
103 | |
104 | static time_point now(); |
105 | }; |
106 | |
107 | bool custom_std_clock::is_steady = false; |
108 | |
109 | custom_std_clock::time_point custom_std_clock::now() |
110 | { |
111 | return time_point(std::chrono::duration_cast<duration>(std::chrono::system_clock::now().time_since_epoch()) - std::chrono::hours(10 * 365 * 24)); |
112 | } |
113 | #endif |
114 | } |
115 | |
116 | /******************************************************************************/ |
117 | |
118 | template <typename MutexType = boost::mutex, typename CondType = boost::condition_variable> |
119 | struct BoostHelper |
120 | { |
121 | typedef MutexType mutex; |
122 | typedef CondType cond; |
123 | |
124 | typedef boost::lock_guard<MutexType> lock_guard; |
125 | typedef boost::unique_lock<MutexType> unique_lock; |
126 | |
127 | typedef boost::chrono::milliseconds milliseconds; |
128 | typedef boost::chrono::nanoseconds nanoseconds; |
129 | |
130 | typedef boost::chrono::system_clock system_clock; |
131 | typedef boost::chrono::steady_clock steady_clock; |
132 | typedef custom::custom_boost_clock custom_clock; |
133 | |
134 | typedef system_clock::time_point system_time_point; |
135 | typedef steady_clock::time_point steady_time_point; |
136 | typedef custom_clock::time_point custom_time_point; |
137 | |
138 | typedef boost::cv_status cv_status; |
139 | typedef boost::future_status future_status; |
140 | |
141 | typedef boost::packaged_task<bool> packaged_task; |
142 | typedef boost::future<bool> future; |
143 | typedef boost::shared_future<bool> shared_future; |
144 | |
145 | typedef boost::thread thread; |
146 | |
147 | static const milliseconds waitDur; |
148 | |
149 | template <typename T> |
150 | static void sleep_for(T d) |
151 | { |
152 | boost::this_thread::sleep_for(d); |
153 | } |
154 | |
155 | template <typename T> |
156 | static void sleep_for_no_int(T d) |
157 | { |
158 | boost::this_thread::no_interruption_point::sleep_for(d); |
159 | } |
160 | |
161 | template <typename T> |
162 | static void sleep_until(T t) |
163 | { |
164 | boost::this_thread::sleep_until(t); |
165 | } |
166 | |
167 | template <typename T> |
168 | static void sleep_until_no_int(T t) |
169 | { |
170 | boost::this_thread::no_interruption_point::sleep_until(t); |
171 | } |
172 | |
173 | static system_time_point systemNow() |
174 | { |
175 | return system_clock::now(); |
176 | } |
177 | |
178 | static steady_time_point steadyNow() |
179 | { |
180 | return steady_clock::now(); |
181 | } |
182 | |
183 | static custom_time_point customNow() |
184 | { |
185 | return custom_clock::now(); |
186 | } |
187 | |
188 | template <class ToDuration, class Rep, class Period> |
189 | static ToDuration duration_cast(const boost::chrono::duration<Rep, Period>& d) |
190 | { |
191 | return boost::chrono::duration_cast<ToDuration>(d); |
192 | } |
193 | |
194 | static milliseconds zero() |
195 | { |
196 | return milliseconds(0); |
197 | } |
198 | }; |
199 | |
200 | template <typename MutexType, typename CondType> |
201 | const typename BoostHelper<MutexType, CondType>::milliseconds |
202 | BoostHelper<MutexType, CondType>::waitDur = typename BoostHelper<MutexType, CondType>::milliseconds(s_waitMs); |
203 | |
204 | #ifdef TEST_CPP14_FEATURES |
205 | template <typename MutexType = std::mutex, typename CondType = std::condition_variable> |
206 | struct StdHelper |
207 | { |
208 | typedef MutexType mutex; |
209 | typedef CondType cond; |
210 | |
211 | typedef std::lock_guard<MutexType> lock_guard; |
212 | typedef std::unique_lock<MutexType> unique_lock; |
213 | |
214 | typedef std::chrono::milliseconds milliseconds; |
215 | typedef std::chrono::nanoseconds nanoseconds; |
216 | |
217 | typedef std::chrono::system_clock system_clock; |
218 | typedef std::chrono::steady_clock steady_clock; |
219 | typedef custom::custom_std_clock custom_clock; |
220 | |
221 | typedef system_clock::time_point system_time_point; |
222 | typedef steady_clock::time_point steady_time_point; |
223 | typedef custom_clock::time_point custom_time_point; |
224 | |
225 | typedef std::cv_status cv_status; |
226 | typedef std::future_status future_status; |
227 | |
228 | typedef std::packaged_task<bool()> packaged_task; |
229 | typedef std::future<bool> future; |
230 | typedef std::shared_future<bool> shared_future; |
231 | |
232 | typedef std::thread thread; |
233 | |
234 | static const milliseconds waitDur; |
235 | |
236 | template <typename T> |
237 | static void sleep_for(T d) |
238 | { |
239 | std::this_thread::sleep_for(d); |
240 | } |
241 | |
242 | template <typename T> |
243 | static void sleep_until(T t) |
244 | { |
245 | std::this_thread::sleep_until(t); |
246 | } |
247 | |
248 | static system_time_point systemNow() |
249 | { |
250 | return system_clock::now(); |
251 | } |
252 | |
253 | static steady_time_point steadyNow() |
254 | { |
255 | return steady_clock::now(); |
256 | } |
257 | |
258 | static custom_time_point customNow() |
259 | { |
260 | return custom_clock::now(); |
261 | } |
262 | |
263 | template <class ToDuration, class Rep, class Period> |
264 | static ToDuration duration_cast(const std::chrono::duration<Rep, Period>& d) |
265 | { |
266 | return std::chrono::duration_cast<ToDuration>(d); |
267 | } |
268 | |
269 | static milliseconds zero() |
270 | { |
271 | return milliseconds(0); |
272 | } |
273 | }; |
274 | |
275 | template <typename MutexType, typename CondType> |
276 | const typename StdHelper<MutexType, CondType>::milliseconds |
277 | StdHelper<MutexType, CondType>::waitDur = typename StdHelper<MutexType, CondType>::milliseconds(s_waitMs); |
278 | #endif |
279 | |
280 | /******************************************************************************/ |
281 | |
282 | #ifdef _WIN32 |
283 | |
284 | void changeSystemTime(long long changeMs) |
285 | { |
286 | Sleep(s_sleepBeforeJumpMs); |
287 | |
288 | SYSTEMTIME systemTime; |
289 | GetSystemTime(&systemTime); |
290 | |
291 | FILETIME fileTime; |
292 | if (!SystemTimeToFileTime(&systemTime, &fileTime)) |
293 | { |
294 | std::cout << "ERROR: Couldn't convert system time to file time" << std::endl; |
295 | } |
296 | |
297 | ULARGE_INTEGER largeInt; |
298 | largeInt.LowPart = fileTime.dwLowDateTime; |
299 | largeInt.HighPart = fileTime.dwHighDateTime; |
300 | largeInt.QuadPart += changeMs * 10000; |
301 | fileTime.dwLowDateTime = largeInt.LowPart; |
302 | fileTime.dwHighDateTime = largeInt.HighPart; |
303 | |
304 | if (!FileTimeToSystemTime(&fileTime, &systemTime)) |
305 | { |
306 | std::cout << "ERROR: Couldn't convert file time to system time" << std::endl; |
307 | } |
308 | |
309 | if (!SetSystemTime(&systemTime)) |
310 | { |
311 | std::cout << "ERROR: Couldn't set system time" << std::endl; |
312 | } |
313 | } |
314 | |
315 | #else |
316 | |
317 | void changeSystemTime(long long changeMs) |
318 | { |
319 | struct timespec sleepTs; |
320 | sleepTs.tv_sec = (s_sleepBeforeJumpMs / 1000); |
321 | sleepTs.tv_nsec = (s_sleepBeforeJumpMs % 1000) * 1000000; |
322 | nanosleep(requested_time: &sleepTs, NULL); |
323 | |
324 | struct timeval tv; |
325 | if (gettimeofday(tv: &tv, NULL) != 0) |
326 | { |
327 | std::cout << "ERROR: Couldn't get system time" << std::endl; |
328 | } |
329 | |
330 | changeMs += tv.tv_sec * 1000; |
331 | changeMs += tv.tv_usec / 1000; |
332 | tv.tv_sec = (changeMs / 1000); |
333 | tv.tv_usec = (changeMs % 1000) * 1000; |
334 | |
335 | if (settimeofday(tv: &tv, NULL) != 0) |
336 | { |
337 | std::cout << "ERROR: Couldn't set system time" << std::endl; |
338 | } |
339 | } |
340 | |
341 | #endif |
342 | |
343 | enum RcEnum |
344 | { |
345 | e_no_timeout, |
346 | e_timeout, |
347 | e_failed_bad, |
348 | e_failed_good, |
349 | e_succeeded_bad, |
350 | e_succeeded_good, |
351 | e_ready_bad, |
352 | e_not_ready_good, |
353 | e_na |
354 | }; |
355 | |
356 | template <typename Helper> |
357 | void checkWaitTime(typename Helper::nanoseconds expected, typename Helper::nanoseconds actual, RcEnum rc) |
358 | { |
359 | if (expected != Helper::zero() && expected < typename Helper::milliseconds(s_sleepBeforeJumpMs)) |
360 | { |
361 | expected = typename Helper::milliseconds(s_sleepBeforeJumpMs); |
362 | } |
363 | |
364 | typename Helper::milliseconds expectedMs = Helper::template duration_cast<typename Helper::milliseconds>(expected); |
365 | typename Helper::milliseconds actualMs = Helper::template duration_cast<typename Helper::milliseconds>(actual); |
366 | |
367 | std::cout << "Expected: " << std::setw(4) << expectedMs.count() << " ms" |
368 | << ", Actual: " << std::setw(4) << actualMs.count() << " ms" |
369 | << ", Returned: " ; |
370 | switch (rc) |
371 | { |
372 | case e_no_timeout : std::cout << "no_timeout, " ; break; |
373 | case e_timeout : std::cout << "timeout, " ; break; |
374 | case e_failed_bad : std::cout << "failed, " ; break; |
375 | case e_failed_good : std::cout << "failed, " ; break; |
376 | case e_succeeded_bad : std::cout << "succeeded, " ; break; |
377 | case e_succeeded_good : std::cout << "succeeded, " ; break; |
378 | case e_ready_bad : std::cout << "ready, " ; break; |
379 | case e_not_ready_good : std::cout << "not_ready, " ; break; |
380 | default : std::cout << "N/A, " ; break; |
381 | } |
382 | |
383 | if (expectedMs == Helper::zero()) |
384 | { |
385 | std::cout << "FAILED: SKIPPED (test would lock up if run)" ; |
386 | g_numTestsFailed++; |
387 | } |
388 | else if (actual < expected - typename Helper::milliseconds(s_maxEarlyErrorMs)) |
389 | { |
390 | std::cout << "FAILED: TOO SHORT" ; |
391 | if (rc == e_timeout) // bad |
392 | { |
393 | std::cout << ", RETURNED TIMEOUT" ; |
394 | } |
395 | else if (rc == e_failed_bad) |
396 | { |
397 | std::cout << ", RETURNED FAILED" ; |
398 | } |
399 | else if (rc == e_succeeded_bad) |
400 | { |
401 | std::cout << ", RETURNED SUCCEEDED" ; |
402 | } |
403 | else if (rc == e_ready_bad) |
404 | { |
405 | std::cout << ", RETURNED READY" ; |
406 | } |
407 | g_numTestsFailed++; |
408 | } |
409 | else if (actual > expected + typename Helper::milliseconds(s_maxLateErrorMs)) |
410 | { |
411 | std::cout << "FAILED: TOO LONG" ; |
412 | if (rc == e_no_timeout) // bad |
413 | { |
414 | std::cout << ", RETURNED NO_TIMEOUT" ; |
415 | } |
416 | else if (rc == e_failed_bad) |
417 | { |
418 | std::cout << ", RETURNED FAILED" ; |
419 | } |
420 | else if (rc == e_succeeded_bad) |
421 | { |
422 | std::cout << ", RETURNED SUCCEEDED" ; |
423 | } |
424 | else if (rc == e_ready_bad) |
425 | { |
426 | std::cout << ", RETURNED READY" ; |
427 | } |
428 | g_numTestsFailed++; |
429 | } |
430 | else if (rc == e_no_timeout) // bad |
431 | { |
432 | std::cout << "FAILED: RETURNED NO_TIMEOUT" ; |
433 | g_numTestsFailed++; |
434 | } |
435 | else if (rc == e_failed_bad) |
436 | { |
437 | std::cout << "FAILED: RETURNED FAILED" ; |
438 | g_numTestsFailed++; |
439 | } |
440 | else if (rc == e_succeeded_bad) |
441 | { |
442 | std::cout << "FAILED: RETURNED SUCCEEDED" ; |
443 | g_numTestsFailed++; |
444 | } |
445 | else if (rc == e_ready_bad) |
446 | { |
447 | std::cout << "FAILED: RETURNED READY" ; |
448 | g_numTestsFailed++; |
449 | } |
450 | else |
451 | { |
452 | std::cout << "Passed" ; |
453 | g_numTestsPassed++; |
454 | } |
455 | std::cout << std::endl; |
456 | |
457 | g_numTestsRun++; |
458 | } |
459 | |
460 | void sleepForLongTime() |
461 | { |
462 | #ifdef _WIN32 |
463 | Sleep(10000); |
464 | #else |
465 | struct timespec ts = {.tv_sec: 5, .tv_nsec: 0}; |
466 | nanosleep(requested_time: &ts, NULL); |
467 | #endif |
468 | } |
469 | |
470 | bool returnFalse() |
471 | { |
472 | return false; |
473 | } |
474 | |
475 | /******************************************************************************/ |
476 | |
477 | // Run the test in the context provided, which may be the current thread or a separate thread. |
478 | template <typename Helper, typename Context, typename Function> |
479 | void runTestInContext(Context context, Function func, const std::string name) |
480 | { |
481 | std::cout << name << ":" << std::endl; |
482 | |
483 | { |
484 | std::cout << " While system clock remains stable: " ; |
485 | context(func, 0); |
486 | } |
487 | |
488 | { |
489 | std::cout << " While system clock jumps back (short): " ; |
490 | typename Helper::thread t(boost::bind(f: changeSystemTime, a1: -s_shortJumpMs)); |
491 | context(func, -s_shortJumpMs); |
492 | t.join(); |
493 | } |
494 | |
495 | { |
496 | std::cout << " While system clock jumps back (long): " ; |
497 | typename Helper::thread t(boost::bind(f: changeSystemTime, a1: -s_longJumpMs)); |
498 | context(func, -s_longJumpMs); |
499 | t.join(); |
500 | } |
501 | |
502 | { |
503 | std::cout << " While system clock jumps forward (short): " ; |
504 | typename Helper::thread t(boost::bind(f: changeSystemTime, a1: s_shortJumpMs)); |
505 | context(func, s_shortJumpMs); |
506 | t.join(); |
507 | } |
508 | |
509 | { |
510 | std::cout << " While system clock jumps forward (long): " ; |
511 | typename Helper::thread t(boost::bind(f: changeSystemTime, a1: s_longJumpMs)); |
512 | context(func, s_longJumpMs); |
513 | t.join(); |
514 | } |
515 | } |
516 | |
517 | //-------------------------------------- |
518 | |
519 | template <typename Helper, typename Function> |
520 | void noThreadContext(Function func, const long long jumpMs) |
521 | { |
522 | func(jumpMs); |
523 | } |
524 | |
525 | template <typename Helper, typename Function> |
526 | void threadContextWithNone(Function func, const long long jumpMs) |
527 | { |
528 | typename Helper::thread t(boost::bind(func, jumpMs)); |
529 | t.join(); |
530 | } |
531 | |
532 | template <typename Helper, typename Function> |
533 | void threadContextWithUnique(Function func, const long long jumpMs) |
534 | { |
535 | typename Helper::mutex m; |
536 | typename Helper::lock_guard g(m); |
537 | typename Helper::thread t(boost::bind(func, boost::ref(m), jumpMs)); |
538 | t.join(); |
539 | } |
540 | |
541 | template <typename Helper, typename Function> |
542 | void threadContextWithShared(Function func, const long long jumpMs) |
543 | { |
544 | typename Helper::mutex m; |
545 | boost::shared_lock_guard<typename Helper::mutex> g(m); |
546 | typename Helper::thread t(boost::bind(func, boost::ref(m), jumpMs)); |
547 | t.join(); |
548 | } |
549 | |
550 | template <typename Helper, typename Function> |
551 | void threadContextWithUpgrade(Function func, const long long jumpMs) |
552 | { |
553 | typename Helper::mutex m; |
554 | boost::upgrade_lock<typename Helper::mutex> g(m); |
555 | typename Helper::thread t(boost::bind(func, boost::ref(m), jumpMs)); |
556 | t.join(); |
557 | } |
558 | |
559 | //-------------------------------------- |
560 | |
561 | // Run the test in the current thread. |
562 | template <typename Helper, typename Function> |
563 | void runTest(Function func, const std::string name) |
564 | { |
565 | runTestInContext<Helper>(noThreadContext<Helper, Function>, func, name); |
566 | } |
567 | |
568 | // Run the test in a separate thread. |
569 | template <typename Helper, typename Function> |
570 | void runTestWithNone(Function func, const std::string name) |
571 | { |
572 | runTestInContext<Helper>(threadContextWithNone<Helper, Function>, func, name); |
573 | } |
574 | |
575 | // Run the test in a separate thread. Pass a locked mutex to the function under test. |
576 | template <typename Helper, typename Function> |
577 | void runTestWithUnique(Function func, const std::string name) |
578 | { |
579 | runTestInContext<Helper>(threadContextWithUnique<Helper, Function>, func, name); |
580 | } |
581 | |
582 | // Run the test in a separate thread. Pass a shared-locked mutex to the function under test. |
583 | template <typename Helper, typename Function> |
584 | void runTestWithShared(Function func, const std::string name) |
585 | { |
586 | runTestInContext<Helper>(threadContextWithShared<Helper, Function>, func, name); |
587 | } |
588 | |
589 | // Run the test in a separate thread. Pass an upgrade-locked mutex to the function under test. |
590 | template <typename Helper, typename Function> |
591 | void runTestWithUpgrade(Function func, const std::string name) |
592 | { |
593 | runTestInContext<Helper>(threadContextWithUpgrade<Helper, Function>, func, name); |
594 | } |
595 | |
596 | /******************************************************************************/ |
597 | |
598 | // Test Sleep |
599 | |
600 | template <typename Helper> |
601 | void testSleepFor(const long long jumpMs) |
602 | { |
603 | typename Helper::steady_time_point before(Helper::steadyNow()); |
604 | Helper::sleep_for(Helper::waitDur); |
605 | typename Helper::steady_time_point after(Helper::steadyNow()); |
606 | |
607 | checkWaitTime<Helper>(Helper::waitDur, after - before, e_na); |
608 | } |
609 | |
610 | template <typename Helper> |
611 | void testSleepUntilSteady(const long long jumpMs) |
612 | { |
613 | typename Helper::steady_time_point before(Helper::steadyNow()); |
614 | Helper::sleep_until(Helper::steadyNow() + Helper::waitDur); |
615 | typename Helper::steady_time_point after(Helper::steadyNow()); |
616 | |
617 | checkWaitTime<Helper>(Helper::waitDur, after - before, e_na); |
618 | } |
619 | |
620 | template <typename Helper> |
621 | void testSleepUntilSystem(const long long jumpMs) |
622 | { |
623 | typename Helper::steady_time_point before(Helper::steadyNow()); |
624 | Helper::sleep_until(Helper::systemNow() + Helper::waitDur); |
625 | typename Helper::steady_time_point after(Helper::steadyNow()); |
626 | |
627 | checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, e_na); |
628 | } |
629 | |
630 | template <typename Helper> |
631 | void testSleepUntilCustom(const long long jumpMs) |
632 | { |
633 | typename Helper::steady_time_point before(Helper::steadyNow()); |
634 | Helper::sleep_until(Helper::customNow() + Helper::waitDur); |
635 | typename Helper::steady_time_point after(Helper::steadyNow()); |
636 | |
637 | checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, e_na); |
638 | } |
639 | |
640 | //-------------------------------------- |
641 | |
642 | template <typename Helper> |
643 | void testSleepRelative(const long long jumpMs) |
644 | { |
645 | #ifndef SKIP_DATETIME_FUNCTIONS |
646 | typename Helper::steady_time_point before(Helper::steadyNow()); |
647 | boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count()); |
648 | boost::this_thread::sleep(rel_time: ptDur); |
649 | typename Helper::steady_time_point after(Helper::steadyNow()); |
650 | |
651 | checkWaitTime<Helper>(Helper::waitDur, after - before, e_na); |
652 | #else |
653 | checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na); |
654 | #endif |
655 | } |
656 | |
657 | template <typename Helper> |
658 | void testSleepAbsolute(const long long jumpMs) |
659 | { |
660 | #ifndef SKIP_DATETIME_FUNCTIONS |
661 | typename Helper::steady_time_point before(Helper::steadyNow()); |
662 | boost::posix_time::ptime ptNow(boost::posix_time::microsec_clock::universal_time()); |
663 | boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count()); |
664 | boost::this_thread::sleep(abs_time: ptNow + ptDur); |
665 | typename Helper::steady_time_point after(Helper::steadyNow()); |
666 | |
667 | checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, e_na); |
668 | #else |
669 | checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na); |
670 | #endif |
671 | } |
672 | |
673 | //-------------------------------------- |
674 | |
675 | template <typename Helper> |
676 | void testSleepStd(const std::string& name) |
677 | { |
678 | std::cout << std::endl; |
679 | runTestWithNone<Helper>(testSleepFor <Helper>, name + "::this_thread::sleep_for()" ); |
680 | runTestWithNone<Helper>(testSleepUntilSteady<Helper>, name + "::this_thread::sleep_until(), steady time" ); |
681 | runTestWithNone<Helper>(testSleepUntilSystem<Helper>, name + "::this_thread::sleep_until(), system time" ); |
682 | runTestWithNone<Helper>(testSleepUntilCustom<Helper>, name + "::this_thread::sleep_until(), custom time" ); |
683 | } |
684 | |
685 | template <typename Helper> |
686 | void testSleepBoost(const std::string& name) |
687 | { |
688 | testSleepStd<Helper>(name); |
689 | |
690 | // Boost-only functions |
691 | runTestWithNone<Helper>(testSleepRelative<Helper>, name + "::this_thread::sleep(), relative time" ); |
692 | runTestWithNone<Helper>(testSleepAbsolute<Helper>, name + "::this_thread::sleep(), absolute time" ); |
693 | } |
694 | |
695 | template <typename Helper> |
696 | void testSleepNoThreadStd(const std::string& name) |
697 | { |
698 | std::cout << std::endl; |
699 | runTest<Helper>(testSleepFor <Helper>, name + "::this_thread::sleep_for(), no thread" ); |
700 | runTest<Helper>(testSleepUntilSteady<Helper>, name + "::this_thread::sleep_until(), no thread, steady time" ); |
701 | runTest<Helper>(testSleepUntilSystem<Helper>, name + "::this_thread::sleep_until(), no thread, system time" ); |
702 | runTest<Helper>(testSleepUntilCustom<Helper>, name + "::this_thread::sleep_until(), no thread, custom time" ); |
703 | } |
704 | |
705 | template <typename Helper> |
706 | void testSleepNoThreadBoost(const std::string& name) |
707 | { |
708 | testSleepNoThreadStd<Helper>(name); |
709 | |
710 | // Boost-only functions |
711 | runTest<Helper>(testSleepRelative<Helper>, name + "::this_thread::sleep(), no thread, relative time" ); |
712 | runTest<Helper>(testSleepAbsolute<Helper>, name + "::this_thread::sleep(), no thread, absolute time" ); |
713 | } |
714 | |
715 | /******************************************************************************/ |
716 | |
717 | // Test Sleep, No Interruption Point |
718 | |
719 | template <typename Helper> |
720 | void testSleepForNoInt(const long long jumpMs) |
721 | { |
722 | typename Helper::steady_time_point before(Helper::steadyNow()); |
723 | Helper::sleep_for_no_int(Helper::waitDur); |
724 | typename Helper::steady_time_point after(Helper::steadyNow()); |
725 | |
726 | checkWaitTime<Helper>(Helper::waitDur, after - before, e_na); |
727 | } |
728 | |
729 | template <typename Helper> |
730 | void testSleepUntilNoIntSteady(const long long jumpMs) |
731 | { |
732 | typename Helper::steady_time_point before(Helper::steadyNow()); |
733 | Helper::sleep_until_no_int(Helper::steadyNow() + Helper::waitDur); |
734 | typename Helper::steady_time_point after(Helper::steadyNow()); |
735 | |
736 | checkWaitTime<Helper>(Helper::waitDur, after - before, e_na); |
737 | } |
738 | |
739 | template <typename Helper> |
740 | void testSleepUntilNoIntSystem(const long long jumpMs) |
741 | { |
742 | typename Helper::steady_time_point before(Helper::steadyNow()); |
743 | Helper::sleep_until_no_int(Helper::systemNow() + Helper::waitDur); |
744 | typename Helper::steady_time_point after(Helper::steadyNow()); |
745 | |
746 | checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, e_na); |
747 | } |
748 | |
749 | template <typename Helper> |
750 | void testSleepUntilNoIntCustom(const long long jumpMs) |
751 | { |
752 | typename Helper::steady_time_point before(Helper::steadyNow()); |
753 | Helper::sleep_until_no_int(Helper::customNow() + Helper::waitDur); |
754 | typename Helper::steady_time_point after(Helper::steadyNow()); |
755 | |
756 | checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, e_na); |
757 | } |
758 | |
759 | //-------------------------------------- |
760 | |
761 | #ifndef SKIP_NO_INT_SLEEP |
762 | |
763 | template <typename Helper> |
764 | void testSleepNoIntRelative(const long long jumpMs) |
765 | { |
766 | #ifndef SKIP_DATETIME_FUNCTIONS |
767 | typename Helper::steady_time_point before(Helper::steadyNow()); |
768 | boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count()); |
769 | boost::this_thread::no_interruption_point::sleep(rel_time: ptDur); |
770 | typename Helper::steady_time_point after(Helper::steadyNow()); |
771 | |
772 | checkWaitTime<Helper>(Helper::waitDur, after - before, e_na); |
773 | #else |
774 | checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na); |
775 | #endif |
776 | } |
777 | |
778 | template <typename Helper> |
779 | void testSleepNoIntAbsolute(const long long jumpMs) |
780 | { |
781 | #ifndef SKIP_DATETIME_FUNCTIONS |
782 | typename Helper::steady_time_point before(Helper::steadyNow()); |
783 | boost::posix_time::ptime ptNow(boost::posix_time::microsec_clock::universal_time()); |
784 | boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count()); |
785 | boost::this_thread::no_interruption_point::sleep(abs_time: ptNow + ptDur); |
786 | typename Helper::steady_time_point after(Helper::steadyNow()); |
787 | |
788 | checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, e_na); |
789 | #else |
790 | checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na); |
791 | #endif |
792 | } |
793 | |
794 | #endif |
795 | |
796 | //-------------------------------------- |
797 | |
798 | // Only Boost supports no_interruption_point |
799 | |
800 | template <typename Helper> |
801 | void testSleepNoIntBoost(const std::string& name) |
802 | { |
803 | std::cout << std::endl; |
804 | runTestWithNone<Helper>(testSleepForNoInt <Helper>, name + "::this_thread::no_interruption_point::sleep_for()" ); |
805 | runTestWithNone<Helper>(testSleepUntilNoIntSteady<Helper>, name + "::this_thread::no_interruption_point::sleep_until(), steady time" ); |
806 | runTestWithNone<Helper>(testSleepUntilNoIntSystem<Helper>, name + "::this_thread::no_interruption_point::sleep_until(), system time" ); |
807 | runTestWithNone<Helper>(testSleepUntilNoIntCustom<Helper>, name + "::this_thread::no_interruption_point::sleep_until(), custom time" ); |
808 | |
809 | #ifndef SKIP_NO_INT_SLEEP |
810 | runTestWithNone<Helper>(testSleepNoIntRelative<Helper>, name + "::this_thread::no_interruption_point::sleep(), relative time" ); |
811 | runTestWithNone<Helper>(testSleepNoIntAbsolute<Helper>, name + "::this_thread::no_interruption_point::sleep(), absolute time" ); |
812 | #endif |
813 | } |
814 | |
815 | template <typename Helper> |
816 | void testSleepNoThreadNoIntBoost(const std::string& name) |
817 | { |
818 | std::cout << std::endl; |
819 | runTest<Helper>(testSleepForNoInt <Helper>, name + "::this_thread::no_interruption_point::sleep_for(), no thread" ); |
820 | runTest<Helper>(testSleepUntilNoIntSteady<Helper>, name + "::this_thread::no_interruption_point::sleep_until(), no thread, steady time" ); |
821 | runTest<Helper>(testSleepUntilNoIntSystem<Helper>, name + "::this_thread::no_interruption_point::sleep_until(), no thread, system time" ); |
822 | runTest<Helper>(testSleepUntilNoIntCustom<Helper>, name + "::this_thread::no_interruption_point::sleep_until(), no thread, custom time" ); |
823 | |
824 | #ifndef SKIP_NO_INT_SLEEP |
825 | runTest<Helper>(testSleepNoIntRelative<Helper>, name + "::this_thread::no_interruption_point::sleep(), no thread, relative time" ); |
826 | runTest<Helper>(testSleepNoIntAbsolute<Helper>, name + "::this_thread::no_interruption_point::sleep(), no thread, absolute time" ); |
827 | #endif |
828 | } |
829 | |
830 | /******************************************************************************/ |
831 | |
832 | // Test Try Join |
833 | |
834 | template <typename Helper> |
835 | void testTryJoinFor(const long long jumpMs) |
836 | { |
837 | typename Helper::steady_time_point before(Helper::steadyNow()); |
838 | typename Helper::thread t3(sleepForLongTime); |
839 | bool succeeded = t3.try_join_for(Helper::waitDur); |
840 | typename Helper::steady_time_point after(Helper::steadyNow()); |
841 | |
842 | checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good); |
843 | } |
844 | |
845 | template <typename Helper> |
846 | void testTryJoinUntilSteady(const long long jumpMs) |
847 | { |
848 | typename Helper::steady_time_point before(Helper::steadyNow()); |
849 | typename Helper::thread t3(sleepForLongTime); |
850 | bool succeeded = t3.try_join_until(Helper::steadyNow() + Helper::waitDur); |
851 | typename Helper::steady_time_point after(Helper::steadyNow()); |
852 | |
853 | checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good); |
854 | } |
855 | |
856 | template <typename Helper> |
857 | void testTryJoinUntilSystem(const long long jumpMs) |
858 | { |
859 | typename Helper::steady_time_point before(Helper::steadyNow()); |
860 | typename Helper::thread t3(sleepForLongTime); |
861 | bool succeeded = t3.try_join_until(Helper::systemNow() + Helper::waitDur); |
862 | typename Helper::steady_time_point after(Helper::steadyNow()); |
863 | |
864 | checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good); |
865 | } |
866 | |
867 | template <typename Helper> |
868 | void testTryJoinUntilCustom(const long long jumpMs) |
869 | { |
870 | typename Helper::steady_time_point before(Helper::steadyNow()); |
871 | typename Helper::thread t3(sleepForLongTime); |
872 | bool succeeded = t3.try_join_until(Helper::customNow() + Helper::waitDur); |
873 | typename Helper::steady_time_point after(Helper::steadyNow()); |
874 | |
875 | checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good); |
876 | } |
877 | |
878 | //-------------------------------------- |
879 | |
880 | template <typename Helper> |
881 | void testTimedJoinRelative(const long long jumpMs) |
882 | { |
883 | #ifndef SKIP_DATETIME_FUNCTIONS |
884 | typename Helper::steady_time_point before(Helper::steadyNow()); |
885 | boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count()); |
886 | typename Helper::thread t3(sleepForLongTime); |
887 | bool succeeded = t3.timed_join(ptDur); |
888 | typename Helper::steady_time_point after(Helper::steadyNow()); |
889 | |
890 | checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good); |
891 | #else |
892 | checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na); |
893 | #endif |
894 | } |
895 | |
896 | template <typename Helper> |
897 | void testTimedJoinAbsolute(const long long jumpMs) |
898 | { |
899 | #ifndef SKIP_DATETIME_FUNCTIONS |
900 | typename Helper::steady_time_point before(Helper::steadyNow()); |
901 | boost::posix_time::ptime ptNow(boost::posix_time::microsec_clock::universal_time()); |
902 | boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count()); |
903 | typename Helper::thread t3(sleepForLongTime); |
904 | bool succeeded = t3.timed_join(ptNow + ptDur); |
905 | typename Helper::steady_time_point after(Helper::steadyNow()); |
906 | |
907 | checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good); |
908 | #else |
909 | checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na); |
910 | #endif |
911 | } |
912 | |
913 | //-------------------------------------- |
914 | |
915 | // Only Boost supports timed try_join functions |
916 | |
917 | template <typename Helper> |
918 | void testJoinBoost(const std::string& name) |
919 | { |
920 | std::cout << std::endl; |
921 | runTestWithNone<Helper>(testTryJoinFor <Helper>, name + "::thread::try_join_for()" ); |
922 | runTestWithNone<Helper>(testTryJoinUntilSteady<Helper>, name + "::thread::try_join_until(), steady time" ); |
923 | runTestWithNone<Helper>(testTryJoinUntilSystem<Helper>, name + "::thread::try_join_until(), system time" ); |
924 | runTestWithNone<Helper>(testTryJoinUntilCustom<Helper>, name + "::thread::try_join_until(), custom time" ); |
925 | runTestWithNone<Helper>(testTimedJoinRelative <Helper>, name + "::thread::timed_join(), relative time" ); |
926 | runTestWithNone<Helper>(testTimedJoinAbsolute <Helper>, name + "::thread::timed_join(), absolute time" ); |
927 | } |
928 | |
929 | /******************************************************************************/ |
930 | |
931 | // Test Condition Variable Wait |
932 | |
933 | template <typename Helper> |
934 | void testCondVarWaitFor(const long long jumpMs) |
935 | { |
936 | typename Helper::cond cv; |
937 | typename Helper::mutex m; |
938 | typename Helper::unique_lock g(m); |
939 | |
940 | typename Helper::steady_time_point before(Helper::steadyNow()); |
941 | bool noTimeout = (cv.wait_for(g, Helper::waitDur) == Helper::cv_status::no_timeout); |
942 | typename Helper::steady_time_point after(Helper::steadyNow()); |
943 | |
944 | checkWaitTime<Helper>(Helper::waitDur, after - before, noTimeout ? e_no_timeout : e_timeout); |
945 | } |
946 | |
947 | template <typename Helper> |
948 | void testCondVarWaitUntilSteady(const long long jumpMs) |
949 | { |
950 | typename Helper::cond cv; |
951 | typename Helper::mutex m; |
952 | typename Helper::unique_lock g(m); |
953 | |
954 | typename Helper::steady_time_point before(Helper::steadyNow()); |
955 | bool noTimeout = (cv.wait_until(g, Helper::steadyNow() + Helper::waitDur) == Helper::cv_status::no_timeout); |
956 | typename Helper::steady_time_point after(Helper::steadyNow()); |
957 | |
958 | checkWaitTime<Helper>(Helper::waitDur, after - before, noTimeout ? e_no_timeout : e_timeout); |
959 | } |
960 | |
961 | template <typename Helper> |
962 | void testCondVarWaitUntilSystem(const long long jumpMs) |
963 | { |
964 | typename Helper::cond cv; |
965 | typename Helper::mutex m; |
966 | typename Helper::unique_lock g(m); |
967 | |
968 | typename Helper::steady_time_point before(Helper::steadyNow()); |
969 | bool noTimeout = (cv.wait_until(g, Helper::systemNow() + Helper::waitDur) == Helper::cv_status::no_timeout); |
970 | typename Helper::steady_time_point after(Helper::steadyNow()); |
971 | |
972 | checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, noTimeout ? e_no_timeout : e_timeout); |
973 | } |
974 | |
975 | template <typename Helper> |
976 | void testCondVarWaitUntilCustom(const long long jumpMs) |
977 | { |
978 | typename Helper::cond cv; |
979 | typename Helper::mutex m; |
980 | typename Helper::unique_lock g(m); |
981 | |
982 | typename Helper::steady_time_point before(Helper::steadyNow()); |
983 | bool noTimeout = (cv.wait_until(g, Helper::customNow() + Helper::waitDur) == Helper::cv_status::no_timeout); |
984 | typename Helper::steady_time_point after(Helper::steadyNow()); |
985 | |
986 | checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, noTimeout ? e_no_timeout : e_timeout); |
987 | } |
988 | |
989 | //-------------------------------------- |
990 | |
991 | template <typename Helper> |
992 | void testCondVarTimedWaitRelative(const long long jumpMs) |
993 | { |
994 | #ifndef SKIP_DATETIME_FUNCTIONS |
995 | typename Helper::cond cv; |
996 | typename Helper::mutex m; |
997 | typename Helper::unique_lock g(m); |
998 | |
999 | typename Helper::steady_time_point before(Helper::steadyNow()); |
1000 | boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count()); |
1001 | bool noTimeout = cv.timed_wait(g, ptDur); |
1002 | typename Helper::steady_time_point after(Helper::steadyNow()); |
1003 | |
1004 | checkWaitTime<Helper>(Helper::waitDur, after - before, noTimeout ? e_no_timeout : e_timeout); |
1005 | #else |
1006 | checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na); |
1007 | #endif |
1008 | } |
1009 | |
1010 | template <typename Helper> |
1011 | void testCondVarTimedWaitAbsolute(const long long jumpMs) |
1012 | { |
1013 | #ifndef SKIP_DATETIME_FUNCTIONS |
1014 | typename Helper::cond cv; |
1015 | typename Helper::mutex m; |
1016 | typename Helper::unique_lock g(m); |
1017 | |
1018 | typename Helper::steady_time_point before(Helper::steadyNow()); |
1019 | boost::posix_time::ptime ptNow(boost::posix_time::microsec_clock::universal_time()); |
1020 | boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count()); |
1021 | bool noTimeout = cv.timed_wait(g, ptNow + ptDur); |
1022 | typename Helper::steady_time_point after(Helper::steadyNow()); |
1023 | |
1024 | checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, noTimeout ? e_no_timeout : e_timeout); |
1025 | #else |
1026 | checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na); |
1027 | #endif |
1028 | } |
1029 | |
1030 | //-------------------------------------- |
1031 | |
1032 | template <typename Helper> |
1033 | void testCondVarStd(const std::string& name) |
1034 | { |
1035 | std::cout << std::endl; |
1036 | runTestWithNone<Helper>(testCondVarWaitFor <Helper>, name + "::wait_for()" ); |
1037 | runTestWithNone<Helper>(testCondVarWaitUntilSteady<Helper>, name + "::wait_until(), steady time" ); |
1038 | runTestWithNone<Helper>(testCondVarWaitUntilSystem<Helper>, name + "::wait_until(), system time" ); |
1039 | runTestWithNone<Helper>(testCondVarWaitUntilCustom<Helper>, name + "::wait_until(), custom time" ); |
1040 | } |
1041 | |
1042 | template <typename Helper> |
1043 | void testCondVarBoost(const std::string& name) |
1044 | { |
1045 | testCondVarStd<Helper>(name); |
1046 | |
1047 | // Boost-only functions |
1048 | runTestWithNone<Helper>(testCondVarTimedWaitRelative<Helper>, name + "::timed_wait(), relative time" ); |
1049 | runTestWithNone<Helper>(testCondVarTimedWaitAbsolute<Helper>, name + "::timed_wait(), absolute time" ); |
1050 | } |
1051 | |
1052 | /******************************************************************************/ |
1053 | |
1054 | // Test Condition Variable Wait with Predicate |
1055 | |
1056 | template <typename Helper> |
1057 | void testCondVarWaitForPred(const long long jumpMs) |
1058 | { |
1059 | typename Helper::cond cv; |
1060 | typename Helper::mutex m; |
1061 | typename Helper::unique_lock g(m); |
1062 | |
1063 | typename Helper::steady_time_point before(Helper::steadyNow()); |
1064 | bool noTimeout = cv.wait_for(g, Helper::waitDur, returnFalse); |
1065 | typename Helper::steady_time_point after(Helper::steadyNow()); |
1066 | |
1067 | checkWaitTime<Helper>(Helper::waitDur, after - before, noTimeout ? e_no_timeout : e_timeout); |
1068 | } |
1069 | |
1070 | template <typename Helper> |
1071 | void testCondVarWaitUntilPredSteady(const long long jumpMs) |
1072 | { |
1073 | typename Helper::cond cv; |
1074 | typename Helper::mutex m; |
1075 | typename Helper::unique_lock g(m); |
1076 | |
1077 | typename Helper::steady_time_point before(Helper::steadyNow()); |
1078 | bool noTimeout = cv.wait_until(g, Helper::steadyNow() + Helper::waitDur, returnFalse); |
1079 | typename Helper::steady_time_point after(Helper::steadyNow()); |
1080 | |
1081 | checkWaitTime<Helper>(Helper::waitDur, after - before, noTimeout ? e_no_timeout : e_timeout); |
1082 | } |
1083 | |
1084 | template <typename Helper> |
1085 | void testCondVarWaitUntilPredSystem(const long long jumpMs) |
1086 | { |
1087 | typename Helper::cond cv; |
1088 | typename Helper::mutex m; |
1089 | typename Helper::unique_lock g(m); |
1090 | |
1091 | typename Helper::steady_time_point before(Helper::steadyNow()); |
1092 | bool noTimeout = cv.wait_until(g, Helper::systemNow() + Helper::waitDur, returnFalse); |
1093 | typename Helper::steady_time_point after(Helper::steadyNow()); |
1094 | |
1095 | checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, noTimeout ? e_no_timeout : e_timeout); |
1096 | } |
1097 | |
1098 | template <typename Helper> |
1099 | void testCondVarWaitUntilPredCustom(const long long jumpMs) |
1100 | { |
1101 | typename Helper::cond cv; |
1102 | typename Helper::mutex m; |
1103 | typename Helper::unique_lock g(m); |
1104 | |
1105 | typename Helper::steady_time_point before(Helper::steadyNow()); |
1106 | bool noTimeout = cv.wait_until(g, Helper::customNow() + Helper::waitDur, returnFalse); |
1107 | typename Helper::steady_time_point after(Helper::steadyNow()); |
1108 | |
1109 | checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, noTimeout ? e_no_timeout : e_timeout); |
1110 | } |
1111 | |
1112 | //-------------------------------------- |
1113 | |
1114 | template <typename Helper> |
1115 | void testCondVarTimedWaitPredRelative(const long long jumpMs) |
1116 | { |
1117 | #ifndef SKIP_DATETIME_FUNCTIONS |
1118 | typename Helper::cond cv; |
1119 | typename Helper::mutex m; |
1120 | typename Helper::unique_lock g(m); |
1121 | |
1122 | typename Helper::steady_time_point before(Helper::steadyNow()); |
1123 | boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count()); |
1124 | bool noTimeout = cv.timed_wait(g, ptDur, returnFalse); |
1125 | typename Helper::steady_time_point after(Helper::steadyNow()); |
1126 | |
1127 | checkWaitTime<Helper>(Helper::waitDur, after - before, noTimeout ? e_no_timeout : e_timeout); |
1128 | #else |
1129 | checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na); |
1130 | #endif |
1131 | } |
1132 | |
1133 | template <typename Helper> |
1134 | void testCondVarTimedWaitPredAbsolute(const long long jumpMs) |
1135 | { |
1136 | #ifndef SKIP_DATETIME_FUNCTIONS |
1137 | typename Helper::cond cv; |
1138 | typename Helper::mutex m; |
1139 | typename Helper::unique_lock g(m); |
1140 | |
1141 | typename Helper::steady_time_point before(Helper::steadyNow()); |
1142 | boost::posix_time::ptime ptNow(boost::posix_time::microsec_clock::universal_time()); |
1143 | boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count()); |
1144 | bool noTimeout = cv.timed_wait(g, ptNow + ptDur, returnFalse); |
1145 | typename Helper::steady_time_point after(Helper::steadyNow()); |
1146 | |
1147 | checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, noTimeout ? e_no_timeout : e_timeout); |
1148 | #else |
1149 | checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na); |
1150 | #endif |
1151 | } |
1152 | |
1153 | //-------------------------------------- |
1154 | |
1155 | template <typename Helper> |
1156 | void testCondVarPredStd(const std::string& name) |
1157 | { |
1158 | std::cout << std::endl; |
1159 | runTestWithNone<Helper>(testCondVarWaitForPred <Helper>, name + "::wait_for(), with predicate" ); |
1160 | runTestWithNone<Helper>(testCondVarWaitUntilPredSteady<Helper>, name + "::wait_until(), with predicate, steady time" ); |
1161 | runTestWithNone<Helper>(testCondVarWaitUntilPredSystem<Helper>, name + "::wait_until(), with predicate, system time" ); |
1162 | runTestWithNone<Helper>(testCondVarWaitUntilPredCustom<Helper>, name + "::wait_until(), with predicate, custom time" ); |
1163 | } |
1164 | |
1165 | template <typename Helper> |
1166 | void testCondVarPredBoost(const std::string& name) |
1167 | { |
1168 | testCondVarPredStd<Helper>(name); |
1169 | |
1170 | // Boost-only functions |
1171 | runTestWithNone<Helper>(testCondVarTimedWaitPredRelative<Helper>, name + "::timed_wait(), with predicate, relative time" ); |
1172 | runTestWithNone<Helper>(testCondVarTimedWaitPredAbsolute<Helper>, name + "::timed_wait(), with predicate, absolute time" ); |
1173 | } |
1174 | |
1175 | /******************************************************************************/ |
1176 | |
1177 | // Test Try Lock |
1178 | |
1179 | template <typename Helper> |
1180 | void testTryLockFor(typename Helper::mutex& m, const long long jumpMs) |
1181 | { |
1182 | typename Helper::steady_time_point before(Helper::steadyNow()); |
1183 | bool succeeded = m.try_lock_for(Helper::waitDur); |
1184 | typename Helper::steady_time_point after(Helper::steadyNow()); |
1185 | |
1186 | checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good); |
1187 | } |
1188 | |
1189 | template <typename Helper> |
1190 | void testTryLockUntilSteady(typename Helper::mutex& m, const long long jumpMs) |
1191 | { |
1192 | typename Helper::steady_time_point before(Helper::steadyNow()); |
1193 | bool succeeded = m.try_lock_until(Helper::steadyNow() + Helper::waitDur); |
1194 | typename Helper::steady_time_point after(Helper::steadyNow()); |
1195 | |
1196 | checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good); |
1197 | } |
1198 | |
1199 | template <typename Helper> |
1200 | void testTryLockUntilSystem(typename Helper::mutex& m, const long long jumpMs) |
1201 | { |
1202 | typename Helper::steady_time_point before(Helper::steadyNow()); |
1203 | bool succeeded = m.try_lock_until(Helper::systemNow() + Helper::waitDur); |
1204 | typename Helper::steady_time_point after(Helper::steadyNow()); |
1205 | |
1206 | checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good); |
1207 | } |
1208 | |
1209 | template <typename Helper> |
1210 | void testTryLockUntilCustom(typename Helper::mutex& m, const long long jumpMs) |
1211 | { |
1212 | typename Helper::steady_time_point before(Helper::steadyNow()); |
1213 | bool succeeded = m.try_lock_until(Helper::customNow() + Helper::waitDur); |
1214 | typename Helper::steady_time_point after(Helper::steadyNow()); |
1215 | |
1216 | checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good); |
1217 | } |
1218 | |
1219 | //-------------------------------------- |
1220 | |
1221 | template <typename Helper> |
1222 | void testTimedLockRelative(typename Helper::mutex& m, const long long jumpMs) |
1223 | { |
1224 | #ifndef SKIP_DATETIME_FUNCTIONS |
1225 | typename Helper::steady_time_point before(Helper::steadyNow()); |
1226 | boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count()); |
1227 | bool succeeded = m.timed_lock(ptDur); |
1228 | typename Helper::steady_time_point after(Helper::steadyNow()); |
1229 | |
1230 | checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good); |
1231 | #else |
1232 | checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na); |
1233 | #endif |
1234 | } |
1235 | |
1236 | template <typename Helper> |
1237 | void testTimedLockAbsolute(typename Helper::mutex& m, const long long jumpMs) |
1238 | { |
1239 | #ifndef SKIP_DATETIME_FUNCTIONS |
1240 | typename Helper::steady_time_point before(Helper::steadyNow()); |
1241 | boost::posix_time::ptime ptNow(boost::posix_time::microsec_clock::universal_time()); |
1242 | boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count()); |
1243 | bool succeeded = m.timed_lock(ptNow + ptDur); |
1244 | typename Helper::steady_time_point after(Helper::steadyNow()); |
1245 | |
1246 | checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good); |
1247 | #else |
1248 | checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na); |
1249 | #endif |
1250 | } |
1251 | |
1252 | //-------------------------------------- |
1253 | |
1254 | template <typename Helper> |
1255 | void testMutexStd(const std::string& name) |
1256 | { |
1257 | std::cout << std::endl; |
1258 | runTestWithUnique<Helper>(testTryLockFor <Helper>, name + "::try_lock_for()" ); |
1259 | runTestWithUnique<Helper>(testTryLockUntilSteady<Helper>, name + "::try_lock_until(), steady time" ); |
1260 | runTestWithUnique<Helper>(testTryLockUntilSystem<Helper>, name + "::try_lock_until(), system time" ); |
1261 | runTestWithUnique<Helper>(testTryLockUntilCustom<Helper>, name + "::try_lock_until(), custom time" ); |
1262 | } |
1263 | |
1264 | template <typename Helper> |
1265 | void testMutexBoost(const std::string& name) |
1266 | { |
1267 | testMutexStd<Helper>(name); |
1268 | |
1269 | // Boost-only functions |
1270 | runTestWithUnique<Helper>(testTimedLockRelative<Helper>, name + "::timed_lock(), relative time" ); |
1271 | runTestWithUnique<Helper>(testTimedLockAbsolute<Helper>, name + "::timed_lock(), absolute time" ); |
1272 | } |
1273 | |
1274 | /******************************************************************************/ |
1275 | |
1276 | // Test Try Lock Shared |
1277 | |
1278 | template <typename Helper> |
1279 | void testTryLockSharedFor(typename Helper::mutex& m, const long long jumpMs) |
1280 | { |
1281 | typename Helper::steady_time_point before(Helper::steadyNow()); |
1282 | bool succeeded = m.try_lock_shared_for(Helper::waitDur); |
1283 | typename Helper::steady_time_point after(Helper::steadyNow()); |
1284 | |
1285 | checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good); |
1286 | } |
1287 | |
1288 | template <typename Helper> |
1289 | void testTryLockSharedUntilSteady(typename Helper::mutex& m, const long long jumpMs) |
1290 | { |
1291 | typename Helper::steady_time_point before(Helper::steadyNow()); |
1292 | bool succeeded = m.try_lock_shared_until(Helper::steadyNow() + Helper::waitDur); |
1293 | typename Helper::steady_time_point after(Helper::steadyNow()); |
1294 | |
1295 | checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good); |
1296 | } |
1297 | |
1298 | template <typename Helper> |
1299 | void testTryLockSharedUntilSystem(typename Helper::mutex& m, const long long jumpMs) |
1300 | { |
1301 | typename Helper::steady_time_point before(Helper::steadyNow()); |
1302 | bool succeeded = m.try_lock_shared_until(Helper::systemNow() + Helper::waitDur); |
1303 | typename Helper::steady_time_point after(Helper::steadyNow()); |
1304 | |
1305 | checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good); |
1306 | } |
1307 | |
1308 | template <typename Helper> |
1309 | void testTryLockSharedUntilCustom(typename Helper::mutex& m, const long long jumpMs) |
1310 | { |
1311 | typename Helper::steady_time_point before(Helper::steadyNow()); |
1312 | bool succeeded = m.try_lock_shared_until(Helper::customNow() + Helper::waitDur); |
1313 | typename Helper::steady_time_point after(Helper::steadyNow()); |
1314 | |
1315 | checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good); |
1316 | } |
1317 | |
1318 | //-------------------------------------- |
1319 | |
1320 | template <typename Helper> |
1321 | void testTimedLockSharedRelative(typename Helper::mutex& m, const long long jumpMs) |
1322 | { |
1323 | #ifndef SKIP_DATETIME_FUNCTIONS |
1324 | typename Helper::steady_time_point before(Helper::steadyNow()); |
1325 | boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count()); |
1326 | bool succeeded = m.timed_lock_shared(ptDur); |
1327 | typename Helper::steady_time_point after(Helper::steadyNow()); |
1328 | |
1329 | checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good); |
1330 | #else |
1331 | checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na); |
1332 | #endif |
1333 | } |
1334 | |
1335 | template <typename Helper> |
1336 | void testTimedLockSharedAbsolute(typename Helper::mutex& m, const long long jumpMs) |
1337 | { |
1338 | #ifndef SKIP_DATETIME_FUNCTIONS |
1339 | typename Helper::steady_time_point before(Helper::steadyNow()); |
1340 | boost::posix_time::ptime ptNow(boost::posix_time::microsec_clock::universal_time()); |
1341 | boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count()); |
1342 | bool succeeded = m.timed_lock_shared(ptNow + ptDur); |
1343 | typename Helper::steady_time_point after(Helper::steadyNow()); |
1344 | |
1345 | checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good); |
1346 | #else |
1347 | checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na); |
1348 | #endif |
1349 | } |
1350 | |
1351 | //-------------------------------------- |
1352 | |
1353 | template <typename Helper> |
1354 | void testMutexSharedStd(const std::string& name) |
1355 | { |
1356 | std::cout << std::endl; |
1357 | runTestWithUnique<Helper>(testTryLockSharedFor <Helper>, name + "::try_lock_shared_for()" ); |
1358 | runTestWithUnique<Helper>(testTryLockSharedUntilSteady<Helper>, name + "::try_lock_shared_until(), steady time" ); |
1359 | runTestWithUnique<Helper>(testTryLockSharedUntilSystem<Helper>, name + "::try_lock_shared_until(), system time" ); |
1360 | runTestWithUnique<Helper>(testTryLockSharedUntilCustom<Helper>, name + "::try_lock_shared_until(), custom time" ); |
1361 | } |
1362 | |
1363 | template <typename Helper> |
1364 | void testMutexSharedBoost(const std::string& name) |
1365 | { |
1366 | testMutexSharedStd<Helper>(name); |
1367 | |
1368 | // Boost-only functions |
1369 | runTestWithUnique<Helper>(testTimedLockSharedRelative<Helper>, name + "::timed_lock_shared(), relative time" ); |
1370 | runTestWithUnique<Helper>(testTimedLockSharedAbsolute<Helper>, name + "::timed_lock_shared(), absolute time" ); |
1371 | } |
1372 | |
1373 | /******************************************************************************/ |
1374 | |
1375 | // Test Try Lock Upgrade |
1376 | |
1377 | #ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS |
1378 | |
1379 | template <typename Helper> |
1380 | void testTryLockUpgradeFor(typename Helper::mutex& m, const long long jumpMs) |
1381 | { |
1382 | typename Helper::steady_time_point before(Helper::steadyNow()); |
1383 | bool succeeded = m.try_lock_upgrade_for(Helper::waitDur); |
1384 | typename Helper::steady_time_point after(Helper::steadyNow()); |
1385 | |
1386 | checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good); |
1387 | } |
1388 | |
1389 | template <typename Helper> |
1390 | void testTryLockUpgradeUntilSteady(typename Helper::mutex& m, const long long jumpMs) |
1391 | { |
1392 | typename Helper::steady_time_point before(Helper::steadyNow()); |
1393 | bool succeeded = m.try_lock_upgrade_until(Helper::steadyNow() + Helper::waitDur); |
1394 | typename Helper::steady_time_point after(Helper::steadyNow()); |
1395 | |
1396 | checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good); |
1397 | } |
1398 | |
1399 | template <typename Helper> |
1400 | void testTryLockUpgradeUntilSystem(typename Helper::mutex& m, const long long jumpMs) |
1401 | { |
1402 | typename Helper::steady_time_point before(Helper::steadyNow()); |
1403 | bool succeeded = m.try_lock_upgrade_until(Helper::systemNow() + Helper::waitDur); |
1404 | typename Helper::steady_time_point after(Helper::steadyNow()); |
1405 | |
1406 | checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good); |
1407 | } |
1408 | |
1409 | template <typename Helper> |
1410 | void testTryLockUpgradeUntilCustom(typename Helper::mutex& m, const long long jumpMs) |
1411 | { |
1412 | typename Helper::steady_time_point before(Helper::steadyNow()); |
1413 | bool succeeded = m.try_lock_upgrade_until(Helper::customNow() + Helper::waitDur); |
1414 | typename Helper::steady_time_point after(Helper::steadyNow()); |
1415 | |
1416 | checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good); |
1417 | } |
1418 | |
1419 | //-------------------------------------- |
1420 | |
1421 | template <typename Helper> |
1422 | void testTimedLockUpgradeRelative(typename Helper::mutex& m, const long long jumpMs) |
1423 | { |
1424 | #ifndef SKIP_DATETIME_FUNCTIONS |
1425 | typename Helper::steady_time_point before(Helper::steadyNow()); |
1426 | boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count()); |
1427 | bool succeeded = m.timed_lock_upgrade(ptDur); |
1428 | typename Helper::steady_time_point after(Helper::steadyNow()); |
1429 | |
1430 | checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good); |
1431 | #else |
1432 | checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na); |
1433 | #endif |
1434 | } |
1435 | |
1436 | template <typename Helper> |
1437 | void testTimedLockUpgradeAbsolute(typename Helper::mutex& m, const long long jumpMs) |
1438 | { |
1439 | #ifndef SKIP_DATETIME_FUNCTIONS |
1440 | typename Helper::steady_time_point before(Helper::steadyNow()); |
1441 | boost::posix_time::ptime ptNow(boost::posix_time::microsec_clock::universal_time()); |
1442 | boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count()); |
1443 | bool succeeded = m.timed_lock_upgrade(ptNow + ptDur); |
1444 | typename Helper::steady_time_point after(Helper::steadyNow()); |
1445 | |
1446 | checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good); |
1447 | #else |
1448 | checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na); |
1449 | #endif |
1450 | } |
1451 | |
1452 | //-------------------------------------- |
1453 | |
1454 | template <typename Helper> |
1455 | void testTryUnlockSharedAndLockFor(typename Helper::mutex& m, const long long jumpMs) |
1456 | { |
1457 | boost::shared_lock_guard<typename Helper::mutex> g(m); |
1458 | |
1459 | typename Helper::steady_time_point before(Helper::steadyNow()); |
1460 | bool succeeded = m.try_unlock_shared_and_lock_for(Helper::waitDur); |
1461 | typename Helper::steady_time_point after(Helper::steadyNow()); |
1462 | |
1463 | checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good); |
1464 | } |
1465 | |
1466 | template <typename Helper> |
1467 | void testTryUnlockSharedAndLockUntilSteady(typename Helper::mutex& m, const long long jumpMs) |
1468 | { |
1469 | boost::shared_lock_guard<typename Helper::mutex> g(m); |
1470 | |
1471 | typename Helper::steady_time_point before(Helper::steadyNow()); |
1472 | bool succeeded = m.try_unlock_shared_and_lock_until(Helper::steadyNow() + Helper::waitDur); |
1473 | typename Helper::steady_time_point after(Helper::steadyNow()); |
1474 | |
1475 | checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good); |
1476 | } |
1477 | |
1478 | template <typename Helper> |
1479 | void testTryUnlockSharedAndLockUntilSystem(typename Helper::mutex& m, const long long jumpMs) |
1480 | { |
1481 | boost::shared_lock_guard<typename Helper::mutex> g(m); |
1482 | |
1483 | typename Helper::steady_time_point before(Helper::steadyNow()); |
1484 | bool succeeded = m.try_unlock_shared_and_lock_until(Helper::systemNow() + Helper::waitDur); |
1485 | typename Helper::steady_time_point after(Helper::steadyNow()); |
1486 | |
1487 | checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good); |
1488 | } |
1489 | |
1490 | template <typename Helper> |
1491 | void testTryUnlockSharedAndLockUntilCustom(typename Helper::mutex& m, const long long jumpMs) |
1492 | { |
1493 | boost::shared_lock_guard<typename Helper::mutex> g(m); |
1494 | |
1495 | typename Helper::steady_time_point before(Helper::steadyNow()); |
1496 | bool succeeded = m.try_unlock_shared_and_lock_until(Helper::customNow() + Helper::waitDur); |
1497 | typename Helper::steady_time_point after(Helper::steadyNow()); |
1498 | |
1499 | checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good); |
1500 | } |
1501 | |
1502 | //-------------------------------------- |
1503 | |
1504 | template <typename Helper> |
1505 | void testTryUnlockUpgradeAndLockFor(typename Helper::mutex& m, const long long jumpMs) |
1506 | { |
1507 | boost::upgrade_lock<typename Helper::mutex> g(m); |
1508 | |
1509 | typename Helper::steady_time_point before(Helper::steadyNow()); |
1510 | bool succeeded = m.try_unlock_upgrade_and_lock_for(Helper::waitDur); |
1511 | typename Helper::steady_time_point after(Helper::steadyNow()); |
1512 | |
1513 | checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good); |
1514 | } |
1515 | |
1516 | template <typename Helper> |
1517 | void testTryUnlockUpgradeAndLockUntilSteady(typename Helper::mutex& m, const long long jumpMs) |
1518 | { |
1519 | boost::upgrade_lock<typename Helper::mutex> g(m); |
1520 | |
1521 | typename Helper::steady_time_point before(Helper::steadyNow()); |
1522 | bool succeeded = m.try_unlock_upgrade_and_lock_until(Helper::steadyNow() + Helper::waitDur); |
1523 | typename Helper::steady_time_point after(Helper::steadyNow()); |
1524 | |
1525 | checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good); |
1526 | } |
1527 | |
1528 | template <typename Helper> |
1529 | void testTryUnlockUpgradeAndLockUntilSystem(typename Helper::mutex& m, const long long jumpMs) |
1530 | { |
1531 | boost::upgrade_lock<typename Helper::mutex> g(m); |
1532 | |
1533 | typename Helper::steady_time_point before(Helper::steadyNow()); |
1534 | bool succeeded = m.try_unlock_upgrade_and_lock_until(Helper::systemNow() + Helper::waitDur); |
1535 | typename Helper::steady_time_point after(Helper::steadyNow()); |
1536 | |
1537 | checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good); |
1538 | } |
1539 | |
1540 | template <typename Helper> |
1541 | void testTryUnlockUpgradeAndLockUntilCustom(typename Helper::mutex& m, const long long jumpMs) |
1542 | { |
1543 | boost::upgrade_lock<typename Helper::mutex> g(m); |
1544 | |
1545 | typename Helper::steady_time_point before(Helper::steadyNow()); |
1546 | bool succeeded = m.try_unlock_upgrade_and_lock_until(Helper::customNow() + Helper::waitDur); |
1547 | typename Helper::steady_time_point after(Helper::steadyNow()); |
1548 | |
1549 | checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good); |
1550 | } |
1551 | |
1552 | //-------------------------------------- |
1553 | |
1554 | template <typename Helper> |
1555 | void testTryUnlockSharedAndLockUpgradeFor(typename Helper::mutex& m, const long long jumpMs) |
1556 | { |
1557 | boost::shared_lock_guard<typename Helper::mutex> g(m); |
1558 | |
1559 | typename Helper::steady_time_point before(Helper::steadyNow()); |
1560 | bool succeeded = m.try_unlock_shared_and_lock_upgrade_for(Helper::waitDur); |
1561 | typename Helper::steady_time_point after(Helper::steadyNow()); |
1562 | |
1563 | checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good); |
1564 | } |
1565 | |
1566 | template <typename Helper> |
1567 | void testTryUnlockSharedAndLockUpgradeUntilSteady(typename Helper::mutex& m, const long long jumpMs) |
1568 | { |
1569 | boost::shared_lock_guard<typename Helper::mutex> g(m); |
1570 | |
1571 | typename Helper::steady_time_point before(Helper::steadyNow()); |
1572 | bool succeeded = m.try_unlock_shared_and_lock_upgrade_until(Helper::steadyNow() + Helper::waitDur); |
1573 | typename Helper::steady_time_point after(Helper::steadyNow()); |
1574 | |
1575 | checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good); |
1576 | } |
1577 | |
1578 | template <typename Helper> |
1579 | void testTryUnlockSharedAndLockUpgradeUntilSystem(typename Helper::mutex& m, const long long jumpMs) |
1580 | { |
1581 | boost::shared_lock_guard<typename Helper::mutex> g(m); |
1582 | |
1583 | typename Helper::steady_time_point before(Helper::steadyNow()); |
1584 | bool succeeded = m.try_unlock_shared_and_lock_upgrade_until(Helper::systemNow() + Helper::waitDur); |
1585 | typename Helper::steady_time_point after(Helper::steadyNow()); |
1586 | |
1587 | checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good); |
1588 | } |
1589 | |
1590 | template <typename Helper> |
1591 | void testTryUnlockSharedAndLockUpgradeUntilCustom(typename Helper::mutex& m, const long long jumpMs) |
1592 | { |
1593 | boost::shared_lock_guard<typename Helper::mutex> g(m); |
1594 | |
1595 | typename Helper::steady_time_point before(Helper::steadyNow()); |
1596 | bool succeeded = m.try_unlock_shared_and_lock_upgrade_until(Helper::customNow() + Helper::waitDur); |
1597 | typename Helper::steady_time_point after(Helper::steadyNow()); |
1598 | |
1599 | checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good); |
1600 | } |
1601 | |
1602 | #endif |
1603 | |
1604 | //-------------------------------------- |
1605 | |
1606 | // Only Boost supports upgrade mutexes |
1607 | |
1608 | template <typename Helper> |
1609 | void testMutexUpgradeBoost(const std::string& name) |
1610 | { |
1611 | #ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS |
1612 | std::cout << std::endl; |
1613 | runTestWithUnique<Helper>(testTryLockUpgradeFor <Helper>, name + "::try_lock_upgrade_for()" ); |
1614 | runTestWithUnique<Helper>(testTryLockUpgradeUntilSteady<Helper>, name + "::try_lock_upgrade_until(), steady time" ); |
1615 | runTestWithUnique<Helper>(testTryLockUpgradeUntilSystem<Helper>, name + "::try_lock_upgrade_until(), system time" ); |
1616 | runTestWithUnique<Helper>(testTryLockUpgradeUntilCustom<Helper>, name + "::try_lock_upgrade_until(), custom time" ); |
1617 | runTestWithUnique<Helper>(testTimedLockUpgradeRelative <Helper>, name + "::timed_lock_upgrade(), relative time" ); |
1618 | runTestWithUnique<Helper>(testTimedLockUpgradeAbsolute <Helper>, name + "::timed_lock_upgrade(), absolute time" ); |
1619 | |
1620 | std::cout << std::endl; |
1621 | runTestWithShared<Helper>(testTryUnlockSharedAndLockFor <Helper>, name + "::try_unlock_shared_and_lock_for()" ); |
1622 | runTestWithShared<Helper>(testTryUnlockSharedAndLockUntilSteady<Helper>, name + "::try_unlock_shared_and_lock_until(), steady time" ); |
1623 | runTestWithShared<Helper>(testTryUnlockSharedAndLockUntilSystem<Helper>, name + "::try_unlock_shared_and_lock_until(), system time" ); |
1624 | runTestWithShared<Helper>(testTryUnlockSharedAndLockUntilCustom<Helper>, name + "::try_unlock_shared_and_lock_until(), custom time" ); |
1625 | |
1626 | std::cout << std::endl; |
1627 | runTestWithShared<Helper>(testTryUnlockUpgradeAndLockFor <Helper>, name + "::try_unlock_upgrade_and_lock_for()" ); |
1628 | runTestWithShared<Helper>(testTryUnlockUpgradeAndLockUntilSteady<Helper>, name + "::try_unlock_upgrade_and_lock_until(), steady time" ); |
1629 | runTestWithShared<Helper>(testTryUnlockUpgradeAndLockUntilSystem<Helper>, name + "::try_unlock_upgrade_and_lock_until(), system time" ); |
1630 | runTestWithShared<Helper>(testTryUnlockUpgradeAndLockUntilCustom<Helper>, name + "::try_unlock_upgrade_and_lock_until(), custom time" ); |
1631 | |
1632 | std::cout << std::endl; |
1633 | runTestWithUpgrade<Helper>(testTryUnlockSharedAndLockFor <Helper>, name + "::try_unlock_shared_and_lock_upgrade_for()" ); |
1634 | runTestWithUpgrade<Helper>(testTryUnlockSharedAndLockUntilSteady<Helper>, name + "::try_unlock_shared_and_lock_upgrade_until(), steady time" ); |
1635 | runTestWithUpgrade<Helper>(testTryUnlockSharedAndLockUntilSystem<Helper>, name + "::try_unlock_shared_and_lock_upgrade_until(), system time" ); |
1636 | runTestWithUpgrade<Helper>(testTryUnlockSharedAndLockUntilCustom<Helper>, name + "::try_unlock_shared_and_lock_upgrade_until(), custom time" ); |
1637 | #endif |
1638 | } |
1639 | |
1640 | /******************************************************************************/ |
1641 | |
1642 | // Test Future Wait |
1643 | |
1644 | template <typename Helper> |
1645 | void testFutureWaitFor(const long long jumpMs) |
1646 | { |
1647 | typename Helper::packaged_task pt(returnFalse); |
1648 | typename Helper::future f = pt.get_future(); |
1649 | |
1650 | typename Helper::steady_time_point before(Helper::steadyNow()); |
1651 | bool timeout = (f.wait_for(Helper::waitDur) == Helper::future_status::timeout); |
1652 | typename Helper::steady_time_point after(Helper::steadyNow()); |
1653 | |
1654 | checkWaitTime<Helper>(Helper::waitDur, after - before, timeout ? e_timeout : e_no_timeout); |
1655 | } |
1656 | |
1657 | template <typename Helper> |
1658 | void testFutureWaitUntilSteady(const long long jumpMs) |
1659 | { |
1660 | typename Helper::packaged_task pt(returnFalse); |
1661 | typename Helper::future f = pt.get_future(); |
1662 | |
1663 | typename Helper::steady_time_point before(Helper::steadyNow()); |
1664 | bool timeout = (f.wait_until(Helper::steadyNow() + Helper::waitDur) == Helper::future_status::timeout); |
1665 | typename Helper::steady_time_point after(Helper::steadyNow()); |
1666 | |
1667 | checkWaitTime<Helper>(Helper::waitDur, after - before, timeout ? e_timeout : e_no_timeout); |
1668 | } |
1669 | |
1670 | template <typename Helper> |
1671 | void testFutureWaitUntilSystem(const long long jumpMs) |
1672 | { |
1673 | typename Helper::packaged_task pt(returnFalse); |
1674 | typename Helper::future f = pt.get_future(); |
1675 | |
1676 | typename Helper::steady_time_point before(Helper::steadyNow()); |
1677 | bool timeout = (f.wait_until(Helper::systemNow() + Helper::waitDur) == Helper::future_status::timeout); |
1678 | typename Helper::steady_time_point after(Helper::steadyNow()); |
1679 | |
1680 | checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, timeout ? e_timeout : e_no_timeout); |
1681 | } |
1682 | |
1683 | template <typename Helper> |
1684 | void testFutureWaitUntilCustom(const long long jumpMs) |
1685 | { |
1686 | typename Helper::packaged_task pt(returnFalse); |
1687 | typename Helper::future f = pt.get_future(); |
1688 | |
1689 | typename Helper::steady_time_point before(Helper::steadyNow()); |
1690 | bool timeout = (f.wait_until(Helper::customNow() + Helper::waitDur) == Helper::future_status::timeout); |
1691 | typename Helper::steady_time_point after(Helper::steadyNow()); |
1692 | |
1693 | checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, timeout ? e_timeout : e_no_timeout); |
1694 | } |
1695 | |
1696 | //-------------------------------------- |
1697 | |
1698 | template <typename Helper> |
1699 | void testFutureTimedWaitRelative(const long long jumpMs) |
1700 | { |
1701 | #ifndef SKIP_DATETIME_FUNCTIONS |
1702 | typename Helper::packaged_task pt(returnFalse); |
1703 | typename Helper::future f = pt.get_future(); |
1704 | |
1705 | typename Helper::steady_time_point before(Helper::steadyNow()); |
1706 | boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count()); |
1707 | bool noTimeout = f.timed_wait(ptDur); |
1708 | typename Helper::steady_time_point after(Helper::steadyNow()); |
1709 | |
1710 | checkWaitTime<Helper>(Helper::waitDur, after - before, noTimeout ? e_no_timeout : e_timeout); |
1711 | #else |
1712 | checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na); |
1713 | #endif |
1714 | } |
1715 | |
1716 | template <typename Helper> |
1717 | void testFutureTimedWaitAbsolute(const long long jumpMs) |
1718 | { |
1719 | #ifndef SKIP_DATETIME_FUNCTIONS |
1720 | typename Helper::packaged_task pt(returnFalse); |
1721 | typename Helper::future f = pt.get_future(); |
1722 | |
1723 | typename Helper::steady_time_point before(Helper::steadyNow()); |
1724 | boost::posix_time::ptime ptNow(boost::posix_time::microsec_clock::universal_time()); |
1725 | boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count()); |
1726 | bool noTimeout = f.timed_wait_until(ptNow + ptDur); |
1727 | typename Helper::steady_time_point after(Helper::steadyNow()); |
1728 | |
1729 | checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, noTimeout ? e_no_timeout : e_timeout); |
1730 | #else |
1731 | checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na); |
1732 | #endif |
1733 | } |
1734 | |
1735 | //-------------------------------------- |
1736 | |
1737 | template <typename Helper> |
1738 | void testFutureStd(const std::string& name) |
1739 | { |
1740 | std::cout << std::endl; |
1741 | runTestWithNone<Helper>(testFutureWaitFor <Helper>, name + "::wait_for()" ); |
1742 | runTestWithNone<Helper>(testFutureWaitUntilSteady<Helper>, name + "::wait_until(), steady time" ); |
1743 | runTestWithNone<Helper>(testFutureWaitUntilSystem<Helper>, name + "::wait_until(), system time" ); |
1744 | runTestWithNone<Helper>(testFutureWaitUntilCustom<Helper>, name + "::wait_until(), custom time" ); |
1745 | } |
1746 | |
1747 | template <typename Helper> |
1748 | void testFutureBoost(const std::string& name) |
1749 | { |
1750 | testFutureStd<Helper>(name); |
1751 | |
1752 | // Boost-only functions |
1753 | runTestWithNone<Helper>(testFutureTimedWaitRelative<Helper>, name + "::timed_wait(), relative time" ); |
1754 | runTestWithNone<Helper>(testFutureTimedWaitAbsolute<Helper>, name + "::timed_wait_until(), absolute time" ); |
1755 | } |
1756 | |
1757 | /******************************************************************************/ |
1758 | |
1759 | // Test Shared Future Wait |
1760 | |
1761 | template <typename Helper> |
1762 | void testSharedFutureWaitFor(const long long jumpMs) |
1763 | { |
1764 | typename Helper::packaged_task pt(returnFalse); |
1765 | typename Helper::future f = pt.get_future(); |
1766 | typename Helper::shared_future sf = boost::move(f); |
1767 | |
1768 | typename Helper::steady_time_point before(Helper::steadyNow()); |
1769 | bool timeout = (sf.wait_for(Helper::waitDur) == Helper::future_status::timeout); |
1770 | typename Helper::steady_time_point after(Helper::steadyNow()); |
1771 | |
1772 | checkWaitTime<Helper>(Helper::waitDur, after - before, timeout ? e_timeout : e_no_timeout); |
1773 | } |
1774 | |
1775 | template <typename Helper> |
1776 | void testSharedFutureWaitUntilSteady(const long long jumpMs) |
1777 | { |
1778 | typename Helper::packaged_task pt(returnFalse); |
1779 | typename Helper::future f = pt.get_future(); |
1780 | typename Helper::shared_future sf = boost::move(f); |
1781 | |
1782 | typename Helper::steady_time_point before(Helper::steadyNow()); |
1783 | bool timeout = (sf.wait_until(Helper::steadyNow() + Helper::waitDur) == Helper::future_status::timeout); |
1784 | typename Helper::steady_time_point after(Helper::steadyNow()); |
1785 | |
1786 | checkWaitTime<Helper>(Helper::waitDur, after - before, timeout ? e_timeout : e_no_timeout); |
1787 | } |
1788 | |
1789 | template <typename Helper> |
1790 | void testSharedFutureWaitUntilSystem(const long long jumpMs) |
1791 | { |
1792 | typename Helper::packaged_task pt(returnFalse); |
1793 | typename Helper::future f = pt.get_future(); |
1794 | typename Helper::shared_future sf = boost::move(f); |
1795 | |
1796 | typename Helper::steady_time_point before(Helper::steadyNow()); |
1797 | bool timeout = (sf.wait_until(Helper::systemNow() + Helper::waitDur) == Helper::future_status::timeout); |
1798 | typename Helper::steady_time_point after(Helper::steadyNow()); |
1799 | |
1800 | checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, timeout ? e_timeout : e_no_timeout); |
1801 | } |
1802 | |
1803 | template <typename Helper> |
1804 | void testSharedFutureWaitUntilCustom(const long long jumpMs) |
1805 | { |
1806 | typename Helper::packaged_task pt(returnFalse); |
1807 | typename Helper::future f = pt.get_future(); |
1808 | typename Helper::shared_future sf = boost::move(f); |
1809 | |
1810 | typename Helper::steady_time_point before(Helper::steadyNow()); |
1811 | bool timeout = (sf.wait_until(Helper::customNow() + Helper::waitDur) == Helper::future_status::timeout); |
1812 | typename Helper::steady_time_point after(Helper::steadyNow()); |
1813 | |
1814 | checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, timeout ? e_timeout : e_no_timeout); |
1815 | } |
1816 | |
1817 | //-------------------------------------- |
1818 | |
1819 | template <typename Helper> |
1820 | void testSharedFutureTimedWaitRelative(const long long jumpMs) |
1821 | { |
1822 | #ifndef SKIP_DATETIME_FUNCTIONS |
1823 | typename Helper::packaged_task pt(returnFalse); |
1824 | typename Helper::future f = pt.get_future(); |
1825 | typename Helper::shared_future sf = boost::move(f); |
1826 | |
1827 | typename Helper::steady_time_point before(Helper::steadyNow()); |
1828 | boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count()); |
1829 | bool noTimeout = sf.timed_wait(ptDur); |
1830 | typename Helper::steady_time_point after(Helper::steadyNow()); |
1831 | |
1832 | checkWaitTime<Helper>(Helper::waitDur, after - before, noTimeout ? e_no_timeout : e_timeout); |
1833 | #else |
1834 | checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na); |
1835 | #endif |
1836 | } |
1837 | |
1838 | template <typename Helper> |
1839 | void testSharedFutureTimedWaitAbsolute(const long long jumpMs) |
1840 | { |
1841 | #ifndef SKIP_DATETIME_FUNCTIONS |
1842 | typename Helper::packaged_task pt(returnFalse); |
1843 | typename Helper::future f = pt.get_future(); |
1844 | typename Helper::shared_future sf = boost::move(f); |
1845 | |
1846 | typename Helper::steady_time_point before(Helper::steadyNow()); |
1847 | boost::posix_time::ptime ptNow(boost::posix_time::microsec_clock::universal_time()); |
1848 | boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count()); |
1849 | bool noTimeout = sf.timed_wait_until(ptNow + ptDur); |
1850 | typename Helper::steady_time_point after(Helper::steadyNow()); |
1851 | |
1852 | checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, noTimeout ? e_no_timeout : e_timeout); |
1853 | #else |
1854 | checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na); |
1855 | #endif |
1856 | } |
1857 | |
1858 | //-------------------------------------- |
1859 | |
1860 | template <typename Helper> |
1861 | void testSharedFutureStd(const std::string& name) |
1862 | { |
1863 | std::cout << std::endl; |
1864 | runTestWithNone<Helper>(testSharedFutureWaitFor <Helper>, name + "::wait_for()" ); |
1865 | runTestWithNone<Helper>(testSharedFutureWaitUntilSteady<Helper>, name + "::wait_until(), steady time" ); |
1866 | runTestWithNone<Helper>(testSharedFutureWaitUntilSystem<Helper>, name + "::wait_until(), system time" ); |
1867 | runTestWithNone<Helper>(testSharedFutureWaitUntilCustom<Helper>, name + "::wait_until(), custom time" ); |
1868 | } |
1869 | |
1870 | template <typename Helper> |
1871 | void testSharedFutureBoost(const std::string& name) |
1872 | { |
1873 | testSharedFutureStd<Helper>(name); |
1874 | |
1875 | // Boost-only functions |
1876 | runTestWithNone<Helper>(testSharedFutureTimedWaitRelative<Helper>, name + "::timed_wait(), relative time" ); |
1877 | runTestWithNone<Helper>(testSharedFutureTimedWaitAbsolute<Helper>, name + "::timed_wait_until(), absolute time" ); |
1878 | } |
1879 | |
1880 | /******************************************************************************/ |
1881 | |
1882 | // Test Sync Priority Queue |
1883 | |
1884 | template <typename Helper> |
1885 | void testSyncPriorityQueuePullFor(const long long jumpMs) |
1886 | { |
1887 | boost::sync_priority_queue<int> q; |
1888 | int i; |
1889 | |
1890 | typename Helper::steady_time_point before(Helper::steadyNow()); |
1891 | bool timeout = (q.pull_for(Helper::waitDur, i) == boost::queue_op_status::timeout); |
1892 | typename Helper::steady_time_point after(Helper::steadyNow()); |
1893 | |
1894 | checkWaitTime<Helper>(Helper::waitDur, after - before, timeout ? e_timeout : e_no_timeout); |
1895 | } |
1896 | |
1897 | template <typename Helper> |
1898 | void testSyncPriorityQueuePullUntilSteady(const long long jumpMs) |
1899 | { |
1900 | boost::sync_priority_queue<int> q; |
1901 | int i; |
1902 | |
1903 | typename Helper::steady_time_point before(Helper::steadyNow()); |
1904 | bool timeout = (q.pull_until(Helper::steadyNow() + Helper::waitDur, i) == boost::queue_op_status::timeout); |
1905 | typename Helper::steady_time_point after(Helper::steadyNow()); |
1906 | |
1907 | checkWaitTime<Helper>(Helper::waitDur, after - before, timeout ? e_timeout : e_no_timeout); |
1908 | } |
1909 | |
1910 | template <typename Helper> |
1911 | void testSyncPriorityQueuePullUntilSystem(const long long jumpMs) |
1912 | { |
1913 | boost::sync_priority_queue<int> q; |
1914 | int i; |
1915 | |
1916 | typename Helper::steady_time_point before(Helper::steadyNow()); |
1917 | bool timeout = (q.pull_until(Helper::systemNow() + Helper::waitDur, i) == boost::queue_op_status::timeout); |
1918 | typename Helper::steady_time_point after(Helper::steadyNow()); |
1919 | |
1920 | checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, timeout ? e_timeout : e_no_timeout); |
1921 | } |
1922 | |
1923 | template <typename Helper> |
1924 | void testSyncPriorityQueuePullUntilCustom(const long long jumpMs) |
1925 | { |
1926 | boost::sync_priority_queue<int> q; |
1927 | int i; |
1928 | |
1929 | typename Helper::steady_time_point before(Helper::steadyNow()); |
1930 | bool timeout = (q.pull_until(Helper::customNow() + Helper::waitDur, i) == boost::queue_op_status::timeout); |
1931 | typename Helper::steady_time_point after(Helper::steadyNow()); |
1932 | |
1933 | checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, timeout ? e_timeout : e_no_timeout); |
1934 | } |
1935 | |
1936 | //-------------------------------------- |
1937 | |
1938 | // Only Boost supports sync_priority_queue |
1939 | |
1940 | template <typename Helper> |
1941 | void testSyncPriorityQueueBoost(const std::string& name) |
1942 | { |
1943 | std::cout << std::endl; |
1944 | runTestWithNone<Helper>(testSyncPriorityQueuePullFor <Helper>, name + "::pull_for()" ); |
1945 | runTestWithNone<Helper>(testSyncPriorityQueuePullUntilSteady<Helper>, name + "::pull_until(), steady time" ); |
1946 | runTestWithNone<Helper>(testSyncPriorityQueuePullUntilSystem<Helper>, name + "::pull_until(), system time" ); |
1947 | runTestWithNone<Helper>(testSyncPriorityQueuePullUntilCustom<Helper>, name + "::pull_until(), custom time" ); |
1948 | } |
1949 | |
1950 | /******************************************************************************/ |
1951 | |
1952 | // Test Sync Timed Queue |
1953 | |
1954 | template <typename Helper> |
1955 | void testSyncTimedQueuePullForEmptySteady(const long long jumpMs) |
1956 | { |
1957 | boost::sync_timed_queue<int, typename Helper::steady_clock> q; |
1958 | int i; |
1959 | |
1960 | typename Helper::steady_time_point before(Helper::steadyNow()); |
1961 | bool timeout = (q.pull_for(Helper::waitDur, i) == boost::queue_op_status::timeout); |
1962 | typename Helper::steady_time_point after(Helper::steadyNow()); |
1963 | |
1964 | checkWaitTime<Helper>(Helper::waitDur, after - before, timeout ? e_timeout : e_no_timeout); |
1965 | } |
1966 | |
1967 | template <typename Helper> |
1968 | void testSyncTimedQueuePullForEmptySystem(const long long jumpMs) |
1969 | { |
1970 | boost::sync_timed_queue<int, typename Helper::system_clock> q; |
1971 | int i; |
1972 | |
1973 | typename Helper::steady_time_point before(Helper::steadyNow()); |
1974 | bool timeout = (q.pull_for(Helper::waitDur, i) == boost::queue_op_status::timeout); |
1975 | typename Helper::steady_time_point after(Helper::steadyNow()); |
1976 | |
1977 | checkWaitTime<Helper>(Helper::waitDur, after - before, timeout ? e_timeout : e_no_timeout); |
1978 | } |
1979 | |
1980 | template <typename Helper> |
1981 | void testSyncTimedQueuePullForEmptyCustom(const long long jumpMs) |
1982 | { |
1983 | boost::sync_timed_queue<int, typename Helper::custom_clock> q; |
1984 | int i; |
1985 | |
1986 | typename Helper::steady_time_point before(Helper::steadyNow()); |
1987 | bool timeout = (q.pull_for(Helper::waitDur, i) == boost::queue_op_status::timeout); |
1988 | typename Helper::steady_time_point after(Helper::steadyNow()); |
1989 | |
1990 | checkWaitTime<Helper>(Helper::waitDur, after - before, timeout ? e_timeout : e_no_timeout); |
1991 | } |
1992 | |
1993 | template <typename Helper> |
1994 | void testSyncTimedQueuePullUntilEmptySteady(const long long jumpMs) |
1995 | { |
1996 | boost::sync_timed_queue<int, typename Helper::steady_clock> q; |
1997 | int i; |
1998 | |
1999 | typename Helper::steady_time_point before(Helper::steadyNow()); |
2000 | bool timeout = (q.pull_until(Helper::steadyNow() + Helper::waitDur, i) == boost::queue_op_status::timeout); |
2001 | typename Helper::steady_time_point after(Helper::steadyNow()); |
2002 | |
2003 | checkWaitTime<Helper>(Helper::waitDur, after - before, timeout ? e_timeout : e_no_timeout); |
2004 | } |
2005 | |
2006 | template <typename Helper> |
2007 | void testSyncTimedQueuePullUntilEmptySystem(const long long jumpMs) |
2008 | { |
2009 | boost::sync_timed_queue<int, typename Helper::system_clock> q; |
2010 | int i; |
2011 | |
2012 | typename Helper::steady_time_point before(Helper::steadyNow()); |
2013 | bool timeout = (q.pull_until(Helper::systemNow() + Helper::waitDur, i) == boost::queue_op_status::timeout); |
2014 | typename Helper::steady_time_point after(Helper::steadyNow()); |
2015 | |
2016 | checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, timeout ? e_timeout : e_no_timeout); |
2017 | } |
2018 | |
2019 | template <typename Helper> |
2020 | void testSyncTimedQueuePullUntilEmptyCustom(const long long jumpMs) |
2021 | { |
2022 | boost::sync_timed_queue<int, typename Helper::custom_clock> q; |
2023 | int i; |
2024 | |
2025 | typename Helper::steady_time_point before(Helper::steadyNow()); |
2026 | bool timeout = (q.pull_until(Helper::customNow() + Helper::waitDur, i) == boost::queue_op_status::timeout); |
2027 | typename Helper::steady_time_point after(Helper::steadyNow()); |
2028 | |
2029 | checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, timeout ? e_timeout : e_no_timeout); |
2030 | } |
2031 | |
2032 | //-------------------------------------- |
2033 | |
2034 | template <typename Helper> |
2035 | void testSyncTimedQueuePullForNotReadySteady(const long long jumpMs) |
2036 | { |
2037 | boost::sync_timed_queue<int, typename Helper::steady_clock> q; |
2038 | q.push(0, typename Helper::milliseconds(10000)); // a long time |
2039 | int i; |
2040 | |
2041 | typename Helper::steady_time_point before(Helper::steadyNow()); |
2042 | bool notReady = (q.pull_for(Helper::waitDur, i) == boost::queue_op_status::not_ready); |
2043 | typename Helper::steady_time_point after(Helper::steadyNow()); |
2044 | |
2045 | checkWaitTime<Helper>(Helper::waitDur, after - before, notReady ? e_not_ready_good : e_ready_bad); |
2046 | } |
2047 | |
2048 | template <typename Helper> |
2049 | void testSyncTimedQueuePullForNotReadySystem(const long long jumpMs) |
2050 | { |
2051 | boost::sync_timed_queue<int, typename Helper::system_clock> q; |
2052 | q.push(0, typename Helper::milliseconds(10000)); // a long time |
2053 | int i; |
2054 | |
2055 | typename Helper::steady_time_point before(Helper::steadyNow()); |
2056 | bool notReady = (q.pull_for(Helper::waitDur, i) == boost::queue_op_status::not_ready); |
2057 | typename Helper::steady_time_point after(Helper::steadyNow()); |
2058 | |
2059 | checkWaitTime<Helper>(Helper::waitDur, after - before, notReady ? e_not_ready_good : e_ready_bad); |
2060 | } |
2061 | |
2062 | template <typename Helper> |
2063 | void testSyncTimedQueuePullForNotReadyCustom(const long long jumpMs) |
2064 | { |
2065 | boost::sync_timed_queue<int, typename Helper::custom_clock> q; |
2066 | q.push(0, typename Helper::milliseconds(10000)); // a long time |
2067 | int i; |
2068 | |
2069 | typename Helper::steady_time_point before(Helper::steadyNow()); |
2070 | bool notReady = (q.pull_for(Helper::waitDur, i) == boost::queue_op_status::not_ready); |
2071 | typename Helper::steady_time_point after(Helper::steadyNow()); |
2072 | |
2073 | checkWaitTime<Helper>(Helper::waitDur, after - before, notReady ? e_not_ready_good : e_ready_bad); |
2074 | } |
2075 | |
2076 | template <typename Helper> |
2077 | void testSyncTimedQueuePullUntilNotReadySteady(const long long jumpMs) |
2078 | { |
2079 | boost::sync_timed_queue<int, typename Helper::steady_clock> q; |
2080 | q.push(0, typename Helper::milliseconds(10000)); // a long time |
2081 | int i; |
2082 | |
2083 | typename Helper::steady_time_point before(Helper::steadyNow()); |
2084 | bool notReady = (q.pull_until(Helper::steadyNow() + Helper::waitDur, i) == boost::queue_op_status::not_ready); |
2085 | typename Helper::steady_time_point after(Helper::steadyNow()); |
2086 | |
2087 | checkWaitTime<Helper>(Helper::waitDur, after - before, notReady ? e_not_ready_good : e_ready_bad); |
2088 | } |
2089 | |
2090 | template <typename Helper> |
2091 | void testSyncTimedQueuePullUntilNotReadySystem(const long long jumpMs) |
2092 | { |
2093 | boost::sync_timed_queue<int, typename Helper::system_clock> q; |
2094 | q.push(0, typename Helper::milliseconds(10000)); // a long time |
2095 | int i; |
2096 | |
2097 | typename Helper::steady_time_point before(Helper::steadyNow()); |
2098 | bool notReady = (q.pull_until(Helper::systemNow() + Helper::waitDur, i) == boost::queue_op_status::not_ready); |
2099 | typename Helper::steady_time_point after(Helper::steadyNow()); |
2100 | |
2101 | checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, notReady ? e_not_ready_good : e_ready_bad); |
2102 | } |
2103 | |
2104 | template <typename Helper> |
2105 | void testSyncTimedQueuePullUntilNotReadyCustom(const long long jumpMs) |
2106 | { |
2107 | boost::sync_timed_queue<int, typename Helper::custom_clock> q; |
2108 | q.push(0, typename Helper::milliseconds(10000)); // a long time |
2109 | int i; |
2110 | |
2111 | typename Helper::steady_time_point before(Helper::steadyNow()); |
2112 | bool notReady = (q.pull_until(Helper::customNow() + Helper::waitDur, i) == boost::queue_op_status::not_ready); |
2113 | typename Helper::steady_time_point after(Helper::steadyNow()); |
2114 | |
2115 | checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, notReady ? e_not_ready_good : e_ready_bad); |
2116 | } |
2117 | |
2118 | //-------------------------------------- |
2119 | |
2120 | template <typename Helper> |
2121 | void testSyncTimedQueuePullForSucceedsSteady(const long long jumpMs) |
2122 | { |
2123 | boost::sync_timed_queue<int, typename Helper::steady_clock> q; |
2124 | q.push(0, Helper::waitDur); |
2125 | int i; |
2126 | |
2127 | typename Helper::steady_time_point before(Helper::steadyNow()); |
2128 | bool succeeded = (q.pull_for(typename Helper::milliseconds(10000), i) == boost::queue_op_status::success); |
2129 | typename Helper::steady_time_point after(Helper::steadyNow()); |
2130 | |
2131 | checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_good : e_failed_bad); |
2132 | } |
2133 | |
2134 | template <typename Helper> |
2135 | void testSyncTimedQueuePullForSucceedsSystem(const long long jumpMs) |
2136 | { |
2137 | boost::sync_timed_queue<int, typename Helper::system_clock> q; |
2138 | q.push(0, Helper::waitDur); |
2139 | int i; |
2140 | |
2141 | typename Helper::steady_time_point before(Helper::steadyNow()); |
2142 | bool succeeded = (q.pull_for(typename Helper::milliseconds(10000), i) == boost::queue_op_status::success); |
2143 | typename Helper::steady_time_point after(Helper::steadyNow()); |
2144 | |
2145 | checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_good : e_failed_bad); |
2146 | } |
2147 | |
2148 | template <typename Helper> |
2149 | void testSyncTimedQueuePullForSucceedsCustom(const long long jumpMs) |
2150 | { |
2151 | boost::sync_timed_queue<int, typename Helper::custom_clock> q; |
2152 | q.push(0, Helper::waitDur); |
2153 | int i; |
2154 | |
2155 | typename Helper::steady_time_point before(Helper::steadyNow()); |
2156 | bool succeeded = (q.pull_for(typename Helper::milliseconds(10000), i) == boost::queue_op_status::success); |
2157 | typename Helper::steady_time_point after(Helper::steadyNow()); |
2158 | |
2159 | checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_good : e_failed_bad); |
2160 | } |
2161 | |
2162 | template <typename Helper> |
2163 | void testSyncTimedQueuePullUntilSucceedsSteady(const long long jumpMs) |
2164 | { |
2165 | boost::sync_timed_queue<int, typename Helper::steady_clock> q; |
2166 | q.push(0, Helper::steadyNow() + Helper::waitDur); |
2167 | int i; |
2168 | |
2169 | typename Helper::steady_time_point before(Helper::steadyNow()); |
2170 | bool succeeded = (q.pull_until(Helper::steadyNow() + typename Helper::milliseconds(10000), i) == boost::queue_op_status::success); |
2171 | typename Helper::steady_time_point after(Helper::steadyNow()); |
2172 | |
2173 | checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_good : e_failed_bad); |
2174 | } |
2175 | |
2176 | template <typename Helper> |
2177 | void testSyncTimedQueuePullUntilSucceedsSystem(const long long jumpMs) |
2178 | { |
2179 | boost::sync_timed_queue<int, typename Helper::system_clock> q; |
2180 | q.push(0, Helper::systemNow() + Helper::waitDur); |
2181 | int i; |
2182 | |
2183 | typename Helper::steady_time_point before(Helper::steadyNow()); |
2184 | bool succeeded = (q.pull_until(Helper::systemNow() + typename Helper::milliseconds(10000), i) == boost::queue_op_status::success); |
2185 | typename Helper::steady_time_point after(Helper::steadyNow()); |
2186 | |
2187 | checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_good : e_failed_bad); |
2188 | } |
2189 | |
2190 | template <typename Helper> |
2191 | void testSyncTimedQueuePullUntilSucceedsCustom(const long long jumpMs) |
2192 | { |
2193 | boost::sync_timed_queue<int, typename Helper::custom_clock> q; |
2194 | q.push(0, Helper::customNow() + Helper::waitDur); |
2195 | int i; |
2196 | |
2197 | typename Helper::steady_time_point before(Helper::steadyNow()); |
2198 | bool succeeded = (q.pull_until(Helper::customNow() + typename Helper::milliseconds(10000), i) == boost::queue_op_status::success); |
2199 | typename Helper::steady_time_point after(Helper::steadyNow()); |
2200 | |
2201 | checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_good : e_failed_bad); |
2202 | } |
2203 | |
2204 | //-------------------------------------- |
2205 | |
2206 | template <typename Helper> |
2207 | void testSyncTimedQueueWaitPullSucceedsSteady(const long long jumpMs) |
2208 | { |
2209 | boost::sync_timed_queue<int, typename Helper::steady_clock> q; |
2210 | q.push(0, Helper::steadyNow() + Helper::waitDur); |
2211 | int i; |
2212 | |
2213 | typename Helper::steady_time_point before(Helper::steadyNow()); |
2214 | bool succeeded = (q.wait_pull(i) == boost::queue_op_status::success); |
2215 | typename Helper::steady_time_point after(Helper::steadyNow()); |
2216 | |
2217 | checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_good : e_failed_bad); |
2218 | } |
2219 | |
2220 | template <typename Helper> |
2221 | void testSyncTimedQueueWaitPullSucceedsSystem(const long long jumpMs) |
2222 | { |
2223 | boost::sync_timed_queue<int, typename Helper::system_clock> q; |
2224 | q.push(0, Helper::systemNow() + Helper::waitDur); |
2225 | int i; |
2226 | |
2227 | typename Helper::steady_time_point before(Helper::steadyNow()); |
2228 | bool succeeded = (q.wait_pull(i) == boost::queue_op_status::success); |
2229 | typename Helper::steady_time_point after(Helper::steadyNow()); |
2230 | |
2231 | checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_good : e_failed_bad); |
2232 | } |
2233 | |
2234 | template <typename Helper> |
2235 | void testSyncTimedQueueWaitPullSucceedsCustom(const long long jumpMs) |
2236 | { |
2237 | boost::sync_timed_queue<int, typename Helper::custom_clock> q; |
2238 | q.push(0, Helper::customNow() + Helper::waitDur); |
2239 | int i; |
2240 | |
2241 | typename Helper::steady_time_point before(Helper::steadyNow()); |
2242 | bool succeeded = (q.wait_pull(i) == boost::queue_op_status::success); |
2243 | typename Helper::steady_time_point after(Helper::steadyNow()); |
2244 | |
2245 | checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_good : e_failed_bad); |
2246 | } |
2247 | |
2248 | //-------------------------------------- |
2249 | |
2250 | // Only Boost supports sync_timed_queue |
2251 | |
2252 | template <typename Helper> |
2253 | void testSyncTimedQueueBoost(const std::string& name) |
2254 | { |
2255 | std::cout << std::endl; |
2256 | runTestWithNone<Helper>(testSyncTimedQueuePullForEmptySteady <Helper>, name + "::pull_for(), empty, steady time" ); |
2257 | runTestWithNone<Helper>(testSyncTimedQueuePullForEmptySystem <Helper>, name + "::pull_for(), empty, system time" ); |
2258 | runTestWithNone<Helper>(testSyncTimedQueuePullForEmptyCustom <Helper>, name + "::pull_for(), empty, custom time" ); |
2259 | runTestWithNone<Helper>(testSyncTimedQueuePullUntilEmptySteady<Helper>, name + "::pull_until(), empty, steady time" ); |
2260 | runTestWithNone<Helper>(testSyncTimedQueuePullUntilEmptySystem<Helper>, name + "::pull_until(), empty, system time" ); |
2261 | runTestWithNone<Helper>(testSyncTimedQueuePullUntilEmptyCustom<Helper>, name + "::pull_until(), empty, custom time" ); |
2262 | |
2263 | std::cout << std::endl; |
2264 | runTestWithNone<Helper>(testSyncTimedQueuePullForNotReadySteady <Helper>, name + "::pull_for(), not ready, steady time" ); |
2265 | runTestWithNone<Helper>(testSyncTimedQueuePullForNotReadySystem <Helper>, name + "::pull_for(), not ready, system time" ); |
2266 | runTestWithNone<Helper>(testSyncTimedQueuePullForNotReadyCustom <Helper>, name + "::pull_for(), not ready, custom time" ); |
2267 | runTestWithNone<Helper>(testSyncTimedQueuePullUntilNotReadySteady<Helper>, name + "::pull_until(), not ready, steady time" ); |
2268 | runTestWithNone<Helper>(testSyncTimedQueuePullUntilNotReadySystem<Helper>, name + "::pull_until(), not ready, system time" ); |
2269 | runTestWithNone<Helper>(testSyncTimedQueuePullUntilNotReadyCustom<Helper>, name + "::pull_until(), not ready, custom time" ); |
2270 | |
2271 | std::cout << std::endl; |
2272 | runTestWithNone<Helper>(testSyncTimedQueuePullForSucceedsSteady <Helper>, name + "::pull_for(), succeeds, steady time" ); |
2273 | runTestWithNone<Helper>(testSyncTimedQueuePullForSucceedsSystem <Helper>, name + "::pull_for(), succeeds, system time" ); |
2274 | runTestWithNone<Helper>(testSyncTimedQueuePullForSucceedsCustom <Helper>, name + "::pull_for(), succeeds, custom time" ); |
2275 | runTestWithNone<Helper>(testSyncTimedQueuePullUntilSucceedsSteady<Helper>, name + "::pull_until(), succeeds, steady time" ); |
2276 | runTestWithNone<Helper>(testSyncTimedQueuePullUntilSucceedsSystem<Helper>, name + "::pull_until(), succeeds, system time" ); |
2277 | runTestWithNone<Helper>(testSyncTimedQueuePullUntilSucceedsCustom<Helper>, name + "::pull_until(), succeeds, custom time" ); |
2278 | |
2279 | std::cout << std::endl; |
2280 | runTestWithNone<Helper>(testSyncTimedQueueWaitPullSucceedsSteady<Helper>, name + "::wait_pull(), succeeds, steady time" ); |
2281 | runTestWithNone<Helper>(testSyncTimedQueueWaitPullSucceedsSystem<Helper>, name + "::wait_pull(), succeeds, system time" ); |
2282 | runTestWithNone<Helper>(testSyncTimedQueueWaitPullSucceedsCustom<Helper>, name + "::wait_pull(), succeeds, custom time" ); |
2283 | } |
2284 | |
2285 | /******************************************************************************/ |
2286 | |
2287 | int main() |
2288 | { |
2289 | std::cout << std::endl; |
2290 | std::cout << "INFO: This test requires root/Administrator privileges in order to change the system clock." << std::endl; |
2291 | std::cout << "INFO: Disable NTP while running this test to prevent NTP from changing the system clock." << std::endl; |
2292 | std::cout << std::endl; |
2293 | |
2294 | std::cout << "BOOST_HAS_PTHREAD_DELAY_NP: " ; |
2295 | #ifdef BOOST_HAS_PTHREAD_DELAY_NP |
2296 | std::cout << "YES" << std::endl; |
2297 | #else |
2298 | std::cout << "NO" << std::endl; |
2299 | #endif |
2300 | |
2301 | std::cout << "BOOST_HAS_NANOSLEEP: " ; |
2302 | #ifdef BOOST_HAS_NANOSLEEP |
2303 | std::cout << "YES" << std::endl; |
2304 | #else |
2305 | std::cout << "NO" << std::endl; |
2306 | #endif |
2307 | |
2308 | std::cout << "BOOST_THREAD_SLEEP_FOR_IS_STEADY: " ; |
2309 | #ifdef BOOST_THREAD_SLEEP_FOR_IS_STEADY |
2310 | std::cout << "YES" << std::endl; |
2311 | #else |
2312 | std::cout << "NO" << std::endl; |
2313 | #endif |
2314 | |
2315 | std::cout << "CLOCK_MONOTONIC: " ; |
2316 | #ifdef CLOCK_MONOTONIC |
2317 | std::cout << "YES" << std::endl; |
2318 | #else |
2319 | std::cout << "NO" << std::endl; |
2320 | #endif |
2321 | |
2322 | std::cout << "BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN: " ; |
2323 | #ifdef BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN |
2324 | std::cout << "YES" << std::endl; |
2325 | #else |
2326 | std::cout << "NO" << std::endl; |
2327 | #endif |
2328 | |
2329 | std::cout << "BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS: " ; |
2330 | #ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS |
2331 | std::cout << "YES" << std::endl; |
2332 | #else |
2333 | std::cout << "NO" << std::endl; |
2334 | #endif |
2335 | |
2336 | std::cout << "BOOST_THREAD_V2_SHARED_MUTEX: " ; |
2337 | #ifdef BOOST_THREAD_V2_SHARED_MUTEX |
2338 | std::cout << "YES" << std::endl; |
2339 | #else |
2340 | std::cout << "NO" << std::endl; |
2341 | #endif |
2342 | |
2343 | std::cout << "BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC: " ; |
2344 | #ifdef BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC |
2345 | std::cout << "YES" << std::endl; |
2346 | #else |
2347 | std::cout << "NO" << std::endl; |
2348 | #endif |
2349 | |
2350 | std::cout << std::endl; |
2351 | std::cout << "Wait Time: " << s_waitMs << " ms" << std::endl; |
2352 | std::cout << "Short Jump Time: " << s_shortJumpMs << " ms" << std::endl; |
2353 | std::cout << "Long Jump Time: " << s_longJumpMs << " ms" << std::endl; |
2354 | std::cout << "Sleep Before Jump Time: " << s_sleepBeforeJumpMs << " ms" << std::endl; |
2355 | std::cout << "Max Early Error: " << s_maxEarlyErrorMs << " ms" << std::endl; |
2356 | std::cout << "Max Late Error: " << s_maxLateErrorMs << " ms" << std::endl; |
2357 | |
2358 | testSleepBoost <BoostHelper< > >(name: "boost" ); |
2359 | testSleepNoIntBoost <BoostHelper< > >(name: "boost" ); |
2360 | testSleepNoThreadBoost <BoostHelper< > >(name: "boost" ); |
2361 | testSleepNoThreadNoIntBoost<BoostHelper< > >(name: "boost" ); |
2362 | testJoinBoost <BoostHelper< > >(name: "boost" ); |
2363 | testCondVarBoost <BoostHelper<boost::mutex, boost::condition_variable > >(name: "boost::condition_variable" ); |
2364 | testCondVarPredBoost <BoostHelper<boost::mutex, boost::condition_variable > >(name: "boost::condition_variable" ); |
2365 | testCondVarBoost <BoostHelper<boost::mutex, boost::condition_variable_any> >(name: "boost::condition_variable_any" ); |
2366 | testCondVarPredBoost <BoostHelper<boost::mutex, boost::condition_variable_any> >(name: "boost::condition_variable_any" ); |
2367 | testMutexBoost <BoostHelper<boost::timed_mutex > >(name: "boost::timed_mutex" ); |
2368 | testMutexBoost <BoostHelper<boost::recursive_timed_mutex > >(name: "boost::recursive_timed_mutex" ); |
2369 | testMutexBoost <BoostHelper<boost::shared_mutex > >(name: "boost::shared_mutex" ); // upgrade_mutex is a typedef of shared_mutex, so no need to test upgrade_mutex |
2370 | testMutexSharedBoost <BoostHelper<boost::shared_mutex > >(name: "boost::shared_mutex" ); // upgrade_mutex is a typedef of shared_mutex, so no need to test upgrade_mutex |
2371 | testMutexUpgradeBoost <BoostHelper<boost::shared_mutex > >(name: "boost::shared_mutex" ); // upgrade_mutex is a typedef of shared_mutex, so no need to test upgrade_mutex |
2372 | testFutureBoost <BoostHelper< > >(name: "boost::future" ); |
2373 | testSharedFutureBoost <BoostHelper< > >(name: "boost::shared_future" ); |
2374 | testSyncPriorityQueueBoost <BoostHelper< > >(name: "boost::sync_priority_queue" ); |
2375 | testSyncTimedQueueBoost <BoostHelper< > >(name: "boost::sync_timed_queue" ); |
2376 | |
2377 | #ifdef TEST_CPP14_FEATURES |
2378 | testSleepStd <StdHelper< > >("std" ); |
2379 | testSleepNoThreadStd<StdHelper< > >("std" ); |
2380 | testCondVarStd <StdHelper<std::mutex, std::condition_variable > >("std::condition_variable" ); |
2381 | testCondVarPredStd <StdHelper<std::mutex, std::condition_variable > >("std::condition_variable" ); |
2382 | testCondVarStd <StdHelper<std::mutex, std::condition_variable_any> >("std::condition_variable_any" ); |
2383 | testCondVarPredStd <StdHelper<std::mutex, std::condition_variable_any> >("std::condition_variable_any" ); |
2384 | testMutexStd <StdHelper<std::timed_mutex > >("std::timed_mutex" ); |
2385 | testMutexStd <StdHelper<std::recursive_timed_mutex > >("std::recursive_timed_mutex" ); |
2386 | testMutexStd <StdHelper<std::shared_timed_mutex > >("std::shared_timed_mutex" ); |
2387 | testMutexSharedStd <StdHelper<std::shared_timed_mutex > >("std::shared_timed_mutex" ); |
2388 | testFutureStd <StdHelper< > >("std::future" ); |
2389 | testSharedFutureStd <StdHelper< > >("std::shared_future" ); |
2390 | #endif |
2391 | |
2392 | std::cout << std::endl; |
2393 | std::cout << "Number of Tests Run: " << g_numTestsRun << std::endl; |
2394 | std::cout << "Number of Tests Passed: " << g_numTestsPassed << std::endl; |
2395 | std::cout << "Number of Tests Failed: " << g_numTestsFailed << std::endl; |
2396 | |
2397 | return 0; |
2398 | } |
2399 | |