1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00
RIOT/tests/sys/cpp11_condition_variable/main.cpp

132 lines
3.0 KiB
C++

/*
* 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 <system_error>
#include "time_units.h"
#include "ztimer64.h"
#include "riot/mutex.hpp"
#include "riot/chrono.hpp"
#include "riot/thread.hpp"
#include "riot/condition_variable.hpp"
#include "test_utils/expect.h"
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";
expect(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([&m, &cv] {
unique_lock<mutex> lk(m);
cv.notify_all();
}).detach();
t1.join();
t2.join();
t3.join();
}
puts("Done\n");
puts("Wait for ...");
{
using chrono::system_clock;
constexpr unsigned timeout = 1;
mutex m;
condition_variable cv;
uint64_t before, after;
unique_lock<mutex> lk(m);
before = ztimer64_now(ZTIMER64_USEC);
cv.wait_for(lk, chrono::seconds(timeout));
after = ztimer64_now(ZTIMER64_USEC);
auto diff = after - before;
expect(diff >= timeout * US_PER_SEC);
}
puts("Done\n");
puts("Wait until ...");
{
using chrono::system_clock;
constexpr unsigned timeout = 1;
mutex m;
condition_variable cv;
uint64_t before, after;
unique_lock<mutex> lk(m);
before = ztimer64_now(ZTIMER64_USEC);
auto time = riot::now() += chrono::seconds(timeout);
cv.wait_until(lk, time);
after = ztimer64_now(ZTIMER64_USEC);
auto diff = after - before;
expect(diff >= timeout * US_PER_SEC);
}
puts("Done\n");
puts("Bye, bye. ");
puts("******************************************************\n");
return 0;
}