home *** CD-ROM | disk | FTP | other *** search
- /***
- *heapinit.c - Initialze the heap
- *
- * Copyright (c) 1989-1997, Microsoft Corporation. All rights reserved.
- *
- *Purpose:
- *
- *******************************************************************************/
-
-
- #ifdef WINHEAP
-
-
- #include <cruntime.h>
- #include <malloc.h>
- #include <winheap.h>
-
- HANDLE _crtheap;
-
- /*
- * Dummy definition of _amblksiz. Included primarily so the dll will build
- * without having to change crtlib.c (there is an access function for _amblksiz
- * defined in crtlib.c).
- */
- unsigned int _amblksiz = BYTES_PER_PARA;
-
-
- /***
- *_heap_init() - Initialize the heap
- *
- *Purpose:
- * Setup the initial C library heap.
- *
- * NOTES:
- * (1) This routine should only be called once!
- * (2) This routine must be called before any other heap requests.
- *
- *Entry:
- * <void>
- *Exit:
- * Returns 1 if successful, 0 otherwise.
- *
- *Exceptions:
- * If heap cannot be initialized, the program will be terminated
- * with a fatal runtime error.
- *
- *******************************************************************************/
-
- int __cdecl _heap_init (
- int mtflag
- )
- {
- // Initialize the "big-block" heap first.
- if ( (_crtheap = HeapCreate( mtflag ? 0 : HEAP_NO_SERIALIZE,
- BYTES_PER_PAGE, 0 )) == NULL )
- return 0;
-
- // Initialize the small-block heap
- if (__sbh_heap_init() == 0)
- {
- HeapDestroy(_crtheap);
- return 0;
- }
- return 1;
- }
-
- /***
- *_heap_term() - return the heap to the OS
- *
- *Purpose:
- *
- * NOTES:
- * (1) This routine should only be called once!
- * (2) This routine must be called AFTER any other heap requests.
- *
- *Entry:
- * <void>
- *Exit:
- * <void>
- *
- *Exceptions:
- *
- *******************************************************************************/
-
- void __cdecl _heap_term (void)
- {
- PHEADER pHeader = __sbh_pHeaderList;
- int cntHeader;
-
- // scan through all the headers
- for (cntHeader = 0; cntHeader < __sbh_cntHeaderList; cntHeader++)
- {
- // decommit and release the address space for the region
- VirtualFree(pHeader->pHeapData, BYTES_PER_REGION, MEM_DECOMMIT);
- VirtualFree(pHeader->pHeapData, 0, MEM_RELEASE);
-
- // free the region data structure
- HeapFree(_crtheap, 0, pHeader->pRegion);
-
- pHeader++;
- }
- // free the header list
- HeapFree(_crtheap, 0, __sbh_pHeaderList);
-
- // destroy the large-block heap
- HeapDestroy(_crtheap);
- }
-
-
- #else /* WINHEAP */
-
-
- #ifdef _WIN32
-
-
- #include <cruntime.h>
- #include <oscalls.h>
- #include <dos.h>
- #include <heap.h>
- #include <stddef.h>
- #include <stdio.h>
- #include <stdlib.h>
-
- /*
- * Heap descriptor
- */
-
-
- struct _heap_desc_ _heap_desc = {
- &_heap_desc.sentinel, /* pfirstdesc */
- &_heap_desc.sentinel, /* proverdesc */
- NULL, /* emptylist */
- NULL, /* sentinel.pnextdesc */
- NULL /* sentinel.pblock */
- };
-
- /*
- * Array of region structures
- * [Note: We count on the fact that this is always initialized to zero
- * by the compiler.]
- */
-
- struct _heap_region_ _heap_regions[_HEAP_REGIONMAX];
-
- void ** _heap_descpages; /* linked list of pages used for descriptors */
-
- /*
- * Control parameter locations
- */
-
- unsigned int _heap_resetsize = 0xffffffff;
-
- /* NOTE: Currenlty, _heap_growsize is a #define to _amblksiz */
- unsigned int _heap_growsize = _HEAP_GROWSIZE; /* region inc size */
- unsigned int _heap_regionsize = _HEAP_REGIONSIZE_L; /* region size */
- unsigned int _heap_maxregsize = _HEAP_MAXREGSIZE_L; /* max region size */
-
-
- /***
- *_heap_init() - Initialize the heap
- *
- *Purpose:
- * Setup the initial C library heap. All necessary memory and
- * data bases are init'd appropriately so future requests work
- * correctly.
- *
- * NOTES:
- * (1) This routine should only be called once!
- * (2) This routine must be called before any other heap requests.
- *
- *
- *Entry:
- * <void>
- *Exit:
- * <void>
- *
- *Exceptions:
- * If heap cannot be initialized, the program will be terminated
- * with a fatal runtime error.
- *
- *******************************************************************************/
-
- void __cdecl _heap_init (
- void
- )
- {
- /*
- * Test for Win32S or Phar Lap TNT environment
- * which cannot allocate uncommitted memory
- * without actually allocating physical memory
- *
- * High bit of _osver is set for both of those environments
- * -AND- the Windows version will be less than 4.0.
- */
-
- if ( ( _osver & 0x8000 ) && ( _winmajor < 4 ) )
- {
- _heap_regionsize = _HEAP_REGIONSIZE_S;
- _heap_maxregsize = _HEAP_MAXREGSIZE_S;
- }
- }
-
-
-
- /***
- *_heap_term() - Clean-up the heap
- *
- *Purpose:
- * This routine will decommit and release ALL of the CRT heap.
- * All memory malloc-ed by the CRT will then be invalid.
- *
- * NOTES:
- * (1) This routine should only be called once!
- * (2) This routine must be called AFTER any other heap requests.
- *
- *Entry:
- * <void>
- *Exit:
- * <void>
- *
- *Exceptions:
- *
- *******************************************************************************/
-
- void __cdecl _heap_term (
- void
- )
- {
- int index;
- void **pageptr;
-
- /*
- * Loop through the region descriptor table, decommitting
- * and releasing (freeing up) each region that is in use.
- */
-
- for ( index=0 ; index < _HEAP_REGIONMAX ; index++ ) {
- void * regbase ;
-
- if ( (regbase = _heap_regions[index]._regbase)
- && VirtualFree(regbase, _heap_regions[index]._currsize, MEM_DECOMMIT)
- && VirtualFree(regbase, 0, MEM_RELEASE) )
- regbase = _heap_regions[index]._regbase = NULL ;
- }
-
- /*
- * Now we need to decommit and release the pages used for descriptors
- * _heap_descpages points to the head of a singly-linked list of the pages.
- */
-
- pageptr = _heap_descpages;
-
- while ( pageptr ) {
- void **nextpage;
-
- nextpage = *pageptr;
-
- if(!VirtualFree(pageptr, 0, MEM_RELEASE))
- break; /* if the linked list is corrupted, give up */
-
- pageptr = nextpage;
- }
-
- }
-
-
-
- /***
- * _heap_grow_emptylist() - Grow the empty heap descriptor list
- *
- *Purpose:
- * (1) Get memory from OS
- * (2) Form it into a linked list of empty heap descriptors
- * (3) Attach it to the master empty list
- *
- * NOTE: This routine assumes that the emptylist is NULL
- * when called (i.e., there are no available empty heap descriptors).
- *
- *Entry:
- * (void)
- *
- *Exit:
- * 1, if the empty heap descriptor list was grown
- * 0, if the empty heap descriptor list could not be grown.
- *
- *Exceptions:
- *
- *******************************************************************************/
-
- static int __cdecl _heap_grow_emptylist (
- void
- )
- {
- REG1 _PBLKDESC first;
- REG2 _PBLKDESC next;
- _PBLKDESC last;
-
- /*
- * Get memory for the new empty heap descriptors
- *
- * Note that last is used to hold the returned pointer because
- * first (and next) are register class.
- */
-
- if ( !(last = VirtualAlloc(NULL,
- _HEAP_EMPTYLIST_SIZE,
- MEM_COMMIT,
- PAGE_READWRITE)) )
- return 0;
-
- /*
- * Add this descriptor block to the front of the list
- *
- * Advance "last" to skip over the
- */
-
- *(void **)last = _heap_descpages;
- _heap_descpages = (void **)(last++);
-
-
- /*
- * Init the empty heap descriptor list.
- */
-
- _heap_desc.emptylist = first = last;
-
-
- /*
- * Carve the memory into an empty list
- */
-
- last = (_PBLKDESC) ((char *) first + _HEAP_EMPTYLIST_SIZE - 2 * sizeof(_BLKDESC));
- next = (_PBLKDESC) ((char *) first + sizeof(_BLKDESC));
-
- while ( first < last ) {
-
- /* Init this descriptor */
- first->pnextdesc = next;
-
- /* onto the next block */
-
- first = next++;
-
- }
-
- /*
- * Take care of the last descriptor (end of the empty list)
- */
-
- last->pnextdesc = NULL;
-
-
- return 1;
- }
-
-
- /***
- *__getempty() - get an empty heap descriptor
- *
- *Purpose:
- * Get a descriptor from the list of empty heap descriptors. If the list
- * is empty, call _heap_grow_emptylist.
- *
- *Entry:
- * no arguments
- *
- *Exit:
- * If successful, a pointer to the descriptor is returned.
- * Otherwise, NULL is returned.
- *
- *Exceptions:
- *
- *******************************************************************************/
-
- _PBLKDESC __cdecl __getempty(
- void
- )
- {
- _PBLKDESC pdesc;
-
- if ( (_heap_desc.emptylist == NULL) && (_heap_grow_emptylist()
- == 0) )
- return NULL;
-
- pdesc = _heap_desc.emptylist;
-
- _heap_desc.emptylist = pdesc->pnextdesc;
-
- return pdesc;
- }
-
-
- #else /* _WIN32 */
-
- #if defined (_M_MPPC) || defined (_M_M68K)
-
-
- #include <cruntime.h>
- #include <dos.h>
- #include <heap.h>
- #include <malloc.h>
- #include <stddef.h>
- #include <stdio.h>
- #include <string.h>
- #include <dbgint.h>
-
- #include <macos\types.h>
- #include <macos\errors.h>
- #include <macos\memory.h> // Mac OS interface header
- #include <macos\lowmem.h>
- #include <macos\segload.h>
-
- #define _HEAP_EMPTYLIST_SIZE (1 * _PAGESIZE_)
-
- #define DSErrCode (*(short*)(0x0af0))
-
- /*
- * Heap descriptor
- */
-
- struct _heap_desc_ _heap_desc = {
- &_heap_desc.sentinel, /* pfirstdesc */
- &_heap_desc.sentinel, /* proverdesc */
- NULL, /* emptylist */
- NULL, /* sentinel.pnextdesc */
- NULL /* sentinel.pblock */
- };
-
- /*
- * Array of region structures
- * [Note: We count on the fact that this is always initialized to zero
- * by the compiler.]
- */
-
- Handle hHeapRegions = NULL;
- int _heap_region_table_cur = 0;
-
- /*
- * Control parameter locations
- */
-
- unsigned int _heap_resetsize = 0xffffffff;
-
- /* NOTE: Currenlty, _heap_growsize is a #define to _amblksiz */
- unsigned int _heap_growsize = _HEAP_GROWSIZE; /* region inc size */
- unsigned int _heap_regionsize = _HEAP_REGIONSIZE; /* region size */
-
-
- /***
- *_heap_init() - Initialize the heap
- *
- *Purpose:
- * Setup the initial C library heap. All necessary memory and
- * data bases are init'd appropriately so future requests work
- * correctly.
- *
- * NOTES:
- * (1) This routine should only be called once!
- * (2) This routine must be called before any other heap requests.
- *
- *
- *Entry:
- * <void>
- *Exit:
- * <void>
- *
- *Exceptions:
- * If heap cannot be initialized, the program will be terminated
- * with a fatal runtime error.
- *
- *******************************************************************************/
-
- void __cdecl _heap_init (
- void
- )
- {
-
- #define _INITREGIONSZ 0x1000
-
- /*LATER -- do we need to do anything to init heap? Yes, in case user not malloc first*/
- int oldregionsz = _heap_regionsize; /* save current region size */
-
- struct _heap_region_ *pHeapRegions;
- void *p;
- void *p2;
-
- if (hHeapRegions == NULL)
- {
- hHeapRegions = NewHandle(sizeof(struct _heap_region_)*_HEAP_REGIONMAX);
- if (hHeapRegions == NULL)
- {
- DSErrCode = appMemFullErr;
- ExitToShell();
- }
- HLock(hHeapRegions);
- pHeapRegions = (struct _heap_region_ *)(*hHeapRegions);
- memset(pHeapRegions, 0, sizeof(struct _heap_region_)*_HEAP_REGIONMAX);
- _heap_region_table_cur = _HEAP_REGIONMAX;
- }
-
-
- _heap_regionsize = _INITREGIONSZ; /* set region size to 64 Kb */
-
- /* make sure we have enough memory to do initialization */
- if ((p = NewPtr(_HEAP_EMPTYLIST_SIZE)) == NULL)
- {
- DSErrCode = appMemFullErr;
- ExitToShell();
- }
-
- if ((p2 = NewPtr(_heap_regionsize)) == NULL)
- {
- DSErrCode = appMemFullErr;
- ExitToShell();
- }
-
- if (p)
- {
- DisposePtr(p);
- }
- if (p2)
- {
- DisposePtr(p2);
- }
-
- p = _malloc_base(4);
- if (p == NULL)
- {
- DSErrCode = appMemFullErr;
- ExitToShell();
- }
- _free_base( p ); /* malloc, then free a block */
- _heap_regionsize = oldregionsz; /* restore region size */
-
- }
-
-
-
- /***
- * _heap_grow_emptylist() - Grow the empty heap descriptor list
- *
- *Purpose:
- * (1) Get memory from OS
- * (2) Form it into a linked list of empty heap descriptors
- * (3) Attach it to the master empty list
- *
- * NOTE: This routine assumes that the emptylist is NULL
- * when called (i.e., there are no available empty heap descriptors).
- *
- *Entry:
- * (void)
- *
- *Exit:
- * (void)
- *
- *Exceptions:
- *
- *******************************************************************************/
-
- static int __cdecl _heap_grow_emptylist (
- void
- )
- {
- REG1 _PBLKDESC first;
- REG2 _PBLKDESC next;
- _PBLKDESC last;
-
-
- /*
- * Get memory for the new empty heap descriptors
- *
- * Note that last is used to hold the returned pointer because
- * first (and next) are register class.
- */
-
- if ((last = (_PBLKDESC)NewPtr(_HEAP_EMPTYLIST_SIZE)) == NULL)
- {
- return 0;
- }
-
- /*
- * Init the empty heap descriptor list.
- */
-
- _heap_desc.emptylist = first = last;
-
-
- /*
- * Carve the memory into an empty list
- */
-
- last = (_PBLKDESC) ((char *) first + _HEAP_EMPTYLIST_SIZE - sizeof(_BLKDESC));
- next = (_PBLKDESC) ((char *) first + sizeof(_BLKDESC));
-
- while ( first < last ) {
-
- /* Init this descriptor */
- first->pnextdesc = next;
-
- /* onto the next block */
-
- first = next++;
-
- }
-
- /*
- * Take care of the last descriptor (end of the empty list)
- */
-
- last->pnextdesc = NULL;
-
-
- return 1;
-
- }
-
- /***
- *__getempty() - get an empty heap descriptor
- *
- *Purpose:
- * Get a descriptor from the list of empty heap descriptors. If the list
- * is empty, call _heap_grow_emptylist.
- *
- *Entry:
- * no arguments
- *
- *Exit:
- * If successful, a pointer to the descriptor is returned.
- * Otherwise, NULL is returned.
- *
- *Exceptions:
- *
- *******************************************************************************/
-
- _PBLKDESC __cdecl __getempty(
- void
- )
- {
- _PBLKDESC pdesc;
-
- if ( (_heap_desc.emptylist == NULL) && (_heap_grow_emptylist()
- == 0) )
- return NULL;
-
- pdesc = _heap_desc.emptylist;
-
- _heap_desc.emptylist = pdesc->pnextdesc;
-
- return pdesc;
- }
-
-
- #endif /* defined (_M_MPPC) || defined (_M_M68K) */
-
- #endif /* _WIN32 */
-
- #endif /* WINHEAP */
-