annotate libcilkrts/runtime/cilk_fiber.h @ 111:04ced10e8804

gcc 7
author kono
date Fri, 27 Oct 2017 22:46:09 +0900
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 /* cilk_fiber.h -*-C++-*-
kono
parents:
diff changeset
2 *
kono
parents:
diff changeset
3 *************************************************************************
kono
parents:
diff changeset
4 *
kono
parents:
diff changeset
5 * Copyright (C) 2012-2016, Intel Corporation
kono
parents:
diff changeset
6 * All rights reserved.
kono
parents:
diff changeset
7 *
kono
parents:
diff changeset
8 * Redistribution and use in source and binary forms, with or without
kono
parents:
diff changeset
9 * modification, are permitted provided that the following conditions
kono
parents:
diff changeset
10 * are met:
kono
parents:
diff changeset
11 *
kono
parents:
diff changeset
12 * * Redistributions of source code must retain the above copyright
kono
parents:
diff changeset
13 * notice, this list of conditions and the following disclaimer.
kono
parents:
diff changeset
14 * * Redistributions in binary form must reproduce the above copyright
kono
parents:
diff changeset
15 * notice, this list of conditions and the following disclaimer in
kono
parents:
diff changeset
16 * the documentation and/or other materials provided with the
kono
parents:
diff changeset
17 * distribution.
kono
parents:
diff changeset
18 * * Neither the name of Intel Corporation nor the names of its
kono
parents:
diff changeset
19 * contributors may be used to endorse or promote products derived
kono
parents:
diff changeset
20 * from this software without specific prior written permission.
kono
parents:
diff changeset
21 *
kono
parents:
diff changeset
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
kono
parents:
diff changeset
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
kono
parents:
diff changeset
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
kono
parents:
diff changeset
25 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
kono
parents:
diff changeset
26 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
kono
parents:
diff changeset
27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
kono
parents:
diff changeset
28 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
kono
parents:
diff changeset
29 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
kono
parents:
diff changeset
30 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
kono
parents:
diff changeset
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
kono
parents:
diff changeset
32 * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
kono
parents:
diff changeset
33 * POSSIBILITY OF SUCH DAMAGE.
kono
parents:
diff changeset
34 *
kono
parents:
diff changeset
35 * *********************************************************************
kono
parents:
diff changeset
36 *
kono
parents:
diff changeset
37 * PLEASE NOTE: This file is a downstream copy of a file mainitained in
kono
parents:
diff changeset
38 * a repository at cilkplus.org. Changes made to this file that are not
kono
parents:
diff changeset
39 * submitted through the contribution process detailed at
kono
parents:
diff changeset
40 * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
kono
parents:
diff changeset
41 * time that a new version is released. Changes only submitted to the
kono
parents:
diff changeset
42 * GNU compiler collection or posted to the git repository at
kono
parents:
diff changeset
43 * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
kono
parents:
diff changeset
44 * not tracked.
kono
parents:
diff changeset
45 *
kono
parents:
diff changeset
46 * We welcome your contributions to this open source project. Thank you
kono
parents:
diff changeset
47 * for your assistance in helping us improve Cilk Plus.
kono
parents:
diff changeset
48 **************************************************************************/
kono
parents:
diff changeset
49
kono
parents:
diff changeset
50 /**
kono
parents:
diff changeset
51 * @file cilk_fiber.h
kono
parents:
diff changeset
52 *
kono
parents:
diff changeset
53 * @brief Abstraction of a "fiber": A coprocess-like stack and auxiliary data
kono
parents:
diff changeset
54 */
kono
parents:
diff changeset
55
kono
parents:
diff changeset
56 #ifndef INCLUDED_CILK_FIBER_DOT_H
kono
parents:
diff changeset
57 #define INCLUDED_CILK_FIBER_DOT_H
kono
parents:
diff changeset
58
kono
parents:
diff changeset
59 #include <cilk/common.h>
kono
parents:
diff changeset
60 #ifdef __cplusplus
kono
parents:
diff changeset
61 # include <cstddef>
kono
parents:
diff changeset
62 #else
kono
parents:
diff changeset
63 # include <stddef.h>
kono
parents:
diff changeset
64 #endif
kono
parents:
diff changeset
65
kono
parents:
diff changeset
66 #include "bug.h"
kono
parents:
diff changeset
67 #include "cilk-tbb-interop.h"
kono
parents:
diff changeset
68 #include "spin_mutex.h"
kono
parents:
diff changeset
69 #include "internal/abi.h" // Define __cilkrts_stack_frame
kono
parents:
diff changeset
70
kono
parents:
diff changeset
71 /**
kono
parents:
diff changeset
72 * @brief Debugging level for Cilk fiber code.
kono
parents:
diff changeset
73 *
kono
parents:
diff changeset
74 * A value of 0 means no debugging.
kono
parents:
diff changeset
75 * Higher values generate more debugging output.
kono
parents:
diff changeset
76 *
kono
parents:
diff changeset
77 */
kono
parents:
diff changeset
78
kono
parents:
diff changeset
79 #ifndef FIBER_DEBUG
kono
parents:
diff changeset
80 #define FIBER_DEBUG 0
kono
parents:
diff changeset
81 #endif
kono
parents:
diff changeset
82 /**
kono
parents:
diff changeset
83 * @brief Flag for validating reference counts.
kono
parents:
diff changeset
84 *
kono
parents:
diff changeset
85 * Set to 1 to assert that fiber reference counts are reasonable.
kono
parents:
diff changeset
86 */
kono
parents:
diff changeset
87 #define FIBER_CHECK_REF_COUNTS 1
kono
parents:
diff changeset
88
kono
parents:
diff changeset
89 /**
kono
parents:
diff changeset
90 * @brief Flag to determine whether fibers support reference counting.
kono
parents:
diff changeset
91 * We require reference counting only on Windows, for exception
kono
parents:
diff changeset
92 * processing. Unix does not need reference counting.
kono
parents:
diff changeset
93 */
kono
parents:
diff changeset
94 #if defined(_WIN32)
kono
parents:
diff changeset
95 # define NEED_FIBER_REF_COUNTS 1
kono
parents:
diff changeset
96 #endif
kono
parents:
diff changeset
97
kono
parents:
diff changeset
98 /**
kono
parents:
diff changeset
99 * @brief Flag to enable support for the
kono
parents:
diff changeset
100 * cilk_fiber_get_current_fiber() method.
kono
parents:
diff changeset
101 *
kono
parents:
diff changeset
102 * I'd like this flag to be 0. However, the cilk_fiber test depends
kono
parents:
diff changeset
103 * on being able to call this method.
kono
parents:
diff changeset
104 */
kono
parents:
diff changeset
105 #if !defined(SUPPORT_GET_CURRENT_FIBER)
kono
parents:
diff changeset
106 # define SUPPORT_GET_CURRENT_FIBER 0
kono
parents:
diff changeset
107 #endif
kono
parents:
diff changeset
108
kono
parents:
diff changeset
109 /**
kono
parents:
diff changeset
110 * @brief Switch for enabling "fast path" check for fibers, which
kono
parents:
diff changeset
111 * doesn't go to the heap or OS until checking the ancestors first.
kono
parents:
diff changeset
112 *
kono
parents:
diff changeset
113 * Doing this check seems to make the stress test in
kono
parents:
diff changeset
114 * cilk_fiber_pool.t.cpp run faster. But it doesn't seem to make much
kono
parents:
diff changeset
115 * difference in other benchmarks, so it is disabled by default.
kono
parents:
diff changeset
116 */
kono
parents:
diff changeset
117 #define USE_FIBER_TRY_ALLOCATE_FROM_POOL 0
kono
parents:
diff changeset
118
kono
parents:
diff changeset
119
kono
parents:
diff changeset
120 __CILKRTS_BEGIN_EXTERN_C
kono
parents:
diff changeset
121
kono
parents:
diff changeset
122 /// @brief Forward reference to fiber pool.
kono
parents:
diff changeset
123 typedef struct cilk_fiber_pool cilk_fiber_pool;
kono
parents:
diff changeset
124
kono
parents:
diff changeset
125 /** @brief Opaque data structure representing a fiber */
kono
parents:
diff changeset
126 typedef struct cilk_fiber cilk_fiber;
kono
parents:
diff changeset
127
kono
parents:
diff changeset
128 /** @brief Function pointer type for use as a fiber's "main" procedure */
kono
parents:
diff changeset
129 typedef void (*cilk_fiber_proc)(cilk_fiber*);
kono
parents:
diff changeset
130
kono
parents:
diff changeset
131 /** @brief Data structure associated with each fiber. */
kono
parents:
diff changeset
132 typedef struct cilk_fiber_data
kono
parents:
diff changeset
133 {
kono
parents:
diff changeset
134 __STDNS size_t stack_size; /**< Size of stack for fiber */
kono
parents:
diff changeset
135 __cilkrts_worker* owner; /**< Worker using this fiber */
kono
parents:
diff changeset
136 __cilkrts_stack_frame* resume_sf; /**< Stack frame to resume */
kono
parents:
diff changeset
137 __cilk_tbb_pfn_stack_op stack_op_routine; /**< Cilk/TBB interop callback */
kono
parents:
diff changeset
138 void* stack_op_data; /**< Data for Cilk/TBB callback */
kono
parents:
diff changeset
139 void* client_data; /**< Data managed by client */
kono
parents:
diff changeset
140
kono
parents:
diff changeset
141 #ifdef _WIN32
kono
parents:
diff changeset
142 char *initial_sp; /**< Initalized in fiber_stub */
kono
parents:
diff changeset
143 # ifdef _WIN64
kono
parents:
diff changeset
144 char *steal_frame_sp; /**< RSP for frame stealing work */
kono
parents:
diff changeset
145 // Needed for exception handling so we can
kono
parents:
diff changeset
146 // identify when about to unwind off stack
kono
parents:
diff changeset
147 # endif
kono
parents:
diff changeset
148 #endif
kono
parents:
diff changeset
149
kono
parents:
diff changeset
150 } cilk_fiber_data;
kono
parents:
diff changeset
151
kono
parents:
diff changeset
152 /** @brief Pool of cilk_fiber for fiber reuse
kono
parents:
diff changeset
153 *
kono
parents:
diff changeset
154 * Pools form a hierarchy, with each pool pointing to its parent. When the
kono
parents:
diff changeset
155 * pool undeflows, it gets a fiber from its parent. When a pool overflows,
kono
parents:
diff changeset
156 * it returns some fibers to its parent. If the root pool underflows, it
kono
parents:
diff changeset
157 * allocates and initializes a new fiber from the heap but only if the total
kono
parents:
diff changeset
158 * is less than max_size; otherwise, fiber creation fails.
kono
parents:
diff changeset
159 */
kono
parents:
diff changeset
160 struct cilk_fiber_pool
kono
parents:
diff changeset
161 {
kono
parents:
diff changeset
162 spin_mutex* lock; ///< Mutual exclusion for pool operations
kono
parents:
diff changeset
163 __STDNS size_t stack_size; ///< Size of stacks for fibers in this pool.
kono
parents:
diff changeset
164 cilk_fiber_pool* parent; ///< @brief Parent pool.
kono
parents:
diff changeset
165 ///< If this pool is empty, get from parent
kono
parents:
diff changeset
166
kono
parents:
diff changeset
167 // Describes inactive fibers stored in the pool.
kono
parents:
diff changeset
168 cilk_fiber** fibers; ///< Array of max_size fiber pointers
kono
parents:
diff changeset
169 unsigned max_size; ///< Limit on number of fibers in pool
kono
parents:
diff changeset
170 unsigned size; ///< Number of fibers currently in the pool
kono
parents:
diff changeset
171
kono
parents:
diff changeset
172 // Statistics on active fibers that were allocated from this pool,
kono
parents:
diff changeset
173 // but no longer in the pool.
kono
parents:
diff changeset
174 int total; ///< @brief Fibers allocated - fiber deallocated from pool
kono
parents:
diff changeset
175 ///< total may be negative for non-root pools.
kono
parents:
diff changeset
176 int high_water; ///< High water mark of total fibers
kono
parents:
diff changeset
177 int alloc_max; ///< Limit on number of fibers allocated from the heap/OS
kono
parents:
diff changeset
178 };
kono
parents:
diff changeset
179
kono
parents:
diff changeset
180 /** @brief Initializes a cilk_fiber_pool structure
kono
parents:
diff changeset
181 *
kono
parents:
diff changeset
182 * @param pool - The address of the pool that is to be initialized
kono
parents:
diff changeset
183 * @param parent - The address of this pool's parent, or NULL for root pool
kono
parents:
diff changeset
184 * @param stack_size - Size of stacks for fibers allocated from this pool.
kono
parents:
diff changeset
185 * @param buffer_size - The maximum number of fibers that may be pooled.
kono
parents:
diff changeset
186 * @param alloc_max - Limit on # of fibers this pool can allocate from the heap.
kono
parents:
diff changeset
187 * @param is_shared - True if accessing this pool needs a lock, false otherwise.
kono
parents:
diff changeset
188 */
kono
parents:
diff changeset
189 void cilk_fiber_pool_init(cilk_fiber_pool* pool,
kono
parents:
diff changeset
190 cilk_fiber_pool* parent,
kono
parents:
diff changeset
191 size_t stack_size,
kono
parents:
diff changeset
192 unsigned buffer_size,
kono
parents:
diff changeset
193 int alloc_max,
kono
parents:
diff changeset
194 int is_shared);
kono
parents:
diff changeset
195
kono
parents:
diff changeset
196 /** @brief Sets the maximum number of fibers to allocate from a root pool.
kono
parents:
diff changeset
197 *
kono
parents:
diff changeset
198 * @param root_pool - A root fiber pool
kono
parents:
diff changeset
199 * @param max_fibers_to_allocate - The limit on # of fibers to allocate.
kono
parents:
diff changeset
200 *
kono
parents:
diff changeset
201 * Sets the maximum number of fibers that can be allocated from this
kono
parents:
diff changeset
202 * pool and all its descendants. This pool must be a root pool.
kono
parents:
diff changeset
203 */
kono
parents:
diff changeset
204 void cilk_fiber_pool_set_fiber_limit(cilk_fiber_pool* root_pool,
kono
parents:
diff changeset
205 unsigned max_fibers_to_allocate);
kono
parents:
diff changeset
206
kono
parents:
diff changeset
207 /** @brief De-initalizes a cilk_fiber_pool
kono
parents:
diff changeset
208 *
kono
parents:
diff changeset
209 * @param pool - The address of the pool that is to be destroyed
kono
parents:
diff changeset
210 */
kono
parents:
diff changeset
211 void cilk_fiber_pool_destroy(cilk_fiber_pool* pool);
kono
parents:
diff changeset
212
kono
parents:
diff changeset
213 /** @brief Allocates a new cilk_fiber.
kono
parents:
diff changeset
214 *
kono
parents:
diff changeset
215 * If the specified pool is empty, this method may choose to either
kono
parents:
diff changeset
216 * allocate a fiber from the heap (if pool->total < pool->alloc_max),
kono
parents:
diff changeset
217 * or retrieve a fiber from the parent pool.
kono
parents:
diff changeset
218 *
kono
parents:
diff changeset
219 * @note If a non-null fiber is returned, @c cilk_fiber_reset_state
kono
parents:
diff changeset
220 * should be called on this fiber before using it.
kono
parents:
diff changeset
221 *
kono
parents:
diff changeset
222 * An allocated fiber begins with a reference count of 1.
kono
parents:
diff changeset
223 * This method may lock @c pool or one of its ancestors.
kono
parents:
diff changeset
224 *
kono
parents:
diff changeset
225 * @pre pool should not be NULL.
kono
parents:
diff changeset
226 *
kono
parents:
diff changeset
227 * @param pool The fiber pool from which to retrieve a fiber.
kono
parents:
diff changeset
228 * @return An allocated fiber, or NULL if failed to allocate.
kono
parents:
diff changeset
229 */
kono
parents:
diff changeset
230 cilk_fiber* cilk_fiber_allocate(cilk_fiber_pool* pool);
kono
parents:
diff changeset
231
kono
parents:
diff changeset
232 /** @brief Allocate and initialize a new cilk_fiber using memory from
kono
parents:
diff changeset
233 * the heap and/or OS.
kono
parents:
diff changeset
234 *
kono
parents:
diff changeset
235 * The allocated fiber begins with a reference count of 1.
kono
parents:
diff changeset
236 *
kono
parents:
diff changeset
237 * @param stack_size The size (in bytes) to be allocated for the fiber's
kono
parents:
diff changeset
238 * stack.
kono
parents:
diff changeset
239 * @return An initialized fiber. This method should not return NULL
kono
parents:
diff changeset
240 * unless some exceptional condition has occurred.
kono
parents:
diff changeset
241 */
kono
parents:
diff changeset
242 cilk_fiber* cilk_fiber_allocate_from_heap(size_t stack_size);
kono
parents:
diff changeset
243
kono
parents:
diff changeset
244
kono
parents:
diff changeset
245 /** @brief Resets an fiber object just allocated from a pool with the
kono
parents:
diff changeset
246 * specified proc.
kono
parents:
diff changeset
247 *
kono
parents:
diff changeset
248 * After this call, cilk_fiber_data object associated with this fiber
kono
parents:
diff changeset
249 * is filled with zeros.
kono
parents:
diff changeset
250 *
kono
parents:
diff changeset
251 * This function can be called only on a fiber that has been allocated
kono
parents:
diff changeset
252 * from a pool, but never used.
kono
parents:
diff changeset
253 *
kono
parents:
diff changeset
254 * @param fiber The fiber to reset and initialize.
kono
parents:
diff changeset
255 * @param start_proc The function to run when switching to the fiber. If
kono
parents:
diff changeset
256 * null, the fiber can be used with cilk_fiber_run_proc()
kono
parents:
diff changeset
257 * but not with cilk_fiber_resume().
kono
parents:
diff changeset
258 */
kono
parents:
diff changeset
259 void cilk_fiber_reset_state(cilk_fiber* fiber,
kono
parents:
diff changeset
260 cilk_fiber_proc start_proc);
kono
parents:
diff changeset
261
kono
parents:
diff changeset
262 /** @brief Remove a reference from this fiber, possibly deallocating it.
kono
parents:
diff changeset
263 *
kono
parents:
diff changeset
264 * This fiber is deallocated only when there are no other references
kono
parents:
diff changeset
265 * to it. Deallocation happens either by returning the fiber to the
kono
parents:
diff changeset
266 * specified pool, or returning it to the heap.
kono
parents:
diff changeset
267 *
kono
parents:
diff changeset
268 * A fiber that is currently executing should not remove the last
kono
parents:
diff changeset
269 * reference to itself.
kono
parents:
diff changeset
270 *
kono
parents:
diff changeset
271 * When a fiber is deallocated, destructors are not called for the
kono
parents:
diff changeset
272 * objects (if any) still on its stack. The fiber's stack and fiber
kono
parents:
diff changeset
273 * data is returned to the stack pool but the client fiber data is not
kono
parents:
diff changeset
274 * deallocated.
kono
parents:
diff changeset
275 *
kono
parents:
diff changeset
276 * If the pool overflows because of a deallocation, then some fibers
kono
parents:
diff changeset
277 * will be returned to the parent pool. If the root pool overflows,
kono
parents:
diff changeset
278 * then the fiber is returned to the heap.
kono
parents:
diff changeset
279 *
kono
parents:
diff changeset
280 * @param fiber The Cilk fiber to remove a reference to.
kono
parents:
diff changeset
281 * @param pool The fiber pool to which the fiber should be returned. The
kono
parents:
diff changeset
282 * caller is assumed to have exclusive access to the pool
kono
parents:
diff changeset
283 * either because there is no contention for it or because
kono
parents:
diff changeset
284 * its lock has been acquired. If pool is NULL, any
kono
parents:
diff changeset
285 * deallocated fiber is destroyed and returned to the
kono
parents:
diff changeset
286 * heap.
kono
parents:
diff changeset
287 *
kono
parents:
diff changeset
288 * @return Final reference count. If the count is 0, the fiber was
kono
parents:
diff changeset
289 * returned to a pool or the heap.
kono
parents:
diff changeset
290 */
kono
parents:
diff changeset
291 int cilk_fiber_remove_reference(cilk_fiber *fiber, cilk_fiber_pool *pool);
kono
parents:
diff changeset
292
kono
parents:
diff changeset
293 /** @brief Allocates and intializes this thread's main fiber
kono
parents:
diff changeset
294 *
kono
parents:
diff changeset
295 * Each thread has an "implicit" main fiber that control's the
kono
parents:
diff changeset
296 * thread's initial stack. This function makes this fiber visible to
kono
parents:
diff changeset
297 * the client and allocates the Cilk-specific aspects of the implicit
kono
parents:
diff changeset
298 * fiber. A call to this function must be paired with a call to
kono
parents:
diff changeset
299 * cilk_fiber_deallocate_fiber_from_thread()
kono
parents:
diff changeset
300 * or a memory leak (or worse) will result.
kono
parents:
diff changeset
301 *
kono
parents:
diff changeset
302 * A fiber allocated from a thread begins with a reference count of 2.
kono
parents:
diff changeset
303 * One is for being allocated, and one is for being active.
kono
parents:
diff changeset
304 * (A fiber created from a thread is automatically currently executing.)
kono
parents:
diff changeset
305 * The matching calls above each decrement the reference count by 1.
kono
parents:
diff changeset
306 *
kono
parents:
diff changeset
307 * @return A fiber for the currently executing thread.
kono
parents:
diff changeset
308 */
kono
parents:
diff changeset
309 cilk_fiber* cilk_fiber_allocate_from_thread(void);
kono
parents:
diff changeset
310
kono
parents:
diff changeset
311 /** @brief Remove a fiber created from a thread,
kono
parents:
diff changeset
312 * possibly deallocating it.
kono
parents:
diff changeset
313 *
kono
parents:
diff changeset
314 * Same as cilk_fiber_remove_reference, except that it works on fibers
kono
parents:
diff changeset
315 * created via cilk_fiber_allocate_from_thread().
kono
parents:
diff changeset
316 *
kono
parents:
diff changeset
317 * Fibers created from a thread are never returned to a pool.
kono
parents:
diff changeset
318 *
kono
parents:
diff changeset
319 * @param fiber The Cilk fiber to remove a reference from.
kono
parents:
diff changeset
320 * @return Final reference count. If the count is 0, the fiber was
kono
parents:
diff changeset
321 * returned to the heap.
kono
parents:
diff changeset
322 */
kono
parents:
diff changeset
323 int cilk_fiber_remove_reference_from_thread(cilk_fiber *fiber);
kono
parents:
diff changeset
324
kono
parents:
diff changeset
325 /** @brief Deallocate a fiber created from a thread,
kono
parents:
diff changeset
326 * possibly destroying it.
kono
parents:
diff changeset
327 *
kono
parents:
diff changeset
328 * This method decrements the reference count of the fiber by 2, and
kono
parents:
diff changeset
329 * destroys the fiber struct if the reference count is 0.
kono
parents:
diff changeset
330 *
kono
parents:
diff changeset
331 * OS-specific cleanup for the fiber executes unconditionally with
kono
parents:
diff changeset
332 * this method. The destruction of the actual object, however, does
kono
parents:
diff changeset
333 * not occur unless the reference count is 0.
kono
parents:
diff changeset
334 *
kono
parents:
diff changeset
335 * @param fiber The cilk_fiber to deallocate from a thread.
kono
parents:
diff changeset
336 * @return Final reference count. If the count is 0, the fiber was
kono
parents:
diff changeset
337 * returned to the heap.
kono
parents:
diff changeset
338 */
kono
parents:
diff changeset
339 int cilk_fiber_deallocate_from_thread(cilk_fiber *fiber);
kono
parents:
diff changeset
340
kono
parents:
diff changeset
341 /** @brief Returns true if this fiber is allocated from a thread.
kono
parents:
diff changeset
342 */
kono
parents:
diff changeset
343 int cilk_fiber_is_allocated_from_thread(cilk_fiber *fiber);
kono
parents:
diff changeset
344
kono
parents:
diff changeset
345
kono
parents:
diff changeset
346 /** @brief Suspend execution on current fiber resumes other fiber.
kono
parents:
diff changeset
347 *
kono
parents:
diff changeset
348 * Suspends the current fiber and transfers control to a new fiber. Execution
kono
parents:
diff changeset
349 * on the new fiber resumes from the point at which fiber suspended itself to
kono
parents:
diff changeset
350 * run a different fiber. If fiber was freshly allocated, then runs the
kono
parents:
diff changeset
351 * start_proc function specified at allocation. This function returns when
kono
parents:
diff changeset
352 * another fiber resumes the self fiber. Note that the state of the
kono
parents:
diff changeset
353 * floating-point control register (i.e., the register that controls rounding
kono
parents:
diff changeset
354 * mode, etc.) is valid but indeterminate on return -- different
kono
parents:
diff changeset
355 * implementations will have different results.
kono
parents:
diff changeset
356 *
kono
parents:
diff changeset
357 * When the @c self fiber is resumed, execution proceeds as though
kono
parents:
diff changeset
358 * this function call returns.
kono
parents:
diff changeset
359 *
kono
parents:
diff changeset
360 * This operation increments the reference count of @p other.
kono
parents:
diff changeset
361 * This operation decrements the reference count of @p self.
kono
parents:
diff changeset
362 *
kono
parents:
diff changeset
363 * @param self Fiber to switch from. Must equal current fiber.
kono
parents:
diff changeset
364 * @param other Fiber to switch to.
kono
parents:
diff changeset
365 */
kono
parents:
diff changeset
366 void cilk_fiber_suspend_self_and_resume_other(cilk_fiber* self,
kono
parents:
diff changeset
367 cilk_fiber* other);
kono
parents:
diff changeset
368
kono
parents:
diff changeset
369 /** @brief Removes a reference from the currently executing fiber and
kono
parents:
diff changeset
370 * resumes other fiber.
kono
parents:
diff changeset
371 *
kono
parents:
diff changeset
372 * Removes a reference from @p self and transfer control to @p other
kono
parents:
diff changeset
373 * fiber. Execution on @p other resumes from the point at which @p
kono
parents:
diff changeset
374 * other suspended itself to run a different fiber. If @p other fiber
kono
parents:
diff changeset
375 * was freshly allocated, then runs the function specified at
kono
parents:
diff changeset
376 * creation.
kono
parents:
diff changeset
377 *
kono
parents:
diff changeset
378 *
kono
parents:
diff changeset
379 * This operation increments the reference count of @p other.
kono
parents:
diff changeset
380 *
kono
parents:
diff changeset
381 * This operation conceptually decrements the reference count of
kono
parents:
diff changeset
382 * @p self twice, once to suspend it, and once to remove a reference to
kono
parents:
diff changeset
383 * it. Then, if the count is 0, it is returned to the specified pool
kono
parents:
diff changeset
384 * or destroyed.
kono
parents:
diff changeset
385 *
kono
parents:
diff changeset
386 * @pre @p self is the currently executing fiber.
kono
parents:
diff changeset
387 *
kono
parents:
diff changeset
388 * @param self Fiber to remove reference switch from.
kono
parents:
diff changeset
389 * @param self_pool Pool to which the current fiber should be returned
kono
parents:
diff changeset
390 * @param other Fiber to switch to.
kono
parents:
diff changeset
391 */
kono
parents:
diff changeset
392 NORETURN
kono
parents:
diff changeset
393 cilk_fiber_remove_reference_from_self_and_resume_other(cilk_fiber* self,
kono
parents:
diff changeset
394 cilk_fiber_pool* self_pool,
kono
parents:
diff changeset
395 cilk_fiber* other);
kono
parents:
diff changeset
396
kono
parents:
diff changeset
397 /** @brief Set the proc method to execute immediately after a switch
kono
parents:
diff changeset
398 * to this fiber.
kono
parents:
diff changeset
399 *
kono
parents:
diff changeset
400 * The @c post_switch_proc method executes immediately after switching
kono
parents:
diff changeset
401 * away form @p self fiber to some other fiber, but before @c self
kono
parents:
diff changeset
402 * gets cleaned up.
kono
parents:
diff changeset
403 *
kono
parents:
diff changeset
404 * @note A fiber can have only one post_switch_proc method at a time.
kono
parents:
diff changeset
405 * If this method is called multiple times before switching to the
kono
parents:
diff changeset
406 * fiber, only the last proc method will execute.
kono
parents:
diff changeset
407 *
kono
parents:
diff changeset
408 * @param self Fiber.
kono
parents:
diff changeset
409 * @param post_switch_proc Proc method to execute immediately after switching to this fiber.
kono
parents:
diff changeset
410 */
kono
parents:
diff changeset
411 void cilk_fiber_set_post_switch_proc(cilk_fiber* self, cilk_fiber_proc post_switch_proc);
kono
parents:
diff changeset
412
kono
parents:
diff changeset
413 /** @brief Invoke TBB stack op for this fiber.
kono
parents:
diff changeset
414 *
kono
parents:
diff changeset
415 * @param fiber Fiber to invoke stack op for.
kono
parents:
diff changeset
416 * @param op The stack op to invoke
kono
parents:
diff changeset
417 */
kono
parents:
diff changeset
418 void cilk_fiber_invoke_tbb_stack_op(cilk_fiber* fiber, __cilk_tbb_stack_op op);
kono
parents:
diff changeset
419
kono
parents:
diff changeset
420 /** @brief Returns the fiber data associated with the specified fiber.
kono
parents:
diff changeset
421 *
kono
parents:
diff changeset
422 * The returned struct is owned by the fiber and is deallocated automatically
kono
parents:
diff changeset
423 * when the fiber is destroyed. However, the client_data field is owned by
kono
parents:
diff changeset
424 * the client and must be deallocated separately. When called for a
kono
parents:
diff changeset
425 * newly-allocated fiber, the returned data is zero-filled.
kono
parents:
diff changeset
426 *
kono
parents:
diff changeset
427 * @param fiber The fiber for which data is being requested.
kono
parents:
diff changeset
428 * @return The fiber data for the specified fiber
kono
parents:
diff changeset
429 */
kono
parents:
diff changeset
430 cilk_fiber_data* cilk_fiber_get_data(cilk_fiber* fiber);
kono
parents:
diff changeset
431
kono
parents:
diff changeset
432 /** @brief Retrieve the owner field from the fiber.
kono
parents:
diff changeset
433 *
kono
parents:
diff changeset
434 * This method is provided for convenience. One can also get the
kono
parents:
diff changeset
435 * fiber data, and then get the owner field.
kono
parents:
diff changeset
436 */
kono
parents:
diff changeset
437 __CILKRTS_INLINE
kono
parents:
diff changeset
438 __cilkrts_worker* cilk_fiber_get_owner(cilk_fiber* fiber)
kono
parents:
diff changeset
439 {
kono
parents:
diff changeset
440 // TBD: We really want a static assert here, that this cast is
kono
parents:
diff changeset
441 // doing the right thing.
kono
parents:
diff changeset
442 cilk_fiber_data* fdata = (cilk_fiber_data*)fiber;
kono
parents:
diff changeset
443 return fdata->owner;
kono
parents:
diff changeset
444 }
kono
parents:
diff changeset
445
kono
parents:
diff changeset
446 /** @brief Sets the owner field of a fiber.
kono
parents:
diff changeset
447 *
kono
parents:
diff changeset
448 * This method is provided for convenience. One can also get the
kono
parents:
diff changeset
449 * fiber data, and then get the owner field.
kono
parents:
diff changeset
450 */
kono
parents:
diff changeset
451 __CILKRTS_INLINE
kono
parents:
diff changeset
452 void cilk_fiber_set_owner(cilk_fiber* fiber, __cilkrts_worker* owner)
kono
parents:
diff changeset
453 {
kono
parents:
diff changeset
454 // TBD: We really want a static assert here, that this cast is
kono
parents:
diff changeset
455 // doing the right thing.
kono
parents:
diff changeset
456 cilk_fiber_data* fdata = (cilk_fiber_data*)fiber;
kono
parents:
diff changeset
457 fdata->owner = owner;
kono
parents:
diff changeset
458 }
kono
parents:
diff changeset
459
kono
parents:
diff changeset
460 /** @brief Returns true if this fiber is resumable.
kono
parents:
diff changeset
461 *
kono
parents:
diff changeset
462 * A fiber is considered resumable when it is not currently being
kono
parents:
diff changeset
463 * executed.
kono
parents:
diff changeset
464 *
kono
parents:
diff changeset
465 * This function is used by Windows exception code.
kono
parents:
diff changeset
466 * @param fiber The fiber to check.
kono
parents:
diff changeset
467 * @return Nonzero value if fiber is resumable.
kono
parents:
diff changeset
468 */
kono
parents:
diff changeset
469 int cilk_fiber_is_resumable(cilk_fiber* fiber);
kono
parents:
diff changeset
470
kono
parents:
diff changeset
471 /**
kono
parents:
diff changeset
472 * @brief Returns the base of this fiber's stack.
kono
parents:
diff changeset
473 *
kono
parents:
diff changeset
474 * On some platforms (e.g., Windows), the fiber must have started
kono
parents:
diff changeset
475 * running before we can get this information.
kono
parents:
diff changeset
476 *
kono
parents:
diff changeset
477 * @param fiber The fiber to get the stack pointer from.
kono
parents:
diff changeset
478 * @return The base of the stack, or NULL if this
kono
parents:
diff changeset
479 * information is not available yet.
kono
parents:
diff changeset
480 */
kono
parents:
diff changeset
481 char* cilk_fiber_get_stack_base(cilk_fiber* fiber);
kono
parents:
diff changeset
482
kono
parents:
diff changeset
483
kono
parents:
diff changeset
484 /****************************************************************************
kono
parents:
diff changeset
485 * TBB interop functions
kono
parents:
diff changeset
486 * **************************************************************************/
kono
parents:
diff changeset
487 /**
kono
parents:
diff changeset
488 * @brief Set the TBB callback information for a stack
kono
parents:
diff changeset
489 *
kono
parents:
diff changeset
490 * @param fiber The fiber to set the TBB callback information for
kono
parents:
diff changeset
491 * @param o The TBB callback thunk. Specifies the callback address and
kono
parents:
diff changeset
492 * context value.
kono
parents:
diff changeset
493 */
kono
parents:
diff changeset
494 void cilk_fiber_set_stack_op(cilk_fiber *fiber,
kono
parents:
diff changeset
495 __cilk_tbb_stack_op_thunk o);
kono
parents:
diff changeset
496
kono
parents:
diff changeset
497 /**
kono
parents:
diff changeset
498 * @brief Save the TBB callback address and context value in
kono
parents:
diff changeset
499 * thread-local storage.
kono
parents:
diff changeset
500 *
kono
parents:
diff changeset
501 * We'll use it later when the thread binds to a worker.
kono
parents:
diff changeset
502 *
kono
parents:
diff changeset
503 * @param o The TBB callback thunk which is to be saved.
kono
parents:
diff changeset
504 */
kono
parents:
diff changeset
505 void cilk_fiber_tbb_interop_save_stack_op_info(__cilk_tbb_stack_op_thunk o);
kono
parents:
diff changeset
506
kono
parents:
diff changeset
507 /**
kono
parents:
diff changeset
508 * @brief Move TBB stack-op info from thread-local storage and store
kono
parents:
diff changeset
509 * it into the fiber.
kono
parents:
diff changeset
510 *
kono
parents:
diff changeset
511 * Called when we bind a thread to the runtime. If there is any TBB
kono
parents:
diff changeset
512 * interop information in thread-local storage, bind it to the stack
kono
parents:
diff changeset
513 * now.
kono
parents:
diff changeset
514 *
kono
parents:
diff changeset
515 * @pre \c fiber should not be NULL.
kono
parents:
diff changeset
516 * @param fiber The fiber that should take over the TBB interop information.
kono
parents:
diff changeset
517 */
kono
parents:
diff changeset
518 void cilk_fiber_tbb_interop_use_saved_stack_op_info(cilk_fiber *fiber);
kono
parents:
diff changeset
519
kono
parents:
diff changeset
520 /**
kono
parents:
diff changeset
521 * @brief Free any TBB interop information saved in thread-local storage
kono
parents:
diff changeset
522 */
kono
parents:
diff changeset
523 void cilk_fiber_tbb_interop_free_stack_op_info(void);
kono
parents:
diff changeset
524
kono
parents:
diff changeset
525 /**
kono
parents:
diff changeset
526 * @brief Migrate any TBB interop information from a cilk_fiber to
kono
parents:
diff changeset
527 * thread-local storage.
kono
parents:
diff changeset
528 *
kono
parents:
diff changeset
529 * Returns immediately if no TBB interop information has been
kono
parents:
diff changeset
530 * associated with the stack.
kono
parents:
diff changeset
531 *
kono
parents:
diff changeset
532 * @param fiber The cilk_fiber who's TBB interop information should be
kono
parents:
diff changeset
533 * saved in thread-local storage.
kono
parents:
diff changeset
534 */
kono
parents:
diff changeset
535 void cilk_fiber_tbb_interop_save_info_from_stack(cilk_fiber* fiber);
kono
parents:
diff changeset
536
kono
parents:
diff changeset
537
kono
parents:
diff changeset
538 #if SUPPORT_GET_CURRENT_FIBER
kono
parents:
diff changeset
539 /** @brief Returns the fiber associated with the currently executing thread
kono
parents:
diff changeset
540 *
kono
parents:
diff changeset
541 * @note This function is currently used only for testing the Cilk
kono
parents:
diff changeset
542 * runtime.
kono
parents:
diff changeset
543 *
kono
parents:
diff changeset
544 * @return Fiber associated with the currently executing thread or NULL if no
kono
parents:
diff changeset
545 * fiber was associated with this thread.
kono
parents:
diff changeset
546 */
kono
parents:
diff changeset
547 cilk_fiber* cilk_fiber_get_current_fiber(void);
kono
parents:
diff changeset
548 #endif
kono
parents:
diff changeset
549
kono
parents:
diff changeset
550
kono
parents:
diff changeset
551 #if NEED_FIBER_REF_COUNTS
kono
parents:
diff changeset
552 /** @brief Returns true if this fiber has reference count > 0.
kono
parents:
diff changeset
553 *
kono
parents:
diff changeset
554 * @param fiber The fiber to check for references.
kono
parents:
diff changeset
555 * @return Nonzero value if the fiber has references.
kono
parents:
diff changeset
556 */
kono
parents:
diff changeset
557 int cilk_fiber_has_references(cilk_fiber *fiber);
kono
parents:
diff changeset
558
kono
parents:
diff changeset
559 /** @brief Returns the value of the reference count.
kono
parents:
diff changeset
560 *
kono
parents:
diff changeset
561 * @param fiber The fiber to check for references.
kono
parents:
diff changeset
562 * @return The value of the reference count of fiber.
kono
parents:
diff changeset
563 */
kono
parents:
diff changeset
564 int cilk_fiber_get_ref_count(cilk_fiber *fiber);
kono
parents:
diff changeset
565
kono
parents:
diff changeset
566 /** @brief Adds a reference to this fiber.
kono
parents:
diff changeset
567 *
kono
parents:
diff changeset
568 * Increments the reference count of a current fiber. Fibers with
kono
parents:
diff changeset
569 * nonzero reference count will not be freed or returned to a fiber
kono
parents:
diff changeset
570 * pool.
kono
parents:
diff changeset
571 *
kono
parents:
diff changeset
572 * @param fiber The fiber to add a reference to.
kono
parents:
diff changeset
573 */
kono
parents:
diff changeset
574 void cilk_fiber_add_reference(cilk_fiber *fiber);
kono
parents:
diff changeset
575
kono
parents:
diff changeset
576 #endif // NEED_FIBER_REF_COUNTS
kono
parents:
diff changeset
577
kono
parents:
diff changeset
578 __CILKRTS_END_EXTERN_C
kono
parents:
diff changeset
579
kono
parents:
diff changeset
580 #ifdef __cplusplus
kono
parents:
diff changeset
581 // Some C++ implementation details
kono
parents:
diff changeset
582
kono
parents:
diff changeset
583 /// Opaque declaration of a cilk_fiber_sysdep object.
kono
parents:
diff changeset
584 struct cilk_fiber_sysdep;
kono
parents:
diff changeset
585
kono
parents:
diff changeset
586 /**
kono
parents:
diff changeset
587 * cilk_fiber is a base-class for system-dependent fiber implementations.
kono
parents:
diff changeset
588 */
kono
parents:
diff changeset
589 struct cilk_fiber : protected cilk_fiber_data
kono
parents:
diff changeset
590 {
kono
parents:
diff changeset
591 protected:
kono
parents:
diff changeset
592 // This is a rare acceptable use of protected inheritence and protected
kono
parents:
diff changeset
593 // variable access: when the base class and derived class collaborate
kono
parents:
diff changeset
594 // tightly to comprise a single component.
kono
parents:
diff changeset
595
kono
parents:
diff changeset
596 /// For overloading constructor of cilk_fiber.
kono
parents:
diff changeset
597 enum from_thread_t { from_thread = 1 };
kono
parents:
diff changeset
598
kono
parents:
diff changeset
599 // Boolean flags capturing the status of the fiber.
kono
parents:
diff changeset
600 // Each one can be set independently.
kono
parents:
diff changeset
601 // A default fiber is constructed with a flag value of 0.
kono
parents:
diff changeset
602 static const int RESUMABLE = 0x01; ///< True if the fiber is in a suspended state and can be resumed.
kono
parents:
diff changeset
603 static const int ALLOCATED_FROM_THREAD = 0x02; ///< True if fiber was allocated from a thread.
kono
parents:
diff changeset
604
kono
parents:
diff changeset
605 cilk_fiber_proc m_start_proc; ///< Function to run on start up/reset
kono
parents:
diff changeset
606 cilk_fiber_proc m_post_switch_proc; ///< Function that executes when we first switch to a new fiber from a different one.
kono
parents:
diff changeset
607
kono
parents:
diff changeset
608 cilk_fiber* m_pending_remove_ref;///< Fiber to possibly delete on start up or resume
kono
parents:
diff changeset
609 cilk_fiber_pool* m_pending_pool; ///< Pool where m_pending_remove_ref should go if it is deleted.
kono
parents:
diff changeset
610 unsigned m_flags; ///< Captures the status of this fiber.
kono
parents:
diff changeset
611
kono
parents:
diff changeset
612 #if NEED_FIBER_REF_COUNTS
kono
parents:
diff changeset
613 volatile long m_outstanding_references; ///< Counts references to this fiber.
kono
parents:
diff changeset
614 #endif
kono
parents:
diff changeset
615
kono
parents:
diff changeset
616 /// Creates a fiber with NULL data.
kono
parents:
diff changeset
617 cilk_fiber();
kono
parents:
diff changeset
618
kono
parents:
diff changeset
619 /**
kono
parents:
diff changeset
620 * @brief Creates a fiber with user-specified arguments.
kono
parents:
diff changeset
621 *
kono
parents:
diff changeset
622 * @param stack_size Size of stack to use for this fiber.
kono
parents:
diff changeset
623 */
kono
parents:
diff changeset
624 cilk_fiber(std::size_t stack_size);
kono
parents:
diff changeset
625
kono
parents:
diff changeset
626 /// Empty destructor.
kono
parents:
diff changeset
627 ~cilk_fiber();
kono
parents:
diff changeset
628
kono
parents:
diff changeset
629 /**
kono
parents:
diff changeset
630 * @brief Performs any actions that happen after switching from
kono
parents:
diff changeset
631 * one fiber to another.
kono
parents:
diff changeset
632 *
kono
parents:
diff changeset
633 * These actions are:
kono
parents:
diff changeset
634 * 1. Execute m_post_switch_proc on a fiber.
kono
parents:
diff changeset
635 * 2. Do any pending deallocations from the previous fiber.
kono
parents:
diff changeset
636 */
kono
parents:
diff changeset
637 void do_post_switch_actions();
kono
parents:
diff changeset
638
kono
parents:
diff changeset
639 /**
kono
parents:
diff changeset
640 *@brief Helper method that converts a @c cilk_fiber object into a
kono
parents:
diff changeset
641 * @c cilk_fiber_sysdep object.
kono
parents:
diff changeset
642 *
kono
parents:
diff changeset
643 * The @c cilk_fiber_sysdep object contains the system-dependent parts
kono
parents:
diff changeset
644 * of the implementation of a @\c cilk_fiber.
kono
parents:
diff changeset
645 *
kono
parents:
diff changeset
646 * We could have @c cilk_fiber_sysdep inherit from @c cilk_fiber and
kono
parents:
diff changeset
647 * then use virtual functions. But since a given platform only uses
kono
parents:
diff changeset
648 * one definition of @c cilk_fiber_sysdep at a time, we statically
kono
parents:
diff changeset
649 * cast between them.
kono
parents:
diff changeset
650 */
kono
parents:
diff changeset
651 inline cilk_fiber_sysdep* sysdep();
kono
parents:
diff changeset
652
kono
parents:
diff changeset
653 /**
kono
parents:
diff changeset
654 * @brief Set resumable flag to specified state.
kono
parents:
diff changeset
655 */
kono
parents:
diff changeset
656 inline void set_resumable(bool state) {
kono
parents:
diff changeset
657 m_flags = state ? (m_flags | RESUMABLE) : (m_flags & (~RESUMABLE));
kono
parents:
diff changeset
658 }
kono
parents:
diff changeset
659
kono
parents:
diff changeset
660 /**
kono
parents:
diff changeset
661 *@brief Set the allocated_from_thread flag.
kono
parents:
diff changeset
662 */
kono
parents:
diff changeset
663 inline void set_allocated_from_thread(bool state) {
kono
parents:
diff changeset
664 m_flags = state ? (m_flags | ALLOCATED_FROM_THREAD) : (m_flags & (~ALLOCATED_FROM_THREAD));
kono
parents:
diff changeset
665 }
kono
parents:
diff changeset
666
kono
parents:
diff changeset
667 public:
kono
parents:
diff changeset
668
kono
parents:
diff changeset
669 /**
kono
parents:
diff changeset
670 * @brief Allocates and initializes a new cilk_fiber, either from
kono
parents:
diff changeset
671 * the specified pool or from the heap.
kono
parents:
diff changeset
672 *
kono
parents:
diff changeset
673 * @pre pool should not be NULL.
kono
parents:
diff changeset
674 */
kono
parents:
diff changeset
675 static cilk_fiber* allocate(cilk_fiber_pool* pool);
kono
parents:
diff changeset
676
kono
parents:
diff changeset
677 /**
kono
parents:
diff changeset
678 * @brief Allocates a fiber from the heap.
kono
parents:
diff changeset
679 */
kono
parents:
diff changeset
680 static cilk_fiber* allocate_from_heap(size_t stack_size);
kono
parents:
diff changeset
681
kono
parents:
diff changeset
682 /**
kono
parents:
diff changeset
683 * @brief Return a fiber to the heap.
kono
parents:
diff changeset
684 */
kono
parents:
diff changeset
685 void deallocate_to_heap();
kono
parents:
diff changeset
686
kono
parents:
diff changeset
687 /**
kono
parents:
diff changeset
688 * @brief Reset the state of a fiber just allocated from a pool.
kono
parents:
diff changeset
689 */
kono
parents:
diff changeset
690 void reset_state(cilk_fiber_proc start_proc);
kono
parents:
diff changeset
691
kono
parents:
diff changeset
692 /**
kono
parents:
diff changeset
693 * @brief Remove a reference from this fiber, possibly
kono
parents:
diff changeset
694 * deallocating it if the reference count becomes 0.
kono
parents:
diff changeset
695 *
kono
parents:
diff changeset
696 * @param pool The fiber pool to which this fiber should be returned.
kono
parents:
diff changeset
697 * @return The final reference count.
kono
parents:
diff changeset
698 */
kono
parents:
diff changeset
699 int remove_reference(cilk_fiber_pool* pool);
kono
parents:
diff changeset
700
kono
parents:
diff changeset
701 /**
kono
parents:
diff changeset
702 * @brief Deallocate the fiber by returning it to the pool.
kono
parents:
diff changeset
703 * @pre This method should only be called if the reference count
kono
parents:
diff changeset
704 * is 0.
kono
parents:
diff changeset
705 *
kono
parents:
diff changeset
706 * @param pool The fiber pool to return this fiber to. If NULL,
kono
parents:
diff changeset
707 * fiber is returned to the heap.
kono
parents:
diff changeset
708 */
kono
parents:
diff changeset
709 void deallocate_self(cilk_fiber_pool *pool);
kono
parents:
diff changeset
710
kono
parents:
diff changeset
711 /** @brief Allocates and intializes this thread's main fiber. */
kono
parents:
diff changeset
712 static cilk_fiber* allocate_from_thread();
kono
parents:
diff changeset
713
kono
parents:
diff changeset
714 /** @brief Deallocate a fiber created from a thread,
kono
parents:
diff changeset
715 * possibly destroying it.
kono
parents:
diff changeset
716 *
kono
parents:
diff changeset
717 * This method decrements the reference count of this fiber by 2,
kono
parents:
diff changeset
718 * and destroys the fiber if the reference count is 0.
kono
parents:
diff changeset
719 *
kono
parents:
diff changeset
720 * OS-specific cleanup for the fiber executes unconditionally with for
kono
parents:
diff changeset
721 * this method. The destruction of the actual object, however, does
kono
parents:
diff changeset
722 * not occur unless the reference count is 0.
kono
parents:
diff changeset
723 *
kono
parents:
diff changeset
724 * @return Final reference count. If the count is 0, the fiber was
kono
parents:
diff changeset
725 * returned to the heap.
kono
parents:
diff changeset
726 */
kono
parents:
diff changeset
727 int deallocate_from_thread();
kono
parents:
diff changeset
728
kono
parents:
diff changeset
729 /** @brief Removes a reference from this fiber.
kono
parents:
diff changeset
730 *
kono
parents:
diff changeset
731 * This method deallocates this fiber if the reference count
kono
parents:
diff changeset
732 * becomes 0.
kono
parents:
diff changeset
733 *
kono
parents:
diff changeset
734 * @pre This fiber must be allocated from a thread.
kono
parents:
diff changeset
735 * @return The final reference count of this fiber.
kono
parents:
diff changeset
736 */
kono
parents:
diff changeset
737 int remove_reference_from_thread();
kono
parents:
diff changeset
738
kono
parents:
diff changeset
739 #if SUPPORT_GET_CURRENT_FIBER
kono
parents:
diff changeset
740 /** @brief Get the current fiber from TLS.
kono
parents:
diff changeset
741 *
kono
parents:
diff changeset
742 * @note This function is only used for testing the runtime.
kono
parents:
diff changeset
743 */
kono
parents:
diff changeset
744 static cilk_fiber* get_current_fiber();
kono
parents:
diff changeset
745 #endif
kono
parents:
diff changeset
746
kono
parents:
diff changeset
747 /** @brief Suspend execution on current fiber resumes other fiber.
kono
parents:
diff changeset
748 *
kono
parents:
diff changeset
749 * Control returns after resuming execution of the self fiber.
kono
parents:
diff changeset
750 */
kono
parents:
diff changeset
751 void suspend_self_and_resume_other(cilk_fiber* other);
kono
parents:
diff changeset
752
kono
parents:
diff changeset
753
kono
parents:
diff changeset
754 /** @brief Removes a reference from the currently executing fiber
kono
parents:
diff changeset
755 * and resumes other fiber.
kono
parents:
diff changeset
756 *
kono
parents:
diff changeset
757 * This fiber may be returned to a pool or deallocated.
kono
parents:
diff changeset
758 */
kono
parents:
diff changeset
759 NORETURN remove_reference_from_self_and_resume_other(cilk_fiber_pool* self_pool,
kono
parents:
diff changeset
760 cilk_fiber* other);
kono
parents:
diff changeset
761
kono
parents:
diff changeset
762 /** @brief Set the proc method to execute immediately after a switch
kono
parents:
diff changeset
763 * to this fiber.
kono
parents:
diff changeset
764 *
kono
parents:
diff changeset
765 * @param post_switch_proc Proc method to execute immediately
kono
parents:
diff changeset
766 * after switching to this fiber.
kono
parents:
diff changeset
767 */
kono
parents:
diff changeset
768 inline void set_post_switch_proc(cilk_fiber_proc post_switch_proc) {
kono
parents:
diff changeset
769 m_post_switch_proc = post_switch_proc;
kono
parents:
diff changeset
770 }
kono
parents:
diff changeset
771
kono
parents:
diff changeset
772 /** @brief Returns true if this fiber is resumable.
kono
parents:
diff changeset
773 *
kono
parents:
diff changeset
774 * A fiber is considered resumable when it is not currently being
kono
parents:
diff changeset
775 * executed.
kono
parents:
diff changeset
776 */
kono
parents:
diff changeset
777 inline bool is_resumable(void) {
kono
parents:
diff changeset
778 return (m_flags & RESUMABLE);
kono
parents:
diff changeset
779 }
kono
parents:
diff changeset
780
kono
parents:
diff changeset
781 /** @brief Returns true if fiber was allocated from a thread. */
kono
parents:
diff changeset
782 inline bool is_allocated_from_thread(void) {
kono
parents:
diff changeset
783 return (m_flags & ALLOCATED_FROM_THREAD);
kono
parents:
diff changeset
784 }
kono
parents:
diff changeset
785
kono
parents:
diff changeset
786 /**
kono
parents:
diff changeset
787 *@brief Get the address at the base of the stack for this fiber.
kono
parents:
diff changeset
788 */
kono
parents:
diff changeset
789 inline char* get_stack_base();
kono
parents:
diff changeset
790
kono
parents:
diff changeset
791 /** @brief Return the data for this fiber. */
kono
parents:
diff changeset
792 cilk_fiber_data* get_data() { return this; }
kono
parents:
diff changeset
793
kono
parents:
diff changeset
794 /** @brief Return the data for this fiber. */
kono
parents:
diff changeset
795 cilk_fiber_data const* get_data() const { return this; }
kono
parents:
diff changeset
796
kono
parents:
diff changeset
797
kono
parents:
diff changeset
798 #if NEED_FIBER_REF_COUNTS
kono
parents:
diff changeset
799 /** @brief Verifies that this fiber's reference count equals v. */
kono
parents:
diff changeset
800 inline void assert_ref_count_equals(long v) {
kono
parents:
diff changeset
801 #if FIBER_CHECK_REF_COUNTS
kono
parents:
diff changeset
802 CILK_ASSERT(m_outstanding_references >= v);
kono
parents:
diff changeset
803 #endif
kono
parents:
diff changeset
804 }
kono
parents:
diff changeset
805
kono
parents:
diff changeset
806 /** @brief Verifies that this fiber's reference count is at least v. */
kono
parents:
diff changeset
807 inline void assert_ref_count_at_least(long v) {
kono
parents:
diff changeset
808 #if FIBER_CHECK_REF_COUNTS
kono
parents:
diff changeset
809 CILK_ASSERT(m_outstanding_references >= v);
kono
parents:
diff changeset
810 #endif
kono
parents:
diff changeset
811 }
kono
parents:
diff changeset
812
kono
parents:
diff changeset
813 /** @brief Get reference count. */
kono
parents:
diff changeset
814 inline long get_ref_count() { return m_outstanding_references; }
kono
parents:
diff changeset
815
kono
parents:
diff changeset
816 /** @brief Initialize reference count.
kono
parents:
diff changeset
817 * Operation is not atomic.
kono
parents:
diff changeset
818 */
kono
parents:
diff changeset
819 inline void init_ref_count(long v) { m_outstanding_references = v; }
kono
parents:
diff changeset
820
kono
parents:
diff changeset
821 // For Windows, updates to the fiber reference count need to be
kono
parents:
diff changeset
822 // atomic, because exceptions can live on a stack that we are not
kono
parents:
diff changeset
823 // currently executing on. Thus, we can update the reference
kono
parents:
diff changeset
824 // count of a fiber we are not currently executing on.
kono
parents:
diff changeset
825
kono
parents:
diff changeset
826 /** @brief Increment reference count for this fiber [Windows]. */
kono
parents:
diff changeset
827 inline void inc_ref_count() { atomic_inc_ref_count(); }
kono
parents:
diff changeset
828
kono
parents:
diff changeset
829 /** @brief Decrement reference count for this fiber [Windows]. */
kono
parents:
diff changeset
830 inline long dec_ref_count() { return atomic_dec_ref_count(); }
kono
parents:
diff changeset
831
kono
parents:
diff changeset
832 /** @brief Subtract v from the reference count for this fiber [Windows]. */
kono
parents:
diff changeset
833 inline long sub_from_ref_count(long v) { return atomic_sub_from_ref_count(v); }
kono
parents:
diff changeset
834 #else // NEED_FIBER_REF_COUNTS
kono
parents:
diff changeset
835
kono
parents:
diff changeset
836 // Without reference counting, we have placeholder methods.
kono
parents:
diff changeset
837 inline void init_ref_count(long v) { }
kono
parents:
diff changeset
838
kono
parents:
diff changeset
839 inline void inc_ref_count() { }
kono
parents:
diff changeset
840
kono
parents:
diff changeset
841 // With no reference counting, dec_ref_count always return 0.
kono
parents:
diff changeset
842 // Thus, anyone checking is always the "last" one.
kono
parents:
diff changeset
843 inline long dec_ref_count() { return 0; }
kono
parents:
diff changeset
844 inline long sub_from_ref_count(long v) { return 0; }
kono
parents:
diff changeset
845
kono
parents:
diff changeset
846 // The assert methods do nothing.
kono
parents:
diff changeset
847 inline void assert_ref_count_equals(long v) { }
kono
parents:
diff changeset
848 inline void assert_ref_count_at_least(long v) { }
kono
parents:
diff changeset
849 #endif
kono
parents:
diff changeset
850
kono
parents:
diff changeset
851 /**
kono
parents:
diff changeset
852 * @brief Call TBB to tell it about an "interesting" event.
kono
parents:
diff changeset
853 *
kono
parents:
diff changeset
854 * @param op Value specifying the event to track.
kono
parents:
diff changeset
855 */
kono
parents:
diff changeset
856 void invoke_tbb_stack_op(__cilk_tbb_stack_op op);
kono
parents:
diff changeset
857
kono
parents:
diff changeset
858 private:
kono
parents:
diff changeset
859
kono
parents:
diff changeset
860 /**
kono
parents:
diff changeset
861 * @brief Helper method: try to allocate a fiber from this pool or
kono
parents:
diff changeset
862 * its ancestors without going to the OS / heap.
kono
parents:
diff changeset
863 *
kono
parents:
diff changeset
864 * Returns allocated pool, or NULL if no pool is found.
kono
parents:
diff changeset
865 *
kono
parents:
diff changeset
866 * If pool contains a suitable fiber. Return it. Otherwise, try to
kono
parents:
diff changeset
867 * recursively grab a fiber from the parent pool, if there is one.
kono
parents:
diff changeset
868 *
kono
parents:
diff changeset
869 * This method will not allocate a fiber from the heap.
kono
parents:
diff changeset
870 */
kono
parents:
diff changeset
871 static cilk_fiber* try_allocate_from_pool_recursive(cilk_fiber_pool* pool);
kono
parents:
diff changeset
872
kono
parents:
diff changeset
873
kono
parents:
diff changeset
874 #if NEED_FIBER_REF_COUNTS
kono
parents:
diff changeset
875 /**
kono
parents:
diff changeset
876 * @brief Atomic increment of reference count.
kono
parents:
diff changeset
877 */
kono
parents:
diff changeset
878 void atomic_inc_ref_count();
kono
parents:
diff changeset
879
kono
parents:
diff changeset
880 /**
kono
parents:
diff changeset
881 * @brief Atomic decrement of reference count.
kono
parents:
diff changeset
882 */
kono
parents:
diff changeset
883 long atomic_dec_ref_count();
kono
parents:
diff changeset
884
kono
parents:
diff changeset
885 /**
kono
parents:
diff changeset
886 * @brief Atomic subtract of v from reference count.
kono
parents:
diff changeset
887 * @param v Value to subtract.
kono
parents:
diff changeset
888 */
kono
parents:
diff changeset
889 long atomic_sub_from_ref_count(long v);
kono
parents:
diff changeset
890 #endif // NEED_FIBER_REF_COUNTS
kono
parents:
diff changeset
891
kono
parents:
diff changeset
892 };
kono
parents:
diff changeset
893
kono
parents:
diff changeset
894 #endif // __cplusplus
kono
parents:
diff changeset
895
kono
parents:
diff changeset
896 #endif // ! defined(INCLUDED_CILK_FIBER_DOT_H)