scheduler.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422
  1. /* scheduler.h -*-C++-*-
  2. *
  3. *************************************************************************
  4. *
  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:
  13. *
  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.
  23. *
  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. **************************************************************************/
  38. /**
  39. * @file scheduler.h
  40. *
  41. * @brief scheduler.h declares routines for the Intel Cilk Plus scheduler,
  42. * making it the heart of the Intel Cilk Plus implementation.
  43. */
  44. #ifndef INCLUDED_SCHEDULER_DOT_H
  45. #define INCLUDED_SCHEDULER_DOT_H
  46. #include <cilk/common.h>
  47. #include <internal/abi.h>
  48. #include "rts-common.h"
  49. #include "full_frame.h"
  50. #include "reducer_impl.h"
  51. #include "global_state.h"
  52. #ifdef CILK_RECORD_REPLAY
  53. #include "record-replay.h"
  54. #endif
  55. __CILKRTS_BEGIN_EXTERN_C
  56. /**
  57. * @brief Flag to disable parallel reductions.
  58. *
  59. * Set to 0 to allow parallel reductions.
  60. */
  61. #define DISABLE_PARALLEL_REDUCERS 0
  62. /**
  63. * @brief Debugging level for parallel reductions.
  64. *
  65. * Print debugging messages and assertions for parallel reducers. 0 is
  66. * no debugging. A higher value generates more output.
  67. */
  68. #define REDPAR_DEBUG 0
  69. /**
  70. * @brief Lock the worker mutex to allow exclusive access to the
  71. * values in the @c __cilkrts_worker and local_state structures.
  72. *
  73. * @pre @c w->l->do_not_steal must not be set. Essentially this
  74. * condition asserts that the worker is not locked recursively.
  75. *
  76. * @param w The worker to lock.
  77. */
  78. COMMON_PORTABLE
  79. void __cilkrts_worker_lock(__cilkrts_worker *w);
  80. /**
  81. * @brief Unlock the worker mutex.
  82. *
  83. * @pre @c w->l->do_not_steal must be set. Essentially this condition
  84. * asserts that the worker has been previously locked.
  85. *
  86. * @param w The worker to unlock.
  87. */
  88. COMMON_PORTABLE
  89. void __cilkrts_worker_unlock(__cilkrts_worker *w);
  90. /**
  91. * @brief Push the next full frame to be made active in this worker
  92. * and increment its join counter.
  93. *
  94. * __cilkrts_push_next_frame and pop_next_frame work on a one-element queue.
  95. * This queue is used to communicate across the runtime from the code that
  96. * wants to activate a frame to the code that can actually begin execution
  97. * on that frame. They are asymetrical in that push increments the join
  98. * counter but pop does not decrement it. Rather, a single push/pop
  99. * combination makes a frame active and increments its join counter once.
  100. *
  101. * @note A system worker may chose to push work onto a user worker if
  102. * the work is the continuation from a sync which only the user worker
  103. * may complete.
  104. *
  105. * @param w The worker which the frame is to be pushed onto.
  106. * @param ff The full_frame which is to be continued by the worker.
  107. */
  108. COMMON_PORTABLE
  109. void __cilkrts_push_next_frame(__cilkrts_worker *w,
  110. full_frame *ff);
  111. /**
  112. * @brief Sync on this worker.
  113. *
  114. * If this worker is the last to reach the sync, execution may resume
  115. * on this worker after the sync.
  116. *
  117. * If this worker is not the last spawned child to reach the sync,
  118. * then execution is suspended and the worker will re-enter the
  119. * scheduling loop, looking for work it can steal.
  120. *
  121. * This function will jump into the runtime to switch to the scheduling
  122. * stack to implement most of its logic.
  123. *
  124. * @param w The worker which is executing the sync.
  125. * @param sf The __cilkrts_stack_frame containing the sync.
  126. */
  127. COMMON_PORTABLE
  128. NORETURN __cilkrts_c_sync(__cilkrts_worker *w,
  129. __cilkrts_stack_frame *sf);
  130. /**
  131. * @brief Worker @c w completely promotes its own deque, simulating the case
  132. * where the whole deque is stolen.
  133. *
  134. * We use this mechanism to force the allocation of new storage for
  135. * reducers for race-detection purposes.
  136. *
  137. * This method is called from the reducer lookup logic when
  138. * @c g->force_reduce is set.
  139. *
  140. * @warning Use of "force_reduce" is known to have bugs when run with
  141. * more than 1 worker.
  142. *
  143. * @param w The worker which is to have all entries in its deque
  144. * promoted to full frames.
  145. */
  146. COMMON_PORTABLE
  147. void __cilkrts_promote_own_deque(__cilkrts_worker *w);
  148. /**
  149. * Called when a spawned function attempts to return and
  150. * __cilkrts_undo_detach() fails. This can happen for two reasons:
  151. *
  152. * @li If another worker is considering stealing our parent, it bumps the
  153. * exception pointer while it did so, which will cause __cilkrts_undo_detach()
  154. * to fail. If the other worker didn't complete the steal of our parent, we
  155. * still may be able to return to it, either because the steal attempt failed,
  156. * or we won the race for the tail pointer.
  157. *
  158. * @li If the function's parent has been stolen then we cannot return. Instead
  159. * we'll longjmp into the runtime to switch onto the scheduling stack to
  160. * execute do_return_from_spawn() and determine what to do. Either this
  161. * worker is the last one to the sync, in which case we need to jump to the
  162. * sync, or this worker is not the last one to the sync, in which case we'll
  163. * abandon this work and jump to the scheduling loop to search for more work
  164. * we can steal.
  165. *
  166. * @param w The worker which attempting to return from a spawn to
  167. * a stolen parent.
  168. * @param returning_sf The stack frame which is returning.
  169. */
  170. COMMON_PORTABLE
  171. void __cilkrts_c_THE_exception_check(__cilkrts_worker *w,
  172. __cilkrts_stack_frame *returning_sf);
  173. /**
  174. * @brief Return an exception to an stolen parent.
  175. *
  176. * Used by the gcc implementation of exceptions to return an exception
  177. * to a stolen parent
  178. *
  179. * @param w The worker which attempting to return from a spawn with an
  180. * exception to a stolen parent.
  181. * @param returning_sf The stack frame which is returning.
  182. */
  183. COMMON_PORTABLE
  184. NORETURN __cilkrts_exception_from_spawn(__cilkrts_worker *w,
  185. __cilkrts_stack_frame *returning_sf);
  186. /**
  187. * @brief Used by the Windows implementations of exceptions to migrate an exception
  188. * across fibers.
  189. *
  190. * Call this function when an exception has been thrown and has to
  191. * traverse across a steal. The exception has already been wrapped
  192. * up, so all that remains is to longjmp() into the continuation,
  193. * sync, and re-raise it.
  194. *
  195. * @param sf The __cilkrts_stack_frame for the frame that is attempting to
  196. * return an exception to a stolen parent.
  197. */
  198. void __cilkrts_migrate_exception (__cilkrts_stack_frame *sf);
  199. /**
  200. * @brief Return from a call, not a spawn, where this frame has ever
  201. * been stolen.
  202. *
  203. * @param w The worker that is returning from a frame which was ever stolen.
  204. */
  205. COMMON_PORTABLE
  206. void __cilkrts_return(__cilkrts_worker *w);
  207. /**
  208. * @brief Special return from the initial frame.
  209. *
  210. * This method will be called from @c __cilkrts_leave_frame if
  211. * @c CILK_FRAME_LAST is set.
  212. *
  213. * This function will do the things necessary to cleanup, and unbind the
  214. * thread from the Intel Cilk Plus runtime. If this is the last user
  215. * worker unbinding from the runtime, all system worker threads will be
  216. * suspended.
  217. *
  218. * @pre @c w must be the currently executing worker, and must be a user
  219. * worker.
  220. *
  221. * @param w The worker that's returning from the initial frame.
  222. */
  223. COMMON_PORTABLE
  224. void __cilkrts_c_return_from_initial(__cilkrts_worker *w);
  225. /**
  226. * @brief Used by exception handling code to pop an entry from the
  227. * worker's deque.
  228. *
  229. * @param w Worker to pop the entry from
  230. *
  231. * @return __cilkrts_stack_frame of parent call
  232. * @return NULL if the deque is empty
  233. */
  234. COMMON_PORTABLE
  235. __cilkrts_stack_frame *__cilkrts_pop_tail(__cilkrts_worker *w);
  236. /**
  237. * @brief Modifies the worker's protected_tail to prevent frames from
  238. * being stolen.
  239. *
  240. * The Dekker protocol has been extended to only steal if head+1 is also
  241. * less than protected_tail.
  242. *
  243. * @param w The worker to be modified.
  244. * @param new_protected_tail The new setting for protected_tail, or NULL if the
  245. * entire deque is to be protected
  246. *
  247. * @return Previous value of protected tail.
  248. */
  249. COMMON_PORTABLE
  250. __cilkrts_stack_frame *volatile *__cilkrts_disallow_stealing(
  251. __cilkrts_worker *w,
  252. __cilkrts_stack_frame *volatile *new_protected_tail);
  253. /**
  254. * @brief Restores the protected tail to a previous state, possibly
  255. * allowing frames to be stolen.
  256. *
  257. * @param w The worker to be modified.
  258. * @param saved_protected_tail A previous setting for protected_tail that is
  259. * to be restored
  260. */
  261. COMMON_PORTABLE
  262. void __cilkrts_restore_stealing(
  263. __cilkrts_worker *w,
  264. __cilkrts_stack_frame *volatile *saved_protected_tail);
  265. /**
  266. * @brief Initialize a @c __cilkrts_worker.
  267. *
  268. * @note The memory for the worker must have been allocated outside
  269. * this call.
  270. *
  271. * @param g The global_state_t.
  272. * @param self The index into the global_state's array of workers for this
  273. * worker, or -1 if this worker was allocated from the heap and cannot be
  274. * stolen from.
  275. * @param w The worker to be initialized.
  276. *
  277. * @return The initialized __cilkrts_worker.
  278. */
  279. COMMON_PORTABLE
  280. __cilkrts_worker *make_worker(global_state_t *g,
  281. int self,
  282. __cilkrts_worker *w);
  283. /**
  284. * @brief Free up any resources allocated for a worker.
  285. *
  286. * @note The memory for the @c __cilkrts_worker itself must be
  287. * deallocated outside this call.
  288. *
  289. * @param w The worker to be destroyed.
  290. */
  291. COMMON_PORTABLE
  292. void destroy_worker (__cilkrts_worker *w);
  293. /**
  294. * @brief Initialize the runtime.
  295. *
  296. * If necessary, allocates and initializes the global state. If
  297. * necessary, unsuspends the system workers.
  298. *
  299. * @param start Specifies whether the workers are to be unsuspended if
  300. * they are suspended. Allows __cilkrts_init() to start up the runtime without
  301. * releasing the system threads.
  302. */
  303. COMMON_PORTABLE
  304. void __cilkrts_init_internal(int start);
  305. /**
  306. * @brief Part of the sequence to shutdown the runtime.
  307. *
  308. * Specifically, this call frees the @c global_state_t for the runtime.
  309. *
  310. * @param g The global_state_t.
  311. */
  312. COMMON_PORTABLE
  313. void __cilkrts_deinit_internal(global_state_t *g);
  314. /**
  315. * Obsolete. We no longer need to import or export reducer maps.
  316. */
  317. COMMON_PORTABLE
  318. cilkred_map *__cilkrts_xchg_reducer(
  319. __cilkrts_worker *w, cilkred_map *newmap) cilk_nothrow;
  320. /**
  321. * @brief Called when a user thread is bound to the runtime.
  322. *
  323. * If this action increments the count of bound user threads from 0 to
  324. * 1, the system worker threads are unsuspended.
  325. *
  326. * If this action increments the count of bound user threads from 0 to
  327. * 1, the system worker threads are unsuspended.
  328. *
  329. * @pre Global lock must be held.
  330. * @param g The runtime global state.
  331. */
  332. COMMON_PORTABLE
  333. void __cilkrts_enter_cilk(global_state_t *g);
  334. /**
  335. * @brief Called when a user thread is unbound from the runtime.
  336. *
  337. * If this action decrements the count of bound user threads to 0, the
  338. * system worker threads are suspended.
  339. *
  340. *
  341. * @pre Global lock must be held.
  342. *
  343. * @param g The runtime global state.
  344. */
  345. COMMON_PORTABLE
  346. void __cilkrts_leave_cilk(global_state_t *g);
  347. /**
  348. * @brief cilk_fiber_proc that runs the main scheduler loop on a
  349. * user worker.
  350. *
  351. * @pre fiber's owner field should be set to the correct __cilkrts_worker
  352. * @pre fiber must be a user worker.
  353. *
  354. * @param fiber The scheduling fiber object.
  355. */
  356. void scheduler_fiber_proc_for_user_worker(cilk_fiber *fiber);
  357. /**
  358. * @brief Prints out Cilk runtime statistics.
  359. *
  360. * @param g The runtime global state.
  361. *
  362. * This method is useful only for debugging purposes. No guarantees
  363. * are made as to the validity of this data. :)
  364. */
  365. COMMON_PORTABLE
  366. void __cilkrts_dump_stats_to_stderr(global_state_t *g);
  367. #ifdef CILK_RECORD_REPLAY
  368. COMMON_PORTABLE
  369. char * walk_pedigree_nodes(char *p, const __cilkrts_pedigree *pnode);
  370. /**
  371. * @brief Used by exception handling code to simulate the popping of
  372. * an entry from the worker's deque.
  373. *
  374. * @param w Worker whose deque we want to check
  375. *
  376. * @return @c __cilkrts_stack_frame of parent call
  377. * @return NULL if the deque is empty
  378. */
  379. COMMON_PORTABLE
  380. __cilkrts_stack_frame *simulate_pop_tail(__cilkrts_worker *w);
  381. #endif
  382. __CILKRTS_END_EXTERN_C
  383. #endif // ! defined(INCLUDED_SCHEDULER_DOT_H)