/[MITgcm]/MITgcm/eesupp/src/barrier.F
ViewVC logotype

Contents of /MITgcm/eesupp/src/barrier.F

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.7 - (show annotations) (download)
Sun Feb 4 14:38:42 2001 UTC (23 years, 4 months ago) by cnh
Branch: MAIN
CVS Tags: pre38tag1, c37_adj, pre38-close, checkpoint37, checkpoint36, checkpoint35
Branch point for: pre38
Changes since 1.6: +2 -1 lines
Made sure each .F and .h file had
the CVS keywords Header and Name at its start.
Most had header but very few currently have Name, so
lots of changes!

1 C $Header: /u/gcmpack/models/MITgcmUV/eesupp/src/barrier.F,v 1.6 1999/05/18 17:39:21 adcroft Exp $
2 C $Name: $
3
4 #include "CPP_EEOPTIONS.h"
5
6 SUBROUTINE BARRIER_INIT
7 IMPLICIT NONE
8
9 #include "SIZE.h"
10 #include "EEPARAMS.h"
11 #include "EESUPPORT.h"
12 #include "BARRIER.h"
13
14 C === Local Variables ===
15 INTEGER I
16
17 DO I=1,nThreads
18 key1(1,I) = INVALID
19 key2(1,I) = INVALID
20 key3(1,I) = INVALID
21 door1 = SHUT
22 door2 = SHUT
23 door3 = SHUT
24 ENDDO
25
26 RETURN
27 END
28 SUBROUTINE BARRIER( myThid )
29 IMPLICIT NONE
30 C
31 C /==========================================================\
32 C | SUBROUTINE BARRIER |
33 C | o Barrier routine that uses "busy waiting". |
34 C |==========================================================|
35 C | This routine provides a pure fortran mechanism to |
36 C | synchronise multiple threads in a multi-threaded code. |
37 C | No thread can leave this routine before all the threads |
38 C | have entered it. |
39 C | Notes |
40 C | ===== |
41 C | The door and key variables are assumed to have been |
42 C | initialized once an initial state of key = INVALID |
43 C | and door = SHUT. |
44 C | We use the routine FOOL_THE_COMPILER to stop compilers |
45 C | generating code which might simply set and test a |
46 C | register value. Shared-memory systems only maintain |
47 C | coherency over process caches and not registers. |
48 C | Also we have to be a bit careful regarding sequential |
49 C | consistency - or lack of it. At the moment the code |
50 C | assumes a total store order memory model, which some |
51 C | machines do not have! However, I have yet to find a |
52 C | problem with this I think because the tolerances in |
53 C | terms of memory ordering i.e. a little bit of reordering |
54 C | probably will not break the barrier mechanism! |
55 C | On non-cache coherent systems e.g. T3E we need to use |
56 C | a library function to do barriers. |
57 C | Note - The PANIC tests can be removed for working code |
58 C | I have left them in without an ifdef option |
59 C | because without them programming errors can |
60 C | lead to infinitely spinning code. If you are |
61 C | confident that your code is OK then removing |
62 C | them may increase performance. Do not remove these|
63 C | lines to make your code "work" If the code is |
64 C | stopping in these PANIC blocks then something is |
65 C | wrong with your program and it needs to be fixed. |
66 C \==========================================================/
67
68 #include "SIZE.h"
69 #include "EEPARAMS.h"
70 #include "EESUPPORT.h"
71 #include "BARRIER.h"
72
73 C === Routine arguments ===
74 INTEGER myThid
75
76 C === Local variables ===
77 C nDone - Counter for number of threads that have
78 C completed a section.
79 C I - Loop counter
80 INTEGER nDone
81 INTEGER I
82
83 CcnhDebugStarts
84 C WRITE(myThid,*) ' Barrier entered '
85 CcnhDebugEnds
86
87 C-- Check that thread number is expected range
88 IF ( myThid .LT. 1 .OR. myThid .GT. nThreads ) THEN
89 WRITE(0,*) '!!!!!!! PANIC !!!!!!! CATASTROPHIC ERROR'
90 WRITE(0,*) '!!!!!!! PANIC !!!!!!! in S/R BARRIER myThid = ',
91 & myThid, ' nThreads = ', nThreads
92 STOP 'ABNROMAL END: S/R BARRIER'
93 ENDIF
94
95 C-- When every threads key1 is valid thread 1 will open door1.
96 IF ( key1(1,myThid) .EQ. VALID ) THEN
97 WRITE(0,*) '!!!!!!! PANIC !!!!!!! CATASTROPHIC ERROR'
98 WRITE(0,*) '!!!!!!! PANIC !!!!!!! in S/R BARRIER myThid = ',
99 & myThid, ' key1 already validated'
100 STOP 'ABNROMAL END: S/R BARRIER'
101 ENDIF
102 key1(1,myThid) = VALID
103
104 IF ( myThid .eq. 1 ) THEN
105 10 CONTINUE
106 nDone = 0
107 DO I=1,nThreads
108 if ( key1(1,I) .EQ. VALID ) nDone = nDone+1
109 ENDDO
110 CALL FOOL_THE_COMPILER( key1 )
111 IF ( nDone .LT. nThreads ) GOTO 10
112 door1 = OPEN
113 ELSE
114 11 CONTINUE
115 CALL FOOL_THE_COMPILER( door1 )
116 IF ( door1 .NE. OPEN ) GOTO 11
117 ENDIF
118 C-- Invalidate keys for door1 here as it is now open
119 key1(1,myThid) = INVALID
120
121 CcnhDebugStarts
122 C IF ( myThid .EQ. 1 ) THEN
123 C WRITE(0,*) ' DOOR1 Opened '
124 C ENDIF
125 CcnhDebugEnds
126
127 C-- I can now shut door3 because I know everyone has reached
128 C-- door1. I can't shut door1 because I don't know if everyone
129 C-- has "gone" through the door yet. Nobody has yet reached
130 C-- door3 because they have to go through door2 first.
131 IF ( myThid .EQ. 1 ) THEN
132 door3 = SHUT
133 ENDIF
134
135 C-- When every threads key2 is valid thread 1 will open door2.
136 C Notes
137 C =====
138 C I think that to work with any memory model ( i.e. relaxed,
139 C partial store, total store) the variables key1, key2 and key3
140 C might need to be set to invalid by thread 1.
141 C
142 IF ( key2(1,myThid) .EQ. VALID ) THEN
143 WRITE(0,*) '!!!!!!! PANIC !!!!!!! CATASTROPHIC ERROR'
144 WRITE(0,*) '!!!!!!! PANIC !!!!!!! in S/R BARRIER myThid = ',
145 & myThid, ' key2 already validated'
146 STOP 'ABNROMAL END: S/R BARRIER'
147 ENDIF
148 key2(1,myThid) = VALID
149 C
150 IF ( myThid .eq. 1 ) THEN
151 20 CONTINUE
152 nDone = 0
153 DO I=1,nThreads
154 if ( key2(1,I) .EQ. VALID ) nDone = nDone+1
155 ENDDO
156 CALL FOOL_THE_COMPILER( key2 )
157 IF ( nDone .LT. nThreads ) GOTO 20
158 door2 = OPEN
159 ELSE
160 21 CONTINUE
161 CALL FOOL_THE_COMPILER( door2 )
162 IF ( door2 .NE. OPEN ) GOTO 21
163 ENDIF
164
165 C-- Invalidate keys for door2 here as it is now open
166 key2(1,myThid) = INVALID
167
168 C-- I can now shut door1 because I know everyone has reached
169 C-- door2. I can't shut door2 because I don't know if everyone
170 C-- has "gone" through the door yet. Nobody has yet reached
171 C-- door1 because they have to go through door3 first.
172 IF ( myThid .EQ. 1 ) THEN
173 door1 = SHUT
174 ENDIF
175
176
177 C-- When every threads key3 is valid thread 1 will open door3.
178 IF ( key3(1,myThid) .EQ. VALID ) THEN
179 WRITE(0,*) '!!!!!!! PANIC !!!!!!! CATASTROPHIC ERROR'
180 WRITE(0,*) '!!!!!!! PANIC !!!!!!! in S/R BARRIER myThid = ',
181 & myThid, ' key3 already validated'
182 STOP 'ABNROMAL END: S/R BARRIER'
183 ENDIF
184 key3(1,myThid) = VALID
185 C
186 IF ( myThid .eq. 1 ) THEN
187 30 CONTINUE
188 nDone = 0
189 DO I=1,nThreads
190 if ( key3(1,I) .EQ. VALID ) nDone = nDone+1
191 ENDDO
192 CALL FOOL_THE_COMPILER( key3 )
193 IF ( nDone .LT. nThreads ) GOTO 30
194 door3 = OPEN
195 ELSE
196 31 CONTINUE
197 CALL FOOL_THE_COMPILER( door3 )
198 IF ( door3 .NE. OPEN ) GOTO 31
199 ENDIF
200
201 C-- Invalidate keys for door3 here as it is now open
202 key3(1,myThid) = INVALID
203
204 C-- I can now shut door2 because I know everyone has reached
205 C-- door3. I can't shut door3 because I don't know if everyone
206 C-- has "gone" through the door yet. Nobody has yet reached
207 C-- door2 because they have to go through door1 first.
208 IF ( myThid .EQ. 1 ) THEN
209 door2 = SHUT
210 ENDIF
211
212 CcnhDebugStarts
213 C WRITE(myThid,*) ' Barrier exited '
214 CcnhDebugEnds
215
216 RETURN
217 END

  ViewVC Help
Powered by ViewVC 1.1.22