/*** *heapinit.c - Initialze the heap * * Copyright (c) 1989-1993, Microsoft Corporation. All rights reserved. * *Purpose: * *Revision History: * 06-28-89 JCR Module created. * 06-30-89 JCR Added _heap_grow_emptylist * 11-13-89 GJF Fixed copyright * 11-15-89 JCR Moved _heap_abort routine to another module * 12-15-89 GJF Removed DEBUG286 stuff, did some tuning, changed header * file name to heap.h and made functions explicitly * _cdecl. * 12-19-89 GJF Removed plastdesc field from _heap_desc_ struct * 03-11-90 GJF Replaced _cdecl with _CALLTYPE1, added #include * and removed #include . * 07-24-90 SBM Removed '32' from API names * 10-03-90 GJF New-style function declarators. * 12-04-90 SRW Changed to include instead of * 12-06-90 SRW Added _CRUISER_ and _WIN32 conditionals. * 02-01-91 SRW Changed for new VirtualAlloc interface (_WIN32_) * 03-05-91 GJF Added definition of _heap_resetsize (conditioned on * _OLDROVER_ not being #define-d). * 04-04-91 GJF Reduce _heap_regionsize to 1/2 a meg for Dosx32 * (_WIN32_). * 04-05-91 GJF Temporary hack for Win32/DOS folks - special version * of _heap_init which calls HeapCreate. The change * conditioned on _WIN32DOS_. * 04-09-91 PNT Added _MAC_ conditional * 02-23-93 SKS Remove DOSX32 support under WIN32 ifdef * *******************************************************************************/ #ifndef _WIN32DOS_ #include #include #include #include #include #include #define _HEAP_EMPTYLIST_SIZE (1 * _PAGESIZE_) /* * 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]; /* * Control parameter locations */ #ifndef _OLDROVER_ unsigned int _heap_resetsize = 0xffffffff; #endif /* _OLDROVER_ */ /* 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: * *Exit: * * *Exceptions: * If heap cannot be initialized, the program will be terminated * with a fatal runtime error. * *******************************************************************************/ void _CALLTYPE1 _heap_init ( void ) { #ifdef _CRUISER_ /* * Currently nothing to do to init the 386 heap!!! * If this stays true, we can get rid of the _heapinit call * in startup and remove this module! */ #else /* ndef _CRUISER*/ #ifdef _WIN32_ /* * Currently nothing to do to init the 386 heap!!! * If this stays true, we can get rid of the _heapinit call * in startup and remove this module! */ #else /* ndef _WIN32_ */ #error ERROR - ONLY CRUISER OR WIN32 TARGET SUPPORTED! #endif /* _WIN32_ */ #endif /* _CRUISER_ */ } /*** * _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: * *******************************************************************************/ void _CALLTYPE1 _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. */ #ifdef _CRUISER_ if ( DOSALLOCMEM(&last, _HEAP_EMPTYLIST_SIZE, _COMMIT, 0) != 0 ) _heap_abort(); #else /* ndef _CRUISER_ */ #ifdef _WIN32_ if (!(last = VirtualAlloc(NULL, _HEAP_EMPTYLIST_SIZE, MEM_COMMIT, PAGE_READWRITE))) _heap_abort(); #else /* ndef _WIN32_ */ #ifdef _MAC_ TBD(); #else /* ndef _MAC_ */ #error ERROR - ONLY CRUISER, WIN32, OR MAC TARGET SUPPORTED! #endif /* _MAC_ */ #endif /* _WIN32_ */ #endif /* _CRUISER_ */ /* * 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 */ #ifdef DEBUG first->pblock = NULL; #endif first->pnextdesc = next; /* onto the next block */ first = next++; } /* * Take care of the last descriptor (end of the empty list) */ last->pnextdesc = NULL; #ifdef DEBUG last->pblock = NULL; #endif } #else /* _WIN32DOS_ */ /* * TEMPORARY HACK! THE CODE BELOW IS INTENDED TO ALLOW LIMITED USE OF THE * C RUNTIME ON WIN32/DOS. IT WILL BE DELETED AS SOON AS THEY IMPLEMENT * VirtualAlloc()! */ #include #include #include HANDLE _HeapHandle; void _CALLTYPE1 _heap_init ( void ) { if ( (_HeapHandle = HeapCreate(HEAP_SERIALIZE, 0x10000, 0)) == NULL ) _heap_abort(); } #endif /* _WIN32DOS_ */