Leaked source code of windows server 2003
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.

109 lines
3.2 KiB

  1. /**************************************************************************\
  2. *
  3. * Copyright (c) 1998 Microsoft Corporation
  4. *
  5. * Module Name:
  6. *
  7. * Dynamic array implementation of StackBuffer class
  8. *
  9. * Abstract:
  10. *
  11. * This class provides a simple allocation scheme for a fixed size buffer.
  12. *
  13. * First case. Reserve of 128 bytes on the stack.
  14. * Second case. Lookaside buffer, size equal to first usage of it.
  15. * Third case. Allocate size on heap.
  16. *
  17. * This is much less flexible than the DynamicArray class, the break up of
  18. * cost is basically as follows:
  19. *
  20. * First case. 1 assignment + 2 compare (no allocation)
  21. * Second case. 1 assignment + 5 compare + 2 InterlockExchange's (pot. alloc)
  22. * Third case. 1 assignment + 4 compare + GpMalloc + GpFree
  23. *
  24. * The cost is cheap for case one. For case two, Lock + Unlock is small
  25. * and fast whereas case three is O(size of heap) in time. There is also
  26. * the benefit of less fragmentation from fewer allocations.
  27. *
  28. * If you are considering using this code elsewhere, please contact Andrew
  29. * Godfrey or Eric VandenBerg. It is important this class be used properly
  30. * to ensure the performance benefit isn't adversely effected.
  31. *
  32. * The initialization and clean up of lookaside buffer is done in
  33. * InitializeGdiplus() and UninitializeGdiplus().
  34. *
  35. * We provide the source here so it can be inlined easily.
  36. *
  37. \**************************************************************************/
  38. #define INIT_SIZE 128 // 16 pairs of GpPoint types
  39. class StackBuffer
  40. {
  41. private:
  42. BYTE buffer[INIT_SIZE];
  43. BYTE* allocBuffer;
  44. public:
  45. StackBuffer()
  46. {
  47. }
  48. BYTE* GetBuffer(INT size)
  49. {
  50. if (size < 0)
  51. {
  52. return (allocBuffer = NULL);
  53. }
  54. else if (size<INIT_SIZE)
  55. {
  56. allocBuffer = NULL;
  57. return &buffer[0];
  58. }
  59. else if (size>Globals::LookAsideBufferSize)
  60. {
  61. return (allocBuffer = (BYTE*)GpMalloc(size));
  62. }
  63. else
  64. {
  65. if ((CompareExchangeLong_Ptr(&Globals::LookAsideCount, 1, 0) == 0)
  66. && Globals::LookAsideCount == 1)
  67. {
  68. if (Globals::LookAsideBuffer == NULL)
  69. {
  70. Globals::LookAsideBufferSize = size + 128;
  71. Globals::LookAsideBuffer = (BYTE*)GpMalloc(Globals::LookAsideBufferSize);
  72. }
  73. return (allocBuffer = Globals::LookAsideBuffer);
  74. // we have exclusive access to lookaside
  75. }
  76. else
  77. {
  78. return (allocBuffer = (BYTE*)GpMalloc(size));
  79. }
  80. }
  81. }
  82. ~StackBuffer()
  83. {
  84. if (allocBuffer != NULL)
  85. {
  86. if (allocBuffer == Globals::LookAsideBuffer)
  87. {
  88. ASSERT(Globals::LookAsideCount == 1); // should be true
  89. CompareExchangeLong_Ptr(&Globals::LookAsideCount, 0, 1);
  90. }
  91. else
  92. {
  93. GpFree(allocBuffer);
  94. }
  95. }
  96. }
  97. };