bar.c revision 169695
1251886Speter/* Copyright (C) 2005 Free Software Foundation, Inc.
2251886Speter   Contributed by Richard Henderson <rth@redhat.com>.
3264400Simp
4251886Speter   This file is part of the GNU OpenMP Library (libgomp).
5251886Speter
6251886Speter   Libgomp is free software; you can redistribute it and/or modify it
7251886Speter   under the terms of the GNU Lesser General Public License as published by
8251886Speter   the Free Software Foundation; either version 2.1 of the License, or
9251886Speter   (at your option) any later version.
10251886Speter
11251886Speter   Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
12251886Speter   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13251886Speter   FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
14251886Speter   more details.
15251886Speter
16251886Speter   You should have received a copy of the GNU Lesser General Public License
17251886Speter   along with libgomp; see the file COPYING.LIB.  If not, write to the
18251886Speter   Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19251886Speter   MA 02110-1301, USA.  */
20251886Speter
21251886Speter/* As a special exception, if you link this library with other files, some
22251886Speter   of which are compiled with GCC, to produce an executable, this library
23251886Speter   does not by itself cause the resulting executable to be covered by the
24289180Speter   GNU General Public License.  This exception does not however invalidate
25251886Speter   any other reasons why the executable file might be covered by the GNU
26251886Speter   General Public License.  */
27251886Speter
28251886Speter/* This is a Linux specific implementation of a barrier synchronization
29275079Sbapt   mechanism for libgomp.  This type is private to the library.  This
30275079Sbapt   implementation uses atomic instructions and the futex syscall.  */
31251886Speter
32251886Speter#include "libgomp.h"
33251886Speter#include "futex.h"
34275079Sbapt#include <limits.h>
35251886Speter
36251886Speter
37void
38gomp_barrier_wait_end (gomp_barrier_t *bar, bool last)
39{
40  if (last)
41    {
42      bar->generation++;
43      futex_wake (&bar->generation, INT_MAX);
44    }
45  else
46    {
47      unsigned int generation = bar->generation;
48
49      gomp_mutex_unlock (&bar->mutex);
50
51      do
52	futex_wait (&bar->generation, generation);
53      while (bar->generation == generation);
54    }
55
56  if (__sync_add_and_fetch (&bar->arrived, -1) == 0)
57    gomp_mutex_unlock (&bar->mutex);
58}
59
60void
61gomp_barrier_wait (gomp_barrier_t *barrier)
62{
63  gomp_barrier_wait_end (barrier, gomp_barrier_wait_start (barrier));
64}
65