diff options
Diffstat (limited to 'indra/newview/llmeshrepository.cpp')
-rwxr-xr-x | indra/newview/llmeshrepository.cpp | 134 |
1 files changed, 89 insertions, 45 deletions
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 7146c7f4f5..97d6c57a78 100755 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -155,20 +155,26 @@ // // So, in addition to documentation, take this as a to-do/review // list and see if you can improve things. For porters to non-x86 -// architectures, including amd64, the weaker memory models will -// make these platforms probabilistically more susceptible to hitting -// race conditions. True here and in other multi-thread code such -// as texture fetching. +// architectures, the weaker memory models will make these platforms +// probabilistically more susceptible to hitting race conditions. +// True here and in other multi-thread code such as texture fetching. +// (Strong memory models make weak programmers. Weak memory models +// make strong programmers. Ref: arm, ppc, mips, alpha) // // LLMeshRepository: // // sBytesReceived +// sMeshRequestCount // sHTTPRequestCount +// sHTTPLargeRequestCount // sHTTPRetryCount +// sHTTPErrorCount // sLODPending // sLODProcessing // sCacheBytesRead // sCacheBytesWritten +// sCacheReads +// sCacheWrites // mLoadingMeshes none rw.main.none, rw.main.mMeshMutex [4] // mSkinMap none rw.main.none // mDecompositionMap none rw.main.none @@ -246,13 +252,19 @@ const long LARGE_MESH_XFER_TIMEOUT = 600L; // Seconds to complete xfer, large const S32 MAX_MESH_VERSION = 999; U32 LLMeshRepository::sBytesReceived = 0; +U32 LLMeshRepository::sMeshRequestCount = 0; U32 LLMeshRepository::sHTTPRequestCount = 0; +U32 LLMeshRepository::sHTTPLargeRequestCount = 0; U32 LLMeshRepository::sHTTPRetryCount = 0; +U32 LLMeshRepository::sHTTPErrorCount = 0; U32 LLMeshRepository::sLODProcessing = 0; U32 LLMeshRepository::sLODPending = 0; U32 LLMeshRepository::sCacheBytesRead = 0; U32 LLMeshRepository::sCacheBytesWritten = 0; +U32 LLMeshRepository::sCacheReads = 0; +U32 LLMeshRepository::sCacheWrites = 0; + LLDeadmanTimer LLMeshRepository::sQuiescentTimer(15.0, true); // true -> gather cpu metrics @@ -366,6 +378,7 @@ volatile S32 LLMeshRepoThread::sActiveLODRequests = 0; U32 LLMeshRepoThread::sMaxConcurrentRequests = 1; S32 LLMeshRepoThread::sRequestLowWater = REQUEST_LOW_WATER_MIN; S32 LLMeshRepoThread::sRequestHighWater = REQUEST_HIGH_WATER_MIN; +S32 LLMeshRepoThread::sRequestWaterLevel = 0; // Base handler class for all mesh users of llcorehttp. // This is roughly equivalent to a Responder class in @@ -619,9 +632,7 @@ LLMeshRepoThread::LLMeshRepoThread() mHttpPolicyClass(LLCore::HttpRequest::DEFAULT_POLICY_ID), mHttpLegacyPolicyClass(LLCore::HttpRequest::DEFAULT_POLICY_ID), mHttpLargePolicyClass(LLCore::HttpRequest::DEFAULT_POLICY_ID), - mHttpPriority(0), - mHttpGetCount(0U), - mHttpLargeGetCount(0U) + mHttpPriority(0) { mMutex = new LLMutex(NULL); mHeaderMutex = new LLMutex(NULL); @@ -641,8 +652,8 @@ LLMeshRepoThread::LLMeshRepoThread() LLMeshRepoThread::~LLMeshRepoThread() { - LL_INFOS(LOG_MESH) << "Small GETs issued: " << mHttpGetCount - << ", Large GETs issued: " << mHttpLargeGetCount + LL_INFOS(LOG_MESH) << "Small GETs issued: " << LLMeshRepository::sHTTPRequestCount + << ", Large GETs issued: " << LLMeshRepository::sHTTPLargeRequestCount << LL_ENDL; for (http_request_set::iterator iter(mHttpRequestSet.begin()); @@ -700,7 +711,8 @@ void LLMeshRepoThread::run() if (! LLApp::isQuitting()) { // NOTE: order of queue processing intentionally favors LOD requests over header requests - + + sRequestWaterLevel = mHttpRequestSet.size(); while (!mLODReqQ.empty() && mHttpRequestSet.size() < sRequestHighWater) { if (! mMutex) @@ -743,19 +755,26 @@ void LLMeshRepoThread::run() // list, we scan the entire thing. This gets us through any requests // which can be resolved in the cache. It also keeps the request // set somewhat fresher otherwise items at the end of the set - // order will lose. Keep to the throttle enforcement and pay - // attention to the highwater level (enforced in each fetchXXX() - // method). + // order will lose. if (! mSkinRequests.empty() && mHttpRequestSet.size() < sRequestHighWater) { // *FIXME: this really does need a lock as do the following ones std::set<LLUUID> incomplete; for (std::set<LLUUID>::iterator iter = mSkinRequests.begin(); iter != mSkinRequests.end(); ++iter) { - LLUUID mesh_id = *iter; - if (!fetchMeshSkinInfo(mesh_id)) + if (mHttpRequestSet.size() < sRequestHighWater) + { + LLUUID mesh_id = *iter; + if (!fetchMeshSkinInfo(mesh_id)) + { + incomplete.insert(mesh_id); + } + } + else { - incomplete.insert(mesh_id); + // Hit high-water mark, copy remaining to incomplete. + incomplete.insert(iter, mSkinRequests.end()); + break; } } mSkinRequests.swap(incomplete); @@ -766,10 +785,19 @@ void LLMeshRepoThread::run() std::set<LLUUID> incomplete; for (std::set<LLUUID>::iterator iter = mDecompositionRequests.begin(); iter != mDecompositionRequests.end(); ++iter) { - LLUUID mesh_id = *iter; - if (!fetchMeshDecomposition(mesh_id)) + if (mHttpRequestSet.size() < sRequestHighWater) { - incomplete.insert(mesh_id); + LLUUID mesh_id = *iter; + if (!fetchMeshDecomposition(mesh_id)) + { + incomplete.insert(mesh_id); + } + } + else + { + // Hit high-water mark, copy remaining to incomplete. + incomplete.insert(iter, mDecompositionRequests.end()); + break; } } mDecompositionRequests.swap(incomplete); @@ -780,10 +808,19 @@ void LLMeshRepoThread::run() std::set<LLUUID> incomplete; for (std::set<LLUUID>::iterator iter = mPhysicsShapeRequests.begin(); iter != mPhysicsShapeRequests.end(); ++iter) { - LLUUID mesh_id = *iter; - if (!fetchMeshPhysicsShape(mesh_id)) + if (mHttpRequestSet.size() < sRequestHighWater) + { + LLUUID mesh_id = *iter; + if (!fetchMeshPhysicsShape(mesh_id)) + { + incomplete.insert(mesh_id); + } + } + else { - incomplete.insert(mesh_id); + // Hit high-water mark, copy remaining to incomplete. + incomplete.insert(iter, mPhysicsShapeRequests.end()); + break; } } mPhysicsShapeRequests.swap(incomplete); @@ -926,7 +963,10 @@ LLCore::HttpHandle LLMeshRepoThread::getByteRange(const std::string & url, int c mHttpOptions, mHttpHeaders, handler); - ++mHttpGetCount; + if (LLCORE_HTTP_HANDLE_INVALID != handle) + { + ++LLMeshRepository::sHTTPRequestCount; + } } else { @@ -938,7 +978,10 @@ LLCore::HttpHandle LLMeshRepoThread::getByteRange(const std::string & url, int c mHttpLargeOptions, mHttpHeaders, handler); - ++mHttpLargeGetCount; + if (LLCORE_HTTP_HANDLE_INVALID != handle) + { + ++LLMeshRepository::sHTTPLargeRequestCount; + } } if (LLCORE_HTTP_HANDLE_INVALID == handle) { @@ -965,7 +1008,8 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id) return false; } - bool ret = true ; + ++LLMeshRepository::sMeshRequestCount; + bool ret = true; U32 header_size = mMeshHeaderSize[mesh_id]; if (header_size > 0) @@ -983,6 +1027,7 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id) if (file.getSize() >= offset+size) { LLMeshRepository::sCacheBytesRead += size; + ++LLMeshRepository::sCacheReads; file.seek(offset); U8* buffer = new U8[size]; file.read(buffer, size); @@ -1007,10 +1052,6 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id) } //reading from VFS failed for whatever reason, fetch from sim - if (mHttpRequestSet.size() >= sRequestHighWater) - { - return false; - } int cap_version(gMeshRepo.mGetMeshVersion); std::string http_url = constructUrl(mesh_id); if (!http_url.empty()) @@ -1025,12 +1066,12 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id) << LL_ENDL; delete handler; ret = false; + } else { handler->mHttpHandle = handle; mHttpRequestSet.insert(handler); - ++LLMeshRepository::sHTTPRequestCount; } } } @@ -1059,8 +1100,9 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id) return false; } + ++LLMeshRepository::sMeshRequestCount; U32 header_size = mMeshHeaderSize[mesh_id]; - bool ret = true ; + bool ret = true; if (header_size > 0) { @@ -1077,6 +1119,7 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id) if (file.getSize() >= offset+size) { LLMeshRepository::sCacheBytesRead += size; + ++LLMeshRepository::sCacheReads; file.seek(offset); U8* buffer = new U8[size]; @@ -1102,10 +1145,6 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id) } //reading from VFS failed for whatever reason, fetch from sim - if (mHttpRequestSet.size() >= sRequestHighWater) - { - return false; - } int cap_version(gMeshRepo.mGetMeshVersion); std::string http_url = constructUrl(mesh_id); if (!http_url.empty()) @@ -1125,7 +1164,6 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id) { handler->mHttpHandle = handle; mHttpRequestSet.insert(handler); - ++LLMeshRepository::sHTTPRequestCount; } } } @@ -1154,8 +1192,9 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id) return false; } + ++LLMeshRepository::sMeshRequestCount; U32 header_size = mMeshHeaderSize[mesh_id]; - bool ret = true ; + bool ret = true; if (header_size > 0) { @@ -1172,6 +1211,7 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id) if (file.getSize() >= offset+size) { LLMeshRepository::sCacheBytesRead += size; + ++LLMeshRepository::sCacheReads; file.seek(offset); U8* buffer = new U8[size]; file.read(buffer, size); @@ -1196,10 +1236,6 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id) } //reading from VFS failed for whatever reason, fetch from sim - if (mHttpRequestSet.size() >= sRequestHighWater) - { - return false; - } int cap_version(gMeshRepo.mGetMeshVersion); std::string http_url = constructUrl(mesh_id); if (!http_url.empty()) @@ -1219,7 +1255,6 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id) { handler->mHttpHandle = handle; mHttpRequestSet.insert(handler); - ++LLMeshRepository::sHTTPRequestCount; } } } @@ -1268,6 +1303,8 @@ void LLMeshRepoThread::decActiveHeaderRequests() //return false if failed to get header bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params) { + ++LLMeshRepository::sMeshRequestCount; + { //look for mesh in asset in vfs LLVFile file(gVFS, mesh_params.getSculptID(), LLAssetType::AT_MESH); @@ -1280,6 +1317,7 @@ bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params) U8 buffer[MESH_HEADER_SIZE]; S32 bytes = llmin(size, MESH_HEADER_SIZE); LLMeshRepository::sCacheBytesRead += bytes; + ++LLMeshRepository::sCacheReads; file.read(buffer, bytes); if (headerReceived(mesh_params, buffer, bytes)) { @@ -1314,7 +1352,6 @@ bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params) { handler->mHttpHandle = handle; mHttpRequestSet.insert(handler); - ++LLMeshRepository::sHTTPRequestCount; } } @@ -1331,6 +1368,7 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod) mHeaderMutex->lock(); + ++LLMeshRepository::sMeshRequestCount; bool retval = true; LLUUID mesh_id = mesh_params.getSculptID(); @@ -1352,6 +1390,7 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod) if (file.getSize() >= offset+size) { LLMeshRepository::sCacheBytesRead += size; + ++LLMeshRepository::sCacheReads; file.seek(offset); U8* buffer = new U8[size]; file.read(buffer, size); @@ -1395,7 +1434,6 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod) { handler->mHttpHandle = handle; mHttpRequestSet.insert(handler); - ++LLMeshRepository::sHTTPRequestCount; } } else @@ -2364,6 +2402,7 @@ void LLMeshHandlerBase::onCompleted(LLCore::HttpHandle handle, LLCore::HttpRespo if (! status) { processFailure(status); + ++LLMeshRepository::sHTTPErrorCount; } else { @@ -2484,6 +2523,7 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * body, U8 * data, S32 if (file.getMaxSize() >= bytes || file.setMaxSize(bytes)) { LLMeshRepository::sCacheBytesWritten += data_size; + ++LLMeshRepository::sCacheWrites; file.write(data, data_size); @@ -2556,6 +2596,7 @@ void LLMeshLODHandler::processData(LLCore::BufferArray * body, U8 * data, S32 da file.seek(offset); file.write(data, size); LLMeshRepository::sCacheBytesWritten += size; + ++LLMeshRepository::sCacheWrites; } } // *TODO: Mark mesh unavailable on error @@ -2601,6 +2642,7 @@ void LLMeshSkinInfoHandler::processData(LLCore::BufferArray * body, U8 * data, S if (file.getSize() >= offset+size) { LLMeshRepository::sCacheBytesWritten += size; + ++LLMeshRepository::sCacheWrites; file.seek(offset); file.write(data, size); } @@ -2648,6 +2690,7 @@ void LLMeshDecompositionHandler::processData(LLCore::BufferArray * body, U8 * da if (file.getSize() >= offset+size) { LLMeshRepository::sCacheBytesWritten += size; + ++LLMeshRepository::sCacheWrites; file.seek(offset); file.write(data, size); } @@ -2695,6 +2738,7 @@ void LLMeshPhysicsShapeHandler::processData(LLCore::BufferArray * body, U8 * dat if (file.getSize() >= offset+size) { LLMeshRepository::sCacheBytesWritten += size; + ++LLMeshRepository::sCacheWrites; file.seek(offset); file.write(data, size); } @@ -4204,7 +4248,7 @@ void LLMeshRepository::metricsUpdate() LLSD metrics; metrics["reason"] = "Mesh Download Quiescent"; - metrics["scope"] = "Login"; + metrics["scope"] = metrics_teleport_start_count > 1 ? "Teleport" : "Login"; metrics["start"] = started; metrics["stop"] = stopped; metrics["fetches"] = LLSD::Integer(total_count); |