1169695Skan/* Copyright (C) 2005 Free Software Foundation, Inc. 2169695Skan Contributed by Richard Henderson <rth@redhat.com>. 3169695Skan 4169695Skan This file is part of the GNU OpenMP Library (libgomp). 5169695Skan 6169695Skan Libgomp is free software; you can redistribute it and/or modify it 7169695Skan under the terms of the GNU Lesser General Public License as published by 8169695Skan the Free Software Foundation; either version 2.1 of the License, or 9169695Skan (at your option) any later version. 10169695Skan 11169695Skan Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY 12169695Skan WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 13169695Skan FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for 14169695Skan more details. 15169695Skan 16169695Skan You should have received a copy of the GNU Lesser General Public License 17169695Skan along with libgomp; see the file COPYING.LIB. If not, write to the 18169695Skan Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 19169695Skan MA 02110-1301, USA. */ 20169695Skan 21169695Skan/* As a special exception, if you link this library with other files, some 22169695Skan of which are compiled with GCC, to produce an executable, this library 23169695Skan does not by itself cause the resulting executable to be covered by the 24169695Skan GNU General Public License. This exception does not however invalidate 25169695Skan any other reasons why the executable file might be covered by the GNU 26169695Skan General Public License. */ 27169695Skan 28169695Skan/* This file handles the LOOP (FOR/DO) construct. */ 29169695Skan 30169695Skan#include "libgomp.h" 31169695Skan#include <stdlib.h> 32169695Skan 33169695Skan 34169695Skan/* Initialize the given work share construct from the given arguments. */ 35169695Skan 36169695Skanstatic inline void 37169695Skangomp_loop_init (struct gomp_work_share *ws, long start, long end, long incr, 38169695Skan enum gomp_schedule_type sched, long chunk_size) 39169695Skan{ 40169695Skan ws->sched = sched; 41169695Skan ws->chunk_size = chunk_size; 42169695Skan /* Canonicalize loops that have zero iterations to ->next == ->end. */ 43169695Skan ws->end = ((incr > 0 && start > end) || (incr < 0 && start < end)) 44169695Skan ? start : end; 45169695Skan ws->incr = incr; 46169695Skan ws->next = start; 47169695Skan} 48169695Skan 49169695Skan/* The *_start routines are called when first encountering a loop construct 50169695Skan that is not bound directly to a parallel construct. The first thread 51169695Skan that arrives will create the work-share construct; subsequent threads 52169695Skan will see the construct exists and allocate work from it. 53169695Skan 54169695Skan START, END, INCR are the bounds of the loop; due to the restrictions of 55169695Skan OpenMP, these values must be the same in every thread. This is not 56169695Skan verified (nor is it entirely verifiable, since START is not necessarily 57169695Skan retained intact in the work-share data structure). CHUNK_SIZE is the 58169695Skan scheduling parameter; again this must be identical in all threads. 59169695Skan 60169695Skan Returns true if there's any work for this thread to perform. If so, 61169695Skan *ISTART and *IEND are filled with the bounds of the iteration block 62169695Skan allocated to this thread. Returns false if all work was assigned to 63169695Skan other threads prior to this thread's arrival. */ 64169695Skan 65169695Skanstatic bool 66169695Skangomp_loop_static_start (long start, long end, long incr, long chunk_size, 67169695Skan long *istart, long *iend) 68169695Skan{ 69169695Skan struct gomp_thread *thr = gomp_thread (); 70169695Skan 71169695Skan if (gomp_work_share_start (false)) 72169695Skan gomp_loop_init (thr->ts.work_share, start, end, incr, 73169695Skan GFS_STATIC, chunk_size); 74169695Skan gomp_mutex_unlock (&thr->ts.work_share->lock); 75169695Skan 76169695Skan return !gomp_iter_static_next (istart, iend); 77169695Skan} 78169695Skan 79169695Skanstatic bool 80169695Skangomp_loop_dynamic_start (long start, long end, long incr, long chunk_size, 81169695Skan long *istart, long *iend) 82169695Skan{ 83169695Skan struct gomp_thread *thr = gomp_thread (); 84169695Skan bool ret; 85169695Skan 86169695Skan if (gomp_work_share_start (false)) 87169695Skan gomp_loop_init (thr->ts.work_share, start, end, incr, 88169695Skan GFS_DYNAMIC, chunk_size); 89169695Skan 90169695Skan#ifdef HAVE_SYNC_BUILTINS 91169695Skan gomp_mutex_unlock (&thr->ts.work_share->lock); 92169695Skan ret = gomp_iter_dynamic_next (istart, iend); 93169695Skan#else 94169695Skan ret = gomp_iter_dynamic_next_locked (istart, iend); 95169695Skan gomp_mutex_unlock (&thr->ts.work_share->lock); 96169695Skan#endif 97169695Skan 98169695Skan return ret; 99169695Skan} 100169695Skan 101169695Skanstatic bool 102169695Skangomp_loop_guided_start (long start, long end, long incr, long chunk_size, 103169695Skan long *istart, long *iend) 104169695Skan{ 105169695Skan struct gomp_thread *thr = gomp_thread (); 106169695Skan bool ret; 107169695Skan 108169695Skan if (gomp_work_share_start (false)) 109169695Skan gomp_loop_init (thr->ts.work_share, start, end, incr, 110169695Skan GFS_GUIDED, chunk_size); 111169695Skan 112169695Skan#ifdef HAVE_SYNC_BUILTINS 113169695Skan gomp_mutex_unlock (&thr->ts.work_share->lock); 114169695Skan ret = gomp_iter_guided_next (istart, iend); 115169695Skan#else 116169695Skan ret = gomp_iter_guided_next_locked (istart, iend); 117169695Skan gomp_mutex_unlock (&thr->ts.work_share->lock); 118169695Skan#endif 119169695Skan 120169695Skan return ret; 121169695Skan} 122169695Skan 123169695Skanbool 124169695SkanGOMP_loop_runtime_start (long start, long end, long incr, 125169695Skan long *istart, long *iend) 126169695Skan{ 127169695Skan switch (gomp_run_sched_var) 128169695Skan { 129169695Skan case GFS_STATIC: 130169695Skan return gomp_loop_static_start (start, end, incr, gomp_run_sched_chunk, 131169695Skan istart, iend); 132169695Skan case GFS_DYNAMIC: 133169695Skan return gomp_loop_dynamic_start (start, end, incr, gomp_run_sched_chunk, 134169695Skan istart, iend); 135169695Skan case GFS_GUIDED: 136169695Skan return gomp_loop_guided_start (start, end, incr, gomp_run_sched_chunk, 137169695Skan istart, iend); 138169695Skan default: 139169695Skan abort (); 140169695Skan } 141169695Skan} 142169695Skan 143169695Skan/* The *_ordered_*_start routines are similar. The only difference is that 144169695Skan this work-share construct is initialized to expect an ORDERED section. */ 145169695Skan 146169695Skanstatic bool 147169695Skangomp_loop_ordered_static_start (long start, long end, long incr, 148169695Skan long chunk_size, long *istart, long *iend) 149169695Skan{ 150169695Skan struct gomp_thread *thr = gomp_thread (); 151169695Skan 152169695Skan if (gomp_work_share_start (true)) 153169695Skan { 154169695Skan gomp_loop_init (thr->ts.work_share, start, end, incr, 155169695Skan GFS_STATIC, chunk_size); 156169695Skan gomp_ordered_static_init (); 157169695Skan } 158169695Skan gomp_mutex_unlock (&thr->ts.work_share->lock); 159169695Skan 160169695Skan return !gomp_iter_static_next (istart, iend); 161169695Skan} 162169695Skan 163169695Skanstatic bool 164169695Skangomp_loop_ordered_dynamic_start (long start, long end, long incr, 165169695Skan long chunk_size, long *istart, long *iend) 166169695Skan{ 167169695Skan struct gomp_thread *thr = gomp_thread (); 168169695Skan bool ret; 169169695Skan 170169695Skan if (gomp_work_share_start (true)) 171169695Skan gomp_loop_init (thr->ts.work_share, start, end, incr, 172169695Skan GFS_DYNAMIC, chunk_size); 173169695Skan 174169695Skan ret = gomp_iter_dynamic_next_locked (istart, iend); 175169695Skan if (ret) 176169695Skan gomp_ordered_first (); 177169695Skan gomp_mutex_unlock (&thr->ts.work_share->lock); 178169695Skan 179169695Skan return ret; 180169695Skan} 181169695Skan 182169695Skanstatic bool 183169695Skangomp_loop_ordered_guided_start (long start, long end, long incr, 184169695Skan long chunk_size, long *istart, long *iend) 185169695Skan{ 186169695Skan struct gomp_thread *thr = gomp_thread (); 187169695Skan bool ret; 188169695Skan 189169695Skan if (gomp_work_share_start (true)) 190169695Skan gomp_loop_init (thr->ts.work_share, start, end, incr, 191169695Skan GFS_GUIDED, chunk_size); 192169695Skan 193169695Skan ret = gomp_iter_guided_next_locked (istart, iend); 194169695Skan if (ret) 195169695Skan gomp_ordered_first (); 196169695Skan gomp_mutex_unlock (&thr->ts.work_share->lock); 197169695Skan 198169695Skan return ret; 199169695Skan} 200169695Skan 201169695Skanbool 202169695SkanGOMP_loop_ordered_runtime_start (long start, long end, long incr, 203169695Skan long *istart, long *iend) 204169695Skan{ 205169695Skan switch (gomp_run_sched_var) 206169695Skan { 207169695Skan case GFS_STATIC: 208169695Skan return gomp_loop_ordered_static_start (start, end, incr, 209169695Skan gomp_run_sched_chunk, 210169695Skan istart, iend); 211169695Skan case GFS_DYNAMIC: 212169695Skan return gomp_loop_ordered_dynamic_start (start, end, incr, 213169695Skan gomp_run_sched_chunk, 214169695Skan istart, iend); 215169695Skan case GFS_GUIDED: 216169695Skan return gomp_loop_ordered_guided_start (start, end, incr, 217169695Skan gomp_run_sched_chunk, 218169695Skan istart, iend); 219169695Skan default: 220169695Skan abort (); 221169695Skan } 222169695Skan} 223169695Skan 224169695Skan/* The *_next routines are called when the thread completes processing of 225169695Skan the iteration block currently assigned to it. If the work-share 226169695Skan construct is bound directly to a parallel construct, then the iteration 227169695Skan bounds may have been set up before the parallel. In which case, this 228169695Skan may be the first iteration for the thread. 229169695Skan 230169695Skan Returns true if there is work remaining to be performed; *ISTART and 231169695Skan *IEND are filled with a new iteration block. Returns false if all work 232169695Skan has been assigned. */ 233169695Skan 234169695Skanstatic bool 235169695Skangomp_loop_static_next (long *istart, long *iend) 236169695Skan{ 237169695Skan return !gomp_iter_static_next (istart, iend); 238169695Skan} 239169695Skan 240169695Skanstatic bool 241169695Skangomp_loop_dynamic_next (long *istart, long *iend) 242169695Skan{ 243169695Skan bool ret; 244169695Skan 245169695Skan#ifdef HAVE_SYNC_BUILTINS 246169695Skan ret = gomp_iter_dynamic_next (istart, iend); 247169695Skan#else 248169695Skan struct gomp_thread *thr = gomp_thread (); 249169695Skan gomp_mutex_lock (&thr->ts.work_share->lock); 250169695Skan ret = gomp_iter_dynamic_next_locked (istart, iend); 251169695Skan gomp_mutex_unlock (&thr->ts.work_share->lock); 252169695Skan#endif 253169695Skan 254169695Skan return ret; 255169695Skan} 256169695Skan 257169695Skanstatic bool 258169695Skangomp_loop_guided_next (long *istart, long *iend) 259169695Skan{ 260169695Skan bool ret; 261169695Skan 262169695Skan#ifdef HAVE_SYNC_BUILTINS 263169695Skan ret = gomp_iter_guided_next (istart, iend); 264169695Skan#else 265169695Skan struct gomp_thread *thr = gomp_thread (); 266169695Skan gomp_mutex_lock (&thr->ts.work_share->lock); 267169695Skan ret = gomp_iter_guided_next_locked (istart, iend); 268169695Skan gomp_mutex_unlock (&thr->ts.work_share->lock); 269169695Skan#endif 270169695Skan 271169695Skan return ret; 272169695Skan} 273169695Skan 274169695Skanbool 275169695SkanGOMP_loop_runtime_next (long *istart, long *iend) 276169695Skan{ 277169695Skan struct gomp_thread *thr = gomp_thread (); 278169695Skan 279169695Skan switch (thr->ts.work_share->sched) 280169695Skan { 281169695Skan case GFS_STATIC: 282169695Skan return gomp_loop_static_next (istart, iend); 283169695Skan case GFS_DYNAMIC: 284169695Skan return gomp_loop_dynamic_next (istart, iend); 285169695Skan case GFS_GUIDED: 286169695Skan return gomp_loop_guided_next (istart, iend); 287169695Skan default: 288169695Skan abort (); 289169695Skan } 290169695Skan} 291169695Skan 292169695Skan/* The *_ordered_*_next routines are called when the thread completes 293169695Skan processing of the iteration block currently assigned to it. 294169695Skan 295169695Skan Returns true if there is work remaining to be performed; *ISTART and 296169695Skan *IEND are filled with a new iteration block. Returns false if all work 297169695Skan has been assigned. */ 298169695Skan 299169695Skanstatic bool 300169695Skangomp_loop_ordered_static_next (long *istart, long *iend) 301169695Skan{ 302169695Skan struct gomp_thread *thr = gomp_thread (); 303169695Skan int test; 304169695Skan 305169695Skan gomp_ordered_sync (); 306169695Skan gomp_mutex_lock (&thr->ts.work_share->lock); 307169695Skan test = gomp_iter_static_next (istart, iend); 308169695Skan if (test >= 0) 309169695Skan gomp_ordered_static_next (); 310169695Skan gomp_mutex_unlock (&thr->ts.work_share->lock); 311169695Skan 312169695Skan return test == 0; 313169695Skan} 314169695Skan 315169695Skanstatic bool 316169695Skangomp_loop_ordered_dynamic_next (long *istart, long *iend) 317169695Skan{ 318169695Skan struct gomp_thread *thr = gomp_thread (); 319169695Skan bool ret; 320169695Skan 321169695Skan gomp_ordered_sync (); 322169695Skan gomp_mutex_lock (&thr->ts.work_share->lock); 323169695Skan ret = gomp_iter_dynamic_next_locked (istart, iend); 324169695Skan if (ret) 325169695Skan gomp_ordered_next (); 326169695Skan else 327169695Skan gomp_ordered_last (); 328169695Skan gomp_mutex_unlock (&thr->ts.work_share->lock); 329169695Skan 330169695Skan return ret; 331169695Skan} 332169695Skan 333169695Skanstatic bool 334169695Skangomp_loop_ordered_guided_next (long *istart, long *iend) 335169695Skan{ 336169695Skan struct gomp_thread *thr = gomp_thread (); 337169695Skan bool ret; 338169695Skan 339169695Skan gomp_ordered_sync (); 340169695Skan gomp_mutex_lock (&thr->ts.work_share->lock); 341169695Skan ret = gomp_iter_guided_next_locked (istart, iend); 342169695Skan if (ret) 343169695Skan gomp_ordered_next (); 344169695Skan else 345169695Skan gomp_ordered_last (); 346169695Skan gomp_mutex_unlock (&thr->ts.work_share->lock); 347169695Skan 348169695Skan return ret; 349169695Skan} 350169695Skan 351169695Skanbool 352169695SkanGOMP_loop_ordered_runtime_next (long *istart, long *iend) 353169695Skan{ 354169695Skan struct gomp_thread *thr = gomp_thread (); 355169695Skan 356169695Skan switch (thr->ts.work_share->sched) 357169695Skan { 358169695Skan case GFS_STATIC: 359169695Skan return gomp_loop_ordered_static_next (istart, iend); 360169695Skan case GFS_DYNAMIC: 361169695Skan return gomp_loop_ordered_dynamic_next (istart, iend); 362169695Skan case GFS_GUIDED: 363169695Skan return gomp_loop_ordered_guided_next (istart, iend); 364169695Skan default: 365169695Skan abort (); 366169695Skan } 367169695Skan} 368169695Skan 369169695Skan/* The GOMP_parallel_loop_* routines pre-initialize a work-share construct 370169695Skan to avoid one synchronization once we get into the loop. */ 371169695Skan 372169695Skanstatic void 373169695Skangomp_parallel_loop_start (void (*fn) (void *), void *data, 374169695Skan unsigned num_threads, long start, long end, 375169695Skan long incr, enum gomp_schedule_type sched, 376169695Skan long chunk_size) 377169695Skan{ 378169695Skan struct gomp_work_share *ws; 379169695Skan 380169695Skan num_threads = gomp_resolve_num_threads (num_threads); 381169695Skan ws = gomp_new_work_share (false, num_threads); 382169695Skan gomp_loop_init (ws, start, end, incr, sched, chunk_size); 383169695Skan gomp_team_start (fn, data, num_threads, ws); 384169695Skan} 385169695Skan 386169695Skanvoid 387169695SkanGOMP_parallel_loop_static_start (void (*fn) (void *), void *data, 388169695Skan unsigned num_threads, long start, long end, 389169695Skan long incr, long chunk_size) 390169695Skan{ 391169695Skan gomp_parallel_loop_start (fn, data, num_threads, start, end, incr, 392169695Skan GFS_STATIC, chunk_size); 393169695Skan} 394169695Skan 395169695Skanvoid 396169695SkanGOMP_parallel_loop_dynamic_start (void (*fn) (void *), void *data, 397169695Skan unsigned num_threads, long start, long end, 398169695Skan long incr, long chunk_size) 399169695Skan{ 400169695Skan gomp_parallel_loop_start (fn, data, num_threads, start, end, incr, 401169695Skan GFS_DYNAMIC, chunk_size); 402169695Skan} 403169695Skan 404169695Skanvoid 405169695SkanGOMP_parallel_loop_guided_start (void (*fn) (void *), void *data, 406169695Skan unsigned num_threads, long start, long end, 407169695Skan long incr, long chunk_size) 408169695Skan{ 409169695Skan gomp_parallel_loop_start (fn, data, num_threads, start, end, incr, 410169695Skan GFS_GUIDED, chunk_size); 411169695Skan} 412169695Skan 413169695Skanvoid 414169695SkanGOMP_parallel_loop_runtime_start (void (*fn) (void *), void *data, 415169695Skan unsigned num_threads, long start, long end, 416169695Skan long incr) 417169695Skan{ 418169695Skan gomp_parallel_loop_start (fn, data, num_threads, start, end, incr, 419169695Skan gomp_run_sched_var, gomp_run_sched_chunk); 420169695Skan} 421169695Skan 422169695Skan/* The GOMP_loop_end* routines are called after the thread is told that 423169695Skan all loop iterations are complete. This first version synchronizes 424169695Skan all threads; the nowait version does not. */ 425169695Skan 426169695Skanvoid 427169695SkanGOMP_loop_end (void) 428169695Skan{ 429169695Skan gomp_work_share_end (); 430169695Skan} 431169695Skan 432169695Skanvoid 433169695SkanGOMP_loop_end_nowait (void) 434169695Skan{ 435169695Skan gomp_work_share_end_nowait (); 436169695Skan} 437169695Skan 438169695Skan 439169695Skan/* We use static functions above so that we're sure that the "runtime" 440169695Skan function can defer to the proper routine without interposition. We 441169695Skan export the static function with a strong alias when possible, or with 442169695Skan a wrapper function otherwise. */ 443169695Skan 444169695Skan#ifdef HAVE_ATTRIBUTE_ALIAS 445169695Skanextern __typeof(gomp_loop_static_start) GOMP_loop_static_start 446169695Skan __attribute__((alias ("gomp_loop_static_start"))); 447169695Skanextern __typeof(gomp_loop_dynamic_start) GOMP_loop_dynamic_start 448169695Skan __attribute__((alias ("gomp_loop_dynamic_start"))); 449169695Skanextern __typeof(gomp_loop_guided_start) GOMP_loop_guided_start 450169695Skan __attribute__((alias ("gomp_loop_guided_start"))); 451169695Skan 452169695Skanextern __typeof(gomp_loop_ordered_static_start) GOMP_loop_ordered_static_start 453169695Skan __attribute__((alias ("gomp_loop_ordered_static_start"))); 454169695Skanextern __typeof(gomp_loop_ordered_dynamic_start) GOMP_loop_ordered_dynamic_start 455169695Skan __attribute__((alias ("gomp_loop_ordered_dynamic_start"))); 456169695Skanextern __typeof(gomp_loop_ordered_guided_start) GOMP_loop_ordered_guided_start 457169695Skan __attribute__((alias ("gomp_loop_ordered_guided_start"))); 458169695Skan 459169695Skanextern __typeof(gomp_loop_static_next) GOMP_loop_static_next 460169695Skan __attribute__((alias ("gomp_loop_static_next"))); 461169695Skanextern __typeof(gomp_loop_dynamic_next) GOMP_loop_dynamic_next 462169695Skan __attribute__((alias ("gomp_loop_dynamic_next"))); 463169695Skanextern __typeof(gomp_loop_guided_next) GOMP_loop_guided_next 464169695Skan __attribute__((alias ("gomp_loop_guided_next"))); 465169695Skan 466169695Skanextern __typeof(gomp_loop_ordered_static_next) GOMP_loop_ordered_static_next 467169695Skan __attribute__((alias ("gomp_loop_ordered_static_next"))); 468169695Skanextern __typeof(gomp_loop_ordered_dynamic_next) GOMP_loop_ordered_dynamic_next 469169695Skan __attribute__((alias ("gomp_loop_ordered_dynamic_next"))); 470169695Skanextern __typeof(gomp_loop_ordered_guided_next) GOMP_loop_ordered_guided_next 471169695Skan __attribute__((alias ("gomp_loop_ordered_guided_next"))); 472169695Skan#else 473169695Skanbool 474169695SkanGOMP_loop_static_start (long start, long end, long incr, long chunk_size, 475169695Skan long *istart, long *iend) 476169695Skan{ 477169695Skan return gomp_loop_static_start (start, end, incr, chunk_size, istart, iend); 478169695Skan} 479169695Skan 480169695Skanbool 481169695SkanGOMP_loop_dynamic_start (long start, long end, long incr, long chunk_size, 482169695Skan long *istart, long *iend) 483169695Skan{ 484169695Skan return gomp_loop_dynamic_start (start, end, incr, chunk_size, istart, iend); 485169695Skan} 486169695Skan 487169695Skanbool 488169695SkanGOMP_loop_guided_start (long start, long end, long incr, long chunk_size, 489169695Skan long *istart, long *iend) 490169695Skan{ 491169695Skan return gomp_loop_guided_start (start, end, incr, chunk_size, istart, iend); 492169695Skan} 493169695Skan 494169695Skanbool 495169695SkanGOMP_loop_ordered_static_start (long start, long end, long incr, 496169695Skan long chunk_size, long *istart, long *iend) 497169695Skan{ 498169695Skan return gomp_loop_ordered_static_start (start, end, incr, chunk_size, 499169695Skan istart, iend); 500169695Skan} 501169695Skan 502169695Skanbool 503169695SkanGOMP_loop_ordered_dynamic_start (long start, long end, long incr, 504169695Skan long chunk_size, long *istart, long *iend) 505169695Skan{ 506169695Skan return gomp_loop_ordered_dynamic_start (start, end, incr, chunk_size, 507169695Skan istart, iend); 508169695Skan} 509169695Skan 510169695Skanbool 511169695SkanGOMP_loop_ordered_guided_start (long start, long end, long incr, 512169695Skan long chunk_size, long *istart, long *iend) 513169695Skan{ 514169695Skan return gomp_loop_ordered_guided_start (start, end, incr, chunk_size, 515169695Skan istart, iend); 516169695Skan} 517169695Skan 518169695Skanbool 519169695SkanGOMP_loop_static_next (long *istart, long *iend) 520169695Skan{ 521169695Skan return gomp_loop_static_next (istart, iend); 522169695Skan} 523169695Skan 524169695Skanbool 525169695SkanGOMP_loop_dynamic_next (long *istart, long *iend) 526169695Skan{ 527169695Skan return gomp_loop_dynamic_next (istart, iend); 528169695Skan} 529169695Skan 530169695Skanbool 531169695SkanGOMP_loop_guided_next (long *istart, long *iend) 532169695Skan{ 533169695Skan return gomp_loop_guided_next (istart, iend); 534169695Skan} 535169695Skan 536169695Skanbool 537169695SkanGOMP_loop_ordered_static_next (long *istart, long *iend) 538169695Skan{ 539169695Skan return gomp_loop_ordered_static_next (istart, iend); 540169695Skan} 541169695Skan 542169695Skanbool 543169695SkanGOMP_loop_ordered_dynamic_next (long *istart, long *iend) 544169695Skan{ 545169695Skan return gomp_loop_ordered_dynamic_next (istart, iend); 546169695Skan} 547169695Skan 548169695Skanbool 549169695SkanGOMP_loop_ordered_guided_next (long *istart, long *iend) 550169695Skan{ 551169695Skan return gomp_loop_ordered_guided_next (istart, iend); 552169695Skan} 553169695Skan#endif 554