diff --git a/nemu/Makefile b/nemu/Makefile index 57860b6a50f54ca68556e6a401b887100970ba5f..d47a0af0ddf90c06f0fc9c47885855b5c321ffe4 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 560d1b08f36209fa834ee22aa3cce70b1ede2153..b36ae401cc29a4af046bc59ab548579e0d775e9e 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