Add inter-thread communication
This commit is contained in:
parent
277c9500f9
commit
0132b3ca1d
|
@ -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;
|
||||||
|
}
|
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
2
main.cpp
2
main.cpp
|
@ -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();
|
||||||
|
|
Loading…
Reference in New Issue