1 /* Copyright (C) 2010 Free Software Foundation, Inc.
2 Contributed by Antoniu Pop <antoniu.pop@gmail.com>.
4 This file is part of the GNU OpenMP Library (libgomp).
6 Libgomp is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
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 Lesser General Public License for
16 You should have received a copy of the GNU Lesser General Public License
17 along with libgomp; see the file COPYING.LIB. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 MA 02110-1301, USA. */
21 /* As a special exception, if you link this library with other files, some
22 of which are compiled with GCC, to produce an executable, this library
23 does not by itself cause the resulting executable to be covered by the
24 GNU General Public License. This exception does not however invalidate
25 any other reasons why the executable file might be covered by the GNU
26 General Public License. */
28 /* This implements the stream communication layer for libGOMP. */
31 #define GOMP_STREAM_H 1
35 /* Define the type and maximum value for the indices used within the
36 stream. The indices are strictly monotonically increasing
37 integers, so we need a type that does not wrap around too fast. An
38 implementation of the wrap-around is necessary for systems where
39 this poses a problem. */
40 /* typedef unsigned long long int gomp_stream_index_t; */
41 #define GOMP_STREAM_MAX_INDEX ULLONG_MAX
44 #define GUARDED_WAKE*/
48 GOMP_STREAM_INITIALIZED = 1,
49 GOMP_STREAM_ALLOCATED = 2,
50 GOMP_STREAM_PRODUCED = 4,
51 GOMP_STREAM_CONSUMED = 8,
52 GOMP_STREAM_ZOMBIE = 16,
53 GOMP_STREAM_STALL = 32
61 } gomp_stream_view_type_t
;
64 struct gomp_stream_task
;
67 /* GOMP_STREAM_VIEW data structure. Producer and consumer tasks
68 connect to a GOMP_STREAM using views. */
70 typedef struct gomp_stream_view
72 /* The stream accessed through this view. WARNING: this field needs
74 struct gomp_stream
*stream
;
76 /* Size in bytes of the burst associated to this view. Later this
77 may become a stream. */
82 /* The alignment directives are needed to ensure these
83 high-potential false-sharing fields are on their own cache
85 /* Lower and upper bounds accessible in the stream through this
87 unsigned long long lower_index
__attribute__((aligned (64)));
88 unsigned long long upper_index
__attribute__((aligned (64)));
90 /* The task using this view. */
91 struct gomp_stream_task
*task
__attribute__((aligned (64)));
93 /* Setting this flag means the process accessing the stream through
94 this view relinquishes his access to the stream (generally when
98 /* Type of this view (read or write). */
99 gomp_stream_view_type_t type
;
101 /* In order to avoid excessive accesses to the global minimum index
102 (released or consumed), which strongly impacts cache traffic, use
103 this duplcated field for an additional level of caching and only
104 update when needed. */
105 unsigned long long local_min_value
;
107 } gomp_stream_view_t
, *gomp_stream_view_p
;
109 /* List of GOMP_STREAM_VIEWs. As this list is only modified in the
110 initialization phase and we never remove items, we'll use an
113 typedef struct gomp_stream_view_list
115 gomp_stream_view_p
*views
;
119 /* Enforce atomic connection of the views in this list. */
120 gomp_mutex_t connect_view_mutex
;
122 } gomp_stream_view_list_t
, *gomp_stream_view_list_p
;
125 /* GOMP_STREAM_VIEW_HANDLE data structure. This allows the tasks
126 interacting through the GOMP_STREAM to which this handle is
127 attached to keep updated information global to all similar views on
130 typedef struct gomp_stream_view_handle
132 /* The alignment directives are needed to ensure these
133 high-potential false-sharing fields are on their own cache
135 /* Latest computed value of the min released index and max acquired
136 index values across views. */
137 volatile unsigned long long current_min
__attribute__((aligned (64)));
138 volatile unsigned long long current_max
__attribute__((aligned (64)));
140 /* Bookkeeping for view connections. */
141 gomp_stream_view_list_t view_list
__attribute__((aligned (64)));
142 int nr_expected_views
;
143 int nr_registered_views
;
144 int nr_unregistered_views
;
146 } gomp_stream_view_handle_t
, *gomp_stream_view_handle_p
;
149 /* GOMP_STREAM data structure. */
151 typedef struct gomp_stream
153 /* WARNING: the first two fields (BUFFER and BUFFER_MASK) need to
154 remain in their respective positions. */
156 /* The pointer to the buffer, as well as the subsequent buffer
157 description, should be on a single mostly read cache line. The
158 EOS_P flag is only set at the very end of the use of this
160 /* Circular buffer containing the data communicated through this
162 char *buffer
__attribute__((aligned (64)));
164 /* Size of the buffer and the bitmask used for modulo computation
165 for the wrap-around. The size is expressed in basic elements for
166 this stream. The size in bytes of the buffer is
167 BUFFER_SIZE * ELEMENT_SIZE. */
168 unsigned long long buffer_size
;
169 unsigned long long buffer_mask
;
170 unsigned long long pre_shift
;
172 /* True once all the tasks that should be expected to connect to
173 this stream been declared. */
174 bool expected_ready_p
;
176 /* True once all the tasks expected to connect to this stream have
180 /* End of stream: true when all producers have finished committing
181 all the data and are terminating. */
184 /* Handles for read and write views on this stream. */
185 gomp_stream_view_handle_t read_views
;
186 gomp_stream_view_handle_t write_views
;
188 /* Barrier used both for waiting for all views to connect to the
189 stream and to find the last view disconnecting (and who therefore
190 frees this stream). */
191 /*gomp_barrier_t view_handling_barrier;*/
193 /* Counter of the number of total unregistered views, both read and
194 write, used to determine the last task deconnecting its view.
195 The last task will also free the data structures. */
196 int unregistered_views
;
198 #ifndef HAVE_SYNC_BUILTINS
199 /* We may need a lock for atomicity if no atomic operations are
201 gomp_mutex_t stream_mutex
;
203 } gomp_stream_t
, *gomp_stream_p
;
206 /* GOMP_STREAM_TASK data structure. Runtime node in the task
209 typedef struct gomp_stream_task
211 /* Lists of views on streams used by this task. */
212 gomp_stream_view_list_t read_view_list
;
213 gomp_stream_view_list_t write_view_list
;
215 /* The following are used directly in the generated code and should
216 only be read here. A memory fence is guaranteed before the
217 termination flag is set to true. */
219 /* Number of activations allowed for the task. */
220 volatile unsigned long long activation_counter
;
221 volatile unsigned long long first_unassigned_activation_counter
;
225 /* True only when the activation counter has reached the maximum
226 number of activations allowed for this task. */
227 volatile bool termination_flag
;
229 } gomp_stream_task_t
, *gomp_stream_task_p
;
233 /* GOMP_STREAM_CONTROL_STREAM data structure. Implements a simple
234 if-conversion analog that allows a non data-driven task to conform
235 to its original control dependences. */
237 typedef struct gomp_stream_control_stream
239 /* In all cases where the streams bypass control (i.e., for
240 sequential control flow only), an activation counter is
241 sufficient to carry the control flow. */
243 /* Local counter of the number of times a task has been activated. */
244 unsigned long long activation_counter
__attribute__((aligned (64)));
245 unsigned long long local_enabled_activations
;
247 /* Number of times this task is allowed to activate. */
248 unsigned long long enabled_activations
__attribute__((aligned (64)));
250 /* When a task's inputs or outputs cross a parallel control flow
251 boundary (i.e., worksharing construct), their activation pattern
252 can be sparse wrt. the actual stream of data that they share with
253 their sibling tasks. We use activation ranges as an optimization
254 to streaming the activation indexes themselves, but the two
255 options are equivalent. These streams are inherently 1-to-1, so
256 a simpler implementation of the synchronization should be used in
258 /* gomp_stream_p activation_range_stream; */
260 /* End of stream: true when all producers have finished committing
261 all the data and are terminating. */
264 } gomp_stream_control_stream_t
, *gomp_stream_control_stream_p
;
269 #endif /* GOMP_STREAM_H */