Copyright (C) 1994, Digital Equipment Corp. UNSAFE MODULE--------------------------------------------------- process termination ---; IMPORT Unix, Uuio, Cstdlib, RT0u; RTOS
PROCEDURE------------------------------------------------------------- allocator ---Exit (n: INTEGER) = BEGIN Unix.exit (n); END Exit; PROCEDURECrash () = BEGIN Cstdlib.abort (); LOOP END; (* wait *) END Crash;
PROCEDURE------------------------------------------------------------- collector --- These procedures provide synchronization primitives for the allocator and collector. This is the Ultrix version, and depends on the Ultrix user-level thread implementation.GetMemory (size: INTEGER): ADDRESS = (* Return the address of "size" bytes of unused storage *) BEGIN RETURN LOOPHOLE(Unix.sbrk(size), ADDRESS); END GetMemory;
LockHeap() enters a critical section; the same thread may enter the critical section multiple times. It could be written at user level as:
VAR mutex : MUTEX := NEW(MUTEX); condition: Thread.Condition := NEW(Thread.Condition); thread : Thread.T := NIL; count : CARDINAL := 0;
PROCEDURE LockHeap () = BEGIN LOCK mutex DO IF count = 0 THEN thread := Thread.Self(); INC(count); ELSIF thread = Thread.Self() THEN INC(count); ELSE Thread.Wait(mutex, condition); END; END; END LockHeap;However, it must be possible to call it from anywhere in the collector.
PROCEDUREUnlockHeap() leaves the critical section. It could be written at user level as:LockHeap () = BEGIN INC(RT0u.inCritical); END LockHeap;
PROCEDURE UnlockHeap () = BEGIN LOCK mutex DO DEC(count); END; IF count = 0 THEN Thread.Signal(condition); END; END UnlockHeap;However, it must be possible to call it from anywhere inside the collector.
PROCEDURE------------------------------------------------------------------- I/O ---UnlockHeap () = BEGIN DEC(RT0u.inCritical); END UnlockHeap;
PROCEDUREWrite (a: ADDRESS; n: INTEGER) = BEGIN EVAL Uuio.write (2, a, n); END Write; BEGIN END RTOS.