1 /* sysdep.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 /** 40 * @file sysdep.h 41 * 42 * @brief Common system-dependent functions 43 */ 44 45 #ifndef INCLUDED_SYSDEP_DOT_H 46 #define INCLUDED_SYSDEP_DOT_H 47 48 #include <cilk/common.h> 49 #include <internal/abi.h> 50 51 #include "global_state.h" 52 #include "full_frame.h" 53 #include "os.h" 54 #include "os_mutex.h" 55 56 /** 57 * @brief Default page size for Cilk stacks. 58 * 59 * All Cilk stacks should have size that is a multiple of this value. 60 */ 61 #define PAGE 4096 62 63 /** 64 * @brief Size of a scheduling stack. 65 * 66 * A scheduling stack is used to by system workers to execute runtime 67 * code. Since this stack is only executing runtime functions, we 68 * don't need it to be a full size stack. 69 * 70 * The number "18" should be small since the runtime doesn't require a 71 * large stack, but large enough to call "printf" for debugging. 72 */ 73 #define CILK_SCHEDULING_STACK_SIZE (18*PAGE) 74 75 __CILKRTS_BEGIN_EXTERN_C 76 77 78 /** 79 * Code to initialize the system-dependent portion of the global_state_t 80 * 81 * @param g Pointer to the global state. 82 */ 83 COMMON_SYSDEP 84 void __cilkrts_init_global_sysdep(global_state_t *g); 85 86 /** 87 * Code to clean up the system-dependent portion of the global_state_t 88 * 89 * @param g Pointer to the global state. 90 */ 91 COMMON_SYSDEP 92 void __cilkrts_destroy_global_sysdep(global_state_t *g); 93 94 /** 95 * Passes stack range to Cilkscreen. This functionality should be moved 96 * into Cilkscreen. 97 */ 98 COMMON_SYSDEP 99 void __cilkrts_establish_c_stack(void); 100 101 102 /** 103 * Save system dependent information in the full_frame and 104 * __cilkrts_stack_frame. Part of promoting a 105 * __cilkrts_stack_frame to a full_frame. 106 * 107 * @param w The worker the frame was running on. Not used. 108 * @param ff The full frame that is being created for the 109 * __cilkrts_stack_frame. 110 * @param sf The __cilkrts_stack_frame that's being promoted 111 * to a full frame. 112 * @param state_valid ? 113 * @param why A description of why make_unrunnable was called. 114 * Used for debugging. 115 */ 116 COMMON_SYSDEP 117 void __cilkrts_make_unrunnable_sysdep(__cilkrts_worker *w, 118 full_frame *ff, 119 __cilkrts_stack_frame *sf, 120 int state_valid, 121 const char *why); 122 123 124 /** 125 * OS-specific code to spawn worker threads. 126 * 127 * @param g The global state. 128 * @param n Number of worker threads to start. 129 */ 130 COMMON_SYSDEP 131 void __cilkrts_start_workers(global_state_t *g, int n); 132 133 /** 134 * @brief OS-specific code to stop worker threads. 135 * 136 * @param g The global state. 137 */ 138 COMMON_SYSDEP 139 void __cilkrts_stop_workers(global_state_t *g); 140 141 /** 142 * @brief Imports a user thread the first time it returns to a stolen parent. 143 * 144 * The thread has been bound to a worker, but additional steps need to 145 * be taken to start running a scheduling loop. 146 * 147 * @param w The worker bound to the thread. 148 */ 149 COMMON_SYSDEP 150 void __cilkrts_sysdep_import_user_thread(__cilkrts_worker *w); 151 152 /** 153 * @brief Function to be run for each of the system worker threads. 154 * 155 * This declaration also appears in cilk/cilk_undocumented.h -- don't 156 * change one declaration without also changing the other. 157 * 158 * @param arg The context value passed to the thread creation routine for 159 * the OS we're running on. 160 * 161 * @returns OS dependent. 162 */ 163 #ifdef _WIN32 164 /* Do not use CILK_API because __cilkrts_worker_stub must be __stdcall */ 165 CILK_EXPORT unsigned __CILKRTS_NOTHROW __stdcall 166 __cilkrts_worker_stub(void *arg); 167 #else 168 /* Do not use CILK_API because __cilkrts_worker_stub have default visibility */ 169 __attribute__((visibility("default"))) 170 void* __CILKRTS_NOTHROW __cilkrts_worker_stub(void *arg); 171 #endif 172 173 /** 174 * Initialize any OS-depenendent portions of a newly created 175 * __cilkrts_worker. 176 * 177 * Exported for Piersol. Without the export, Piersol doesn't display 178 * useful information in the stack trace. This declaration also appears in 179 * cilk/cilk_undocumented.h -- do not modify one without modifying the other. 180 * 181 * @param w The worker being initialized. 182 */ 183 COMMON_SYSDEP 184 CILK_EXPORT 185 void __cilkrts_init_worker_sysdep(__cilkrts_worker *w); 186 187 /** 188 * Deallocate any OS-depenendent portions of a __cilkrts_worker. 189 * 190 * @param w The worker being deallocaed. 191 */ 192 COMMON_SYSDEP 193 void __cilkrts_destroy_worker_sysdep(__cilkrts_worker *w); 194 195 /** 196 * Called to do any OS-dependent setup before starting execution on a 197 * frame. Mostly deals with exception handling data. 198 * 199 * @param w The worker the frame will run on. 200 * @param ff The full_frame that is about to be resumed. 201 */ 202 COMMON_SYSDEP 203 void __cilkrts_setup_for_execution_sysdep(__cilkrts_worker *w, 204 full_frame *ff); 205 206 /** 207 * @brief OS-specific implementaton of resetting fiber and frame state 208 * to resume exeuction. 209 * 210 * This method: 211 * 1. Calculates the value of stack pointer where we should resume 212 * execution of "sf". This calculation uses info stored in the 213 * fiber, and takes into account alignment and frame size. 214 * 2. Updates sf and ff to match the calculated stack pointer. 215 * 216 * On Unix, the stack pointer calculation looks up the base of the 217 * stack from the fiber. 218 * 219 * On Windows, this calculation is calls "alloca" to find a stack 220 * pointer on the currently executing stack. Thus, the Windows code 221 * assumes @c fiber is the currently executing fiber. 222 * 223 * @param fiber fiber to resume execution on. 224 * @param ff full_frame for the frame we're resuming. 225 * @param sf __cilkrts_stack_frame that we should resume 226 * @return The calculated stack pointer. 227 */ 228 COMMON_SYSDEP 229 char* sysdep_reset_jump_buffers_for_resume(cilk_fiber* fiber, 230 full_frame *ff, 231 __cilkrts_stack_frame *sf); 232 233 /** 234 * @brief System-dependent longjmp to user code for resuming execution 235 * of a @c __cilkrts_stack_frame. 236 * 237 * This method: 238 * - Changes the stack pointer in @c sf to @c new_sp. 239 * - If @c ff_for_exceptions is not NULL, changes fields in @c sf and 240 * @c ff_for_exceptions for exception processing. 241 * - Restores any floating point state 242 * - Finishes with a longjmp to user code, never to return. 243 * 244 * @param new_sp stack pointer where we should resume execution 245 * @param sf @c __cilkrts_stack_frame for the frame we're resuming. 246 * @param ff_for_exceptions full_frame to safe exception info into, if necessary 247 */ 248 COMMON_SYSDEP 249 NORETURN 250 sysdep_longjmp_to_sf(char* new_sp, 251 __cilkrts_stack_frame *sf, 252 full_frame *ff_for_exceptions); 253 254 /** 255 * @brief System-dependent code to save floating point control information 256 * to a @c __cilkrts_stack_frame. This function will be called by compilers 257 * that cannot inline the code. 258 * 259 * Note that this function does *not* save the current floating point 260 * registers. It saves the floating point control words that control 261 * precision and rounding and stuff like that. 262 * 263 * This function will be a noop for architectures that don't have warts 264 * like the floating point control words, or where the information is 265 * already being saved by the setjmp. 266 * 267 * @param sf @c __cilkrts_stack_frame for the frame we're 268 * saving the floating point control information in. 269 */ 270 COMMON_SYSDEP 271 void 272 sysdep_save_fp_ctrl_state(__cilkrts_stack_frame *sf); 273 274 275 /** 276 * @brief restore x86 floating point state 277 * 278 * Only used for x86 and Intel64 processors 279 */ 280 COMMON_SYSDEP 281 void restore_x86_fp_state(__cilkrts_stack_frame *sf); 282 283 __CILKRTS_END_EXTERN_C 284 285 #endif // ! defined(INCLUDED_SYSDEP_DOT_H) 286