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