Intel® Fortran Compiler Classic and Intel® Fortran Compiler Developer Guide and Reference

ID 767251
Date 3/22/2024
Public
Document Table of Contents

CRITICAL Directive

OpenMP* Fortran Compiler Directive: Restricts access to a block of code to only one thread at a time.

Syntax

!$OMP CRITICAL [(name) [[,] clause]]

   loosely-structured-block

!$OMP END CRITICAL [(name)]

-or-

!$OMP CRITICAL [(name) [[,] clause]]

   strictly-structured-block

[!$OMP END CRITICAL [(name)]]

name

Is the name of the critical section.

clause

Is HINT (hint-expression).

loosely-structured-block

Is a structured block (section) of statements or constructs. You cannot branch into or out of the block.

strictly-structured-block

Is a Fortran BLOCK construct. You cannot branch into or out of the BLOCK construct.

The binding thread set for a CRITICAL construct is all threads in the contention group. Region execution is restricted to a single thread at a time among all threads in the contention group, without regard to the teams to which the threads belong.

A thread waits at the beginning of a critical section until no other thread in the team is executing a critical section having the same name. All unnamed CRITICAL directives map to the same name.

A name is optional if HINT does not appear, or if HINT appears with a hint value of OMP_SYNC_HINT_NONE. If a name is specified in the CRITICAL directive, the same name must appear in the corresponding END CRITICAL directive. If no name appears in the CRITICAL directive, no name can appear in the corresponding END CRITICAL directive. The hint-expression of each CRITICAL construct with the same name specified must evaluate to the same HINT value.

Critical section names are global entities of the program. If the name specified conflicts with any other entity, the behavior of the program is undefined.

Example

The following example shows a queuing model in which a task is dequeued and worked on. To guard against multiple threads dequeuing the same task, the dequeuing operation is placed in a critical section.

Because there are two independent queues in this example, each queue is protected by CRITICAL directives having different names, XAXIS and YAXIS, respectively:

  !$OMP PARALLEL DEFAULT(PRIVATE) SHARED(X,Y)
  !$OMP CRITICAL(XAXIS)
        CALL DEQUEUE(IX_NEXT, X)
  !$OMP END   CRITICAL(XAXIS)
        CALL WORK(IX_NEXT, X)
  !$OMP CRITICAL(YAXIS)
        CALL DEQUEUE(IY_NEXT,Y)
  !$OMP END   CRITICAL(YAXIS)
        CALL WORK(IY_NEXT, Y)
  !$OMP END PARALLEL