SH-4162 Merge metrics repo into this branch and integrate

Tue, 07 May 2013 17:27:12 -0400

author
Monty Brandenberg <monty@lindenlab.com>
date
Tue, 07 May 2013 17:27:12 -0400
changeset 40675
6289b8edf5fa
parent 40670
fcdea8fb7b1c
parent 40674
e871c50e5754
child 40676
73d52141f4c5

SH-4162 Merge metrics repo into this branch and integrate
Pull cpu-based metrics into llcorehttp work to enable A/B
testing. Simple merge.

indra/newview/llmeshrepository.cpp file | annotate | diff | revisions
     1.1 --- a/indra/llcommon/CMakeLists.txt	Tue May 07 17:24:12 2013 -0400
     1.2 +++ b/indra/llcommon/CMakeLists.txt	Tue May 07 17:27:12 2013 -0400
     1.3 @@ -79,6 +79,7 @@
     1.4      llptrto.cpp 
     1.5      llprocess.cpp
     1.6      llprocessor.cpp
     1.7 +    llprocinfo.cpp
     1.8      llqueuedthread.cpp
     1.9      llrand.cpp
    1.10      llrefcount.cpp
    1.11 @@ -207,6 +208,7 @@
    1.12      llpriqueuemap.h
    1.13      llprocess.h
    1.14      llprocessor.h
    1.15 +    llprocinfo.h
    1.16      llptrskiplist.h
    1.17      llptrskipmap.h
    1.18      llptrto.h
    1.19 @@ -331,6 +333,7 @@
    1.20    LL_ADD_INTEGRATION_TEST(llinstancetracker "" "${test_libs}")
    1.21    LL_ADD_INTEGRATION_TEST(lllazy "" "${test_libs}")
    1.22    LL_ADD_INTEGRATION_TEST(llprocessor "" "${test_libs}")
    1.23 +  LL_ADD_INTEGRATION_TEST(llprocinfo "" "${test_libs}")
    1.24    LL_ADD_INTEGRATION_TEST(llrand "" "${test_libs}")
    1.25    LL_ADD_INTEGRATION_TEST(llsdserialize "" "${test_libs}")
    1.26    LL_ADD_INTEGRATION_TEST(llsingleton "" "${test_libs}")                          
     2.1 --- a/indra/llcommon/lldeadmantimer.cpp	Tue May 07 17:24:12 2013 -0400
     2.2 +++ b/indra/llcommon/lldeadmantimer.cpp	Tue May 07 17:27:12 2013 -0400
     2.3 @@ -42,14 +42,19 @@
     2.4  //   false    true   Timer finished, result can be read once
     2.5  //    true    true   Not allowed
     2.6  //
     2.7 -LLDeadmanTimer::LLDeadmanTimer(F64 horizon)
     2.8 +LLDeadmanTimer::LLDeadmanTimer(F64 horizon, bool inc_cpu)
     2.9  	: mHorizon(time_type(llmax(horizon, F64(0.0)) * gClockFrequency)),
    2.10  	  mActive(false),			// If true, a timer is running.
    2.11  	  mDone(false),				// If true, timer has completed and can be read (once)
    2.12  	  mStarted(U64L(0)),
    2.13  	  mExpires(U64L(0)),
    2.14  	  mStopped(U64L(0)),
    2.15 -	  mCount(U64L(0))
    2.16 +	  mCount(U64L(0)),
    2.17 +	  mIncCPU(inc_cpu),
    2.18 +	  mUStartCPU(LLProcInfo::time_type(U64L(0))),
    2.19 +	  mUEndCPU(LLProcInfo::time_type(U64L(0))),
    2.20 +	  mSStartCPU(LLProcInfo::time_type(U64L(0))),
    2.21 +	  mSEndCPU(LLProcInfo::time_type(U64L(0)))
    2.22  {}
    2.23  
    2.24  
    2.25 @@ -76,6 +81,10 @@
    2.26  	mExpires = now + mHorizon;
    2.27  	mStopped = now;
    2.28  	mCount = U64L(0);
    2.29 +	if (mIncCPU)
    2.30 +	{
    2.31 +		LLProcInfo::getCPUUsage(mUStartCPU, mSStartCPU);
    2.32 +	}
    2.33  }
    2.34  
    2.35  
    2.36 @@ -93,9 +102,26 @@
    2.37  	mStopped = now;
    2.38  	mActive = false;
    2.39  	mDone = true;
    2.40 +	if (mIncCPU)
    2.41 +	{
    2.42 +		LLProcInfo::getCPUUsage(mUEndCPU, mSEndCPU);
    2.43 +	}
    2.44  }
    2.45  
    2.46  
    2.47 +bool LLDeadmanTimer::isExpired(time_type now, F64 & started, F64 & stopped, U64 & count,
    2.48 +							   U64 & user_cpu, U64 & sys_cpu)
    2.49 +{
    2.50 +	const bool status(isExpired(now, started, stopped, count));
    2.51 +	if (status)
    2.52 +	{
    2.53 +		user_cpu = U64(mUEndCPU - mUStartCPU);
    2.54 +		sys_cpu = U64(mSEndCPU - mSStartCPU);
    2.55 +	}
    2.56 +	return status;
    2.57 +}
    2.58 +
    2.59 +		
    2.60  bool LLDeadmanTimer::isExpired(time_type now, F64 & started, F64 & stopped, U64 & count)
    2.61  {
    2.62  	if (mActive && ! mDone)
    2.63 @@ -141,14 +167,20 @@
    2.64  
    2.65  	if (now >= mExpires)
    2.66  	{
    2.67 +		// Timer has expired, this event will be dropped
    2.68  		mActive = false;
    2.69  		mDone = true;
    2.70  	}
    2.71  	else
    2.72  	{
    2.73 +		// Timer renewed, keep going
    2.74  		mStopped = now;
    2.75  		mExpires = now + mHorizon;
    2.76  		mCount += count;
    2.77 +		if (mIncCPU)
    2.78 +		{
    2.79 +			LLProcInfo::getCPUUsage(mUEndCPU, mSEndCPU);
    2.80 +		}
    2.81  	}
    2.82  	
    2.83  	return;
     3.1 --- a/indra/llcommon/lldeadmantimer.h	Tue May 07 17:24:12 2013 -0400
     3.2 +++ b/indra/llcommon/lldeadmantimer.h	Tue May 07 17:27:12 2013 -0400
     3.3 @@ -32,6 +32,7 @@
     3.4  #include "linden_common.h"
     3.5  
     3.6  #include "lltimer.h"
     3.7 +#include "llprocinfo.h"
     3.8  
     3.9  
    3.10  /// @file lldeadmantimer.h
    3.11 @@ -93,7 +94,11 @@
    3.12  	///                 call at which point the timer will consider itself
    3.13  	///					expired.
    3.14  	///
    3.15 -	LLDeadmanTimer(F64 horizon);
    3.16 +	/// @param inc_cpu	If true, gather system and user cpu stats while
    3.17 +	///					running the timer.  This does require more syscalls
    3.18 +	///					during updates.  If false, cpu usage data isn't
    3.19 +	///					collected and will be zero if queried.
    3.20 +	LLDeadmanTimer(F64 horizon, bool inc_cpu);
    3.21  
    3.22  	~LLDeadmanTimer() 
    3.23  		{}
    3.24 @@ -173,21 +178,38 @@
    3.25  	/// @param count	If expired, the number of ringBell() calls
    3.26  	///					made prior to expiration.
    3.27  	///
    3.28 +	/// @param user_cpu	Amount of CPU spent in user mode by the process
    3.29 +	///					during the event.  Value in microseconds and will
    3.30 +	///					read zero if not enabled by the constructor.
    3.31 +	///
    3.32 +	/// @param sys_cpu	Amount of CPU spent in system mode by the process.
    3.33 +	///
    3.34  	/// @return			true if the timer has expired, false otherwise.
    3.35  	///					If true, it also returns the started,
    3.36  	///					stopped and count values otherwise these are
    3.37  	///					left unchanged.
    3.38  	///
    3.39 +	bool isExpired(time_type now, F64 & started, F64 & stopped, U64 & count,
    3.40 +				   U64 & user_cpu, U64 & sys_cpu);
    3.41 +
    3.42 +	/// Identical to the six-arugment form except is does without the
    3.43 +	/// CPU time return if the caller isn't interested in it.
    3.44  	bool isExpired(time_type now, F64 & started, F64 & stopped, U64 & count);
    3.45  
    3.46  protected:
    3.47 -	time_type	mHorizon;
    3.48 -	bool		mActive;
    3.49 -	bool		mDone;
    3.50 -	time_type	mStarted;
    3.51 -	time_type	mExpires;
    3.52 -	time_type	mStopped;
    3.53 -	time_type	mCount;
    3.54 +	time_type					mHorizon;
    3.55 +	bool						mActive;
    3.56 +	bool						mDone;
    3.57 +	time_type					mStarted;
    3.58 +	time_type					mExpires;
    3.59 +	time_type					mStopped;
    3.60 +	time_type					mCount;
    3.61 +
    3.62 +	const bool					mIncCPU;		// Include CPU metrics in timer
    3.63 +	LLProcInfo::time_type		mUStartCPU;
    3.64 +	LLProcInfo::time_type		mUEndCPU;
    3.65 +	LLProcInfo::time_type		mSStartCPU;
    3.66 +	LLProcInfo::time_type		mSEndCPU;
    3.67  };
    3.68  	
    3.69  
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/indra/llcommon/llprocinfo.cpp	Tue May 07 17:27:12 2013 -0400
     4.3 @@ -0,0 +1,94 @@
     4.4 +/** 
     4.5 +* @file llprocinfo.cpp
     4.6 +* @brief Process, cpu and resource usage information APIs.
     4.7 +* @author monty@lindenlab.com
     4.8 +*
     4.9 +* $LicenseInfo:firstyear=2013&license=viewerlgpl$
    4.10 +* Second Life Viewer Source Code
    4.11 +* Copyright (C) 2013, Linden Research, Inc.
    4.12 +*
    4.13 +* This library is free software; you can redistribute it and/or
    4.14 +* modify it under the terms of the GNU Lesser General Public
    4.15 +* License as published by the Free Software Foundation;
    4.16 +* version 2.1 of the License only.
    4.17 +*
    4.18 +* This library is distributed in the hope that it will be useful,
    4.19 +* but WITHOUT ANY WARRANTY; without even the implied warranty of
    4.20 +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    4.21 +* Lesser General Public License for more details.
    4.22 +*
    4.23 +* You should have received a copy of the GNU Lesser General Public
    4.24 +* License along with this library; if not, write to the Free Software
    4.25 +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
    4.26 +*
    4.27 +* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
    4.28 +* $/LicenseInfo$
    4.29 +*/
    4.30 +
    4.31 +
    4.32 +#include "llprocinfo.h"
    4.33 +
    4.34 +#if LL_WINDOWS
    4.35 +
    4.36 +#define	PSAPI_VERSION	1
    4.37 +#include "windows.h"
    4.38 +#include "psapi.h"
    4.39 +
    4.40 +#elif LL_DARWIN
    4.41 +
    4.42 +#include <sys/resource.h>
    4.43 +#include <mach/mach.h>
    4.44 +	
    4.45 +#else
    4.46 +
    4.47 +#include <sys/time.h>
    4.48 +#include <sys/resource.h>
    4.49 +
    4.50 +#endif // LL_WINDOWS/LL_DARWIN
    4.51 +
    4.52 +
    4.53 +// static
    4.54 +void LLProcInfo::getCPUUsage(time_type & user_time, time_type & system_time)
    4.55 +{
    4.56 +#if LL_WINDOWS
    4.57 +
    4.58 +	HANDLE self(GetCurrentProcess());			// Does not have to be closed
    4.59 +	FILETIME ft_dummy, ft_system, ft_user;
    4.60 +
    4.61 +	GetProcessTimes(self, &ft_dummy, &ft_dummy, &ft_system, &ft_user);
    4.62 +	ULARGE_INTEGER uli;
    4.63 +	uli.u.LowPart = ft_system.dwLowDateTime;
    4.64 +	uli.u.HighPart = ft_system.dwHighDateTime;
    4.65 +	system_time = uli.QuadPart / U64L(10);		// Convert to uS
    4.66 +	uli.u.LowPart = ft_user.dwLowDateTime;
    4.67 +	uli.u.HighPart = ft_user.dwHighDateTime;
    4.68 +	user_time = uli.QuadPart / U64L(10);
    4.69 +	
    4.70 +#elif LL_DARWIN
    4.71 +
    4.72 +	struct rusage usage;
    4.73 +
    4.74 +	if (getrusage(RUSAGE_SELF, &usage))
    4.75 +	{
    4.76 +		user_time = system_time = time_type(0U);
    4.77 +		return;
    4.78 +	}
    4.79 +	user_time = U64(usage.ru_utime.tv_sec) * U64L(1000000) + usage.ru_utime.tv_usec;
    4.80 +	system_time = U64(usage.ru_stime.tv_sec) * U64L(1000000) + usage.ru_stime.tv_usec;
    4.81 +
    4.82 +#else // Linux
    4.83 +
    4.84 +	struct rusage usage;
    4.85 +
    4.86 +	if (getrusage(RUSAGE_SELF, &usage))
    4.87 +	{
    4.88 +		user_time = system_time = time_type(0U);
    4.89 +		return;
    4.90 +	}
    4.91 +	user_time = U64(usage.ru_utime.tv_sec) * U64L(1000000) + usage.ru_utime.tv_usec;
    4.92 +	system_time = U64(usage.ru_stime.tv_sec) * U64L(1000000) + usage.ru_stime.tv_usec;
    4.93 +	
    4.94 +#endif // LL_WINDOWS/LL_DARWIN/Linux
    4.95 +}
    4.96 +
    4.97 +
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/indra/llcommon/llprocinfo.h	Tue May 07 17:27:12 2013 -0400
     5.3 @@ -0,0 +1,68 @@
     5.4 +/** 
     5.5 +* @file   llprocinfo.h
     5.6 +* @brief  Interface to process/cpu/resource information services.
     5.7 +* @author monty@lindenlab.com
     5.8 +*
     5.9 +* $LicenseInfo:firstyear=2013&license=viewerlgpl$
    5.10 +* Second Life Viewer Source Code
    5.11 +* Copyright (C) 2013, Linden Research, Inc.
    5.12 +*
    5.13 +* This library is free software; you can redistribute it and/or
    5.14 +* modify it under the terms of the GNU Lesser General Public
    5.15 +* License as published by the Free Software Foundation;
    5.16 +* version 2.1 of the License only.
    5.17 +*
    5.18 +* This library is distributed in the hope that it will be useful,
    5.19 +* but WITHOUT ANY WARRANTY; without even the implied warranty of
    5.20 +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    5.21 +* Lesser General Public License for more details.
    5.22 +*
    5.23 +* You should have received a copy of the GNU Lesser General Public
    5.24 +* License along with this library; if not, write to the Free Software
    5.25 +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
    5.26 +*
    5.27 +* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
    5.28 +* $/LicenseInfo$
    5.29 +*/
    5.30 +
    5.31 +#ifndef	LL_PROCINFO_H
    5.32 +#define	LL_PROCINFO_H
    5.33 +
    5.34 +
    5.35 +#include "linden_common.h"
    5.36 +
    5.37 +/// @file llprocinfo.h
    5.38 +///
    5.39 +/// Right now, this is really a namespace disguised as a class.
    5.40 +/// It wraps some types and functions to return information about
    5.41 +/// process resource consumption in a non-OS-specific manner.
    5.42 +///
    5.43 +/// Threading:  No instances so that's thread-safe.  Implementations
    5.44 +/// of static functions should be thread-safe, they mostly involve
    5.45 +/// direct syscall invocations.
    5.46 +///
    5.47 +/// Allocation:  Not instantiatable.
    5.48 +
    5.49 +class LL_COMMON_API LLProcInfo
    5.50 +{
    5.51 +public:
    5.52 +	/// Public types
    5.53 +
    5.54 +	typedef U64 time_type;								/// Relative microseconds
    5.55 +	
    5.56 +private:
    5.57 +	LLProcInfo();										// Not defined
    5.58 +	~LLProcInfo();										// Not defined
    5.59 +	LLProcInfo(const LLProcInfo &);						// Not defined
    5.60 +	void operator=(const LLProcInfo &);					// Not defined
    5.61 +
    5.62 +public:
    5.63 +	/// Get accumulated system and user CPU time in
    5.64 +	/// microseconds.  Syscalls involved in every invocation.
    5.65 +	///
    5.66 +	/// Threading:  expected to be safe.
    5.67 +	static void getCPUUsage(time_type & user_time, time_type & system_time);
    5.68 +};
    5.69 +	
    5.70 +
    5.71 +#endif	// LL_PROCINFO_H
     6.1 --- a/indra/llcommon/tests/lldeadmantimer_test.cpp	Tue May 07 17:24:12 2013 -0400
     6.2 +++ b/indra/llcommon/tests/lldeadmantimer_test.cpp	Tue May 07 17:27:12 2013 -0400
     6.3 @@ -28,6 +28,7 @@
     6.4  
     6.5  #include "../lldeadmantimer.h"
     6.6  #include "../llsd.h"
     6.7 +#include "../lltimer.h"
     6.8  
     6.9  #include "../test/lltut.h"
    6.10  
    6.11 @@ -65,14 +66,31 @@
    6.12  template<> template<>
    6.13  void deadmantimer_object_t::test<1>()
    6.14  {
    6.15 -	F64 started(42.0), stopped(97.0);
    6.16 -	U64 count(U64L(8));
    6.17 -	LLDeadmanTimer timer(10.0);
    6.18 +	{
    6.19 +		// Without cpu metrics
    6.20 +		F64 started(42.0), stopped(97.0);
    6.21 +		U64 count(U64L(8));
    6.22 +		LLDeadmanTimer timer(10.0, false);
    6.23  
    6.24 -	ensure_equals("isExpired() returns false after ctor()", timer.isExpired(0, started, stopped, count), false);
    6.25 -	ensure_approximately_equals("t1 - isExpired() does not modify started", started, F64(42.0), 2);
    6.26 -	ensure_approximately_equals("t1 - isExpired() does not modify stopped", stopped, F64(97.0), 2);
    6.27 -	ensure_equals("t1 - isExpired() does not modify count", count, U64L(8));
    6.28 +		ensure_equals("WOCM isExpired() returns false after ctor()", timer.isExpired(0, started, stopped, count), false);
    6.29 +		ensure_approximately_equals("WOCM t1 - isExpired() does not modify started", started, F64(42.0), 2);
    6.30 +		ensure_approximately_equals("WOCM t1 - isExpired() does not modify stopped", stopped, F64(97.0), 2);
    6.31 +		ensure_equals("WOCM t1 - isExpired() does not modify count", count, U64L(8));
    6.32 +	}
    6.33 +
    6.34 +	{
    6.35 +		// With cpu metrics
    6.36 +		F64 started(42.0), stopped(97.0);
    6.37 +		U64 count(U64L(8)), user_cpu(29000), sys_cpu(57000);
    6.38 +		LLDeadmanTimer timer(10.0, true);
    6.39 +
    6.40 +		ensure_equals("WCM isExpired() returns false after ctor()", timer.isExpired(0, started, stopped, count, user_cpu, sys_cpu), false);
    6.41 +		ensure_approximately_equals("WCM t1 - isExpired() does not modify started", started, F64(42.0), 2);
    6.42 +		ensure_approximately_equals("WCM t1 - isExpired() does not modify stopped", stopped, F64(97.0), 2);
    6.43 +		ensure_equals("WCM t1 - isExpired() does not modify count", count, U64L(8));
    6.44 +		ensure_equals("WCM t1 - isExpired() does not modify user_cpu", user_cpu, U64L(29000));
    6.45 +		ensure_equals("WCM t1 - isExpired() does not modify sys_cpu", sys_cpu, U64L(57000));
    6.46 +	}
    6.47  }
    6.48  
    6.49  
    6.50 @@ -80,12 +98,25 @@
    6.51  template<> template<>
    6.52  void deadmantimer_object_t::test<2>()
    6.53  {
    6.54 -	F64 started(42.0), stopped(97.0);
    6.55 -	U64 count(U64L(8));
    6.56 -	LLDeadmanTimer timer(0.0);			// Zero is pre-expired
    6.57 +	{
    6.58 +		// Without cpu metrics
    6.59 +		F64 started(42.0), stopped(97.0);
    6.60 +		U64 count(U64L(8));
    6.61 +		LLDeadmanTimer timer(0.0, false);			// Zero is pre-expired
    6.62 +		
    6.63 +		ensure_equals("WOCM isExpired() still returns false with 0.0 time ctor()",
    6.64 +					  timer.isExpired(0, started, stopped, count), false);
    6.65 +	}
    6.66  
    6.67 -	ensure_equals("isExpired() still returns false with 0.0 time ctor()",
    6.68 -				  timer.isExpired(0, started, stopped, count), false);
    6.69 +	{
    6.70 +		// With cpu metrics
    6.71 +		F64 started(42.0), stopped(97.0);
    6.72 +		U64 count(U64L(8)), user_cpu(29000), sys_cpu(57000);
    6.73 +		LLDeadmanTimer timer(0.0, true);			// Zero is pre-expired
    6.74 +		
    6.75 +		ensure_equals("WCM isExpired() still returns false with 0.0 time ctor()",
    6.76 +					  timer.isExpired(0, started, stopped, count, user_cpu, sys_cpu), false);
    6.77 +	}
    6.78  }
    6.79  
    6.80  
    6.81 @@ -94,14 +125,28 @@
    6.82  template<> template<>
    6.83  void deadmantimer_object_t::test<3>()
    6.84  {
    6.85 -	F64 started(42.0), stopped(97.0);
    6.86 -	U64 count(U64L(8));
    6.87 -	LLDeadmanTimer timer(0.0);
    6.88 +	{
    6.89 +		// Without cpu metrics
    6.90 +		F64 started(42.0), stopped(97.0);
    6.91 +		U64 count(U64L(8));
    6.92 +		LLDeadmanTimer timer(0.0, false);
    6.93  
    6.94 -	timer.start(0);
    6.95 -	ensure_equals("isExpired() returns true with 0.0 horizon time",
    6.96 -				  timer.isExpired(0, started, stopped, count), true);
    6.97 -	ensure_approximately_equals("expired timer with no bell ringing has stopped == started", started, stopped, 8);
    6.98 +		timer.start(0);
    6.99 +		ensure_equals("WOCM isExpired() returns true with 0.0 horizon time",
   6.100 +					  timer.isExpired(0, started, stopped, count), true);
   6.101 + 		ensure_approximately_equals("WOCM expired timer with no bell ringing has stopped == started", started, stopped, 8);
   6.102 +	}
   6.103 +	{
   6.104 +		// With cpu metrics
   6.105 +		F64 started(42.0), stopped(97.0);
   6.106 +		U64 count(U64L(8)), user_cpu(29000), sys_cpu(57000);
   6.107 +		LLDeadmanTimer timer(0.0, true);
   6.108 +
   6.109 +		timer.start(0);
   6.110 +		ensure_equals("WCM isExpired() returns true with 0.0 horizon time",
   6.111 +					  timer.isExpired(0, started, stopped, count, user_cpu, sys_cpu), true);
   6.112 +		ensure_approximately_equals("WCM expired timer with no bell ringing has stopped == started", started, stopped, 8);
   6.113 +	}
   6.114  }
   6.115  
   6.116  
   6.117 @@ -109,15 +154,30 @@
   6.118  template<> template<>
   6.119  void deadmantimer_object_t::test<4>()
   6.120  {
   6.121 -	F64 started(42.0), stopped(97.0);
   6.122 -	U64 count(U64L(8));
   6.123 -	LLDeadmanTimer timer(0.0);
   6.124 +	{
   6.125 +		// Without cpu metrics
   6.126 +		F64 started(42.0), stopped(97.0);
   6.127 +		U64 count(U64L(8));
   6.128 +		LLDeadmanTimer timer(0.0, false);
   6.129  	
   6.130 -	timer.start(0);
   6.131 -	timer.ringBell(LLDeadmanTimer::getNow() + float_time_to_u64(1000.0), 1);
   6.132 -	ensure_equals("isExpired() returns true with 0.0 horizon time after bell ring",
   6.133 -				  timer.isExpired(0, started, stopped, count), true);
   6.134 -	ensure_approximately_equals("ringBell has no impact on expired timer leaving stopped == started", started, stopped, 8);
   6.135 +		timer.start(0);
   6.136 +		timer.ringBell(LLDeadmanTimer::getNow() + float_time_to_u64(1000.0), 1);
   6.137 +		ensure_equals("WOCM isExpired() returns true with 0.0 horizon time after bell ring",
   6.138 +					  timer.isExpired(0, started, stopped, count), true);
   6.139 +		ensure_approximately_equals("WOCM ringBell has no impact on expired timer leaving stopped == started", started, stopped, 8);
   6.140 +	}
   6.141 +	{
   6.142 +		// With cpu metrics
   6.143 +		F64 started(42.0), stopped(97.0);
   6.144 +		U64 count(U64L(8)), user_cpu(29000), sys_cpu(57000);
   6.145 +		LLDeadmanTimer timer(0.0, true);
   6.146 +	
   6.147 +		timer.start(0);
   6.148 +		timer.ringBell(LLDeadmanTimer::getNow() + float_time_to_u64(1000.0), 1);
   6.149 +		ensure_equals("WCM isExpired() returns true with 0.0 horizon time after bell ring",
   6.150 +					  timer.isExpired(0, started, stopped, count, user_cpu, sys_cpu), true);
   6.151 +		ensure_approximately_equals("WCM ringBell has no impact on expired timer leaving stopped == started", started, stopped, 8);
   6.152 +	}
   6.153  }
   6.154  
   6.155  
   6.156 @@ -125,16 +185,34 @@
   6.157  template<> template<>
   6.158  void deadmantimer_object_t::test<5>()
   6.159  {
   6.160 -	F64 started(42.0), stopped(97.0);
   6.161 -	U64 count(U64L(8));
   6.162 -	LLDeadmanTimer timer(10.0);
   6.163 +	{
   6.164 +		// Without cpu metrics
   6.165 +		F64 started(42.0), stopped(97.0);
   6.166 +		U64 count(U64L(8));
   6.167 +		LLDeadmanTimer timer(10.0, false);
   6.168  	
   6.169 -	timer.start(0);
   6.170 -	ensure_equals("isExpired() returns false after starting with 10.0 horizon time",
   6.171 -				  timer.isExpired(0, started, stopped, count), false);
   6.172 -	ensure_approximately_equals("t5 - isExpired() does not modify started", started, F64(42.0), 2);
   6.173 -	ensure_approximately_equals("t5 - isExpired() does not modify stopped", stopped, F64(97.0), 2);
   6.174 -	ensure_equals("t5 - isExpired() does not modify count", count, U64L(8));
   6.175 +		timer.start(0);
   6.176 +		ensure_equals("WOCM isExpired() returns false after starting with 10.0 horizon time",
   6.177 +					  timer.isExpired(0, started, stopped, count), false);
   6.178 +		ensure_approximately_equals("WOCM t5 - isExpired() does not modify started", started, F64(42.0), 2);
   6.179 +		ensure_approximately_equals("WOCM t5 - isExpired() does not modify stopped", stopped, F64(97.0), 2);
   6.180 +		ensure_equals("WOCM t5 - isExpired() does not modify count", count, U64L(8));
   6.181 +	}
   6.182 +	{
   6.183 +		// With cpu metrics
   6.184 +		F64 started(42.0), stopped(97.0);
   6.185 +		U64 count(U64L(8)), user_cpu(29000), sys_cpu(57000);
   6.186 +		LLDeadmanTimer timer(10.0, true);
   6.187 +	
   6.188 +		timer.start(0);
   6.189 +		ensure_equals("WCM isExpired() returns false after starting with 10.0 horizon time",
   6.190 +					  timer.isExpired(0, started, stopped, count, user_cpu, sys_cpu), false);
   6.191 +		ensure_approximately_equals("WCM t5 - isExpired() does not modify started", started, F64(42.0), 2);
   6.192 +		ensure_approximately_equals("WCM t5 - isExpired() does not modify stopped", stopped, F64(97.0), 2);
   6.193 +		ensure_equals("WCM t5 - isExpired() does not modify count", count, U64L(8));
   6.194 +		ensure_equals("WCM t5 - isExpired() does not modify user_cpu", user_cpu, U64L(29000));
   6.195 +		ensure_equals("WCM t5 - isExpired() does not modify sys_cpu", sys_cpu, U64L(57000));
   6.196 +	}
   6.197  }
   6.198  
   6.199  
   6.200 @@ -142,22 +220,46 @@
   6.201  template<> template<>
   6.202  void deadmantimer_object_t::test<6>()
   6.203  {
   6.204 -	F64 started(42.0), stopped(97.0);
   6.205 -	U64 count(U64L(8));
   6.206 -	LLDeadmanTimer timer(10.0);
   6.207 +	{
   6.208 +		// Without cpu metrics
   6.209 +		F64 started(42.0), stopped(97.0);
   6.210 +		U64 count(U64L(8));
   6.211 +		LLDeadmanTimer timer(10.0, false);
   6.212  
   6.213 -	// Would like to do subtraction on current time but can't because
   6.214 -	// the implementation on Windows is zero-based.  We wrap around
   6.215 -	// the backside resulting in a large U64 number.
   6.216 +		// Would like to do subtraction on current time but can't because
   6.217 +		// the implementation on Windows is zero-based.  We wrap around
   6.218 +		// the backside resulting in a large U64 number.
   6.219  	
   6.220 -	LLDeadmanTimer::time_type the_past(LLDeadmanTimer::getNow());
   6.221 -	LLDeadmanTimer::time_type now(the_past + float_time_to_u64(5.0));
   6.222 -	timer.start(the_past);
   6.223 -	ensure_equals("isExpired() returns false with 10.0 horizon time starting 5.0 in past",
   6.224 -				  timer.isExpired(now, started, stopped, count), false);
   6.225 -	ensure_approximately_equals("t6 - isExpired() does not modify started", started, F64(42.0), 2);
   6.226 -	ensure_approximately_equals("t6 - isExpired() does not modify stopped", stopped, F64(97.0), 2);
   6.227 -	ensure_equals("t6 - isExpired() does not modify count", count, U64L(8));
   6.228 +		LLDeadmanTimer::time_type the_past(LLDeadmanTimer::getNow());
   6.229 +		LLDeadmanTimer::time_type now(the_past + float_time_to_u64(5.0));
   6.230 +		timer.start(the_past);
   6.231 +		ensure_equals("WOCM t6 - isExpired() returns false with 10.0 horizon time starting 5.0 in past",
   6.232 +					  timer.isExpired(now, started, stopped, count), false);
   6.233 +		ensure_approximately_equals("WOCM t6 - isExpired() does not modify started", started, F64(42.0), 2);
   6.234 +		ensure_approximately_equals("WOCM t6 - isExpired() does not modify stopped", stopped, F64(97.0), 2);
   6.235 +		ensure_equals("WOCM t6 - isExpired() does not modify count", count, U64L(8));
   6.236 +	}
   6.237 +	{
   6.238 +		// With cpu metrics
   6.239 +		F64 started(42.0), stopped(97.0);
   6.240 +		U64 count(U64L(8)), user_cpu(29000), sys_cpu(57000);
   6.241 +		LLDeadmanTimer timer(10.0, true);
   6.242 +
   6.243 +		// Would like to do subtraction on current time but can't because
   6.244 +		// the implementation on Windows is zero-based.  We wrap around
   6.245 +		// the backside resulting in a large U64 number.
   6.246 +	
   6.247 +		LLDeadmanTimer::time_type the_past(LLDeadmanTimer::getNow());
   6.248 +		LLDeadmanTimer::time_type now(the_past + float_time_to_u64(5.0));
   6.249 +		timer.start(the_past);
   6.250 +		ensure_equals("WCM t6 - isExpired() returns false with 10.0 horizon time starting 5.0 in past",
   6.251 +					  timer.isExpired(now, started, stopped, count, user_cpu, sys_cpu), false);
   6.252 +		ensure_approximately_equals("WCM t6 - isExpired() does not modify started", started, F64(42.0), 2);
   6.253 +		ensure_approximately_equals("WCM t6 - isExpired() does not modify stopped", stopped, F64(97.0), 2);
   6.254 +		ensure_equals("t6 - isExpired() does not modify count", count, U64L(8));
   6.255 +		ensure_equals("WCM t6 - isExpired() does not modify user_cpu", user_cpu, U64L(29000));
   6.256 +		ensure_equals("WCM t6 - isExpired() does not modify sys_cpu", sys_cpu, U64L(57000));
   6.257 +	}
   6.258  }
   6.259  
   6.260  
   6.261 @@ -165,20 +267,40 @@
   6.262  template<> template<>
   6.263  void deadmantimer_object_t::test<7>()
   6.264  {
   6.265 -	F64 started(42.0), stopped(97.0);
   6.266 -	U64 count(U64L(8));
   6.267 -	LLDeadmanTimer timer(10.0);
   6.268 -
   6.269 -	// Would like to do subtraction on current time but can't because
   6.270 -	// the implementation on Windows is zero-based.  We wrap around
   6.271 -	// the backside resulting in a large U64 number.
   6.272 +	{
   6.273 +		// Without cpu metrics
   6.274 +		F64 started(42.0), stopped(97.0);
   6.275 +		U64 count(U64L(8));
   6.276 +		LLDeadmanTimer timer(10.0, false);
   6.277 +		
   6.278 +		// Would like to do subtraction on current time but can't because
   6.279 +		// the implementation on Windows is zero-based.  We wrap around
   6.280 +		// the backside resulting in a large U64 number.
   6.281  	
   6.282 -	LLDeadmanTimer::time_type the_past(LLDeadmanTimer::getNow());
   6.283 -	LLDeadmanTimer::time_type now(the_past + float_time_to_u64(20.0));
   6.284 -	timer.start(the_past);
   6.285 -	ensure_equals("isExpired() returns true with 10.0 horizon time starting 20.0 in past",
   6.286 -				  timer.isExpired(now,started, stopped, count), true);
   6.287 -	ensure_approximately_equals("starting before horizon still gives equal started / stopped", started, stopped, 8);
   6.288 +		LLDeadmanTimer::time_type the_past(LLDeadmanTimer::getNow());
   6.289 +		LLDeadmanTimer::time_type now(the_past + float_time_to_u64(20.0));
   6.290 +		timer.start(the_past);
   6.291 +		ensure_equals("WOCM t7 - isExpired() returns true with 10.0 horizon time starting 20.0 in past",
   6.292 +					  timer.isExpired(now,started, stopped, count), true);
   6.293 +		ensure_approximately_equals("WOCM t7 - starting before horizon still gives equal started / stopped", started, stopped, 8);
   6.294 +	}
   6.295 +	{
   6.296 +		// With cpu metrics
   6.297 +		F64 started(42.0), stopped(97.0);
   6.298 +		U64 count(U64L(8)), user_cpu(29000), sys_cpu(57000);
   6.299 +		LLDeadmanTimer timer(10.0, true);
   6.300 +		
   6.301 +		// Would like to do subtraction on current time but can't because
   6.302 +		// the implementation on Windows is zero-based.  We wrap around
   6.303 +		// the backside resulting in a large U64 number.
   6.304 +	
   6.305 +		LLDeadmanTimer::time_type the_past(LLDeadmanTimer::getNow());
   6.306 +		LLDeadmanTimer::time_type now(the_past + float_time_to_u64(20.0));
   6.307 +		timer.start(the_past);
   6.308 +		ensure_equals("WCM t7 - isExpired() returns true with 10.0 horizon time starting 20.0 in past",
   6.309 +					  timer.isExpired(now,started, stopped, count, user_cpu, sys_cpu), true);
   6.310 +		ensure_approximately_equals("WOCM t7 - starting before horizon still gives equal started / stopped", started, stopped, 8);
   6.311 +	}
   6.312  }
   6.313  
   6.314  
   6.315 @@ -186,28 +308,60 @@
   6.316  template<> template<>
   6.317  void deadmantimer_object_t::test<8>()
   6.318  {
   6.319 -	F64 started(42.0), stopped(97.0);
   6.320 -	U64 count(U64L(8));
   6.321 -	LLDeadmanTimer timer(10.0);
   6.322 +	{
   6.323 +		// Without cpu metrics
   6.324 +		F64 started(42.0), stopped(97.0);
   6.325 +		U64 count(U64L(8));
   6.326 +		LLDeadmanTimer timer(10.0, false);
   6.327  
   6.328 -	// Would like to do subtraction on current time but can't because
   6.329 -	// the implementation on Windows is zero-based.  We wrap around
   6.330 -	// the backside resulting in a large U64 number.
   6.331 +		// Would like to do subtraction on current time but can't because
   6.332 +		// the implementation on Windows is zero-based.  We wrap around
   6.333 +		// the backside resulting in a large U64 number.
   6.334  	
   6.335 -	LLDeadmanTimer::time_type the_past(LLDeadmanTimer::getNow());
   6.336 -	LLDeadmanTimer::time_type now(the_past + float_time_to_u64(20.0));
   6.337 -	timer.start(the_past);
   6.338 -	ensure_equals("t8 - isExpired() returns true with 10.0 horizon time starting 20.0 in past",
   6.339 -				  timer.isExpired(now, started, stopped, count), true);
   6.340 +		LLDeadmanTimer::time_type the_past(LLDeadmanTimer::getNow());
   6.341 +		LLDeadmanTimer::time_type now(the_past + float_time_to_u64(20.0));
   6.342 +		timer.start(the_past);
   6.343 +		ensure_equals("WOCM t8 - isExpired() returns true with 10.0 horizon time starting 20.0 in past",
   6.344 +					  timer.isExpired(now, started, stopped, count), true);
   6.345 +		
   6.346 +		started = 42.0;
   6.347 +		stopped = 97.0;
   6.348 +		count = U64L(8);
   6.349 +		ensure_equals("WOCM t8 - second isExpired() returns false after true",
   6.350 +					  timer.isExpired(now, started, stopped, count), false);
   6.351 +		ensure_approximately_equals("WOCM t8 - 2nd isExpired() does not modify started", started, F64(42.0), 2);
   6.352 +		ensure_approximately_equals("WOCM t8 - 2nd isExpired() does not modify stopped", stopped, F64(97.0), 2);
   6.353 +		ensure_equals("WOCM t8 - 2nd isExpired() does not modify count", count, U64L(8));
   6.354 +	}
   6.355 +	{
   6.356 +		// With cpu metrics
   6.357 +		F64 started(42.0), stopped(97.0);
   6.358 +		U64 count(U64L(8)), user_cpu(29000), sys_cpu(57000);
   6.359 +		LLDeadmanTimer timer(10.0, true);
   6.360  
   6.361 -	started = 42.0;
   6.362 -	stopped = 97.0;
   6.363 -	count = U64L(8);
   6.364 -	ensure_equals("t8 - second isExpired() returns false after true",
   6.365 -				  timer.isExpired(now, started, stopped, count), false);
   6.366 -	ensure_approximately_equals("t8 - 2nd isExpired() does not modify started", started, F64(42.0), 2);
   6.367 -	ensure_approximately_equals("t8 - 2nd isExpired() does not modify stopped", stopped, F64(97.0), 2);
   6.368 -	ensure_equals("t8 - 2nd isExpired() does not modify count", count, U64L(8));
   6.369 +		// Would like to do subtraction on current time but can't because
   6.370 +		// the implementation on Windows is zero-based.  We wrap around
   6.371 +		// the backside resulting in a large U64 number.
   6.372 +	
   6.373 +		LLDeadmanTimer::time_type the_past(LLDeadmanTimer::getNow());
   6.374 +		LLDeadmanTimer::time_type now(the_past + float_time_to_u64(20.0));
   6.375 +		timer.start(the_past);
   6.376 +		ensure_equals("WCM t8 - isExpired() returns true with 10.0 horizon time starting 20.0 in past",
   6.377 +					  timer.isExpired(now, started, stopped, count, user_cpu, sys_cpu), true);
   6.378 +		
   6.379 +		started = 42.0;
   6.380 +		stopped = 97.0;
   6.381 +		count = U64L(8);
   6.382 +		user_cpu = 29000;
   6.383 +		sys_cpu = 57000;
   6.384 +		ensure_equals("WCM t8 - second isExpired() returns false after true",
   6.385 +					  timer.isExpired(now, started, stopped, count), false);
   6.386 +		ensure_approximately_equals("WCM t8 - 2nd isExpired() does not modify started", started, F64(42.0), 2);
   6.387 +		ensure_approximately_equals("WCM t8 - 2nd isExpired() does not modify stopped", stopped, F64(97.0), 2);
   6.388 +		ensure_equals("WCM t8 - 2nd isExpired() does not modify count", count, U64L(8));
   6.389 +		ensure_equals("WCM t8 - 2nd isExpired() does not modify user_cpu", user_cpu, U64L(29000));
   6.390 +		ensure_equals("WCM t8 - 2nd isExpired() does not modify sys_cpu", sys_cpu, U64L(57000));
   6.391 +	}
   6.392  }
   6.393  
   6.394  
   6.395 @@ -215,46 +369,92 @@
   6.396  template<> template<>
   6.397  void deadmantimer_object_t::test<9>()
   6.398  {
   6.399 -	F64 started(42.0), stopped(97.0);
   6.400 -	U64 count(U64L(8));
   6.401 -	LLDeadmanTimer timer(5.0);
   6.402 +	{
   6.403 +		// Without cpu metrics
   6.404 +		F64 started(42.0), stopped(97.0);
   6.405 +		U64 count(U64L(8));
   6.406 +		LLDeadmanTimer timer(5.0, false);
   6.407  
   6.408 -	LLDeadmanTimer::time_type now(LLDeadmanTimer::getNow());
   6.409 -	F64 real_start(u64_time_to_float(now));
   6.410 -	timer.start(0);
   6.411 +		LLDeadmanTimer::time_type now(LLDeadmanTimer::getNow());
   6.412 +		F64 real_start(u64_time_to_float(now));
   6.413 +		timer.start(0);
   6.414  
   6.415 -	now += float_time_to_u64(1.0);
   6.416 -	timer.ringBell(now, 1);
   6.417 -	now += float_time_to_u64(1.0);
   6.418 -	timer.ringBell(now, 1);
   6.419 -	now += float_time_to_u64(1.0);
   6.420 -	timer.ringBell(now, 1);
   6.421 -	now += float_time_to_u64(1.0);
   6.422 -	timer.ringBell(now, 1);
   6.423 -	now += float_time_to_u64(1.0);
   6.424 -	timer.ringBell(now, 1);
   6.425 -	now += float_time_to_u64(1.0);
   6.426 -	timer.ringBell(now, 1);
   6.427 -	now += float_time_to_u64(1.0);
   6.428 -	timer.ringBell(now, 1);
   6.429 -	now += float_time_to_u64(1.0);
   6.430 -	timer.ringBell(now, 1);
   6.431 -	now += float_time_to_u64(1.0);
   6.432 -	timer.ringBell(now, 1);
   6.433 -	now += float_time_to_u64(1.0);
   6.434 -	timer.ringBell(now, 1);
   6.435 -	ensure_equals("t9 - 5.0 horizon timer has not timed out after 10 1-second bell rings",
   6.436 -				  timer.isExpired(now, started, stopped, count), false);
   6.437 -	F64 last_good_ring(u64_time_to_float(now));
   6.438 +		now += float_time_to_u64(1.0);
   6.439 +		timer.ringBell(now, 1);
   6.440 +		now += float_time_to_u64(1.0);
   6.441 +		timer.ringBell(now, 1);
   6.442 +		now += float_time_to_u64(1.0);
   6.443 +		timer.ringBell(now, 1);
   6.444 +		now += float_time_to_u64(1.0);
   6.445 +		timer.ringBell(now, 1);
   6.446 +		now += float_time_to_u64(1.0);
   6.447 +		timer.ringBell(now, 1);
   6.448 +		now += float_time_to_u64(1.0);
   6.449 +		timer.ringBell(now, 1);
   6.450 +		now += float_time_to_u64(1.0);
   6.451 +		timer.ringBell(now, 1);
   6.452 +		now += float_time_to_u64(1.0);
   6.453 +		timer.ringBell(now, 1);
   6.454 +		now += float_time_to_u64(1.0);
   6.455 +		timer.ringBell(now, 1);
   6.456 +		now += float_time_to_u64(1.0);
   6.457 +		timer.ringBell(now, 1);
   6.458 +		ensure_equals("WOCM t9 - 5.0 horizon timer has not timed out after 10 1-second bell rings",
   6.459 +					  timer.isExpired(now, started, stopped, count), false);
   6.460 +		F64 last_good_ring(u64_time_to_float(now));
   6.461  
   6.462 -	// Jump forward and expire
   6.463 -	now += float_time_to_u64(10.0);
   6.464 -	ensure_equals("t9 - 5.0 horizon timer expires on 10-second jump",
   6.465 -				  timer.isExpired(now, started, stopped, count), true);
   6.466 -	ensure_approximately_equals("t9 - started matches start() time", started, real_start, 4);
   6.467 -	ensure_approximately_equals("t9 - stopped matches last ringBell() time", stopped, last_good_ring, 4);
   6.468 -	ensure_equals("t9 - 10 good ringBell()s", count, U64L(10));
   6.469 -	ensure_equals("t9 - single read only", timer.isExpired(now, started, stopped, count), false);
   6.470 +		// Jump forward and expire
   6.471 +		now += float_time_to_u64(10.0);
   6.472 +		ensure_equals("WOCM t9 - 5.0 horizon timer expires on 10-second jump",
   6.473 +					  timer.isExpired(now, started, stopped, count), true);
   6.474 +		ensure_approximately_equals("WOCM t9 - started matches start() time", started, real_start, 4);
   6.475 +		ensure_approximately_equals("WOCM t9 - stopped matches last ringBell() time", stopped, last_good_ring, 4);
   6.476 +		ensure_equals("WOCM t9 - 10 good ringBell()s", count, U64L(10));
   6.477 +		ensure_equals("WOCM t9 - single read only", timer.isExpired(now, started, stopped, count), false);
   6.478 +	}
   6.479 +	{
   6.480 +		// With cpu metrics
   6.481 +		F64 started(42.0), stopped(97.0);
   6.482 +		U64 count(U64L(8)), user_cpu(29000), sys_cpu(57000);
   6.483 +		LLDeadmanTimer timer(5.0, true);
   6.484 +
   6.485 +		LLDeadmanTimer::time_type now(LLDeadmanTimer::getNow());
   6.486 +		F64 real_start(u64_time_to_float(now));
   6.487 +		timer.start(0);
   6.488 +
   6.489 +		now += float_time_to_u64(1.0);
   6.490 +		timer.ringBell(now, 1);
   6.491 +		now += float_time_to_u64(1.0);
   6.492 +		timer.ringBell(now, 1);
   6.493 +		now += float_time_to_u64(1.0);
   6.494 +		timer.ringBell(now, 1);
   6.495 +		now += float_time_to_u64(1.0);
   6.496 +		timer.ringBell(now, 1);
   6.497 +		now += float_time_to_u64(1.0);
   6.498 +		timer.ringBell(now, 1);
   6.499 +		now += float_time_to_u64(1.0);
   6.500 +		timer.ringBell(now, 1);
   6.501 +		now += float_time_to_u64(1.0);
   6.502 +		timer.ringBell(now, 1);
   6.503 +		now += float_time_to_u64(1.0);
   6.504 +		timer.ringBell(now, 1);
   6.505 +		now += float_time_to_u64(1.0);
   6.506 +		timer.ringBell(now, 1);
   6.507 +		now += float_time_to_u64(1.0);
   6.508 +		timer.ringBell(now, 1);
   6.509 +		ensure_equals("WCM t9 - 5.0 horizon timer has not timed out after 10 1-second bell rings",
   6.510 +					  timer.isExpired(now, started, stopped, count, user_cpu, sys_cpu), false);
   6.511 +		F64 last_good_ring(u64_time_to_float(now));
   6.512 +
   6.513 +		// Jump forward and expire
   6.514 +		now += float_time_to_u64(10.0);
   6.515 +		ensure_equals("WCM t9 - 5.0 horizon timer expires on 10-second jump",
   6.516 +					  timer.isExpired(now, started, stopped, count, user_cpu, sys_cpu), true);
   6.517 +		ensure_approximately_equals("WCM t9 - started matches start() time", started, real_start, 4);
   6.518 +		ensure_approximately_equals("WCM t9 - stopped matches last ringBell() time", stopped, last_good_ring, 4);
   6.519 +		ensure_equals("WCM t9 - 10 good ringBell()s", count, U64L(10));
   6.520 +		ensure_equals("WCM t9 - single read only", timer.isExpired(now, started, stopped, count, user_cpu, sys_cpu), false);
   6.521 +	}
   6.522  }
   6.523  
   6.524  
   6.525 @@ -262,83 +462,167 @@
   6.526  template<> template<>
   6.527  void deadmantimer_object_t::test<10>()
   6.528  {
   6.529 -	F64 started(42.0), stopped(97.0);
   6.530 -	U64 count(U64L(8));
   6.531 -	LLDeadmanTimer timer(5.0);
   6.532 +	{
   6.533 +		// Without cpu metrics
   6.534 +		F64 started(42.0), stopped(97.0);
   6.535 +		U64 count(U64L(8));
   6.536 +		LLDeadmanTimer timer(5.0, false);
   6.537  
   6.538 -	LLDeadmanTimer::time_type now(LLDeadmanTimer::getNow());
   6.539 -	F64 real_start(u64_time_to_float(now));
   6.540 -	timer.start(0);
   6.541 +		LLDeadmanTimer::time_type now(LLDeadmanTimer::getNow());
   6.542 +		F64 real_start(u64_time_to_float(now));
   6.543 +		timer.start(0);
   6.544  
   6.545 -	now += float_time_to_u64(1.0);
   6.546 -	timer.ringBell(now, 1);
   6.547 -	now += float_time_to_u64(1.0);
   6.548 -	timer.ringBell(now, 1);
   6.549 -	now += float_time_to_u64(1.0);
   6.550 -	timer.ringBell(now, 1);
   6.551 -	now += float_time_to_u64(1.0);
   6.552 -	timer.ringBell(now, 1);
   6.553 -	now += float_time_to_u64(1.0);
   6.554 -	timer.ringBell(now, 1);
   6.555 -	now += float_time_to_u64(1.0);
   6.556 -	timer.ringBell(now, 1);
   6.557 -	now += float_time_to_u64(1.0);
   6.558 -	timer.ringBell(now, 1);
   6.559 -	now += float_time_to_u64(1.0);
   6.560 -	timer.ringBell(now, 1);
   6.561 -	now += float_time_to_u64(1.0);
   6.562 -	timer.ringBell(now, 1);
   6.563 -	now += float_time_to_u64(1.0);
   6.564 -	timer.ringBell(now, 1);
   6.565 -	ensure_equals("t10 - 5.0 horizon timer has not timed out after 10 1-second bell rings",
   6.566 -				  timer.isExpired(now, started, stopped, count), false);
   6.567 -	F64 last_good_ring(u64_time_to_float(now));
   6.568 +		now += float_time_to_u64(1.0);
   6.569 +		timer.ringBell(now, 1);
   6.570 +		now += float_time_to_u64(1.0);
   6.571 +		timer.ringBell(now, 1);
   6.572 +		now += float_time_to_u64(1.0);
   6.573 +		timer.ringBell(now, 1);
   6.574 +		now += float_time_to_u64(1.0);
   6.575 +		timer.ringBell(now, 1);
   6.576 +		now += float_time_to_u64(1.0);
   6.577 +		timer.ringBell(now, 1);
   6.578 +		now += float_time_to_u64(1.0);
   6.579 +		timer.ringBell(now, 1);
   6.580 +		now += float_time_to_u64(1.0);
   6.581 +		timer.ringBell(now, 1);
   6.582 +		now += float_time_to_u64(1.0);
   6.583 +		timer.ringBell(now, 1);
   6.584 +		now += float_time_to_u64(1.0);
   6.585 +		timer.ringBell(now, 1);
   6.586 +		now += float_time_to_u64(1.0);
   6.587 +		timer.ringBell(now, 1);
   6.588 +		ensure_equals("WOCM t10 - 5.0 horizon timer has not timed out after 10 1-second bell rings",
   6.589 +					  timer.isExpired(now, started, stopped, count), false);
   6.590 +		F64 last_good_ring(u64_time_to_float(now));
   6.591  
   6.592 -	// Jump forward and expire
   6.593 -	now += float_time_to_u64(10.0);
   6.594 -	ensure_equals("t10 - 5.0 horizon timer expires on 10-second jump",
   6.595 -				  timer.isExpired(now, started, stopped, count), true);
   6.596 -	ensure_approximately_equals("t10 - started matches start() time", started, real_start, 4);
   6.597 -	ensure_approximately_equals("t10 - stopped matches last ringBell() time", stopped, last_good_ring, 4);
   6.598 -	ensure_equals("t10 - 10 good ringBell()s", count, U64L(10));
   6.599 -	ensure_equals("t10 - single read only", timer.isExpired(now, started, stopped, count), false);
   6.600 +		// Jump forward and expire
   6.601 +		now += float_time_to_u64(10.0);
   6.602 +		ensure_equals("WOCM t10 - 5.0 horizon timer expires on 10-second jump",
   6.603 +					  timer.isExpired(now, started, stopped, count), true);
   6.604 +		ensure_approximately_equals("WOCM t10 - started matches start() time", started, real_start, 4);
   6.605 +		ensure_approximately_equals("WOCM t10 - stopped matches last ringBell() time", stopped, last_good_ring, 4);
   6.606 +		ensure_equals("WOCM t10 - 10 good ringBell()s", count, U64L(10));
   6.607 +		ensure_equals("WOCM t10 - single read only", timer.isExpired(now, started, stopped, count), false);
   6.608 +		
   6.609 +		// Jump forward and restart
   6.610 +		now += float_time_to_u64(1.0);
   6.611 +		real_start = u64_time_to_float(now);
   6.612 +		timer.start(now);
   6.613 +		
   6.614 +		// Run a modified bell ring sequence
   6.615 +		now += float_time_to_u64(1.0);
   6.616 +		timer.ringBell(now, 1);
   6.617 +		now += float_time_to_u64(1.0);
   6.618 +		timer.ringBell(now, 1);
   6.619 +		now += float_time_to_u64(1.0);
   6.620 +		timer.ringBell(now, 1);
   6.621 +		now += float_time_to_u64(1.0);
   6.622 +		timer.ringBell(now, 1);
   6.623 +		now += float_time_to_u64(1.0);
   6.624 +		timer.ringBell(now, 1);
   6.625 +		now += float_time_to_u64(1.0);
   6.626 +		timer.ringBell(now, 1);
   6.627 +		now += float_time_to_u64(1.0);
   6.628 +		timer.ringBell(now, 1);
   6.629 +		now += float_time_to_u64(1.0);
   6.630 +		timer.ringBell(now, 1);
   6.631 +		ensure_equals("WOCM t10 - 5.0 horizon timer has not timed out after 8 1-second bell rings",
   6.632 +					  timer.isExpired(now, started, stopped, count), false);
   6.633 +		last_good_ring = u64_time_to_float(now);
   6.634  
   6.635 -	// Jump forward and restart
   6.636 -	now += float_time_to_u64(1.0);
   6.637 -	real_start = u64_time_to_float(now);
   6.638 -	timer.start(now);
   6.639 +		// Jump forward and expire
   6.640 +		now += float_time_to_u64(10.0);
   6.641 +		ensure_equals("WOCM t10 - 5.0 horizon timer expires on 8-second jump",
   6.642 +					  timer.isExpired(now, started, stopped, count), true);
   6.643 +		ensure_approximately_equals("WOCM t10 - 2nd started matches start() time", started, real_start, 4);
   6.644 +		ensure_approximately_equals("WOCM t10 - 2nd stopped matches last ringBell() time", stopped, last_good_ring, 4);
   6.645 +		ensure_equals("WOCM t10 - 8 good ringBell()s", count, U64L(8));
   6.646 +		ensure_equals("WOCM t10 - single read only - 2nd start",
   6.647 +					  timer.isExpired(now, started, stopped, count), false);
   6.648 +	}
   6.649 +	{
   6.650 +		// With cpu metrics
   6.651 +		F64 started(42.0), stopped(97.0);
   6.652 +		U64 count(U64L(8)), user_cpu(29000), sys_cpu(57000);
   6.653  
   6.654 -	// Run a modified bell ring sequence
   6.655 -	now += float_time_to_u64(1.0);
   6.656 -	timer.ringBell(now, 1);
   6.657 -	now += float_time_to_u64(1.0);
   6.658 -	timer.ringBell(now, 1);
   6.659 -	now += float_time_to_u64(1.0);
   6.660 -	timer.ringBell(now, 1);
   6.661 -	now += float_time_to_u64(1.0);
   6.662 -	timer.ringBell(now, 1);
   6.663 -	now += float_time_to_u64(1.0);
   6.664 -	timer.ringBell(now, 1);
   6.665 -	now += float_time_to_u64(1.0);
   6.666 -	timer.ringBell(now, 1);
   6.667 -	now += float_time_to_u64(1.0);
   6.668 -	timer.ringBell(now, 1);
   6.669 -	now += float_time_to_u64(1.0);
   6.670 -	timer.ringBell(now, 1);
   6.671 -	ensure_equals("t10 - 5.0 horizon timer has not timed out after 8 1-second bell rings",
   6.672 -				  timer.isExpired(now, started, stopped, count), false);
   6.673 -	last_good_ring = u64_time_to_float(now);
   6.674 +		LLDeadmanTimer timer(5.0, true);
   6.675  
   6.676 -	// Jump forward and expire
   6.677 -	now += float_time_to_u64(10.0);
   6.678 -	ensure_equals("t10 - 5.0 horizon timer expires on 8-second jump",
   6.679 -				  timer.isExpired(now, started, stopped, count), true);
   6.680 -	ensure_approximately_equals("t10 - 2nd started matches start() time", started, real_start, 4);
   6.681 -	ensure_approximately_equals("t10 - 2nd stopped matches last ringBell() time", stopped, last_good_ring, 4);
   6.682 -	ensure_equals("t10 - 8 good ringBell()s", count, U64L(8));
   6.683 -	ensure_equals("t10 - single read only - 2nd start",
   6.684 -				  timer.isExpired(now, started, stopped, count), false);
   6.685 +		LLDeadmanTimer::time_type now(LLDeadmanTimer::getNow());
   6.686 +		F64 real_start(u64_time_to_float(now));
   6.687 +		timer.start(0);
   6.688 +
   6.689 +		now += float_time_to_u64(1.0);
   6.690 +		timer.ringBell(now, 1);
   6.691 +		now += float_time_to_u64(1.0);
   6.692 +		timer.ringBell(now, 1);
   6.693 +		now += float_time_to_u64(1.0);
   6.694 +		timer.ringBell(now, 1);
   6.695 +		now += float_time_to_u64(1.0);
   6.696 +		timer.ringBell(now, 1);
   6.697 +		now += float_time_to_u64(1.0);
   6.698 +		timer.ringBell(now, 1);
   6.699 +		now += float_time_to_u64(1.0);
   6.700 +		timer.ringBell(now, 1);
   6.701 +		now += float_time_to_u64(1.0);
   6.702 +		timer.ringBell(now, 1);
   6.703 +		now += float_time_to_u64(1.0);
   6.704 +		timer.ringBell(now, 1);
   6.705 +		now += float_time_to_u64(1.0);
   6.706 +		timer.ringBell(now, 1);
   6.707 +		now += float_time_to_u64(1.0);
   6.708 +		timer.ringBell(now, 1);
   6.709 +		ensure_equals("WCM t10 - 5.0 horizon timer has not timed out after 10 1-second bell rings",
   6.710 +					  timer.isExpired(now, started, stopped, count, user_cpu, sys_cpu), false);
   6.711 +		F64 last_good_ring(u64_time_to_float(now));
   6.712 +
   6.713 +		// Jump forward and expire
   6.714 +		now += float_time_to_u64(10.0);
   6.715 +		ensure_equals("WCM t10 - 5.0 horizon timer expires on 10-second jump",
   6.716 +					  timer.isExpired(now, started, stopped, count, user_cpu, sys_cpu), true);
   6.717 +		ensure_approximately_equals("WCM t10 - started matches start() time", started, real_start, 4);
   6.718 +		ensure_approximately_equals("WCM t10 - stopped matches last ringBell() time", stopped, last_good_ring, 4);
   6.719 +		ensure_equals("WCM t10 - 10 good ringBell()s", count, U64L(10));
   6.720 +		ensure_equals("WCM t10 - single read only", timer.isExpired(now, started, stopped, count, user_cpu, sys_cpu), false);
   6.721 +		
   6.722 +		// Jump forward and restart
   6.723 +		now += float_time_to_u64(1.0);
   6.724 +		real_start = u64_time_to_float(now);
   6.725 +		timer.start(now);
   6.726 +		
   6.727 +		// Run a modified bell ring sequence
   6.728 +		now += float_time_to_u64(1.0);
   6.729 +		timer.ringBell(now, 1);
   6.730 +		now += float_time_to_u64(1.0);
   6.731 +		timer.ringBell(now, 1);
   6.732 +		now += float_time_to_u64(1.0);
   6.733 +		timer.ringBell(now, 1);
   6.734 +		now += float_time_to_u64(1.0);
   6.735 +		timer.ringBell(now, 1);
   6.736 +		now += float_time_to_u64(1.0);
   6.737 +		timer.ringBell(now, 1);
   6.738 +		now += float_time_to_u64(1.0);
   6.739 +		timer.ringBell(now, 1);
   6.740 +		now += float_time_to_u64(1.0);
   6.741 +		timer.ringBell(now, 1);
   6.742 +		now += float_time_to_u64(1.0);
   6.743 +		timer.ringBell(now, 1);
   6.744 +		ensure_equals("WCM t10 - 5.0 horizon timer has not timed out after 8 1-second bell rings",
   6.745 +					  timer.isExpired(now, started, stopped, count, user_cpu, sys_cpu), false);
   6.746 +		last_good_ring = u64_time_to_float(now);
   6.747 +
   6.748 +		// Jump forward and expire
   6.749 +		now += float_time_to_u64(10.0);
   6.750 +		ensure_equals("WCM t10 - 5.0 horizon timer expires on 8-second jump",
   6.751 +					  timer.isExpired(now, started, stopped, count, user_cpu, sys_cpu), true);
   6.752 +		ensure_approximately_equals("WCM t10 - 2nd started matches start() time", started, real_start, 4);
   6.753 +		ensure_approximately_equals("WCM t10 - 2nd stopped matches last ringBell() time", stopped, last_good_ring, 4);
   6.754 +		ensure_equals("WCM t10 - 8 good ringBell()s", count, U64L(8));
   6.755 +		ensure_equals("WCM t10 - single read only - 2nd start",
   6.756 +					  timer.isExpired(now, started, stopped, count, user_cpu, sys_cpu), false);
   6.757 +	}
   6.758  }
   6.759  
   6.760  
   6.761 +
   6.762  } // end namespace tut
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/indra/llcommon/tests/llprocinfo_test.cpp	Tue May 07 17:27:12 2013 -0400
     7.3 @@ -0,0 +1,91 @@
     7.4 +/** 
     7.5 + * @file llprocinfo_test.cpp
     7.6 + * @brief Tests for the LLProcInfo class.
     7.7 + *
     7.8 + * $LicenseInfo:firstyear=2013&license=viewerlgpl$
     7.9 + * Second Life Viewer Source Code
    7.10 + * Copyright (C) 2013, Linden Research, Inc.
    7.11 + * 
    7.12 + * This library is free software; you can redistribute it and/or
    7.13 + * modify it under the terms of the GNU Lesser General Public
    7.14 + * License as published by the Free Software Foundation;
    7.15 + * version 2.1 of the License only.
    7.16 + * 
    7.17 + * This library is distributed in the hope that it will be useful,
    7.18 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    7.19 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    7.20 + * Lesser General Public License for more details.
    7.21 + * 
    7.22 + * You should have received a copy of the GNU Lesser General Public
    7.23 + * License along with this library; if not, write to the Free Software
    7.24 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
    7.25 + * 
    7.26 + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
    7.27 + * $/LicenseInfo$
    7.28 + */
    7.29 +
    7.30 +#include "linden_common.h"
    7.31 +
    7.32 +#include "../llprocinfo.h"
    7.33 +
    7.34 +#include "../test/lltut.h"
    7.35 +#include "../lltimer.h"
    7.36 +
    7.37 +
    7.38 +static const LLProcInfo::time_type bad_user(289375U), bad_system(275U);
    7.39 +
    7.40 +
    7.41 +namespace tut
    7.42 +{
    7.43 +
    7.44 +struct procinfo_test
    7.45 +{
    7.46 +	procinfo_test()
    7.47 +		{
    7.48 +		}
    7.49 +};
    7.50 +
    7.51 +typedef test_group<procinfo_test> procinfo_group_t;
    7.52 +typedef procinfo_group_t::object procinfo_object_t;
    7.53 +tut::procinfo_group_t procinfo_instance("LLProcInfo");
    7.54 +
    7.55 +
    7.56 +// Basic invocation works
    7.57 +template<> template<>
    7.58 +void procinfo_object_t::test<1>()
    7.59 +{
    7.60 +	LLProcInfo::time_type user(bad_user), system(bad_system);
    7.61 +
    7.62 +	set_test_name("getCPUUsage() basic function");
    7.63 +
    7.64 +	LLProcInfo::getCPUUsage(user, system);
    7.65 +	
    7.66 +	ensure_not_equals("getCPUUsage() writes to its user argument", user, bad_user);
    7.67 +	ensure_not_equals("getCPUUsage() writes to its system argument", system, bad_system);
    7.68 +}
    7.69 +
    7.70 +
    7.71 +// Time increases
    7.72 +template<> template<>
    7.73 +void procinfo_object_t::test<2>()
    7.74 +{
    7.75 +	LLProcInfo::time_type user(bad_user), system(bad_system);
    7.76 +	LLProcInfo::time_type user2(bad_user), system2(bad_system);
    7.77 +
    7.78 +	set_test_name("getCPUUsage() increases over time");
    7.79 +
    7.80 +	LLProcInfo::getCPUUsage(user, system);
    7.81 +	
    7.82 +	for (int i(0); i < 100000; ++i)
    7.83 +	{
    7.84 +		ms_sleep(0);
    7.85 +	}
    7.86 +	
    7.87 +	LLProcInfo::getCPUUsage(user2, system2);
    7.88 +
    7.89 +	ensure_equals("getCPUUsage() user value doesn't decrease over time", user2 >= user, true);
    7.90 +	ensure_equals("getCPUUsage() system value doesn't decrease over time", system2 >= system, true);
    7.91 +}
    7.92 +
    7.93 +
    7.94 +} // end namespace tut
     8.1 --- a/indra/newview/llmeshrepository.cpp	Tue May 07 17:24:12 2013 -0400
     8.2 +++ b/indra/newview/llmeshrepository.cpp	Tue May 07 17:27:12 2013 -0400
     8.3 @@ -98,7 +98,7 @@
     8.4  U32 LLMeshRepository::sCacheBytesRead = 0;
     8.5  U32 LLMeshRepository::sCacheBytesWritten = 0;
     8.6  U32 LLMeshRepository::sPeakKbps = 0;
     8.7 -LLDeadmanTimer LLMeshRepository::sQuiescentTimer(15.0);
     8.8 +LLDeadmanTimer LLMeshRepository::sQuiescentTimer(15.0, true);	// true -> gather cpu metrics
     8.9  
    8.10  	
    8.11  const U32 MAX_TEXTURE_UPLOAD_RETRIES = 5;
    8.12 @@ -4420,9 +4420,9 @@
    8.13  void LLMeshRepository::metricsUpdate()
    8.14  {
    8.15  	F64 started, stopped;
    8.16 -	U64 total_count;
    8.17 -
    8.18 -	if (sQuiescentTimer.isExpired(0, started, stopped, total_count))
    8.19 +	U64 total_count(U64L(0)), user_cpu(U64L(0)), sys_cpu(U64L(0));
    8.20 +	
    8.21 +	if (sQuiescentTimer.isExpired(0, started, stopped, total_count, user_cpu, sys_cpu))
    8.22  	{
    8.23  		LLSD metrics;
    8.24  
    8.25 @@ -4432,6 +4432,8 @@
    8.26  		metrics["stop"] = stopped;
    8.27  		metrics["downloads"] = LLSD::Integer(total_count);
    8.28  		metrics["teleports"] = LLSD::Integer(metrics_teleport_start_count);
    8.29 +		metrics["user_cpu"] = double(user_cpu) / 1.0e6;
    8.30 +		metrics["sys_cpu"] = double(sys_cpu) / 1.0e6;
    8.31  		llinfos << "EventMarker " << metrics << llendl;
    8.32  	}
    8.33  }

mercurial