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