Add inter-thread communication

This commit is contained in:
blankie 2023-01-18 23:34:17 +07:00
parent 277c9500f9
commit 0132b3ca1d
Signed by: blankie
GPG Key ID: CC15FC822C7F61F5
6 changed files with 82 additions and 4 deletions

49
arb.h Normal file
View File

@ -0,0 +1,49 @@
#pragma once
#include <atomic>
#include "logcat_thread.h"
#define ARB_MAX_SIZE 16
template<typename T>
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<size_t> _used = 0;
T _items[ARB_MAX_SIZE];
};
// function bodies must be in the header because https://stackoverflow.com/a/999383
template<typename T>
T* AtomicRingBuffer<T>::get() {
if (this->_used.load() == 0) {
return nullptr;
}
return &this->_items[this->_read];
}
template<typename T>
void AtomicRingBuffer<T>::increment_read() {
if (this->_used.load() == 0) {
return;
}
--this->_used;
this->_read = (this->_read + 1) % ARB_MAX_SIZE;
}
template<typename T>
void AtomicRingBuffer<T>::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;
}

View File

@ -3,6 +3,7 @@
#include "log.h" #include "log.h"
#include "config.h" #include "config.h"
#include "logcat_thread.h"
static inline void write_config_and_update_structures(const Config& config) { static inline void write_config_and_update_structures(const Config& config) {
try { 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<std::string>(*logcat_thread_item)) {
if (!log_entries.empty()) {
log_entries += '\n';
}
log_entries += std::move(std::get<std::string>(*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) { static inline void settings_window(Config& config, float* config_write_timer, bool* show_settings_window) {
if (!ImGui::Begin("Settings", show_settings_window)) { if (!ImGui::Begin("Settings", show_settings_window)) {
@ -132,11 +149,13 @@ static inline void debug_window() {
ImGui::End(); 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_settings_window = false;
static bool show_logs_window = false; static bool show_logs_window = false;
static size_t log_entries_read = 0; static size_t log_entries_read = 0;
check_for_logcat_items(logcat_thread);
debug_window(); debug_window();
if (show_settings_window) { if (show_settings_window) {

View File

@ -3,5 +3,6 @@
#include <imgui.h> #include <imgui.h>
#include "config.h" #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);

View File

@ -106,9 +106,12 @@ void LogcatThread::_run(std::stop_token stoken) {
while (!stoken.stop_requested()) { while (!stoken.stop_requested()) {
printf("(boop)\n"); printf("(boop)\n");
int ready_fds = epoll_wait(this->_epoll_fd, events, EPOLL_MAX_EVENTS, 1000); int ready_fds = epoll_wait(this->_epoll_fd, events, EPOLL_MAX_EVENTS, 1000);
if (ready_fds == -1) { 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; break;
} }

View File

@ -1,6 +1,10 @@
#pragma once #pragma once
#include <thread> #include <thread>
#include <variant>
#include "arb.h"
typedef std::variant<std::string> LogcatThreadItem;
class LogcatThread { class LogcatThread {
public: public:
@ -13,6 +17,8 @@ public:
void request_stop(); void request_stop();
void join(); void join();
AtomicRingBuffer<LogcatThreadItem> atomic_ring_buffer;
private: private:
void _run(std::stop_token stoken); void _run(std::stop_token stoken);

View File

@ -161,7 +161,7 @@ int main(int, char**) {
ImGui_ImplSDL2_NewFrame(); ImGui_ImplSDL2_NewFrame();
ImGui::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 // Rendering
ImGui::Render(); ImGui::Render();