A.25 Examples of the copyprivate Data Attribute Clause
Example 1: The copyprivate clause (Section 2.7.2.8 on page 32) can be used to broadcast values acquired by a single thread directly to all instances of the private variables in the other threads.
float x, y;
#pragma omp threadprivate(x, y)
void init( )
{
float a;
float b;
#pragma omp single copyprivate(a,b,x,y)
{
get_values(a,b,x,y);
}
use_values(a, b, x, y);
}
If routine init is called from a serial region, its behavior is not affected by the presence of the directives. After the call to the get_values routine has been executed by one thread, no thread leaves the construct until the private objects designated by a, b, x, and y in all threads have become defined with the values read.
Example 2: In contrast to the previous example, suppose the read must be performed by a particular thread, say the master thread. In this case, the copyprivate clause cannot be used to do the broadcast directly, but it can be used to provide access to a temporary shared object.
float read_next( )
{
float * tmp;
float return_val;
#pragma omp single copyprivate(tmp)
{
tmp = (float *) malloc(sizeof(float));
}
#pragma omp master
{
get_float( tmp );
}
#pragma omp barrier
return_val = *tmp;
#pragma omp barrier
#pragma omp single
{
free(tmp);
}
return return_val;
}
Example 3: Suppose that the number of lock objects required within a parallel region cannot easily be determined prior to entering it. The copyprivate clause can be used to provide access to shared lock objects that are allocated within that parallel region.
#include <omp.h>
omp_lock_t *new_lock()
{
omp_lock_t *lock_ptr;
#pragma omp single copyprivate(lock_ptr)
{
lock_ptr = (omp_lock_t *) malloc(sizeof(omp_lock_t));
omp_init_lock( lock_ptr );
}
return lock_ptr;
}