1169695Skan\input texinfo @c -*-texinfo-*-
2169695Skan
3169695Skan@c %**start of header
4169695Skan@setfilename libgomp.info
5169695Skan@settitle GNU libgomp
6169695Skan@c %**end of header
7169695Skan
8169695Skan
9169695Skan@copying
10169695SkanCopyright @copyright{} 2006 Free Software Foundation, Inc.
11169695Skan
12169695SkanPermission is granted to copy, distribute and/or modify this document
13169695Skanunder the terms of the GNU Free Documentation License, Version 1.1 or
14169695Skanany later version published by the Free Software Foundation; with the
15169695SkanInvariant Sections being ``GNU General Public License'' and ``Funding
16169695SkanFree Software'', the Front-Cover
17169695Skantexts being (a) (see below), and with the Back-Cover Texts being (b)
18169695Skan(see below).  A copy of the license is included in the section entitled
19169695Skan``GNU Free Documentation License''.
20169695Skan
21169695Skan(a) The FSF's Front-Cover Text is:
22169695Skan
23169695Skan     A GNU Manual
24169695Skan
25169695Skan(b) The FSF's Back-Cover Text is:
26169695Skan
27169695Skan     You have freedom to copy and modify this GNU Manual, like GNU
28169695Skan     software.  Copies published by the Free Software Foundation raise
29169695Skan     funds for GNU development.
30169695Skan@end copying
31169695Skan
32169695Skan@ifinfo
33169695Skan@dircategory GNU Libraries
34169695Skan@direntry
35169695Skan* libgomp: (libgomp).                    GNU OpenMP runtime library
36169695Skan@end direntry
37169695Skan
38169695SkanThis manual documents the GNU implementation of the OpenMP API for 
39169695Skanmulti-platform shared-memory parallel programming in C/C++ and Fortran.
40169695Skan
41169695SkanPublished by the Free Software Foundation
42169695Skan51 Franklin Street, Fifth Floor
43169695SkanBoston, MA 02110-1301 USA
44169695Skan
45169695Skan@insertcopying
46169695Skan@end ifinfo
47169695Skan
48169695Skan
49169695Skan@setchapternewpage odd
50169695Skan
51169695Skan@titlepage
52169695Skan@title The GNU OpenMP Implementation
53169695Skan@page
54169695Skan@vskip 0pt plus 1filll
55169695Skan@comment For the @value{version-GCC} Version*
56169695Skan@sp 1
57169695SkanPublished by the Free Software Foundation @*
58169695Skan51 Franklin Street, Fifth Floor@*
59169695SkanBoston, MA 02110-1301, USA@*
60169695Skan@sp 1
61169695Skan@insertcopying
62169695Skan@end titlepage
63169695Skan
64169695Skan@summarycontents
65169695Skan@contents
66169695Skan@page
67169695Skan
68169695Skan
69169695Skan@node Top
70169695Skan@top Introduction
71169695Skan@cindex Introduction
72169695Skan
73169695SkanThis manual documents the usage of libgomp, the GNU implementation of the 
74169695Skan@uref{http://www.openmp.org, OpenMP} Application Programming Interface (API)
75169695Skanfor multi-platform shared-memory parallel programming in C/C++ and Fortran.
76169695Skan
77169695Skan
78169695Skan
79169695Skan@comment
80169695Skan@comment  When you add a new menu item, please keep the right hand
81169695Skan@comment  aligned to the same column.  Do not use tabs.  This provides
82169695Skan@comment  better formatting.
83169695Skan@comment
84169695Skan@menu
85169695Skan* Enabling OpenMP::            How to enable OpenMP for your applications.
86169695Skan* Runtime Library Routines::   The OpenMP runtime application programming 
87169695Skan                               interface.
88169695Skan* Environment Variables::      Influencing runtime behavior with environment 
89169695Skan                               variables.
90169695Skan* The libgomp ABI::            Notes on the external ABI presented by libgomp.
91169695Skan* Reporting Bugs::             How to report bugs in GNU OpenMP.
92169695Skan* Copying::                    GNU general public license says
93169695Skan                               how you can copy and share libgomp.
94169695Skan* GNU Free Documentation License::
95169695Skan                               How you can copy and share this manual.
96169695Skan* Funding::                    How to help assure continued work for free 
97169695Skan                               software.
98169695Skan* Index::                      Index of this documentation.
99169695Skan@end menu
100169695Skan
101169695Skan
102169695Skan@c ---------------------------------------------------------------------
103169695Skan@c Enabling OpenMP
104169695Skan@c ---------------------------------------------------------------------
105169695Skan
106169695Skan@node Enabling OpenMP
107169695Skan@chapter Enabling OpenMP
108169695Skan
109169695SkanTo activate the OpenMP extensions for C/C++ and Fortran, the compile-time 
110169695Skanflag @command{-fopenmp} must be specified. This enables the OpenMP directive
111169695Skan@code{#pragma omp} in C/C++ and @code{!$omp} directives in free form, 
112169695Skan@code{c$omp}, @code{*$omp} and @code{!$omp} directives in fixed form, 
113169695Skan@code{!$} conditional compilation sentinels in free form and @code{c$},
114169695Skan@code{*$} and @code{!$} sentinels in fixed form, for Fortran. The flag also
115169695Skanarranges for automatic linking of the OpenMP runtime library 
116169695Skan(@ref{Runtime Library Routines}).
117169695Skan
118169695SkanA complete description of all OpenMP directives accepted may be found in 
119169695Skanthe @uref{http://www.openmp.org, OpenMP Application Program Interface} manual,
120169695Skanversion 2.5.
121169695Skan
122169695Skan
123169695Skan@c ---------------------------------------------------------------------
124169695Skan@c Runtime Library Routines
125169695Skan@c ---------------------------------------------------------------------
126169695Skan
127169695Skan@node Runtime Library Routines
128169695Skan@chapter Runtime Library Routines
129169695Skan
130169695SkanThe runtime routines described here are defined by section 3 of the OpenMP 
131169695Skanspecifications in version 2.5.
132169695Skan
133169695SkanControl threads, processors and the parallel environment.
134169695Skan
135169695Skan@menu
136169695Skan* omp_get_dynamic::          Dynamic teams setting
137169695Skan* omp_get_max_threads::      Maximum number of threads
138169695Skan* omp_get_nested::           Nested parallel regions
139169695Skan* omp_get_num_procs::        Number of processors online
140169695Skan* omp_get_num_threads::      Size of the active team
141169695Skan* omp_get_thread_num::       Current thread ID
142169695Skan* omp_in_parallel::          Whether a parallel region is active
143169695Skan* omp_set_dynamic::          Enable/disable dynamic teams
144169695Skan* omp_set_nested::           Enable/disable nested parallel regions
145169695Skan* omp_set_num_threads::      Set upper team size limit
146169695Skan@end menu
147169695Skan
148169695SkanInitialize, set, test, unset and destroy simple and nested locks.
149169695Skan
150169695Skan@menu
151169695Skan* omp_init_lock::            Initialize simple lock
152169695Skan* omp_set_lock::             Wait for and set simple lock
153169695Skan* omp_test_lock::            Test and set simple lock if available
154169695Skan* omp_unset_lock::           Unset simple lock
155169695Skan* omp_destroy_lock::         Destroy simple lock
156169695Skan* omp_init_nest_lock::       Initialize nested lock
157169695Skan* omp_set_nest_lock::        Wait for and set simple lock
158169695Skan* omp_test_nest_lock::       Test and set nested lock if available
159169695Skan* omp_unset_nest_lock::      Unset nested lock
160169695Skan* omp_destroy_nest_lock::    Destroy nested lock
161169695Skan@end menu
162169695Skan
163169695SkanPortable, thread-based, wall clock timer.
164169695Skan
165169695Skan@menu
166169695Skan* omp_get_wtick::            Get timer precision.
167169695Skan* omp_get_wtime::            Elapsed wall clock time.
168169695Skan@end menu
169169695Skan
170169695Skan@node omp_get_dynamic
171169695Skan@section @code{omp_get_dynamic} -- Dynamic teams setting
172169695Skan@table @asis
173169695Skan@item @emph{Description}:
174169695SkanThis function returns @code{true} if enabled, @code{false} otherwise. 
175169695SkanHere, @code{true} and @code{false} represent their language-specific 
176169695Skancounterparts.
177169695Skan
178169695SkanThe dynamic team setting may be initialized at startup by the 
179169695Skan@code{OMP_DYNAMIC} environment variable or at runtime using 
180169695Skan@code{omp_set_dynamic}. If undefined, dynamic adjustment is 
181169695Skandisabled by default.
182169695Skan
183169695Skan@item @emph{C/C++}:
184169695Skan@multitable @columnfractions .20 .80
185169695Skan@item @emph{Prototype}: @tab @code{int omp_get_dynamic();}
186169695Skan@end multitable
187169695Skan
188169695Skan@item @emph{Fortran}:
189169695Skan@multitable @columnfractions .20 .80
190169695Skan@item @emph{Interface}: @tab @code{logical function omp_get_dynamic()}
191169695Skan@end multitable
192169695Skan
193169695Skan@item @emph{See also}:
194169695Skan@ref{omp_set_dynamic}, @ref{OMP_DYNAMIC}
195169695Skan
196169695Skan@item @emph{Reference}:
197169695Skan@uref{http://www.openmp.org/, OpenMP specifications v2.5}, section 3.2.8.
198169695Skan@end table
199169695Skan
200169695Skan
201169695Skan
202169695Skan@node omp_get_max_threads
203169695Skan@section @code{omp_get_max_threads} -- Maximum number of threads
204169695Skan@table @asis
205169695Skan@item @emph{Description}:
206169695SkanReturn the maximum number of threads used for parallel regions that do
207169695Skannot use the clause @code{num_threads}.
208169695Skan
209169695Skan@item @emph{C/C++}:
210169695Skan@multitable @columnfractions .20 .80
211169695Skan@item @emph{Prototype}: @tab @code{int omp_get_max_threads();}
212169695Skan@end multitable
213169695Skan
214169695Skan@item @emph{Fortran}:
215169695Skan@multitable @columnfractions .20 .80
216169695Skan@item @emph{Interface}: @tab @code{integer function omp_get_max_threads()}
217169695Skan@end multitable
218169695Skan
219169695Skan@item @emph{See also}:
220169695Skan@ref{omp_set_num_threads}, @ref{omp_set_dynamic}
221169695Skan
222169695Skan@item @emph{Reference}:
223169695Skan@uref{http://www.openmp.org/, OpenMP specifications v2.5}, section 3.2.3.
224169695Skan@end table
225169695Skan
226169695Skan
227169695Skan
228169695Skan@node omp_get_nested
229169695Skan@section @code{omp_get_nested} -- Nested parallel regions
230169695Skan@table @asis
231169695Skan@item @emph{Description}:
232169695SkanThis function returns @code{true} if nested parallel regions are
233169695Skanenabled, @code{false} otherwise. Here, @code{true} and @code{false} 
234169695Skanrepresent their language-specific counterparts.
235169695Skan
236169695SkanNested parallel regions may be initialized at startup by the 
237169695Skan@code{OMP_NESTED} environment variable or at runtime using 
238169695Skan@code{omp_set_nested}. If undefined, nested parallel regions are
239169695Skandisabled by default.
240169695Skan
241169695Skan@item @emph{C/C++}:
242169695Skan@multitable @columnfractions .20 .80
243169695Skan@item @emph{Prototype}: @tab @code{int omp_get_nested();}
244169695Skan@end multitable
245169695Skan
246169695Skan@item @emph{Fortran}:
247169695Skan@multitable @columnfractions .20 .80
248169695Skan@item @emph{Interface}: @tab @code{integer function omp_get_nested()}
249169695Skan@end multitable
250169695Skan
251169695Skan@item @emph{See also}:
252169695Skan@ref{omp_set_nested}, @ref{OMP_NESTED}
253169695Skan
254169695Skan@item @emph{Reference}:
255169695Skan@uref{http://www.openmp.org/, OpenMP specifications v2.5}, section 3.2.10.
256169695Skan@end table
257169695Skan
258169695Skan
259169695Skan
260169695Skan@node omp_get_num_procs
261169695Skan@section @code{omp_get_num_procs} -- Number of processors online
262169695Skan@table @asis
263169695Skan@item @emph{Description}:
264169695SkanReturns the number of processors online.
265169695Skan
266169695Skan@item @emph{C/C++}:
267169695Skan@multitable @columnfractions .20 .80
268169695Skan@item @emph{Prototype}: @tab @code{int omp_get_num_procs();}
269169695Skan@end multitable
270169695Skan
271169695Skan@item @emph{Fortran}:
272169695Skan@multitable @columnfractions .20 .80
273169695Skan@item @emph{Interface}: @tab @code{integer function omp_get_num_procs()}
274169695Skan@end multitable
275169695Skan
276169695Skan@item @emph{Reference}:
277169695Skan@uref{http://www.openmp.org/, OpenMP specifications v2.5}, section 3.2.5.
278169695Skan@end table
279169695Skan
280169695Skan
281169695Skan
282169695Skan@node omp_get_num_threads
283169695Skan@section @code{omp_get_num_threads} -- Size of the active team
284169695Skan@table @asis
285169695Skan@item @emph{Description}:
286169695SkanThe number of threads in the current team. In a sequential section of 
287169695Skanthe program @code{omp_get_num_threads} returns 1.
288169695Skan
289169695SkanThe default team size may be initialized at startup by the 
290169695Skan@code{OMP_NUM_THREADS} environment variable. At runtime, the size 
291169695Skanof the current team may be set either by the @code{NUM_THREADS}
292169695Skanclause or by @code{omp_set_num_threads}. If none of the above were 
293169695Skanused to define a specific value and @code{OMP_DYNAMIC} is disabled,
294169695Skanone thread per CPU online is used.
295169695Skan
296169695Skan@item @emph{C/C++}:
297169695Skan@multitable @columnfractions .20 .80
298169695Skan@item @emph{Prototype}: @tab @code{int omp_get_num_threads();}
299169695Skan@end multitable
300169695Skan
301169695Skan@item @emph{Fortran}:
302169695Skan@multitable @columnfractions .20 .80
303169695Skan@item @emph{Interface}: @tab @code{integer function omp_get_num_threads()}
304169695Skan@end multitable
305169695Skan
306169695Skan@item @emph{See also}:
307169695Skan@ref{omp_get_max_threads}, @ref{omp_set_num_threads}, @ref{OMP_NUM_THREADS}
308169695Skan
309169695Skan@item @emph{Reference}:
310169695Skan@uref{http://www.openmp.org/, OpenMP specifications v2.5}, section 3.2.2.
311169695Skan@end table
312169695Skan
313169695Skan
314169695Skan
315169695Skan@node omp_get_thread_num 
316169695Skan@section @code{omp_get_thread_num} -- Current thread ID
317169695Skan@table @asis
318169695Skan@item @emph{Description}:
319169695SkanUnique thread identification number. In a sequential parts of the program, 
320169695Skan@code{omp_get_thread_num} always returns 0. In parallel regions the return
321169695Skanvalue varies from 0 to @code{omp_get_max_threads}-1 inclusive. The return 
322169695Skanvalue of the master thread of a team is always 0.
323169695Skan
324169695Skan@item @emph{C/C++}:
325169695Skan@multitable @columnfractions .20 .80
326169695Skan@item @emph{Prototype}: @tab @code{int omp_get_thread_num();}
327169695Skan@end multitable
328169695Skan
329169695Skan@item @emph{Fortran}:
330169695Skan@multitable @columnfractions .20 .80
331169695Skan@item @emph{Interface}: @tab @code{integer function omp_get_thread_num()}
332169695Skan@end multitable
333169695Skan
334169695Skan@item @emph{See also}:
335169695Skan@ref{omp_get_max_threads}
336169695Skan
337169695Skan@item @emph{Reference}:
338169695Skan@uref{http://www.openmp.org/, OpenMP specifications v2.5}, section 3.2.4.
339169695Skan@end table
340169695Skan
341169695Skan
342169695Skan
343169695Skan@node omp_in_parallel
344169695Skan@section @code{omp_in_parallel} -- Whether a parallel region is active
345169695Skan@table @asis
346169695Skan@item @emph{Description}:
347169695SkanThis function returns @code{true} if currently running in parallel, 
348169695Skan@code{false} otherwise. Here, @code{true} and @code{false} represent 
349169695Skantheir language-specific counterparts.
350169695Skan
351169695Skan@item @emph{C/C++}:
352169695Skan@multitable @columnfractions .20 .80
353169695Skan@item @emph{Prototype}: @tab @code{int omp_in_parallel();}
354169695Skan@end multitable
355169695Skan
356169695Skan@item @emph{Fortran}:
357169695Skan@multitable @columnfractions .20 .80
358169695Skan@item @emph{Interface}: @tab @code{logical function omp_in_parallel()}
359169695Skan@end multitable
360169695Skan
361169695Skan@item @emph{Reference}:
362169695Skan@uref{http://www.openmp.org/, OpenMP specifications v2.5}, section 3.2.6.
363169695Skan@end table
364169695Skan
365169695Skan
366169695Skan@node omp_set_dynamic
367169695Skan@section @code{omp_set_dynamic} -- Enable/disable dynamic teams
368169695Skan@table @asis
369169695Skan@item @emph{Description}:
370169695SkanEnable or disable the dynamic adjustment of the number of threads 
371169695Skanwithin a team. The function takes the language-specific equivalent
372169695Skanof @code{true} and @code{false}, where @code{true} enables dynamic 
373169695Skanadjustment of team sizes and @code{false} disables it.
374169695Skan
375169695Skan@item @emph{C/C++}:
376169695Skan@multitable @columnfractions .20 .80
377169695Skan@item @emph{Prototype}: @tab @code{void omp_set_dynamic(int);}
378169695Skan@end multitable
379169695Skan
380169695Skan@item @emph{Fortran}:
381169695Skan@multitable @columnfractions .20 .80
382169695Skan@item @emph{Interface}: @tab @code{subroutine omp_set_dynamic(set)}
383169695Skan@item                   @tab @code{integer, intent(in) :: set}
384169695Skan@end multitable
385169695Skan
386169695Skan@item @emph{See also}:
387169695Skan@ref{OMP_DYNAMIC}, @ref{omp_get_dynamic}
388169695Skan
389169695Skan@item @emph{Reference}:
390169695Skan@uref{http://www.openmp.org/, OpenMP specifications v2.5}, section 3.2.7.
391169695Skan@end table
392169695Skan
393169695Skan
394169695Skan
395169695Skan@node omp_set_nested
396169695Skan@section @code{omp_set_nested} -- Enable/disable nested parallel regions
397169695Skan@table @asis
398169695Skan@item @emph{Description}:
399169695SkanEnable or disable nested parallel regions, i.e., whether team members
400169695Skanare allowed to create new teams. The function takes the language-specific 
401169695Skanequivalent of @code{true} and @code{false}, where @code{true} enables 
402169695Skandynamic adjustment of team sizes and @code{false} disables it.
403169695Skan
404169695Skan@item @emph{C/C++}:
405169695Skan@multitable @columnfractions .20 .80
406169695Skan@item @emph{Prototype}: @tab @code{void omp_set_dynamic(int);}
407169695Skan@end multitable
408169695Skan
409169695Skan@item @emph{Fortran}:
410169695Skan@multitable @columnfractions .20 .80
411169695Skan@item @emph{Interface}: @tab @code{subroutine omp_set_dynamic(set)}
412169695Skan@item                   @tab @code{integer, intent(in) :: set}
413169695Skan@end multitable
414169695Skan
415169695Skan@item @emph{See also}:
416169695Skan@ref{OMP_NESTED}, @ref{omp_get_nested}
417169695Skan
418169695Skan@item @emph{Reference}:
419169695Skan@uref{http://www.openmp.org/, OpenMP specifications v2.5}, section 3.2.9.
420169695Skan@end table
421169695Skan
422169695Skan
423169695Skan
424169695Skan@node omp_set_num_threads
425169695Skan@section @code{omp_set_num_threads} -- Set upper team size limit
426169695Skan@table @asis
427169695Skan@item @emph{Description}:
428169695SkanSpecifies the number of threads used by default in subsequent parallel 
429169695Skansections, if those do not specify a @code{num_threads} clause. The 
430169695Skanargument of @code{omp_set_num_threads} shall be a positive integer. 
431169695Skan
432169695Skan@item @emph{C/C++}:
433169695Skan@multitable @columnfractions .20 .80
434169695Skan@item @emph{Prototype}: @tab @code{void omp_set_num_threads(int);}
435169695Skan@end multitable
436169695Skan
437169695Skan@item @emph{Fortran}:
438169695Skan@multitable @columnfractions .20 .80
439169695Skan@item @emph{Interface}: @tab @code{subroutine omp_set_num_threads(set)}
440169695Skan@item                   @tab @code{integer, intent(in) :: set}
441169695Skan@end multitable
442169695Skan
443169695Skan@item @emph{See also}:
444169695Skan@ref{OMP_NUM_THREADS}, @ref{omp_get_num_threads}, @ref{omp_get_max_threads}
445169695Skan
446169695Skan@item @emph{Reference}:
447169695Skan@uref{http://www.openmp.org/, OpenMP specifications v2.5}, section 3.2.1.
448169695Skan@end table
449169695Skan
450169695Skan
451169695Skan
452169695Skan@node omp_init_lock
453169695Skan@section @code{omp_init_lock} -- Initialize simple lock
454169695Skan@table @asis
455169695Skan@item @emph{Description}:
456169695SkanInitialize a simple lock. After initialization, the lock is in 
457169695Skanan unlocked state.
458169695Skan
459169695Skan@item @emph{C/C++}:
460169695Skan@multitable @columnfractions .20 .80
461169695Skan@item @emph{Prototype}: @tab @code{void omp_init_lock(omp_lock_t *lock);}
462169695Skan@end multitable
463169695Skan
464169695Skan@item @emph{Fortran}:
465169695Skan@multitable @columnfractions .20 .80
466169695Skan@item @emph{Interface}: @tab @code{subroutine omp_init_lock(lock)}
467169695Skan@item                   @tab @code{integer(omp_lock_kind), intent(out) :: lock}
468169695Skan@end multitable
469169695Skan
470169695Skan@item @emph{See also}:
471169695Skan@ref{omp_destroy_lock}
472169695Skan
473169695Skan@item @emph{Reference}: 
474169695Skan@uref{http://www.openmp.org/, OpenMP specifications v2.5}, section 3.3.1.
475169695Skan@end table
476169695Skan
477169695Skan
478169695Skan
479169695Skan@node omp_set_lock
480169695Skan@section @code{omp_set_lock} -- Wait for and set simple lock
481169695Skan@table @asis
482169695Skan@item @emph{Description}:
483169695SkanBefore setting a simple lock, the lock variable must be initialized by 
484169695Skan@code{omp_init_lock}. The calling thread is blocked until the lock 
485169695Skanis available. If the lock is already held by the current thread, 
486169695Skana deadlock occurs.
487169695Skan
488169695Skan@item @emph{C/C++}:
489169695Skan@multitable @columnfractions .20 .80
490169695Skan@item @emph{Prototype}: @tab @code{void omp_set_lock(omp_lock_t *lock);}
491169695Skan@end multitable
492169695Skan
493169695Skan@item @emph{Fortran}:
494169695Skan@multitable @columnfractions .20 .80
495169695Skan@item @emph{Interface}: @tab @code{subroutine omp_set_lock(lock)}
496169695Skan@item                   @tab @code{integer(omp_lock_kind), intent(out) :: lock}
497169695Skan@end multitable
498169695Skan
499169695Skan@item @emph{See also}:
500169695Skan@ref{omp_init_lock}, @ref{omp_test_lock}, @ref{omp_unset_lock}
501169695Skan
502169695Skan@item @emph{Reference}: 
503169695Skan@uref{http://www.openmp.org/, OpenMP specifications v2.5}, section 3.3.3.
504169695Skan@end table
505169695Skan
506169695Skan
507169695Skan
508169695Skan@node omp_test_lock
509169695Skan@section @code{omp_test_lock} -- Test and set simple lock if available
510169695Skan@table @asis
511169695Skan@item @emph{Description}:
512169695SkanBefore setting a simple lock, the lock variable must be initialized by 
513169695Skan@code{omp_init_lock}. Contrary to @code{omp_set_lock}, @code{omp_test_lock} 
514169695Skandoes not block if the lock is not available. This function returns 
515169695Skan@code{true} upon success,@code{false} otherwise. Here, @code{true} and 
516169695Skan@code{false} represent their language-specific counterparts.
517169695Skan
518169695Skan@item @emph{C/C++}:
519169695Skan@multitable @columnfractions .20 .80
520169695Skan@item @emph{Prototype}: @tab @code{int omp_test_lock(omp_lock_t *lock);}
521169695Skan@end multitable
522169695Skan
523169695Skan@item @emph{Fortran}:
524169695Skan@multitable @columnfractions .20 .80
525169695Skan@item @emph{Interface}: @tab @code{subroutine omp_test_lock(lock)}
526169695Skan@item                   @tab @code{logical(omp_logical_kind) :: omp_test_lock}
527169695Skan@item                   @tab @code{integer(omp_lock_kind), intent(out) :: lock}
528169695Skan@end multitable
529169695Skan
530169695Skan@item @emph{See also}:
531169695Skan@ref{omp_init_lock}, @ref{omp_set_lock}, @ref{omp_set_lock}
532169695Skan
533169695Skan@item @emph{Reference}: 
534169695Skan@uref{http://www.openmp.org/, OpenMP specifications v2.5}, section 3.3.5.
535169695Skan@end table
536169695Skan
537169695Skan
538169695Skan
539169695Skan@node omp_unset_lock
540169695Skan@section @code{omp_unset_lock} -- Unset simple lock
541169695Skan@table @asis
542169695Skan@item @emph{Description}:
543169695SkanA simple lock about to be unset must have been locked by @code{omp_set_lock}
544169695Skanor @code{omp_test_lock} before. In addition, the lock must be held by the 
545169695Skanthread calling @code{omp_unset_lock}. Then, the lock becomes unlocked. If one 
546169695Skanore more threads attempted to set the lock before, one of them is chosen to, 
547169695Skanagain, set the lock for itself.
548169695Skan
549169695Skan@item @emph{C/C++}:
550169695Skan@multitable @columnfractions .20 .80
551169695Skan@item @emph{Prototype}: @tab @code{void omp_unset_lock(omp_lock_t *lock);}
552169695Skan@end multitable
553169695Skan
554169695Skan@item @emph{Fortran}:
555169695Skan@multitable @columnfractions .20 .80
556169695Skan@item @emph{Interface}: @tab @code{subroutine omp_unset_lock(lock)}
557169695Skan@item                   @tab @code{integer(omp_lock_kind), intent(out) :: lock}
558169695Skan@end multitable
559169695Skan
560169695Skan@item @emph{See also}:
561169695Skan@ref{omp_set_lock}, @ref{omp_test_lock}
562169695Skan
563169695Skan@item @emph{Reference}: 
564169695Skan@uref{http://www.openmp.org/, OpenMP specifications v2.5}, section 3.3.4.
565169695Skan@end table
566169695Skan
567169695Skan
568169695Skan
569169695Skan@node omp_destroy_lock
570169695Skan@section @code{omp_destroy_lock} -- Destroy simple lock
571169695Skan@table @asis
572169695Skan@item @emph{Description}:
573169695SkanDestroy a simple lock. In order to be destroyed, a simple lock must be 
574169695Skanin the unlocked state. 
575169695Skan
576169695Skan@item @emph{C/C++}:
577169695Skan@multitable @columnfractions .20 .80
578169695Skan@item @emph{Prototype}: @tab @code{void omp_destroy_lock(omp_lock_t *);}
579169695Skan@end multitable
580169695Skan
581169695Skan@item @emph{Fortran}:
582169695Skan@multitable @columnfractions .20 .80
583169695Skan@item @emph{Interface}: @tab @code{subroutine omp_destroy_lock(lock)}
584169695Skan@item                   @tab @code{integer(omp_lock_kind), intent(inout) :: lock}
585169695Skan@end multitable
586169695Skan
587169695Skan@item @emph{See also}:
588169695Skan@ref{omp_init_lock}
589169695Skan
590169695Skan@item @emph{Reference}: 
591169695Skan@uref{http://www.openmp.org/, OpenMP specifications v2.5}, section 3.3.2.
592169695Skan@end table
593169695Skan
594169695Skan
595169695Skan
596169695Skan@node omp_init_nest_lock
597169695Skan@section @code{omp_init_nest_lock} -- Initialize nested lock
598169695Skan@table @asis
599169695Skan@item @emph{Description}:
600169695SkanInitialize a nested lock. After initialization, the lock is in 
601169695Skanan unlocked state and the nesting count is set to zero.
602169695Skan
603169695Skan@item @emph{C/C++}:
604169695Skan@multitable @columnfractions .20 .80
605169695Skan@item @emph{Prototype}: @tab @code{void omp_init_nest_lock(omp_nest_lock_t *lock);}
606169695Skan@end multitable
607169695Skan
608169695Skan@item @emph{Fortran}:
609169695Skan@multitable @columnfractions .20 .80
610169695Skan@item @emph{Interface}: @tab @code{subroutine omp_init_nest_lock(lock)}
611169695Skan@item                   @tab @code{integer(omp_nest_lock_kind), intent(out) :: lock}
612169695Skan@end multitable
613169695Skan
614169695Skan@item @emph{See also}:
615169695Skan@ref{omp_destroy_nest_lock}
616169695Skan
617169695Skan@item @emph{Reference}:
618169695Skan@uref{http://www.openmp.org/, OpenMP specifications v2.5}, section 3.3.1.
619169695Skan@end table
620169695Skan
621169695Skan
622169695Skan@node omp_set_nest_lock
623169695Skan@section @code{omp_set_nest_lock} -- Wait for and set simple lock
624169695Skan@table @asis
625169695Skan@item @emph{Description}:
626169695SkanBefore setting a nested lock, the lock variable must be initialized by 
627169695Skan@code{omp_init_nest_lock}. The calling thread is blocked until the lock 
628169695Skanis available. If the lock is already held by the current thread, the 
629169695Skannesting count for the lock in incremented.
630169695Skan
631169695Skan@item @emph{C/C++}:
632169695Skan@multitable @columnfractions .20 .80
633169695Skan@item @emph{Prototype}: @tab @code{void omp_set_nest_lock(omp_nest_lock_t *lock);}
634169695Skan@end multitable
635169695Skan
636169695Skan@item @emph{Fortran}:
637169695Skan@multitable @columnfractions .20 .80
638169695Skan@item @emph{Interface}: @tab @code{subroutine omp_set_nest_lock(lock)}
639169695Skan@item                   @tab @code{integer(omp_nest_lock_kind), intent(out) :: lock}
640169695Skan@end multitable
641169695Skan
642169695Skan@item @emph{See also}:
643169695Skan@ref{omp_init_nest_lock}, @ref{omp_unset_nest_lock}
644169695Skan
645169695Skan@item @emph{Reference}: 
646169695Skan@uref{http://www.openmp.org/, OpenMP specifications v2.5}, section 3.3.3.
647169695Skan@end table
648169695Skan
649169695Skan
650169695Skan
651169695Skan@node omp_test_nest_lock
652169695Skan@section @code{omp_test_nest_lock} -- Test and set nested lock if available
653169695Skan@table @asis
654169695Skan@item @emph{Description}:
655169695SkanBefore setting a nested lock, the lock variable must be initialized by 
656169695Skan@code{omp_init_nest_lock}. Contrary to @code{omp_set_nest_lock}, 
657169695Skan@code{omp_test_nest_lock} does not block if the lock is not available. 
658169695SkanIf the lock is already held by the current thread, the new nesting count 
659169695Skanis returned. Otherwise, the return value equals zero.
660169695Skan
661169695Skan@item @emph{C/C++}:
662169695Skan@multitable @columnfractions .20 .80
663169695Skan@item @emph{Prototype}: @tab @code{int omp_test_nest_lock(omp_nest_lock_t *lock);}
664169695Skan@end multitable
665169695Skan
666169695Skan@item @emph{Fortran}:
667169695Skan@multitable @columnfractions .20 .80
668169695Skan@item @emph{Interface}: @tab @code{integer function omp_test_nest_lock(lock)}
669169695Skan@item                   @tab @code{integer(omp_integer_kind) :: omp_test_nest_lock}
670169695Skan@item                   @tab @code{integer(omp_nest_lock_kind), intent(inout) :: lock}
671169695Skan@end multitable
672169695Skan
673169695Skan
674169695Skan@item @emph{See also}:
675169695Skan@ref{omp_init_lock}, @ref{omp_set_lock}, @ref{omp_set_lock}
676169695Skan
677169695Skan@item @emph{Reference}: 
678169695Skan@uref{http://www.openmp.org/, OpenMP specifications v2.5}, section 3.3.5.
679169695Skan@end table
680169695Skan
681169695Skan
682169695Skan
683169695Skan@node omp_unset_nest_lock
684169695Skan@section @code{omp_unset_nest_lock} -- Unset nested lock
685169695Skan@table @asis
686169695Skan@item @emph{Description}:
687169695SkanA nested lock about to be unset must have been locked by @code{omp_set_nested_lock}
688169695Skanor @code{omp_test_nested_lock} before. In addition, the lock must be held by the 
689169695Skanthread calling @code{omp_unset_nested_lock}. If the nesting count drops to zero, the 
690169695Skanlock becomes unlocked. If one ore more threads attempted to set the lock before, 
691169695Skanone of them is chosen to, again, set the lock for itself.
692169695Skan
693169695Skan@item @emph{C/C++}:
694169695Skan@multitable @columnfractions .20 .80
695169695Skan@item @emph{Prototype}: @tab @code{void omp_unset_nest_lock(omp_nest_lock_t *lock);}
696169695Skan@end multitable
697169695Skan
698169695Skan@item @emph{Fortran}:
699169695Skan@multitable @columnfractions .20 .80
700169695Skan@item @emph{Interface}: @tab @code{subroutine omp_unset_nest_lock(lock)}
701169695Skan@item                   @tab @code{integer(omp_nest_lock_kind), intent(out) :: lock}
702169695Skan@end multitable
703169695Skan
704169695Skan@item @emph{See also}:
705169695Skan@ref{omp_set_nest_lock}
706169695Skan
707169695Skan@item @emph{Reference}: 
708169695Skan@uref{http://www.openmp.org/, OpenMP specifications v2.5}, section 3.3.4.
709169695Skan@end table
710169695Skan
711169695Skan
712169695Skan
713169695Skan@node omp_destroy_nest_lock
714169695Skan@section @code{omp_destroy_nest_lock} -- Destroy nested lock
715169695Skan@table @asis
716169695Skan@item @emph{Description}:
717169695SkanDestroy a nested lock. In order to be destroyed, a nested lock must be 
718169695Skanin the unlocked state and its nesting count must equal zero.
719169695Skan
720169695Skan@item @emph{C/C++}:
721169695Skan@multitable @columnfractions .20 .80
722169695Skan@item @emph{Prototype}: @tab @code{void omp_destroy_nest_lock(omp_nest_lock_t *);}
723169695Skan@end multitable
724169695Skan
725169695Skan@item @emph{Fortran}:
726169695Skan@multitable @columnfractions .20 .80
727169695Skan@item @emph{Interface}: @tab @code{subroutine omp_destroy_nest_lock(lock)}
728169695Skan@item                   @tab @code{integer(omp_nest_lock_kind), intent(inout) :: lock}
729169695Skan@end multitable
730169695Skan
731169695Skan@item @emph{See also}:
732169695Skan@ref{omp_init_lock}
733169695Skan
734169695Skan@item @emph{Reference}: 
735169695Skan@uref{http://www.openmp.org/, OpenMP specifications v2.5}, section 3.3.2.
736169695Skan@end table
737169695Skan
738169695Skan
739169695Skan
740169695Skan@node omp_get_wtick
741169695Skan@section @code{omp_get_wtick} -- Get timer precision
742169695Skan@table @asis
743169695Skan@item @emph{Description}:
744169695SkanGets the timer precision, i.e., the number of seconds between two 
745169695Skansuccessive clock ticks.
746169695Skan
747169695Skan@item @emph{C/C++}:
748169695Skan@multitable @columnfractions .20 .80
749169695Skan@item @emph{Prototype}: @tab @code{double omp_get_wtick();}
750169695Skan@end multitable
751169695Skan
752169695Skan@item @emph{Fortran}:
753169695Skan@multitable @columnfractions .20 .80
754169695Skan@item @emph{Interface}: @tab @code{double precision function omp_get_wtick()}
755169695Skan@end multitable
756169695Skan
757169695Skan@item @emph{See also}:
758169695Skan@ref{omp_get_wtime}
759169695Skan
760169695Skan@item @emph{Reference}: 
761169695Skan@uref{http://www.openmp.org/, OpenMP specifications v2.5}, section 3.4.2.
762169695Skan@end table
763169695Skan
764169695Skan
765169695Skan
766169695Skan@node omp_get_wtime
767169695Skan@section @code{omp_get_wtime} -- Elapsed wall clock time
768169695Skan@table @asis
769169695Skan@item @emph{Description}:
770169695SkanElapsed wall clock time in seconds. The time is measured per thread, no 
771169695Skanguarantee can bee made that two distinct threads measure the same time.
772169695SkanTime is measured from some "time in the past". On POSIX compliant systems 
773169695Skanthe seconds since the Epoch (00:00:00 UTC, January 1, 1970) are returned.
774169695Skan
775169695Skan@item @emph{C/C++}:
776169695Skan@multitable @columnfractions .20 .80
777169695Skan@item @emph{Prototype}: @tab @code{double omp_get_wtime();}
778169695Skan@end multitable
779169695Skan
780169695Skan@item @emph{Fortran}:
781169695Skan@multitable @columnfractions .20 .80
782169695Skan@item @emph{Interface}: @tab @code{double precision function omp_get_wtime()}
783169695Skan@end multitable
784169695Skan
785169695Skan@item @emph{See also}:
786169695Skan@ref{omp_get_wtick}
787169695Skan
788169695Skan@item @emph{Reference}: 
789169695Skan@uref{http://www.openmp.org/, OpenMP specifications v2.5}, section 3.4.1.
790169695Skan@end table
791169695Skan
792169695Skan
793169695Skan
794169695Skan@c ---------------------------------------------------------------------
795169695Skan@c Environment Variables
796169695Skan@c ---------------------------------------------------------------------
797169695Skan
798169695Skan@node Environment Variables
799169695Skan@chapter Environment Variables
800169695Skan
801169695SkanThe variables @env{OMP_DYNAMIC}, @env{OMP_NESTED}, @env{OMP_NUM_THREADS} and 
802169695Skan@env{OMP_SCHEDULE} are defined by section 4 of the OpenMP specifications in 
803169695Skanversion 2.5, while @env{GOMP_CPU_AFFINITY} and @env{GOMP_STACKSIZE} are GNU 
804169695Skanextensions.
805169695Skan
806169695Skan@menu
807169695Skan* OMP_DYNAMIC::        Dynamic adjustment of threads
808169695Skan* OMP_NESTED::         Nested parallel regions
809169695Skan* OMP_NUM_THREADS::    Specifies the number of threads to use
810169695Skan* OMP_SCHEDULE::       How threads are scheduled
811169695Skan* GOMP_CPU_AFFINITY::  Bind threads to specific CPUs
812169695Skan* GOMP_STACKSIZE::     Set default thread stack size
813169695Skan@end menu
814169695Skan
815169695Skan
816169695Skan@node OMP_DYNAMIC
817169695Skan@section @env{OMP_DYNAMIC} -- Dynamic adjustment of threads
818169695Skan@cindex Environment Variable
819169695Skan@cindex Implementation specific setting
820169695Skan@table @asis
821169695Skan@item @emph{Description}:
822169695SkanEnable or disable the dynamic adjustment of the number of threads 
823169695Skanwithin a team. The value of this environment variable shall be 
824169695Skan@code{TRUE} or @code{FALSE}. If undefined, dynamic adjustment is
825169695Skandisabled by default.
826169695Skan
827169695Skan@item @emph{See also}:
828169695Skan@ref{omp_set_dynamic}
829169695Skan
830169695Skan@item @emph{Reference}: 
831169695Skan@uref{http://www.openmp.org/, OpenMP specifications v2.5}, section 4.3
832169695Skan@end table
833169695Skan
834169695Skan
835169695Skan
836169695Skan@node OMP_NESTED
837169695Skan@section @env{OMP_NESTED} -- Nested parallel regions
838169695Skan@cindex Environment Variable
839169695Skan@cindex Implementation specific setting
840169695Skan@table @asis
841169695Skan@item @emph{Description}:
842169695SkanEnable or disable nested parallel regions, i.e., whether team members
843169695Skanare allowed to create new teams. The value of this environment variable 
844169695Skanshall be @code{TRUE} or @code{FALSE}. If undefined, nested parallel 
845169695Skanregions are disabled by default.
846169695Skan
847169695Skan@item @emph{See also}:
848169695Skan@ref{omp_set_nested}
849169695Skan
850169695Skan@item @emph{Reference}: 
851169695Skan@uref{http://www.openmp.org/, OpenMP specifications v2.5}, section 4.4
852169695Skan@end table
853169695Skan
854169695Skan
855169695Skan
856169695Skan@node OMP_NUM_THREADS
857169695Skan@section @env{OMP_NUM_THREADS} -- Specifies the number of threads to use
858169695Skan@cindex Environment Variable
859169695Skan@cindex Implementation specific setting
860169695Skan@table @asis
861169695Skan@item @emph{Description}:
862169695SkanSpecifies the default number of threads to use in parallel regions. The 
863169695Skanvalue of this variable shall be positive integer. If undefined one thread 
864169695Skanper CPU online is used.
865169695Skan
866169695Skan@item @emph{See also}:
867169695Skan@ref{omp_set_num_threads}
868169695Skan
869169695Skan@item @emph{Reference}: 
870169695Skan@uref{http://www.openmp.org/, OpenMP specifications v2.5}, section 4.2
871169695Skan@end table
872169695Skan
873169695Skan
874169695Skan
875169695Skan@node OMP_SCHEDULE
876169695Skan@section @env{OMP_SCHEDULE} -- How threads are scheduled
877169695Skan@cindex Environment Variable
878169695Skan@cindex Implementation specific setting
879169695Skan@table @asis
880169695Skan@item @emph{Description}:
881169695SkanAllows to specify @code{schedule type} and @code{chunk size}. 
882169695SkanThe value of the variable shall have the form: @code{type[,chunk]} where
883169695Skan@code{type} is one of @code{static}, @code{dynamic} or @code{guided}. 
884169695SkanThe optional @code{chunk size} shall be a positive integer. If undefined,
885169695Skandynamic scheduling and a chunk size of 1 is used.
886169695Skan
887169695Skan@item @emph{Reference}: 
888169695Skan@uref{http://www.openmp.org/, OpenMP specifications v2.5}, sections 2.5.1 and 4.1
889169695Skan@end table
890169695Skan
891169695Skan
892169695Skan
893169695Skan@node GOMP_CPU_AFFINITY
894169695Skan@section @env{GOMP_CPU_AFFINITY} -- Bind threads to specific CPUs
895169695Skan@cindex Environment Variable
896169695Skan@table @asis
897169695Skan@item @emph{Description}:
898282152SpfgBinds threads to specific CPUs. The variable should contain a space- or
899282152Spfgcomma-separated list of CPUs. This list may contain different kind of 
900282152Spfgentries: either single CPU numbers in any order, a range of CPUs (M-N) 
901282152Spfgor a range with some stride (M-N:S). CPU numbers are zero based. For example,
902282152Spfg@code{GOMP_CPU_AFFINITY="0 3 1-2 4-15:2"} will bind the initial thread
903282152Spfgto CPU 0, the second to CPU 3, the third to CPU 1, the fourth to 
904282152SpfgCPU 2, the fifth to CPU 4, the sixth through tenth to CPUs 6, 8, 10, 12,
905282152Spfgand 14 respectively and then start assigning back from the beginning of
906282152Spfgthe list. @code{GOMP_CPU_AFFINITY=0} binds all threads to CPU 0.
907169695Skan
908282152SpfgThere is no GNU OpenMP library routine to determine whether a CPU affinity 
909282152Spfgspecification is in effect. As a workaround, language-specific library 
910282152Spfgfunctions, e.g., @code{getenv} in C or @code{GET_ENVIRONMENT_VARIABLE} in 
911282152SpfgFortran, may be used to query the setting of the @code{GOMP_CPU_AFFINITY} 
912282152Spfgenvironment variable. A defined CPU affinity on startup cannot be changed 
913282152Spfgor disabled during the runtime of the application.
914282152Spfg
915282152SpfgIf this environment variable is omitted, the host system will handle the 
916282152Spfgassignment of threads to CPUs. 
917169695Skan@end table
918169695Skan
919169695Skan
920169695Skan
921169695Skan@node GOMP_STACKSIZE
922169695Skan@section @env{GOMP_STACKSIZE} -- Set default thread stack size
923169695Skan@cindex Environment Variable
924169695Skan@cindex Implementation specific setting
925169695Skan@table @asis
926169695Skan@item @emph{Description}:
927169695SkanSet the default thread stack size in kilobytes. This is in opposition 
928169695Skanto @code{pthread_attr_setstacksize} which gets the number of bytes as an 
929169695Skanargument. If the stacksize can not be set due to system constraints, an 
930169695Skanerror is reported and the initial stacksize is left unchanged. If undefined,
931169695Skanthe stack size is system dependent.
932169695Skan
933169695Skan@item @emph{Reference}: 
934169695Skan@uref{http://gcc.gnu.org/ml/gcc-patches/2006-06/msg00493.html, 
935169695SkanGCC Patches Mailinglist}, 
936169695Skan@uref{http://gcc.gnu.org/ml/gcc-patches/2006-06/msg00496.html,
937169695SkanGCC Patches Mailinglist}
938169695Skan@end table
939169695Skan
940169695Skan
941169695Skan
942169695Skan@c ---------------------------------------------------------------------
943169695Skan@c The libgomp ABI
944169695Skan@c ---------------------------------------------------------------------
945169695Skan
946169695Skan@node The libgomp ABI
947169695Skan@chapter The libgomp ABI
948169695Skan
949169695SkanThe following sections present notes on the external ABI as 
950169695Skanpresented by libgomp. Only maintainers should need them.
951169695Skan
952169695Skan@menu
953169695Skan* Implementing MASTER construct::
954169695Skan* Implementing CRITICAL construct::
955169695Skan* Implementing ATOMIC construct::
956169695Skan* Implementing FLUSH construct::
957169695Skan* Implementing BARRIER construct::
958169695Skan* Implementing THREADPRIVATE construct::
959169695Skan* Implementing PRIVATE clause::
960169695Skan* Implementing FIRSTPRIVATE LASTPRIVATE COPYIN and COPYPRIVATE clauses::
961169695Skan* Implementing REDUCTION clause::
962169695Skan* Implementing PARALLEL construct::
963169695Skan* Implementing FOR construct::
964169695Skan* Implementing ORDERED construct::
965169695Skan* Implementing SECTIONS construct::
966169695Skan* Implementing SINGLE construct::
967169695Skan@end menu
968169695Skan
969169695Skan
970169695Skan@node Implementing MASTER construct
971169695Skan@section Implementing MASTER construct
972169695Skan
973169695Skan@smallexample
974169695Skanif (omp_get_thread_num () == 0)
975169695Skan  block
976169695Skan@end smallexample
977169695Skan
978169695SkanAlternately, we generate two copies of the parallel subfunction
979169695Skanand only include this in the version run by the master thread.
980169695SkanSurely that's not worthwhile though...
981169695Skan
982169695Skan
983169695Skan
984169695Skan@node Implementing CRITICAL construct
985169695Skan@section Implementing CRITICAL construct
986169695Skan
987169695SkanWithout a specified name,
988169695Skan
989169695Skan@smallexample
990169695Skan  void GOMP_critical_start (void);
991169695Skan  void GOMP_critical_end (void);
992169695Skan@end smallexample
993169695Skan
994169695Skanso that we don't get COPY relocations from libgomp to the main
995169695Skanapplication.
996169695Skan
997169695SkanWith a specified name, use omp_set_lock and omp_unset_lock with
998169695Skanname being transformed into a variable declared like
999169695Skan
1000169695Skan@smallexample
1001169695Skan  omp_lock_t gomp_critical_user_<name> __attribute__((common))
1002169695Skan@end smallexample
1003169695Skan
1004169695SkanIdeally the ABI would specify that all zero is a valid unlocked
1005169695Skanstate, and so we wouldn't actually need to initialize this at
1006169695Skanstartup.
1007169695Skan
1008169695Skan
1009169695Skan
1010169695Skan@node Implementing ATOMIC construct
1011169695Skan@section Implementing ATOMIC construct
1012169695Skan
1013169695SkanThe target should implement the @code{__sync} builtins.
1014169695Skan
1015169695SkanFailing that we could add
1016169695Skan
1017169695Skan@smallexample
1018169695Skan  void GOMP_atomic_enter (void)
1019169695Skan  void GOMP_atomic_exit (void)
1020169695Skan@end smallexample
1021169695Skan
1022169695Skanwhich reuses the regular lock code, but with yet another lock
1023169695Skanobject private to the library.
1024169695Skan
1025169695Skan
1026169695Skan
1027169695Skan@node Implementing FLUSH construct
1028169695Skan@section Implementing FLUSH construct
1029169695Skan
1030169695SkanExpands to the @code{__sync_synchronize} builtin.
1031169695Skan
1032169695Skan
1033169695Skan
1034169695Skan@node Implementing BARRIER construct
1035169695Skan@section Implementing BARRIER construct
1036169695Skan
1037169695Skan@smallexample
1038169695Skan  void GOMP_barrier (void)
1039169695Skan@end smallexample
1040169695Skan
1041169695Skan
1042169695Skan@node Implementing THREADPRIVATE construct
1043169695Skan@section Implementing THREADPRIVATE construct
1044169695Skan
1045169695SkanIn _most_ cases we can map this directly to @code{__thread}.  Except
1046169695Skanthat OMP allows constructors for C++ objects.  We can either
1047169695Skanrefuse to support this (how often is it used?) or we can 
1048169695Skanimplement something akin to .ctors.
1049169695Skan
1050169695SkanEven more ideally, this ctor feature is handled by extensions
1051169695Skanto the main pthreads library.  Failing that, we can have a set
1052169695Skanof entry points to register ctor functions to be called.
1053169695Skan
1054169695Skan
1055169695Skan
1056169695Skan@node Implementing PRIVATE clause
1057169695Skan@section Implementing PRIVATE clause
1058169695Skan
1059169695SkanIn association with a PARALLEL, or within the lexical extent
1060169695Skanof a PARALLEL block, the variable becomes a local variable in
1061169695Skanthe parallel subfunction.
1062169695Skan
1063169695SkanIn association with FOR or SECTIONS blocks, create a new
1064169695Skanautomatic variable within the current function.  This preserves
1065169695Skanthe semantic of new variable creation.
1066169695Skan
1067169695Skan
1068169695Skan
1069169695Skan@node Implementing FIRSTPRIVATE LASTPRIVATE COPYIN and COPYPRIVATE clauses
1070169695Skan@section Implementing FIRSTPRIVATE LASTPRIVATE COPYIN and COPYPRIVATE clauses
1071169695Skan
1072169695SkanSeems simple enough for PARALLEL blocks.  Create a private 
1073169695Skanstruct for communicating between parent and subfunction.
1074169695SkanIn the parent, copy in values for scalar and "small" structs;
1075169695Skancopy in addresses for others TREE_ADDRESSABLE types.  In the 
1076169695Skansubfunction, copy the value into the local variable.
1077169695Skan
1078169695SkanNot clear at all what to do with bare FOR or SECTION blocks.
1079169695SkanThe only thing I can figure is that we do something like
1080169695Skan
1081169695Skan@smallexample
1082169695Skan#pragma omp for firstprivate(x) lastprivate(y)
1083169695Skanfor (int i = 0; i < n; ++i)
1084169695Skan  body;
1085169695Skan@end smallexample
1086169695Skan
1087169695Skanwhich becomes
1088169695Skan
1089169695Skan@smallexample
1090169695Skan@{
1091169695Skan  int x = x, y;
1092169695Skan
1093169695Skan  // for stuff
1094169695Skan
1095169695Skan  if (i == n)
1096169695Skan    y = y;
1097169695Skan@}
1098169695Skan@end smallexample
1099169695Skan
1100169695Skanwhere the "x=x" and "y=y" assignments actually have different
1101169695Skanuids for the two variables, i.e. not something you could write
1102169695Skandirectly in C.  Presumably this only makes sense if the "outer"
1103169695Skanx and y are global variables.
1104169695Skan
1105169695SkanCOPYPRIVATE would work the same way, except the structure 
1106169695Skanbroadcast would have to happen via SINGLE machinery instead.
1107169695Skan
1108169695Skan
1109169695Skan
1110169695Skan@node Implementing REDUCTION clause
1111169695Skan@section Implementing REDUCTION clause
1112169695Skan
1113169695SkanThe private struct mentioned in the previous section should have 
1114169695Skana pointer to an array of the type of the variable, indexed by the 
1115169695Skanthread's @var{team_id}.  The thread stores its final value into the 
1116169695Skanarray, and after the barrier the master thread iterates over the
1117169695Skanarray to collect the values.
1118169695Skan
1119169695Skan
1120169695Skan@node Implementing PARALLEL construct
1121169695Skan@section Implementing PARALLEL construct
1122169695Skan
1123169695Skan@smallexample
1124169695Skan  #pragma omp parallel
1125169695Skan  @{
1126169695Skan    body;
1127169695Skan  @}
1128169695Skan@end smallexample
1129169695Skan
1130169695Skanbecomes
1131169695Skan
1132169695Skan@smallexample
1133169695Skan  void subfunction (void *data)
1134169695Skan  @{
1135169695Skan    use data;
1136169695Skan    body;
1137169695Skan  @}
1138169695Skan
1139169695Skan  setup data;
1140169695Skan  GOMP_parallel_start (subfunction, &data, num_threads);
1141169695Skan  subfunction (&data);
1142169695Skan  GOMP_parallel_end ();
1143169695Skan@end smallexample
1144169695Skan
1145169695Skan@smallexample
1146169695Skan  void GOMP_parallel_start (void (*fn)(void *), void *data, unsigned num_threads)
1147169695Skan@end smallexample
1148169695Skan
1149169695SkanThe @var{FN} argument is the subfunction to be run in parallel.
1150169695Skan
1151169695SkanThe @var{DATA} argument is a pointer to a structure used to 
1152169695Skancommunicate data in and out of the subfunction, as discussed
1153169695Skanabove with respect to FIRSTPRIVATE et al.
1154169695Skan
1155169695SkanThe @var{NUM_THREADS} argument is 1 if an IF clause is present
1156169695Skanand false, or the value of the NUM_THREADS clause, if
1157169695Skanpresent, or 0.
1158169695Skan
1159169695SkanThe function needs to create the appropriate number of
1160169695Skanthreads and/or launch them from the dock.  It needs to
1161169695Skancreate the team structure and assign team ids.
1162169695Skan
1163169695Skan@smallexample
1164169695Skan  void GOMP_parallel_end (void)
1165169695Skan@end smallexample
1166169695Skan
1167169695SkanTears down the team and returns us to the previous @code{omp_in_parallel()} state.
1168169695Skan
1169169695Skan
1170169695Skan
1171169695Skan@node Implementing FOR construct
1172169695Skan@section Implementing FOR construct
1173169695Skan
1174169695Skan@smallexample
1175169695Skan  #pragma omp parallel for
1176169695Skan  for (i = lb; i <= ub; i++)
1177169695Skan    body;
1178169695Skan@end smallexample
1179169695Skan
1180169695Skanbecomes
1181169695Skan
1182169695Skan@smallexample
1183169695Skan  void subfunction (void *data)
1184169695Skan  @{
1185169695Skan    long _s0, _e0;
1186169695Skan    while (GOMP_loop_static_next (&_s0, &_e0))
1187169695Skan    @{
1188169695Skan      long _e1 = _e0, i;
1189169695Skan      for (i = _s0; i < _e1; i++)
1190169695Skan        body;
1191169695Skan    @}
1192169695Skan    GOMP_loop_end_nowait ();
1193169695Skan  @}
1194169695Skan
1195169695Skan  GOMP_parallel_loop_static (subfunction, NULL, 0, lb, ub+1, 1, 0);
1196169695Skan  subfunction (NULL);
1197169695Skan  GOMP_parallel_end ();
1198169695Skan@end smallexample
1199169695Skan
1200169695Skan@smallexample
1201169695Skan  #pragma omp for schedule(runtime)
1202169695Skan  for (i = 0; i < n; i++)
1203169695Skan    body;
1204169695Skan@end smallexample
1205169695Skan
1206169695Skanbecomes
1207169695Skan
1208169695Skan@smallexample
1209169695Skan  @{
1210169695Skan    long i, _s0, _e0;
1211169695Skan    if (GOMP_loop_runtime_start (0, n, 1, &_s0, &_e0))
1212169695Skan      do @{
1213169695Skan        long _e1 = _e0;
1214169695Skan        for (i = _s0, i < _e0; i++)
1215169695Skan          body;
1216169695Skan      @} while (GOMP_loop_runtime_next (&_s0, _&e0));
1217169695Skan    GOMP_loop_end ();
1218169695Skan  @}
1219169695Skan@end smallexample
1220169695Skan
1221169695SkanNote that while it looks like there is trickyness to propagating
1222169695Skana non-constant STEP, there isn't really.  We're explicitly allowed
1223169695Skanto evaluate it as many times as we want, and any variables involved
1224169695Skanshould automatically be handled as PRIVATE or SHARED like any other
1225169695Skanvariables.  So the expression should remain evaluable in the 
1226169695Skansubfunction.  We can also pull it into a local variable if we like,
1227169695Skanbut since its supposed to remain unchanged, we can also not if we like.
1228169695Skan
1229169695SkanIf we have SCHEDULE(STATIC), and no ORDERED, then we ought to be
1230169695Skanable to get away with no work-sharing context at all, since we can
1231169695Skansimply perform the arithmetic directly in each thread to divide up
1232169695Skanthe iterations.  Which would mean that we wouldn't need to call any
1233169695Skanof these routines.
1234169695Skan
1235169695SkanThere are separate routines for handling loops with an ORDERED
1236169695Skanclause.  Bookkeeping for that is non-trivial...
1237169695Skan
1238169695Skan
1239169695Skan
1240169695Skan@node Implementing ORDERED construct
1241169695Skan@section Implementing ORDERED construct
1242169695Skan
1243169695Skan@smallexample
1244169695Skan  void GOMP_ordered_start (void)
1245169695Skan  void GOMP_ordered_end (void)
1246169695Skan@end smallexample
1247169695Skan
1248169695Skan
1249169695Skan
1250169695Skan@node Implementing SECTIONS construct
1251169695Skan@section Implementing SECTIONS construct
1252169695Skan
1253169695SkanA block as 
1254169695Skan
1255169695Skan@smallexample
1256169695Skan  #pragma omp sections
1257169695Skan  @{
1258169695Skan    #pragma omp section
1259169695Skan    stmt1;
1260169695Skan    #pragma omp section
1261169695Skan    stmt2;
1262169695Skan    #pragma omp section
1263169695Skan    stmt3;
1264169695Skan  @}
1265169695Skan@end smallexample
1266169695Skan
1267169695Skanbecomes
1268169695Skan
1269169695Skan@smallexample
1270169695Skan  for (i = GOMP_sections_start (3); i != 0; i = GOMP_sections_next ())
1271169695Skan    switch (i)
1272169695Skan      @{
1273169695Skan      case 1:
1274169695Skan        stmt1;
1275169695Skan        break;
1276169695Skan      case 2:
1277169695Skan        stmt2;
1278169695Skan        break;
1279169695Skan      case 3:
1280169695Skan        stmt3;
1281169695Skan        break;
1282169695Skan      @}
1283169695Skan  GOMP_barrier ();
1284169695Skan@end smallexample
1285169695Skan
1286169695Skan
1287169695Skan@node Implementing SINGLE construct
1288169695Skan@section Implementing SINGLE construct
1289169695Skan
1290169695SkanA block like 
1291169695Skan
1292169695Skan@smallexample
1293169695Skan  #pragma omp single
1294169695Skan  @{
1295169695Skan    body;
1296169695Skan  @}
1297169695Skan@end smallexample
1298169695Skan
1299169695Skanbecomes
1300169695Skan
1301169695Skan@smallexample
1302169695Skan  if (GOMP_single_start ())
1303169695Skan    body;
1304169695Skan  GOMP_barrier ();
1305169695Skan@end smallexample
1306169695Skan
1307169695Skanwhile 
1308169695Skan
1309169695Skan@smallexample
1310169695Skan  #pragma omp single copyprivate(x)
1311169695Skan    body;
1312169695Skan@end smallexample
1313169695Skan
1314169695Skanbecomes
1315169695Skan
1316169695Skan@smallexample
1317169695Skan  datap = GOMP_single_copy_start ();
1318169695Skan  if (datap == NULL)
1319169695Skan    @{
1320169695Skan      body;
1321169695Skan      data.x = x;
1322169695Skan      GOMP_single_copy_end (&data);
1323169695Skan    @}
1324169695Skan  else
1325169695Skan    x = datap->x;
1326169695Skan  GOMP_barrier ();
1327169695Skan@end smallexample
1328169695Skan
1329169695Skan
1330169695Skan
1331169695Skan@c ---------------------------------------------------------------------
1332169695Skan@c 
1333169695Skan@c ---------------------------------------------------------------------
1334169695Skan
1335169695Skan@node Reporting Bugs
1336169695Skan@chapter Reporting Bugs
1337169695Skan
1338169695SkanBugs in the GNU OpenMP implementation should be reported via 
1339169695Skan@uref{http://gcc.gnu.org/bugzilla/, bugzilla}. In all cases, please add 
1340169695Skan"openmp" to the keywords field in the bug report.
1341169695Skan
1342169695Skan
1343169695Skan
1344169695Skan@c ---------------------------------------------------------------------
1345169695Skan@c GNU General Public License
1346169695Skan@c ---------------------------------------------------------------------
1347169695Skan
1348169695Skan@include gpl.texi
1349169695Skan
1350169695Skan
1351169695Skan
1352169695Skan@c ---------------------------------------------------------------------
1353169695Skan@c GNU Free Documentation License
1354169695Skan@c ---------------------------------------------------------------------
1355169695Skan
1356169695Skan@include fdl.texi
1357169695Skan
1358169695Skan
1359169695Skan
1360169695Skan@c ---------------------------------------------------------------------
1361169695Skan@c Funding Free Software
1362169695Skan@c ---------------------------------------------------------------------
1363169695Skan
1364169695Skan@include funding.texi
1365169695Skan
1366169695Skan@c ---------------------------------------------------------------------
1367169695Skan@c Index
1368169695Skan@c ---------------------------------------------------------------------
1369169695Skan
1370169695Skan@node Index
1371169695Skan@unnumbered Index
1372169695Skan
1373169695Skan@printindex cp
1374169695Skan
1375169695Skan@bye
1376