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