suspend - temporarily stop the execution of one or more threads
until restarted by another thread.
F, each of the target threads
is suspended asynchronously and the calling thread (self())
continues.
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.
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.
suspended.threads = suspend(wait=T)
syncrhonize()
start(suspended.threads)