Source code of Windows XP (NT5)
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.

169 lines
3.3 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. Random.c
  5. Abstract:
  6. This module implements a simple random number generator
  7. Author:
  8. Gary Kimura [GaryKi] 26-May-1989
  9. Environment:
  10. Pure utility routine
  11. Revision History:
  12. Vishnu Patankar [VishnuP] 12-Nov-2000
  13. Added new random number generator RtlRandomEx()
  14. --*/
  15. #include <ntrtlp.h>
  16. #if defined(ALLOC_PRAGMA) && defined(NTOS_KERNEL_RUNTIME)
  17. #pragma alloc_text(PAGE, RtlRandom)
  18. #endif
  19. #define Multiplier ((ULONG)(0x80000000ul - 19)) // 2**31 - 19
  20. #define Increment ((ULONG)(0x80000000ul - 61)) // 2**31 - 61
  21. #define Modulus ((ULONG)(0x80000000ul - 1)) // 2**31 - 1
  22. #if !defined(NTOS_KERNEL_RUNTIME)
  23. ULONG
  24. RtlUniform (
  25. IN OUT PULONG Seed
  26. )
  27. /*++
  28. Routine Description:
  29. A simple uniform random number generator, based on D.H. Lehmer's 1948
  30. alrogithm.
  31. Arguments:
  32. Seed - Supplies a pointer to the random number generator seed.
  33. Return Value:
  34. ULONG - returns a random number uniformly distributed over [0..MAXLONG]
  35. --*/
  36. {
  37. *Seed = ((Multiplier * (*Seed)) + Increment) % Modulus;
  38. return *Seed;
  39. }
  40. #endif
  41. #define UniformMacro(Seed) ( \
  42. *Seed = (((Multiplier * (*Seed)) + Increment) % Modulus) \
  43. )
  44. extern ULONG RtlpRandomConstantVector[];
  45. ULONG
  46. RtlRandom (
  47. IN OUT PULONG Seed
  48. )
  49. /*++
  50. Routine Description:
  51. An every better random number generator based on MacLaren and Marsaglia.
  52. Arguments:
  53. Seed - Supplies a pointer to the random number generator seed.
  54. Return Value:
  55. ULONG - returns a random number uniformly distributed over [0..MAXLONG]
  56. --*/
  57. {
  58. ULONG X;
  59. ULONG Y;
  60. ULONG j;
  61. ULONG Result;
  62. RTL_PAGED_CODE();
  63. X = UniformMacro(Seed);
  64. Y = UniformMacro(Seed);
  65. j = Y % 128;
  66. Result = RtlpRandomConstantVector[j];
  67. RtlpRandomConstantVector[j] = X;
  68. return Result;
  69. }
  70. extern ULONG RtlpRandomExAuxVarY;
  71. extern ULONG RtlpRandomExConstantVector[];
  72. ULONG
  73. RtlRandomEx(
  74. IN OUT PULONG Seed
  75. )
  76. /*++
  77. Routine Description:
  78. This algorithm is preferred over RtlRandom() for two reasons:
  79. (a) it is faster than RtlRandom() since it saves one multiplication, one addition and
  80. one modulus operation. This almost doubles the performance since it halves the number of
  81. clocks even on a pipelined Integer Unit such as the P6/ia64 processors i.e. ~ 52% perf gain.
  82. Plain RtlRandom() suffers from a RAW data dependency that integer pipelines cannot exploit.
  83. (b) it produces better random numbers than RtlRandom() since the period of the random
  84. numbers generated is comparatively higher.
  85. The algorithm here is based on a paper by Carter Bays and S.D.Durham [ACM Trans. Math.
  86. Software 2, pp. 59-64].
  87. Knuth's The Art of Computer Programming (Seminumerical Algorithms) outlines the algorithm
  88. with proofs to support claims (a) and (b) above.
  89. Arguments:
  90. Seed - Supplies a pointer to the random number generator seed.
  91. Return Value:
  92. ULONG - returns a random number uniformly distributed over [0..MAXLONG]
  93. --*/
  94. {
  95. ULONG j;
  96. ULONG Result;
  97. RTL_PAGED_CODE();
  98. j = RtlpRandomExAuxVarY % 128;
  99. RtlpRandomExAuxVarY = RtlpRandomExConstantVector[j];
  100. Result = RtlpRandomExAuxVarY;
  101. RtlpRandomExConstantVector[j] = UniformMacro(Seed);
  102. return Result;
  103. }
  104.