Blame view

RIOT/tests/cpp11_condition_variable/main.cpp 2.95 KB
a752c7ab   elopes   add first test an...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
  /*
   * Copyright (C) 2015 Hamburg University of Applied Sciences (HAW)
   *
   * This file is subject to the terms and conditions of the GNU Lesser
   * General Public License v2.1. See the file LICENSE in the top level
   * directory for more details.
   */
  
  /**
   * @ingroup tests
   * @{
   *
   * @file
   * @brief test condition variable replacement header
   *
   * @author Raphael Hiesgen <raphael.hiesgen@haw-hamburg.de>
   *
   * @}
   */
  
  #include <string>
  #include <cstdio>
  #include <cassert>
  #include <system_error>
  
  #include "riot/mutex.hpp"
  #include "riot/chrono.hpp"
  #include "riot/thread.hpp"
  #include "riot/condition_variable.hpp"
  
  using namespace std;
  using namespace riot;
  
  /* http://en.cppreference.com/w/cpp/thread/condition_variable */
  int main() {
    puts("\n************ C++ condition_variable test ***********");
  
    puts("Wait with predicate and notify one ... ");
    {
      mutex m;
      condition_variable cv;
      string data;
      bool ready = false;
      bool processed = false;
      thread worker([&] {
        unique_lock<mutex> lk(m);
        cv.wait(lk, [&ready] { return ready; });
        data += " after processing";
        processed = true;
        cv.notify_one();
      });
      data = "Example data";
      {
        lock_guard<mutex> lk(m);
        /* cppcheck-suppress unreadVariable
         * (reason variable is read in the thread created above) */
        ready = true;
        cv.notify_one();
      }
      {
        unique_lock<mutex> lk(m);
        cv.wait(lk, [&processed] { return processed; });
      }
      string expected = "Example data after processing";
      assert(data == expected);
      worker.join();
    }
    puts("Done\n");
  
    puts("Wait and notify all ...");
    {
      mutex m;
      condition_variable cv;
      auto waits = [&m, &cv] {
        unique_lock<mutex> lk(m);
        cv.wait(lk);
      };
      thread t1(waits);
      thread t2(waits);
      thread t3(waits);
      thread t4(waits);
      thread([&m, &cv] {
               unique_lock<mutex> lk(m);
               cv.notify_all();
             }).detach();
      t1.join();
      t2.join();
      t3.join();
      t4.join();
    }
    puts("Done\n");
  
    puts("Wait for ...");
    {
      using chrono::system_clock;
      constexpr unsigned timeout = 1;
      mutex m;
      condition_variable cv;
      timex_t before, after;
      unique_lock<mutex> lk(m);
      xtimer_now_timex(&before);
      cv.wait_for(lk, chrono::seconds(timeout));
      xtimer_now_timex(&after);
      auto diff = timex_sub(after, before);
      assert(diff.seconds >= timeout);
    }
    puts("Done\n");
  
    puts("Wait until ...");
    {
      using chrono::system_clock;
      constexpr unsigned timeout = 1;
      mutex m;
      condition_variable cv;
      timex_t before, after;
      unique_lock<mutex> lk(m);
      xtimer_now_timex(&before);
      auto time = riot::now() += chrono::seconds(timeout);
      cv.wait_until(lk, time);
      xtimer_now_timex(&after);
      auto diff = timex_sub(after, before);
      assert(diff.seconds >= timeout);
    }
    puts("Done\n");
  
    puts("Bye, bye. ");
    puts("******************************************************\n");
  
    return 0;
  }