home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / vc98 / crt / src / heap.h < prev    next >
C/C++ Source or Header  |  1998-06-17  |  10KB  |  369 lines

  1. /***
  2. *heap.h - Heap code include file
  3. *
  4. *       Copyright (c) 1988-1997, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. *       Contains information needed by the C library heap code.
  8. *
  9. *       [Internal]
  10. *
  11. ****/
  12.  
  13. #if _MSC_VER > 1000
  14. #pragma once
  15. #endif  /* _MSC_VER > 1000 */
  16.  
  17. #ifndef _INC_HEAP
  18. #define _INC_HEAP
  19.  
  20. #ifndef _CRTBLD
  21. /*
  22.  * This is an internal C runtime header file. It is used when building
  23.  * the C runtimes only. It is not to be used as a public header file.
  24.  */
  25. #error ERROR: Use of C runtime library internal header file.
  26. #endif  /* _CRTBLD */
  27.  
  28. #ifdef __cplusplus
  29. extern "C" {
  30. #endif  /* __cplusplus */
  31.  
  32. #include <cruntime.h>
  33.  
  34.  
  35. /* Define __cdecl for non-Microsoft compilers */
  36.  
  37. #if (!defined (_MSC_VER) && !defined (__cdecl))
  38. #define __cdecl
  39. #endif  /* (!defined (_MSC_VER) && !defined (__cdecl)) */
  40.  
  41. /*
  42.  * Heap block descriptor
  43.  */
  44.  
  45. struct _block_descriptor {
  46.         struct _block_descriptor *pnextdesc;    /* ptr to next descriptor */
  47.         void *pblock;               /* ptr to memory block */
  48. };
  49.  
  50. #define _BLKDESC    struct _block_descriptor
  51. #define _PBLKDESC   struct _block_descriptor *
  52.  
  53.  
  54. /*
  55.  * Useful constants
  56.  */
  57.  
  58. /*
  59.  * Unit of allocation. All allocations are of size n * _GRANULARITY. Note
  60.  * that _GRANULARITY must be a power of 2, or it cannot be used with the
  61.  * _ROUND2 macro.
  62.  */
  63. #if defined (_M_MRX000) || defined (_M_ALPHA) || defined (_M_PPC) || defined (_M_MPPC)
  64. #define _GRANULARITY    8
  65. #else  /* defined (_M_MRX000) || defined (_M_ALPHA) || defined (_M_PPC) || defined (_M_MPPC) */
  66. #define _GRANULARITY    4
  67. #endif  /* defined (_M_MRX000) || defined (_M_ALPHA) || defined (_M_PPC) || defined (_M_MPPC) */
  68.  
  69. /*
  70.  * Size of the header in a memory block. Note that we must have
  71.  * sizeof(void *) <= _HDRSIZE so the header is big enough to hold a pointer
  72.  * to the descriptor.
  73.  */
  74.  
  75. #define _HDRSIZE    1 * _GRANULARITY
  76.  
  77. /* _heapchk/_heapset parameter */
  78. #define _HEAP_NOFILL    0x7FFFFFF
  79.  
  80.  
  81. /*
  82.  * Descriptor status values
  83.  */
  84.  
  85. #define _INUSE      0
  86. #define _FREE       1
  87. #define _DUMMY      2
  88.  
  89.  
  90. #if _INUSE != 0
  91. #error *** Heap code assumes _INUSE value is 0! ***
  92. #endif  /* _INUSE != 0 */
  93.  
  94.  
  95. /*
  96.  * Macros for manipulating heap memory block descriptors
  97.  *      stat = one of the status values
  98.  *      addr = user-visible address of a heap block
  99.  */
  100.  
  101. #define _STATUS_MASK    0x3 /* last 2 bits are status */
  102.  
  103. #define _ADDRESS(pdesc)     ( (void *) ((unsigned)((pdesc)->pblock) & \
  104.                     (~_STATUS_MASK)) )
  105. #define _STATUS(pdesc)      ( (unsigned) ((unsigned)((pdesc)->pblock) & \
  106.                     _STATUS_MASK) )
  107.  
  108. #define _SET_INUSE(pdesc)   ( pdesc->pblock = (void *) \
  109.                        ((unsigned)_ADDRESS(pdesc) | _INUSE) )
  110. #define _SET_FREE(pdesc)    ( pdesc->pblock = (void *) \
  111.                        ((unsigned)_ADDRESS(pdesc) | _FREE) )
  112. #define _SET_DUMMY(pdesc)   ( pdesc->pblock = (void *) \
  113.                        ((unsigned)_ADDRESS(pdesc) | _DUMMY) )
  114.  
  115. #define _IS_INUSE(pdesc)    ( _STATUS(pdesc) == _INUSE )
  116. #define _IS_FREE(pdesc)     ( _STATUS(pdesc) == _FREE )
  117. #define _IS_DUMMY(pdesc)    ( _STATUS(pdesc) == _DUMMY )
  118.  
  119. #define _BLKSIZE(pdesc)     ( (unsigned) ( \
  120.                       (char *)_ADDRESS(pdesc->pnextdesc) - \
  121.                       (char *)_ADDRESS(pdesc) - _HDRSIZE ) )
  122.  
  123. #define _MEMSIZE(pdesc)     ( (char *)_ADDRESS(pdesc->pnextdesc) - \
  124.                       (char *)_ADDRESS(pdesc) )
  125.  
  126. #define _BACKPTR(addr)      ( *(_PBLKDESC*)((char *)(addr) - _HDRSIZE) )
  127.  
  128. #define _CHECK_PDESC(pdesc) ( (*(_PBLKDESC*) (_ADDRESS(pdesc))) == pdesc )
  129.  
  130. #define _CHECK_BACKPTR(addr)    ( ((char *)(_BACKPTR(addr)->pblock) + _HDRSIZE) \
  131.                     == addr)
  132.  
  133.  
  134. /*
  135.  * Heap descriptor
  136.  */
  137.  
  138. struct _heap_desc_ {
  139.  
  140.         _PBLKDESC pfirstdesc;   /* pointer to first descriptor */
  141.         _PBLKDESC proverdesc;   /* rover pointer */
  142.         _PBLKDESC emptylist;    /* pointer to empty list */
  143.  
  144.         _BLKDESC  sentinel; /* Sentinel block for end of heap list */
  145.  
  146. };
  147.  
  148. extern struct _heap_desc_ _heap_desc;
  149.  
  150. /*
  151.  * Region descriptor and heap grow data
  152.  */
  153.  
  154. struct _heap_region_ {
  155.         void * _regbase;    /* base address of region */
  156.         unsigned _currsize; /* current size of region */
  157.         unsigned _totalsize;    /* total size of region */
  158. #ifdef _MAC
  159.         void * _regbaseCopy;    /* save original Ptr and make _regbase at 4 bytes bound */
  160. #endif  /* _MAC */
  161.         };
  162.  
  163. #define _heap_growsize _amblksiz
  164.  
  165. extern unsigned int _heap_resetsize;
  166. extern unsigned int _heap_regionsize;
  167. extern unsigned int _heap_maxregsize;
  168. extern struct _heap_region_ _heap_regions[];
  169. extern void ** _heap_descpages;
  170.  
  171. #ifdef _M_ALPHA
  172. #define _PAGESIZE_      0x2000      /* one page */
  173. #else  /* _M_ALPHA */
  174. #define _PAGESIZE_      0x1000      /* one page */
  175. #endif  /* _M_ALPHA */
  176.  
  177. #define _SEGSIZE_       0x10000     /* one segment (i.e., 64 Kb) */
  178.  
  179. #ifdef _WIN32
  180. #define _HEAP_REGIONMAX     0x40        /* Max number of regions: 64 */
  181.                                         /* For small memory systems: */
  182. #define _HEAP_REGIONSIZE_S  0x4000      /* Initial region size (16K) */
  183. #define _HEAP_MAXREGSIZE_S  0x1000000   /* Maximum region size (16M) */
  184.                                         /* For large memory systems: */
  185. #define _HEAP_REGIONSIZE_L  0x100000    /* Initial region size  (1M) */
  186. #define _HEAP_MAXREGSIZE_L  0x1000000   /* Maximum region size (16M) */
  187.  
  188. #define _HEAP_GROWSIZE      0x10000     /* Default grow increment (64K) */
  189. #else  /* _WIN32 */
  190. #define _HEAP_REGIONMAX     0x20        /* Max number of regions */
  191. #define _HEAP_REGIONSIZE    0x8000  /* Default region size (1/4 meg) */
  192. #define _HEAP_GROWSIZE      0x8000      /* Default grow increment (32K) */
  193. #endif  /* _WIN32 */
  194.  
  195. #define _HEAP_GROWMIN       _PAGESIZE_  /* Minimum grow inc (1 page) */
  196. #define _HEAP_GROWSTART     _PAGESIZE_  /* Startup grow increment */
  197. #define _HEAP_COALESCE      -1      /* Coalesce heap value */
  198.  
  199. #define _HEAP_EMPTYLIST_SIZE    (1 * _PAGESIZE_)
  200.  
  201. /*
  202.  * Values returned by _heap_findaddr() routine
  203.  */
  204.  
  205. #define _HEAPFIND_EXACT     0   /* found address exactly */
  206. #define _HEAPFIND_WITHIN    1   /* address is within a block */
  207. #define _HEAPFIND_BEFORE    -1  /* address before beginning of heap */
  208. #define _HEAPFIND_AFTER     -2  /* address after end of heap */
  209. #define _HEAPFIND_EMPTY     -3  /* address not found: empty heap */
  210.  
  211. /*
  212.  * Arguments to _heap_param
  213.  */
  214.  
  215. #define _HP_GETPARAM    0       /* get heap parameter value */
  216. #define _HP_SETPARAM    1       /* set heap parameter value */
  217.  
  218. #define _HP_AMBLKSIZ    1       /* get/set _amblksiz value (aka */
  219. #define _HP_GROWSIZE    _HP_AMBLKSIZ    /* _heap_growsize */
  220. #define _HP_RESETSIZE   2       /* get/set _heap_resetsize value */
  221.  
  222.  
  223. /*
  224.  * Macros to round numbers
  225.  *
  226.  * _ROUND2 = rounds a number up to a power of 2
  227.  * _ROUND = rounds a number up to any other numer
  228.  *
  229.  * n = number to be rounded
  230.  * pow2 = must be a power of two value
  231.  * r = any number
  232.  */
  233.  
  234. #define _ROUND2(n,pow2) \
  235.         ( ( n + pow2 - 1) & ~(pow2 - 1) )
  236.  
  237. #define _ROUND(n,r) \
  238.         ( ( (n/r) + ((n%r)?1:0) ) * r)
  239.  
  240. /*
  241.  
  242.    Macros for accessing heap descriptor lists:
  243.  
  244.         _PUTEMPTY(x) = Puts an empty heap desc on the empty list
  245.  
  246.         (x = _PBLKDESC = pointer to heap block descriptor)
  247. */
  248.  
  249. #ifdef _DEBUG
  250.  
  251. #define _PUTEMPTY(x) \
  252. {                               \
  253.         (x)->pnextdesc = _heap_desc.emptylist;      \
  254.                                 \
  255.         (x)->pblock = NULL;             \
  256.                                 \
  257.         _heap_desc.emptylist = (x);         \
  258. }
  259.  
  260. #else  /* _DEBUG */
  261.  
  262. #define _PUTEMPTY(x) \
  263. {                               \
  264.         (x)->pnextdesc = _heap_desc.emptylist;      \
  265.                                 \
  266.         _heap_desc.emptylist = (x);         \
  267. }
  268.  
  269. #endif  /* _DEBUG */
  270.  
  271.  
  272. /*
  273.  * Macros for finding the next 64 Kb boundary from a pointer
  274.  */
  275.  
  276. #define _NXTSEGBNDRY(p)     ((void *)((unsigned)(p) & 0xffff0000 + 0x10000))
  277.  
  278. #define _DISTTOBNDRY(p)     ((unsigned)(0x10000 - (0x0000ffff & (unsigned)(p))))
  279.  
  280.  
  281. /*
  282.  * Define size_t type (if necessary)
  283.  */
  284.  
  285. #ifndef _SIZE_T_DEFINED
  286. typedef unsigned int size_t;
  287. #define _SIZE_T_DEFINED
  288. #endif  /* _SIZE_T_DEFINED */
  289.  
  290.  
  291. /*
  292.  * Prototypes
  293.  */
  294.  
  295. void * __cdecl _nh_malloc(size_t, int);
  296. void * __cdecl _heap_alloc(size_t);
  297. void * __cdecl _flat_malloc(size_t);
  298. _PBLKDESC __getempty(void);
  299. void __cdecl _heap_abort(void);
  300. int __cdecl _heap_addblock(void *, unsigned int);
  301.  
  302.  
  303. void __cdecl _heap_free_region(int);
  304. int __cdecl _heap_findaddr(void *, _PBLKDESC *);
  305. int __cdecl _heap_grow(unsigned int);
  306. int __cdecl _heap_grow_region(unsigned, size_t);
  307. #ifdef _MAC
  308. void __cdecl _heap_init(void);
  309. #else  /* _MAC */
  310. int __cdecl _heap_init(void);
  311. #endif  /* _MAC */
  312.  
  313. int __cdecl _heap_param(int, int, void *);
  314.  
  315. _PBLKDESC __cdecl _heap_search(unsigned size);
  316. _PBLKDESC __cdecl _heap_split_block(_PBLKDESC, size_t);
  317.  
  318. #ifdef _DEBUG
  319. void __cdecl _heap_print_all(void);
  320. void __cdecl _heap_print_regions(void);
  321. void __cdecl _heap_print_desc(void);
  322. void __cdecl _heap_print_emptylist(void);
  323. void __cdecl _heap_print_heaplist(void);
  324. #endif  /* _DEBUG */
  325.  
  326.  
  327. /*
  328.  * Prototypes and macros for multi-thread support
  329.  */
  330.  
  331. #ifdef _MT
  332.  
  333. void __cdecl _free_lk(void *);
  334. size_t __cdecl _msize_lk(void *);
  335. size_t __cdecl _heapused_lk(size_t *pUsed, size_t *pFree);
  336.  
  337. #ifdef _DEBUG
  338. void __cdecl _heap_print_regions_lk(void);
  339. void __cdecl _heap_print_desc_lk(void);
  340. void __cdecl _heap_print_emptylist_lk(void);
  341. void __cdecl _heap_print_heaplist_lk(void);
  342. #endif  /* _DEBUG */
  343.  
  344. #else  /* _MT */
  345.  
  346. #ifdef _MAC
  347. //this needs to be removed after source merge
  348. #define _malloc_lk(s)   malloc(s)
  349. #endif  /* _MAC */
  350.  
  351. #define _free_lk(p) free(p)
  352. #define _msize_lk(p)    _msize(p)
  353.  
  354. #ifdef _DEBUG
  355. #define _heap_print_regions_lk()    _heap_print_regions()
  356. #define _heap_print_desc_lk()       _heap_print_desc()
  357. #define _heap_print_emptylist_lk()  _heap_print_emptylist()
  358. #define _heap_print_heaplist_lk()   _heap_print_heaplist()
  359. #endif  /* _DEBUG */
  360.  
  361. #endif  /* _MT */
  362.  
  363.  
  364. #ifdef __cplusplus
  365. }
  366. #endif  /* __cplusplus */
  367.  
  368. #endif  /* _INC_HEAP */
  369.