/* Copyright (C) 2005-2019 Free Software Foundation, Inc.
   Contributed by Richard Henderson <rth@redhat.com>.

   This file is part of the GNU Offloading and Multi Processing Library
   (libgomp).

   Libgomp is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3, or (at your option)
   any later version.

   Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   more details.

   Under Section 7 of GPL version 3, you are granted additional
   permissions described in the GCC Runtime Library Exception, version
   3.1, as published by the Free Software Foundation.

   You should have received a copy of the GNU General Public License and
   a copy of the GCC Runtime Library Exception along with this program;
   see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
   <http://www.gnu.org/licenses/>.  */

/* This file handles the ORDERED construct.  */

#include "libgomp.h"
#include <stdarg.h>
#include <string.h>
#include "doacross.h"


/* This function is called when first allocating an iteration block.  That
   is, the thread is not currently on the queue.  The work-share lock must
   be held on entry.  */

void
gomp_ordered_first (void)
{
  struct gomp_thread *thr = gomp_thread ();
  struct gomp_team *team = thr->ts.team;
  struct gomp_work_share *ws = thr->ts.work_share;
  unsigned index;

  /* Work share constructs can be orphaned.  */
  if (team == NULL || team->nthreads == 1)
    return;

  index = ws->ordered_cur + ws->ordered_num_used;
  if (index >= team->nthreads)
    index -= team->nthreads;
  ws->ordered_team_ids[index] = thr->ts.team_id;

  /* If this is the first and only thread in the queue, then there is
     no one to release us when we get to our ordered section.  Post to
     our own release queue now so that we won't block later.  */
  if (ws->ordered_num_used++ == 0)
    gomp_sem_post (team->ordered_release[thr->ts.team_id]);
}

/* This function is called when completing the last iteration block.  That
   is, there are no more iterations to perform and so the thread should be
   removed from the queue entirely.  Because of the way ORDERED blocks are
   managed, it follows that we currently own access to the ORDERED block,
   and should now pass it on to the next thread.  The work-share lock must
   be held on entry.  */

void
gomp_ordered_last (void)
{
  struct gomp_thread *thr = gomp_thread ();
  struct gomp_team *team = thr->ts.team;
  struct gomp_work_share *ws = thr->ts.work_share;
  unsigned next_id;

  /* Work share constructs can be orphaned.  */
  if (team == NULL || team->nthreads == 1)
    return;

  /* We're no longer the owner.  */
  ws->ordered_owner = -1;

  /* If we're not the last thread in the queue, then wake the next.  */
  if (--ws->ordered_num_used > 0)
    {
      unsigned next = ws->ordered_cur + 1;
      if (next == team->nthreads)
	next = 0;
      ws->ordered_cur = next;

      next_id = ws->ordered_team_ids[next];
      gomp_sem_post (team->ordered_release[next_id]);
    }
}


/* This function is called when allocating a subsequent allocation block.
   That is, we're done with the current iteration block and we're allocating
   another.  This is the logical combination of a call to gomp_ordered_last
   followed by a call to gomp_ordered_first.  The work-share lock must be
   held on entry. */

void
gomp_ordered_next (void)
{
  struct gomp_thread *thr = gomp_thread ();
  struct gomp_team *team = thr->ts.team;
  struct gomp_work_share *ws = thr->ts.work_share;
  unsigned index, next_id;

  /* Work share constructs can be orphaned.  */
  if (team == NULL || team->nthreads == 1)
    return;

  /* We're no longer the owner.  */
  ws->ordered_owner = -1;

  /* If there's only one thread in the queue, that must be us.  */
  if (ws->ordered_num_used == 1)
    {
      /* We have a similar situation as in gomp_ordered_first
	 where we need to post to our own release semaphore.  */
      gomp_sem_post (team->ordered_release[thr->ts.team_id]);
      return;
    }

  /* If the queue is entirely full, then we move ourself to the end of 
     the queue merely by incrementing ordered_cur.  Only if it's not 
     full do we have to write our id.  */
  if (ws->ordered_num_used < team->nthreads)
    {
      index = ws->ordered_cur + ws->ordered_num_used;
      if (index >= team->nthreads)
	index -= team->nthreads;
      ws->ordered_team_ids[index] = thr->ts.team_id;
    }

  index = ws->ordered_cur + 1;
  if (index == team->nthreads)
    index = 0;
  ws->ordered_cur = index;

  next_id = ws->ordered_team_ids[index];
  gomp_sem_post (team->ordered_release[next_id]);
}


