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.

256 lines
7.7 KiB

  1. /***
  2. *calloc.c - allocate storage for an array from the heap
  3. *
  4. * Copyright (c) 1989-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * Defines the calloc() function.
  8. *
  9. *Revision History:
  10. * 07-25-89 GJF Module created
  11. * 11-13-89 GJF Added MTHREAD support. Also fixed copyright and got
  12. * rid of DEBUG286 stuff.
  13. * 12-04-89 GJF Renamed header file (now heap.h). Added register
  14. * declarations
  15. * 12-18-89 GJF Added explicit _cdecl to function definition
  16. * 03-09-90 GJF Replaced _cdecl with _CALLTYPE1, added #include
  17. * <cruntime.h> and removed #include <register.h>.
  18. * 09-27-90 GJF New-style function declarator.
  19. * 05-28-91 GJF Tuned a bit.
  20. * 04-06-93 SKS Replace _CRTAPI* with __cdecl
  21. * 11-03-94 CFW Debug heap support.
  22. * 12-01-94 CFW Use malloc with new handler, remove locks.
  23. * 02-01-95 GJF #ifdef out the *_base names for the Mac builds
  24. * (temporary).
  25. * 02-09-95 GJF Restored *_base names.
  26. * 04-28-95 GJF Spliced on winheap version.
  27. * 05-24-95 CFW Official ANSI C++ new handler added.
  28. * 03-04-96 GJF Added support for small-block heap.
  29. * 05-22-97 RDK New small-block heap scheme implemented.
  30. * 09-26-97 BWT Fix POSIX
  31. * 11-05-97 GJF Small POSIX fixes from Roger Lanser.
  32. * 12-17-97 GJF Exception-safe locking.
  33. * 05-22-98 JWM Support for KFrei's RTC work.
  34. * 07-28-98 JWM RTC update.
  35. * 09-30-98 GJF Bypass all small-block heap code when __sbh_initialized
  36. * is 0.
  37. * 11-16-98 GJF Merged in VC++ 5.0 version of small-block heap.
  38. * 12-18-98 GJF Changes for 64-bit size_t.
  39. * 05-01-99 PML Disable small-block heap for Win64.
  40. * 05-26-99 KBF Updated RTC_Allocate_hook params
  41. * 06-17-99 GJF Removed old small-block heap from static libs.
  42. * 08-04-00 PML Don't round allocation sizes when using system
  43. * heap (VS7#131005).
  44. *
  45. *******************************************************************************/
  46. #ifdef WINHEAP
  47. #include <malloc.h>
  48. #include <string.h>
  49. #include <winheap.h>
  50. #include <windows.h>
  51. #include <internal.h>
  52. #include <mtdll.h>
  53. #include <dbgint.h>
  54. #include <rtcsup.h>
  55. /***
  56. *void *calloc(size_t num, size_t size) - allocate storage for an array from
  57. * the heap
  58. *
  59. *Purpose:
  60. * Allocate a block of memory from heap big enough for an array of num
  61. * elements of size bytes each, initialize all bytes in the block to 0
  62. * and return a pointer to it.
  63. *
  64. *Entry:
  65. * size_t num - number of elements in the array
  66. * size_t size - size of each element
  67. *
  68. *Exit:
  69. * Success: void pointer to allocated block
  70. * Failure: NULL
  71. *
  72. *Uses:
  73. *
  74. *Exceptions:
  75. *
  76. *******************************************************************************/
  77. void * __cdecl _calloc_base (size_t num, size_t size)
  78. {
  79. size_t size_orig;
  80. void * pvReturn;
  81. size_orig = size = size * num;
  82. #ifdef HEAPHOOK
  83. /* call heap hook if installed */
  84. if (_heaphook)
  85. {
  86. if ((*_heaphook)(_HEAP_CALLOC, size, NULL, (void *)&pvReturn))
  87. return pvReturn;
  88. }
  89. #endif /* HEAPHOOK */
  90. /* force nonzero size */
  91. if (size == 0)
  92. size = 1;
  93. #ifdef _POSIX_
  94. {
  95. void * retp = NULL;
  96. if ( size <= _HEAP_MAXREQ ) {
  97. retp = HeapAlloc( _crtheap,
  98. HEAP_ZERO_MEMORY,
  99. size );
  100. }
  101. return retp;
  102. }
  103. #else
  104. for (;;)
  105. {
  106. pvReturn = NULL;
  107. if (size <= _HEAP_MAXREQ)
  108. {
  109. #ifndef _WIN64
  110. if ( __active_heap == __V6_HEAP )
  111. {
  112. /* round up to nearest paragraph */
  113. if (size <= _HEAP_MAXREQ)
  114. size = (size + BYTES_PER_PARA - 1) & ~(BYTES_PER_PARA - 1);
  115. if ( size_orig <= __sbh_threshold )
  116. {
  117. // Allocate the block from the small-block heap and
  118. // initialize it with zeros.
  119. #ifdef _MT
  120. _mlock( _HEAP_LOCK );
  121. __try {
  122. #endif
  123. pvReturn = __sbh_alloc_block((int)size_orig);
  124. #ifdef _MT
  125. }
  126. __finally {
  127. _munlock( _HEAP_LOCK );
  128. }
  129. #endif
  130. if (pvReturn != NULL)
  131. memset(pvReturn, 0, size_orig);
  132. }
  133. }
  134. #ifdef CRTDLL
  135. else if ( __active_heap == __V5_HEAP )
  136. {
  137. /* round up to nearest paragraph */
  138. if (size <= _HEAP_MAXREQ)
  139. size = (size + BYTES_PER_PARA - 1) & ~(BYTES_PER_PARA - 1);
  140. if ( size <= __old_sbh_threshold )
  141. {
  142. // Allocate the block from the small-block heap and
  143. // initialize it with zeros.
  144. #ifdef _MT
  145. _mlock(_HEAP_LOCK);
  146. __try {
  147. #endif
  148. pvReturn = __old_sbh_alloc_block(size >> _OLD_PARASHIFT);
  149. #ifdef _MT
  150. }
  151. __finally {
  152. _munlock(_HEAP_LOCK);
  153. }
  154. #endif
  155. if ( pvReturn != NULL )
  156. memset(pvReturn, 0, size);
  157. }
  158. }
  159. #endif /* CRTDLL */
  160. #endif /* ndef _WIN64 */
  161. if (pvReturn == NULL)
  162. pvReturn = HeapAlloc(_crtheap, HEAP_ZERO_MEMORY, size);
  163. }
  164. if (pvReturn || _newmode == 0)
  165. {
  166. RTCCALLBACK(_RTC_Allocate_hook, (pvReturn, size_orig, 0));
  167. return pvReturn;
  168. }
  169. /* call installed new handler */
  170. if (!_callnewh(size))
  171. return NULL;
  172. /* new handler was successful -- try to allocate again */
  173. }
  174. #endif /* _POSIX_ */
  175. }
  176. #else /* ndef WINHEAP */
  177. #include <cruntime.h>
  178. #include <heap.h>
  179. #include <malloc.h>
  180. #include <mtdll.h>
  181. #include <stddef.h>
  182. #include <dbgint.h>
  183. /***
  184. *void *calloc(size_t num, size_t size) - allocate storage for an array from
  185. * the heap
  186. *
  187. *Purpose:
  188. * Allocate a block of memory from heap big enough for an array of num
  189. * elements of size bytes each, initialize all bytes in the block to 0
  190. * and return a pointer to it.
  191. *
  192. *Entry:
  193. * size_t num - number of elements in the array
  194. * size_t size - size of each element
  195. *
  196. *Exit:
  197. * Success: void pointer to allocated block block
  198. * Failure: NULL
  199. *
  200. *Uses:
  201. *
  202. *Exceptions:
  203. *
  204. *******************************************************************************/
  205. void * __cdecl _calloc_base (
  206. size_t num,
  207. size_t size
  208. )
  209. {
  210. void *retp;
  211. REG1 size_t *startptr;
  212. REG2 size_t *lastptr;
  213. /* try to malloc the requested space
  214. */
  215. retp = _malloc_base(size *= num);
  216. /* if malloc() succeeded, initialize the allocated space to zeros.
  217. * note the assumptions that the size of the allocation block is an
  218. * integral number of sizeof(size_t) bytes and that (size_t)0 is
  219. * sizeof(size_t) bytes of 0.
  220. */
  221. if ( retp != NULL ) {
  222. startptr = (size_t *)retp;
  223. lastptr = startptr + ((size + sizeof(size_t) - 1) /
  224. sizeof(size_t));
  225. while ( startptr < lastptr )
  226. *(startptr++) = 0;
  227. }
  228. return retp;
  229. }
  230. #endif /* WINHEAP */