Home | History | Annotate | Line # | Download | only in linux
bar.h revision 1.1
      1  1.1  mrg /* Copyright (C) 2005, 2008, 2009 Free Software Foundation, Inc.
      2  1.1  mrg    Contributed by Richard Henderson <rth (at) redhat.com>.
      3  1.1  mrg 
      4  1.1  mrg    This file is part of the GNU OpenMP Library (libgomp).
      5  1.1  mrg 
      6  1.1  mrg    Libgomp is free software; you can redistribute it and/or modify it
      7  1.1  mrg    under the terms of the GNU General Public License as published by
      8  1.1  mrg    the Free Software Foundation; either version 3, or (at your option)
      9  1.1  mrg    any later version.
     10  1.1  mrg 
     11  1.1  mrg    Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
     12  1.1  mrg    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
     13  1.1  mrg    FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
     14  1.1  mrg    more details.
     15  1.1  mrg 
     16  1.1  mrg    Under Section 7 of GPL version 3, you are granted additional
     17  1.1  mrg    permissions described in the GCC Runtime Library Exception, version
     18  1.1  mrg    3.1, as published by the Free Software Foundation.
     19  1.1  mrg 
     20  1.1  mrg    You should have received a copy of the GNU General Public License and
     21  1.1  mrg    a copy of the GCC Runtime Library Exception along with this program;
     22  1.1  mrg    see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     23  1.1  mrg    <http://www.gnu.org/licenses/>.  */
     24  1.1  mrg 
     25  1.1  mrg /* This is a Linux specific implementation of a barrier synchronization
     26  1.1  mrg    mechanism for libgomp.  This type is private to the library.  This
     27  1.1  mrg    implementation uses atomic instructions and the futex syscall.  */
     28  1.1  mrg 
     29  1.1  mrg #ifndef GOMP_BARRIER_H
     30  1.1  mrg #define GOMP_BARRIER_H 1
     31  1.1  mrg 
     32  1.1  mrg #include "mutex.h"
     33  1.1  mrg 
     34  1.1  mrg typedef struct
     35  1.1  mrg {
     36  1.1  mrg   /* Make sure total/generation is in a mostly read cacheline, while
     37  1.1  mrg      awaited in a separate cacheline.  */
     38  1.1  mrg   unsigned total __attribute__((aligned (64)));
     39  1.1  mrg   unsigned generation;
     40  1.1  mrg   unsigned awaited __attribute__((aligned (64)));
     41  1.1  mrg } gomp_barrier_t;
     42  1.1  mrg typedef unsigned int gomp_barrier_state_t;
     43  1.1  mrg 
     44  1.1  mrg static inline void gomp_barrier_init (gomp_barrier_t *bar, unsigned count)
     45  1.1  mrg {
     46  1.1  mrg   bar->total = count;
     47  1.1  mrg   bar->awaited = count;
     48  1.1  mrg   bar->generation = 0;
     49  1.1  mrg }
     50  1.1  mrg 
     51  1.1  mrg static inline void gomp_barrier_reinit (gomp_barrier_t *bar, unsigned count)
     52  1.1  mrg {
     53  1.1  mrg   __sync_fetch_and_add (&bar->awaited, count - bar->total);
     54  1.1  mrg   bar->total = count;
     55  1.1  mrg }
     56  1.1  mrg 
     57  1.1  mrg static inline void gomp_barrier_destroy (gomp_barrier_t *bar)
     58  1.1  mrg {
     59  1.1  mrg }
     60  1.1  mrg 
     61  1.1  mrg extern void gomp_barrier_wait (gomp_barrier_t *);
     62  1.1  mrg extern void gomp_barrier_wait_last (gomp_barrier_t *);
     63  1.1  mrg extern void gomp_barrier_wait_end (gomp_barrier_t *, gomp_barrier_state_t);
     64  1.1  mrg extern void gomp_team_barrier_wait (gomp_barrier_t *);
     65  1.1  mrg extern void gomp_team_barrier_wait_end (gomp_barrier_t *,
     66  1.1  mrg 					gomp_barrier_state_t);
     67  1.1  mrg extern void gomp_team_barrier_wake (gomp_barrier_t *, int);
     68  1.1  mrg 
     69  1.1  mrg static inline gomp_barrier_state_t
     70  1.1  mrg gomp_barrier_wait_start (gomp_barrier_t *bar)
     71  1.1  mrg {
     72  1.1  mrg   unsigned int ret = bar->generation & ~3;
     73  1.1  mrg   /* Do we need any barrier here or is __sync_add_and_fetch acting
     74  1.1  mrg      as the needed LoadLoad barrier already?  */
     75  1.1  mrg   ret += __sync_add_and_fetch (&bar->awaited, -1) == 0;
     76  1.1  mrg   return ret;
     77  1.1  mrg }
     78  1.1  mrg 
     79  1.1  mrg static inline bool
     80  1.1  mrg gomp_barrier_last_thread (gomp_barrier_state_t state)
     81  1.1  mrg {
     82  1.1  mrg   return state & 1;
     83  1.1  mrg }
     84  1.1  mrg 
     85  1.1  mrg /* All the inlines below must be called with team->task_lock
     86  1.1  mrg    held.  */
     87  1.1  mrg 
     88  1.1  mrg static inline void
     89  1.1  mrg gomp_team_barrier_set_task_pending (gomp_barrier_t *bar)
     90  1.1  mrg {
     91  1.1  mrg   bar->generation |= 1;
     92  1.1  mrg }
     93  1.1  mrg 
     94  1.1  mrg static inline void
     95  1.1  mrg gomp_team_barrier_clear_task_pending (gomp_barrier_t *bar)
     96  1.1  mrg {
     97  1.1  mrg   bar->generation &= ~1;
     98  1.1  mrg }
     99  1.1  mrg 
    100  1.1  mrg static inline void
    101  1.1  mrg gomp_team_barrier_set_waiting_for_tasks (gomp_barrier_t *bar)
    102  1.1  mrg {
    103  1.1  mrg   bar->generation |= 2;
    104  1.1  mrg }
    105  1.1  mrg 
    106  1.1  mrg static inline bool
    107  1.1  mrg gomp_team_barrier_waiting_for_tasks (gomp_barrier_t *bar)
    108  1.1  mrg {
    109  1.1  mrg   return (bar->generation & 2) != 0;
    110  1.1  mrg }
    111  1.1  mrg 
    112  1.1  mrg static inline void
    113  1.1  mrg gomp_team_barrier_done (gomp_barrier_t *bar, gomp_barrier_state_t state)
    114  1.1  mrg {
    115  1.1  mrg   bar->generation = (state & ~3) + 4;
    116  1.1  mrg }
    117  1.1  mrg 
    118  1.1  mrg #endif /* GOMP_BARRIER_H */
    119