Mercurial > cgi-bin > hgwebdir.cgi > VMS > VMS_Implementations > VMS_impls > VMS__MC_shared_impl
comparison VMS.c @ 29:0e008278fe3c
Works Sequentially -- took out all threads and debugged -- works
| author | Me |
|---|---|
| date | Wed, 28 Jul 2010 13:12:10 -0700 |
| parents | 8b9e4c333fe6 |
| children | c8823e0bb2b4 |
comparison
equal
deleted
inserted
replaced
| 10:5b6503e02149 | 11:d21d939b862a |
|---|---|
| 387 void | 387 void |
| 388 VMS__remove_and_free_top_request( VirtProcr *procrWithReq ) | 388 VMS__remove_and_free_top_request( VirtProcr *procrWithReq ) |
| 389 { VMSReqst *req; | 389 { VMSReqst *req; |
| 390 | 390 |
| 391 req = procrWithReq->requests; | 391 req = procrWithReq->requests; |
| 392 if( req == NULL ) return; | |
| 392 procrWithReq->requests = procrWithReq->requests->nextReqst; | 393 procrWithReq->requests = procrWithReq->requests->nextReqst; |
| 393 free( req ); | 394 VMS__free_request( req ); |
| 394 } | 395 } |
| 395 | 396 |
| 396 | 397 |
| 397 //TODO: add a semantic-layer supplied "freer" for the semantic-data portion | 398 //TODO: add a semantic-layer supplied "freer" for the semantic-data portion |
| 398 // of a request -- IE call with both a virt procr and a fn-ptr to request | 399 // of a request -- IE call with both a virt procr and a fn-ptr to request |
| 452 reqstingPr->requests = req; | 453 reqstingPr->requests = req; |
| 453 | 454 |
| 454 VMS__suspend_procr( reqstingPr ); | 455 VMS__suspend_procr( reqstingPr ); |
| 455 } | 456 } |
| 456 | 457 |
| 457 | |
| 458 /*The semantic layer figures out when the work is done ( perhaps by a call | |
| 459 * in the application to "work all done", or perhaps all the virtual | |
| 460 * processors have dissipated.. a.s.o. ) | |
| 461 * | |
| 462 *The semantic layer is responsible for making sure all work has fully | |
| 463 * completed before using this to shutdown the VMS system. | |
| 464 * | |
| 465 *After the semantic layer has determined it wants to shut down, the | |
| 466 * next time the Master Loop calls the scheduler plug-in, the scheduler | |
| 467 * then calls this function and returns the virtual processor it gets back. | |
| 468 * | |
| 469 *When the shut-down processor runs, it first frees all locations malloc'd to | |
| 470 * the VMS system (that wasn't | |
| 471 * specified as return-locations). Then it creates one core-loop shut-down | |
| 472 * processor for each core loop and puts them all into the workQ. When a | |
| 473 * core loop animates a core loop shut-down processor, it causes exit-thread | |
| 474 * to run, and when all core loop threads have exited, then the "wait for | |
| 475 * work to finish" in the main thread is woken, and the function-call that | |
| 476 * started all the work returns. | |
| 477 * | |
| 478 *The function animated by this processor performs the shut-down work. | |
| 479 */ | |
| 480 VirtProcr * | |
| 481 VMS__create_the_shutdown_procr() | |
| 482 { | |
| 483 return VMS__create_procr( &shutdownFn, NULL ); | |
| 484 } | |
| 485 | 458 |
| 486 | 459 |
| 487 /*This must be called by the request handler plugin -- it cannot be called | 460 /*This must be called by the request handler plugin -- it cannot be called |
| 488 * from the semantic library "dissipate processor" function -- instead, the | 461 * from the semantic library "dissipate processor" function -- instead, the |
| 489 * semantic layer has to generate a request for the plug-in to call this | 462 * semantic layer has to generate a request for the plug-in to call this |
| 500 *If the dissipated processor is the sole (remaining) owner of VMS__malloc'd | 473 *If the dissipated processor is the sole (remaining) owner of VMS__malloc'd |
| 501 * state, then that state gets freed (or sent to recycling) as a side-effect | 474 * state, then that state gets freed (or sent to recycling) as a side-effect |
| 502 * of dis-owning it. | 475 * of dis-owning it. |
| 503 */ | 476 */ |
| 504 void | 477 void |
| 505 VMS__free_procr_locs( VirtProcr *animatingPr ) | 478 VMS__handle_dissipate_reqst( VirtProcr *animatingPr ) |
| 506 { | 479 { |
| 507 //dis-own all locations owned by this processor, causing to be freed | 480 //dis-own all locations owned by this processor, causing to be freed |
| 508 // any locations that it is (was) sole owner of | 481 // any locations that it is (was) sole owner of |
| 509 //TODO: implement VMS__malloc system, including "give up ownership" | 482 //TODO: implement VMS__malloc system, including "give up ownership" |
| 510 | 483 |
| 511 //The dissipate request might still be attached, so remove and free it | 484 //The dissipate request might still be attached, so remove and free it |
| 512 VMS__remove_and_free_top_request( animatingPr ); | 485 VMS__remove_and_free_top_request( animatingPr ); |
| 513 free( animatingPr->startOfStack ); | |
| 514 | 486 |
| 515 //NOTE: initialData was given to the processor, so should either have | 487 //NOTE: initialData was given to the processor, so should either have |
| 516 // been alloc'd with VMS__malloc, or freed by the level above animPr. | 488 // been alloc'd with VMS__malloc, or freed by the level above animPr. |
| 517 //So, all that's left to free here is the stack and the VirtProcr struc | 489 //So, all that's left to free here is the stack and the VirtProcr struc |
| 518 // itself | 490 // itself |
| 519 free( animatingPr->startOfStack ); | 491 free( animatingPr->startOfStack ); |
| 520 free( animatingPr ); | 492 free( animatingPr ); |
| 521 } | 493 } |
| 522 | 494 |
| 523 | 495 |
| 524 | 496 //TODO: re-architect so that have clean separation between request handler |
| 525 /*This is the function run by the special "shut-down" processor | 497 // and master loop, for dissipate, create, shutdown, and other non-semantic |
| 498 // requests. Issue is chain: one removes requests from AppVP, one dispatches | |
| 499 // on type of request, and one handles each type.. but some types require | |
| 500 // action from both request handler and master loop -- maybe just give the | |
| 501 // request handler calls like: VMS__handle_X_request_type | |
| 502 | |
| 503 void | |
| 504 endOSThreadFn( void *initData, VirtProcr *animatingPr ); | |
| 505 | |
| 506 /*This is called by the semantic layer's request handler when it decides its | |
| 507 * time to shut down the VMS system. Calling this causes the core loop OS | |
| 508 * threads to exit, which unblocks the entry-point function that started up | |
| 509 * VMS, and allows it to grab the result and return to the original single- | |
| 510 * threaded application. | |
| 526 * | 511 * |
| 527 *The _VMSMasterEnv is needed by this shut down function, so the "wait" | 512 *The _VMSMasterEnv is needed by this shut down function, so the create-seed- |
| 528 * function run in the main loop has to free it, and the thread-related | 513 * and-wait function has to free a bunch of stuff after it detects the |
| 529 * locations (coreLoopThdParams a.s.o.). | 514 * threads have all died: the masterEnv, the thread-related locations, |
| 530 *However, the semantic environment and all data malloc'd to VMS can be | 515 * masterVP any AppVPs that might still be allocated and sitting in the |
| 531 * freed here. | 516 * semantic environment, or have been orphaned in the _VMSWorkQ. |
| 532 * | 517 * |
| 533 *NOTE: the semantic plug-in is expected to use VMS__malloc to get all the | 518 *NOTE: the semantic plug-in is expected to use VMS__malloc_to to get all the |
| 534 * locations it needs -- they will be automatically freed by the standard | 519 * locations it needs, and give ownership to masterVP. Then, they will be |
| 535 * "free all owned locations" | 520 * automatically freed when the masterVP is dissipated. (This happens after |
| 536 * | 521 * the core loop threads have all exited) |
| 537 *Free any locations malloc'd to the VMS system (that weren't | 522 * |
| 538 * specified as return-locations). | 523 *In here,create one core-loop shut-down processor for each core loop and put |
| 539 *Then create one core-loop shut-down processor for each core loop and puts | 524 * them all directly into the workQ. |
| 540 * them all into the workQ. | 525 *Note, this function can ONLY be called after the semantic environment no |
| 541 */ | 526 * longer cares if AppVPs get animated after the point this is called. In |
| 542 void | 527 * other words, this can be used as an abort, or else it should only be |
| 543 shutdownFn( void *dummy, VirtProcr *animatingPr ) | 528 * called when all AppVPs have finished dissipate requests -- only at that |
| 529 * point is it sure that all results have completed. | |
| 530 */ | |
| 531 void | |
| 532 VMS__handle_shutdown_reqst( void *dummy, VirtProcr *animatingPr ) | |
| 544 { int coreIdx; | 533 { int coreIdx; |
| 545 VirtProcr *shutDownPr; | 534 VirtProcr *shutDownPr; |
| 546 VMSQueueStruc *workQ = _VMSWorkQ; | 535 VMSQueueStruc *workQ = _VMSWorkQ; |
| 547 | 536 |
| 548 //free all the locations owned within the VMS system | 537 //create the shutdown processors, one for each core loop -- put them |
| 549 //TODO: write VMS__malloc and free.. -- take the DKU malloc as starting pt | 538 // directly into _VMSWorkQ -- each core will die when gets one, so |
| 550 | 539 // the system distributes them evenly itself. |
| 551 //make the core loop shut-down processors and put them into the workQ | |
| 552 for( coreIdx=0; coreIdx < NUM_CORES; coreIdx++ ) | 540 for( coreIdx=0; coreIdx < NUM_CORES; coreIdx++ ) |
| 553 { | 541 { |
| 554 shutDownPr = VMS__create_procr( NULL, NULL ); | 542 shutDownPr = VMS__create_procr( &endOSThreadFn, NULL ); |
| 555 shutDownPr->nextInstrPt = _VMSMasterEnv->coreLoopShutDownPt; | |
| 556 writeVMSQ( shutDownPr, workQ ); | 543 writeVMSQ( shutDownPr, workQ ); |
| 557 } | 544 } |
| 558 | 545 |
| 559 //This is an issue: the animating processor of this function may not | 546 } |
| 560 // get its request handled before all the cores have shutdown. | 547 |
| 561 //TODO: after all the threads stop, clean out the MasterEnv, the | 548 |
| 562 // SemanticEnv, and the workQ before returning. | 549 /*Am trying to be cute, avoiding IF statement in coreLoop that checks for |
| 563 VMS__dissipate_procr( animatingPr ); //will never come back from this | 550 * a special shutdown procr. Ended up with extra-complex shutdown sequence. |
| 564 } | 551 *This function has the sole purpose of setting the stack and framePtr |
| 565 | 552 * to the coreLoop's stack and framePtr.. it does that then jumps to the |
| 566 | 553 * core loop's shutdown point -- might be able to just call Pthread_exit |
| 567 /*This has to free anything allocated during VMS_init, and any other alloc'd | 554 * from here, but going back to the pthread's stack and setting everything |
| 555 * up just as if it never jumped out, before calling pthread_exit. | |
| 556 *The end-point of core loop will free the stack and so forth of the | |
| 557 * processor that animates this function, (this fn is transfering the | |
| 558 * animator of the AppVP that is in turn animating this function over | |
| 559 * to core loop function -- note that this slices out a level of virtual | |
| 560 * processors). | |
| 561 */ | |
| 562 void | |
| 563 endOSThreadFn( void *initData, VirtProcr *animatingPr ) | |
| 564 { void *jmpPt, *coreLoopStackPtr, *coreLoopFramePtr; | |
| 565 | |
| 566 jmpPt = _VMSMasterEnv->coreLoopEndPt; | |
| 567 coreLoopStackPtr = animatingPr->coreLoopStackPtr; | |
| 568 coreLoopFramePtr = animatingPr->coreLoopFramePtr; | |
| 569 | |
| 570 | |
| 571 asm volatile("movl %0, %%eax; \ | |
| 572 movl %1, %%esp; \ | |
| 573 movl %2, %%ebp; \ | |
| 574 jmp %%eax " \ | |
| 575 /* outputs */ : \ | |
| 576 /* inputs */ : "m" (jmpPt), "m"(coreLoopStackPtr), "m"(coreLoopFramePtr)\ | |
| 577 /* clobber */ : "memory", "%eax", "%ebx", "%ecx", "%edx", "%edi","%esi" \ | |
| 578 ); | |
| 579 } | |
| 580 | |
| 581 | |
| 582 | |
| 583 /*This is called has to free anything allocated during VMS_init, and any other alloc'd | |
| 568 * locations that might be left over. | 584 * locations that might be left over. |
| 569 */ | 585 */ |
| 570 void | 586 void |
| 571 VMS__shutdown() | 587 VMS__cleanup_after_shutdown() |
| 572 { int i; | 588 { int i; |
| 573 | 589 |
| 574 free( _VMSWorkQ ); | 590 free( _VMSWorkQ ); |
| 575 free( _VMSMasterEnv->filledSlots ); | 591 free( _VMSMasterEnv->filledSlots ); |
| 576 for( i = 0; i < NUM_SCHED_SLOTS; i++ ) | 592 for( i = 0; i < NUM_SCHED_SLOTS; i++ ) |
| 577 { | 593 { |
| 578 free( _VMSMasterEnv->schedSlots[i] ); | 594 free( _VMSMasterEnv->schedSlots[i] ); |
| 579 } | 595 } |
| 580 | 596 |
| 581 free( _VMSMasterEnv->schedSlots); | 597 free( _VMSMasterEnv->schedSlots); |
| 582 VMS__free_procr_locs( _VMSMasterEnv->masterVirtPr ); | 598 VMS__handle_dissipate_reqst( _VMSMasterEnv->masterVirtPr ); |
| 583 | 599 |
| 584 free( _VMSMasterEnv ); | 600 free( _VMSMasterEnv ); |
| 585 } | 601 } |
| 586 | 602 |
| 587 | 603 |
