heap.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. /*++
  2. Copyright (c) 2013 Minoca Corp.
  3. This file is licensed under the terms of the GNU General Public License
  4. version 3. Alternative licensing terms are available. Contact
  5. info@minocacorp.com for details. See the LICENSE file at the root of this
  6. project for complete licensing information.
  7. Module Name:
  8. heap.c
  9. Abstract:
  10. This module implements heap functionality for the C Library.
  11. Author:
  12. Evan Green 6-Mar-2013
  13. Environment:
  14. User Mode C Library
  15. --*/
  16. //
  17. // ------------------------------------------------------------------- Includes
  18. //
  19. #include "libcp.h"
  20. #include <errno.h>
  21. #include <stdlib.h>
  22. #include <string.h>
  23. //
  24. // ---------------------------------------------------------------- Definitions
  25. //
  26. #define MALLOC_ALLOCATION_TAG 0x6C6C614D // 'llaM'
  27. //
  28. // ------------------------------------------------------ Data Type Definitions
  29. //
  30. //
  31. // ----------------------------------------------- Internal Function Prototypes
  32. //
  33. //
  34. // -------------------------------------------------------------------- Globals
  35. //
  36. //
  37. // ------------------------------------------------------------------ Functions
  38. //
  39. LIBC_API
  40. void
  41. free (
  42. void *Memory
  43. )
  44. /*++
  45. Routine Description:
  46. This routine frees previously allocated memory.
  47. Arguments:
  48. Memory - Supplies a pointer to memory returned by the allocation function.
  49. Return Value:
  50. None.
  51. --*/
  52. {
  53. if (Memory == NULL) {
  54. return;
  55. }
  56. OsHeapFree(Memory);
  57. return;
  58. }
  59. LIBC_API
  60. void *
  61. malloc (
  62. size_t AllocationSize
  63. )
  64. /*++
  65. Routine Description:
  66. This routine allocates memory from the heap.
  67. Arguments:
  68. AllocationSize - Supplies the required allocation size in bytes.
  69. Return Value:
  70. Returns a pointer to the allocated memory on success.
  71. NULL on failure.
  72. --*/
  73. {
  74. if (AllocationSize == 0) {
  75. AllocationSize = 1;
  76. }
  77. return OsHeapAllocate(AllocationSize, MALLOC_ALLOCATION_TAG);
  78. }
  79. LIBC_API
  80. void *
  81. realloc (
  82. void *Allocation,
  83. size_t AllocationSize
  84. )
  85. /*++
  86. Routine Description:
  87. This routine resizes the given buffer. If the new allocation size is
  88. greater than the original allocation, the contents of the new bytes are
  89. unspecified (just like the contents of a malloced buffer).
  90. Arguments:
  91. Allocation - Supplies the optional original allocation. If this is not
  92. supplied, this routine is equivalent to malloc.
  93. AllocationSize - Supplies the new required allocation size in bytes.
  94. Return Value:
  95. Returns a pointer to the new buffer on success.
  96. NULL on failure or if the supplied size was zero. If the new buffer could
  97. not be allocated, errno will be set to ENOMEM.
  98. --*/
  99. {
  100. void *NewBuffer;
  101. if ((Allocation == NULL) && (AllocationSize == 0)) {
  102. AllocationSize = 1;
  103. }
  104. NewBuffer = OsHeapReallocate(Allocation,
  105. AllocationSize,
  106. MALLOC_ALLOCATION_TAG);
  107. if ((NewBuffer == NULL) && (AllocationSize != 0)) {
  108. errno = ENOMEM;
  109. }
  110. return NewBuffer;
  111. }
  112. LIBC_API
  113. void *
  114. calloc (
  115. size_t ElementCount,
  116. size_t ElementSize
  117. )
  118. /*++
  119. Routine Description:
  120. This routine allocates memory from the heap large enough to store the
  121. given number of elements of the given size (the product of the two
  122. parameters). The buffer returned will have all zeros written to it.
  123. Arguments:
  124. ElementCount - Supplies the number of elements to allocate.
  125. ElementSize - Supplies the size of each element in bytes.
  126. Return Value:
  127. Returns a pointer to the new zeroed buffer on success.
  128. NULL on failure or if the either the element count of the element size was
  129. zero. If the new buffer could not be allocated, errno will be set to ENOMEM.
  130. --*/
  131. {
  132. void *NewBuffer;
  133. size_t TotalSize;
  134. TotalSize = ElementCount * ElementSize;
  135. if ((ElementCount != 0) && ((TotalSize / ElementCount) != ElementSize)) {
  136. errno = ENOMEM;
  137. return NULL;
  138. }
  139. if (TotalSize == 0) {
  140. TotalSize = 1;
  141. }
  142. NewBuffer = OsHeapAllocate(TotalSize, MALLOC_ALLOCATION_TAG);
  143. if (NewBuffer == NULL) {
  144. errno = ENOMEM;
  145. return NULL;
  146. }
  147. memset(NewBuffer, 0, TotalSize);
  148. return NewBuffer;
  149. }
  150. LIBC_API
  151. int
  152. posix_memalign (
  153. void **AllocationPointer,
  154. size_t AllocationAlignment,
  155. size_t AllocationSize
  156. )
  157. /*++
  158. Routine Description:
  159. This routine allocates aligned memory from the heap. The given alignment
  160. must be a power of 2 and a multiple of the size of a pointer.
  161. Arguments:
  162. AllocationPointer - Supplies a pointer that receives a pointer to the
  163. allocated memory on success.
  164. AllocationAlignment - Supplies the required allocation alignment in bytes.
  165. AllocationSize - Supplies the required allocation size in bytes.
  166. Return Value:
  167. 0 on success.
  168. Returns an error number on failure.
  169. --*/
  170. {
  171. KSTATUS Status;
  172. if ((IS_ALIGNED(AllocationAlignment, sizeof(void *)) == FALSE) ||
  173. (POWER_OF_2(AllocationAlignment) == FALSE) ||
  174. (AllocationAlignment == 0)) {
  175. return EINVAL;
  176. }
  177. Status = OsHeapAlignedAllocate(AllocationPointer,
  178. AllocationAlignment,
  179. AllocationSize,
  180. MALLOC_ALLOCATION_TAG);
  181. return ClConvertKstatusToErrorNumber(Status);
  182. }
  183. //
  184. // --------------------------------------------------------- Internal Functions
  185. //