1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
|
//========= 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;
|