From e2ab622a148c2698e589303e835a7660bfe5b42b Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Sat, 11 Apr 2020 18:23:38 +0100 Subject: [PATCH] Avoid data race in modal progress mode --- src/gfx.cpp | 7 ++++++- src/newgrf_config.cpp | 16 +++++++++++++--- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/gfx.cpp b/src/gfx.cpp index e48de20a64..364fca20a2 100644 --- a/src/gfx.cpp +++ b/src/gfx.cpp @@ -1490,12 +1490,17 @@ void DrawDirtyBlocks() if (HasModalProgress()) { /* We are generating the world, so release our rights to the map and * painting while we are waiting a bit. */ + bool is_first_modal_progress_loop = IsFirstModalProgressLoop(); _modal_progress_paint_mutex.unlock(); _modal_progress_work_mutex.unlock(); /* Wait a while and update _realtime_tick so we are given the rights */ - if (!IsFirstModalProgressLoop()) CSleep(MODAL_PROGRESS_REDRAW_TIMEOUT); + if (!is_first_modal_progress_loop) CSleep(MODAL_PROGRESS_REDRAW_TIMEOUT); +#if defined(__GNUC__) || defined(__clang__) + __atomic_add_fetch(&_realtime_tick, MODAL_PROGRESS_REDRAW_TIMEOUT, __ATOMIC_RELAXED); +#else _realtime_tick += MODAL_PROGRESS_REDRAW_TIMEOUT; +#endif /* Modal progress thread may need blitter access while we are waiting for it. */ VideoDriver::GetInstance()->ReleaseBlitterLock(); diff --git a/src/newgrf_config.cpp b/src/newgrf_config.cpp index fce97bd289..b3b25506a8 100644 --- a/src/newgrf_config.cpp +++ b/src/newgrf_config.cpp @@ -721,8 +721,13 @@ class GRFFileScanner : FileScanner { std::vector grfs; public: - GRFFileScanner() : next_update(_realtime_tick), num_scanned(0) + GRFFileScanner() : num_scanned(0) { +#if defined(__GNUC__) || defined(__clang__) + this->next_update = __atomic_load_n(&_realtime_tick, __ATOMIC_RELAXED); +#else + this->next_update = _realtime_tick; +#endif } bool AddFile(const char *filename, size_t basepath_length, const char *tar_filename) override; @@ -783,7 +788,12 @@ bool GRFFileScanner::AddFile(const char *filename, size_t basepath_length, const } this->num_scanned++; - if (this->next_update <= _realtime_tick) { +#if defined(__GNUC__) || defined(__clang__) + const uint32 now = __atomic_load_n(&_realtime_tick, __ATOMIC_RELAXED); +#else + const uint32 now = _realtime_tick; +#endif + if (this->next_update <= now) { _modal_progress_work_mutex.unlock(); _modal_progress_paint_mutex.lock(); @@ -795,7 +805,7 @@ bool GRFFileScanner::AddFile(const char *filename, size_t basepath_length, const _modal_progress_work_mutex.lock(); _modal_progress_paint_mutex.unlock(); - this->next_update = _realtime_tick + MODAL_PROGRESS_REDRAW_TIMEOUT; + this->next_update = now + MODAL_PROGRESS_REDRAW_TIMEOUT; } if (!added) {