summaryrefslogtreecommitdiffstats
path: root/private/crt32/heap/heapinit.c
blob: 6658596fe1fea267eb47e7939464fb5a629b5373 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
/***
*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
*			<cruntime.h> and removed #include <register.h>.
*	07-24-90  SBM	Removed '32' from API names
*	10-03-90  GJF	New-style function declarators.
*	12-04-90  SRW	Changed to include <oscalls.h> instead of <doscalls.h>
*	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 <cruntime.h>
#include <oscalls.h>
#include <dos.h>
#include <heap.h>
#include <stddef.h>
#include <stdio.h>

#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:
*	<void>
*Exit:
*	<void>
*
*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 <cruntime.h>
#include <oscalls.h>
#include <heap.h>

HANDLE _HeapHandle;

void _CALLTYPE1 _heap_init (
	void
	)
{
	if ( (_HeapHandle = HeapCreate(HEAP_SERIALIZE, 0x10000, 0)) == NULL )
		_heap_abort();
}

#endif	/* _WIN32DOS_ */