2011-06-14 Antoniu Pop <antoniu.pop@gmail.com>
[official-gcc.git] / libgomp / stream.h
blobdd75994ec4c8b4278e37f0aaed3f903fabfbf008
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
14 more details.
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. */
30 #ifndef GOMP_STREAM_H
31 #define GOMP_STREAM_H 1
33 #include <limits.h>
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
43 /*#define LAZY_SYNCH
44 #define GUARDED_WAKE*/
47 typedef enum {
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
54 } gomp_stream_state;
57 typedef enum
59 READ_VIEW,
60 WRITE_VIEW
61 } gomp_stream_view_type_t;
63 struct gomp_stream;
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
73 to be first. */
74 struct gomp_stream *stream;
76 /* Size in bytes of the burst associated to this view. Later this
77 may become a stream. */
78 size_t view_size;
79 size_t burst_size;
80 size_t pxxk_size;
82 /* The alignment directives are needed to ensure these
83 high-potential false-sharing fields are on their own cache
84 lines. */
85 /* Lower and upper bounds accessible in the stream through this
86 view. */
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
95 terminating). */
96 bool end_p;
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
111 array. */
113 typedef struct gomp_stream_view_list
115 gomp_stream_view_p *views;
116 int nr_views;
117 int size;
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
128 this stream. */
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
134 lines. */
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
159 stream. */
160 /* Circular buffer containing the data communicated through this
161 stream. */
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
177 done so. */
178 bool connected_p;
180 /* End of stream: true when all producers have finished committing
181 all the data and are terminating. */
182 bool eos_p;
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
200 available. */
201 gomp_mutex_t stream_mutex;
202 #endif
203 } gomp_stream_t, *gomp_stream_p;
206 /* GOMP_STREAM_TASK data structure. Runtime node in the task
207 graph. */
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;
223 int num_instances;
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;
232 #if 0
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
257 this case.*/
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. */
262 bool eos_p;
264 } gomp_stream_control_stream_t, *gomp_stream_control_stream_p;
266 #endif
269 #endif /* GOMP_STREAM_H */