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