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.

153 lines
4.4 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows/NT **/
  3. /** Copyright(c) Microsoft Corporation, 1997 - 2002 **/
  4. /**********************************************************************/
  5. #include "stdafx.h"
  6. #include "util.h"
  7. PVOID __fastcall MyVirtualAlloc(ULONG Size)
  8. {
  9. return VirtualAlloc( NULL, Size, MEM_COMMIT, PAGE_READWRITE );
  10. }
  11. VOID __fastcall MyVirtualFree(PVOID Allocation)
  12. {
  13. VirtualFree( Allocation, 0, MEM_RELEASE );
  14. }
  15. HANDLE CreateSubAllocator(IN ULONG InitialCommitSize, IN ULONG GrowthCommitSize)
  16. {
  17. PSUBALLOCATOR SubAllocator;
  18. ULONG InitialSize;
  19. ULONG GrowthSize;
  20. InitialSize = ROUNDUP2( InitialCommitSize, MINIMUM_VM_ALLOCATION );
  21. GrowthSize = ROUNDUP2( GrowthCommitSize, MINIMUM_VM_ALLOCATION );
  22. SubAllocator = (PSUBALLOCATOR)MyVirtualAlloc( InitialSize );
  23. //
  24. // If can't allocate entire initial size, back off to minimum size.
  25. // Very large initial requests sometimes cannot be allocated simply
  26. // because there is not enough contiguous address space.
  27. //
  28. if ( SubAllocator == NULL )
  29. {
  30. SubAllocator = (PSUBALLOCATOR)MyVirtualAlloc( GrowthSize );
  31. }
  32. if ( SubAllocator == NULL )
  33. {
  34. SubAllocator = (PSUBALLOCATOR)MyVirtualAlloc( MINIMUM_VM_ALLOCATION );
  35. }
  36. if ( SubAllocator != NULL )
  37. {
  38. SubAllocator->NextAvailable = (PCHAR)SubAllocator + ROUNDUP2( sizeof( SUBALLOCATOR ), SUBALLOCATOR_ALIGNMENT );
  39. SubAllocator->LastAvailable = (PCHAR)SubAllocator + InitialSize;
  40. SubAllocator->VirtualList = (PVOID*)SubAllocator;
  41. SubAllocator->GrowSize = GrowthSize;
  42. }
  43. return (HANDLE) SubAllocator;
  44. }
  45. PVOID __fastcall SubAllocate(IN HANDLE hAllocator, IN ULONG Size)
  46. {
  47. PSUBALLOCATOR SubAllocator = (PSUBALLOCATOR) hAllocator;
  48. PCHAR NewVirtual;
  49. PCHAR Allocation;
  50. ULONG AllocSize;
  51. ULONG_PTR Available;
  52. ULONG GrowSize;
  53. ASSERT( Size < (ULONG)( ~(( SUBALLOCATOR_ALIGNMENT * 2 ) - 1 )));
  54. AllocSize = ROUNDUP2( Size, SUBALLOCATOR_ALIGNMENT );
  55. Available = SubAllocator->LastAvailable - SubAllocator->NextAvailable;
  56. if ( AllocSize <= Available )
  57. {
  58. Allocation = SubAllocator->NextAvailable;
  59. SubAllocator->NextAvailable = Allocation + AllocSize;
  60. return Allocation;
  61. }
  62. //
  63. // Insufficient VM, so grow it. Make sure we grow it enough to satisfy
  64. // the allocation request in case the request is larger than the grow
  65. // size specified in CreateSubAllocator.
  66. //
  67. GrowSize = SubAllocator->GrowSize;
  68. if ( GrowSize < ( AllocSize + SUBALLOCATOR_ALIGNMENT ))
  69. {
  70. GrowSize = ROUNDUP2(( AllocSize + SUBALLOCATOR_ALIGNMENT ), MINIMUM_VM_ALLOCATION );
  71. }
  72. NewVirtual = (PCHAR)MyVirtualAlloc( GrowSize );
  73. // If failed to alloc GrowSize VM, and the allocation could be satisfied
  74. // with a minimum VM allocation, try allocating minimum VM to satisfy
  75. // this request.
  76. //
  77. if (( NewVirtual == NULL ) && ( AllocSize <= ( MINIMUM_VM_ALLOCATION - SUBALLOCATOR_ALIGNMENT )))
  78. {
  79. GrowSize = MINIMUM_VM_ALLOCATION;
  80. NewVirtual = (PCHAR)MyVirtualAlloc( GrowSize );
  81. }
  82. if ( NewVirtual != NULL )
  83. {
  84. // Set LastAvailable to end of new VM block.
  85. SubAllocator->LastAvailable = NewVirtual + GrowSize;
  86. // Link new VM into list of VM allocations.
  87. *(PVOID*)NewVirtual = SubAllocator->VirtualList;
  88. SubAllocator->VirtualList = (PVOID*)NewVirtual;
  89. // Requested allocation comes next.
  90. Allocation = NewVirtual + SUBALLOCATOR_ALIGNMENT;
  91. // Then set the NextAvailable for what's remaining.
  92. SubAllocator->NextAvailable = Allocation + AllocSize;
  93. // And return the allocation.
  94. return Allocation;
  95. }
  96. // Could not allocate enough VM to satisfy request.
  97. return NULL;
  98. }
  99. VOID DestroySubAllocator(IN HANDLE hAllocator)
  100. {
  101. PSUBALLOCATOR SubAllocator = (PSUBALLOCATOR) hAllocator;
  102. PVOID VirtualBlock = SubAllocator->VirtualList;
  103. PVOID NextVirtualBlock;
  104. do
  105. {
  106. NextVirtualBlock = *(PVOID*)VirtualBlock;
  107. MyVirtualFree( VirtualBlock );
  108. VirtualBlock = NextVirtualBlock;
  109. }while (VirtualBlock != NULL);
  110. }