Compare commits

..

2 Commits

Author SHA1 Message Date
Erki
f4649142e5 Threads: SignalMux
All checks were successful
continuous-integration/drone/push Build is passing
Allows multiplexing multiple signals together.
2021-06-26 13:11:20 +03:00
Erki
9620c2206e Threads: refactor signals to simply return void
this is required for muxing signals together.
2021-06-26 13:10:57 +03:00
4 changed files with 92 additions and 25 deletions

View File

@ -55,20 +55,20 @@ public:
: q_(q) : q_(q)
{} {}
bool emit(const T& data) override void emit(const T& data) override
{ {
parent::value_type to_send = data; parent::value_type to_send = data;
const BaseType_t success = xQueueSend(q_->msg_queue_, &to_send, 0); xQueueSend(q_->msg_queue_, &to_send, 0);
return success == pdTRUE;
} }
std::pair<bool, BaseType_t> emitFromIsr(const T& data) override BaseType_t emitFromIsr(const T& data) override
{ {
parent::value_type to_send = data; parent::value_type to_send = data;
BaseType_t was_awoken = pdFALSE; BaseType_t was_awoken = pdFALSE;
const BaseType_t success = xQueueSendFromISR(q_->msg_queue_, &to_send, &was_awoken);
return {success == pdTRUE, was_awoken}; xQueueSendFromISR(q_->msg_queue_, &to_send, &was_awoken);
return was_awoken;
} }
private: private:
@ -192,22 +192,21 @@ private:
: q(q) : q(q)
{} {}
bool emit() override void emit() override
{ {
const int data = 0; const int data = 0;
const BaseType_t success = xQueueSend(q.msg_queue_, &data, 0); xQueueSend(q.msg_queue_, &data, 0);
return success == pdTRUE;
} }
std::pair<bool, BaseType_t> emitFromIsr() override BaseType_t emitFromIsr() override
{ {
const int data = 0; const int data = 0;
BaseType_t was_awoken = pdFALSE; BaseType_t was_awoken = pdFALSE;
const BaseType_t success = xQueueSendFromISR(q.msg_queue_, &data, &was_awoken); xQueueSendFromISR(q.msg_queue_, &data, &was_awoken);
return {success == pdTRUE, was_awoken}; return was_awoken;
} }
}; };

View File

@ -144,28 +144,26 @@ struct ExclusiveSignal<void> : public Signallable<void>
return currentThread.notifyWait(timeout); return currentThread.notifyWait(timeout);
} }
bool emit() override void emit() override
{ {
if (!waiting_thread_) if (waiting_thread_)
{ {
return false; auto const _ = waiting_thread_->notify(0, eNoAction);
} else (void) _;
{
return waiting_thread_->notify(0, eNoAction);
} }
} }
std::pair<bool, BaseType_t> emitFromIsr() override BaseType_t emitFromIsr() override
{ {
if (!waiting_thread_) if (!waiting_thread_)
{ {
return {false, pdFALSE}; return pdFALSE;
} else } else
{ {
auto const [discard, was_notified] = waiting_thread_->notifyFromIsr(0, eNoAction); auto const [discard, was_notified] = waiting_thread_->notifyFromIsr(0, eNoAction);
(void) discard; (void) discard;
return {true, was_notified}; return was_notified;
} }
} }

View File

@ -23,8 +23,8 @@ struct Signallable
static_assert(std::is_trivially_copyable_v<value_type>, "T must be trivially copyable."); static_assert(std::is_trivially_copyable_v<value_type>, "T must be trivially copyable.");
static_assert(std::is_default_constructible_v<value_type>, "T must be default constructible."); static_assert(std::is_default_constructible_v<value_type>, "T must be default constructible.");
virtual bool emit(const T& t) = 0; virtual void emit(const T& t) = 0;
virtual std::pair<bool, BaseType_t> emitFromIsr(const T& t) = 0; virtual BaseType_t emitFromIsr(const T& t) = 0;
}; };
template<> template<>
@ -32,8 +32,8 @@ struct Signallable<void>
{ {
using value_type = void; using value_type = void;
virtual bool emit() = 0; virtual void emit() = 0;
virtual std::pair<bool, BaseType_t> emitFromIsr() = 0; virtual BaseType_t emitFromIsr() = 0;
}; };
template<typename R> template<typename R>

View File

@ -0,0 +1,70 @@
/*
* threads_signal_mux.hpp
*
* Created on: Jun 26, 2021
* Author: erki
*/
#ifndef SKULLC_THREADS_SIGNAL_MUX_HPP_
#define SKULLC_THREADS_SIGNAL_MUX_HPP_
#include "threads_signal.hpp"
#include <algorithm>
#include <tuple>
namespace Threads
{
template<typename T, typename... Ss>
struct SignalMux : Signallable<T>
{
std::tuple<Ss...> signals;
SignalMux(Ss... args)
: signals(std::make_tuple(args...))
{}
SignalMux(Ss&&... args)
: signals(std::make_tuple(args...))
{}
void emit(const T& t) override
{
std::apply([&t](auto&... sig) { (..., sig.emit(t)); }, signals);
}
BaseType_t emitFromIsr(const T& t) override
{
BaseType_t higher_was_awoken = pdFALSE;
auto emitSignal = [&higher_was_awoken, &t](auto& sig) {
const BaseType_t awoken = sig.emitFromIsr(t);
higher_was_awoken = awoken || higher_was_awoken;
};
std::apply([&t, &emitSignal](auto&... sig) {
(..., emitSignal(sig));
},
signals);
return higher_was_awoken;
}
};
template<typename T, typename... Ss>
SignalMux<T, Ss...> makeSignalMux(Ss&&... args)
{
return SignalMux<T, Ss...>(std::forward(args...));
}
template<typename T, typename... Ss>
SignalMux<T, Ss...> makeSignalMux(Ss... args)
{
return SignalMux<T, Ss...>(args...);
}
}// namespace Threads
#endif /* SKULLC_THREADS_SIGNAL_MUX_HPP_ */