Title:

suspend - temporarily stop the execution of one or more threads until restarted by another thread.

Usage:

suspend(thread, wait = F)

Arguments:

thread:
the threads or threadGroups to suspend as a vector or list. Recall that character strings can be used in place of thread objects. If this argument is missing, all threads in the session are suspended except this calling thread (self()). This allows the user to suspended all threads before calling a function such as synchronize(). Note that not all threads can be suspended and some threads are considered read only, such as the evaluator manager thread, signal thread, and perhaps certain input and output/display threads.
wait:
if this is F, each of the target threads is suspended asynchronously and the calling thread (self()) continues.
if wait is T, the calling thread waits for notifcation from each of the the target threads that it is in suspend mode (or about to enter it). This should be implemented in the evaluator manager and might require a special channel/queue or use of the relevant flags and check positions to pass "urgent" messages or tasks that are to be evaluated immediately. Can use several queues with different priorities for each thread.

Side Effect:

All the threads referenced in the argument thread are taken from their current mode to suspend mode so that they cannot proceed. If no threads are specified, all but the calling thread are suspended. This yields the same result as the expression
        suspend(lapply(threads(),function(x,y) x!= y, y=self()), wait = T)
     
but is more succinct

There is no real need to suspend the calling thread, e.g. suspend(self()), but it is available and will stop the thread as soon as possible. But the default is to have no argument refer to all threads other than this one. This is effectively the opposite of exit(), but it makes some sense. If one thread suspends itself, it cannot guarantee that another will wake it up. Instead some sort of global "Condition variable" should be used to block the thread indefinitely so that the evaluator manager can wake it.

If two threads attempt to call suspend() simultaneously, deadlock could arise. It is not yet obvious what should happen here. The Evaluator Manager can be made responsible for handling this but it might be both difficult and confusing. For the moment, we leave it to the developer of an application to avoid deadlock between threads and we will attempt to provide assistance at a higher level by identifying such deadlock "while" code is being developed.

More than likely we will allow only one thread be in the cancel code and so whichever thread gets there first wins. The others will spin waiting for this lock. In some senses, these are effectively suspended. However, in this particular case, we can organize the code so that we have a timed wait for the lock and if it returns with an EBUSY value, then the thread should attempt to suspend itself. This should work, if a little less than general.

Return Value:

A list of threads that were suspended due directly to this call. This allows this information to be stored and the threads to be started following some action while they are in suspended mode.

See Also:

cancel,
start

Examples:

      suspended.threads = suspend(wait=T)
      syncrhonize()
      start(suspended.threads)

Key Words:

User Level Threads

Last modified: Mon Feb 10 16:36:15 1997