From 0132b3ca1dba9ec31c9fc8a94fb6a998818a5666 Mon Sep 17 00:00:00 2001 From: blankie Date: Wed, 18 Jan 2023 23:34:17 +0700 Subject: [PATCH] Add inter-thread communication --- arb.h | 49 +++++++++++++++++++++++++++++++++++++++++++++++ event_loop.cpp | 21 +++++++++++++++++++- event_loop.h | 3 ++- logcat_thread.cpp | 5 ++++- logcat_thread.h | 6 ++++++ main.cpp | 2 +- 6 files changed, 82 insertions(+), 4 deletions(-) create mode 100644 arb.h diff --git a/arb.h b/arb.h new file mode 100644 index 0000000..df26ae0 --- /dev/null +++ b/arb.h @@ -0,0 +1,49 @@ +#pragma once + +#include +#include "logcat_thread.h" + +#define ARB_MAX_SIZE 16 + +template +class AtomicRingBuffer { +public: + T* get(); + void increment_read(); + void put_and_increment_write(T item); + +private: + size_t _read = 0; + size_t _write = 0; + std::atomic _used = 0; + T _items[ARB_MAX_SIZE]; +}; + +// function bodies must be in the header because https://stackoverflow.com/a/999383 + +template +T* AtomicRingBuffer::get() { + if (this->_used.load() == 0) { + return nullptr; + } + return &this->_items[this->_read]; +} + +template +void AtomicRingBuffer::increment_read() { + if (this->_used.load() == 0) { + return; + } + --this->_used; + this->_read = (this->_read + 1) % ARB_MAX_SIZE; +} + +template +void AtomicRingBuffer::put_and_increment_write(T item) { + while (this->_used.load() == ARB_MAX_SIZE) { + printf("spinlocking!!!\n"); + } + this->_items[this->_write] = std::move(item); + ++this->_used; + this->_write = (this->_write + 1) % ARB_MAX_SIZE; +} diff --git a/event_loop.cpp b/event_loop.cpp index bcd89a1..00f3b92 100644 --- a/event_loop.cpp +++ b/event_loop.cpp @@ -3,6 +3,7 @@ #include "log.h" #include "config.h" +#include "logcat_thread.h" static inline void write_config_and_update_structures(const Config& config) { try { @@ -13,6 +14,22 @@ static inline void write_config_and_update_structures(const Config& config) { } } +static inline void check_for_logcat_items(LogcatThread& logcat_thread) { + LogcatThreadItem* logcat_thread_item; + + while ((logcat_thread_item = logcat_thread.atomic_ring_buffer.get())) { + if (std::holds_alternative(*logcat_thread_item)) { + if (!log_entries.empty()) { + log_entries += '\n'; + } + log_entries += std::move(std::get(*logcat_thread_item)); + } else { + throw std::runtime_error("Cannot handle all possible logcat thread item variants"); + } + logcat_thread.atomic_ring_buffer.increment_read(); + } +} + static inline void settings_window(Config& config, float* config_write_timer, bool* show_settings_window) { if (!ImGui::Begin("Settings", show_settings_window)) { @@ -132,11 +149,13 @@ static inline void debug_window() { ImGui::End(); } -void event_loop(ImFont* monospace_font, Config& config, float* config_write_timer, bool* run_event_loop) { +void event_loop(ImFont* monospace_font, Config& config, float* config_write_timer, LogcatThread& logcat_thread, bool* run_event_loop) { static bool show_settings_window = false; static bool show_logs_window = false; static size_t log_entries_read = 0; + check_for_logcat_items(logcat_thread); + debug_window(); if (show_settings_window) { diff --git a/event_loop.h b/event_loop.h index 56adbc9..c9a4103 100644 --- a/event_loop.h +++ b/event_loop.h @@ -3,5 +3,6 @@ #include #include "config.h" +#include "logcat_thread.h" -void event_loop(ImFont* monospace_font, Config& config, float* config_write_timer, bool* run_event_loop); +void event_loop(ImFont* monospace_font, Config& config, float* config_write_timer, LogcatThread& logcat_thread, bool* run_event_loop); diff --git a/logcat_thread.cpp b/logcat_thread.cpp index 120c215..86c097c 100644 --- a/logcat_thread.cpp +++ b/logcat_thread.cpp @@ -106,9 +106,12 @@ void LogcatThread::_run(std::stop_token stoken) { while (!stoken.stop_requested()) { printf("(boop)\n"); + int ready_fds = epoll_wait(this->_epoll_fd, events, EPOLL_MAX_EVENTS, 1000); if (ready_fds == -1) { - printf("%s\n", format_log(std::string("epoll_wait(): ") + strerror(errno)).c_str()); + std::string log_entry = format_log(std::string("epoll_wait(): ") + strerror(errno)); + printf("%s\n", log_entry.c_str()); + this->atomic_ring_buffer.put_and_increment_write(std::move(log_entry)); break; } diff --git a/logcat_thread.h b/logcat_thread.h index d2f2496..c9dee9c 100644 --- a/logcat_thread.h +++ b/logcat_thread.h @@ -1,6 +1,10 @@ #pragma once #include +#include +#include "arb.h" + +typedef std::variant LogcatThreadItem; class LogcatThread { public: @@ -13,6 +17,8 @@ public: void request_stop(); void join(); + AtomicRingBuffer atomic_ring_buffer; + private: void _run(std::stop_token stoken); diff --git a/main.cpp b/main.cpp index f21ac4f..55cd87c 100644 --- a/main.cpp +++ b/main.cpp @@ -161,7 +161,7 @@ int main(int, char**) { ImGui_ImplSDL2_NewFrame(); ImGui::NewFrame(); - event_loop(monospace_font, config, &config_write_timer, &run_event_loop); + event_loop(monospace_font, config, &config_write_timer, logcat_thread, &run_event_loop); // Rendering ImGui::Render();