/* This function is called when a statically scheduled loop is first
   being created.  */

void
gomp_ordered_static_init (void)
{
  struct gomp_thread *thr = gomp_thread ();
  struct gomp_team *team = thr->ts.team;

  if (team == NULL || team->nthreads == 1)
    return;

  gomp_sem_post (team->ordered_release[0]);
}

/* This function is called when a statically scheduled loop is moving to
   the next allocation block.  Static schedules are not first come first
   served like the others, so we're to move to the numerically next thread,
   not the next thread on a list.  The work-share lock should *not* be held
   on entry.  */

void
gomp_ordered_static_next (void)
{
  struct gomp_thread *thr = gomp_thread ();
  struct gomp_team *team = thr->ts.team;
  struct gomp_work_share *ws = thr->ts.work_share;
  unsigned id = thr->ts.team_id;

  if (team == NULL || team->nthreads == 1)
    return;

  ws->ordered_owner = -1;

  /* This thread currently owns the lock.  Increment the owner.  */
  if (++id == team->nthreads)
    id = 0;
  ws->ordered_team_ids[0] = id;
  gomp_sem_post (team->ordered_release[id]);
}

/* This function is called when we need to assert that the thread owns the
   ordered section.  Due to the problem of posted-but-not-waited semaphores,
   this needs to happen before completing a loop iteration.  */

void
gomp_ordered_sync (void)
{
  struct gomp_thread *thr = gomp_thread ();
  struct gomp_team *team = thr->ts.team;
  struct gomp_work_share *ws = thr->ts.work_share;

  /* Work share constructs can be orphaned.  But this clearly means that
     we are the only thread, and so we automatically own the section.  */
  if (team == NULL || team->nthreads == 1)
    return;

  /* ??? I believe it to be safe to access this data without taking the
     ws->lock.  The only presumed race condition is with the previous
     thread on the queue incrementing ordered_cur such that it points
     to us, concurrently with our check below.  But our team_id is
     already present in the queue, and the other thread will always
     post to our release semaphore.  So the two cases are that we will
     either win the race an momentarily block on the semaphore, or lose
     the race and find the semaphore already unlocked and so not block.
     Either way we get correct results.
     However, there is an implicit flush on entry to an ordered region,
     so we do need to have a barrier here.  If we were taking a lock
     this could be MEMMODEL_RELEASE since the acquire would be coverd
     by the lock.  */

  __atomic_thread_fence (MEMMODEL_ACQ_REL);
  if (ws->ordered_owner != thr->ts.team_id)
    {
      gomp_sem_wait (team->ordered_release[thr->ts.team_id]);
      ws->ordered_owner = thr->ts.team_id;
    }
}

/* This function is called by user code when encountering the start of an
   ORDERED block.  We must check to see if the current thread is at the
   head of the queue, and if not, block.  */

#ifdef HAVE_ATTRIBUTE_ALIAS
extern void GOMP_ordered_start (void)
	__attribute__((alias ("gomp_ordered_sync")));
#else
void
GOMP_ordered_start (void)
{
  gomp_ordered_sync ();
}
#endif

/* This function is called by user code when encountering the end of an
   ORDERED block.  With the current ORDERED implementation there's nothing
   for us to do.

   However, the current implementation has a flaw in that it does not allow
   the next thread into the ORDERED section immediately after the current
   thread exits the ORDERED section in its last iteration.  The existance
   of this function allows the implementation to change.  */

void
GOMP_ordered_end (void)
{
}

/* DOACROSS initialization.  */

#define MAX_COLLAPSED_BITS (__SIZEOF_LONG__ * __CHAR_BIT__)

