forked from OpenMP/Examples
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathExample_atomic.3.f
More file actions
50 lines (49 loc) · 1.37 KB
/
Example_atomic.3.f
File metadata and controls
50 lines (49 loc) · 1.37 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
! @@name: atomic.3f
! @@type: F-fixed
! @@compilable: yes
! @@linkable: no
! @@expect: success
function fetch_and_add(p)
integer:: fetch_and_add
integer, intent(inout) :: p
! Atomically read the value of p and then increment it. The previous value is
! returned. This can be used to implement a simple lock as shown below.
!$omp atomic capture
fetch_and_add = p
p = p + 1
!$omp end atomic
end function fetch_and_add
module m
interface
function fetch_and_add(p)
integer :: fetch_and_add
integer, intent(inout) :: p
end function
function atomic_read(p)
integer :: atomic_read
integer, intent(in) :: p
end function
end interface
type locktype
integer ticketnumber
integer turn
end type
contains
subroutine do_locked_work(lock)
type(locktype), intent(inout) :: lock
integer myturn
integer junk
! obtain the lock
myturn = fetch_and_add(lock%ticketnumber)
do while (atomic_read(lock%turn) .ne. myturn)
continue
enddo
! Do some work. The flush is needed to ensure visibility of variables
! not involved in atomic directives
!$omp flush
call work
!$omp flush
! Release the lock
junk = fetch_and_add(lock%turn)
end subroutine
end module