From a6c4f29f835a9c768f217cb1fbf70d385dce3569 Mon Sep 17 00:00:00 2001 From: Recolic Keghart <root@recolic.net> Date: Sun, 29 Dec 2019 23:28:13 +0800 Subject: [PATCH] async device update --- nemu/Makefile | 2 +- nemu/src/device/device.cc | 26 +++++++++++++++++++------- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/nemu/Makefile b/nemu/Makefile index 57860b6..d47a0af 100644 --- a/nemu/Makefile +++ b/nemu/Makefile @@ -53,7 +53,7 @@ NEMU_EXEC := $(BINARY) $(ARGS) $(BINARY): $(OBJS) $(call git_commit, "compile") @echo + LD $@ - @$(LD) -O2 -rdynamic $(SO_LDLAGS) -o $@ $^ -lSDL2 -lreadline -ldl + @$(LD) -O2 -rdynamic $(SO_LDLAGS) -o $@ $^ -lSDL2 -lreadline -ldl -pthread run: $(BINARY) $(call git_commit, "run") diff --git a/nemu/src/device/device.cc b/nemu/src/device/device.cc index 560d1b0..b36ae40 100644 --- a/nemu/src/device/device.cc +++ b/nemu/src/device/device.cc @@ -6,13 +6,16 @@ #include <signal.h> #include <SDL2/SDL.h> +#include <thread> +#include <atomic> + #define TIMER_HZ 100 #define VGA_HZ 50 static uint64_t jiffy = 0; static struct itimerval it; -static int device_update_flag = false; -static int update_screen_flag = false; +static std::atomic<bool> device_update_flag(false); +static std::atomic<bool> update_screen_flag(false); void init_serial(); void init_timer(); @@ -37,12 +40,9 @@ static void timer_sig_handler(int signum) { Assert(ret == 0, "Can not set timer"); } -void device_update() { - if (!device_update_flag) { - return; - } - device_update_flag = false; +void device_update() {} // Now an independent thread will do it. +void device_update_impl() { if (update_screen_flag) { update_screen(); update_screen_flag = false; @@ -72,6 +72,16 @@ void device_update() { } } +static void device_update_thread_daemon() { + while(true) { + if(device_update_flag.exchange(false)) { + device_update_impl(); + } + // At most, 1000FPS + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } +} + void sdl_clear_event_queue() { SDL_Event event; while (SDL_PollEvent(&event)); @@ -93,6 +103,8 @@ void init_device() { it.it_value.tv_usec = 1000000 / TIMER_HZ; ret = setitimer(ITIMER_VIRTUAL, &it, NULL); Assert(ret == 0, "Can not set timer"); + + std::thread(device_update_thread_daemon).detach(); } #else -- GitLab