From 49ae35e7cf105b778575026b1ce0641520bd9598 Mon Sep 17 00:00:00 2001 From: SoftCoder Date: Sat, 21 Nov 2015 11:30:23 -0800 Subject: [PATCH] - thread safe localtime and hopefully back to good performance --- source/glest_game/game/game.cpp | 28 ++++++----- source/glest_game/graphics/renderer.cpp | 7 +-- source/glest_game/main/main.cpp | 7 +-- .../glest_game/network/server_interface.cpp | 5 +- .../include/platform/common/platform_common.h | 7 +++ .../platform/common/platform_common.cpp | 48 ++++++++++++++----- .../shared_lib/sources/util/leak_dumper.cpp | 7 +-- source/shared_lib/sources/util/util.cpp | 5 +- 8 files changed, 77 insertions(+), 37 deletions(-) diff --git a/source/glest_game/game/game.cpp b/source/glest_game/game/game.cpp index fdc0b383..e0c6b11f 100644 --- a/source/glest_game/game/game.cpp +++ b/source/glest_game/game/game.cpp @@ -6460,20 +6460,22 @@ string Game::saveGame(string name, string path) { Config &config= Config::getInstance(); // auto name file if using saved file pattern string if(name == GameConstants::saveGameFilePattern) { - time_t curTime = time(NULL); - struct tm *loctime = localtime (&curTime); + //time_t curTime = time(NULL); + //struct tm *loctime = localtime (&curTime); + struct tm loctime = threadsafe_localtime(systemtime_now()); char szBuf2[100]=""; - strftime(szBuf2,100,"%Y%m%d_%H%M%S",loctime); + strftime(szBuf2,100,"%Y%m%d_%H%M%S",&loctime); char szBuf[8096]=""; snprintf(szBuf,8096,name.c_str(),szBuf2); name = szBuf; } else if(name == GameConstants::saveGameFileAutoTestDefault) { - time_t curTime = time(NULL); - struct tm *loctime = localtime (&curTime); + //time_t curTime = time(NULL); + //struct tm *loctime = localtime (&curTime); + struct tm loctime = threadsafe_localtime(systemtime_now()); char szBuf2[100]=""; - strftime(szBuf2,100,"%Y%m%d_%H%M%S",loctime); + strftime(szBuf2,100,"%Y%m%d_%H%M%S",&loctime); char szBuf[8096]=""; snprintf(szBuf,8096,name.c_str(),szBuf2); @@ -6504,10 +6506,11 @@ string Game::saveGame(string name, string path) { XmlNode *rootNodeReplay = xmlTreeSaveGame.getRootNode(); //std::map mapTagReplacements; - time_t now = time(NULL); - struct tm *loctime = localtime (&now); + //time_t now = time(NULL); + //struct tm *loctime = localtime (&now); + struct tm loctime = threadsafe_localtime(systemtime_now()); char szBuf[4096]=""; - strftime(szBuf,4095,"%Y-%m-%d %H:%M:%S",loctime); + strftime(szBuf,4095,"%Y-%m-%d %H:%M:%S",&loctime); rootNodeReplay->addAttribute("version",glestVersionString, mapTagReplacements); rootNodeReplay->addAttribute("timestamp",szBuf, mapTagReplacements); @@ -6533,10 +6536,11 @@ string Game::saveGame(string name, string path) { XmlNode *rootNode = xmlTree.getRootNode(); std::map mapTagReplacements; - time_t now = time(NULL); - struct tm *loctime = localtime (&now); + //time_t now = time(NULL); + //struct tm *loctime = localtime (&now); + struct tm loctime = threadsafe_localtime(systemtime_now()); char szBuf[4096]=""; - strftime(szBuf,4095,"%Y-%m-%d %H:%M:%S",loctime); + strftime(szBuf,4095,"%Y-%m-%d %H:%M:%S",&loctime); rootNode->addAttribute("version",glestVersionString, mapTagReplacements); rootNode->addAttribute("timestamp",szBuf, mapTagReplacements); diff --git a/source/glest_game/graphics/renderer.cpp b/source/glest_game/graphics/renderer.cpp index b608c803..7e6337c2 100644 --- a/source/glest_game/graphics/renderer.cpp +++ b/source/glest_game/graphics/renderer.cpp @@ -2334,10 +2334,11 @@ void Renderer::renderClock() { } if(config.getBool("InGameLocalClock","true") == true) { - time_t nowTime = time(NULL); - struct tm *loctime = localtime(&nowTime); + //time_t nowTime = time(NULL); + //struct tm *loctime = localtime(&nowTime); + struct tm loctime = threadsafe_localtime(systemtime_now()); char szBuf2[100]=""; - strftime(szBuf2,100,"%H:%M",loctime); + strftime(szBuf2,100,"%H:%M",&loctime); Lang &lang= Lang::getInstance(); char szBuf[200]=""; diff --git a/source/glest_game/main/main.cpp b/source/glest_game/main/main.cpp index 30aef0f6..2bc41c4d 100644 --- a/source/glest_game/main/main.cpp +++ b/source/glest_game/main/main.cpp @@ -588,10 +588,11 @@ void stackdumper(unsigned int type, EXCEPTION_POINTERS *ep, bool fatalExit) { #endif if(logFile.is_open() == true) { - time_t curtime = time (NULL); - struct tm *loctime = localtime (&curtime); + //time_t curtime = time (NULL); + //struct tm *loctime = localtime (&curtime); + struct tm loctime = threadsafe_localtime(systemtime_now()); char szBuf2[100]=""; - strftime(szBuf2,100,"%Y-%m-%d %H:%M:%S",loctime); + strftime(szBuf2,100,"%Y-%m-%d %H:%M:%S",&loctime); logFile << "[" << szBuf2 << "] Runtime Error information:" << std::endl; logFile << "======================================================" << std::endl; diff --git a/source/glest_game/network/server_interface.cpp b/source/glest_game/network/server_interface.cpp index 96bb9c5d..79685817 100644 --- a/source/glest_game/network/server_interface.cpp +++ b/source/glest_game/network/server_interface.cpp @@ -3092,9 +3092,10 @@ std::string ServerInterface::DumpStatsToLog(bool dumpToStringOnly) const { if(slot->isConnected() == true) { time_t connectTime = slot->getConnectedTime(); - struct tm *loctime = localtime (&connectTime); + //struct tm *loctime = localtime (&connectTime); + struct tm loctime = threadsafe_localtime(connectTime); char szBuf[8096] = ""; - strftime(szBuf,100,"%Y-%m-%d %H:%M:%S",loctime); + strftime(szBuf,100,"%Y-%m-%d %H:%M:%S",&loctime); const int HOURS_IN_DAY = 24; const int MINUTES_IN_HOUR = 60; diff --git a/source/shared_lib/include/platform/common/platform_common.h b/source/shared_lib/include/platform/common/platform_common.h index ff6a13cc..72b0f550 100644 --- a/source/shared_lib/include/platform/common/platform_common.h +++ b/source/shared_lib/include/platform/common/platform_common.h @@ -25,6 +25,7 @@ #include #include #include +#include #include "leak_dumper.h" #if (defined WIN32) && !(defined snprintf) @@ -90,6 +91,12 @@ public: virtual void ShellCommandOutput_CallbackEvent(string cmd,char *output,void *userdata) = 0; }; +typedef std::chrono::time_point system_time_point; +tm threadsafe_localtime(const time_t &time); +// extracting std::time_t from std:chrono for "now" +time_t systemtime_now(); + + // ===================================================== // class PerformanceTimer // ===================================================== diff --git a/source/shared_lib/sources/platform/common/platform_common.cpp b/source/shared_lib/sources/platform/common/platform_common.cpp index baa94879..a89f3749 100644 --- a/source/shared_lib/sources/platform/common/platform_common.cpp +++ b/source/shared_lib/sources/platform/common/platform_common.cpp @@ -102,6 +102,26 @@ int ScreenHeight = 600; } +/* + A thread safe localtime proxy +*/ +tm threadsafe_localtime(const time_t &time) { + tm tm_snapshot; +#if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__)) + localtime_s(&tm_snapshot, &time); +#else + localtime_r(&time, &tm_snapshot); // POSIX +#endif + return tm_snapshot; +} + +// extracting std::time_t from std:chrono for "now" +time_t systemtime_now() { + system_time_point system_now = std::chrono::system_clock::now(); + return std::chrono::system_clock::to_time_t(system_now); +} + + // ===================================== // PerformanceTimer // ===================================== @@ -786,9 +806,10 @@ pair hasCachedFileCRCValue(string crcCacheFile, uint32 &value) { value = crcValue; if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) { - struct tm *loctime = localtime (&refreshDate); + //struct tm *loctime = localtime (&refreshDate); + struct tm loctime = threadsafe_localtime(refreshDate); char szBuf1[100]=""; - strftime(szBuf1,100,"%Y-%m-%d %H:%M:%S",loctime); + strftime(szBuf1,100,"%Y-%m-%d %H:%M:%S",&loctime); SystemFlags::OutputDebug(SystemFlags::debugSystem, "=-=-=-=- READ CACHE for Cache file [%s] refreshDate = %ld [%s], crcValue = %u\n", @@ -796,19 +817,20 @@ pair hasCachedFileCRCValue(string crcCacheFile, uint32 &value) { } } else { - time_t now = time(NULL); - struct tm *loctime = localtime (&now); + //time_t now = time(NULL); + //struct tm *loctime = localtime (&now); + struct tm loctime = threadsafe_localtime(systemtime_now()); char szBuf1[100]=""; - strftime(szBuf1,100,"%Y-%m-%d %H:%M:%S",loctime); + strftime(szBuf1,100,"%Y-%m-%d %H:%M:%S",&loctime); - loctime = localtime (&refreshDate); + loctime = threadsafe_localtime(refreshDate); char szBuf2[100]=""; - strftime(szBuf2,100,"%Y-%m-%d %H:%M:%S",loctime); + strftime(szBuf2,100,"%Y-%m-%d %H:%M:%S",&loctime); if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) { SystemFlags::OutputDebug(SystemFlags::debugSystem, "=-=-=-=- NEED TO CALCULATE CRC for Cache file [%s] now = %ld [%s], refreshDate = %ld [%s], crcValue = %u\n", - crcCacheFile.c_str(),now, szBuf1, refreshDate, szBuf2, crcValue); + crcCacheFile.c_str(), systemtime_now(), szBuf1, refreshDate, szBuf2, crcValue); } } } @@ -844,9 +866,10 @@ void writeCachedFileCRCValue(string crcCacheFile, uint32 &crcValue, string actua time_t now = time(NULL); time_t refreshDate = now + (REFRESH_CRC_DAY_SECONDS * offset); - struct tm *loctime = localtime (&refreshDate); + //struct tm *loctime = localtime (&refreshDate); + struct tm loctime = threadsafe_localtime(refreshDate); char szBuf1[100]=""; - strftime(szBuf1,100,"%Y-%m-%d %H:%M:%S",loctime); + strftime(szBuf1,100,"%Y-%m-%d %H:%M:%S",&loctime); string writeGameVer = Shared::PlatformByteOrder::toCommonEndian(gameVersion); string writeGameGITVersion = Shared::PlatformByteOrder::toCommonEndian(gameGITVersion); @@ -904,9 +927,10 @@ time_t getFolderTreeContentsCheckSumRecursivelyLastGenerated(vector path uint32 crcValue = 0; pair crcResult = hasCachedFileCRCValue(crcCacheFile, crcValue); if(crcResult.first == true) { - struct tm *loctime = localtime (&crcResult.second); + //struct tm *loctime = localtime (&crcResult.second); + struct tm loctime = threadsafe_localtime(crcResult.second); char szBuf1[100]=""; - strftime(szBuf1,100,"%Y-%m-%d %H:%M:%S",loctime); + strftime(szBuf1,100,"%Y-%m-%d %H:%M:%S",&loctime); if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] scanning folders found CACHED FILE for cacheKey [%s] last updated [%s]\n",__FILE__,__FUNCTION__,__LINE__,cacheKey.c_str(),szBuf1); //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\n-------------- In [%s::%s Line: %d] scanning folders found CACHED FILE for cacheKey [%s] last updated [%s]\n",__FILE__,__FUNCTION__,__LINE__,cacheKey.c_str(),szBuf1); diff --git a/source/shared_lib/sources/util/leak_dumper.cpp b/source/shared_lib/sources/util/leak_dumper.cpp index 133b3e8d..92efcd1b 100644 --- a/source/shared_lib/sources/util/leak_dumper.cpp +++ b/source/shared_lib/sources/util/leak_dumper.cpp @@ -35,10 +35,11 @@ void AllocRegistry::dump(const char *path) { int leakCount=0; size_t leakBytes=0; - time_t debugTime = time(NULL); - struct tm *loctime = localtime (&debugTime); + //time_t debugTime = time(NULL); + //struct tm *loctime = localtime (&debugTime); + struct tm loctime = threadsafe_localtime(systemtime_now()); char szBuf2[100]=""; - strftime(szBuf2,100,"%Y-%m-%d %H:%M:%S",loctime); + strftime(szBuf2,100,"%Y-%m-%d %H:%M:%S",&loctime); #ifdef WIN32 FILE* f= _wfopen(utf8_decode(path).c_str(), L"wt"); diff --git a/source/shared_lib/sources/util/util.cpp b/source/shared_lib/sources/util/util.cpp index 0cbb7611..2f383fe8 100644 --- a/source/shared_lib/sources/util/util.cpp +++ b/source/shared_lib/sources/util/util.cpp @@ -454,8 +454,9 @@ void SystemFlags::logDebugEntry(DebugType type, string debugEntry, time_t debugT // Get the current time. // time_t curtime = time (NULL); // Convert it to local time representation. - struct tm *loctime = localtime (&debugTime); - strftime(szBuf2,100,"%Y-%m-%d %H:%M:%S",loctime); + //struct tm *loctime = localtime (&debugTime); + std::tm loctime = threadsafe_localtime(debugTime); + strftime(szBuf2,100,"%Y-%m-%d %H:%M:%S",&loctime); } /* va_list argList;