void
gomp_doacross_init (unsigned ncounts, long *counts, long chunk_size,
		    size_t extra)
{
  struct gomp_thread *thr = gomp_thread ();
  struct gomp_team *team = thr->ts.team;
  struct gomp_work_share *ws = thr->ts.work_share;
  unsigned int i, bits[MAX_COLLAPSED_BITS], num_bits = 0;
  unsigned long ent, num_ents, elt_sz, shift_sz;
  struct gomp_doacross_work_share *doacross;

  if (team == NULL || team->nthreads == 1)
    {
    empty:
      if (!extra)
	ws->doacross = NULL;
      else
	{
	  doacross = gomp_malloc_cleared (sizeof (*doacross) + extra);
	  doacross->extra = (void *) (doacross + 1);
	  ws->doacross = doacross;
	}
      return;
    }

  for (i = 0; i < ncounts; i++)
    {
      /* If any count is 0, GOMP_doacross_{post,wait} can't be called.  */
      if (counts[i] == 0)
	goto empty;

      if (num_bits <= MAX_COLLAPSED_BITS)
	{
	  unsigned int this_bits;
	  if (counts[i] == 1)
	    this_bits = 1;
	  else
	    this_bits = __SIZEOF_LONG__ * __CHAR_BIT__
			- __builtin_clzl (counts[i] - 1);
	  if (num_bits + this_bits <= MAX_COLLAPSED_BITS)
	    {
	      bits[i] = this_bits;
	      num_bits += this_bits;
	    }
	  else
	    num_bits = MAX_COLLAPSED_BITS + 1;
	}
    }

  if (ws->sched == GFS_STATIC)
    num_ents = team->nthreads;
  else if (ws->sched == GFS_GUIDED)
    num_ents = counts[0];
  else
    num_ents = (counts[0] - 1) / chunk_size + 1;
  if (num_bits <= MAX_COLLAPSED_BITS)
    {
      elt_sz = sizeof (unsigned long);
      shift_sz = ncounts * sizeof (unsigned int);
    }
  else
    {
      elt_sz = sizeof (unsigned long) * ncounts;
      shift_sz = 0;
    }
  elt_sz = (elt_sz + 63) & ~63UL;

  doacross = gomp_malloc (sizeof (*doacross) + 63 + num_ents * elt_sz
			  + shift_sz + extra);
  doacross->chunk_size = chunk_size;
  doacross->elt_sz = elt_sz;
  doacross->ncounts = ncounts;
  doacross->flattened = false;
  doacross->array = (unsigned char *)
		    ((((uintptr_t) (doacross + 1)) + 63 + shift_sz)
		     & ~(uintptr_t) 63);
  if (extra)
    {
      doacross->extra = doacross->array + num_ents * elt_sz;
      memset (doacross->extra, '\0', extra);
    }
  else
    doacross->extra = NULL;
  if (num_bits <= MAX_COLLAPSED_BITS)
    {
      unsigned int shift_count = 0;
      doacross->flattened = true;
      for (i = ncounts; i > 0; i--)
	{
	  doacross->shift_counts[i - 1] = shift_count;
	  shift_count += bits[i - 1];
	}
      for (ent = 0; ent < num_ents; ent++)
	*(unsigned long *) (doacross->array + ent * elt_sz) = 0;
    }
  else
    for (ent = 0; ent < num_ents; ent++)
      memset (doacross->array + ent * elt_sz, '\0',
	      sizeof (unsigned long) * ncounts);
  if (ws->sched == GFS_STATIC && chunk_size == 0)
    {
      unsigned long q = counts[0] / num_ents;
      unsigned long t = counts[0] % num_ents;
      doacross->boundary = t * (q + 1);
      doacross->q = q;
      doacross->t = t;
    }
  ws->doacross = doacross;
}

/* DOACROSS POST operation.  */

void
GOMP_doacross_post (long *counts)
{
  struct gomp_thread *thr = gomp_thread ();
  struct gomp_work_share *ws = thr->ts.work_share;
  struct gomp_doacross_work_share *doacross = ws->doacross;
  unsigned long ent;
  unsigned int i;

  if (__builtin_expect (doacross == NULL, 0)
      || __builtin_expect (doacross->array == NULL, 0))
    {
      __sync_synchronize ();
      return;
    }

  if (__builtin_expect (ws->sched == GFS_STATIC, 1))
    ent = thr->ts.team_id;
  else if (ws->sched == GFS_GUIDED)
    ent = counts[0];
  else
    ent = counts[0] / doacross->chunk_size;
  unsigned long *array = (unsigned long *) (doacross->array
					    + ent * doacross->elt_sz);

  if (__builtin_expect (doacross->flattened, 1))
    {
      unsigned long flattened
	= (unsigned long) counts[0] << doacross->shift_counts[0];

      for (i = 1; i < doacross->ncounts; i++)
	flattened |= (unsigned long) counts[i]
		     << doacross->shift_counts[i];
      flattened++;
      if (flattened == __atomic_load_n (array, MEMMODEL_ACQUIRE))
	__atomic_thread_fence (MEMMODEL_RELEASE);
      else
	__atomic_store_n (array, flattened, MEMMODEL_RELEASE);
      return;
    }

  __atomic_thread_fence (MEMMODEL_ACQUIRE);
  for (i = doacross->ncounts; i-- > 0; )
    {
      if (counts[i] + 1UL != __atomic_load_n (&array[i], MEMMODEL_RELAXED))
	__atomic_store_n (&array[i], counts[i] + 1UL, MEMMODEL_RELEASE);
    }
}

