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