From 0727403ac19b4e6088bc84d5b24714b0ddfb8f36 Mon Sep 17 00:00:00 2001 From: Pauli Date: Sat, 30 Jun 2018 21:12:29 +0300 Subject: [PATCH 1/2] Fix devel plugins linking in linux --- library/include/modules/Screen.h | 4 ++++ library/modules/Screen.cpp | 4 ++++ plugins/devel/zoom.cpp | 3 ++- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/library/include/modules/Screen.h b/library/include/modules/Screen.h index 673533f3e..ebe6d7ef6 100644 --- a/library/include/modules/Screen.h +++ b/library/include/modules/Screen.h @@ -35,6 +35,7 @@ distribution. #include "DataDefs.h" #include "df/graphic.h" #include "df/viewscreen.h" +#include "df/zoom_commands.h" #include "modules/GuiHooks.h" @@ -182,6 +183,9 @@ namespace DFHack return rect2d(df::coord2d(0,0), getWindowSize()-df::coord2d(1,1)); } + /// Wrapper to call enabler->zoom_display from plugins + DFHACK_EXPORT void zoom(df::zoom_commands cmd); + /// Returns the state of [GRAPHICS:YES/NO] DFHACK_EXPORT bool inGraphicsMode(); diff --git a/library/modules/Screen.cpp b/library/modules/Screen.cpp index 6ac39aa05..c6afa742a 100644 --- a/library/modules/Screen.cpp +++ b/library/modules/Screen.cpp @@ -90,6 +90,10 @@ df::coord2d Screen::getWindowSize() return df::coord2d(gps->dimx, gps->dimy); } +void Screen::zoom(df::zoom_commands cmd) { + enabler->zoom_display(cmd); +} + bool Screen::inGraphicsMode() { return init && init->display.flag.is_set(init_display_flags::USE_GRAPHICS); diff --git a/plugins/devel/zoom.cpp b/plugins/devel/zoom.cpp index d302d4900..80f4dfaf1 100644 --- a/plugins/devel/zoom.cpp +++ b/plugins/devel/zoom.cpp @@ -7,6 +7,7 @@ #include #include #include "modules/Gui.h" +#include "modules/Screen.h" #include "modules/World.h" #include "df/enabler.h" @@ -52,7 +53,7 @@ command_result df_zoom (color_ostream &out, std::vector & paramete return CR_FAILURE; } df::zoom_commands cmd = zcmap[parameters[0]]; - enabler->zoom_display(cmd); + Screen::zoom(cmd); if (cmd == df::zoom_commands::zoom_fullscreen) enabler->fullscreen = !enabler->fullscreen; return CR_OK; From 645ec0d591c4f8fee5c7ef2f8cf5dbdad99d7d2c Mon Sep 17 00:00:00 2001 From: Pauli Date: Sat, 30 Jun 2018 21:10:51 +0300 Subject: [PATCH 2/2] Improve kittens thread safety and shutdown with core The bools could use acquire&release memory order or even relaxed but I didn't think code was worth auditing for such low level optimizations. Sequantial consistent is fast enough but much harder to use incorrectly. The timeLast is protected by CoreSuspender lock. plugin_update is only called when CoreSuspender lock is held. The last_menu is protected by trackmenu_flg loads and stores. --- library/include/Console.h | 3 ++- plugins/devel/kittens.cpp | 43 ++++++++++++++++++--------------------- 2 files changed, 22 insertions(+), 24 deletions(-) diff --git a/library/include/Console.h b/library/include/Console.h index 0581f90e0..12ce94488 100644 --- a/library/include/Console.h +++ b/library/include/Console.h @@ -26,6 +26,7 @@ distribution. #include "Pragma.h" #include "Export.h" #include "ColorText.h" +#include #include #include #include @@ -163,6 +164,6 @@ namespace DFHack private: Private * d; tthread::recursive_mutex * wlock; - bool inited; + std::atomic inited; }; } diff --git a/plugins/devel/kittens.cpp b/plugins/devel/kittens.cpp index 395f48b97..5de94ced3 100644 --- a/plugins/devel/kittens.cpp +++ b/plugins/devel/kittens.cpp @@ -1,3 +1,4 @@ +#include #include #include @@ -24,13 +25,12 @@ DFHACK_PLUGIN_IS_ENABLED(is_enabled); REQUIRE_GLOBAL(ui); REQUIRE_GLOBAL(world); -//FIXME: possible race conditions with calling kittens from the IO thread and shutdown from Core. -volatile bool shutdown_flag = false; -volatile bool final_flag = true; -bool timering = false; -bool trackmenu_flg = false; -bool trackpos_flg = false; -bool statetrack = false; +std::atomic shutdown_flag{false}; +std::atomic final_flag{true}; +std::atomic timering{false}; +std::atomic trackmenu_flg{false}; +std::atomic trackpos_flg{0}; +std::atomic statetrack{0}; int32_t last_designation[3] = {-30000, -30000, -30000}; int32_t last_mouse[2] = {-1, -1}; df::ui_sidebar_mode last_menu = df::ui_sidebar_mode::Default; @@ -93,12 +93,10 @@ DFhackCExport command_result plugin_onstatechange(color_ostream &out, state_chan DFhackCExport command_result plugin_onupdate ( color_ostream &out ) { - if(timering == true) + if(timering) { uint64_t time2 = GetTimeMs64(); - // harmless potential data race here... uint64_t delta = time2-timeLast; - // harmless potential data race here... timeLast = time2; out.print("Time delta = %d ms\n", int(delta)); } @@ -135,30 +133,30 @@ DFhackCExport command_result plugin_onupdate ( color_ostream &out ) command_result trackmenu (color_ostream &out, vector & parameters) { - if(trackmenu_flg) + bool is_running = trackmenu_flg.exchange(false); + if(is_running) { - trackmenu_flg = false; return CR_OK; } else { - trackmenu_flg = true; is_enabled = true; last_menu = ui->main.mode; out.print("Menu: %d\n",last_menu); + trackmenu_flg = true; return CR_OK; } } command_result trackpos (color_ostream &out, vector & parameters) { - trackpos_flg = !trackpos_flg; + trackpos_flg.fetch_xor(1); is_enabled = true; return CR_OK; } command_result trackstate ( color_ostream& out, vector< string >& parameters ) { - statetrack = !statetrack; + statetrack.fetch_xor(1); return CR_OK; } @@ -180,20 +178,19 @@ command_result colormods (color_ostream &out, vector & parameters) command_result ktimer (color_ostream &out, vector & parameters) { - if(timering) + bool is_running = timering.exchange(false); + if(is_running) { - timering = false; return CR_OK; } uint64_t timestart = GetTimeMs64(); { CoreSuspender suspend; + uint64_t timeend = GetTimeMs64(); + timeLast = timeend; + timering = true; + out.print("Time to suspend = %d ms\n", int(timeend - timestart)); } - uint64_t timeend = GetTimeMs64(); - out.print("Time to suspend = %d ms\n", int(timeend - timestart)); - // harmless potential data race here... - timeLast = timeend; - timering = true; is_enabled = true; return CR_OK; } @@ -255,7 +252,7 @@ command_result kittens (color_ostream &out, vector & parameters) Console::color_value color = COLOR_BLUE; while(1) { - if(shutdown_flag) + if(shutdown_flag || !con.isInited()) { final_flag = true; con.reset_color();