Team Fortress 2 Source Code as on 22/4/2020
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.

186 lines
6.2 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Miscellaneous code
  4. //
  5. //=============================================================================
  6. #include "stdafx.h"
  7. // memdbgon must be the last include file in a .cpp file!!!
  8. #include "tier0/memdbgon.h"
  9. //-----------------------------------------------------------------------------
  10. // Purpose: Tells us whether an account name looks like a VTT account name
  11. // (used as an exception for IP-based rate limiting)
  12. //-----------------------------------------------------------------------------
  13. bool IsVTTAccountName( const char *szAccountName )
  14. {
  15. const static char *k_szCafe = "valvecafepc";
  16. if ( 0 == Q_strncmp( szAccountName, k_szCafe, Q_strlen( k_szCafe ) ) )
  17. return true;
  18. return false;
  19. }
  20. //-----------------------------------------------------------------------------
  21. // Random number generation
  22. // Use this system for all random number generation. It's very fast, and is
  23. // integrated with our automated tests so that we can perform reproducibly "random"
  24. // test cases.
  25. //-----------------------------------------------------------------------------
  26. uint32 g_unRandCur = 0;
  27. int g_iunRandMask = 0;
  28. // k_rgunMask
  29. // Set of masks used by our quick and dirty random number generator.
  30. const uint32 k_rgunMask[17] =
  31. {
  32. 0x1739a3b0,
  33. 0xb8907fe1,
  34. 0x8290d3b7,
  35. 0x72839cd0,
  36. 0x242df096,
  37. 0x3829750b,
  38. 0x38de7a77,
  39. 0x72f0924c,
  40. 0x44783927,
  41. 0x01925372,
  42. 0x20902714,
  43. 0x27585920,
  44. 0x27890632,
  45. 0x82910476,
  46. 0x72906721,
  47. 0x28798904,
  48. 0x78592700,
  49. };
  50. //-----------------------------------------------------------------------------
  51. // Purpose: Quickly generates a vaguely random number.
  52. // Output: A vaguely random number.
  53. //-----------------------------------------------------------------------------
  54. uint32 UNRandFast()
  55. {
  56. g_iunRandMask++;
  57. g_unRandCur += 637429601; // Just add a large prime number (we'll wrap frequently)
  58. return ( g_unRandCur ^ k_rgunMask[ g_iunRandMask % 17 ] );
  59. }
  60. //-----------------------------------------------------------------------------
  61. // Purpose: Quickly generates a vaguely random character.
  62. // Output: A vaguely random char in the range [32,126].
  63. //-----------------------------------------------------------------------------
  64. char CHRandFast()
  65. {
  66. return ( UNRandFast() % 95 ) + 32;
  67. }
  68. //-----------------------------------------------------------------------------
  69. // Purpose: Sets the random number seed (note that we actually break this down
  70. // into two parts: g_unRandCur and g_iunRandMask).
  71. // Input: ulRandSeed: Value to use as our seed
  72. //-----------------------------------------------------------------------------
  73. void SetRandSeed( uint64 ulRandSeed )
  74. {
  75. g_unRandCur = ulRandSeed >> 32;
  76. g_iunRandMask = ulRandSeed & 0xffffffff;
  77. }
  78. //-----------------------------------------------------------------------------
  79. // Purpose: Returns the current random number seed (actually a composite of
  80. // g_unRandCur and g_iunRandMask)
  81. // Output: Our current 64 bit random number seed.
  82. //-----------------------------------------------------------------------------
  83. uint64 GetRandSeed()
  84. {
  85. return ( ( ((uint64)g_unRandCur) << 32 ) + g_iunRandMask );
  86. }
  87. //-----------------------------------------------------------------------------
  88. // Purpose: Quickly fill a memory block with random bytes
  89. //-----------------------------------------------------------------------------
  90. void RandMem(void *dest, int count)
  91. {
  92. unsigned char *pDest = (unsigned char *)dest;
  93. while ( count >= 4 )
  94. {
  95. *(uint32*)(pDest) = UNRandFast();
  96. pDest+=4;
  97. count-=4;
  98. }
  99. while ( count > 0 )
  100. {
  101. *pDest = UNRandFast();
  102. pDest++;
  103. count--;
  104. }
  105. }
  106. //-----------------------------------------------------------------------------
  107. // Purpose: Calculates the percentage of numerator/demoninator, or 0 if
  108. // denominator is 0.
  109. //-----------------------------------------------------------------------------
  110. float SafeCalcPct( uint64 ulNumerator, uint64 ulDenominator )
  111. {
  112. if ( 0 == ulDenominator )
  113. return 0;
  114. return ( 100.0f * (float) ulNumerator / (float) ulDenominator );
  115. }
  116. //-----------------------------------------------------------------------------
  117. // Purpose: Common code to reject an operation due to a time backlog.
  118. // Does a gradual fade of 0% rejections at the specified threshold
  119. // up to 100% at the limit. The gradual fade reduces system oscillations
  120. // that could occur if you abruptly stop allowing all operations.
  121. // Input: nBacklogCur - the current backlog (in arbitrary units)
  122. // nBacklogThreshold - the threshold backlog at which to begin rejecting
  123. // nBacklogLimit - hard limit at which to reject 100% of operations
  124. // iItem - a monotonically increasing counter of items submitted. Used
  125. // to determine which operations are allowed if there is a partial
  126. // rejection rate.
  127. //-----------------------------------------------------------------------------
  128. bool BRejectDueToBacklog( int nBacklogCur, int nBacklogThreshold, int nBacklogLimit, int iItem )
  129. {
  130. bool bRefuse = false;
  131. if ( nBacklogCur >= nBacklogLimit )
  132. {
  133. // if we're over the hard backlog limit, refuse all operations
  134. bRefuse = true;
  135. }
  136. else if ( nBacklogCur >= nBacklogThreshold )
  137. {
  138. // if we're near the hard backlog limit, start refusing an increasing % of operations,
  139. // so we don't snap abruptly in and out of accepting operations and potentially cause oscillations
  140. // ramp from refusing 0% of operations at the backlog threshold up to 100% at the backlog hard limit
  141. // calculate refuse % to nearest 10%, to make it easy to mod the item # and get a good distribution
  142. float nRefusePctDecile = 10 * (float) ( nBacklogCur - nBacklogThreshold ) /
  143. (float) ( nBacklogLimit - nBacklogThreshold );
  144. Assert( nRefusePctDecile >= 0.0 );
  145. Assert( nRefusePctDecile <= 10.0 );
  146. // compare the operations submitted count mod 10 to the refusal percent decile to decide if we should
  147. // accept or refuse this particular operation
  148. if ( ( iItem % 10 ) < nRefusePctDecile )
  149. bRefuse = true;
  150. }
  151. return bRefuse;
  152. }
  153. //-----------------------------------------------------------------------------
  154. // Purpose: Defines the head of the CDumpMemFnReg linked list
  155. //-----------------------------------------------------------------------------
  156. CDumpMemFnReg *CDumpMemFnReg::sm_Head = NULL;