1// Testing:
2//   State::PauseTiming()
3//   State::ResumeTiming()
4// Test that CHECK's within these function diagnose when they are called
5// outside of the KeepRunning() loop.
6//
7// NOTE: Users should NOT include or use src/check.h. This is only done in
8// order to test library internals.
9
10#include <cstdlib>
11#include <stdexcept>
12
13#include "../src/check.h"
14#include "benchmark/benchmark.h"
15
16#if defined(__GNUC__) && !defined(__EXCEPTIONS)
17#define TEST_HAS_NO_EXCEPTIONS
18#endif
19
20void TestHandler() {
21#ifndef TEST_HAS_NO_EXCEPTIONS
22  throw std::logic_error("");
23#else
24  std::abort();
25#endif
26}
27
28void try_invalid_pause_resume(benchmark::State& state) {
29#if !defined(TEST_BENCHMARK_LIBRARY_HAS_NO_ASSERTIONS) && !defined(TEST_HAS_NO_EXCEPTIONS)
30  try {
31    state.PauseTiming();
32    std::abort();
33  } catch (std::logic_error const&) {
34  }
35  try {
36    state.ResumeTiming();
37    std::abort();
38  } catch (std::logic_error const&) {
39  }
40#else
41  (void)state;  // avoid unused warning
42#endif
43}
44
45void BM_diagnostic_test(benchmark::State& state) {
46  static bool called_once = false;
47
48  if (called_once == false) try_invalid_pause_resume(state);
49
50  for (auto _ : state) {
51    benchmark::DoNotOptimize(state.iterations());
52  }
53
54  if (called_once == false) try_invalid_pause_resume(state);
55
56  called_once = true;
57}
58BENCHMARK(BM_diagnostic_test);
59
60
61void BM_diagnostic_test_keep_running(benchmark::State& state) {
62  static bool called_once = false;
63
64  if (called_once == false) try_invalid_pause_resume(state);
65
66  while(state.KeepRunning()) {
67    benchmark::DoNotOptimize(state.iterations());
68  }
69
70  if (called_once == false) try_invalid_pause_resume(state);
71
72  called_once = true;
73}
74BENCHMARK(BM_diagnostic_test_keep_running);
75
76int main(int argc, char* argv[]) {
77  benchmark::internal::GetAbortHandler() = &TestHandler;
78  benchmark::Initialize(&argc, argv);
79  benchmark::RunSpecifiedBenchmarks();
80}
81