but we need to think now about how to synchronise termination. Felix pthreads are always detached. There are two obvious possibilities: use a pchannel to communicate termination status to the group manager: this is the intended way to simulate joinable threads.

The second technique is modify the process manager to manage multiple processes. This reduces the number of threads required, and supports various synchronisation mechanisms such as event based triggers directly, without needing channels or locking. But it also reduces modularity, and has the major disadvantage that great care must be taken never to block, since that would cause monitoring of the processes to fail.

The previous account of termination only allowed one process group to run. The mainline would hang until all pthreads were dead. The following code provides proper termination, so the mainline can continue on with the next test group.

First, the process manager interface is changed to add an output pchannel:

I have found a bug based on my own misunderstanding of my own code. The fthreads that wait on the DEAD signals block. When an fthread is spawned, Felix does not specify if the spawner or spawnee runs next. The current implementation continues the spawner. This is the only reason the above code works.

In fact it may deadlock because the Faio::sleep() is asynchronous, that is, it actually does block an fthread and not a pthread. And of course this is true for S-channels. P-channel communication should be the same but it isn't.

I need to review how Felix spawns pthreads; some stuff is shared and some not. Clearly the stack isn't shared. Also the queues managing f-threads clearly can't be shared either. However procedural stack frames and the global "thread_frame_t" object are shared. The garbage collector (and allocator) are shared.