From f94be3db2f2bb6c1b359744cb915683095e4ee80 Mon Sep 17 00:00:00 2001 From: jacqueline Date: Wed, 26 Jul 2023 11:23:36 +1000 Subject: make event queue go faster --- src/events/include/event_queue.hpp | 106 ++++++++++++++++++++++--------------- 1 file changed, 62 insertions(+), 44 deletions(-) (limited to 'src/events/include/event_queue.hpp') diff --git a/src/events/include/event_queue.hpp b/src/events/include/event_queue.hpp index 95c331d5..1ea67446 100644 --- a/src/events/include/event_queue.hpp +++ b/src/events/include/event_queue.hpp @@ -7,6 +7,8 @@ #pragma once #include +#include +#include #include #include "audio_fsm.hpp" @@ -20,62 +22,78 @@ namespace events { -typedef std::function WorkItem; - -/* - * Handles communication of events between the system's state machines. Each - * event will be dispatched separately to each FSM, on the correct task for - * that FSM. - */ -class EventQueue { +class Queue { public: - static EventQueue& GetInstance() { - static EventQueue instance; - return instance; - } + Queue() : has_events_(xSemaphoreCreateBinary()), mut_(), events_() {} - template - auto DispatchFromISR(const Event& ev) -> bool { - WorkItem* item = new WorkItem([=]() { - tinyfsm::FsmList::template dispatch(ev); - }); - BaseType_t ret; - xQueueSendFromISR(system_handle_, &item, &ret); - return ret; + auto Add(std::function fn) { + { + std::lock_guard lock{mut_}; + events_.push(fn); + } + xSemaphoreGive(has_events_); } - template - auto Dispatch(const Event& ev) -> void { - WorkItem* item = new WorkItem( - [=]() { tinyfsm::FsmList::template dispatch(ev); }); - if (std::is_same()) { - xQueueSend(ui_handle_, &item, portMAX_DELAY); - } else { - xQueueSend(system_handle_, &item, portMAX_DELAY); + auto Service(TickType_t max_wait) -> bool { + bool res = xSemaphoreTake(has_events_, max_wait); + if (!res) { + return false; } - Dispatch(ev); - } - template - auto Dispatch(const Event& ev) -> void {} + bool had_work = false; + for (;;) { + std::function fn; + { + std::lock_guard lock{mut_}; + if (events_.empty()) { + return had_work; + } + had_work = true; + fn = events_.front(); + events_.pop(); + } + std::invoke(fn); + } + } - auto ServiceSystemAndAudio(TickType_t max_wait_time) -> bool; - auto ServiceUi(TickType_t max_wait_time) -> bool; + auto has_events() -> SemaphoreHandle_t { return has_events_; } - EventQueue(EventQueue const&) = delete; - void operator=(EventQueue const&) = delete; + Queue(Queue const&) = delete; + void operator=(Queue const&) = delete; private: - EventQueue(); + SemaphoreHandle_t has_events_; + std::mutex mut_; + std::queue> events_; +}; + +template +class Dispatcher { + public: + Dispatcher(Queue* queue) : queue_(queue) {} + + template + auto Dispatch(const Event& ev) -> void { + auto dispatch_fn = [=]() { + tinyfsm::FsmList::template dispatch(ev); + }; + queue_->Add(dispatch_fn); + } + + Dispatcher(Dispatcher const&) = delete; + void operator=(Dispatcher const&) = delete; - QueueHandle_t system_handle_; - QueueHandle_t ui_handle_; + private: + Queue* queue_; }; -template -auto Dispatch(const Event& ev) -> void { - EventQueue& queue = EventQueue::GetInstance(); - queue.Dispatch(ev); -} +namespace queues { +auto SystemAndAudio() -> Queue*; +auto Ui() -> Queue*; +} // namespace queues + +auto System() -> Dispatcher&; +auto Audio() -> Dispatcher&; +auto Ui() -> Dispatcher&; } // namespace events -- cgit v1.2.3