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