comparison VSs.c @ 2:f2ed1c379fe7

code nearly complete.. about to begin debugging
author Sean Halle <seanhalle@yahoo.com>
date Wed, 30 May 2012 15:02:38 -0700
parents 67a3a05a39c0
children 468b8638ff92
comparison
equal deleted inserted replaced
0:6b3fd829c598 1:82dc3af3539d
9 #include <malloc.h> 9 #include <malloc.h>
10 10
11 #include "Queue_impl/PrivateQueue.h" 11 #include "Queue_impl/PrivateQueue.h"
12 #include "Hash_impl/PrivateHash.h" 12 #include "Hash_impl/PrivateHash.h"
13 13
14 #include "VOMP.h" 14 #include "VSs.h"
15 #include "VOMP_Counter_Recording.h" 15 #include "VSs_Counter_Recording.h"
16 16
17 //========================================================================== 17 //==========================================================================
18 18
19 void 19 void
20 VOMP__init(); 20 VSs__init();
21 21
22 void 22 void
23 VOMP__init_Helper(); 23 VSs__init_Helper();
24 //========================================================================== 24 //==========================================================================
25 25
26 26
27 27
28 //=========================================================================== 28 //===========================================================================
30 30
31 /*These are the library functions *called in the application* 31 /*These are the library functions *called in the application*
32 * 32 *
33 *There's a pattern for the outside sequential code to interact with the 33 *There's a pattern for the outside sequential code to interact with the
34 * VMS_HW code. 34 * VMS_HW code.
35 *The VMS_HW system is inside a boundary.. every VOMP system is in its 35 *The VMS_HW system is inside a boundary.. every VSs system is in its
36 * own directory that contains the functions for each of the processor types. 36 * own directory that contains the functions for each of the processor types.
37 * One of the processor types is the "seed" processor that starts the 37 * One of the processor types is the "seed" processor that starts the
38 * cascade of creating all the processors that do the work. 38 * cascade of creating all the processors that do the work.
39 *So, in the directory is a file called "EntryPoint.c" that contains the 39 *So, in the directory is a file called "EntryPoint.c" that contains the
40 * function, named appropriately to the work performed, that the outside 40 * function, named appropriately to the work performed, that the outside
41 * sequential code calls. This function follows a pattern: 41 * sequential code calls. This function follows a pattern:
42 *1) it calls VOMP__init() 42 *1) it calls VSs__init()
43 *2) it creates the initial data for the seed processor, which is passed 43 *2) it creates the initial data for the seed processor, which is passed
44 * in to the function 44 * in to the function
45 *3) it creates the seed VOMP processor, with the data to start it with. 45 *3) it creates the seed VSs processor, with the data to start it with.
46 *4) it calls startVOMPThenWaitUntilWorkDone 46 *4) it calls startVSsThenWaitUntilWorkDone
47 *5) it gets the returnValue from the transfer struc and returns that 47 *5) it gets the returnValue from the transfer struc and returns that
48 * from the function 48 * from the function
49 * 49 *
50 *For now, a new VOMP system has to be created via VOMP__init every 50 *For now, a new VSs system has to be created via VSs__init every
51 * time an entry point function is called -- later, might add letting the 51 * time an entry point function is called -- later, might add letting the
52 * VOMP system be created once, and let all the entry points just reuse 52 * VSs system be created once, and let all the entry points just reuse
53 * it -- want to be as simple as possible now, and see by using what makes 53 * it -- want to be as simple as possible now, and see by using what makes
54 * sense for later.. 54 * sense for later..
55 */ 55 */
56 56
57 57
70 * 70 *
71 *NOTE: no Threads should exist in the outside program that might touch 71 *NOTE: no Threads should exist in the outside program that might touch
72 * any of the data reachable from initData passed in to here 72 * any of the data reachable from initData passed in to here
73 */ 73 */
74 void 74 void
75 VOMP__create_seed_procr_and_do_work( TopLevelFnPtr fnPtr, void *initData ) 75 VSs__create_seed_slave_and_do_work( TopLevelFnPtr fnPtr, void *initData )
76 { VOMPSemEnv *semEnv; 76 { VSsSemEnv *semEnv;
77 SlaveVP *seedPr; 77 SlaveVP *seedPr;
78 78
79 VOMP__init(); //normal multi-thd 79 VSs__init(); //normal multi-thd
80 80
81 semEnv = _VMSMasterEnv->semanticEnv; 81 semEnv = _VMSMasterEnv->semanticEnv;
82 82
83 //VOMP starts with one processor, which is put into initial environ, 83 //VSs starts with one processor, which is put into initial environ,
84 // and which then calls create() to create more, thereby expanding work 84 // and which then calls create() to create more, thereby expanding work
85 seedPr = VOMP__create_procr_helper( fnPtr, initData, 85 seedPr = VSs__create_slave_helper( fnPtr, initData,
86 semEnv, semEnv->nextCoreToGetNewPr++ ); 86 semEnv, semEnv->nextCoreToGetNewPr++ );
87 87
88 resume_slaveVP( seedPr, semEnv ); 88 resume_slaveVP( seedPr, semEnv );
89 89
90 VMS_SS__start_the_work_then_wait_until_done(); //normal multi-thd 90 VMS_SS__start_the_work_then_wait_until_done(); //normal multi-thd
91 91
92 VOMP__cleanup_after_shutdown(); 92 VSs__cleanup_after_shutdown();
93 } 93 }
94 94
95 95
96 int32 96 int32
97 VOMP__giveMinWorkUnitCycles( float32 percentOverhead ) 97 VSs__giveMinWorkUnitCycles( float32 percentOverhead )
98 { 98 {
99 return MIN_WORK_UNIT_CYCLES; 99 return MIN_WORK_UNIT_CYCLES;
100 } 100 }
101 101
102 int32 102 int32
103 VOMP__giveIdealNumWorkUnits() 103 VSs__giveIdealNumWorkUnits()
104 { 104 {
105 return NUM_ANIM_SLOTS * NUM_CORES; 105 return NUM_ANIM_SLOTS * NUM_CORES;
106 } 106 }
107 107
108 int32 108 int32
109 VOMP__give_number_of_cores_to_schedule_onto() 109 VSs__give_number_of_cores_to_schedule_onto()
110 { 110 {
111 return NUM_CORES; 111 return NUM_CORES;
112 } 112 }
113 113
114 /*For now, use TSC -- later, make these two macros with assembly that first 114 /*For now, use TSC -- later, make these two macros with assembly that first
115 * saves jump point, and second jumps back several times to get reliable time 115 * saves jump point, and second jumps back several times to get reliable time
116 */ 116 */
117 void 117 void
118 VOMP__start_primitive() 118 VSs__start_primitive()
119 { saveLowTimeStampCountInto( ((VOMPSemEnv *)(_VMSMasterEnv->semanticEnv))-> 119 { saveLowTimeStampCountInto( ((VSsSemEnv *)(_VMSMasterEnv->semanticEnv))->
120 primitiveStartTime ); 120 primitiveStartTime );
121 } 121 }
122 122
123 /*Just quick and dirty for now -- make reliable later 123 /*Just quick and dirty for now -- make reliable later
124 * will want this to jump back several times -- to be sure cache is warm 124 * will want this to jump back several times -- to be sure cache is warm
125 * because don't want comm time included in calc-time measurement -- and 125 * because don't want comm time included in calc-time measurement -- and
126 * also to throw out any "weird" values due to OS interrupt or TSC rollover 126 * also to throw out any "weird" values due to OS interrupt or TSC rollover
127 */ 127 */
128 int32 128 int32
129 VOMP__end_primitive_and_give_cycles() 129 VSs__end_primitive_and_give_cycles()
130 { int32 endTime, startTime; 130 { int32 endTime, startTime;
131 //TODO: fix by repeating time-measurement 131 //TODO: fix by repeating time-measurement
132 saveLowTimeStampCountInto( endTime ); 132 saveLowTimeStampCountInto( endTime );
133 startTime =((VOMPSemEnv*)(_VMSMasterEnv->semanticEnv))->primitiveStartTime; 133 startTime =((VSsSemEnv*)(_VMSMasterEnv->semanticEnv))->primitiveStartTime;
134 return (endTime - startTime); 134 return (endTime - startTime);
135 } 135 }
136 136
137 //=========================================================================== 137 //===========================================================================
138 138
139 /*Initializes all the data-structures for a VOMP system -- but doesn't 139 /*Initializes all the data-structures for a VSs system -- but doesn't
140 * start it running yet! 140 * start it running yet!
141 * 141 *
142 *This runs in the main thread -- before VMS starts up 142 *This runs in the main thread -- before VMS starts up
143 * 143 *
144 *This sets up the semantic layer over the VMS system 144 *This sets up the semantic layer over the VMS system
145 * 145 *
146 *First, calls VMS_Setup, then creates own environment, making it ready 146 *First, calls VMS_Setup, then creates own environment, making it ready
147 * for creating the seed processor and then starting the work. 147 * for creating the seed processor and then starting the work.
148 */ 148 */
149 void 149 void
150 VOMP__init() 150 VSs__init()
151 { 151 {
152 VMS_SS__init(); 152 VMS_SS__init();
153 //masterEnv, a global var, now is partially set up by init_VMS 153 //masterEnv, a global var, now is partially set up by init_VMS
154 // after this, have VMS_int__malloc and VMS_int__free available 154 // after this, have VMS_int__malloc and VMS_int__free available
155 155
156 VOMP__init_Helper(); 156 VSs__init_Helper();
157 } 157 }
158 158
159 159
160 void idle_fn(void* data, SlaveVP *animatingSlv){ 160 void idle_fn(void* data, SlaveVP *animatingSlv){
161 while(1){ 161 while(1){
162 VMS_int__suspend_slaveVP_and_send_req(animatingSlv); 162 VMS_int__suspend_slaveVP_and_send_req(animatingSlv);
163 } 163 }
164 } 164 }
165 165
166 void 166 void
167 VOMP__init_Helper() 167 VSs__init_Helper()
168 { VOMPSemEnv *semanticEnv; 168 { VSsSemEnv *semanticEnv;
169 PrivQueueStruc **readyVPQs; 169 PrivQueueStruc **readyVPQs;
170 int coreIdx, i, j; 170 int coreIdx, i, j;
171 171
172 //Hook up the semantic layer's plug-ins to the Master virt procr 172 //Hook up the semantic layer's plug-ins to the Master virt procr
173 _VMSMasterEnv->requestHandler = &VOMP__Request_Handler; 173 _VMSMasterEnv->requestHandler = &VSs__Request_Handler;
174 _VMSMasterEnv->slaveAssigner = &VOMP__assign_slaveVP_to_slot; 174 _VMSMasterEnv->slaveAssigner = &VSs__assign_slaveVP_to_slot;
175 #ifdef HOLISTIC__TURN_ON_PERF_COUNTERS 175 #ifdef HOLISTIC__TURN_ON_PERF_COUNTERS
176 _VMSMasterEnv->counterHandler = &VOMP__counter_handler; 176 _VMSMasterEnv->counterHandler = &VSs__counter_handler;
177 #endif 177 #endif
178 178
179 //create the semantic layer's environment (all its data) and add to 179 //create the semantic layer's environment (all its data) and add to
180 // the master environment 180 // the master environment
181 semanticEnv = VMS_int__malloc( sizeof( VOMPSemEnv ) ); 181 semanticEnv = VMS_int__malloc( sizeof( VSsSemEnv ) );
182 _VMSMasterEnv->semanticEnv = semanticEnv; 182 _VMSMasterEnv->semanticEnv = semanticEnv;
183 183
184 #ifdef HOLISTIC__TURN_ON_PERF_COUNTERS 184 #ifdef HOLISTIC__TURN_ON_PERF_COUNTERS
185 VOMP__init_counter_data_structs(); 185 VSs__init_counter_data_structs();
186 #endif 186 #endif
187 semanticEnv->shutdownInitiated = FALSE; 187 semanticEnv->shutdownInitiated = FALSE;
188 for(i=0;i<NUM_CORES;++i){ 188 for(i=0;i<NUM_CORES;++i){
189 for(j=0;j<NUM_ANIM_SLOTS;++j){ 189 for(j=0;j<NUM_ANIM_SLOTS;++j){
190 semanticEnv->idlePr[i][j] = VMS_int__create_slaveVP(&idle_fn,NULL); 190 semanticEnv->idlePr[i][j] = VMS_int__create_slaveVP(&idle_fn,NULL);
217 semanticEnv->readyVPQs = readyVPQs; 217 semanticEnv->readyVPQs = readyVPQs;
218 218
219 semanticEnv->nextCoreToGetNewPr = 0; 219 semanticEnv->nextCoreToGetNewPr = 0;
220 semanticEnv->numSlaveVP = 0; 220 semanticEnv->numSlaveVP = 0;
221 221
222 semanticEnv->commHashTbl = makeHashTable( 1<<16, &VMS_int__free );//start big 222 semanticEnv->argPtrHashTbl = makeHashTable( 1<<16, &VMS_int__free );//start big
223 223
224 //TODO: bug -- turn these arrays into dyn arrays to eliminate limit 224 //TODO: bug -- turn these arrays into dyn arrays to eliminate limit
225 //semanticEnv->singletonHasBeenExecutedFlags = makeDynArrayInfo( ); 225 //semanticEnv->singletonHasBeenExecutedFlags = makeDynArrayInfo( );
226 //semanticEnv->transactionStrucs = makeDynArrayInfo( ); 226 //semanticEnv->transactionStrucs = makeDynArrayInfo( );
227 for( i = 0; i < NUM_STRUCS_IN_SEM_ENV; i++ ) 227 for( i = 0; i < NUM_STRUCS_IN_SEM_ENV; i++ )
233 semanticEnv->transactionStrucs[i].waitingVPQ = makeVMSQ(); 233 semanticEnv->transactionStrucs[i].waitingVPQ = makeVMSQ();
234 } 234 }
235 } 235 }
236 236
237 237
238 /*Frees any memory allocated by VOMP__init() then calls VMS_int__shutdown 238 /*Frees any memory allocated by VSs__init() then calls VMS_int__shutdown
239 */ 239 */
240 void 240 void
241 VOMP__cleanup_after_shutdown() 241 VSs__cleanup_after_shutdown()
242 { VOMPSemEnv *semanticEnv; 242 { VSsSemEnv *semanticEnv;
243 243
244 semanticEnv = _VMSMasterEnv->semanticEnv; 244 semanticEnv = _VMSMasterEnv->semanticEnv;
245 245
246 #ifdef HOLISTIC__TURN_ON_OBSERVE_UCC 246 #ifdef HOLISTIC__TURN_ON_OBSERVE_UCC
247 //UCC 247 //UCC
372 372
373 //=========================================================================== 373 //===========================================================================
374 374
375 /* 375 /*
376 */ 376 */
377 SlaveVP * 377 SlaveVP *
378 VOMP__create_procr_with( TopLevelFnPtr fnPtr, void *initData, 378 VSs__create_slave_with( TopLevelFnPtr fnPtr, void *initData,
379 SlaveVP *creatingPr ) 379 SlaveVP *creatingPr )
380 { VOMPSemReq reqData; 380 { VSsSemReq reqData;
381 381
382 //the semantic request data is on the stack and disappears when this 382 //the semantic request data is on the stack and disappears when this
383 // call returns -- it's guaranteed to remain in the VP's stack for as 383 // call returns -- it's guaranteed to remain in the VP's stack for as
384 // long as the VP is suspended. 384 // long as the VP is suspended.
385 reqData.reqType = 0; //know type because in a VMS create req 385 reqData.reqType = 0; //know type because in a VMS create req
386 reqData.coreToAssignOnto = -1; //means round-robin assign 386 reqData.coreToAssignOnto = -1; //means round-robin assign
387 reqData.fnPtr = fnPtr; 387 reqData.fnPtr = fnPtr;
388 reqData.initData = initData; 388 reqData.initData = initData;
389 reqData.sendPr = creatingPr; 389 reqData.callingSlv = creatingPr;
390 390
391 VMS_WL__send_create_slaveVP_req( &reqData, creatingPr ); 391 VMS_WL__send_create_slaveVP_req( &reqData, creatingPr );
392 392
393 return creatingPr->dataRetFromReq; 393 return creatingPr->dataRetFromReq;
394 } 394 }
395 395
396 SlaveVP * 396 SlaveVP *
397 VOMP__create_procr_with_affinity( TopLevelFnPtr fnPtr, void *initData, 397 VSs__create_slave_with_affinity( TopLevelFnPtr fnPtr, void *initData,
398 SlaveVP *creatingPr, int32 coreToAssignOnto ) 398 SlaveVP *creatingPr, int32 coreToAssignOnto )
399 { VOMPSemReq reqData; 399 { VSsSemReq reqData;
400 400
401 //the semantic request data is on the stack and disappears when this 401 //the semantic request data is on the stack and disappears when this
402 // call returns -- it's guaranteed to remain in the VP's stack for as 402 // call returns -- it's guaranteed to remain in the VP's stack for as
403 // long as the VP is suspended. 403 // long as the VP is suspended.
404 reqData.reqType = 0; //know type because in a VMS create req 404 reqData.reqType = create_slave;
405 reqData.coreToAssignOnto = coreToAssignOnto; 405 reqData.coreToAssignOnto = coreToAssignOnto;
406 reqData.fnPtr = fnPtr; 406 reqData.fnPtr = fnPtr;
407 reqData.initData = initData; 407 reqData.initData = initData;
408 reqData.sendPr = creatingPr; 408 reqData.callingSlv = creatingPr;
409 409
410 VMS_WL__send_create_slaveVP_req( &reqData, creatingPr ); 410 VMS_WL__send_create_slaveVP_req( &reqData, creatingPr );
411 411
412 return creatingPr->dataRetFromReq; 412 return creatingPr->dataRetFromReq;
413 } 413 }
414 414
415 415
416 void 416 void
417 VOMP__dissipate_procr( SlaveVP *procrToDissipate ) 417 VSs__dissipate_slave( SlaveVP *slaveToDissipate )
418 { 418 {
419 VMS_WL__send_dissipate_req( procrToDissipate ); 419 VMS_WL__send_dissipate_req( slaveToDissipate );
420 } 420 }
421 421
422 422
423 //=========================================================================== 423 //===========================================================================
424 424
425 void *
426 VOMP__malloc_to( int32 sizeToMalloc, SlaveVP *owningPr )
427 { VOMPSemReq reqData;
428
429 reqData.reqType = malloc_req;
430 reqData.sendPr = owningPr;
431 reqData.sizeToMalloc = sizeToMalloc;
432
433 VMS_WL__send_sem_request( &reqData, owningPr );
434
435 return owningPr->dataRetFromReq;
436 }
437
438
439 /*Sends request to Master, which does the work of freeing
440 */
441 void
442 VOMP__free( void *ptrToFree, SlaveVP *owningPr )
443 { VOMPSemReq reqData;
444
445 reqData.reqType = free_req;
446 reqData.sendPr = owningPr;
447 reqData.ptrToFree = ptrToFree;
448
449 VMS_WL__send_sem_request( &reqData, owningPr );
450 }
451
452
453 void
454 VOMP__transfer_ownership_of_from_to( void *data, SlaveVP *oldOwnerSlv,
455 SlaveVP *newOwnerPr )
456 {
457 //TODO: put in the ownership system that automatically frees when no
458 // owners of data left -- will need keeper for keeping data around when
459 // future created processors might need it but don't exist yet
460 }
461
462
463 void
464 VOMP__add_ownership_by_to( SlaveVP *newOwnerSlv, void *data )
465 {
466
467 }
468
469
470 void
471 VOMP__remove_ownership_by_from( SlaveVP *loserSlv, void *dataLosing )
472 {
473
474 }
475
476
477 /*Causes the VOMP system to remove internal ownership, so data won't be
478 * freed when VOMP shuts down, and will persist in the external program.
479 *
480 *Must be called from the processor that currently owns the data.
481 *
482 *IMPL: Transferring ownership touches two different virtual processor's
483 * state -- which means it has to be done carefully -- the VMS rules for
484 * semantic layers say that a work-unit is only allowed to touch the
485 * virtual processor it is part of, and that only a single work-unit per
486 * virtual processor be assigned to a slave at a time. So, this has to
487 * modify the virtual processor that owns the work-unit that called this
488 * function, then create a request to have the other processor modified.
489 *However, in this case, the TO processor is the outside, and transfers
490 * are only allowed to be called by the giver-upper, so can mark caller of
491 * this function as no longer owner, and return -- done.
492 */
493 void
494 VOMP__transfer_ownership_to_outside( void *data )
495 {
496 //TODO: removeAllOwnersFrom( data );
497 }
498
499 425
500 //=========================================================================== 426 //===========================================================================
501 427 /*Returns a taskID, which can be used to communicate between tasks with
502 void 428 * send-receive, or to use other kinds of constructs with tasks.
503 VOMP__send_of_type_to( SlaveVP *sendPr, void *msg, const int type, 429 */
504 SlaveVP *receivePr) 430 int32
505 { VOMPSemReq reqData; 431 VSs__submit_task( VSsTaskType *taskType, void *args, SlaveVP *animSlv)
506 432 { VSsSemReq reqData;
507 reqData.receivePr = receivePr; 433
508 reqData.sendPr = sendPr; 434 reqData.reqType = submit_task;
509 reqData.reqType = send_type; 435 reqData.callingSlv = animSlv;
510 reqData.msgType = type; 436 reqData.taskType = taskType;
511 reqData.msg = msg; 437 reqData.args = args;
512 reqData.nextReqInHashEntry = NULL; 438
513 439
514 //On ownership -- remove inside the send and let ownership sit in limbo 440 VMS_WL__send_sem_request( &reqData, animSlv );
515 // as a potential in an entry in the hash table, when this receive msg 441 return animSlv->dataRetFromReq;
516 // gets paired to a send, the ownership gets added to the receivePr -- 442 }
517 // the next work-unit in the receivePr's trace will have ownership. 443
518 VMS_WL__send_sem_request( &reqData, sendPr ); 444 /*NOTE: if want, don't need to send the animating SlaveVP around..
519 445 * instead, can make a single slave per core, and coreCtrlr looks up the
520 //When come back from suspend, no longer own data reachable from msg 446 * slave from having the core number.
521 //TODO: release ownership here
522 }
523
524 void
525 VOMP__send_from_to( void *msg, SlaveVP *sendPr, SlaveVP *receivePr )
526 { VOMPSemReq reqData;
527
528 //hash on the receiver, 'cause always know it, but sometimes want to
529 // receive from anonymous sender
530
531 reqData.receivePr = receivePr;
532 reqData.sendPr = sendPr;
533 reqData.reqType = send_from_to;
534 reqData.msg = msg;
535 reqData.nextReqInHashEntry = NULL;
536
537 VMS_WL__send_sem_request( &reqData, sendPr );
538 }
539
540
541 //===========================================================================
542
543 void *
544 VOMP__receive_any_to( SlaveVP *receivePr )
545 {
546
547 }
548
549 void *
550 VOMP__receive_type_to( const int type, SlaveVP *receivePr )
551 { DEBUG__printf1(dbgRqstHdlr,"WL: receive type to: %d", receivePr->slaveID);
552 VOMPSemReq reqData;
553
554 reqData.receivePr = receivePr;
555 reqData.reqType = receive_type;
556 reqData.msgType = type;
557 reqData.nextReqInHashEntry = NULL;
558
559 VMS_WL__send_sem_request( &reqData, receivePr );
560
561 return receivePr->dataRetFromReq;
562 }
563
564
565
566 /*Call this at point receiving virt pr wants in-coming data.
567 * 447 *
568 *The reason receivePr must call this is that it modifies the receivPr 448 *But, to stay compatible with all the other VMS languages, leave it in..
569 * loc structure directly -- and the VMS rules state a virtual processor 449 *
570 * loc structure can only be modified by itself. 450 *This call is the last to happen in every task. It causes the slave to
571 */ 451 * suspend and get the next task out of the task-queue. Notice there is no
572 void * 452 * assigner here.. only one slave, no slave ReadyQ, and so on..
573 VOMP__receive_from_to( SlaveVP *sendPr, SlaveVP *receivePr ) 453 *Can either make the assigner take the next task out of the taskQ, or can
574 { DEBUG__printf2(dbgRqstHdlr,"WL: receive from %d to: %d", sendPr->slaveID, receivePr->slaveID); 454 * leave all as it is, and make task-end take the next task.
575 VOMPSemReq reqData; 455 *Note: this fits the case in the new VMS for no-context tasks, so will use
576 456 * the built-in taskQ of new VMS, and should be local and much faster.
577 //hash on the receiver, 'cause always know it, but sometimes want to 457 *
578 // receive from anonymous sender 458 *The task-stub is saved in the animSlv, so the request handler will get it
579 459 * from there, along with the task-type which has arg types, and so on..
580 reqData.receivePr = receivePr; 460 */
581 reqData.sendPr = sendPr; 461 void
582 reqData.reqType = receive_from_to; 462 VSs__end_task( SlaveVP *animSlv )
583 reqData.nextReqInHashEntry = NULL; 463 { VSsSemReq reqData;
584 464
585 VMS_WL__send_sem_request( &reqData, receivePr ); 465 reqData.reqType = end_task;
586 466 reqData.callingSlv = animSlv;
587 return receivePr->dataRetFromReq; 467
588 } 468 VMS_WL__send_sem_request( &reqData, animSlv );
589 469 }
590 470
591 //=========================================================================== 471 //==========================================================================
592 // 472 //
593 /*A function singleton is a function whose body executes exactly once, on a 473 /*A function singleton is a function whose body executes exactly once, on a
594 * single core, no matter how many times the fuction is called and no 474 * single core, no matter how many times the fuction is called and no
595 * matter how many cores or the timing of cores calling it. 475 * matter how many cores or the timing of cores calling it.
596 * 476 *
599 * times the data is given to the function, and no matter the timing of 479 * times the data is given to the function, and no matter the timing of
600 * trying to get the data through from different cores. 480 * trying to get the data through from different cores.
601 */ 481 */
602 482
603 /*asm function declarations*/ 483 /*asm function declarations*/
604 void asm_save_ret_to_singleton(VOMPSingleton *singletonPtrAddr); 484 void asm_save_ret_to_singleton(VSsSingleton *singletonPtrAddr);
605 void asm_write_ret_from_singleton(VOMPSingleton *singletonPtrAddr); 485 void asm_write_ret_from_singleton(VSsSingleton *singletonPtrAddr);
606 486
607 /*Fn singleton uses ID as index into array of singleton structs held in the 487 /*Fn singleton uses ID as index into array of singleton structs held in the
608 * semantic environment. 488 * semantic environment.
609 */ 489 */
610 void 490 void
611 VOMP__start_fn_singleton( int32 singletonID, SlaveVP *animPr ) 491 VSs__start_fn_singleton( int32 singletonID, SlaveVP *animPr )
612 { 492 {
613 VOMPSemReq reqData; 493 VSsSemReq reqData;
614 494
615 // 495 //
616 reqData.reqType = singleton_fn_start; 496 reqData.reqType = singleton_fn_start;
617 reqData.singletonID = singletonID; 497 reqData.singletonID = singletonID;
618 498
619 VMS_WL__send_sem_request( &reqData, animPr ); 499 VMS_WL__send_sem_request( &reqData, animPr );
620 if( animPr->dataRetFromReq ) //will be 0 or addr of label in end singleton 500 if( animPr->dataRetFromReq ) //will be 0 or addr of label in end singleton
621 { 501 {
622 VOMPSemEnv *semEnv = VMS_int__give_sem_env_for( animPr ); 502 VSsSemEnv *semEnv = VMS_int__give_sem_env_for( animPr );
623 asm_write_ret_from_singleton(&(semEnv->fnSingletons[ singletonID])); 503 asm_write_ret_from_singleton(&(semEnv->fnSingletons[ singletonID]));
624 } 504 }
625 } 505 }
626 506
627 /*Data singleton hands addr of loc holding a pointer to a singleton struct. 507 /*Data singleton hands addr of loc holding a pointer to a singleton struct.
628 * The start_data_singleton makes the structure and puts its addr into the 508 * The start_data_singleton makes the structure and puts its addr into the
629 * location. 509 * location.
630 */ 510 */
631 void 511 void
632 VOMP__start_data_singleton( VOMPSingleton **singletonAddr, SlaveVP *animPr ) 512 VSs__start_data_singleton( VSsSingleton **singletonAddr, SlaveVP *animPr )
633 { 513 {
634 VOMPSemReq reqData; 514 VSsSemReq reqData;
635 515
636 if( *singletonAddr && (*singletonAddr)->hasFinished ) 516 if( *singletonAddr && (*singletonAddr)->hasFinished )
637 goto JmpToEndSingleton; 517 goto JmpToEndSingleton;
638 518
639 reqData.reqType = singleton_data_start; 519 reqData.reqType = singleton_data_start;
656 * 536 *
657 *Note, this call cannot be inlined because the instr addr at the label 537 *Note, this call cannot be inlined because the instr addr at the label
658 * inside is shared by all invocations of a given singleton ID. 538 * inside is shared by all invocations of a given singleton ID.
659 */ 539 */
660 void 540 void
661 VOMP__end_fn_singleton( int32 singletonID, SlaveVP *animPr ) 541 VSs__end_fn_singleton( int32 singletonID, SlaveVP *animPr )
662 { 542 {
663 VOMPSemReq reqData; 543 VSsSemReq reqData;
664 544
665 //don't need this addr until after at least one singleton has reached 545 //don't need this addr until after at least one singleton has reached
666 // this function 546 // this function
667 VOMPSemEnv *semEnv = VMS_int__give_sem_env_for( animPr ); 547 VSsSemEnv *semEnv = VMS_int__give_sem_env_for( animPr );
668 asm_write_ret_from_singleton(&(semEnv->fnSingletons[ singletonID])); 548 asm_write_ret_from_singleton(&(semEnv->fnSingletons[ singletonID]));
669 549
670 reqData.reqType = singleton_fn_end; 550 reqData.reqType = singleton_fn_end;
671 reqData.singletonID = singletonID; 551 reqData.singletonID = singletonID;
672 552
675 EndSingletonInstrAddr: 555 EndSingletonInstrAddr:
676 return; 556 return;
677 } 557 }
678 558
679 void 559 void
680 VOMP__end_data_singleton( VOMPSingleton **singletonPtrAddr, SlaveVP *animPr ) 560 VSs__end_data_singleton( VSsSingleton **singletonPtrAddr, SlaveVP *animPr )
681 { 561 {
682 VOMPSemReq reqData; 562 VSsSemReq reqData;
683 563
684 //don't need this addr until after singleton struct has reached 564 //don't need this addr until after singleton struct has reached
685 // this function for first time 565 // this function for first time
686 //do assembly that saves the return addr of this fn call into the 566 //do assembly that saves the return addr of this fn call into the
687 // data singleton -- that data-singleton can only be given to exactly 567 // data singleton -- that data-singleton can only be given to exactly
707 *Only very short functions should be called this way -- for longer-running 587 *Only very short functions should be called this way -- for longer-running
708 * isolation, use transaction-start and transaction-end, which run the code 588 * isolation, use transaction-start and transaction-end, which run the code
709 * between as work-code. 589 * between as work-code.
710 */ 590 */
711 void 591 void
712 VOMP__animate_short_fn_in_isolation( PtrToAtomicFn ptrToFnToExecInMaster, 592 VSs__animate_short_fn_in_isolation( PtrToAtomicFn ptrToFnToExecInMaster,
713 void *data, SlaveVP *animPr ) 593 void *data, SlaveVP *animPr )
714 { 594 {
715 VOMPSemReq reqData; 595 VSsSemReq reqData;
716 596
717 // 597 //
718 reqData.reqType = atomic; 598 reqData.reqType = atomic;
719 reqData.fnToExecInMaster = ptrToFnToExecInMaster; 599 reqData.fnToExecInMaster = ptrToFnToExecInMaster;
720 reqData.dataForFn = data; 600 reqData.dataForFn = data;
735 * into queue in the struct. (At some point a holder will request 615 * into queue in the struct. (At some point a holder will request
736 * end-transaction, which will take this VP from the queue and resume it.) 616 * end-transaction, which will take this VP from the queue and resume it.)
737 *If NULL, then write requesting into the field and resume. 617 *If NULL, then write requesting into the field and resume.
738 */ 618 */
739 void 619 void
740 VOMP__start_transaction( int32 transactionID, SlaveVP *animPr ) 620 VSs__start_transaction( int32 transactionID, SlaveVP *animPr )
741 { 621 {
742 VOMPSemReq reqData; 622 VSsSemReq reqData;
743 623
744 // 624 //
745 reqData.sendPr = animPr; 625 reqData.callingSlv = animPr;
746 reqData.reqType = trans_start; 626 reqData.reqType = trans_start;
747 reqData.transID = transactionID; 627 reqData.transID = transactionID;
748 628
749 VMS_WL__send_sem_request( &reqData, animPr ); 629 VMS_WL__send_sem_request( &reqData, animPr );
750 } 630 }
757 *If it's empty, it sets VP_currently_executing field to NULL and resumes. 637 *If it's empty, it sets VP_currently_executing field to NULL and resumes.
758 *If something in, gets it, sets VP_currently_executing to that VP, then 638 *If something in, gets it, sets VP_currently_executing to that VP, then
759 * resumes both. 639 * resumes both.
760 */ 640 */
761 void 641 void
762 VOMP__end_transaction( int32 transactionID, SlaveVP *animPr ) 642 VSs__end_transaction( int32 transactionID, SlaveVP *animPr )
763 { 643 {
764 VOMPSemReq reqData; 644 VSsSemReq reqData;
765 645
766 // 646 //
767 reqData.sendPr = animPr; 647 reqData.callingSlv = animPr;
768 reqData.reqType = trans_end; 648 reqData.reqType = trans_end;
769 reqData.transID = transactionID; 649 reqData.transID = transactionID;
770 650
771 VMS_WL__send_sem_request( &reqData, animPr ); 651 VMS_WL__send_sem_request( &reqData, animPr );
772 } 652 }