Previous: Synchronization Up: Synchronization Next: Data Dependencies and Flow of Control

Introduction

Until now, we have discussed how parallel threads of execution can be created (with par, parfor, and spawn) and how the granularity of the interleaving of actions in different threads of execution can be controlled (with atomic). The only mechanism for synchronization between concurrently executing threads of control has been the implicit barrier at the end of a parallel block and at the end of a parfor statement. In this chapter, we introduce a mechanism for programming arbitrary synchronization behavior between concurrent threads of control.

The sharing of a mutable variable (unprotected by atomic access) between actions composed in parallel is dangerous when at least one of the actions modifies the value of this variable. By contrast, it is always safe to share constants (i.e. C or C++ const variables). In this spirit, CC++ defines a new type of variable, a single-assignment variable (or delayed initialization constant), denoted by the keyword sync. Like a constant, the value of a defined single-assignment variable cannot be modified. Attempting to modify the value of a defined single-assignment variable is a run-time error. Unlike a constant, however, a single-assignment variable need not be defined when it is declared. The definition can be postponed until some later point. Thus, a single-assignment variable can be in one of two states: undefined (as it is initially) or defined. Once defined, there is no difference between a single-assignment variable and a constant.

Here are some examples of declarations of single-assignment variables:


sync int a;           //sync integer
char *sync b;         //sync pointer to a mutable character
sync char* c;         //mutable pointer to a sync character
sync float D[N];      //array of sync floats
sync int *sync e;     //sync pointer to a sync integer

The keyword sync is analogous to the keyword const. It can be used anywhere that const can be used. Any regular C or C++ type can be declared to be single-assignment (see Section for an exception).

Single-assignment variables provide a means for synchronization because of the following rule:

If a thread of control attempts to read a single-assignment variable that has not yet been defined, that thread suspends execution until that single-assignment variable has been defined.
Thus, threads of control that share access to a single-assignment variable can use that variable as a synchronization element.

paolo@cs.caltech.edu