File: GCSI.c

package info (click to toggle)
qepcad 1.74%2Bds-5
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 4,848 kB
  • sloc: ansic: 27,242; cpp: 2,995; makefile: 1,287; perl: 91
file content (128 lines) | stat: -rw-r--r-- 3,435 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/*======================================================================
                      GCSI(s,EACSTACK)

Garbage collection, system independent.

Inputs
         s : a BETA-digit, the size in bytes at which data is aligned on the
             stack.
  EACSTACK : a C pointer, the address of the last element on the stack.

Side effects
  Active variables are marked. Then a new available cell list is formed
  from the unmarked cells and the marks are removed.
  If GCM=1 a report is written out. If the number of reclaimed cells
  is no more than NU / RHO  then a message is written and a failure
  occurs.
======================================================================*/
#include "replacesac.h"
#include <cstdio>
extern "C" {
extern void gcw_MARK();
}

void GCSI(Word s, char *EACSTACK)
{
       Word I,L,N,N1,Np,Np1,T,T1,c,inc;
       char *a;
       /* hide I,L,N,N1,Np,Np1,T,T1,c,inc,a; */

Step1: /* Setup. */
	  if (GCM == 1) {
         SWRITE("\nThe "); GWRITE(GCC+1); 
         SWRITE("--th garbage collection....\n");
       }
       T1 = CLOCK();

Step3: /* Mark the global variables. */
       L = GCGLOBALS; 
       while (L != NIL) {
         c = *((Word *)PTRFIRST(L));
	 if ((ISLIST(c) || ISGCA(c)) && !ISNIL(c))  MARK(c);
	 L = PTRRED(L);
       }

Step2: /* Mark the cells in the GCGLOBALS list. */
       L = GCGLOBALS; 
       while (L != NIL) {
	 I = RED(L);
	 SRED(L,-I);
	 L = I;
       }

Step3b: /* Mark the GCWord variables. */
       gcw_MARK();

Step4: /* Mark the cells accessible from the system stack. */
       if (((BACSTACK - EACSTACK) % s) != 0)
         FAIL("GCSI (marking stack)","Alignment error",BACSTACK,EACSTACK);
       if (EACSTACK > BACSTACK)
         inc = s;
       else
         inc = -s;
       for (a = BACSTACK; a != EACSTACK; a += inc) {
         c =  *((Word *) a);
	 if ((ISLIST(c) || ISGCA(c)) && !ISNIL(c))  MARK(c);
       }

Step5: /* Unmark the cells in the AVAIL and GCAAVAIL lists. */
       for (L=AVAIL,N1=0; L!=NIL; L=RED(L),N1++)
	 if (RED(L) <= -BETA)  
           SRED(L,-RED(L)); 
       for (L=GCAAVAIL,Np1=0; L!=NIL; L=GCASPACEBp[L].next,Np1++)
	 if (GCASPACEBp[L].next <= -BETA)
	   GCASPACEBp[L].next = -GCASPACEBp[L].next;

Step6: /* Reclaim unmarked cells */
       AVAIL = NIL;
       N = 0;
       for (L = BETA+NU-1; L > BETA; L -= 2) {
         if (RED(L) > 0) {
           SRED(L,AVAIL);
	   SFIRST(L,0);
           AVAIL = L;
           N++;
         }
         else
           SRED(L,-RED(L));
       }
       GCAAVAIL = NIL;
       Np = 0;
       for (I = BETApp-1; I > BETAp; I--) {
         if (GCASPACEBp[I].next > 0) {
           GCAFREE(I);
           Np++;
         }
         else
           GCASPACEBp[I].next = -GCASPACEBp[I].next;
       }

Step7: /* Increment counters. */
       T = CLOCK() - T1;
       TAU = TAU + T;
       GCC = GCC + 1;
       GCCC = GCCC + N - N1;
       GCAC = GCAC + Np - Np1;
  
Step8: /* Optional report. */
       if (GCM == 1 || N <= NU / RHO) {
         SWRITE("\n** ");
         GWRITE(N); SWRITE(" cells, ");
         GWRITE(Np); SWRITE(" arrays in ");
         GWRITE(T); SWRITE(" milliseconds.\n");
       }

Step9: /* Too few cells or arrays? */
       if (N <= NU / RHO)
         FAIL("GCSI (final check)","Too few cells reclaimed.",N,NU,RHO);
       if (Np == 0)
         FAIL("GCSI (final check)","No arrays reclaimed.",N,NU,RHO);

Return: /* Prepare for return. */
       return;
}