/* DOACROSS WAIT operation.  */

void
GOMP_doacross_wait (long first, ...)
{
  struct gomp_thread *thr = gomp_thread ();
  struct gomp_work_share *ws = thr->ts.work_share;
  struct gomp_doacross_work_share *doacross = ws->doacross;
  va_list ap;
  unsigned long ent;
  unsigned int i;

  if (__builtin_expect (doacross == NULL, 0)
      || __builtin_expect (doacross->array == NULL, 0))
    {
      __sync_synchronize ();
      return;
    }

  if (__builtin_expect (ws->sched == GFS_STATIC, 1))
    {
      if (ws->chunk_size == 0)
	{
	  if (first < doacross->boundary)
	    ent = first / (doacross->q + 1);
	  else
	    ent = (first - doacross->boundary) / doacross->q
		  + doacross->t;
	}
      else
	ent = first / ws->chunk_size % thr->ts.team->nthreads;
    }
  else if (ws->sched == GFS_GUIDED)
    ent = first;
  else
    ent = first / doacross->chunk_size;
  unsigned long *array = (unsigned long *) (doacross->array
					    + ent * doacross->elt_sz);

  if (__builtin_expect (doacross->flattened, 1))
    {
      unsigned long flattened
	= (unsigned long) first << doacross->shift_counts[0];
      unsigned long cur;

      va_start (ap, first);
      for (i = 1; i < doacross->ncounts; i++)
	flattened |= (unsigned long) va_arg (ap, long)
		     << doacross->shift_counts[i];
      cur = __atomic_load_n (array, MEMMODEL_ACQUIRE);
      if (flattened < cur)
	{
	  __atomic_thread_fence (MEMMODEL_RELEASE);
	  va_end (ap);
	  return;
	}
      doacross_spin (array, flattened, cur);
      __atomic_thread_fence (MEMMODEL_RELEASE);
      va_end (ap);
      return;
    }

  do
    {
      va_start (ap, first);
      for (i = 0; i < doacross->ncounts; i++)
	{
	  unsigned long thisv
	    = (unsigned long) (i ? va_arg (ap, long) : first) + 1;
	  unsigned long cur = __atomic_load_n (&array[i], MEMMODEL_RELAXED);
	  if (thisv < cur)
	    {
	      i = doacross->ncounts;
	      break;
	    }
	  if (thisv > cur)
	    break;
	}
      va_end (ap);
      if (i == doacross->ncounts)
	break;
      cpu_relax ();
    }
  while (1);
  __sync_synchronize ();
}

typedef unsigned long long gomp_ull;

