source-engine/gcsdk/steamextra/misc.cpp

187 lines
6.2 KiB
C++
Raw Permalink Normal View History

2020-04-22 16:56:21 +00:00
//========= 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;