Link Search Menu Expand Document

Unstable-Funcons-beta : Notifications.cbs | PRETTY | PDF

Outline

Notifications

[
##### Barriers
Funcon  barrier-create
Funcon  barrier-sync
Funcon  barrier-sync-else-wait
##### Conditions
Funcon  condition-create
Funcon  condition-wait
Funcon  condition-wait-with-lock
Funcon  condition-notify-all
Funcon  condition-notify-first
##### Rendezvous
Funcon  rendezvous-create
Funcon  rendezvous-sync
Funcon  rendezvous-sync-else-wait
]

Threads may synchronise by waiting for notifications. In contrast to locks, notifications are ephemeral, and do not get held and released.

Barriers

A barrier notifies all requesting threads when a specified number of requests for it have been made. Subsequent requests give immediate notification.

When the barrier is already open, requests to pass it are granted immediately. When the barrier is closed, and only one more thread needs to arrive, granting a request for it opens the barrier and resumes all the threads wiating for it; otherwise the request fails.

When the request fails, the current thread is added to the waiting list, and suspended until the request can be granted:

Conditions

A condition is used to represent whether some property holds or not. Threads may request to be notified when another thread makes the property hold.

A condition may notify either one or all of its requesting threads. When it has to notify one thread but more than one request for notification has been made, the choice of thread may be determined by the scheduler. When it has to notify more than one thread, the property associated with the condition may have been invalidated by the time the executions of some of them are resumed, and threads may need to iterate requests for notifications.

In practice, a condition is generally associated with an exclusive lock. When a thread awaiting the condition is notified, it requests the exclusive lock and tests whether the required property holds; if it does not, the thread releases the exclusive lock, and atomically reverts to requesting the notification.

Funcon
  condition-create : =>syncs
   ~> sync-create(
        sync-feature-create sync-waiting-list)

A condition request always adds the current thread to the waiting list, and suspends it until the request can be granted. (In practice, it takes also an associated exclusive lock as a further argument, assumed to be held by the current thread, and releases it at the same time as suspending the thread.)

In practice, a condition request usually takes also an associated exclusive lock as a further argument, assumed to be held by the current thread, releases it together with suspending the thread, and waits for the lock when resumed:

Threads that are waiting for the condition are notified simply by resuming them. To notify them all:

To notify just one of the waiting threads:

Rendezvous

A rendezvous notifies all requesting threads as soon as a specified number N of them have made matching requests for it. The rendezvous can store any number of non-matching requests. If a request that completes a rendezvous matches different sets of N-1 pending requests, the ‘lexicographically’ earliest set of requests is selected; for a binary rendezvous, this is the first matching request in the stored list.

Each rendezvous request includes a pattern, and the corresponding notifications give environments obtained by matching the patterns against the same unified value. When the pattern in each request is simply a value, a rendezvous notifies all the requesting threads as soon as the specified number of requests with the same value have been made. When the pattern in one request is a value, a pattern in another request may bind an identifier to that value, giving one-way data flow.

A rendezvous request may also include a set of additional threads which are all required to participate in the rendezvous. When a pair of matching binary rendezvous requests each specify the other thread as the only required participant, the rendezvous is restricted to that pair of threads. When one of the sets is empty, the rendezvous may involve any other thread.

In this simplified version, rendezvous are always binary, patterns in requests are ground values, and sets of required threads are omitted.

When a rendezvous is available, granting a request for it removes the first matching element from the waiting list, and resumes its thread; otherwise the request fails.

When the request fails, a tuple of the value and the current thread is added to the waiting list, and the thread suspended until the request can be granted:

The remaining rendezvous funcons are all auxiliary:

Auxiliary Type
  rendezvous-waits ~> tuples(ground-values, thread-ids)

The funcon is-rendezvous-match(L, V) returns whether the list L contains tuple(V, TI) for some TI:

Auxiliary Funcon
  is-rendezvous-match(_:lists(rendezvous-waits), _:ground-values) : =>booleans

The funcon rendezvous-first-match-thread(L, V) returns the thread-id of the first element of L with value V:

Auxiliary Funcon
  rendezvous-first-match-thread(_:lists(rendezvous-waits), _:values)
    : =>thread-ids

The funcon rendezvous-first-match-drop(L, V) returns the list L omitting the first element with value V:

Auxiliary Funcon
  rendezvous-first-match-drop(_:lists(rendezvous-waits), _:values)
    : =>lists(rendezvous-waits)

A series of rendezvous between the same two threads is called an extended rendezvous. After the completion of each rendezvous in the series, one of the threads may immediately request the next, allowing the other thread to execute some code before synchronising. A simple rendezvous is restricted to synchronisation, and does not involve ordinary computation steps.