void
gomp_doacross_ull_init (unsigned ncounts, gomp_ull *counts,
			gomp_ull chunk_size, size_t extra)
{
  struct gomp_thread *thr = gomp_thread ();
  struct gomp_team *team = thr->ts.team;
  struct gomp_work_share *ws = thr->ts.work_share;
  unsigned int i, bits[MAX_COLLAPSED_BITS], num_bits = 0;
  unsigned long ent, num_ents, elt_sz, shift_sz;
  struct gomp_doacross_work_share *doacross;

  if (team == NULL || team->nthreads == 1)
    {
    empty:
      if (!extra)
	ws->doacross = NULL;
      else
	{
	  doacross = gomp_malloc_cleared (sizeof (*doacross) + extra);
	  doacross->extra = (void *) (doacross + 1);
	  ws->doacross = doacross;
	}
      return;
    }

  for (i = 0; i < ncounts; i++)
    {
      /* If any count is 0, GOMP_doacross_{post,wait} can't be called.  */
      if (counts[i] == 0)
	goto empty;

      if (num_bits <= MAX_COLLAPSED_BITS)
	{
	  unsigned int this_bits;
	  if (counts[i] == 1)
	    this_bits = 1;
	  else
	    this_bits = __SIZEOF_LONG_LONG__ * __CHAR_BIT__
			- __builtin_clzll (counts[i] - 1);
	  if (num_bits + this_bits <= MAX_COLLAPSED_BITS)
	    {
	      bits[i] = this_bits;
	      num_bits += this_bits;
	    }
	  else
	    num_bits = MAX_COLLAPSED_BITS + 1;
	}
    }

  if (ws->sched == GFS_STATIC)
    num_ents = team->nthreads;
  else if (ws->sched == GFS_GUIDED)
    num_ents = counts[0];
  else
    num_ents = (counts[0] - 1) / chunk_size + 1;
  if (num_bits <= MAX_COLLAPSED_BITS)
    {
      elt_sz = sizeof (unsigned long);
      shift_sz = ncounts * sizeof (unsigned int);
    }
  else
    {
      if (sizeof (gomp_ull) == sizeof (unsigned long))
	elt_sz = sizeof (gomp_ull) * ncounts;
      else if (sizeof (gomp_ull) == 2 * sizeof (unsigned long))
	elt_sz = sizeof (unsigned long) * 2 * ncounts;
      else
	abort ();
      shift_sz = 0;
    }
  elt_sz = (elt_sz + 63) & ~63UL;

  doacross = gomp_malloc (sizeof (*doacross) + 63 + num_ents * elt_sz
			  + shift_sz);
  doacross->chunk_size_ull = chunk_size;
  doacross->elt_sz = elt_sz;
  doacross->ncounts = ncounts;
  doacross->flattened = false;
  doacross->boundary = 0;
  doacross->array = (unsigned char *)
		    ((((uintptr_t) (doacross + 1)) + 63 + shift_sz)
		     & ~(uintptr_t) 63);
  if (extra)
    {
      doacross->extra = doacross->array + num_ents * elt_sz;
      memset (doacross->extra, '\0', extra);
    }
  else
    doacross->extra = NULL;
  if (num_bits <= MAX_COLLAPSED_BITS)
    {
      unsigned int shift_count = 0;
      doacross->flattened = true;
      for (i = ncounts; i > 0; i--)
	{
	  doacross->shift_counts[i - 1] = shift_count;
	  shift_count += bits[i - 1];
	}
      for (ent = 0; ent < num_ents; ent++)
	*(unsigned long *) (doacross->array + ent * elt_sz) = 0;
    }
  else
    for (ent = 0; ent < num_ents; ent++)
      memset (doacross->array + ent * elt_sz, '\0',
	      sizeof (unsigned long) * ncounts);
  if (ws->sched == GFS_STATIC && chunk_size == 0)
    {
      gomp_ull q = counts[0] / num_ents;
      gomp_ull t = counts[0] % num_ents;
      doacross->boundary_ull = t * (q + 1);
      doacross->q_ull = q;
      doacross->t = t;
    }
  ws->doacross = doacross;
}

/* DOACROSS POST operation.  */

void
GOMP_doacross_ull_post (gomp_ull *counts)
{
  struct gomp_thread *thr = gomp_thread ();
  struct gomp_work_share *ws = thr->ts.work_share;
  struct gomp_doacross_work_share *doacross = ws->doacross;
  unsigned long ent;
  unsigned int i;

  if (__builtin_expect (doacross == NULL, 0)
      || __builtin_expect (doacross->array == NULL, 0))
    {
      __sync_synchronize ();
      return;
    }

  if (__builtin_expect (ws->sched == GFS_STATIC, 1))
    ent = thr->ts.team_id;
  else if (ws->sched == GFS_GUIDED)
    ent = counts[0];
  else
    ent = counts[0] / doacross->chunk_size_ull;

  if (__builtin_expect (doacross->flattened, 1))
    {
      unsigned long *array = (unsigned long *) (doacross->array
			      + ent * doacross->elt_sz);
      gomp_ull flattened
	= counts[0] << doacross->shift_counts[0];

      for (i = 1; i < doacross->ncounts; i++)
	flattened |= counts[i] << doacross->shift_counts[i];
      flattened++;
      if (flattened == __atomic_load_n (array, MEMMODEL_ACQUIRE))
	__atomic_thread_fence (MEMMODEL_RELEASE);
      else
	__atomic_store_n (array, flattened, MEMMODEL_RELEASE);
      return;
    }

  __atomic_thread_fence (MEMMODEL_ACQUIRE);
  if (sizeof (gomp_ull) == sizeof (unsigned long))
    {
      gomp_ull *array = (gomp_ull *) (doacross->array
				      + ent * doacross->elt_sz);

      for (i = doacross->ncounts; i-- > 0; )
	{
	  if (counts[i] + 1UL != __atomic_load_n (&array[i], MEMMODEL_RELAXED))
	    __atomic_store_n (&array[i], counts[i] + 1UL, MEMMODEL_RELEASE);
	}
    }
  else
    {
      unsigned long *array = (unsigned long *) (doacross->array
						+ ent * doacross->elt_sz);

      for (i = doacross->ncounts; i-- > 0; )
	{
	  gomp_ull cull = counts[i] + 1UL;
	  unsigned long c = (unsigned long) cull;
	  if (c != __atomic_load_n (&array[2 * i + 1], MEMMODEL_RELAXED))
	    __atomic_store_n (&array[2 * i + 1], c, MEMMODEL_RELEASE);
	  c = cull >> (__SIZEOF_LONG_LONG__ * __CHAR_BIT__ / 2);
	  if (c != __atomic_load_n (&array[2 * i], MEMMODEL_RELAXED))
	    __atomic_store_n (&array[2 * i], c, MEMMODEL_RELEASE);
	}
    }
}

