Home My Page Projects Code Snippets Project Openings SML/NJ
Summary Activity Forums Tracker Lists Tasks Docs Surveys News SCM Files

SCM Repository

[smlnj] Annotation of /sml/trunk/src/runtime/gc/mp-gc.c
ViewVC logotype

Annotation of /sml/trunk/src/runtime/gc/mp-gc.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 651 - (view) (download) (as text)

1 : monnier 249 /* mp-gc.c
2 :     *
3 :     * COPYRIGHT (c) 1994 by AT&T Bell Laboratories.
4 :     *
5 :     * Extra routines to support GC in the MP implementation.
6 :     *
7 :     */
8 :    
9 :     #include <sys/time.h>
10 :     #include <stdarg.h>
11 :     #include "ml-base.h"
12 :     #include "ml-limits.h"
13 :     #include "memory.h"
14 :     #include "ml-state.h"
15 :     #include "ml-values.h"
16 :     #include "ml-objects.h"
17 :     #include "cntr.h"
18 :     #include "heap.h"
19 :     #include "heap-monitor.h"
20 :     #include "ml-globals.h"
21 :     #include "ml-timer.h"
22 :     #include "gc-stats.h"
23 :     #include "ml-mp.h"
24 :     #include "vproc-state.h"
25 :    
26 :     /* MP_SUPPORT */
27 :    
28 :     /* PartitionAllocArena:
29 :     *
30 :     * Divide this allocation arena into smaller disjoint arenas for
31 :     * use by the parallel processors.
32 :     */
33 :     void PartitionAllocArena (vproc_state_t *vsps[])
34 :     {
35 :     int indivSz;
36 :     ml_val_t *aBase;
37 :     int i;
38 :     int pollFreq = INT_MLtoC(DEREF(PollFreq));
39 :     ml_state_t *msp, *msp0;
40 :    
41 :     msp0 = vsps[0]->vp_state;
42 :     indivSz = msp0->ml_heap->allocSzB / MAX_NUM_PROCS;
43 :     aBase = msp0->ml_heap->allocBase;
44 :     for (i = 0; i < MAX_NUM_PROCS; i++) {
45 :     msp = vsps[i]->vp_state;
46 :     #ifdef MP_DEBUG
47 :     SayDebug ("vsps[%d]->vp_state-> (ml_allocPtr %x/ml_limitPtr %x) changed to ",
48 :     i, msp->ml_allocPtr, msp->ml_limitPtr);
49 :     #endif
50 :     msp->ml_heap = msp0->ml_heap;
51 :     msp->ml_allocPtr = aBase;
52 :     msp->ml_realLimit = HEAP_LIMIT_SIZE(aBase, indivSz);
53 :    
54 :     #ifdef MP_GCPOLL
55 :     if (pollFreq > 0) {
56 :     #ifdef MP_DEBUG
57 :     SayDebug ("(with PollFreq=%d) ", pollFreq);
58 :     #endif
59 :     msp->ml_limitPtr = aBase + pollFreq*POLL_GRAIN_CPSI;
60 :     msp->ml_limitPtr =
61 :     (msp->ml_limitPtr > msp->ml_realLimit)
62 :     ? msp->ml_realLimit
63 :     : msp->ml_limitPtr;
64 :    
65 :     }
66 :     else {
67 :     msp->ml_limitPtr = msp->ml_realLimit;
68 :     }
69 :     #else
70 :     msp->ml_limitPtr = HEAP_LIMIT_SIZE(aBase,indivSz);
71 :     #endif
72 :    
73 :     #ifdef MP_DEBUG
74 :     SayDebug ("%x/%x\n",msp->ml_allocPtr, msp->ml_limitPtr);
75 :     #endif
76 :     aBase = (ml_val_t *) (((Addr_t) aBase) + indivSz);
77 :     }
78 :    
79 :     } /* end of PartitionAllocArena */
80 :    
81 :    
82 :     PVT volatile int MP_RdyForGC = 0; /* the number of processors that are */
83 :     /* ready for the GC. */
84 :     PVT int MPCollectorProc; /* the processor that does the GC */
85 :    
86 :     /* extra roots provided by InvokeGCWithRoots go here */
87 :     ml_val_t *mpExtraRoots[NUM_EXTRA_ROOTS*MAX_NUM_PROCS];
88 :     PVT ml_val_t **mpExtraRootsPtr;
89 :    
90 :     /* MP_StartCollect:
91 :     *
92 :     * Waits for all procs to check in and chooses one to do the
93 :     * collect (MPCollectorProc). MPCollectorProc returns to the invoking
94 :     * collection function and does the collect while the other procs
95 :     * wait at a barrier. MPCollectorProc will eventually check into this
96 :     * barrier releasing the waiting procs.
97 :     */
98 :     int MP_StartCollect (ml_state_t *msp)
99 :     {
100 :     int nProcs;
101 :     vproc_state_t *vsp = msp->ml_vproc;
102 :    
103 :     MP_SetLock(MP_GCLock);
104 :     if (MP_RdyForGC++ == 0) {
105 :     mpExtraRoots[0] = NIL(ml_val_t *);
106 :     mpExtraRootsPtr = mpExtraRoots;
107 :     #ifdef MP_GCPOLL
108 :     ASSIGN(PollEvent, ML_true);
109 :     #ifdef MP_DEBUG
110 :     SayDebug ("%d: set poll event\n", msp->ml_mpSelf);
111 :     #endif
112 :     #endif
113 :     /* we're the first one in, we'll do the collect */
114 :     MPCollectorProc = vsp->vp_mpSelf;
115 :     #ifdef MP_DEBUG
116 :     SayDebug ("MPCollectorProc is %d\n",MPCollectorProc);
117 :     #endif
118 :     }
119 :     MP_UnsetLock(MP_GCLock);
120 :    
121 :     {
122 :     #ifdef MP_DEBUG
123 :     int n = 0;
124 :     #endif
125 :     /* nb: some other proc can be concurrently acquiring new processes */
126 :     while (MP_RdyForGC != (nProcs = MP_ActiveProcs())) {
127 :     /* spin */
128 :     #ifdef MP_DEBUG
129 :     if (n == 10000000) {
130 :     n = 0;
131 :     SayDebug ("%d spinning %d <> %d <alloc=0x%x, limit=0x%x>\n",
132 :     msp->ml_mpSelf, MP_RdyForGC, nProcs, msp->ml_allocPtr,
133 :     msp->ml_limitPtr);
134 :     }
135 :     else
136 :     n++;
137 :     #endif
138 :     }
139 :     }
140 :    
141 :     /* Here, all of the processors are ready to do GC */
142 :    
143 :     #ifdef MP_GCPOLL
144 :     ASSIGN(PollEvent, ML_false);
145 :     #ifdef MP_DEBUG
146 :     SayDebug ("%d: cleared poll event\n", msp->ml_mpSelf);
147 :     #endif
148 :     #endif
149 :     #ifdef MP_DEBUG
150 :     SayDebug ("(%d) all %d/%d procs in\n", msp->ml_mpSelf, MP_RdyForGC, MP_ActiveProcs());
151 :     #endif
152 :     if (MPCollectorProc != vsp->vp_mpSelf) {
153 :     #ifdef MP_DEBUG
154 :     SayDebug ("%d entering barrier %d\n",vsp->vp_mpSelf,nProcs);
155 :     #endif
156 :     MP_Barrier(MP_GCBarrier, nProcs);
157 :    
158 :     #ifdef MP_DEBUG
159 :     SayDebug ("%d left barrier\n", vsp->vp_mpSelf);
160 :     #endif
161 :     return 0;
162 :     }
163 :    
164 :     return nProcs;
165 :    
166 :     } /* end of MP_StartCollect */
167 :    
168 :    
169 :     /* MP_StartCollectWithRoots:
170 :     *
171 :     * as above, but collects extra roots into mpExtraRoots
172 :     */
173 :     int MP_StartCollectWithRoots (ml_state_t *msp, va_list ap)
174 :     {
175 :     int nProcs;
176 :     ml_val_t *p;
177 :     vproc_state_t *vsp = msp->ml_vproc;
178 :    
179 :     MP_SetLock(MP_GCLock);
180 :     if (MP_RdyForGC++ == 0) {
181 :     mpExtraRootsPtr = mpExtraRoots;
182 :     #ifdef MP_GCPOLL
183 :     ASSIGN(PollEvent, ML_true);
184 :     #ifdef MP_DEBUG
185 :     SayDebug ("%d: set poll event\n", vsp->vp_mpSelf);
186 :     #endif
187 :     #endif
188 :     /* we're the first one in, we'll do the collect */
189 :     MPCollectorProc = vsp->vp_mpSelf;
190 :     #ifdef MP_DEBUG
191 :     SayDebug ("MPCollectorProc is %d\n",MPCollectorProc);
192 :     #endif
193 :     }
194 :     while ((p = va_arg(ap, ml_val_t *)) != NIL(ml_val_t *)) {
195 :     *mpExtraRootsPtr++ = p;
196 :     }
197 :     *mpExtraRootsPtr = p; /* NIL(ml_val_t *) */
198 :     MP_UnsetLock(MP_GCLock);
199 :    
200 :     {
201 :     #ifdef MP_DEBUG
202 :     int n = 0;
203 :     #endif
204 :     /* nb: some other proc can be concurrently acquiring new processes */
205 :     while (MP_RdyForGC != (nProcs = MP_ActiveProcs())) {
206 :     /* spin */
207 :     #ifdef MP_DEBUG
208 :     if (n == 10000000) {
209 :     n = 0;
210 :     SayDebug ("%d spinning %d <> %d <alloc=0x%x, limit=0x%x>\n",
211 :     vsp->vp_mpSelf, MP_RdyForGC, nProcs, msp->ml_allocPtr,
212 :     msp->ml_limitPtr);
213 :     }
214 :     else
215 :     n++;
216 :     #endif
217 :     }
218 :     }
219 :    
220 :     /* Here, all of the processors are ready to do GC */
221 :    
222 :     #ifdef MP_GCPOLL
223 :     ASSIGN(PollEvent, ML_false);
224 :     #ifdef MP_DEBUG
225 :     SayDebug ("%d: cleared poll event\n", msp->ml_mpSelf);
226 :     #endif
227 :     #endif
228 :     #ifdef MP_DEBUG
229 :     SayDebug ("(%d) all %d/%d procs in\n", msp->ml_vproc->vp_mpSelf, MP_RdyForGC, MP_ActiveProcs());
230 :     #endif
231 :     if (MPCollectorProc != vsp->vp_mpSelf) {
232 :     #ifdef MP_DEBUG
233 :     SayDebug ("%d entering barrier %d\n", vsp->vp_mpSelf, nProcs);
234 :     #endif
235 :     MP_Barrier(MP_GCBarrier, nProcs);
236 :    
237 :     #ifdef MP_DEBUG
238 :     SayDebug ("%d left barrier\n", vsp->vp_mpSelf);
239 :     #endif
240 :     return 0;
241 :     }
242 :    
243 :     return nProcs;
244 :    
245 :     } /* end of MP_StartCollectWithRoots */
246 :    
247 :    
248 :     /* MP_FinishCollect:
249 :     */
250 :     void MP_FinishCollect (ml_state_t *msp, int n)
251 :     {
252 :     /* this works, but PartitionAllocArena is overkill */
253 :     PartitionAllocArena(VProc);
254 :     MP_SetLock(MP_GCLock);
255 :     #ifdef MP_DEBUG
256 :     SayDebug ("%d entering barrier %d\n", msp->ml_vproc->vp_mpSelf,n);
257 :     #endif
258 :     MP_Barrier(MP_GCBarrier,n);
259 :     MP_RdyForGC = 0;
260 :    
261 :     #ifdef MP_DEBUG
262 :     SayDebug ("%d left barrier\n", msp->ml_vproc->vp_mpSelf);
263 :     #endif
264 :     MP_UnsetLock(MP_GCLock);
265 :    
266 :     } /* end of MP_FinishCollect */
267 :    

root@smlnj-gforge.cs.uchicago.edu
ViewVC Help
Powered by ViewVC 1.0.0