OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgomp/] [config/] [posix/] [bar.c] - Blame information for rev 735

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 735 jeremybenn
/* Copyright (C) 2005, 2008, 2009 Free Software Foundation, Inc.
2
   Contributed by Richard Henderson <rth@redhat.com>.
3
 
4
   This file is part of the GNU OpenMP Library (libgomp).
5
 
6
   Libgomp is free software; you can redistribute it and/or modify it
7
   under the terms of the GNU General Public License as published by
8
   the Free Software Foundation; either version 3, or (at your option)
9
   any later version.
10
 
11
   Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
12
   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13
   FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
14
   more details.
15
 
16
   Under Section 7 of GPL version 3, you are granted additional
17
   permissions described in the GCC Runtime Library Exception, version
18
   3.1, as published by the Free Software Foundation.
19
 
20
   You should have received a copy of the GNU General Public License and
21
   a copy of the GCC Runtime Library Exception along with this program;
22
   see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23
   <http://www.gnu.org/licenses/>.  */
24
 
25
/* This is the default implementation of a barrier synchronization mechanism
26
   for libgomp.  This type is private to the library.  Note that we rely on
27
   being able to adjust the barrier count while threads are blocked, so the
28
   POSIX pthread_barrier_t won't work.  */
29
 
30
#include "libgomp.h"
31
 
32
 
33
void
34
gomp_barrier_init (gomp_barrier_t *bar, unsigned count)
35
{
36
  gomp_mutex_init (&bar->mutex1);
37
#ifndef HAVE_SYNC_BUILTINS
38
  gomp_mutex_init (&bar->mutex2);
39
#endif
40
  gomp_sem_init (&bar->sem1, 0);
41
  gomp_sem_init (&bar->sem2, 0);
42
  bar->total = count;
43
  bar->arrived = 0;
44
  bar->generation = 0;
45
}
46
 
47
void
48
gomp_barrier_destroy (gomp_barrier_t *bar)
49
{
50
  /* Before destroying, make sure all threads have left the barrier.  */
51
  gomp_mutex_lock (&bar->mutex1);
52
  gomp_mutex_unlock (&bar->mutex1);
53
 
54
  gomp_mutex_destroy (&bar->mutex1);
55
#ifndef HAVE_SYNC_BUILTINS
56
  gomp_mutex_destroy (&bar->mutex2);
57
#endif
58
  gomp_sem_destroy (&bar->sem1);
59
  gomp_sem_destroy (&bar->sem2);
60
}
61
 
62
void
63
gomp_barrier_reinit (gomp_barrier_t *bar, unsigned count)
64
{
65
  gomp_mutex_lock (&bar->mutex1);
66
  bar->total = count;
67
  gomp_mutex_unlock (&bar->mutex1);
68
}
69
 
70
void
71
gomp_barrier_wait_end (gomp_barrier_t *bar, gomp_barrier_state_t state)
72
{
73
  unsigned int n;
74
 
75
  if (state & 1)
76
    {
77
      n = --bar->arrived;
78
      if (n > 0)
79
        {
80
          do
81
            gomp_sem_post (&bar->sem1);
82
          while (--n != 0);
83
          gomp_sem_wait (&bar->sem2);
84
        }
85
      gomp_mutex_unlock (&bar->mutex1);
86
    }
87
  else
88
    {
89
      gomp_mutex_unlock (&bar->mutex1);
90
      gomp_sem_wait (&bar->sem1);
91
 
92
#ifdef HAVE_SYNC_BUILTINS
93
      n = __sync_add_and_fetch (&bar->arrived, -1);
94
#else
95
      gomp_mutex_lock (&bar->mutex2);
96
      n = --bar->arrived;
97
      gomp_mutex_unlock (&bar->mutex2);
98
#endif
99
 
100
      if (n == 0)
101
        gomp_sem_post (&bar->sem2);
102
    }
103
}
104
 
105
void
106
gomp_barrier_wait (gomp_barrier_t *barrier)
107
{
108
  gomp_barrier_wait_end (barrier, gomp_barrier_wait_start (barrier));
109
}
110
 
111
void
112
gomp_team_barrier_wait_end (gomp_barrier_t *bar, gomp_barrier_state_t state)
113
{
114
  unsigned int n;
115
 
116
  if (state & 1)
117
    {
118
      n = --bar->arrived;
119
      struct gomp_thread *thr = gomp_thread ();
120
      struct gomp_team *team = thr->ts.team;
121
 
122
      if (team->task_count)
123
        {
124
          gomp_barrier_handle_tasks (state);
125
          if (n > 0)
126
            gomp_sem_wait (&bar->sem2);
127
          gomp_mutex_unlock (&bar->mutex1);
128
          return;
129
        }
130
 
131
      bar->generation = state + 3;
132
      if (n > 0)
133
        {
134
          do
135
            gomp_sem_post (&bar->sem1);
136
          while (--n != 0);
137
          gomp_sem_wait (&bar->sem2);
138
        }
139
      gomp_mutex_unlock (&bar->mutex1);
140
    }
141
  else
142
    {
143
      gomp_mutex_unlock (&bar->mutex1);
144
      do
145
        {
146
          gomp_sem_wait (&bar->sem1);
147
          if (bar->generation & 1)
148
            gomp_barrier_handle_tasks (state);
149
        }
150
      while (bar->generation != state + 4);
151
 
152
#ifdef HAVE_SYNC_BUILTINS
153
      n = __sync_add_and_fetch (&bar->arrived, -1);
154
#else
155
      gomp_mutex_lock (&bar->mutex2);
156
      n = --bar->arrived;
157
      gomp_mutex_unlock (&bar->mutex2);
158
#endif
159
 
160
      if (n == 0)
161
        gomp_sem_post (&bar->sem2);
162
    }
163
}
164
 
165
void
166
gomp_team_barrier_wait (gomp_barrier_t *barrier)
167
{
168
  gomp_team_barrier_wait_end (barrier, gomp_barrier_wait_start (barrier));
169
}
170
 
171
void
172
gomp_team_barrier_wake (gomp_barrier_t *bar, int count)
173
{
174
  if (count == 0)
175
    count = bar->total - 1;
176
  while (count-- > 0)
177
    gomp_sem_post (&bar->sem1);
178
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.