Documentation fixes
[vlp.git] / src / int / runsys.c
1      /* Loglan82 Compiler&Interpreter
2      Copyright (C) 1981-1993 Institute of Informatics, University of Warsaw
3      Copyright (C)  1993, 1994 LITA, Pau
4      
5      This program is free software; you can redistribute it and/or modify
6      it under the terms of the GNU General Public License as published by
7      the Free Software Foundation; either version 2 of the License, or
8      (at your option) any later version.
9      
10      This program is distributed in the hope that it will be useful,
11      but WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13      GNU General Public License for more details.
14      
15              You should have received a copy of the GNU General Public License
16              along with this program; if not, write to the Free Software
17              Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18
19  contacts:  Andrzej.Salwicki@univ-pau.fr
20
21 or             Andrzej Salwicki
22                 LITA   Departement d'Informatique
23                 Universite de Pau
24                 Avenue de l'Universite
25                 64000 Pau   FRANCE
26                  tel.  ++33 59923154    fax. ++33 59841696
27
28 =======================================================================
29 */
30
31 #include "depend.h"
32 #include "genint.h"
33 #include "int.h"
34 #include "process.h"
35 #include "intproto.h"
36
37 /**
38  * @file
39  */
40
41 /**
42  * Initialize memory structures for objects, main object and a few goodies more.
43  */
44 void runsys()
45 {
46         word apt, i;
47         procaddr father;
48
49         /* initialize process descriptors */
50         for (i = 0; i < MAXPROCESS; i++) {
51                 /* not used */
52                 process[i].used = FALSE;
53                 /* initial mark for processes */
54                 process[i].mark = -1;
55                 /* memory not allocated */
56                 process[i].M = NULL;
57                 process[i].hash = NULL;
58         }
59         /* always contains code */
60         process[0].M = M;
61         /* DISPLAY offset in process object */
62         dispoff = VIRTSC - (lastprot + 1);
63         /* indirect DISPLAY offset */
64         disp2off = dispoff - (lastprot + 1);
65         /* initialize Round-Robin queue */
66         ready = qinit();
67         /* init pseudo-random no. generator */
68         ranset();
69
70 #if OS2
71         {
72                 SEL gsel, lsel;
73                 DosGetInfoSeg(&gsel, &lsel);
74                 ginf = MAKEPGINFOSEG(gsel);
75         }
76 #endif
77
78         /* create main process */
79         if (!remote) {
80                 /* dummy DL for generated process */
81                 father.node = 0;
82                 father.pix  = 0;
83                 father.mark = 0;
84                 /* current process index */
85                 thispix = 0;
86                 /* current process descr pointer */
87                 thisp = &process[thispix];
88                 initprocess((word) 0, (word) MAINBLOCK, &father);
89                 /* am of main */
90                 mainprog = thisp->prochead;
91                 /* pointers to current object */
92                 c1 = thisp->c1;
93                 c2 = thisp->c2;
94                 /* instruction counter */
95                 ic = thisp->ic;
96                 /* parameter vector */
97                 param = thisp->param;
98                 /* LWA+1 of main */
99                 apt = mainprog + M[mainprog];
100                 /* DISPLAY in main */
101                 display = apt + dispoff;
102                 /* indirect DISPLAY in main */
103                 display2 = apt + disp2off;
104                 /* offset of variable mainprog */
105                 mnoff = 2;
106                 /* init variable main */
107                 storevirt(thisp->procref, mainprog + mnoff);
108                 /* flag main included in SL chain */
109                 M[apt + STATSL]++;
110                 thisp->status = STOPPED;
111                 /* activate main process */
112                 activate(thispix);
113         }
114         /* remote */
115         else {
116                 /* a dirty trick: set junk current */
117                 thispix = 0;
118                 /*  process for first transfer() */
119                 thisp =  &process[thispix];
120                 /* (must save 'context' somewhere) */
121         }
122 #if DLINK
123         net_attention();
124 #endif
125 }
126
127 /**
128  * Initialize process descriptor
129  */
130 void initprocess(word pix, word prot, procaddr *father)
131 {
132         procdescr *p;
133         protdescr *ptr;
134         word i, j, ah, am, apt;
135
136 #ifdef RPCDBG
137         fprintf(stderr, "new process(n,p,m) (%d,%d,%d)", 0, pix,
138                                                         process[pix].mark);
139         fprintf(stderr, " from (%d,%d,%d)\n", father->node, father->pix,
140                                                                 father->mark);
141 #endif
142
143         p = &process[pix];
144
145 #ifdef OBJECTADDR
146         hash_create(p, 119);
147 #endif
148         /* process descriptor is used */
149         p->used = TRUE;
150         /* prototype number */
151         p->prot = prot;
152         /* null list of free dictionary items */
153         p->freeitem = 0;
154         /* highest memory address */
155         p->upper = memorysize - 1;
156         /* lowest address for data */
157         p->lower = freem;
158         /* head of killed objects list */
159         p->headk = p->lower;
160         /* maximum appetite sentinel */
161         p->M[ p->headk ] = MAXAPPT;
162         p->headk2 = 0;
163         /* dict. item for process itself */
164         ah = p->upper - 1;
165         /* first word used by dictionary */
166         p->lastitem = ah;
167         ptr = prototype[prot];
168         if (p->upper - p->lower - ptr->appetite < 512)
169                 if (prot == MAINBLOCK)
170                         abend("Memory size too small (use /m option)\n");
171                 else errsignal(RTEMEMOV);
172
173     /* generate process object */
174         p->lastused = p->lower + ptr->appetite;
175         am = p->lower + 1;
176         p->M[am] = ptr->appetite;
177         p->M[am + PROTNUM] = prot;
178         for (i = PROTNUM + 1; i < ptr->appetite; i++)
179                 p->M[am + i] = 0;
180         p->M[ah] = am;
181         p->M[ah + 1] = 0;
182         p->prochead = am;
183         p->procref.addr = ah;
184         p->procref.mark = 0;
185         /* initialize current object ptrs */
186         p->c1 = am;
187         p->c2 = am + ptr->span;
188         apt = am + ptr->appetite;
189         /* initialize coroutine head ptr */
190         p->M[apt + CHD] = ah;
191         p->M[apt + CHD + 1] = 0;
192         /* dummy SL for process */
193         p->M[apt + SL] = DUMMY;
194         /* absolute none */
195         p->M[1] = 1;
196         /* initialize DISPLAY */
197         for (i = MAINBLOCK; i <= lastprot; i++) {
198                 /* dummmy entry for MAIN */
199                 p->M[apt + dispoff + i] = 0;
200         }
201         p->M[apt + disp2off + MAINBLOCK] = DUMMY;
202         /* set DISPLAY entries for process */
203         j = ptr->preflist;
204
205         for (i = j + ptr->lthpreflist - 1; i >= j; i--) {
206                 /* physical address */
207                 p->M[apt + dispoff + M[i]] = am;
208                 /* indirect address */
209                 p->M[apt + disp2off + M[i]] = ah;
210         }
211
212         {
213                 virtaddr v;
214                 mess2obj(p, father, &v);
215                 p->M[apt + DL] = v.addr;
216                 p->M[apt + DL + 1] = v.mark;
217         }
218         p->msgqueue = qinit();
219         p->rpcwait = qinit();
220         p->rpcmask = sinit();
221         /* initialy all RPCs are disabled */
222         pushmask(pix);
223         /* trace line number */
224         p->trlnumber = 0;
225         /* search for executable prefix */
226         i = ptr->preflist;
227         while (prototype[p->M[i]]->kind == RECORD)
228                 i++;
229
230         /* first instruction address */
231         p->ic = prototype[M[i]]->codeaddr;
232         p->force_compactification = FALSE;
233 }
234
235
236 /**
237  * 
238  */
239 bool member(virtaddr *virt, word *am)
240 {
241         *am = M[virt->addr];
242 /*
243         if (virt->mark == M[virt->addr + 1])
244                 fprintf(stderr, "Yes");
245         else {
246                 fprintf(stderr, "No");
247         }
248 */
249         return (virt->mark == M[virt->addr + 1]);
250 }
251
252 /**
253  * Update DISPLAY
254  */
255 void update(word am, word ah)
256 {
257         word t1, t2, t3, t4, t5, t6;
258         protdescr *ptr;
259
260         while (TRUE) {
261                 t1 = am + M[am];
262                 /* flag object included in SL */
263                 M[t1 + STATSL]++;
264                 ptr = prototype[M[am + PROTNUM]];
265                 t2 = ptr->preflist;
266                 t3 = t2 + ptr->lthpreflist - 1;
267                 for (t4 = t3; t4 >= t2; t4--) {
268                         t6 = M[t4];
269                         t5 = display + t6;
270                         /* entry to be updated */
271                         if (M[ t5 ] == 0) {
272                                 M[t5] = am;
273                                 M[display2 + t6] = ah;
274                         }
275                 }
276                 ah = M[t1 + SL];
277                 if (ah == DUMMY)
278                         break;
279
280                 if (M[ah + 1] != M[t1 + SL + 1])
281                         errsignal(RTESLCOF);
282
283                 am = M[ah];
284         }
285 }
286
287 /**
288  * Loosen DISPLAY
289  */
290 void loosen()
291 {
292         word t1, t2, t3;
293         protdescr *ptr;
294
295         t1 = c1;
296         while (TRUE) {
297                 ptr = prototype[M[t1 + PROTNUM]];
298                 t2 = ptr->preflist;
299                 for (t3 = t2 + ptr->lthpreflist - 1; t3 >= t2; t3--)
300                         M[display + M[t3]] = 0;
301                 t3 = t1 + M[t1];
302                 /* flag object removed from SL */
303                 M[t3 + STATSL]--;
304                 /* ah of SL */
305                 t1 = M[t3 + SL];
306                 /* still not main */
307                 if (t1 == DUMMY)
308                         break;
309                 /* am of SL */
310                 t1 = M[t1];
311         }
312 }
313
314 /**
315  * To count trace messages in line
316  */
317 static int tracecnt = 0;
318
319 /**
320  * Trace the program if debug mode
321  */
322 void trace(word lineno)
323 {
324         thisp->trlnumber = lineno;
325         if (debug && lineno > 0) {
326                 tracecnt++;
327                 /* change line */
328                 if (tracecnt == MAXTRACNT) {
329                         tracecnt = 0;
330                         fprintf(tracefile, "\n");
331                 }
332                 fprintf(tracefile, "%6ld", (long) lineno);
333         }
334         /* check for waiting message */
335         trapmsg();
336         /* check for RPC message */
337         rpc2();
338 }
339
340 /**
341  * 
342  */
343 void endrun(int status)
344 {
345         MESSAGE msg;
346         G_MESSAGE m;
347         int i;
348
349         if (debug)
350                 fclose(tracefile);
351
352         msg.msg_type = MSG_INT;
353         msg.param.pword[0] = INT_EXITING;
354         strcpy(msg.param.pstr, ProgName);
355         write(internal_sock, &msg, sizeof(MESSAGE));
356         m.msg_type = MSG_GRAPH;
357         m.param.pword[0] = GRAPH_FREE;
358         write(graph_sock, &m, sizeof(G_MESSAGE));
359         close(internal_sock);
360         close(graph_sock);
361         close(net_sock);
362         unlink(mygname);
363         unlink(mykname);
364         unlink(mynname);
365         for(i = 0; i < 255; i++)
366                 if (DirConn[i] != -1)
367                         close(DirConn[i]);
368         exit(status);
369 }
370
371