1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 %
4 % File: bpsheap.c
5 % Description: Code to dynamically set up bps and heap structures
6 % Author: RAM, HP/FSD
7 % Created: 9-Mar-84
8 % Modified:
9 % Mode: Text
10 % Package:
11 %
12 % (c) Copyright 1987, University of Utah, all rights reserved.
13 %
14 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
15 %
16 % Revisions:
17 %
18 % 11-Aug-88 (Julian Padget)
19 % Added initialization of bpslowerbound in setupbps().
20 % 07-Apr-87 (Harold Carr & Leigh Stoller)
21 % Put in error checking to ensure that the memory pointers will fit in
22 % info field of the lisp item.
23 % 21-Dec-86 (Leigh Stoller)
24 % Added allocatemorebps function, called from try-other-bps-spaces in
25 % allocators.sl.
26 % 18-Dec-86 (Leigh Stoller)
27 % Changed to newer model. Bps is now defined in bps.c so that unexec can
28 % alter the text/data boundry. Took out code that allowed command line
29 % modification of bpssize. (Now set in the Makefile). Added setupbps()
30 % that initialzes nextbps and lastbps.
31 % 20-Sep-86 (Leigh Stoller)
32 % Removed assembler alias statements because they are not portable. Instead,
33 % a sed script will be used to convert the _variables of C to VARIABLES of
34 % PSL.
35 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
36 */
37
38 #include <stdio.h>
39
40 /* Use 1 if using compacting collector ($pxnk/compact-gc.sl).
41 Use 2 if using copying collector ($pnk/copying-gc.sl).
42 Be sure to update $pxnk/load-psl.sl to include correct collector. */
43
44 #define MINSIZE 8000000 /* Default total in number of bytes. */
45 #define MALLOCSIZE 500000 /* Default size for OS support functions. */
46 #define EXTRABPSSIZE 100000 /* Minimum amount to increase bps by. */
47 #define MINIMUMHEAPADD 20000 /* Minimum amount to increase heap by */
48
49
50 #ifndef BPSSIZE
51 #define BPSSIZE 800000 /* Default bps size in number of bytes */
52 #endif
53
54 char * imagefile ;
55 int max_image_size;
56 int oldbreakvalue;
57
58 extern int alreadysetupbpsandheap;
59 extern int hashtable;
60 extern char bps[];
61 extern int lastbps;
62 extern int nextbps;
63 extern int bpslowerbound;
64
65 extern int heaplowerbound;
66 extern int heapupperbound;
67 extern int heaplast;
68 extern int heaptrapbound;
69
70 extern int oldheaplowerbound;
71 extern int oldheapupperbound;
72 extern int oldheaplast;
73 extern int oldheaptrapbound;
74
75 extern int SYMVAL;
76
77 /* Write this ourselves to keep from including half the math library */
power(x,n)78 static power(x, n)
79 int x, n;
80 {
81 int i, p;
82
83 p = 1;
84 for (i = 1; i <= n; ++i)
85 p = p * x;
86 return(p);
87 }
88
setupbpsandheap(argc,argv)89 setupbpsandheap(argc,argv)
90 int argc;
91 char *argv[];
92 { int ohl,ohtb,ohlb,ohub,hl,htb,hlb,hub;
93 int memset = 0; int feder = 200000;
94 FILE * imago;
95 int headerword [8];
96 int i, total, bpssize, heapsize, mallocsize;
97 int current_size_in_bytes, heapsize_in_bytes;
98 double bpspercent, heappercent;
99 char *argp, *scanptr, *scanformat;
100 int ii1,ii2,ii3,ii4,ii5,ii6,ii7,ii8,ii9,ii10,ii11;
101
102 total = MINSIZE;
103 mallocsize = MALLOCSIZE;
104
105 for (i=1; i<argc-1; i++)
106 {
107 argp = argv[i];
108 if (*argp++ == '-')
109 {
110 scanformat = "";
111 switch (*argp++) {
112 case 't': scanptr = (char *)&total;
113 memset = 1;
114 switch (*argp) {
115 case 'x': scanformat = "%x";
116 break;
117 case 'd': scanformat = "%d";
118 break;
119 }
120 break;
121 case 'm': scanptr = (char *)&mallocsize;
122 switch (*argp) {
123 case 'x': scanformat = "%x";
124 break;
125 case 'd': scanformat = "%d";
126 break;
127 }
128 break;
129 case 'f': imagefile = argv[i+1]; break;
130 case 'g': scanptr = (char *)&feder;
131 scanformat = "%d"; break;
132 }
133 if (*scanformat != 0)
134 sscanf(argv[i+1],scanformat,scanptr);
135 }
136 } /* end of for loop -- arg vector searched */
137
138 /* insure valid values */
139 if (total == 0) total = MINSIZE;
140
141 if (mallocsize <= 0) mallocsize = MALLOCSIZE;
142
143
144
145 /* Reserve some space for C's usr of io buffers, etc. By mallocing then
146 freeing, the memory is sbrk'ed onto the image, but available for future
147 calls to malloc, which will not need to call sbrk again. */
148
149
150 ii1=malloc(0x408);
151 ii2=calloc(3,3);
152 ii3=malloc(0x408);
153 ii4=malloc(0x142c);
154 ii5=malloc(0x1008);
155 ii6=malloc(0x17);
156 ii7=malloc(0x3);
157 ii8=malloc(0x1068);
158 ii9=malloc(0x28);
159 ii10=malloc(0xc);
160 ii11=malloc(0x384);
161
162 external_user_homedir_string(); /* This is done by read-init-file */
163 external_anyuser_homedir_string("hugo");
164
165 bpssize = BPSSIZE;
166
167 heapsize_in_bytes = total - bpssize;
168
169 /* On systems in which the image does not start at address 0, this won't
170 really allocate the full maximum, but close enough. */
171 current_size_in_bytes = (((int) sbrk(0))<<4)>>4;
172 max_image_size = power(2, 27); /* 1 more than allowable size */
173
174 if ((heapsize_in_bytes + current_size_in_bytes) >= max_image_size) {
175 heapsize_in_bytes = max_image_size - current_size_in_bytes;
176 total = heapsize_in_bytes + bpssize;
177 printf("Size requested will result in pointer values larger than\n");
178 printf(" PSL items can handle. Will allocate maximum size instead.\n\n");
179 }
180
181 heapsize =(heapsize_in_bytes / 8) * 4; /* insure full words */
182 heappercent = ((float) (total - bpssize) / total) * 100.0;
183 bpspercent = ((float) bpssize / total) * 100.0;
184
185 if (imagefile == NULL)
186 { printf("Setting heap limit as follows:\n");
187 printf("Total heap & bps space = %d (%X), bps = %.2f, heap = %.2f\n",
188 total, total, bpspercent, heappercent);
189 }
190
191 setupbps();
192 getheap(heapsize,feder);
193
194 free (ii2); free(ii4); free (ii6); free(ii8);
195 free (ii1); free (ii3); free (ii5); free(ii7);
196 free (ii11); free (ii9); free (ii10);
197
198
199 if (imagefile == NULL)
200 printf("bpssize = %d (%X), heapsize = %d (%X)\nTotal image size = %d (%X)\n",
201 bpssize, bpssize,
202 heapsize, heapsize,
203 (int) sbrk(0), (int) sbrk(0));
204
205
206 if (imagefile != NULL) {
207 ohl = oldheaplowerbound; ohub = oldheapupperbound;
208 ohl = oldheaplast; ohtb = oldheaptrapbound;
209 hlb = heaplowerbound; hub = heapupperbound;
210 hl = heaplast; htb = heaptrapbound;
211 /* save the new values around restore of the old ones */
212
213 printf("Loading image file: %s \n",imagefile);
214 imago = fopen (imagefile,"r");
215 if (imago == NULL) { perror ("error"); exit (-1); }
216 fread (headerword,4,8,imago);
217
218 if (strcmp(headerword,datetag()))
219 { printf(" Cannot start the image with this bpsl \n");
220 exit (-19); }
221
222 fread (headerword,4,7,imago);
223 fread (&SYMVAL,1,headerword[0],imago);
224 /* printf (" heaplowerbound = %x (new) %x (file)\n" heaplowerbound,
225 headerword[6]); */
226 if(headerword[6] > heaplowerbound + feder/2) {
227 printf (" Cant relocate the image"); exit (-3); }
228 if(headerword[6] < heaplowerbound - feder/2) {
229 printf (" Cant relocate the image"); exit (-3); }
230 feder = heaplowerbound - headerword[6];
231 fread (headerword[6],1,headerword[1],imago);
232 fread (&hashtable,1,headerword[2],imago);
233 fread (bpslowerbound,1,headerword[3],imago);
234 fread (headerword[4],1,headerword[5],imago);
235 fclose (imago);
236 vvm_cflush (bpslowerbound,BPSSIZE);
237 if (memset) {
238 oldheaplowerbound = ohl -feder;
239 oldheapupperbound = ohub -feder;
240 oldheaplast = ohl -feder;
241 oldheaptrapbound = ohtb -feder;
242 heapupperbound = hub -feder;
243 heaptrapbound = htb -feder; }
244 return (4711);
245 }
246 return (0);
247
248 }
249
250
251 /* The current procedure is to convert the starting address of the char
252 array defined in bps.c to an address and store it in nextbps. A check
253 is made to make sure that nextbps falls on an even word boundry.
254 */
255
setupbps()256 setupbps()
257 { bpslowerbound = ((int)bps + 3) & ~3;
258 nextbps = ((int)bps + 3) & ~3; /* Up to a multiple of 4. */
259 lastbps = ((int)bps + BPSSIZE) & ~3; /* Down to a multiple of 4. */
260 }
261
262
263 /* Allocate alternate bps space. Note: The use of sbrk(), and the fact that
264 nextbps is now greater than heaplast means that unexec should be not be
265 tried after this routine is called. The image would be huge.
266 */
allocatemorebps()267 allocatemorebps()
268 {
269 int current_size_in_bytes;
270 int old_nextbps = nextbps;
271
272 current_size_in_bytes = sbrk(0);
273
274 if ((current_size_in_bytes + EXTRABPSSIZE) >= max_image_size)
275 return(0);
276
277 if (((int)sbrk(0)) % 2) /* force to even word boundary*/
278 nextbps = (int)sbrk(1);
279
280 nextbps = (int)sbrk(EXTRABPSSIZE); /* allocate extra BPS */
281 if (nextbps == -1) {
282 nextbps = old_nextbps;
283 return(0);
284 }
285 lastbps = nextbps + EXTRABPSSIZE;
286 return(EXTRABPSSIZE); /* This will be a paramter later */
287 }
288
289
290 /* tag( getheap )
291 */
292
getheap(heapsize,feder)293 getheap(heapsize,feder)
294 int heapsize,feder;
295 {
296 heaplowerbound = (int)sbrk(2 * heapsize + feder );
297 /* allocate first heap */;
298
299 if (heaplowerbound == -1) {
300 perror("GETHEAP");
301 exit(-1);
302 }
303 heaplowerbound += feder / 2;
304 heaplowerbound = heaplowerbound;
305 heapupperbound = heaplowerbound + heapsize;
306 heaplast = heaplowerbound;
307 heaptrapbound = heapupperbound -120;
308
309 oldheaplowerbound = heapupperbound;
310 oldheapupperbound = oldheaplowerbound + heapsize;
311 oldheaplast = oldheaplowerbound;
312 oldheaptrapbound = oldheapupperbound -120;
313
314 oldbreakvalue = (int)sbrk(0);
315 }
316
317
318 /* Tag( alterheapsize )
319 */
320
alterheapsize(increment)321 alterheapsize(increment)
322
323 int increment;
324
325 {
326 /*
327 alters the size of the heap by the specified increment. Returns
328 the increment if successful, otherwise returns 0. May fai i
329 the sbrk is unsuccessful or if the user tries to cut the heap back
330 to nothing or the current break value does not match the old value.
331 The latter case occurs when a malloc or sbrk has allocated space for
332 some other software, in which case we cannot allocate any more space
333 contiguously.
334
335 Modifies both the heap and gcarray size.
336 NOTE: a garbage collection should probably be performed before this
337 routine is called.
338 NOTE: only implemented for the one heap version on the 68000.
339 */
340
341 int heapsize;
342 int current_size_in_bytes;
343
344 /* assumes the current heap is the 'lower' one */
345 int newbreakvalue;
346
347 if ((int) sbrk(0) != oldbreakvalue) /* Non contiguous memory */
348 { printf(" unable to allocate %x %x\n",sbrk(0),oldbreakvalue);
349 return(0); }
350
351 current_size_in_bytes = ( (int) sbrk(0) <<4) >>4;
352
353 if ((current_size_in_bytes + 2* increment) >= max_image_size)
354 return(-1);
355
356 if ((int)sbrk(2 * increment) == -1) /* the sbrk failed. */
357 return(-2);
358
359 newbreakvalue = (int) sbrk(0);
360
361 heapupperbound = heapupperbound + increment ;
362 heaptrapbound = heapupperbound - 120;
363 oldheaplowerbound = oldheaplowerbound + increment;
364 oldheapupperbound = oldheapupperbound + 2* increment ;
365 oldheaplast = oldheaplowerbound;
366 oldheaptrapbound = oldheapupperbound -120;
367
368
369 oldbreakvalue = newbreakvalue;
370 return(increment);
371 }
unexec()372 unexec ()
373 { return (BPSSIZE); }
374