-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy patheventFlags.hpp
118 lines (91 loc) · 4.35 KB
/
eventFlags.hpp
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
#include "tickTimer.hpp"
#include "txCommon.hpp"
#include <bitset>
#include <climits>
#include <functional>
#include <string_view>
namespace ThreadX
{
/// Set and wait on event flags
class EventFlags : Native::TX_EVENT_FLAGS_GROUP
{
public:
enum class Option
{
dontClear,
clear
};
static constexpr size_t eventFlagBit{wordSize * CHAR_BIT};
/// external callback type
using NotifyCallback = std::function<void(EventFlags &)>;
using Bitmask = std::bitset<EventFlags::eventFlagBit>;
using BitmaskPair = std::pair<Error, Bitmask>;
static constexpr auto allBits{Bitmask{std::numeric_limits<Ulong>::max()}};
///
/// \param setNotifyCallback set notify callback. \sa NotifyCallback
explicit EventFlags(const std::string_view name, const NotifyCallback &setNotifyCallback = {});
~EventFlags();
/// \param bitMask flag bitmask to set
Error set(const Bitmask &bitMask);
/// \param bitMask flag bitmask to clear
Error clear(const Bitmask &bitMask = allBits);
// must be used for calls from initialization, timers, and ISRs
BitmaskPair get(const Bitmask &bitMask = allBits, const Option option = Option::clear);
BitmaskPair waitAll(const Bitmask &bitMask, const Option option = Option::clear);
template <class Clock, typename Duration> auto waitAllUntil(const Bitmask &bitMask, const std::chrono::time_point<Clock, Duration> &time, const Option option = Option::clear);
template <typename Rep, typename Period> auto waitAllFor(const Bitmask &bitMask, const std::chrono::duration<Rep, Period> &duration, const Option option = Option::clear);
BitmaskPair waitAny(const Bitmask &bitMask, const Option option = Option::clear);
template <class Clock, typename Duration> auto waitAnyUntil(const Bitmask &bitMask, const std::chrono::time_point<Clock, Duration> &time, const Option option = Option::clear);
template <typename Rep, typename Period> auto waitAnyFor(const Bitmask &bitMask, const std::chrono::duration<Rep, Period> &duration, const Option option = Option::clear);
std::string_view name() const;
private:
enum class FlagOption : Uint
{
any, ///< any resume, if any flag in bitmask is set
orInto = any,
anyClear, ///< anyClear resume, if any flag in bitmask is set and then clear.
all, ///< all resume, if all flags in bitmask are set
andInto = all,
allClear ///< allClear resume, if all flags in bitmask are set and then clear.
};
/// \param bitMask flag bitmask to get
/// \param duration Wait duration
/// \param option \sa Option
/// \return actual flags set
BitmaskPair waitFor(const Bitmask &bitMask, const auto &duration, const FlagOption flagOption);
static void setNotifyCallback(Native::TX_EVENT_FLAGS_GROUP *notifyGroupPtr);
const NotifyCallback m_setNotifyCallback;
};
template <class Clock, typename Duration> auto EventFlags::waitAllUntil(const Bitmask &bitMask, const std::chrono::time_point<Clock, Duration> &time, const Option option)
{
return waitAllFor(bitMask, time - Clock::now(), option);
}
template <typename Rep, typename Period> auto EventFlags::waitAllFor(const Bitmask &bitMask, const std::chrono::duration<Rep, Period> &duration, const Option option)
{
auto flagOption{FlagOption::allClear};
if (option == Option::dontClear)
{
flagOption = FlagOption::all;
}
return waitFor(bitMask, duration, flagOption);
}
template <class Clock, typename Duration> auto EventFlags::waitAnyUntil(const Bitmask &bitMask, const std::chrono::time_point<Clock, Duration> &time, const Option option)
{
return waitAnyFor(bitMask, time - Clock::now(), option);
}
template <typename Rep, typename Period> auto EventFlags::waitAnyFor(const Bitmask &bitMask, const std::chrono::duration<Rep, Period> &duration, const Option option)
{
auto flagOption{FlagOption::anyClear};
if (option == Option::dontClear)
{
flagOption = FlagOption::any;
}
return waitFor(bitMask, duration, flagOption);
}
EventFlags::BitmaskPair EventFlags::waitFor(const Bitmask &bitMask, const auto &duration, const FlagOption flagOption)
{
Ulong actualFlags{};
Error error{tx_event_flags_get(this, bitMask.to_ulong(), std::to_underlying(flagOption), std::addressof(actualFlags), TickTimer::ticks(duration))};
return {error, Bitmask{actualFlags}};
}
} // namespace ThreadX