INTERFACEAThread ; TYPE T <: ROOT; Mutex = MUTEX; Condition <: ROOT;
Thread.T
is a handle on a thread. A Mutex
is locked by some
thread, or unlocked. A Condition
is a set of waiting threads. A
newly-allocated Mutex
is unlocked; a newly-allocated Condition
is empty. It is a checked runtime error to pass the NIL
Mutex
,
Condition
, or T
to any procedure in this interface.
TYPE Closure = OBJECT METHODS apply(): REFANY END; PROCEDURE Fork(cl: Closure): T;
Return a handle on a newly-created thread executing cl.apply()
.
PROCEDURE Join(t: T): REFANY;
Wait untilt
has terminated and return its result. It is a checked runtime error to call this more than once for anyt
.
PROCEDURE Wait(m: Mutex; c: Condition);
The calling thread must havem
locked. Atomically unlocksm
and waits onc
. Then relocksm
and returns.
PROCEDURE Acquire(m: Mutex);
Wait until m
is unlocked and then lock it.
PROCEDURE Release(m: Mutex);
The calling thread must havem
locked. Unlocksm
.
PROCEDURE Broadcast(c: Condition);
All threads waiting on c
become eligible to run.
PROCEDURE Signal(c: Condition);
One or more threads waiting on c
become eligible to run.
PROCEDURE Pause(n: LONGREAL);
Wait for n
seconds to elapse.
To wait until a specified point in time in the future, say
t
,
you can use the call
Pause(t - Time.Now())PROCEDURE Self(): T;Return the handle of the calling thread.EXCEPTION Alerted;Used to approximate asynchronous interrupts.PROCEDURE Alert(t: T);Markt
as an alerted thread.PROCEDURE TestAlert(): BOOLEAN;If the calling thread has been marked alerted, returnTRUE
and unmark it.PROCEDURE AlertWait(m: Mutex; c: Condition) RAISES {Alerted};LikeWait
, but if the thread is marked alerted at the time of call or sometime during the wait, lockm
and raiseAlerted
.PROCEDURE AlertJoin(t: T): REFANY RAISES {Alerted};LikeJoin
, but if the thread is marked alerted at the time of call or sometime during the wait, raiseAlerted
.PROCEDURE AlertPause(n: LONGREAL) RAISES {Alerted};LikePause
, but if the thread is marked alerted at the time of the call or sometime during the wait, raiseAlerted
.\paragraph*{Specifying thread stack size.} NormallyFork
uses a default value for the size of the stack of the new thread. It is possible to change the default value, and also to specify the value used for a particular call toFork
by supplying aSizedClosure
rather than aClosure
. Stack sizes are given as a number ofWord.T
s.PROCEDURE GetDefaultStackSize(): CARDINAL;Return the current default stack size for new threads.PROCEDURE MinDefaultStackSize(min: CARDINAL);Change the default stack size for newly forked threads to the greater ofmin
and the current default stack size.PROCEDURE IncDefaultStackSize(inc: CARDINAL);Increment the default stack size for newly forked threads byinc
.TYPE SizedClosure = Closure OBJECT stackSize: CARDINAL := 0 END; <*PRAGMA SPEC*> <* SPEC FUNC MaxLL(m: MUTEX): BOOLEAN *> <* SPEC AXIOM (ALL [m1, m2: MUTEX] (NOT MaxLL(m1) AND MaxLL(m2) AND m1 # NIL AND m2 # NIL) IMPLIES m1 < m2) *>Any mutex in MaxLL is greater than every mutex not in MaxLL.<* SPEC Acquire(m) MODIFIES LL REQUIRES sup(LL) < m ENSURES LL' = INSERT(LL, m) *> <* SPEC Release(m) MODIFIES LL REQUIRES MEMBER(m, LL) ENSURES LL' = DELETE(LL, m) *> END Thread.