diff options
| author | Andrey Kleshchev <117672381+akleshchev@users.noreply.github.com> | 2026-02-10 03:40:48 +0200 |
|---|---|---|
| committer | Andrey Kleshchev <117672381+akleshchev@users.noreply.github.com> | 2026-02-11 03:29:48 +0200 |
| commit | 6be26a000007af922788ccfd94ec0c6835b1d28e (patch) | |
| tree | 9fdfc1e0c405613ea726bc9295e49aa11fd1c1c5 /indra/newview/lltexturecache.cpp | |
| parent | 58c405ca5fde2ab73b132b1fc2652f0c41cd19c2 (diff) | |
#5356 Fix fast texture cache's mutex stall
Diffstat (limited to 'indra/newview/lltexturecache.cpp')
| -rw-r--r-- | indra/newview/lltexturecache.cpp | 62 |
1 files changed, 47 insertions, 15 deletions
diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp index 2f8158f6f2..2e7f353e03 100644 --- a/indra/newview/lltexturecache.cpp +++ b/indra/newview/lltexturecache.cpp @@ -875,7 +875,7 @@ std::string LLTextureCache::getTextureFileName(const LLUUID& id) //debug bool LLTextureCache::isInCache(const LLUUID& id) { - LLMutexLock lock(&mHeaderMutex); + LLMutexLock lock(&mHeaderIDMapMutex); id_map_t::const_iterator iter = mHeaderIDMap.find(id); return (iter != mHeaderIDMap.end()) ; @@ -1117,10 +1117,13 @@ S32 LLTextureCache::openAndReadEntry(const LLUUID& id, Entry& entry, bool create { S32 idx = -1; - id_map_t::iterator iter1 = mHeaderIDMap.find(id); - if (iter1 != mHeaderIDMap.end()) { - idx = iter1->second; + LLMutexLock lock(&mHeaderIDMapMutex); + id_map_t::iterator iter1 = mHeaderIDMap.find(id); + if (iter1 != mHeaderIDMap.end()) + { + idx = iter1->second; + } } if (idx < 0) @@ -1148,10 +1151,19 @@ S32 LLTextureCache::openAndReadEntry(const LLUUID& id, Entry& entry, bool create // Erase entry from LRU regardless mLRU.erase(curiter2); // Look up entry and use it if it is valid - id_map_t::iterator iter3 = mHeaderIDMap.find(oldid); - if (iter3 != mHeaderIDMap.end() && iter3->second >= 0) + + S32 found_idx = -1; { - idx = iter3->second; + LLMutexLock lock(&mHeaderIDMapMutex); + id_map_t::iterator iter3 = mHeaderIDMap.find(oldid); + if (iter3 != mHeaderIDMap.end() && iter3->second >= 0) + { + found_idx = iter3->second; + } + } + if (found_idx >= 0) + { + idx = found_idx; removeCachedTexture(oldid) ;//remove the existing cached texture to release the entry index. break; } @@ -1287,7 +1299,10 @@ bool LLTextureCache::updateEntry(S32& idx, Entry& entry, S32 new_image_size, S32 bool update_header = false ; if(entry.mImageSize < 0) //is a brand-new entry { - mHeaderIDMap[entry.mID] = idx; + { + LLMutexLock lock(&mHeaderIDMapMutex); + mHeaderIDMap[entry.mID] = idx; + } mTexturesSizeMap[entry.mID] = new_body_size ; mTexturesSizeTotal += new_body_size ; @@ -1325,8 +1340,8 @@ bool LLTextureCache::updateEntry(S32& idx, Entry& entry, S32 new_image_size, S32 U32 LLTextureCache::openAndReadEntries(std::vector<Entry>& entries) { + LLMutexLock lock(&mHeaderIDMapMutex); U32 num_entries = mHeaderEntriesInfo.mEntries; - mHeaderIDMap.clear(); mTexturesSizeMap.clear(); mFreeList.clear(); @@ -1620,7 +1635,10 @@ void LLTextureCache::purgeAllTextures(bool purge_directories) LLFile::rmdir(mTexturesDirName); } } - mHeaderIDMap.clear(); + { + LLMutexLock lock(&mHeaderIDMapMutex); + mHeaderIDMap.clear(); + } mTexturesSizeMap.clear(); mTexturesSizeTotal = 0; mFreeList.clear(); @@ -1667,6 +1685,7 @@ void LLTextureCache::purgeTexturesLazy(F32 time_limit_sec) { if (iter1->second > 0) { + LLMutexLock lock(&mHeaderIDMapMutex); id_map_t::iterator iter2 = mHeaderIDMap.find(iter1->first); if (iter2 != mHeaderIDMap.end()) { @@ -1708,8 +1727,13 @@ void LLTextureCache::purgeTexturesLazy(F32 time_limit_sec) Entry entry = mPurgeEntryList.back().second; mPurgeEntryList.pop_back(); // make sure record is still valid - id_map_t::iterator iter_header = mHeaderIDMap.find(entry.mID); - if (iter_header != mHeaderIDMap.end() && iter_header->second == idx) + bool remove_entry = false; + { + LLMutexLock lock(&mHeaderIDMapMutex); + id_map_t::iterator iter_header = mHeaderIDMap.find(entry.mID); + remove_entry = (iter_header != mHeaderIDMap.end() && iter_header->second == idx); + } + if (remove_entry) { std::string tex_filename = getTextureFileName(entry.mID); removeEntry(idx, entry, tex_filename); @@ -1752,6 +1776,7 @@ void LLTextureCache::purgeTextures(bool validate) { if (iter1->second > 0) { + LLMutexLock lock(&mHeaderIDMapMutex); id_map_t::iterator iter2 = mHeaderIDMap.find(iter1->first); if (iter2 != mHeaderIDMap.end()) { @@ -2006,7 +2031,7 @@ LLPointer<LLImageRaw> LLTextureCache::readFromFastCache(const LLUUID& id, S32& d { U32 offset; { - LLMutexLock lock(&mHeaderMutex); + LLMutexLock lock(&mHeaderIDMapMutex); id_map_t::const_iterator iter = mHeaderIDMap.find(id); if(iter == mHeaderIDMap.end()) { @@ -2020,6 +2045,7 @@ LLPointer<LLImageRaw> LLTextureCache::readFromFastCache(const LLUUID& id, S32& d U8* data; S32 head[4]; { + LL_PROFILE_ZONE_NAMED("Read fast cache"); LLMutexLock lock(&mFastCacheMutex); openFastCache(); @@ -2231,7 +2257,10 @@ void LLTextureCache::removeCachedTexture(const LLUUID& id) mTexturesSizeTotal -= mTexturesSizeMap[id] ; mTexturesSizeMap.erase(id); } - mHeaderIDMap.erase(id); + { + LLMutexLock lock(&mHeaderIDMapMutex); + mHeaderIDMap.erase(id); + } // We are inside header's mutex so mHeaderAPRFilePoolp is safe to use, // but getLocalAPRFilePool() is not safe, it might be in use by worker LLAPRFile::remove(getTextureFileName(id), mHeaderAPRFilePoolp); @@ -2262,7 +2291,10 @@ void LLTextureCache::removeEntry(S32 idx, Entry& entry, std::string& filename) entry.mImageSize = -1; entry.mBodySize = 0; - mHeaderIDMap.erase(entry.mID); + { + LLMutexLock lock(&mHeaderIDMapMutex); + mHeaderIDMap.erase(entry.mID); + } mTexturesSizeMap.erase(entry.mID); mFreeList.insert(idx); } |
