Mercurial > cgi-bin > hgwebdir.cgi > VMS > VMS_Implementations > VSs_impls > VSs__MC_shared_impl
comparison VSs.c @ 27:3b30da4643d1
Update2.. in middle of changes.. made request handler ptr be sent w/req struct
| author | Sean Halle <seanhalle@yahoo.com> |
|---|---|
| date | Sat, 12 Jan 2013 11:31:51 -0800 |
| parents | a60399b62614 |
| children | 91caa8a9d591 |
comparison
equal
deleted
inserted
replaced
| 21:f21b45f50d11 | 22:739e3be3b204 |
|---|---|
| 13 | 13 |
| 14 #include "VSs.h" | 14 #include "VSs.h" |
| 15 #include "Measurement/VSs_Counter_Recording.h" | 15 #include "Measurement/VSs_Counter_Recording.h" |
| 16 | 16 |
| 17 //========================================================================== | 17 //========================================================================== |
| 18 void | |
| 19 VSs__init_Helper(); | |
| 20 | |
| 21 SlaveVP * | |
| 22 VSs__create_thread_w_ID_and_affinity( TopLevelFnPtr fnPtr, void *initData, | |
| 23 int32 *thdID, int32 coreToAssignOnto, SlaveVP *creatingThd ); | |
| 18 | 24 |
| 19 //========================================================================== | 25 //========================================================================== |
| 20 | 26 |
| 21 | 27 |
| 22 | 28 |
| 73 | 79 |
| 74 /*For now, use TSC -- later, make these two macros with assembly that first | 80 /*For now, use TSC -- later, make these two macros with assembly that first |
| 75 * saves jump point, and second jumps back several times to get reliable time | 81 * saves jump point, and second jumps back several times to get reliable time |
| 76 */ | 82 */ |
| 77 void | 83 void |
| 78 VSs__begin_primitive() | 84 VSs__begin_primitive( SlaveVP *animSlv ) |
| 79 { VSsSemData *semData; | 85 { VSsLangData *langData; |
| 80 | 86 |
| 81 semData = (VSsSemData *)PR_WL__give_sem_data( animSlv, VSs_MAGIC_NUMBER); | 87 langData = (VSsLangData *)PR_WL__give_lang_data( animSlv, VSs_MAGIC_NUMBER); |
| 82 | 88 |
| 83 saveLowTimeStampCountInto( semData->primitiveStartTime ); | 89 saveLowTimeStampCountInto( langData->primitiveStartTime ); |
| 84 } | 90 } |
| 85 | 91 |
| 86 /*Just quick and dirty for now -- make reliable later | 92 /*Just quick and dirty for now -- make reliable later |
| 87 * will want this to jump back several times -- to be sure cache is warm | 93 * will want this to jump back several times -- to be sure cache is warm |
| 88 * because don't want comm time included in calc-time measurement -- and | 94 * because don't want comm time included in calc-time measurement -- and |
| 89 * also to throw out any "weird" values due to OS interrupt or TSC rollover | 95 * also to throw out any "weird" values due to OS interrupt or TSC rollover |
| 90 */ | 96 */ |
| 91 int32 | 97 int32 |
| 92 VSs__end_primitive_and_give_cycles( SlaveVP animSlv ) | 98 VSs__end_primitive_and_give_cycles( SlaveVP *animSlv ) |
| 93 { int32 endTime, startTime; | 99 { int32 endTime, startTime; |
| 94 VSsSemData *semData; | 100 VSsLangData *langData; |
| 95 | 101 |
| 96 //TODO: fix by repeating time-measurement | 102 //TODO: fix by repeating time-measurement |
| 97 saveLowTimeStampCountInto( endTime ); | 103 saveLowTimeStampCountInto( endTime ); |
| 98 semData = (VSsSemData *)PR_WL__give_sem_data( animSlv, VSs_MAGIC_NUMBER); | 104 langData = (VSsLangData *)PR_WL__give_lang_data( animSlv, VSs_MAGIC_NUMBER); |
| 99 startTime = semData->primitiveStartTime; | 105 startTime = langData->primitiveStartTime; |
| 100 return (endTime - startTime); | 106 return (endTime - startTime); |
| 101 } | 107 } |
| 102 | |
| 103 | |
| 104 //=========================================================================== | |
| 105 | |
| 106 | 108 |
| 107 | 109 |
| 108 | 110 |
| 109 //=========================================================================== | 111 //=========================================================================== |
| 110 | 112 |
| 122 { | 124 { |
| 123 return VSs__create_thread_w_ID_and_affinity( fnPtr, initData, thdID, | 125 return VSs__create_thread_w_ID_and_affinity( fnPtr, initData, thdID, |
| 124 ANY_CORE, creatingThd ); | 126 ANY_CORE, creatingThd ); |
| 125 } | 127 } |
| 126 | 128 |
| 129 /* old version -- looks safe to delete | |
| 130 SlaveVP * | |
| 131 VSs__create_slave_with_affinity( TopLevelFnPtr fnPtr, void *initData, | |
| 132 SlaveVP *creatingSlv, int32 coreToAssignOnto ) | |
| 133 { VSsLangReq reqData; | |
| 134 | |
| 135 //the lang request data is on the stack and disappears when this | |
| 136 // call returns -- it's guaranteed to remain in the VP's stack for as | |
| 137 // long as the VP is suspended. | |
| 138 reqData.reqType = create_slave_w_aff; //not used, May 2012 | |
| 139 reqData.coreToAssignOnto = coreToAssignOnto; | |
| 140 reqData.fnPtr = fnPtr; | |
| 141 reqData.initData = initData; | |
| 142 reqData.callingSlv = creatingSlv; | |
| 143 | |
| 144 PR_WL__send_create_slaveVP_req( &reqData, creatingSlv, VSs_MAGIC_NUMBER ); | |
| 145 | |
| 146 return creatingSlv->dataRetFromReq; | |
| 147 } | |
| 148 */ | |
| 149 | |
| 127 | 150 |
| 128 SlaveVP * | 151 SlaveVP * |
| 129 VSs__create_thread_w_ID_and_affinity( TopLevelFnPtr fnPtr, void *initData, | 152 VSs__create_thread_w_ID_and_affinity( TopLevelFnPtr fnPtr, void *initData, |
| 130 int32 *thdID, int32 coreToAssignOnto, SlaveVP *creatingThd ) | 153 int32 *thdID, int32 coreToAssignOnto, SlaveVP *creatingThd ) |
| 131 { VSsSemReq reqData; | 154 { VSsLangReq reqData; |
| 132 | 155 |
| 133 //the semantic request data is on the stack and disappears when this | 156 //the lang request data is on the stack and disappears when this |
| 134 // call returns -- it's guaranteed to remain in the VP's stack for as | 157 // call returns -- it's guaranteed to remain in the VP's stack for as |
| 135 // long as the VP is suspended. | 158 // long as the VP is suspended. |
| 136 reqData.reqType = create_slave; //know type because in a PR create req | 159 reqData.reqType = create_slave; //know type because in a PR create req |
| 137 reqData.coreToAssignOnto = coreToAssignOnto; | 160 reqData.coreToAssignOnto = coreToAssignOnto; |
| 138 | 161 reqData.fnPtr = fnPtr; |
| 139 PR_WL__send_create_slaveVP_req( &reqData, fnPtr, initData, thdID, | 162 reqData.initData = initData; |
| 163 | |
| 164 PR_WL__send_create_slaveVP_req( &reqData, thdID, &handleCreateThd, | |
| 140 creatingThd, VSs_MAGIC_NUMBER ); | 165 creatingThd, VSs_MAGIC_NUMBER ); |
| 141 return creatingThd->dataRetFromReq; | 166 return (SlaveVP *)creatingThd->dataRetFromReq; |
| 142 } | 167 } |
| 143 | 168 |
| 144 /*This is always the last thing done in the code animated by a thread VP. | 169 /*This is always the last thing done in the code animated by a thread VP. |
| 145 * Normally, this would be the last line of the thread's top level function. | 170 * Normally, this would be the last line of the thread's top level function. |
| 146 * But, if the thread exits from any point, it has to do so by calling | 171 * But, if the thread exits from any point, it has to do so by calling |
| 149 *It simply sends a dissipate request, which handles all the state cleanup. | 174 *It simply sends a dissipate request, which handles all the state cleanup. |
| 150 */ | 175 */ |
| 151 void | 176 void |
| 152 VSs__end_thread( SlaveVP *thdToEnd ) | 177 VSs__end_thread( SlaveVP *thdToEnd ) |
| 153 { | 178 { |
| 154 PR_WL__send_dissipate_req( thdToEnd, VSs_MAGIC_NUMBER ); | 179 //the lang request is null for VSs version of end slave |
| 180 PR_WL__send_end_slave_req( NULL, &handleDissipate, thdToEnd, VSs_MAGIC_NUMBER ); | |
| 155 } | 181 } |
| 156 | 182 |
| 157 | 183 |
| 158 | 184 |
| 159 //=========================================================================== | 185 //=========================================================================== |
| 162 //======================= task submit and end ============================== | 188 //======================= task submit and end ============================== |
| 163 /* | 189 /* |
| 164 */ | 190 */ |
| 165 void | 191 void |
| 166 VSs__submit_task( VSsTaskType *taskType, void *args, SlaveVP *animSlv) | 192 VSs__submit_task( VSsTaskType *taskType, void *args, SlaveVP *animSlv) |
| 167 { VSsSemReq reqData; | 193 { VSsLangReq reqData; |
| 168 | 194 |
| 169 reqData.reqType = submit_task; | 195 reqData.reqType = submit_task; |
| 170 | 196 |
| 171 reqData.taskType = taskType; | 197 reqData.taskType = taskType; |
| 172 reqData.args = args; | 198 reqData.args = args; |
| 173 reqData.callingSlv = animSlv; | 199 reqData.callingSlv = animSlv; |
| 174 | 200 |
| 175 //Create task is a special form, so have to pass as parameters, the | 201 //Create task is a special form, so have to pass as parameters, the |
| 176 // top-level-fn of task and the data for that fn, plus lang's req, | 202 // top-level-fn of task and the data for that fn, plus lang's req, |
| 177 // animating slave, and lang's magic number | 203 // animating slave, and lang's magic number |
| 178 PR_WL__send_create_task_req( taskType->fn, args, &reqData, NO_ID, animSlv, VSs_MAGIC_NUMBER ); | 204 PR_WL__send_create_task_req( taskType->fn, args, &reqData, NO_ID, |
| 205 &handleSubmitTask, animSlv, VSs_MAGIC_NUMBER ); | |
| 179 } | 206 } |
| 180 | 207 |
| 181 void | 208 void |
| 182 VSs__submit_task_with_ID( VSsTaskType *taskType, void *args, int32 *taskID, | 209 VSs__submit_task_with_ID( VSsTaskType *taskType, void *args, int32 *taskID, |
| 183 SlaveVP *animSlv) | 210 SlaveVP *animSlv ) |
| 184 { VSsSemReq reqData; | 211 { VSsLangReq reqData; |
| 185 | 212 |
| 186 reqData.reqType = submit_task; | 213 reqData.reqType = submit_task; |
| 187 | 214 |
| 188 reqData.taskType = taskType; | 215 reqData.taskType = taskType; |
| 189 reqData.args = args; | 216 reqData.args = args; |
| 190 reqData.callingSlv = animSlv; | 217 reqData.callingSlv = animSlv; |
| 191 | 218 |
| 192 PR_WL__send_create_task_req( taskType->fn, args, &reqData, taskID, animSlv, VSs_MAGIC_NUMBER ); | 219 PR_WL__send_create_task_req( taskType->fn, args, &reqData, taskID, |
| 220 &handleSubmitTask, animSlv, VSs_MAGIC_NUMBER ); | |
| 193 } | 221 } |
| 194 | 222 |
| 195 | 223 |
| 196 /*This call is the last to happen in every task. It causes the slave to | 224 /*This call is the last to happen in every task. It causes the slave to |
| 197 * suspend and get the next task out of the task-queue. Notice there is no | 225 * suspend and get the next task out of the task-queue. Notice there is no |
| 210 * | 238 * |
| 211 *But, to stay compatible with all the other PR languages, leave it in.. | 239 *But, to stay compatible with all the other PR languages, leave it in.. |
| 212 */ | 240 */ |
| 213 void | 241 void |
| 214 VSs__end_task( SlaveVP *animSlv ) | 242 VSs__end_task( SlaveVP *animSlv ) |
| 215 { VSsSemReq reqData; | 243 { VSsLangReq reqData; |
| 216 | 244 |
| 217 reqData.reqType = end_task; | 245 //VSs has nothing extra to communicate to end task handler, so lang req is NULL |
| 218 reqData.callingSlv = animSlv; | 246 PR_WL__send_end_task_request( NULL, &handleEndTask, animSlv, VSs_MAGIC_NUMBER ); |
| 219 | |
| 220 PR_WL__send_end_task_request( &reqData, animSlv, VSs_MAGIC_NUMBER ); | |
| 221 } | 247 } |
| 222 | 248 |
| 223 | 249 |
| 224 /*Waits for all tasks that are direct children to end, then resumes calling | 250 /*Waits for all tasks that are direct children to end, then resumes calling |
| 225 * task or thread | 251 * task or thread |
| 226 */ | 252 */ |
| 227 void | 253 void |
| 228 VSs__taskwait(SlaveVP *animSlv) | 254 VSs__taskwait(SlaveVP *animSlv) |
| 229 { | 255 { |
| 230 VSsSemReq reqData; | 256 VSsLangReq reqData; |
| 231 | 257 |
| 232 reqData.reqType = taskwait; | 258 reqData.reqType = taskwait; |
| 233 reqData.callingSlv = animSlv; | 259 reqData.callingSlv = animSlv; |
| 234 | 260 |
| 235 PR_WL__send_sem_request( &reqData, animSlv, VSs_MAGIC_NUMBER ); | 261 PR_WL__send_lang_request( &reqData, &handleTaskwait, animSlv, VSs_MAGIC_NUMBER ); |
| 236 } | 262 } |
| 237 | 263 |
| 238 | 264 |
| 239 | 265 |
| 240 //========================== send and receive ============================ | 266 //========================== send and receive ============================ |
| 241 // | 267 // |
| 242 | 268 |
| 243 inline int32 * | 269 inline int32 * |
| 244 VSs__give_self_taskID( SlaveVP *animSlv ) | 270 VSs__give_self_taskID( SlaveVP *animSlv ) |
| 245 { | 271 { |
| 246 return PR__give_task_ID( animSlv, VSs_MAGIC_NUMBER ); | 272 return PR__give_ID_from_slave( animSlv, VSs_MAGIC_NUMBER ); |
| 247 } | 273 } |
| 248 | 274 |
| 249 //================================ send =================================== | 275 //================================ send =================================== |
| 250 | 276 |
| 251 void | 277 void |
| 252 VSs__send_of_type_to( void *msg, const int32 type, int32 *receiverID, | 278 VSs__send_of_type_to( void *msg, const int32 type, int32 *receiverID, |
| 253 SlaveVP *senderSlv ) | 279 SlaveVP *senderSlv ) |
| 254 { VSsSemReq reqData; | 280 { VSsLangReq reqData; |
| 255 | 281 |
| 256 reqData.reqType = send_type_to; | 282 reqData.reqType = send_type_to; |
| 257 | 283 |
| 258 reqData.msg = msg; | 284 reqData.msg = msg; |
| 259 reqData.msgType = type; | 285 reqData.msgType = type; |
| 260 reqData.receiverID = receiverID; | 286 reqData.receiverID = receiverID; |
| 261 reqData.senderSlv = senderSlv; | 287 reqData.senderSlv = senderSlv; |
| 262 | 288 |
| 263 reqData.nextReqInHashEntry = NULL; | 289 reqData.nextReqInHashEntry = NULL; |
| 264 | 290 |
| 265 PR_WL__send_sem_request( &reqData, senderSlv, VSs_MAGIC_NUMBER ); | 291 PR_WL__send_lang_request( &reqData, &handleSendTypeTo, senderSlv, VSs_MAGIC_NUMBER ); |
| 266 | 292 |
| 267 //When come back from suspend, no longer own data reachable from msg | 293 //When come back from suspend, no longer own data reachable from msg |
| 268 } | 294 } |
| 269 | 295 |
| 270 void | 296 void |
| 271 VSs__send_from_to( void *msg, int32 *senderID, int32 *receiverID, SlaveVP *senderSlv ) | 297 VSs__send_from_to( void *msg, int32 *senderID, int32 *receiverID, SlaveVP *senderSlv ) |
| 272 { VSsSemReq reqData; | 298 { VSsLangReq reqData; |
| 273 | 299 |
| 274 reqData.reqType = send_from_to; | 300 reqData.reqType = send_from_to; |
| 275 | 301 |
| 276 reqData.msg = msg; | 302 reqData.msg = msg; |
| 277 reqData.senderID = senderID; | 303 reqData.senderID = senderID; |
| 278 reqData.receiverID = receiverID; | 304 reqData.receiverID = receiverID; |
| 279 reqData.senderSlv = senderSlv; | 305 reqData.senderSlv = senderSlv; |
| 280 | 306 |
| 281 reqData.nextReqInHashEntry = NULL; | 307 reqData.nextReqInHashEntry = NULL; |
| 282 | 308 |
| 283 PR_WL__send_sem_request( &reqData, senderSlv, VSs_MAGIC_NUMBER ); | 309 PR_WL__send_lang_request( &reqData, &handleSendFromTo, senderSlv, VSs_MAGIC_NUMBER ); |
| 284 } | 310 } |
| 285 | 311 |
| 286 | 312 |
| 287 //================================ receive ================================ | 313 //================================ receive ================================ |
| 288 | 314 |
| 293 * messages. | 319 * messages. |
| 294 */ | 320 */ |
| 295 void * | 321 void * |
| 296 VSs__receive_type_to( const int32 type, int32* receiverID, SlaveVP *receiverSlv ) | 322 VSs__receive_type_to( const int32 type, int32* receiverID, SlaveVP *receiverSlv ) |
| 297 { DEBUG__printf1(dbgRqstHdlr,"WL: receive type to %d",receiverID[1] ); | 323 { DEBUG__printf1(dbgRqstHdlr,"WL: receive type to %d",receiverID[1] ); |
| 298 VSsSemReq reqData; | 324 VSsLangReq reqData; |
| 299 | 325 |
| 300 reqData.reqType = receive_type_to; | 326 reqData.reqType = receive_type_to; |
| 301 | 327 |
| 302 reqData.msgType = type; | 328 reqData.msgType = type; |
| 303 reqData.receiverID = receiverID; | 329 reqData.receiverID = receiverID; |
| 304 reqData.receiverSlv = receiverSlv; | 330 reqData.receiverSlv = receiverSlv; |
| 305 | 331 |
| 306 reqData.nextReqInHashEntry = NULL; | 332 reqData.nextReqInHashEntry = NULL; |
| 307 | 333 |
| 308 PR_WL__send_sem_request( &reqData, receiverSlv, VSs_MAGIC_NUMBER ); | 334 PR_WL__send_lang_request( &reqData, &handleReceiveTypeTo, receiverSlv, VSs_MAGIC_NUMBER ); |
| 309 | 335 |
| 310 return receiverSlv->dataRetFromReq; | 336 return receiverSlv->dataRetFromReq; |
| 311 } | 337 } |
| 312 | 338 |
| 313 | 339 |
| 317 * between sender and receiver. | 343 * between sender and receiver. |
| 318 */ | 344 */ |
| 319 void * | 345 void * |
| 320 VSs__receive_from_to( int32 *senderID, int32 *receiverID, SlaveVP *receiverSlv ) | 346 VSs__receive_from_to( int32 *senderID, int32 *receiverID, SlaveVP *receiverSlv ) |
| 321 { | 347 { |
| 322 VSsSemReq reqData; | 348 VSsLangReq reqData; |
| 323 | 349 |
| 324 reqData.reqType = receive_from_to; | 350 reqData.reqType = receive_from_to; |
| 325 | 351 |
| 326 reqData.senderID = senderID; | 352 reqData.senderID = senderID; |
| 327 reqData.receiverID = receiverID; | 353 reqData.receiverID = receiverID; |
| 328 reqData.receiverSlv = receiverSlv; | 354 reqData.receiverSlv = receiverSlv; |
| 329 | 355 |
| 330 reqData.nextReqInHashEntry = NULL; | 356 reqData.nextReqInHashEntry = NULL; |
| 331 DEBUG__printf2(dbgRqstHdlr,"WL: receive from %d to: %d", reqData.senderID[1], reqData.receiverID[1]); | 357 DEBUG__printf2(dbgRqstHdlr,"WL: receive from %d to: %d", reqData.senderID[1], reqData.receiverID[1]); |
| 332 | 358 |
| 333 PR_WL__send_sem_request( &reqData, receiverSlv, VSs_MAGIC_NUMBER ); | 359 PR_WL__send_lang_request( &reqData, &handleReceiveFromTo, receiverSlv, VSs_MAGIC_NUMBER ); |
| 334 | 360 |
| 335 return receiverSlv->dataRetFromReq; | 361 return receiverSlv->dataRetFromReq; |
| 336 } | 362 } |
| 337 | 363 |
| 338 | 364 |
| 353 /*asm function declarations*/ | 379 /*asm function declarations*/ |
| 354 void asm_save_ret_to_singleton(VSsSingleton *singletonPtrAddr); | 380 void asm_save_ret_to_singleton(VSsSingleton *singletonPtrAddr); |
| 355 void asm_write_ret_from_singleton(VSsSingleton *singletonPtrAddr); | 381 void asm_write_ret_from_singleton(VSsSingleton *singletonPtrAddr); |
| 356 | 382 |
| 357 /*Fn singleton uses ID as index into array of singleton structs held in the | 383 /*Fn singleton uses ID as index into array of singleton structs held in the |
| 358 * semantic environment. | 384 * language environment. |
| 359 */ | 385 */ |
| 360 void | 386 void |
| 361 VSs__start_fn_singleton( int32 singletonID, SlaveVP *animSlv ) | 387 VSs__start_fn_singleton( int32 singletonID, SlaveVP *animSlv ) |
| 362 { | 388 { |
| 363 VSsSemReq reqData; | 389 VSsLangReq reqData; |
| 364 | 390 |
| 365 // | 391 // |
| 366 reqData.reqType = singleton_fn_start; | 392 reqData.reqType = singleton_fn_start; |
| 367 reqData.singletonID = singletonID; | 393 reqData.singletonID = singletonID; |
| 368 | 394 |
| 369 PR_WL__send_sem_request( &reqData, animSlv, VSs_MAGIC_NUMBER ); | 395 PR_WL__send_lang_request( &reqData, &handleStartFnSingleton, animSlv, VSs_MAGIC_NUMBER ); |
| 370 if( animSlv->dataRetFromReq ) //will be 0 or addr of label in end singleton | 396 if( animSlv->dataRetFromReq ) //will be 0 or addr of label in end singleton |
| 371 { | 397 { |
| 372 VSsSemEnv *semEnv = PR_WL__give_sem_env_for( animSlv, VSs_MAGIC_NUMBER ); | 398 VSsLangEnv *langEnv = |
| 373 asm_write_ret_from_singleton(&(semEnv->fnSingletons[ singletonID])); | 399 PR_int__give_lang_env_for_slave__ML( animSlv, VSs_MAGIC_NUMBER ); |
| 400 asm_write_ret_from_singleton(&(langEnv->fnSingletons[ singletonID])); | |
| 374 } | 401 } |
| 375 } | 402 } |
| 376 | 403 |
| 377 /*Data singleton hands addr of loc holding a pointer to a singleton struct. | 404 /*Data singleton hands addr of loc holding a pointer to a singleton struct. |
| 378 * The start_data_singleton makes the structure and puts its addr into the | 405 * The start_data_singleton makes the structure and puts its addr into the |
| 379 * location. | 406 * location. |
| 380 */ | 407 */ |
| 381 void | 408 void |
| 382 VSs__start_data_singleton( VSsSingleton **singletonAddr, SlaveVP *animSlv ) | 409 VSs__start_data_singleton( VSsSingleton **singletonAddr, SlaveVP *animSlv ) |
| 383 { | 410 { |
| 384 VSsSemReq reqData; | 411 VSsLangReq reqData; |
| 385 | 412 |
| 386 if( *singletonAddr && (*singletonAddr)->hasFinished ) | 413 if( *singletonAddr && (*singletonAddr)->hasFinished ) |
| 387 goto JmpToEndSingleton; | 414 goto JmpToEndSingleton; |
| 388 | 415 |
| 389 reqData.reqType = singleton_data_start; | 416 reqData.reqType = singleton_data_start; |
| 390 reqData.singletonPtrAddr = singletonAddr; | 417 reqData.singletonPtrAddr = singletonAddr; |
| 391 | 418 |
| 392 PR_WL__send_sem_request( &reqData, animSlv, VSs_MAGIC_NUMBER ); | 419 PR_WL__send_lang_request( &reqData, &handleStartDataSingleton, animSlv, VSs_MAGIC_NUMBER ); |
| 393 if( animSlv->dataRetFromReq ) //either 0 or end singleton's return addr | 420 if( animSlv->dataRetFromReq ) //either 0 or end singleton's return addr |
| 394 { //Assembly code changes the return addr on the stack to the one | 421 { //Assembly code changes the return addr on the stack to the one |
| 395 // saved into the singleton by the end-singleton-fn | 422 // saved into the singleton by the end-singleton-fn |
| 396 //The return addr is at 0x4(%%ebp) | 423 //The return addr is at 0x4(%%ebp) |
| 397 JmpToEndSingleton: | 424 JmpToEndSingleton: |
| 408 * inside is shared by all invocations of a given singleton ID. | 435 * inside is shared by all invocations of a given singleton ID. |
| 409 */ | 436 */ |
| 410 void | 437 void |
| 411 VSs__end_fn_singleton( int32 singletonID, SlaveVP *animSlv ) | 438 VSs__end_fn_singleton( int32 singletonID, SlaveVP *animSlv ) |
| 412 { | 439 { |
| 413 VSsSemReq reqData; | 440 VSsLangReq reqData; |
| 414 | 441 |
| 415 //don't need this addr until after at least one singleton has reached | 442 //don't need this addr until after at least one singleton has reached |
| 416 // this function | 443 // this function |
| 417 VSsSemEnv *semEnv = PR_WL__give_sem_env_for( animSlv, VSs_MAGIC_NUMBER ); | 444 VSsLangEnv * |
| 418 asm_write_ret_from_singleton(&(semEnv->fnSingletons[ singletonID])); | 445 langEnv = PR_int__give_lang_env_for_slave__ML( animSlv, VSs_MAGIC_NUMBER ); |
| 446 | |
| 447 asm_write_ret_from_singleton(&(langEnv->fnSingletons[ singletonID])); | |
| 419 | 448 |
| 420 reqData.reqType = singleton_fn_end; | 449 reqData.reqType = singleton_fn_end; |
| 421 reqData.singletonID = singletonID; | 450 reqData.singletonID = singletonID; |
| 422 | 451 |
| 423 PR_WL__send_sem_request( &reqData, animSlv, VSs_MAGIC_NUMBER ); | 452 PR_WL__send_lang_request( &reqData, &handleEndFnSingleton, animSlv, VSs_MAGIC_NUMBER ); |
| 424 | 453 |
| 425 EndSingletonInstrAddr: | 454 EndSingletonInstrAddr: |
| 426 return; | 455 return; |
| 427 } | 456 } |
| 428 | 457 |
| 429 void | 458 void |
| 430 VSs__end_data_singleton( VSsSingleton **singletonPtrAddr, SlaveVP *animSlv ) | 459 VSs__end_data_singleton( VSsSingleton **singletonPtrAddr, SlaveVP *animSlv ) |
| 431 { | 460 { |
| 432 VSsSemReq reqData; | 461 VSsLangReq reqData; |
| 433 | 462 |
| 434 //don't need this addr until after singleton struct has reached | 463 //don't need this addr until after singleton struct has reached |
| 435 // this function for first time | 464 // this function for first time |
| 436 //do assembly that saves the return addr of this fn call into the | 465 //do assembly that saves the return addr of this fn call into the |
| 437 // data singleton -- that data-singleton can only be given to exactly | 466 // data singleton -- that data-singleton can only be given to exactly |
| 440 asm_save_ret_to_singleton(*singletonPtrAddr); | 469 asm_save_ret_to_singleton(*singletonPtrAddr); |
| 441 | 470 |
| 442 reqData.reqType = singleton_data_end; | 471 reqData.reqType = singleton_data_end; |
| 443 reqData.singletonPtrAddr = singletonPtrAddr; | 472 reqData.singletonPtrAddr = singletonPtrAddr; |
| 444 | 473 |
| 445 PR_WL__send_sem_request( &reqData, animSlv, VSs_MAGIC_NUMBER ); | 474 PR_WL__send_lang_request( &reqData, &handleEndDataSingleton, animSlv, VSs_MAGIC_NUMBER ); |
| 446 } | 475 } |
| 447 | 476 |
| 448 /*This executes the function in the masterVP, so it executes in isolation | 477 /*This executes the function in the masterVP, so it executes in isolation |
| 449 * from any other copies -- only one copy of the function can ever execute | 478 * from any other copies -- only one copy of the function can ever execute |
| 450 * at a time. | 479 * at a time. |
| 457 */ | 486 */ |
| 458 void | 487 void |
| 459 VSs__animate_short_fn_in_isolation( PtrToAtomicFn ptrToFnToExecInMaster, | 488 VSs__animate_short_fn_in_isolation( PtrToAtomicFn ptrToFnToExecInMaster, |
| 460 void *data, SlaveVP *animSlv ) | 489 void *data, SlaveVP *animSlv ) |
| 461 { | 490 { |
| 462 VSsSemReq reqData; | 491 VSsLangReq reqData; |
| 463 | 492 |
| 464 // | 493 // |
| 465 reqData.reqType = atomic; | 494 reqData.reqType = atomic; |
| 466 reqData.fnToExecInMaster = ptrToFnToExecInMaster; | 495 reqData.fnToExecInMaster = ptrToFnToExecInMaster; |
| 467 reqData.dataForFn = data; | 496 reqData.dataForFn = data; |
| 468 | 497 |
| 469 PR_WL__send_sem_request( &reqData, animSlv, VSs_MAGIC_NUMBER ); | 498 PR_WL__send_lang_request( &reqData, &handleAtomic, animSlv, VSs_MAGIC_NUMBER ); |
| 470 } | 499 } |
| 471 | 500 |
| 472 | 501 |
| 473 /*This suspends to the master. | 502 /*This suspends to the master. |
| 474 *First, it looks at the VP's data, to see the highest transactionID that VP | 503 *First, it looks at the VP's data, to see the highest transactionID that VP |
| 484 *If NULL, then write requesting into the field and resume. | 513 *If NULL, then write requesting into the field and resume. |
| 485 */ | 514 */ |
| 486 void | 515 void |
| 487 VSs__start_transaction( int32 transactionID, SlaveVP *animSlv ) | 516 VSs__start_transaction( int32 transactionID, SlaveVP *animSlv ) |
| 488 { | 517 { |
| 489 VSsSemReq reqData; | 518 VSsLangReq reqData; |
| 490 | 519 |
| 491 // | 520 // |
| 492 reqData.callingSlv = animSlv; | 521 reqData.callingSlv = animSlv; |
| 493 reqData.reqType = trans_start; | 522 reqData.reqType = trans_start; |
| 494 reqData.transID = transactionID; | 523 reqData.transID = transactionID; |
| 495 | 524 |
| 496 PR_WL__send_sem_request( &reqData, animSlv, VSs_MAGIC_NUMBER ); | 525 PR_WL__send_lang_request( &reqData, &handleTransStart, animSlv, VSs_MAGIC_NUMBER ); |
| 497 } | 526 } |
| 498 | 527 |
| 499 /*This suspends to the master, then uses transactionID as index into an | 528 /*This suspends to the master, then uses transactionID as index into an |
| 500 * array of transaction structures. | 529 * array of transaction structures. |
| 501 *It looks at VP_currently_executing to be sure it's same as requesting VP. | 530 *It looks at VP_currently_executing to be sure it's same as requesting VP. |
| 506 * resumes both. | 535 * resumes both. |
| 507 */ | 536 */ |
| 508 void | 537 void |
| 509 VSs__end_transaction( int32 transactionID, SlaveVP *animSlv ) | 538 VSs__end_transaction( int32 transactionID, SlaveVP *animSlv ) |
| 510 { | 539 { |
| 511 VSsSemReq reqData; | 540 VSsLangReq reqData; |
| 512 | 541 |
| 513 // | 542 // |
| 514 reqData.callingSlv = animSlv; | 543 reqData.callingSlv = animSlv; |
| 515 reqData.reqType = trans_end; | 544 reqData.reqType = trans_end; |
| 516 reqData.transID = transactionID; | 545 reqData.transID = transactionID; |
| 517 | 546 |
| 518 PR_WL__send_sem_request( &reqData, animSlv, VSs_MAGIC_NUMBER ); | 547 PR_WL__send_lang_request( &reqData, &handleTransEnd, animSlv, VSs_MAGIC_NUMBER ); |
| 519 } | 548 } |
| 520 | 549 |
| 521 //======================== Internal ================================== | 550 //======================== Internal ================================== |
| 522 /* | 551 |
| 523 */ | |
| 524 | |
| 525 SlaveVP * | |
| 526 VSs__create_slave_with_affinity( TopLevelFnPtr fnPtr, void *initData, | |
| 527 SlaveVP *creatingSlv, int32 coreToAssignOnto ) | |
| 528 { VSsSemReq reqData; | |
| 529 | |
| 530 //the semantic request data is on the stack and disappears when this | |
| 531 // call returns -- it's guaranteed to remain in the VP's stack for as | |
| 532 // long as the VP is suspended. | |
| 533 reqData.reqType = create_slave_w_aff; //not used, May 2012 | |
| 534 reqData.coreToAssignOnto = coreToAssignOnto; | |
| 535 reqData.fnPtr = fnPtr; | |
| 536 reqData.initData = initData; | |
| 537 reqData.callingSlv = creatingSlv; | |
| 538 | |
| 539 PR_WL__send_create_slaveVP_req( &reqData, creatingSlv, VSs_MAGIC_NUMBER ); | |
| 540 | |
| 541 return creatingSlv->dataRetFromReq; | |
| 542 } | |
| 543 |
