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/mp/sgi-mp.c
ViewVC logotype

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

Parent Directory Parent Directory | Revision Log Revision Log


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

1 : monnier 2 /* sgi-mp.c
2 :     *
3 :     * COPYRIGHT (c) 1994 AT&T Bell Laboratories.
4 :     *
5 :     * MP support for SGI Challenge machines (Irix 5.x).
6 :     */
7 :    
8 :     #include <sys/types.h>
9 :     #include <sys/prctl.h>
10 :     #include <unistd.h>
11 :     #include <ulocks.h>
12 :     #include "ml-base.h"
13 :     #include "ml-limits.h"
14 :     #include "ml-values.h"
15 :     #include "ml-objects.h"
16 :     #include "tags.h"
17 :     #include "ml-mp.h"
18 :     #include "ml-state.h"
19 :     #include "ml-globals.h"
20 :     #include "vproc-state.h"
21 :    
22 :     /* #define ARENA_FNAME tmpnam(0) */
23 :     #define ARENA_FNAME "/tmp/sml-mp.lock-arena"
24 :    
25 :     #define INT_MLinc(n,i) ((ml_val_t)INT_CtoML(INT_MLtoC(n) + (i)))
26 :     #define INT_MLdec(n,i) (INT_MLinc(n,(-i)))
27 :    
28 :     /* forwards */
29 :     PVT mp_lock_t AllocLock ();
30 :     PVT mp_barrier_t *AllocBarrier();
31 :    
32 :     /* locals */
33 :     PVT usptr_t *arena; /* arena for shared sync objects */
34 :     PVT ulock_t MP_ArenaLock; /* must be held to alloc/free a lock */
35 :     PVT ulock_t MP_ProcLock; /* must be held to acquire/release procs */
36 :    
37 :     /* globals */
38 :     mp_lock_t MP_GCLock;
39 :     mp_lock_t MP_GCGenLock;
40 :     mp_barrier_t *MP_GCBarrier;
41 :     mp_lock_t MP_TimerLock;
42 :    
43 :    
44 :     /* MP_Init:
45 :     */
46 :     void MP_Init ()
47 :     {
48 :     /* set '_utrace = 1;' to debug shared arenas */
49 :     if (usconfig(CONF_LOCKTYPE, US_NODEBUG) == -1) {
50 :     Die ("usconfig failed in MP_Init");
51 :     }
52 :     usconfig(CONF_AUTOGROW, 0);
53 :     if (usconfig(CONF_INITSIZE, 65536) == -1) {
54 :     Die ("usconfig failed in MP_Init");
55 :     }
56 :     if ((arena = usinit(ARENA_FNAME)) == NIL(usptr_t *)) {
57 :     Die ("usinit failed in MP_Init");
58 :     }
59 :    
60 :     MP_ArenaLock = AllocLock();
61 :     MP_ProcLock = AllocLock();
62 :     MP_GCLock = AllocLock();
63 :     MP_GCGenLock = AllocLock();
64 :     MP_TimerLock = AllocLock();
65 :     MP_GCBarrier = AllocBarrier();
66 :     ASSIGN(ActiveProcs, INT_CtoML(1));
67 :    
68 :     } /* end of MP_Init */
69 :    
70 :    
71 :     /* MP_ProcId:
72 :     */
73 :     mp_pid_t MP_ProcId ()
74 :     {
75 :    
76 :     return getpid ();
77 :    
78 :     } /* end of MP_ProcId */
79 :    
80 :    
81 :     /* AllocLock:
82 :     *
83 :     * Allocate and initialize a system lock.
84 :     */
85 :     PVT mp_lock_t AllocLock ()
86 :     {
87 :     ulock_t lock;
88 :    
89 :     if ((lock = usnewlock(arena)) == NIL(ulock_t)) {
90 :     Die ("AllocLock: cannot get lock with usnewlock\n");
91 :     }
92 :     usinitlock(lock);
93 :     usunsetlock(lock);
94 :    
95 :     return lock;
96 :    
97 :     } /* end of AllocLock */
98 :    
99 :    
100 :     /* MP_SetLock:
101 :     */
102 :     void MP_SetLock (mp_lock_t lock)
103 :     {
104 :     ussetlock(lock);
105 :    
106 :     } /* end of MP_SetLock */
107 :    
108 :    
109 :     /* MP_UnsetLock:
110 :     */
111 :     void MP_UnsetLock (mp_lock_t lock)
112 :     {
113 :     usunsetlock(lock);
114 :    
115 :     } /* end of MP_UnsetLock */
116 :    
117 :    
118 :     /* MP_TryLock:
119 :     */
120 :     bool_t MP_TryLock (mp_lock_t lock)
121 :     {
122 :     return ((bool_t) uscsetlock(lock, 1)); /* try once */
123 :    
124 :     } /* end of MP_TryLock */
125 :    
126 :    
127 :     /* MP_AllocLock:
128 :     */
129 :     mp_lock_t MP_AllocLock ()
130 :     {
131 :     ulock_t lock;
132 :    
133 :     ussetlock(MP_ArenaLock);
134 :     lock = AllocLock ();
135 :     usunsetlock(MP_ArenaLock);
136 :    
137 :     return lock;
138 :    
139 :     } /* end of MP_AllocLock */
140 :    
141 :    
142 :     /* MP_FreeLock:
143 :     */
144 :     void MP_FreeLock (mp_lock_t lock)
145 :     {
146 :     ussetlock(MP_ArenaLock);
147 :     usfreelock(lock,arena);
148 :     usunsetlock(MP_ArenaLock);
149 :    
150 :     } /* end of MP_FreeLock */
151 :    
152 :    
153 :     /* AllocBarrier:
154 :     *
155 :     * Allocate and initialize a system barrier.
156 :     */
157 :     PVT mp_barrier_t *AllocBarrier ()
158 :     {
159 :     barrier_t *barrierp;
160 :    
161 :     if ((barrierp = new_barrier(arena)) == NIL(barrier_t *)) {
162 :     Die ("cannot get barrier with new_barrier");
163 :     }
164 :     init_barrier(barrierp);
165 :    
166 :     return barrierp;
167 :    
168 :     } /* end of AllocBarrier */
169 :    
170 :     /* MP_AllocBarrier:
171 :     */
172 :     mp_barrier_t *MP_AllocBarrier ()
173 :     {
174 :     barrier_t *barrierp;
175 :    
176 :     ussetlock(MP_ArenaLock);
177 :     barrierp = AllocBarrier ();
178 :     usunsetlock(MP_ArenaLock);
179 :    
180 :     return barrierp;
181 :    
182 :     } /* end of MP_AllocBarrier */
183 :    
184 :     /* MP_FreeBarrier:
185 :     */
186 :     void MP_FreeBarrier (mp_barrier_t *barrierp)
187 :     {
188 :     ussetlock(MP_ArenaLock);
189 :     free_barrier(barrierp);
190 :     usunsetlock(MP_ArenaLock);
191 :    
192 :     } /* end of MP_FreeBarrier */
193 :    
194 :     /* MP_Barrier:
195 :     */
196 :     void MP_Barrier (mp_barrier_t *barrierp, unsigned n)
197 :     {
198 :     barrier(barrierp, n);
199 :    
200 :     } /* end of MP_Barrier */
201 :    
202 :     /* MP_ResetBarrier:
203 :     */
204 :     void MP_ResetBarrier (mp_barrier_t *barrierp)
205 :     {
206 :     init_barrier(barrierp);
207 :    
208 :     } /* end of MP_ResetBarrier */
209 :    
210 :     /* ??? */
211 :     PVT void fixPnum (int n)
212 :     {
213 :     /* dummy for now */
214 :     }
215 :    
216 :    
217 :     /* MP_MaxProcs:
218 :     */
219 :     int MP_MaxProcs ()
220 :     {
221 :     return MAX_NUM_PROCS;
222 :    
223 :     } /* end of MP_MaxProcs */
224 :    
225 :    
226 :     /* ProcMain:
227 :     */
228 :     PVT void ProcMain (void *vmsp)
229 :     {
230 :     ml_state_t *msp = (ml_state_t *) vmsp;
231 :    
232 :     /* needs to be done
233 :     fixPnum(msp->pnum);
234 :     setup_signals(msp, TRUE);
235 :     */
236 :     /* spin until we get our id (from return of call to NewProc) */
237 :     while (msp->ml_vproc->vp_mpSelf == NIL(mp_pid_t)) {
238 :     #ifdef MP_DEBUG
239 :     SayDebug("[waiting for self]\n");
240 :     #endif
241 :     continue;
242 :     }
243 :     #ifdef MP_DEBUG
244 :     SayDebug ("[new proc main: releasing lock]\n");
245 :     #endif
246 :     MP_UnsetLock (MP_ProcLock); /* implicitly handed to us by the parent */
247 :     RunML (msp); /* should never return */
248 :     Die ("proc returned after run_ml() in ProcMain().\n");
249 :    
250 :     } /* end of ProcMain */
251 :    
252 :    
253 :     /* NewProc:
254 :     */
255 :     PVT int NewProc (ml_state_t *state)
256 :     {
257 :     int ret, error;
258 :    
259 :     ret = sproc(ProcMain, PR_SALL, (void *)state);
260 :     if (ret == -1) {
261 :     extern int errno;
262 :    
263 :     error = oserror(); /* this is potentially a problem since */
264 :     /* each thread should have its own errno. */
265 :     /* see sgi man pages for sproc */
266 :     Error ("error=%d,errno=%d\n", error, errno);
267 :     Error ("[warning NewProc: %s]\n",strerror(error));
268 :     }
269 :    
270 :     return ret;
271 :     }
272 :    
273 :    
274 :     /* MP_AcquireProc:
275 :     */
276 :     ml_val_t MP_AcquireProc (ml_state_t *msp, ml_val_t arg)
277 :     {
278 :     ml_state_t *p;
279 :     vproc_state_t *vsp;
280 :     ml_val_t v = REC_SEL(arg, 0);
281 :     ml_val_t f = REC_SEL(arg, 1);
282 :     int i;
283 :    
284 :     #ifdef MP_DEBUG
285 :     SayDebug("[acquiring proc]\n");
286 :     #endif
287 :     MP_SetLock(MP_ProcLock);
288 :     /* search for a suspended proc to reuse */
289 :     for (i = 0;
290 :     (i < NumVProcs) && (VProc[i]->vp_mpState != MP_PROC_SUSPENDED);
291 :     i++
292 :     )
293 :     continue;
294 :     #ifdef MP_DEBUG
295 :     SayDebug("[checking for suspended processor]\n");
296 :     #endif
297 :     if (i == NumVProcs) {
298 :     if (DEREF(ActiveProcs) == INT_CtoML(MAX_NUM_PROCS)) {
299 :     MP_UnsetLock(MP_ProcLock);
300 :     Error("[processors maxed]\n");
301 :     return ML_false;
302 :     }
303 :     #ifdef MP_DEBUG
304 :     SayDebug("[checking for NO_PROC]\n");
305 :     #endif
306 :     /* search for a slot in which to put a new proc */
307 :     for (i = 0;
308 :     (i < NumVProcs) && (VProc[i]->vp_mpState != MP_PROC_NO_PROC);
309 :     i++
310 :     )
311 :     continue;
312 :     if (i == NumVProcs) {
313 :     MP_UnsetLock(MP_ProcLock);
314 :     Error("[no processor to allocate]\n");
315 :     return ML_false;
316 :     }
317 :     }
318 :     #ifdef MP_DEBUG
319 :     SayDebug("[using processor at index %d]\n", i);
320 :     #endif
321 :     /* use processor at index i */
322 :     vsp = VProc[i];
323 :     p = vsp->vp_state;
324 :    
325 :     p->ml_exnCont = PTR_CtoML(handle_v+1);
326 :     p->ml_arg = ML_unit;
327 :     p->ml_cont = PTR_CtoML(return_c);
328 :     p->ml_closure = f;
329 :     p->ml_pc =
330 :     p->ml_linkReg = GET_CODE_ADDR(f);
331 :     p->ml_varReg = v;
332 :    
333 :     if (vsp->vp_mpState == MP_PROC_NO_PROC) {
334 :     /* assume we get one */
335 :     ASSIGN(ActiveProcs, INT_MLinc(DEREF(ActiveProcs), 1));
336 :     if ((vsp->vp_mpSelf = NewProc(p)) != -1) {
337 :     #ifdef MP_DEBUG
338 :     SayDebug ("[got a processor]\n");
339 :     #endif
340 :     vsp->vp_mpState = MP_PROC_RUNNING;
341 :     /* NewProc will release MP_ProcLock */
342 :     return ML_true;
343 :     }
344 :     else {
345 :     ASSIGN(ActiveProcs, INT_MLdec(DEREF(ActiveProcs), 1));
346 :     MP_UnsetLock(MP_ProcLock);
347 :     return ML_false;
348 :     }
349 :     }
350 :     else {
351 :     vsp->vp_mpState = MP_PROC_RUNNING;
352 :     #ifdef MP_DEBUG
353 :     SayDebug ("[reusing a processor]\n");
354 :     #endif
355 :     MP_UnsetLock(MP_ProcLock);
356 :     return ML_true;
357 :     }
358 :    
359 :     } /* end of MP_AcquireProc */
360 :    
361 :     /* MP_ReleaseProc:
362 :     */
363 :     void MP_ReleaseProc (ml_state_t *msp)
364 :     {
365 :     #ifdef MP_DEBUG
366 :     SayDebug("[release_proc: suspending]\n");
367 :     #endif
368 :     InvokeGC(msp,1);
369 :     MP_SetLock(MP_ProcLock);
370 :     msp->ml_vproc->vp_mpState = MP_PROC_SUSPENDED;
371 :     MP_UnsetLock(MP_ProcLock);
372 :     while (msp->ml_vproc->vp_mpState == MP_PROC_SUSPENDED) {
373 :     /* need to be continually available for gc */
374 :     InvokeGC(msp,1);
375 :     }
376 :     #ifdef MP_DEBUG
377 :     SayDebug("[release_proc: resuming]\n");
378 :     #endif
379 :     RunML(msp);
380 :     Die ("return after RunML(msp) in mp_release_proc\n");
381 :    
382 :     } /* end of MP_ReleaseProc */
383 :    
384 :    
385 :     /* MP_ActiveProcs:
386 :     */
387 :     int MP_ActiveProcs ()
388 :     {
389 :     int ap;
390 :    
391 :     MP_SetLock(MP_ProcLock);
392 :     ap = INT_MLtoC(DEREF(ActiveProcs));
393 :     MP_UnsetLock(MP_ProcLock);
394 :    
395 :     return ap;
396 :    
397 :     } /* end of MP_ActiveProcs */
398 :    
399 :    
400 :     /* MP_Shutdown:
401 :     */
402 :     void MP_Shutdown ()
403 :     {
404 :     usdetach(arena);
405 :    
406 :     } /* end of MP_Shutdown */
407 :    

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