Threads Equalizer logo

Author: eilemann@gmail.com

Threads

Application (app/node) Main Thread

The app thread is the main execution thread of an Equalizer application, typically the one running main(). It drives the application's rendering and executes node tasks and nonthreaded rendering tasks.

Render Client (node) Main Thread

The render client main thread is very similar to the application thread, in that it executes node tasks and nonthreaded rendering tasks. The only difference is that it does not drive the application's, and that the main loop is controlled by the Equalizer client library.

Receiver (recv) Thread

Each Equalizer network node has a recv thread, created during Node::initLocal(). It listens on all connections and reads the data into packets. The packets are dispatched to the command handler functions. The command handler functions in the receiver thread should never block to avoid deadlocks.

Pipe Thread(s)

All commands for a pipe and its siblings (windows, channels) are executed in a separate thread for optimal performance. The commands are dispatched from the receiver thread to the node thread using a fifo. Therefore, the pipe thread may block its execution. An exception are nonthreaded pipes, which are executed from the main thread.

Thread Synchronization

Application and render client main loops
Application and render client main loops

The default thread synchronization synchronizes all Channel::frameDraw operations on a single node with the node's main thread. This facilitates porting, since the scene database does not have to be multi-buffered. Advanced applications can remove per-node frame synchronization.

The per-node frame synchronization is achieved through the startFrame, waitFrameStarted and releaseFrameLocal, waitFrameLocal synchronization points. Note that this synchronization is only per-node, different nodes in the cluster still run asynchronously.

The first one ensures that the application (node) thread is done modifiying the data. The pipe threads call Node::waitFrameStarted which blocks until the node calls startFrame in Node::frameStart.

The second pair ensures that after Config::finishFrame all pipe threads are done rendering the current frame. The node's frameDrawFinish waits for all local pipes to release the synchronization by calling Pipe::releaseFrameLocal, which happens by default in Pipe::frameDrawFinish. The frameDrawFinish methods are called after all Channel::frameDraw of the corresponding thread have been executed.

Applications which multi-buffer all dynamic data can completely remove frame synchronization by: