v2v1
v2v1

Reputation: 641

static variable local to function within OpenMP parallel region is modified: race condition?

I am dealing with a large confusing codebase, and I have a situation like this.

#pragma omp parallel for 
for ( int i = 0; i < N; i++) {
  problemFunction();
}

void problemFunction() {

  static bool inFunction;
  if ( inFunction == true ) {
    return;
  }
  else {
    inFunction = true;
  }
}

Would this create a race condition?

Upvotes: 2

Views: 1161

Answers (2)

Walter
Walter

Reputation: 45474

Yes, this will cause a race at execution (obviously). To avoid, you can use thread_local (see also here) variable (also, your function seems unnecessary complicated):

void problemFunction() {
  static thread_local bool inFunction;
  inFunction = true;
}

when each thread has their own variable inFunction. This way your function works with any threading implementation, not just OpenMP.

Upvotes: 0

Hristo Iliev
Hristo Iliev

Reputation: 74485

Unlike automatic local variables that usually reside on the thread's stack (which is private), local variables with static storage class reside in the data segment of the process and are thus shared between all threads executing the given function, therefore your code contains a race condition. To prevent the sharing, you should use OpenMP's threadprivate construct:

void problemFunction() {
  static bool inFunction;
  #pragma omp threadprivate(inFunction)

  if ( inFunction == true ) {
    return;
  }
  else {
    inFunction = true;
  }
}

This will alter the place the variable is stored in from the data segment to the so-called Thread-Local Storage (TLS). The original static semantics are kept, i.e. the value is retained between the function calls, but now each thread has its own copy. The threadprivate construct should always come after the variable declaration.

Upvotes: 3

Related Questions