Restrictions on the atomic Construct
9.5. Restrictions on the atomic Construct#
The following non-conforming examples illustrate the restrictions on the atomic construct.
//%compiler: clang
//%cflags: -fopenmp
/*
* name: atomic_restrict.1
* type: C
* version: omp_3.1
*/
void atomic_wrong ()
{
union {int n; float x;} u;
#pragma omp parallel
{
#pragma omp atomic update
u.n++;
#pragma omp atomic update
u.x += 1.0;
/* Incorrect because the atomic constructs reference the same location
through incompatible types */
}
}
!!%compiler: gfortran
!!%cflags: -fopenmp
! name: atomic_restrict.1
! type: F-fixed
! version: omp_3.1
SUBROUTINE ATOMIC_WRONG()
INTEGER:: I
REAL:: R
EQUIVALENCE(I,R)
!$OMP PARALLEL
!$OMP ATOMIC UPDATE
I = I + 1
!$OMP ATOMIC UPDATE
R = R + 1.0
! incorrect because I and R reference the same location
! but have different types
!$OMP END PARALLEL
END SUBROUTINE ATOMIC_WRONG
//%compiler: clang
//%cflags: -fopenmp
/*
* name: atomic_restrict.2
* type: C
* version: omp_3.1
*/
void atomic_wrong2 ()
{
int x;
int *i;
float *r;
i = &x;
r = (float *)&x;
#pragma omp parallel
{
#pragma omp atomic update
*i += 1;
#pragma omp atomic update
*r += 1.0;
/* Incorrect because the atomic constructs reference the same location
through incompatible types */
}
}
The following example is non-conforming because I and R reference the same location but have different types.
!!%compiler: gfortran
!!%cflags: -fopenmp
! name: atomic_restrict.2
! type: F-fixed
! version: omp_3.1
SUBROUTINE SUB()
COMMON /BLK/ R
REAL R
!$OMP ATOMIC UPDATE
R = R + 1.0
END SUBROUTINE SUB
SUBROUTINE ATOMIC_WRONG2()
COMMON /BLK/ I
INTEGER I
!$OMP PARALLEL
!$OMP ATOMIC UPDATE
I = I + 1
CALL SUB()
!$OMP END PARALLEL
END SUBROUTINE ATOMIC_WRONG2
Although the following example might work on some implementations, this is also non-conforming:
!!%compiler: gfortran
!!%cflags: -fopenmp
! name: atomic_restrict.3
! type: F-fixed
! version: omp_3.1
SUBROUTINE ATOMIC_WRONG3
INTEGER:: I
REAL:: R
EQUIVALENCE(I,R)
!$OMP PARALLEL
!$OMP ATOMIC UPDATE
I = I + 1
! incorrect because I and R reference the same location
! but have different types
!$OMP END PARALLEL
!$OMP PARALLEL
!$OMP ATOMIC UPDATE
R = R + 1.0
! incorrect because I and R reference the same location
! but have different types
!$OMP END PARALLEL
END SUBROUTINE ATOMIC_WRONG3