From d666a3d92cb5dd9844c29e5472db542de7b5ac9e Mon Sep 17 00:00:00 2001 From: Monty Brandenberg Date: Thu, 18 Nov 2010 08:43:09 -0800 Subject: ESC-154 ESC-155 ESC-156 Asset fetch requests wrapped to allow for measurements. Asset fetch enqueues, dequeues and completion times recorded to asset stats collector. Texture fetch operations (http and udp) recorded to asset stats collector. Stats collector time vallue switched from F32 to U64 which is the more common type in the viewer. Cross-thread mechanism introduced to communicate region changes and generate global statistics messages. Facility to deliver metrics via Capabilities sketched in but needs additional work. Documentation and diagrams added. --- indra/newview/lltexturefetch.h | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) (limited to 'indra/newview/lltexturefetch.h') diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h index 796109df06..220305d881 100644 --- a/indra/newview/lltexturefetch.h +++ b/indra/newview/lltexturefetch.h @@ -40,6 +40,7 @@ class HTTPGetResponder; class LLTextureCache; class LLImageDecodeThread; class LLHost; +namespace { class TFRequest; } // Interface class class LLTextureFetch : public LLWorkerThread @@ -83,6 +84,13 @@ public: LLTextureFetchWorker* getWorkerAfterLock(const LLUUID& id); LLTextureInfo* getTextureInfo() { return &mTextureInfo; } + + // Commands available to other threads. + void commandSetRegion(const LLUUID & region_id); + void commandSendMetrics(const std::string & caps_url, LLSD * report_main); + void commandDataBreak(); + + LLCurlRequest & getCurlRequest() { return *mCurlGetRequest; } protected: void addToNetworkQueue(LLTextureFetchWorker* worker); @@ -91,7 +99,10 @@ protected: void removeFromHTTPQueue(const LLUUID& id, S32 received_size = 0); void removeRequest(LLTextureFetchWorker* worker, bool cancel); // Called from worker thread (during doWork) - void processCurlRequests(); + void processCurlRequests(); + + // Overrides from the LLThread tree + bool runCondition(); private: void sendRequestListToSimulators(); @@ -99,6 +110,11 @@ private: /*virtual*/ void endThread(void); /*virtual*/ void threadedUpdate(void); + // command helpers + void cmdEnqueue(TFRequest *); + TFRequest * cmdDequeue(); + void cmdDoWork(LLTextureFetchWorker* worker); + public: LLUUID mDebugID; S32 mDebugCount; @@ -107,7 +123,7 @@ public: S32 mBadPacketCount; private: - LLMutex mQueueMutex; //to protect mRequestMap only + LLMutex mQueueMutex; //to protect mRequestMap and mCommands only LLMutex mNetworkQueueMutex; //to protect mNetworkQueue, mHTTPTextureQueue and mCancelQueue. LLTextureCache* mTextureCache; @@ -129,6 +145,19 @@ private: LLTextureInfo mTextureInfo; U32 mHTTPTextureBits; + + // Special cross-thread command queue. This command queue + // is logically tied to LLQueuedThread's list of + // QueuedRequest instances and so must be covered by the + // same locks. + typedef std::vector command_queue_t; + command_queue_t mCommands; + +public: + // A probabilistically-correct indicator that the current + // attempt to log metrics follows a break in the metrics stream + // reporting due to either startup or a problem POSTing data. + static volatile bool svMetricsDataBreak; }; #endif // LL_LLTEXTUREFETCH_H -- cgit v1.2.3 From f98a622325d8982d32ae98e189f5d3ec6ada183f Mon Sep 17 00:00:00 2001 From: Monty Brandenberg Date: Mon, 22 Nov 2010 10:26:25 -0800 Subject: ESC-154 ESC-156 Metrics integration into viewer's threads Removed declared but undefined interfaces from LLTextureFetch family. Had inserted the cross-thread command processor into some of LLTextureFetchWorker's processing which was unnatural and probably wrong. Moved it to LLTextureFetch which turned out to be far, far more natural. Better documentation on the asLLSD() format. Refined LLSD stats merger logic and enhanced unit tests to verify same. --- indra/newview/lltexturefetch.h | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'indra/newview/lltexturefetch.h') diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h index 220305d881..88b7e4a16b 100644 --- a/indra/newview/lltexturefetch.h +++ b/indra/newview/lltexturefetch.h @@ -85,7 +85,7 @@ public: LLTextureInfo* getTextureInfo() { return &mTextureInfo; } - // Commands available to other threads. + // Commands available to other threads to control metrics gathering operations. void commandSetRegion(const LLUUID & region_id); void commandSendMetrics(const std::string & caps_url, LLSD * report_main); void commandDataBreak(); @@ -98,8 +98,6 @@ protected: void addToHTTPQueue(const LLUUID& id); void removeFromHTTPQueue(const LLUUID& id, S32 received_size = 0); void removeRequest(LLTextureFetchWorker* worker, bool cancel); - // Called from worker thread (during doWork) - void processCurlRequests(); // Overrides from the LLThread tree bool runCondition(); @@ -110,10 +108,10 @@ private: /*virtual*/ void endThread(void); /*virtual*/ void threadedUpdate(void); - // command helpers + // Metrics command helpers void cmdEnqueue(TFRequest *); TFRequest * cmdDequeue(); - void cmdDoWork(LLTextureFetchWorker* worker); + void cmdDoWork(); public: LLUUID mDebugID; @@ -146,7 +144,7 @@ private: U32 mHTTPTextureBits; - // Special cross-thread command queue. This command queue + // Out-of-band cross-thread command queue. This command queue // is logically tied to LLQueuedThread's list of // QueuedRequest instances and so must be covered by the // same locks. -- cgit v1.2.3 From 3962b155b4939f831dfd82701d46c4f15aa9f7ac Mon Sep 17 00:00:00 2001 From: Monty Brandenberg Date: Tue, 23 Nov 2010 12:29:15 -0800 Subject: ESC-154 ESC-156 Integrating metrics collector into viewer. After discussions, renamed 'QAModeMetricsSubmetrics' to 'QAModeMetrics' and confirmed that LLCachedControl<> is the way to go. Moved the resulting flag out of LLViewerAssetStats (where it didn't belong) and it lives in both LLAppViewer and LLTextureFetch where it does belong. --- indra/newview/lltexturefetch.h | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) (limited to 'indra/newview/lltexturefetch.h') diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h index 88b7e4a16b..d46d2da7bc 100644 --- a/indra/newview/lltexturefetch.h +++ b/indra/newview/lltexturefetch.h @@ -49,7 +49,7 @@ class LLTextureFetch : public LLWorkerThread friend class HTTPGetResponder; public: - LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* imagedecodethread, bool threaded); + LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* imagedecodethread, bool threaded, bool qa_mode); ~LLTextureFetch(); /*virtual*/ S32 update(U32 max_time_ms); @@ -90,8 +90,10 @@ public: void commandSendMetrics(const std::string & caps_url, LLSD * report_main); void commandDataBreak(); - LLCurlRequest & getCurlRequest() { return *mCurlGetRequest; } - + LLCurlRequest & getCurlRequest() { return *mCurlGetRequest; } + + bool isQAMode() const { return mQAMode; } + protected: void addToNetworkQueue(LLTextureFetchWorker* worker); void removeFromNetworkQueue(LLTextureFetchWorker* worker, bool cancel); @@ -109,8 +111,33 @@ private: /*virtual*/ void threadedUpdate(void); // Metrics command helpers + /** + * Enqueues a command request at the end of the command queue + * and wakes up the thread as needed. + * + * Takes ownership of the TFRequest object. + * + * Method locks the command queue. + */ void cmdEnqueue(TFRequest *); + + /** + * Returns the first TFRequest object in the command queue or + * NULL if none is present. + * + * Caller acquires ownership of the object and must dispose of it. + * + * Method locks the command queue. + */ TFRequest * cmdDequeue(); + + /** + * Processes the first command in the queue disposing of the + * request on completion. Successive calls are needed to perform + * additional commands. + * + * Method locks the command queue. + */ void cmdDoWork(); public: @@ -151,6 +178,9 @@ private: typedef std::vector command_queue_t; command_queue_t mCommands; + // If true, modifies some behaviors that help with QA tasks. + const bool mQAMode; + public: // A probabilistically-correct indicator that the current // attempt to log metrics follows a break in the metrics stream -- cgit v1.2.3 From 0fd80d09972657e6417193abf577084a3b3b85f1 Mon Sep 17 00:00:00 2001 From: Monty Brandenberg Date: Wed, 24 Nov 2010 16:46:40 -0500 Subject: ESC-154 ESC-156 Metrics integration across threads Using unpause() method in derived class rather than wake() in furthest base class solved the stalling problem. I still think too many levels of the LLTextureFetch hierarchy are keeping thread state, however. The LLViewerRegion instance an agent enters doesn't necessarily have its region_id yet, that only comes after the handshake, if any. So add a few more metrics insertion points to propagate region into metrics. Finally, try to launch a final metrics report when a quit is initiated. --- indra/newview/lltexturefetch.h | 1 + 1 file changed, 1 insertion(+) (limited to 'indra/newview/lltexturefetch.h') diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h index d46d2da7bc..bad0a1498f 100644 --- a/indra/newview/lltexturefetch.h +++ b/indra/newview/lltexturefetch.h @@ -109,6 +109,7 @@ private: /*virtual*/ void startThread(void); /*virtual*/ void endThread(void); /*virtual*/ void threadedUpdate(void); + void commonUpdate(); // Metrics command helpers /** -- cgit v1.2.3 From 0f2ed092c5712cd5dcd928e079671df383227068 Mon Sep 17 00:00:00 2001 From: Monty Brandenberg Date: Mon, 29 Nov 2010 08:31:08 -0800 Subject: ESC-154 ESC-156 Now using region hash rather than region uuid as identifier. In the viewer, the region's UUID is acquired very late and isn't generally used as the canonical region identifier. The U64 region hash is a better and more consistently used identifier so I'm moving over to using that as the region key. Don't have a proper reserved invalid region hash which is unfortunate, but then, so much is. --- indra/newview/lltexturefetch.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/lltexturefetch.h') diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h index bad0a1498f..03e2462058 100644 --- a/indra/newview/lltexturefetch.h +++ b/indra/newview/lltexturefetch.h @@ -86,7 +86,7 @@ public: LLTextureInfo* getTextureInfo() { return &mTextureInfo; } // Commands available to other threads to control metrics gathering operations. - void commandSetRegion(const LLUUID & region_id); + void commandSetRegion(U64 region_handle); void commandSendMetrics(const std::string & caps_url, LLSD * report_main); void commandDataBreak(); -- cgit v1.2.3 From 922b1f26b7279b5f54562c413c333463fe34473b Mon Sep 17 00:00:00 2001 From: Monty Brandenberg Date: Thu, 2 Dec 2010 18:42:47 -0500 Subject: ESC-211 Metrics data sink - fix delivery by viewer The TextureFetch thread was still stalling out due to a different path that determines whether there is work or not in the thread (uses getPending()) and that had to be harmonized with the changes to runCondition(). I'm not happy with this solution but a refactor of the LLThread tree isn't in the cards right now. --- indra/newview/lltexturefetch.h | 1 + 1 file changed, 1 insertion(+) (limited to 'indra/newview/lltexturefetch.h') diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h index 03e2462058..af30d1bb3b 100644 --- a/indra/newview/lltexturefetch.h +++ b/indra/newview/lltexturefetch.h @@ -78,6 +78,7 @@ public: S32 getNumHTTPRequests() ; // Public for access by callbacks + S32 getPending(); void lockQueue() { mQueueMutex.lock(); } void unlockQueue() { mQueueMutex.unlock(); } LLTextureFetchWorker* getWorker(const LLUUID& id); -- cgit v1.2.3 From 11d420dd32e643a191c16b04f2fbb42c2b4db628 Mon Sep 17 00:00:00 2001 From: Monty Brandenberg Date: Fri, 10 Dec 2010 17:41:05 -0800 Subject: Decided to refactor a bit. Was using LLSD as an internal data representation transferring ownership, doing data aggregation in a very pedantic way. That's just adding unneeded cost and complication. Used the same objects to transport data as are collecting it and everything got simpler, faster, easier to read with fewer gotchas. Bit myself *again* doing the min/max/mean merges but the unittests where there to pick me up again. Added a per-region FPS metric while I was at it. This is much asked for and there was a convenient place to sample the value. --- indra/newview/lltexturefetch.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'indra/newview/lltexturefetch.h') diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h index af30d1bb3b..a8fd3ce244 100644 --- a/indra/newview/lltexturefetch.h +++ b/indra/newview/lltexturefetch.h @@ -40,6 +40,8 @@ class HTTPGetResponder; class LLTextureCache; class LLImageDecodeThread; class LLHost; +class LLViewerAssetStats; + namespace { class TFRequest; } // Interface class @@ -88,7 +90,10 @@ public: // Commands available to other threads to control metrics gathering operations. void commandSetRegion(U64 region_handle); - void commandSendMetrics(const std::string & caps_url, LLSD * report_main); + void commandSendMetrics(const std::string & caps_url, + const LLUUID & session_id, + const LLUUID & agent_id, + LLViewerAssetStats * main_stats); void commandDataBreak(); LLCurlRequest & getCurlRequest() { return *mCurlGetRequest; } -- cgit v1.2.3 From 3c05ebd28635e867f9726062b08cdbf4a7b53b22 Mon Sep 17 00:00:00 2001 From: Monty Brandenberg Date: Thu, 16 Dec 2010 16:42:26 -0800 Subject: ESC-237 No static init of LLAtomics and move TFRequest out of unnamed namespace. Linux startup crash appears to be due to static/global C++ init of LLAtomic types. The initializer with explicit value makes some runtime calls and it looks like these assume, at least on Linux, that apr_initialize() has been called. So move the static POST count to a member and provide accessors and increment/decrement. Command queue was built on a pointer to a class in anonymous namespace and that's not quite valid. Made it a nested class (really a nested forward declaration) while keeping the derived classes in anonymous. --- indra/newview/lltexturefetch.h | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'indra/newview/lltexturefetch.h') diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h index a8fd3ce244..ad00a7ea36 100644 --- a/indra/newview/lltexturefetch.h +++ b/indra/newview/lltexturefetch.h @@ -33,6 +33,7 @@ #include "llworkerthread.h" #include "llcurl.h" #include "lltextureinfo.h" +#include "llapr.h" class LLViewerTexture; class LLTextureFetchWorker; @@ -42,8 +43,6 @@ class LLImageDecodeThread; class LLHost; class LLViewerAssetStats; -namespace { class TFRequest; } - // Interface class class LLTextureFetch : public LLWorkerThread { @@ -54,6 +53,8 @@ public: LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* imagedecodethread, bool threaded, bool qa_mode); ~LLTextureFetch(); + class TFRequest; + /*virtual*/ S32 update(U32 max_time_ms); void shutDownTextureCacheThread() ; //called in the main thread after the TextureCacheThread shuts down. void shutDownImageDecodeThread() ; //called in the main thread after the ImageDecodeThread shuts down. @@ -100,6 +101,10 @@ public: bool isQAMode() const { return mQAMode; } + // Curl POST counter maintenance + inline void incrCurlPOSTCount() { mCurlPOSTRequestCount++; } + inline void decrCurlPOSTCount() { mCurlPOSTRequestCount--; } + protected: void addToNetworkQueue(LLTextureFetchWorker* worker); void removeFromNetworkQueue(LLTextureFetchWorker* worker, bool cancel); @@ -187,6 +192,13 @@ private: // If true, modifies some behaviors that help with QA tasks. const bool mQAMode; + + // Count of POST requests outstanding. We maintain the count + // indirectly in the CURL request responder's ctor and dtor and + // use it when determining whether or not to sleep the thread. Can't + // use the LLCurl module's request counter as it isn't thread compatible. + // *NOTE: Don't mix Atomic and static, apr_initialize must be called first. + LLAtomic32 mCurlPOSTRequestCount; public: // A probabilistically-correct indicator that the current -- cgit v1.2.3