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