|
|
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: Miscellaneous code
//
//=============================================================================
#include "stdafx.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
//-----------------------------------------------------------------------------
// Purpose: Tells us whether an account name looks like a VTT account name
// (used as an exception for IP-based rate limiting)
//-----------------------------------------------------------------------------
bool IsVTTAccountName( const char *szAccountName ) { const static char *k_szCafe = "valvecafepc";
if ( 0 == Q_strncmp( szAccountName, k_szCafe, Q_strlen( k_szCafe ) ) ) return true; return false; }
//-----------------------------------------------------------------------------
// Random number generation
// Use this system for all random number generation. It's very fast, and is
// integrated with our automated tests so that we can perform reproducibly "random"
// test cases.
//-----------------------------------------------------------------------------
uint32 g_unRandCur = 0; int g_iunRandMask = 0;
// k_rgunMask
// Set of masks used by our quick and dirty random number generator.
const uint32 k_rgunMask[17] = { 0x1739a3b0, 0xb8907fe1, 0x8290d3b7, 0x72839cd0, 0x242df096, 0x3829750b, 0x38de7a77, 0x72f0924c, 0x44783927, 0x01925372, 0x20902714, 0x27585920, 0x27890632, 0x82910476, 0x72906721, 0x28798904, 0x78592700, };
//-----------------------------------------------------------------------------
// Purpose: Quickly generates a vaguely random number.
// Output: A vaguely random number.
//-----------------------------------------------------------------------------
uint32 UNRandFast() { g_iunRandMask++; g_unRandCur += 637429601; // Just add a large prime number (we'll wrap frequently)
return ( g_unRandCur ^ k_rgunMask[ g_iunRandMask % 17 ] ); }
//-----------------------------------------------------------------------------
// Purpose: Quickly generates a vaguely random character.
// Output: A vaguely random char in the range [32,126].
//-----------------------------------------------------------------------------
char CHRandFast() { return ( UNRandFast() % 95 ) + 32; }
//-----------------------------------------------------------------------------
// Purpose: Sets the random number seed (note that we actually break this down
// into two parts: g_unRandCur and g_iunRandMask).
// Input: ulRandSeed: Value to use as our seed
//-----------------------------------------------------------------------------
void SetRandSeed( uint64 ulRandSeed ) { g_unRandCur = ulRandSeed >> 32; g_iunRandMask = ulRandSeed & 0xffffffff; }
//-----------------------------------------------------------------------------
// Purpose: Returns the current random number seed (actually a composite of
// g_unRandCur and g_iunRandMask)
// Output: Our current 64 bit random number seed.
//-----------------------------------------------------------------------------
uint64 GetRandSeed() { return ( ( ((uint64)g_unRandCur) << 32 ) + g_iunRandMask ); }
//-----------------------------------------------------------------------------
// Purpose: Quickly fill a memory block with random bytes
//-----------------------------------------------------------------------------
void RandMem(void *dest, int count) { unsigned char *pDest = (unsigned char *)dest;
while ( count >= 4 ) { *(uint32*)(pDest) = UNRandFast(); pDest+=4; count-=4; }
while ( count > 0 ) { *pDest = UNRandFast(); pDest++; count--; } }
//-----------------------------------------------------------------------------
// Purpose: Calculates the percentage of numerator/demoninator, or 0 if
// denominator is 0.
//-----------------------------------------------------------------------------
float SafeCalcPct( uint64 ulNumerator, uint64 ulDenominator ) { if ( 0 == ulDenominator ) return 0; return ( 100.0f * (float) ulNumerator / (float) ulDenominator ); }
//-----------------------------------------------------------------------------
// Purpose: Common code to reject an operation due to a time backlog.
// Does a gradual fade of 0% rejections at the specified threshold
// up to 100% at the limit. The gradual fade reduces system oscillations
// that could occur if you abruptly stop allowing all operations.
// Input: nBacklogCur - the current backlog (in arbitrary units)
// nBacklogThreshold - the threshold backlog at which to begin rejecting
// nBacklogLimit - hard limit at which to reject 100% of operations
// iItem - a monotonically increasing counter of items submitted. Used
// to determine which operations are allowed if there is a partial
// rejection rate.
//-----------------------------------------------------------------------------
bool BRejectDueToBacklog( int nBacklogCur, int nBacklogThreshold, int nBacklogLimit, int iItem ) { bool bRefuse = false;
if ( nBacklogCur >= nBacklogLimit ) { // if we're over the hard backlog limit, refuse all operations
bRefuse = true; } else if ( nBacklogCur >= nBacklogThreshold ) { // if we're near the hard backlog limit, start refusing an increasing % of operations,
// so we don't snap abruptly in and out of accepting operations and potentially cause oscillations
// ramp from refusing 0% of operations at the backlog threshold up to 100% at the backlog hard limit
// calculate refuse % to nearest 10%, to make it easy to mod the item # and get a good distribution
float nRefusePctDecile = 10 * (float) ( nBacklogCur - nBacklogThreshold ) / (float) ( nBacklogLimit - nBacklogThreshold ); Assert( nRefusePctDecile >= 0.0 ); Assert( nRefusePctDecile <= 10.0 );
// compare the operations submitted count mod 10 to the refusal percent decile to decide if we should
// accept or refuse this particular operation
if ( ( iItem % 10 ) < nRefusePctDecile ) bRefuse = true; }
return bRefuse; }
//-----------------------------------------------------------------------------
// Purpose: Defines the head of the CDumpMemFnReg linked list
//-----------------------------------------------------------------------------
CDumpMemFnReg *CDumpMemFnReg::sm_Head = NULL;
|