PR target/66148
[official-gcc.git] / libcilkrts / runtime / scheduler.h
blob543adaf68e03831b2c0349fc536880fa736e65c5
1 /* scheduler.h -*-C++-*-
3 *************************************************************************
5 * @copyright
6 * Copyright (C) 2009-2013, Intel Corporation
7 * All rights reserved.
8 *
9 * @copyright
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
14 * * Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * * Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in
18 * the documentation and/or other materials provided with the
19 * distribution.
20 * * Neither the name of Intel Corporation nor the names of its
21 * contributors may be used to endorse or promote products derived
22 * from this software without specific prior written permission.
24 * @copyright
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
30 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
31 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
32 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
33 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
35 * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
37 **************************************************************************/
39 /**
40 * @file scheduler.h
42 * @brief scheduler.h declares routines for the Intel Cilk Plus scheduler,
43 * making it the heart of the Intel Cilk Plus implementation.
46 #ifndef INCLUDED_SCHEDULER_DOT_H
47 #define INCLUDED_SCHEDULER_DOT_H
49 #include <cilk/common.h>
50 #include <internal/abi.h>
52 #include "rts-common.h"
53 #include "full_frame.h"
54 #include "reducer_impl.h"
55 #include "global_state.h"
57 #ifdef CILK_RECORD_REPLAY
58 #include "record-replay.h"
59 #endif
61 __CILKRTS_BEGIN_EXTERN_C
64 /**
65 * @brief Flag to disable parallel reductions.
67 * Set to 0 to allow parallel reductions.
69 #define DISABLE_PARALLEL_REDUCERS 0
71 /**
72 * @brief Debugging level for parallel reductions.
74 * Print debugging messages and assertions for parallel reducers. 0 is
75 * no debugging. A higher value generates more output.
77 #define REDPAR_DEBUG 0
79 /**
80 * @brief Lock the worker mutex to allow exclusive access to the
81 * values in the @c __cilkrts_worker and local_state structures.
83 * @pre @c w->l->do_not_steal must not be set. Essentially this
84 * condition asserts that the worker is not locked recursively.
86 * @param w The worker to lock.
88 COMMON_PORTABLE
89 void __cilkrts_worker_lock(__cilkrts_worker *w);
91 /**
92 * @brief Unlock the worker mutex.
94 * @pre @c w->l->do_not_steal must be set. Essentially this condition
95 * asserts that the worker has been previously locked.
97 * @param w The worker to unlock.
99 COMMON_PORTABLE
100 void __cilkrts_worker_unlock(__cilkrts_worker *w);
103 * @brief Push the next full frame to be made active in this worker
104 * and increment its join counter.
106 * __cilkrts_push_next_frame and pop_next_frame work on a one-element queue.
107 * This queue is used to communicate across the runtime from the code that
108 * wants to activate a frame to the code that can actually begin execution
109 * on that frame. They are asymetrical in that push increments the join
110 * counter but pop does not decrement it. Rather, a single push/pop
111 * combination makes a frame active and increments its join counter once.
113 * @note A system worker may chose to push work onto a user worker if
114 * the work is the continuation from a sync which only the user worker
115 * may complete.
117 * @param w The worker which the frame is to be pushed onto.
118 * @param ff The full_frame which is to be continued by the worker.
120 COMMON_PORTABLE
121 void __cilkrts_push_next_frame(__cilkrts_worker *w,
122 full_frame *ff);
125 * @brief Sync on this worker.
127 * If this worker is the last to reach the sync, execution may resume
128 * on this worker after the sync.
130 * If this worker is not the last spawned child to reach the sync,
131 * then execution is suspended and the worker will re-enter the
132 * scheduling loop, looking for work it can steal.
134 * This function will jump into the runtime to switch to the scheduling
135 * stack to implement most of its logic.
137 * @param w The worker which is executing the sync.
138 * @param sf The __cilkrts_stack_frame containing the sync.
140 COMMON_PORTABLE
141 NORETURN __cilkrts_c_sync(__cilkrts_worker *w,
142 __cilkrts_stack_frame *sf);
145 * @brief Worker @c w completely promotes its own deque, simulating the case
146 * where the whole deque is stolen.
148 * We use this mechanism to force the allocation of new storage for
149 * reducers for race-detection purposes.
151 * This method is called from the reducer lookup logic when
152 * @c g->force_reduce is set.
154 * @warning Use of "force_reduce" is known to have bugs when run with
155 * more than 1 worker.
157 * @param w The worker which is to have all entries in its deque
158 * promoted to full frames.
160 COMMON_PORTABLE
161 void __cilkrts_promote_own_deque(__cilkrts_worker *w);
164 * Called when a spawned function attempts to return and
165 * __cilkrts_undo_detach() fails. This can happen for two reasons:
167 * @li If another worker is considering stealing our parent, it bumps the
168 * exception pointer while it did so, which will cause __cilkrts_undo_detach()
169 * to fail. If the other worker didn't complete the steal of our parent, we
170 * still may be able to return to it, either because the steal attempt failed,
171 * or we won the race for the tail pointer.
173 * @li If the function's parent has been stolen then we cannot return. Instead
174 * we'll longjmp into the runtime to switch onto the scheduling stack to
175 * execute do_return_from_spawn() and determine what to do. Either this
176 * worker is the last one to the sync, in which case we need to jump to the
177 * sync, or this worker is not the last one to the sync, in which case we'll
178 * abandon this work and jump to the scheduling loop to search for more work
179 * we can steal.
181 * @param w The worker which attempting to return from a spawn to
182 * a stolen parent.
183 * @param returning_sf The stack frame which is returning.
185 COMMON_PORTABLE
186 void __cilkrts_c_THE_exception_check(__cilkrts_worker *w,
187 __cilkrts_stack_frame *returning_sf);
190 * @brief Return an exception to an stolen parent.
192 * Used by the gcc implementation of exceptions to return an exception
193 * to a stolen parent
195 * @param w The worker which attempting to return from a spawn with an
196 * exception to a stolen parent.
197 * @param returning_sf The stack frame which is returning.
199 COMMON_PORTABLE
200 NORETURN __cilkrts_exception_from_spawn(__cilkrts_worker *w,
201 __cilkrts_stack_frame *returning_sf);
204 * @brief Used by the Windows implementations of exceptions to migrate an exception
205 * across fibers.
207 * Call this function when an exception has been thrown and has to
208 * traverse across a steal. The exception has already been wrapped
209 * up, so all that remains is to longjmp() into the continuation,
210 * sync, and re-raise it.
212 * @param sf The __cilkrts_stack_frame for the frame that is attempting to
213 * return an exception to a stolen parent.
215 void __cilkrts_migrate_exception (__cilkrts_stack_frame *sf);
218 * @brief Return from a call, not a spawn, where this frame has ever
219 * been stolen.
221 * @param w The worker that is returning from a frame which was ever stolen.
223 COMMON_PORTABLE
224 void __cilkrts_return(__cilkrts_worker *w);
227 * @brief Special return from the initial frame.
229 * This method will be called from @c __cilkrts_leave_frame if
230 * @c CILK_FRAME_LAST is set.
232 * This function will do the things necessary to cleanup, and unbind the
233 * thread from the Intel Cilk Plus runtime. If this is the last user
234 * worker unbinding from the runtime, all system worker threads will be
235 * suspended.
237 * @pre @c w must be the currently executing worker, and must be a user
238 * worker.
240 * @param w The worker that's returning from the initial frame.
242 COMMON_PORTABLE
243 void __cilkrts_c_return_from_initial(__cilkrts_worker *w);
246 * @brief Used by exception handling code to pop an entry from the
247 * worker's deque.
249 * @param w Worker to pop the entry from
251 * @return __cilkrts_stack_frame of parent call
252 * @return NULL if the deque is empty
254 COMMON_PORTABLE
255 __cilkrts_stack_frame *__cilkrts_pop_tail(__cilkrts_worker *w);
258 * @brief Modifies the worker's protected_tail to prevent frames from
259 * being stolen.
261 * The Dekker protocol has been extended to only steal if head+1 is also
262 * less than protected_tail.
264 * @param w The worker to be modified.
265 * @param new_protected_tail The new setting for protected_tail, or NULL if the
266 * entire deque is to be protected
268 * @return Previous value of protected tail.
270 COMMON_PORTABLE
271 __cilkrts_stack_frame *volatile *__cilkrts_disallow_stealing(
272 __cilkrts_worker *w,
273 __cilkrts_stack_frame *volatile *new_protected_tail);
276 * @brief Restores the protected tail to a previous state, possibly
277 * allowing frames to be stolen.
279 * @param w The worker to be modified.
280 * @param saved_protected_tail A previous setting for protected_tail that is
281 * to be restored
283 COMMON_PORTABLE
284 void __cilkrts_restore_stealing(
285 __cilkrts_worker *w,
286 __cilkrts_stack_frame *volatile *saved_protected_tail);
289 * @brief Initialize a @c __cilkrts_worker.
291 * @note The memory for the worker must have been allocated outside
292 * this call.
294 * @param g The global_state_t.
295 * @param self The index into the global_state's array of workers for this
296 * worker, or -1 if this worker was allocated from the heap and cannot be
297 * stolen from.
298 * @param w The worker to be initialized.
300 * @return The initialized __cilkrts_worker.
302 COMMON_PORTABLE
303 __cilkrts_worker *make_worker(global_state_t *g,
304 int self,
305 __cilkrts_worker *w);
308 * @brief Free up any resources allocated for a worker.
310 * @note The memory for the @c __cilkrts_worker itself must be
311 * deallocated outside this call.
313 * @param w The worker to be destroyed.
315 COMMON_PORTABLE
316 void destroy_worker (__cilkrts_worker *w);
319 * @brief Initialize the runtime.
321 * If necessary, allocates and initializes the global state. If
322 * necessary, unsuspends the system workers.
324 * @param start Specifies whether the workers are to be unsuspended if
325 * they are suspended. Allows __cilkrts_init() to start up the runtime without
326 * releasing the system threads.
328 COMMON_PORTABLE
329 void __cilkrts_init_internal(int start);
332 * @brief Part of the sequence to shutdown the runtime.
334 * Specifically, this call frees the @c global_state_t for the runtime.
336 * @param g The global_state_t.
338 COMMON_PORTABLE
339 void __cilkrts_deinit_internal(global_state_t *g);
342 * Obsolete. We no longer need to import or export reducer maps.
344 COMMON_PORTABLE
345 cilkred_map *__cilkrts_xchg_reducer(
346 __cilkrts_worker *w, cilkred_map *newmap) cilk_nothrow;
349 * @brief Called when a user thread is bound to the runtime.
351 * If this action increments the count of bound user threads from 0 to
352 * 1, the system worker threads are unsuspended.
354 * If this action increments the count of bound user threads from 0 to
355 * 1, the system worker threads are unsuspended.
357 * @pre Global lock must be held.
358 * @param g The runtime global state.
360 COMMON_PORTABLE
361 void __cilkrts_enter_cilk(global_state_t *g);
364 * @brief Called when a user thread is unbound from the runtime.
366 * If this action decrements the count of bound user threads to 0, the
367 * system worker threads are suspended.
370 * @pre Global lock must be held.
372 * @param g The runtime global state.
374 COMMON_PORTABLE
375 void __cilkrts_leave_cilk(global_state_t *g);
379 * @brief cilk_fiber_proc that runs the main scheduler loop on a
380 * user worker.
382 * @pre fiber's owner field should be set to the correct __cilkrts_worker
383 * @pre fiber must be a user worker.
385 * @param fiber The scheduling fiber object.
387 void scheduler_fiber_proc_for_user_worker(cilk_fiber *fiber);
391 * @brief Prints out Cilk runtime statistics.
393 * @param g The runtime global state.
395 * This method is useful only for debugging purposes. No guarantees
396 * are made as to the validity of this data. :)
398 COMMON_PORTABLE
399 void __cilkrts_dump_stats_to_stderr(global_state_t *g);
401 #ifdef CILK_RECORD_REPLAY
402 COMMON_PORTABLE
403 char * walk_pedigree_nodes(char *p, const __cilkrts_pedigree *pnode);
406 * @brief Used by exception handling code to simulate the popping of
407 * an entry from the worker's deque.
409 * @param w Worker whose deque we want to check
411 * @return @c __cilkrts_stack_frame of parent call
412 * @return NULL if the deque is empty
414 COMMON_PORTABLE
415 __cilkrts_stack_frame *simulate_pop_tail(__cilkrts_worker *w);
417 #endif
419 __CILKRTS_END_EXTERN_C
421 #endif // ! defined(INCLUDED_SCHEDULER_DOT_H)