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