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