-
Notifications
You must be signed in to change notification settings - Fork 2
/
main.cpp
123 lines (100 loc) · 3.47 KB
/
main.cpp
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
#include <iostream>
#include <array>
#include <span>
#include <numeric>
#include <thread>
#include <chrono>
#include "uart_api.h"
#include "uart_iface.h"
template <class T, class Cast=T>
void print_span(const std::span<T> data, const char delimiter = '\0')
{
for (const auto& x : data) std::cout << static_cast<Cast>(x) << delimiter;
std::cout << "\n";
}
template <class T, class Cast=T>
void print_span_tsv(const std::span<T> data)
{
return print_span<T, Cast>(std::forward<const std::span<T>>(data), '\t');
}
void print_is_constructed()
{
using std::cout;
auto is_constructed = UART::Iface::is_constructed_all();
for (std::size_t i = 0 ; i < is_constructed.size() ; ++i)
cout << "UART" << i << " is " << (is_constructed[i] ? "" : "not ") << "constructed\n";
}
int main()
{
using std::cout;
using std::clog;
using std::cerr;
std::array<char, 10> countup, countdown;
std::iota(countup.begin(), countup.end(), 1);
std::iota(countdown.rbegin(), countdown.rend(), 1);
cout << "\nInitial data:\n";
print_span_tsv<char, int>(countup);
print_span_tsv<char, int>(countdown);
print_is_constructed();
cout << "\nSend data to persistent instance:\n";
auto h_uart0 = UART::Iface(UART0);
auto h_uart0_clone = UART::Iface(UART0, {57600});
if (h_uart0_clone)
{
cerr << "ERROR: got existing instance thats using different config\n";
return EXIT_FAILURE;
}
h_uart0.send(std::span<const char>(countup));
h_uart0.send(std::span<const char>(countdown));
{
cout << "\nSend data to rvalue instance:\n";
UART::Iface(UART1).send(std::span<const char>(countup));
UART::Iface(UART1).send(std::span<const char>(countdown));
}
{
cout << "\nSend data to scoped instance:\n";
auto h_uart1 = UART::Iface(UART1);
h_uart1.send(std::span<const char>(countup));
h_uart1.send(std::span<const char>(countdown));
}
{
cout << "\nSend data from multiple translation units:\n";
auto h_uart1 = UART::Iface(UART1);
h_uart1.send(std::span<const char>(countup));
//foo(UART1);
}
std::mutex mutex_cout{};
auto thread_fn = [&mutex_cout](UART_ID uart_id, bool forwards = true, std::size_t n_iterations = 5)
{
using namespace std::chrono_literals;
const auto this_id = std::this_thread::get_id();
auto h_uart = UART::Iface(uart_id);
auto& impl_mutx = h_uart.mutex();
std::array<char, 10> data;
std::iota(data.begin(), data.end(), 1);
{
std::scoped_lock lock(mutex_cout, impl_mutx);
clog << "Thread" << this_id << " starting\n";
}
for (std::size_t iter = 0 ; iter < n_iterations ; ++iter)
{
h_uart.send(std::span<const char>{data});
if (forwards) std::rotate(data.begin(), data.begin() + 1, data.end());
else std::rotate(data.rbegin(), data.rbegin() + 1, data.rend());
std::this_thread::sleep_for(1ms);
}
{
std::scoped_lock lock(mutex_cout, impl_mutx);
clog << "Thread" << this_id << " finished\n";
}
};
cout << "\nSend data from multiple threads:\n";
std::thread threads[] = {
std::thread(thread_fn, UART1),
std::thread(thread_fn, UART1, false)//,
//std::thread(thread_fn, UART0)
};
for (auto& thread : threads) thread.join();
cout << "\n--END--\n\n";
return EXIT_SUCCESS;
}