mirror of
https://github.com/nillerusr/source-engine.git
synced 2024-12-22 22:27:05 +00:00
187 lines
6.2 KiB
C++
187 lines
6.2 KiB
C++
//========= 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; |