17.5. $ATTACH classes

There are four built-in $ATTACH classes; all subtype from $LOCK. These classes all have an implicit locked status (unlocked, or locked by a particular thread) and a set of attached threads.

In addition to thread attachment, these classes support the operations listed in the following tables See Operations supported by ATTACH, FUTURE{T}, GATE, and GATE{T}, See Operations supported by FUTURE{T} and GATE{T}, See Operations supported only by GATE{T}, and See Operations supported only by GATE. Some operations are exclusive: these lock the gate before proceeding and unlock it when the operation is complete. The exclusive operations also perform imports and exports significant to memory consistency (See Memory consistency).

Table 17-1. Operations supported by ATTACH, FUTURE{T}, GATE, and GATE{T}

SignatureDescriptionExclusive?
create:SAMEMake a new unlocked synchronization object with an empty queue or zero counter and no attached threads.N/A
has_thread:BOOLReturns true if there is an attached thread.No
threads:$LOCKReturns a lock which blocks until lockable and there is some thread attached; then it is locked. Holding this lock does not prevent the completion of attached threads.No
no_threads:$LOCKReturns a lock which blocks until lockable and there are no threads attached; then it is locked. Holding this lock does not prevent the attachment of threads by the holder.No

Table 17-2. Operations supported by FUTURE{T} and GATE{T}

SignatureDescriptionExclusive?
get:TReturn head of queue without removing. Blocks until queue is not empty.Yes
empty:$LOCKReturns a lock which blocks until lockable and the queue is empty; then it is locked. Holding this lock does not prevent the holder from making the queue become not empty.No
not_empty:$LOCKReturns a lock which blocks until the gate is lockable and the gate's queue is not empty; then the gate is locked. Holding this lock does not prevent the holder from making the queue become empty.No

Table 17-3. Operations supported only by GATE{T}

SignatureDescriptionExclusive?
size:INTReturns number of elements in queue.No
set(T)Replace head of queue with argument, or insert into queue if empty.Yes
enqueue(T)Insert argument at tail of queue.Yes
dequeue:TBlock until queue is not empty, then remove and return head of queue.Yes

Table 17-4. Operations supported only by GATE

SignatureDescriptionExclusive?
size:INTReturns counter.No
getBlocks until counter is nonzero.Yes
setIf counter is zero, set to one.Yes
enqueueIncrement counter.Yes
dequeueBlock until counter nonzero, then decrement.Yes
empty:$LOCKReturns a lock which blocks until lockable and the counter is zero; then it is locked. Holding this lock does not prevent the holder from making the counter become nonzero.No
not_empty:$LOCKReturns a lock which blocks until the gate is lockable and the gate's counter is nonzero; then the gate is locked. Holding this lock does not prevent the holder from making the counter become zero.No

17.5.1. Attach examples

Example 17-5. Using a future. The statement 'f :- compute' creates a new thread to do some computation; the current thread continues to execute. It blocks at 'f.get' if the result is not yet available.

   -- Create a future of FLT
f ::= #FUTURE{FLT};
f :- compute;
...
result := f.get;

Example 17-6. Obtaining the first result from several competing searches. Unlike a future, a gate may enqueue multiple values. When one of the threads succeeds, its result is enqueued in 'g'. If the results of the other two threads are not needed, additional code would be needed to prematurely halt the other threads.

g :- search(strategy1);
g :- search(strategy2);
g :- search(strategy3);
...
result := g.dequeue;