Mercurial > cgi-bin > hgwebdir.cgi > VMS > VMS_Implementations > VSs_impls > VSs__MC_shared_impl
comparison VSs.c @ 4:13af59ed7ea5
Works -- with send-receive plus normal dependencies
| author | Sean Halle <seanhalle@yahoo.com> |
|---|---|
| date | Thu, 14 Jun 2012 18:44:47 -0700 |
| parents | 468b8638ff92 |
| children | 8188c5b4bfd7 |
comparison
equal
deleted
inserted
replaced
| 2:f98d42cee3ff | 3:b7ea637e1c74 |
|---|---|
| 224 | 224 |
| 225 semanticEnv->nextCoreToGetNewSlv = 0; | 225 semanticEnv->nextCoreToGetNewSlv = 0; |
| 226 semanticEnv->numSlaveVP = 0; | 226 semanticEnv->numSlaveVP = 0; |
| 227 | 227 |
| 228 semanticEnv->argPtrHashTbl = makeHashTable32( 16, &VMS_int__free ); | 228 semanticEnv->argPtrHashTbl = makeHashTable32( 16, &VMS_int__free ); |
| 229 semanticEnv->commHashTbl = makeHashTable32( 16, &VMS_int__free ); | |
| 229 | 230 |
| 230 //TODO: bug -- turn these arrays into dyn arrays to eliminate limit | 231 //TODO: bug -- turn these arrays into dyn arrays to eliminate limit |
| 231 //semanticEnv->singletonHasBeenExecutedFlags = makeDynArrayInfo( ); | 232 //semanticEnv->singletonHasBeenExecutedFlags = makeDynArrayInfo( ); |
| 232 //semanticEnv->transactionStrucs = makeDynArrayInfo( ); | 233 //semanticEnv->transactionStrucs = makeDynArrayInfo( ); |
| 233 for( i = 0; i < NUM_STRUCS_IN_SEM_ENV; i++ ) | 234 for( i = 0; i < NUM_STRUCS_IN_SEM_ENV; i++ ) |
| 427 | 428 |
| 428 | 429 |
| 429 //=========================================================================== | 430 //=========================================================================== |
| 430 | 431 |
| 431 | 432 |
| 432 //=========================================================================== | 433 //======================= task submit and end ============================== |
| 433 /*Returns a taskID, which can be used to communicate between tasks with | 434 /* |
| 434 * send-receive, or to use other kinds of constructs with tasks. | 435 */ |
| 435 */ | 436 void |
| 436 int32 | |
| 437 VSs__submit_task( VSsTaskType *taskType, void *args, SlaveVP *animSlv) | 437 VSs__submit_task( VSsTaskType *taskType, void *args, SlaveVP *animSlv) |
| 438 { VSsSemReq reqData; | 438 { VSsSemReq reqData; |
| 439 | 439 |
| 440 reqData.reqType = submit_task; | 440 reqData.reqType = submit_task; |
| 441 reqData.callingSlv = animSlv; | 441 |
| 442 reqData.taskType = taskType; | 442 reqData.taskType = taskType; |
| 443 reqData.args = args; | 443 reqData.args = args; |
| 444 reqData.callingSlv = animSlv; | |
| 444 | 445 |
| 446 reqData.taskID = NULL; | |
| 445 | 447 |
| 446 VMS_WL__send_sem_request( &reqData, animSlv ); | 448 VMS_WL__send_sem_request( &reqData, animSlv ); |
| 447 return (int32)animSlv->dataRetFromReq; | 449 } |
| 448 } | 450 |
| 449 | 451 inline int32 * |
| 450 /*NOTE: if want, don't need to send the animating SlaveVP around.. | 452 VSs__create_taskID_of_size( int32 numInts, SlaveVP *animSlv ) |
| 451 * instead, can make a single slave per core, and coreCtrlr looks up the | 453 { int32 *taskID; |
| 452 * slave from having the core number. | 454 |
| 453 * | 455 taskID = VMS_WL__malloc( sizeof(int32) + numInts * sizeof(int32) ); |
| 454 *But, to stay compatible with all the other VMS languages, leave it in.. | 456 taskID[0] = numInts; |
| 455 * | 457 return taskID; |
| 456 *This call is the last to happen in every task. It causes the slave to | 458 } |
| 459 | |
| 460 void | |
| 461 VSs__submit_task_with_ID( VSsTaskType *taskType, void *args, int32 *taskID, | |
| 462 SlaveVP *animSlv) | |
| 463 { VSsSemReq reqData; | |
| 464 | |
| 465 reqData.reqType = submit_task; | |
| 466 | |
| 467 reqData.taskType = taskType; | |
| 468 reqData.args = args; | |
| 469 reqData.taskID = taskID; | |
| 470 reqData.callingSlv = animSlv; | |
| 471 | |
| 472 VMS_WL__send_sem_request( &reqData, animSlv ); | |
| 473 } | |
| 474 | |
| 475 | |
| 476 /*This call is the last to happen in every task. It causes the slave to | |
| 457 * suspend and get the next task out of the task-queue. Notice there is no | 477 * suspend and get the next task out of the task-queue. Notice there is no |
| 458 * assigner here.. only one slave, no slave ReadyQ, and so on.. | 478 * assigner here.. only one slave, no slave ReadyQ, and so on.. |
| 459 *Can either make the assigner take the next task out of the taskQ, or can | 479 *Can either make the assigner take the next task out of the taskQ, or can |
| 460 * leave all as it is, and make task-end take the next task. | 480 * leave all as it is, and make task-end take the next task. |
| 461 *Note: this fits the case in the new VMS for no-context tasks, so will use | 481 *Note: this fits the case in the new VMS for no-context tasks, so will use |
| 462 * the built-in taskQ of new VMS, and should be local and much faster. | 482 * the built-in taskQ of new VMS, and should be local and much faster. |
| 463 * | 483 * |
| 464 *The task-stub is saved in the animSlv, so the request handler will get it | 484 *The task-stub is saved in the animSlv, so the request handler will get it |
| 465 * from there, along with the task-type which has arg types, and so on.. | 485 * from there, along with the task-type which has arg types, and so on.. |
| 486 * | |
| 487 * NOTE: if want, don't need to send the animating SlaveVP around.. | |
| 488 * instead, can make a single slave per core, and coreCtrlr looks up the | |
| 489 * slave from having the core number. | |
| 490 * | |
| 491 *But, to stay compatible with all the other VMS languages, leave it in.. | |
| 466 */ | 492 */ |
| 467 void | 493 void |
| 468 VSs__end_task( SlaveVP *animSlv ) | 494 VSs__end_task( SlaveVP *animSlv ) |
| 469 { VSsSemReq reqData; | 495 { VSsSemReq reqData; |
| 470 | 496 |
| 471 reqData.reqType = end_task; | 497 reqData.reqType = end_task; |
| 472 reqData.callingSlv = animSlv; | 498 reqData.callingSlv = animSlv; |
| 473 | 499 |
| 474 VMS_WL__send_sem_request( &reqData, animSlv ); | 500 VMS_WL__send_sem_request( &reqData, animSlv ); |
| 475 } | 501 } |
| 502 | |
| 503 | |
| 504 //========================== send and receive ============================ | |
| 505 // | |
| 506 | |
| 507 inline int32 * | |
| 508 VSs__give_self_taskID( SlaveVP *animSlv ) | |
| 509 { | |
| 510 return ((VSsSemData*)animSlv->semanticData)->taskStub->taskID; | |
| 511 } | |
| 512 | |
| 513 //================================ send =================================== | |
| 514 | |
| 515 void | |
| 516 VSs__send_of_type_to( void *msg, const int32 type, int32 *receiverID, | |
| 517 SlaveVP *senderSlv ) | |
| 518 { VSsSemReq reqData; | |
| 519 | |
| 520 reqData.reqType = send_type_to; | |
| 521 | |
| 522 reqData.msg = msg; | |
| 523 reqData.msgType = type; | |
| 524 reqData.receiverID = receiverID; | |
| 525 reqData.senderSlv = senderSlv; | |
| 526 | |
| 527 reqData.nextReqInHashEntry = NULL; | |
| 528 | |
| 529 VMS_WL__send_sem_request( &reqData, senderSlv ); | |
| 530 | |
| 531 //When come back from suspend, no longer own data reachable from msg | |
| 532 } | |
| 533 | |
| 534 void | |
| 535 VSs__send_from_to( void *msg, int32 *senderID, int32 *receiverID, SlaveVP *senderSlv ) | |
| 536 { VSsSemReq reqData; | |
| 537 | |
| 538 reqData.reqType = send_from_to; | |
| 539 | |
| 540 reqData.msg = msg; | |
| 541 reqData.senderID = senderID; | |
| 542 reqData.receiverID = receiverID; | |
| 543 reqData.senderSlv = senderSlv; | |
| 544 | |
| 545 reqData.nextReqInHashEntry = NULL; | |
| 546 | |
| 547 VMS_WL__send_sem_request( &reqData, senderSlv ); | |
| 548 } | |
| 549 | |
| 550 | |
| 551 //================================ receive ================================ | |
| 552 | |
| 553 /*The "type" version of send and receive creates a many-to-one relationship. | |
| 554 * The sender is anonymous, and many sends can stack up, waiting to be | |
| 555 * received. The same receiver can also have send from-to's | |
| 556 * waiting for it, and those will be kept separate from the "type" | |
| 557 * messages. | |
| 558 */ | |
| 559 void * | |
| 560 VSs__receive_type_to( const int32 type, int32* receiverID, SlaveVP *receiverSlv ) | |
| 561 { DEBUG__printf1(dbgRqstHdlr,"WL: receive type to %d",receiverID[1] ); | |
| 562 VSsSemReq reqData; | |
| 563 | |
| 564 reqData.reqType = receive_type_to; | |
| 565 | |
| 566 reqData.msgType = type; | |
| 567 reqData.receiverID = receiverID; | |
| 568 reqData.receiverSlv = receiverSlv; | |
| 569 | |
| 570 reqData.nextReqInHashEntry = NULL; | |
| 571 | |
| 572 VMS_WL__send_sem_request( &reqData, receiverSlv ); | |
| 573 | |
| 574 return receiverSlv->dataRetFromReq; | |
| 575 } | |
| 576 | |
| 577 | |
| 578 | |
| 579 /*Call this at the point a receiving task wants in-coming data. | |
| 580 * Use this from-to form when know senderID -- it makes a direct channel | |
| 581 * between sender and receiver. | |
| 582 */ | |
| 583 void * | |
| 584 VSs__receive_from_to( int32 *senderID, int32 *receiverID, SlaveVP *receiverSlv ) | |
| 585 { | |
| 586 VSsSemReq reqData; | |
| 587 | |
| 588 reqData.reqType = receive_from_to; | |
| 589 | |
| 590 reqData.senderID = senderID; | |
| 591 reqData.receiverID = receiverID; | |
| 592 reqData.receiverSlv = receiverSlv; | |
| 593 | |
| 594 reqData.nextReqInHashEntry = NULL; | |
| 595 DEBUG__printf2(dbgRqstHdlr,"WL: receive from %d to: %d", reqData.senderID[1], reqData.receiverID[1]); | |
| 596 | |
| 597 VMS_WL__send_sem_request( &reqData, receiverSlv ); | |
| 598 | |
| 599 return receiverSlv->dataRetFromReq; | |
| 600 } | |
| 601 | |
| 602 | |
| 603 | |
| 476 | 604 |
| 477 //========================================================================== | 605 //========================================================================== |
| 478 // | 606 // |
| 479 /*A function singleton is a function whose body executes exactly once, on a | 607 /*A function singleton is a function whose body executes exactly once, on a |
| 480 * single core, no matter how many times the fuction is called and no | 608 * single core, no matter how many times the fuction is called and no |
