diff --git a/interface/src/ui/Stats.cpp b/interface/src/ui/Stats.cpp index 6bb615948c..c3b1b0c819 100644 --- a/interface/src/ui/Stats.cpp +++ b/interface/src/ui/Stats.cpp @@ -431,7 +431,7 @@ void Stats::updateStats(bool force) { // a new Map sorted by average time... bool onlyDisplayTopTen = Menu::getInstance()->isOptionChecked(MenuOption::OnlyDisplayTopTen); QMap sortedRecords; - const QMap& allRecords = PerformanceTimer::getAllTimerRecords(); + auto allRecords = PerformanceTimer::getAllTimerRecords(); QMapIterator i(allRecords); while (i.hasNext()) { @@ -479,7 +479,7 @@ void Stats::updateStats(bool force) { bool operator<(const SortableStat& other) const { return priority < other.priority; } }; - const QMap& allRecords = PerformanceTimer::getAllTimerRecords(); + auto allRecords = PerformanceTimer::getAllTimerRecords(); std::priority_queue idleUpdateStats; auto itr = allRecords.find("/idle/update"); if (itr != allRecords.end()) { @@ -496,7 +496,7 @@ void Stats::updateStats(bool force) { }; for (int32_t j = 0; j < categories.size(); ++j) { QString recordKey = "/idle/update/" + categories[j]; - auto record = PerformanceTimer::getTimerRecord(recordKey); + auto& record = allRecords[recordKey]; if (record.getCount()) { float dt = (float) record.getMovingAverage() / (float)USECS_PER_MSEC; QString message = QString("\n %1 = %2").arg(categories[j]).arg(dt); diff --git a/libraries/shared/src/PerfStat.cpp b/libraries/shared/src/PerfStat.cpp index c3bc44b7d3..2fc1fb3c9b 100644 --- a/libraries/shared/src/PerfStat.cpp +++ b/libraries/shared/src/PerfStat.cpp @@ -80,16 +80,19 @@ void PerformanceTimerRecord::tallyResult(const quint64& now) { // ---------------------------------------------------------------------------- std::atomic PerformanceTimer::_isActive(false); +std::mutex PerformanceTimer::_mutex; QHash PerformanceTimer::_fullNames; QMap PerformanceTimer::_records; - PerformanceTimer::PerformanceTimer(const QString& name) { if (_isActive) { _name = name; - QString& fullName = _fullNames[QThread::currentThread()]; - fullName.append("/"); - fullName.append(_name); + { + std::lock_guard guard(_mutex); + QString& fullName = _fullNames[QThread::currentThread()]; + fullName.append("/"); + fullName.append(_name); + } _start = usecTimestampNow(); } } @@ -97,6 +100,7 @@ PerformanceTimer::PerformanceTimer(const QString& name) { PerformanceTimer::~PerformanceTimer() { if (_isActive && _start != 0) { quint64 elapsedUsec = (usecTimestampNow() - _start); + std::lock_guard guard(_mutex); QString& fullName = _fullNames[QThread::currentThread()]; PerformanceTimerRecord& namedRecord = _records[fullName]; namedRecord.accumulateResult(elapsedUsec); @@ -111,11 +115,13 @@ bool PerformanceTimer::isActive() { // static QString PerformanceTimer::getContextName() { + std::lock_guard guard(_mutex); return _fullNames[QThread::currentThread()]; } // static void PerformanceTimer::addTimerRecord(const QString& fullName, quint64 elapsedUsec) { + std::lock_guard guard(_mutex); PerformanceTimerRecord& namedRecord = _records[fullName]; namedRecord.accumulateResult(elapsedUsec); } @@ -125,6 +131,7 @@ void PerformanceTimer::setActive(bool active) { if (active != _isActive) { _isActive.store(active); if (!active) { + std::lock_guard guard(_mutex); _fullNames.clear(); _records.clear(); } @@ -133,8 +140,15 @@ void PerformanceTimer::setActive(bool active) { } } +// static +QMap PerformanceTimer::getAllTimerRecords() { + std::lock_guard guard(_mutex); + return _records; +}; + // static void PerformanceTimer::tallyAllTimerRecords() { + std::lock_guard guard(_mutex); QMap::iterator recordsItr = _records.begin(); QMap::const_iterator recordsEnd = _records.end(); quint64 now = usecTimestampNow(); @@ -150,6 +164,7 @@ void PerformanceTimer::tallyAllTimerRecords() { } void PerformanceTimer::dumpAllTimerRecords() { + std::lock_guard guard(_mutex); QMapIterator i(_records); while (i.hasNext()) { i.next(); diff --git a/libraries/shared/src/PerfStat.h b/libraries/shared/src/PerfStat.h index b09cb38808..f9ff6960b0 100644 --- a/libraries/shared/src/PerfStat.h +++ b/libraries/shared/src/PerfStat.h @@ -84,8 +84,7 @@ public: static QString getContextName(); static void addTimerRecord(const QString& fullName, quint64 elapsedUsec); - static const PerformanceTimerRecord& getTimerRecord(const QString& name) { return _records[name]; }; - static const QMap& getAllTimerRecords() { return _records; }; + static QMap getAllTimerRecords(); static void tallyAllTimerRecords(); static void dumpAllTimerRecords(); @@ -93,6 +92,8 @@ private: quint64 _start = 0; QString _name; static std::atomic _isActive; + + static std::mutex _mutex; // used to guard multi-threaded access to _fullNames and _records static QHash _fullNames; static QMap _records; };