/* DOACROSS WAIT operation.  */

void
GOMP_doacross_ull_wait (gomp_ull first, ...)
{
  struct gomp_thread *thr = gomp_thread ();
  struct gomp_work_share *ws = thr->ts.work_share;
  struct gomp_doacross_work_share *doacross = ws->doacross;
  va_list ap;
  unsigned long ent;
  unsigned int i;

  if (__builtin_expect (doacross == NULL, 0)
      || __builtin_expect (doacross->array == NULL, 0))
    {
      __sync_synchronize ();
      return;
    }

  if (__builtin_expect (ws->sched == GFS_STATIC, 1))
    {
      if (ws->chunk_size_ull == 0)
	{
	  if (first < doacross->boundary_ull)
	    ent = first / (doacross->q_ull + 1);
	  else
	    ent = (first - doacross->boundary_ull) / doacross->q_ull
		  + doacross->t;
	}
      else
	ent = first / ws->chunk_size_ull % thr->ts.team->nthreads;
    }
  else if (ws->sched == GFS_GUIDED)
    ent = first;
  else
    ent = first / doacross->chunk_size_ull;

  if (__builtin_expect (doacross->flattened, 1))
    {
      unsigned long *array = (unsigned long *) (doacross->array
						+ ent * doacross->elt_sz);
      gomp_ull flattened = first << doacross->shift_counts[0];
      unsigned long cur;

      va_start (ap, first);
      for (i = 1; i < doacross->ncounts; i++)
	flattened |= va_arg (ap, gomp_ull)
		     << doacross->shift_counts[i];
      cur = __atomic_load_n (array, MEMMODEL_ACQUIRE);
      if (flattened < cur)
	{
	  __atomic_thread_fence (MEMMODEL_RELEASE);
	  va_end (ap);
	  return;
	}
      doacross_spin (array, flattened, cur);
      __atomic_thread_fence (MEMMODEL_RELEASE);
      va_end (ap);
      return;
    }

  if (sizeof (gomp_ull) == sizeof (unsigned long))
    {
      gomp_ull *array = (gomp_ull *) (doacross->array
				      + ent * doacross->elt_sz);
      do
	{
	  va_start (ap, first);
	  for (i = 0; i < doacross->ncounts; i++)
	    {
	      gomp_ull thisv
		= (i ? va_arg (ap, gomp_ull) : first) + 1;
	      gomp_ull cur = __atomic_load_n (&array[i], MEMMODEL_RELAXED);
	      if (thisv < cur)
		{
		  i = doacross->ncounts;
		  break;
		}
	      if (thisv > cur)
		break;
	    }
	  va_end (ap);
	  if (i == doacross->ncounts)
	    break;
	  cpu_relax ();
	}
      while (1);
    }
  else
    {
      unsigned long *array = (unsigned long *) (doacross->array
						+ ent * doacross->elt_sz);
      do
	{
	  va_start (ap, first);
	  for (i = 0; i < doacross->ncounts; i++)
	    {
	      gomp_ull thisv
		= (i ? va_arg (ap, gomp_ull) : first) + 1;
	      unsigned long t
		= thisv >> (__SIZEOF_LONG_LONG__ * __CHAR_BIT__ / 2);
	      unsigned long cur
		= __atomic_load_n (&array[2 * i], MEMMODEL_RELAXED);
	      if (t < cur)
		{
		  i = doacross->ncounts;
		  break;
		}
	      if (t > cur)
		break;
	      t = thisv;
	      cur = __atomic_load_n (&array[2 * i + 1], MEMMODEL_RELAXED);
	      if (t < cur)
		{
		  i = doacross->ncounts;
		  break;
		}
	      if (t > cur)
		break;
	    }
	  va_end (ap);
	  if (i == doacross->ncounts)
	    break;
	  cpu_relax ();
	}
      while (1);
    }
  __sync_synchronize ();
}
