From 188221a90c7a054d390ddaa534d391f6370ac6bc Mon Sep 17 00:00:00 2001 From: Monty Brandenberg Date: Tue, 9 Apr 2013 23:44:59 +0000 Subject: SH-4088 Deadman timer switch started in llcommon. Unit test started. Will be used for mesh, inventory, etc., operation markers. --- indra/llcommon/lldeadmantimer.cpp | 141 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 indra/llcommon/lldeadmantimer.cpp (limited to 'indra/llcommon/lldeadmantimer.cpp') diff --git a/indra/llcommon/lldeadmantimer.cpp b/indra/llcommon/lldeadmantimer.cpp new file mode 100644 index 0000000000..2f48d13c2d --- /dev/null +++ b/indra/llcommon/lldeadmantimer.cpp @@ -0,0 +1,141 @@ +/** +* @file lldeadmantimer.cpp +* @brief Simple deadman-switch timer. +* @author monty@lindenlab.com +* +* $LicenseInfo:firstyear=2013&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2013, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +* $/LicenseInfo$ +*/ + + +#include "lldeadmantimer.h" + + +LLDeadmanTimer::LLDeadmanTimer(F64 horizon) + : mHorizon(U64(horizon * gClockFrequency)), + mActive(false), // If true, a timer is running. + mDone(false), // If true, timer has completed and can be read (once) + mStarted(U64L(0)), + mExpires(U64L(0)), + mStopped(U64L(0)), + mCount(U64L(0)) +{} + + +void LLDeadmanTimer::start(U64 now) +{ + // *TODO: If active, let's complete an existing timer and save + // the result to the side. I think this will be useful later. + // For now, wipe out anything in progress, start fresh. + + if (! now) + { + now = LLTimer::getCurrentClockCount(); + } + mActive = true; + mDone = false; + mStarted = now; + mExpires = now + mHorizon; + mStopped = now; + mCount = U64L(0); +} + + +void LLDeadmanTimer::stop(U64 now) +{ + if (! mActive) + { + return; + } + + if (! now) + { + now = LLTimer::getCurrentClockCount(); + } + mStopped = now; + mActive = false; + mDone = true; +} + + +bool LLDeadmanTimer::isExpired(F64 & started, F64 & stopped, U64 & count, U64 now) +{ + if (! mActive) + { + return false; + } + + if (! mDone) + { + if (! now) + { + now = LLTimer::getCurrentClockCount(); + } + + if (now > mExpires) + { + // mStopped from ringBell() is the value we want + mActive = false; + mDone = true; + } + } + + if (! mDone) + { + return false; + } + + started = mStarted * gClockFrequencyInv; + stopped = mStopped * gClockFrequencyInv; + count = mCount; + mDone = false; + + return true; +} + + +void LLDeadmanTimer::ringBell(U64 now) +{ + if (! mActive) + { + return; + } + + if (! now) + { + now = LLTimer::getCurrentClockCount(); + } + + if (now > mExpires) + { + mActive = false; + mDone = true; + } + else + { + mStopped = now; + mExpires = now + mHorizon; + ++mCount; + } + + return; +} + -- cgit v1.2.3 From aabda8f3073928980b26530eac9b05eeb85a2207 Mon Sep 17 00:00:00 2001 From: Monty Brandenberg Date: Wed, 10 Apr 2013 16:30:26 +0000 Subject: SH-4089 Unit test work for timer. Knocked off some tests for the deadman's timer. Found some bugs, dig some cleanup and documented a few things. Definitely want to get rid of the U64/F64 interfaces at sometime but this is a good start. --- indra/llcommon/lldeadmantimer.cpp | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) (limited to 'indra/llcommon/lldeadmantimer.cpp') diff --git a/indra/llcommon/lldeadmantimer.cpp b/indra/llcommon/lldeadmantimer.cpp index 2f48d13c2d..3d3f738c06 100644 --- a/indra/llcommon/lldeadmantimer.cpp +++ b/indra/llcommon/lldeadmantimer.cpp @@ -29,8 +29,21 @@ #include "lldeadmantimer.h" +// *TODO: Currently, this uses lltimer functions for its time +// aspects and this leaks into the apis in the U64s/F64s. Would +// like to perhaps switch this over to TSC register-based timers +// sometime and drop the overhead some more. + + +// Flag states and their meaning: +// mActive mDone Meaning +// false false Nothing running, no result available +// true false Timer running, no result available +// false true Timer finished, result can be read once +// true true Not allowed +// LLDeadmanTimer::LLDeadmanTimer(F64 horizon) - : mHorizon(U64(horizon * gClockFrequency)), + : mHorizon(U64(llmax(horizon, F64(0.0)) * gClockFrequency)), mActive(false), // If true, a timer is running. mDone(false), // If true, timer has completed and can be read (once) mStarted(U64L(0)), @@ -78,19 +91,14 @@ void LLDeadmanTimer::stop(U64 now) bool LLDeadmanTimer::isExpired(F64 & started, F64 & stopped, U64 & count, U64 now) { - if (! mActive) - { - return false; - } - - if (! mDone) + if (mActive && ! mDone) { if (! now) { now = LLTimer::getCurrentClockCount(); } - if (now > mExpires) + if (now >= mExpires) { // mStopped from ringBell() is the value we want mActive = false; @@ -124,7 +132,7 @@ void LLDeadmanTimer::ringBell(U64 now) now = LLTimer::getCurrentClockCount(); } - if (now > mExpires) + if (now >= mExpires) { mActive = false; mDone = true; -- cgit v1.2.3 From e59d59878200d25dc6e94753026d986d2704ab8d Mon Sep 17 00:00:00 2001 From: Monty Brandenberg Date: Wed, 17 Apr 2013 18:30:46 -0400 Subject: SH-4090 Integrating deadman timer with mesh repo downloads. Timer interface violated my design rules and I paid for it with clumsiness and silent errors. Cleaned it up mainly removing the evil default values. Found better integration points in the mesh downloader and it's producing fairly consistent numbers on the MeshTest2 test region (about 5500 downloads, ~90 seconds, +/- 10 seconds). Will review with davep and do an early timer stop on teleport which invalidates a timing sequence. --- indra/llcommon/lldeadmantimer.cpp | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) (limited to 'indra/llcommon/lldeadmantimer.cpp') diff --git a/indra/llcommon/lldeadmantimer.cpp b/indra/llcommon/lldeadmantimer.cpp index 3d3f738c06..2a356d857a 100644 --- a/indra/llcommon/lldeadmantimer.cpp +++ b/indra/llcommon/lldeadmantimer.cpp @@ -43,7 +43,7 @@ // true true Not allowed // LLDeadmanTimer::LLDeadmanTimer(F64 horizon) - : mHorizon(U64(llmax(horizon, F64(0.0)) * gClockFrequency)), + : mHorizon(time_type(llmax(horizon, F64(0.0)) * gClockFrequency)), mActive(false), // If true, a timer is running. mDone(false), // If true, timer has completed and can be read (once) mStarted(U64L(0)), @@ -53,7 +53,14 @@ LLDeadmanTimer::LLDeadmanTimer(F64 horizon) {} -void LLDeadmanTimer::start(U64 now) +// static +LLDeadmanTimer::time_type LLDeadmanTimer::getNow() +{ + return LLTimer::getCurrentClockCount(); +} + + +void LLDeadmanTimer::start(time_type now) { // *TODO: If active, let's complete an existing timer and save // the result to the side. I think this will be useful later. @@ -72,7 +79,7 @@ void LLDeadmanTimer::start(U64 now) } -void LLDeadmanTimer::stop(U64 now) +void LLDeadmanTimer::stop(time_type now) { if (! mActive) { @@ -81,7 +88,7 @@ void LLDeadmanTimer::stop(U64 now) if (! now) { - now = LLTimer::getCurrentClockCount(); + now = getNow(); } mStopped = now; mActive = false; @@ -89,13 +96,13 @@ void LLDeadmanTimer::stop(U64 now) } -bool LLDeadmanTimer::isExpired(F64 & started, F64 & stopped, U64 & count, U64 now) +bool LLDeadmanTimer::isExpired(time_type now, F64 & started, F64 & stopped, U64 & count) { if (mActive && ! mDone) { if (! now) { - now = LLTimer::getCurrentClockCount(); + now = getNow(); } if (now >= mExpires) @@ -120,7 +127,7 @@ bool LLDeadmanTimer::isExpired(F64 & started, F64 & stopped, U64 & count, U64 no } -void LLDeadmanTimer::ringBell(U64 now) +void LLDeadmanTimer::ringBell(time_type now, unsigned int count) { if (! mActive) { @@ -129,7 +136,7 @@ void LLDeadmanTimer::ringBell(U64 now) if (! now) { - now = LLTimer::getCurrentClockCount(); + now = getNow(); } if (now >= mExpires) @@ -141,7 +148,7 @@ void LLDeadmanTimer::ringBell(U64 now) { mStopped = now; mExpires = now + mHorizon; - ++mCount; + mCount += count; } return; -- cgit v1.2.3 From 11cca95187f01f594172ca950315dcd8d99dc2c3 Mon Sep 17 00:00:00 2001 From: Monty Brandenberg Date: Thu, 2 May 2013 21:59:53 +0000 Subject: SH-4161 Integrate cpu metrics into LLDeadmanTimer and then metrics viewer Integrated as a ctor-time option to LLDeadmanTimer and have mesh use this mode for the stats I'm gathering. --- indra/llcommon/lldeadmantimer.cpp | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) (limited to 'indra/llcommon/lldeadmantimer.cpp') diff --git a/indra/llcommon/lldeadmantimer.cpp b/indra/llcommon/lldeadmantimer.cpp index 2a356d857a..2ba757d2af 100644 --- a/indra/llcommon/lldeadmantimer.cpp +++ b/indra/llcommon/lldeadmantimer.cpp @@ -42,14 +42,19 @@ // false true Timer finished, result can be read once // true true Not allowed // -LLDeadmanTimer::LLDeadmanTimer(F64 horizon) +LLDeadmanTimer::LLDeadmanTimer(F64 horizon, bool inc_cpu) : mHorizon(time_type(llmax(horizon, F64(0.0)) * gClockFrequency)), mActive(false), // If true, a timer is running. mDone(false), // If true, timer has completed and can be read (once) mStarted(U64L(0)), mExpires(U64L(0)), mStopped(U64L(0)), - mCount(U64L(0)) + mCount(U64L(0)), + mIncCPU(inc_cpu), + mUStartCPU(LLProcInfo::time_type(U64L(0))), + mUEndCPU(LLProcInfo::time_type(U64L(0))), + mSStartCPU(LLProcInfo::time_type(U64L(0))), + mSEndCPU(LLProcInfo::time_type(U64L(0))) {} @@ -76,6 +81,10 @@ void LLDeadmanTimer::start(time_type now) mExpires = now + mHorizon; mStopped = now; mCount = U64L(0); + if (mIncCPU) + { + LLProcInfo::getCPUUsage(mUStartCPU, mSStartCPU); + } } @@ -93,9 +102,26 @@ void LLDeadmanTimer::stop(time_type now) mStopped = now; mActive = false; mDone = true; + if (mIncCPU) + { + LLProcInfo::getCPUUsage(mUEndCPU, mSEndCPU); + } } +bool LLDeadmanTimer::isExpired(time_type now, F64 & started, F64 & stopped, U64 & count, + LLProcInfo::time_type & user_cpu, LLProcInfo::time_type & sys_cpu) +{ + const bool status(isExpired(now, started, stopped, count)); + if (status) + { + user_cpu = mUEndCPU - mUStartCPU; + sys_cpu = mSEndCPU - mSStartCPU; + } + return status; +} + + bool LLDeadmanTimer::isExpired(time_type now, F64 & started, F64 & stopped, U64 & count) { if (mActive && ! mDone) @@ -141,14 +167,20 @@ void LLDeadmanTimer::ringBell(time_type now, unsigned int count) if (now >= mExpires) { + // Timer has expired, this event will be dropped mActive = false; mDone = true; } else { + // Timer renewed, keep going mStopped = now; mExpires = now + mHorizon; mCount += count; + if (mIncCPU) + { + LLProcInfo::getCPUUsage(mUEndCPU, mSEndCPU); + } } return; -- cgit v1.2.3 From 960139aa6f02f90c6102d3c5d5c38b5ebe689f9c Mon Sep 17 00:00:00 2001 From: Monty Brandenberg Date: Thu, 2 May 2013 19:12:59 -0400 Subject: SH-4161 Integrate cpu metrics into LLDeadmanTimer and then metrics viewer Normalize deadman timer's args on U64/F64. Internals remain the same. Modify mesh to collect and output enhanced CPU metrics. --- indra/llcommon/lldeadmantimer.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'indra/llcommon/lldeadmantimer.cpp') diff --git a/indra/llcommon/lldeadmantimer.cpp b/indra/llcommon/lldeadmantimer.cpp index 2ba757d2af..7d9097e344 100644 --- a/indra/llcommon/lldeadmantimer.cpp +++ b/indra/llcommon/lldeadmantimer.cpp @@ -110,13 +110,13 @@ void LLDeadmanTimer::stop(time_type now) bool LLDeadmanTimer::isExpired(time_type now, F64 & started, F64 & stopped, U64 & count, - LLProcInfo::time_type & user_cpu, LLProcInfo::time_type & sys_cpu) + U64 & user_cpu, U64 & sys_cpu) { const bool status(isExpired(now, started, stopped, count)); if (status) { - user_cpu = mUEndCPU - mUStartCPU; - sys_cpu = mSEndCPU - mSStartCPU; + user_cpu = U64(mUEndCPU - mUStartCPU); + sys_cpu = U64(mSEndCPU - mSStartCPU); } return status; } -- cgit v1.2.3