Added upstream from http://ftp.icm.edu.pl/pub/loglan/
[loglan.git] / sources / int / memory.c
1 #include        "depend.h"\r
2 #include        "genint.h"\r
3 #include        "int.h"\r
4 #include        "process.h"\r
5 #include        "intproto.h"\r
6 \r
7 /* Memory management routines */\r
8 \r
9 #ifndef NO_PROTOTYPES\r
10 static void compandtake(word, word *, word *, word *, bool);\r
11 static void sinsert(word);\r
12 #else\r
13 static void compandtake();\r
14 static void sinsert();\r
15 #endif\r
16 \r
17 \r
18 int compactify_allowed=1;\r
19 #define space 400 /* words */\r
20 \r
21 \r
22 void request(app, ah, am)\r
23 word app, *ah, *am;\r
24 {\r
25     word t2, t4, t5;\r
26     bool wascompactified, found;\r
27 \r
28     if (app >= MAXAPPT) errsignal(RTEMEMOV);\r
29     wascompactified = FALSE;\r
30 \r
31     if( compactify_allowed && thisp->force_compactification ){\r
32          compactify();\r
33          thisp->force_compactification=FALSE;\r
34          wascompactified=TRUE;\r
35     }\r
36 \r
37     if (thisp->freeitem != 0)           /* reserve dictionary item */\r
38     {\r
39         *ah = thisp->freeitem;\r
40         thisp->freeitem = M[ *ah ];\r
41     }\r
42     else\r
43     {\r
44         *ah = thisp->lastitem-2;\r
45         if (*ah <= thisp->lastused + space)     /* cannot take free item */\r
46         {\r
47             if( compactify_allowed )\r
48                 if( !wascompactified ) compactify(),wascompactified=TRUE;\r
49                 else ;\r
50             else\r
51                 thisp->force_compactification=TRUE;\r
52             *ah = thisp->lastitem-2;\r
53             if (*ah <= thisp->lastused) errsignal(RTEMEMOV);\r
54         }\r
55 \r
56         thisp->lastitem = *ah;\r
57         M[ *ah+1 ] = 0;                 /* clear mark */\r
58     }                                   /* now we have a free dict. item */\r
59 \r
60 \r
61     if (app == 2 && thisp->headk2 != 0)    /* special case app=2 */\r
62     {\r
63         *am = thisp->headk2;\r
64         thisp->headk2 = M[ *am+SHORTLINK ];\r
65     }\r
66     else\r
67     {\r
68         word t1 = thisp->headk;\r
69         found = FALSE;\r
70         t4 = 0;\r
71         while (t1 != thisp->lower && !found)\r
72         {\r
73             t2 = M[ t1 ];\r
74             if (t2 == app) found = TRUE;\r
75             else\r
76                 if (t2-app >= 2) found = TRUE;\r
77                 else\r
78                 {\r
79                     t4 = t1;\r
80                     t1 = M[ t1+LONGLINK ];\r
81                 }\r
82         }\r
83         if( found ) {\r
84             t5 = M[ t1+SHORTLINK ];\r
85             if (t5 != 0) M[ t5+LONGLINK ] = M[ t1+LONGLINK ];\r
86             else t5 = M[ t1+LONGLINK ];\r
87             if (t4 == 0) thisp->headk = t5;  else M[ t4+LONGLINK ] = t5;\r
88             *am = t1;\r
89             if (t2 > app)           /* at least two extra words */\r
90             {\r
91                 t5 = t1+app;\r
92                 M[ t5 ] = t2-app;\r
93                 sinsert(t5);\r
94             }\r
95         }\r
96         else\r
97         if ( thisp->lastitem - thisp->lastused > app + space )\r
98         {\r
99             *am = thisp->lastused+1;\r
100             thisp->lastused += app;\r
101         }\r
102         else\r
103         {\r
104             M[ *ah ] = thisp->freeitem;        /* return dictionary item */\r
105             thisp->freeitem = *ah;\r
106             if( compactify_allowed )\r
107                 if( !wascompactified ) compactify();\r
108                 else ;\r
109             else\r
110                 thisp->force_compactification=TRUE;\r
111             *ah = thisp->lastitem-2;           /* reserve dictionary item */\r
112             thisp->lastitem = *ah;\r
113             M[ *ah+1 ] = 0;                    /* clear mark */\r
114             if ( thisp->lastitem - thisp->lastused > app ) {\r
115                 *am = thisp->lastused+1;\r
116                 thisp->lastused += app;\r
117             }\r
118             else\r
119                 errsignal(RTEMEMOV);\r
120         }\r
121     }\r
122 \r
123     M[ *am ] = app;\r
124     for (t2 = *am+1;  t2 < *am+app;  t2++ ) M[ t2 ] = 0;\r
125     M[ *ah ] = *am;\r
126 \r
127 }\r
128 \r
129 \r
130 static void sinsert(am)                        /* Dispose of a memory item. */\r
131 word am;\r
132 {\r
133     word t1, t2, t3, t4;\r
134 \r
135     t1 = M[ am ];                       /* appetite */\r
136     if (t1 == 2)                        /* a special list should be used */\r
137     {\r
138         M[ am+SHORTLINK ] = thisp->headk2;\r
139         thisp->headk2 = am;\r
140     }\r
141     else\r
142     {\r
143         t2 = thisp->headk;\r
144         t4 = 0;\r
145         while (TRUE)                    /* look for a proper place */\r
146         {\r
147             t3 = M[ t2 ];               /* appetite */\r
148             if (t1 == t3)               /* an entry with matching appetite */\r
149             {\r
150                 M[ am+SHORTLINK ] = M[ t2+SHORTLINK ];\r
151                 M[ t2+SHORTLINK ] = am;\r
152                 break;\r
153             }\r
154             else\r
155                 if (t1 < t3)\r
156                 {\r
157                     M[ am+LONGLINK ] = t2;\r
158                     M[ am+SHORTLINK ] = 0;\r
159                     if (t4 == 0) thisp->headk = am;\r
160                     else M[ t4+LONGLINK ] = am;\r
161                     break;\r
162                 }\r
163                 else\r
164                 {\r
165                     t4 = t2;\r
166                     t2 = M[ t2+LONGLINK ];\r
167                 }\r
168         }\r
169     }\r
170 }\r
171 \r
172 \r
173 void disp(virt)                         /* Simple kill. */\r
174 virtaddr *virt;\r
175 {\r
176     word t1, t2;\r
177 \r
178     t1 = M[ virt->addr+1 ];\r
179     if (t1 == virt->mark)               /* not none */\r
180     {\r
181         t1++;                           /* advance mark */\r
182         t2 = M[ virt->addr ];           /* am */\r
183         M[ virt->addr+1 ] = t1;\r
184         if (t1 != MAXMARKER)            /* mark still usable */\r
185         {\r
186             M[ virt->addr ] = thisp->freeitem;\r
187             thisp->freeitem = virt->addr;\r
188         }                               /* now dictionary item is released */\r
189         if (t2+M[ t2 ]-1 == thisp->lastused)   /* on the boundary */\r
190             thisp->lastused = t2-1;\r
191         else sinsert(t2);\r
192     }\r
193 } /* end disp */\r
194 \r
195 \r
196 word memavail()                         /* Compute available memory size */\r
197 {\r
198     word t1, t2, avail;\r
199 \r
200     avail = thisp->lastitem-thisp->lastused-1;  /* contiguos memory */\r
201     t1 = thisp->headk2;                 /* go through killed 2 list */\r
202     while (t1 != 0)\r
203     {\r
204         avail += 2;\r
205         t1 = M[ t1+SHORTLINK ];\r
206     }\r
207     t1 = thisp->headk;\r
208     while (t1 != thisp->lower)          /* go through killed object list */\r
209     {\r
210         t2 = t1;\r
211         while (t2 != 0)\r
212         {\r
213             avail += M[ t2 ];\r
214             t2 = M[ t2+SHORTLINK ];\r
215         }\r
216         t1 = M[ t1+LONGLINK ];\r
217     }\r
218     t1 = thisp->freeitem;               /* go through free item list */\r
219     while (t1 != 0)\r
220     {\r
221         avail += 2;\r
222         t1 = M[ t1 ];\r
223     }\r
224     return(avail);\r
225 } /* end memavail */\r