From 44d8301bb2e66a60760c0fa5f5ad8dcde1c9d0d1 Mon Sep 17 00:00:00 2001 From: "gregory.hainaut" Date: Tue, 10 Sep 2013 11:41:11 +0000 Subject: [PATCH] spu2x: array out of bond (-1) Performance note, it might be faster to replace the MODULO with an AND. Not sure on the impact for the new time stretcher algo. GSdx: fixed use-after-free (linux) PCSX2: * add a define to support address sanitizer (both rely on 0x20000000-0x3fffffff memory ranges..) * sio_buffer out of bond (-1). Maybe we can move the flush in the 2 if previous branch. It would avoid the extra test. * wxGetEnv (linux) generates double free (maybe not thread safe). Cache the result so it doesn't crash anymore when switching renderer Comment/Review/Improvement are welcome :) git-svn-id: http://pcsx2.googlecode.com/svn/trunk@5727 96395faa-99c1-11dd-bbfe-3dabce05a288 --- pcsx2/HwWrite.cpp | 2 +- pcsx2/System.h | 15 +++++++++++++++ pcsx2/gui/AppMain.cpp | 10 +++++++++- plugins/GSdx/GSdx.cpp | 5 ++++- plugins/spu2-x/src/Timestretcher.cpp | 5 ++++- 5 files changed, 33 insertions(+), 4 deletions(-) diff --git a/pcsx2/HwWrite.cpp b/pcsx2/HwWrite.cpp index 4393631867..932d0aa022 100644 --- a/pcsx2/HwWrite.cpp +++ b/pcsx2/HwWrite.cpp @@ -231,7 +231,7 @@ void __fastcall _hwWrite8(u32 mem, u8 value) sio_buffer[sio_count++] = value; } - if ((sio_count == ArraySize(sio_buffer)-1) || (sio_buffer[sio_count-1] == '\n')) + if ((sio_count == ArraySize(sio_buffer)-1) || (sio_count != 0 && sio_buffer[sio_count-1] == '\n')) { sio_buffer[sio_count] = 0; eeConLog( ShiftJIS_ConvertString(sio_buffer) ); diff --git a/pcsx2/System.h b/pcsx2/System.h index 506bf00bb8..f68dcf7905 100644 --- a/pcsx2/System.h +++ b/pcsx2/System.h @@ -46,6 +46,20 @@ namespace HostMemoryMap static const uptr sVU0rec = _256mb - (_8mb*3); static const uptr sVU1rec = _256mb - (_8mb*2); +#ifdef ASAN_WORKAROUND + // address sanitizer uses a shadow memory to monitor the state of the memory. Shadow is computed + // as S = (M >> 3) + 0x20000000. So PCSX2 can't use 0x20000000 to 0x3FFFFFFF... Just add another + // 0x20000000 offset to avoid conflict. + static const uptr EEmem = 0x40000000; + static const uptr IOPmem = 0x44000000; + static const uptr VUmem = 0x48000000; + static const uptr EErec = 0x50000000; + static const uptr IOPrec = 0x54000000; + static const uptr VIF0rec = 0x56000000; + static const uptr VIF1rec = 0x58000000; + static const uptr mVU0rec = 0x5C000000; + static const uptr mVU1rec = 0x60000000; +#else // PS2 main memory, SPR, and ROMs static const uptr EEmem = 0x20000000; @@ -72,6 +86,7 @@ namespace HostMemoryMap // microVU0 recompiler code cache area (64mb) static const uptr mVU1rec = 0x40000000; +#endif } diff --git a/pcsx2/gui/AppMain.cpp b/pcsx2/gui/AppMain.cpp index 3e4f4487b5..ce521700c7 100644 --- a/pcsx2/gui/AppMain.cpp +++ b/pcsx2/gui/AppMain.cpp @@ -356,6 +356,11 @@ public: #ifdef __LINUX__ wxString GetUserLocalDataDir() const { + // I got memory corruption inside wxGetEnv when I heavily toggle the GS renderer (F9). It seems wxGetEnv + // isn't thread safe? To avoid any issue on this read only variable, I cache the result. + static wxString cache_dir; + if (!cache_dir.IsEmpty()) return cache_dir; + // Note: GetUserLocalDataDir() on linux return $HOME/.pcsx2 unfortunately it does not follow the XDG standard // So we re-implement it, to follow the standard. wxDirName user_local_dir; @@ -371,7 +376,10 @@ public: // variable do not exist user_local_dir = (wxDirName)Path::Combine( GetUserConfigDir() , wxDirName( L".config/pcsx2" )); } - return user_local_dir.ToString(); + + cache_dir = user_local_dir.ToString(); + + return cache_dir; } #endif }; diff --git a/plugins/GSdx/GSdx.cpp b/plugins/GSdx/GSdx.cpp index 0140a42b39..a726b60193 100644 --- a/plugins/GSdx/GSdx.cpp +++ b/plugins/GSdx/GSdx.cpp @@ -172,12 +172,15 @@ GSdxApp::GSdxApp() #ifdef _LINUX void GSdxApp::ReloadConfig() { + if (m_configuration_map.empty()) return; + auto file = m_configuration_map.find("inifile"); if (file == m_configuration_map.end()) return; // A map was built so reload it + std::string filename = file->second; m_configuration_map.clear(); - BuildConfigurationMap(file->second.c_str()); + BuildConfigurationMap(filename.c_str()); } void GSdxApp::BuildConfigurationMap(const char* lpFileName) diff --git a/plugins/spu2-x/src/Timestretcher.cpp b/plugins/spu2-x/src/Timestretcher.cpp index dad23a9364..5466a876d0 100644 --- a/plugins/spu2-x/src/Timestretcher.cpp +++ b/plugins/spu2-x/src/Timestretcher.cpp @@ -100,6 +100,9 @@ int targetIPS=750; //running average can be implemented in O(1) time. //For the sake of simplicity, this average is calculated in O(). Possibly improve later. +// +//Additional performance note: if MAX_STRETCH_AVERAGE_LEN = 128 (or any power of 2), the '%' below +//could be replaced with a faster '&'. However analysis of NEWSTRETCHER_USE_DYNAMIC_TUNING impact must be done #define MAX_STRETCH_AVERAGE_LEN 100 int STRETCH_AVERAGE_LEN=50.0 *targetIPS/750; //adds a value to the running average buffer, and return new running average. @@ -110,7 +113,7 @@ float addToAvg(float val){ avg_fullness[nextAvgPos]=val; nextAvgPos=(nextAvgPos+1)%STRETCH_AVERAGE_LEN; float sum=0; - for(int c=0, i=(nextAvgPos-1)%STRETCH_AVERAGE_LEN; c