You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
187 lines
6.2 KiB
187 lines
6.2 KiB
//========= 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; |