Mercurial > cgi-bin > hgwebdir.cgi > VMS > VMS_Implementations > VMS_impls > VMS__MC_shared_impl
comparison VMS.c @ 38:17d20e5cf924
measures coreloop and masterVP times
| author | Me |
|---|---|
| date | Tue, 07 Sep 2010 18:40:57 -0700 |
| parents | e69579a0e797 |
| children | 1df8d7f2c9b1 |
comparison
equal
deleted
inserted
replaced
| 13:9b4e00ead10c | 16:26c99a33a71e |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright 2010 OpenSourceCodeStewardshipFoundation | 2 * Copyright 2010 OpenSourceStewardshipFoundation |
| 3 * | 3 * |
| 4 * Licensed under BSD | 4 * Licensed under BSD |
| 5 */ | 5 */ |
| 6 | 6 |
| 7 #include <stdio.h> | 7 #include <stdio.h> |
| 8 #include <stdlib.h> | 8 #include <stdlib.h> |
| 9 #include <malloc.h> | 9 #include <malloc.h> |
| 10 | 10 |
| 11 #include "VMS.h" | 11 #include "VMS.h" |
| 12 #include "Queue_impl/BlockingQueue.h" | 12 #include "Queue_impl/BlockingQueue.h" |
| 13 #include "Histogram/Histogram.h" | |
| 13 | 14 |
| 14 | 15 |
| 15 #define thdAttrs NULL | 16 #define thdAttrs NULL |
| 16 | 17 |
| 17 //=========================================================================== | 18 //=========================================================================== |
| 124 //Just allocate a massive chunk of memory and roll own malloc/free and | 125 //Just allocate a massive chunk of memory and roll own malloc/free and |
| 125 // make app use VMS__malloc_to, which will suspend and perform malloc | 126 // make app use VMS__malloc_to, which will suspend and perform malloc |
| 126 // in the master, taking from this massive chunk. | 127 // in the master, taking from this massive chunk. |
| 127 | 128 |
| 128 // initFreeList(); | 129 // initFreeList(); |
| 130 | |
| 131 //============================= MEASUREMENT STUFF ======================== | |
| 132 #ifdef MEAS__TIME_STAMP_SUSP | |
| 133 _VMSMasterEnv->measSuspHist = makeHistogram( 25, 110, 135 ); | |
| 134 #endif | |
| 135 | |
| 136 #ifdef MEAS__TIME_MASTER | |
| 137 _VMSMasterEnv->measMasterHist = makeHistogram( 25, 500, 800 ); | |
| 138 #endif | |
| 139 //======================================================================== | |
| 140 | |
| 129 } | 141 } |
| 130 | 142 |
| 131 /* | 143 /* |
| 132 void | 144 void |
| 133 initMasterMalloc() | 145 initMasterMalloc() |
| 291 newPr = malloc( sizeof(VirtProcr) ); | 303 newPr = malloc( sizeof(VirtProcr) ); |
| 292 newPr->procrID = numProcrsCreated++; | 304 newPr->procrID = numProcrsCreated++; |
| 293 newPr->nextInstrPt = fnPtr; | 305 newPr->nextInstrPt = fnPtr; |
| 294 newPr->initialData = initialData; | 306 newPr->initialData = initialData; |
| 295 newPr->requests = NULL; | 307 newPr->requests = NULL; |
| 308 newPr->schedSlot = NULL; | |
| 296 // newPr->coreLoopStartPt = _VMSMasterEnv->coreLoopStartPt; | 309 // newPr->coreLoopStartPt = _VMSMasterEnv->coreLoopStartPt; |
| 297 | 310 |
| 298 //fnPtr takes two params -- void *initData & void *animProcr | 311 //fnPtr takes two params -- void *initData & void *animProcr |
| 299 //alloc stack locations, make stackPtr be the highest addr minus room | 312 //alloc stack locations, make stackPtr be the highest addr minus room |
| 300 // for 2 params + return addr. Return addr (NULL) is in loc pointed to | 313 // for 2 params + return addr. Return addr (NULL) is in loc pointed to |
| 322 * slave that animated the just-ended work-unit, so all the state is saved | 335 * slave that animated the just-ended work-unit, so all the state is saved |
| 323 * there, and will get passed along, inside the request handler, to the | 336 * there, and will get passed along, inside the request handler, to the |
| 324 * next work-unit for that procr. | 337 * next work-unit for that procr. |
| 325 */ | 338 */ |
| 326 void | 339 void |
| 327 VMS__suspend_procr( VirtProcr *callingPr ) | 340 VMS__suspend_procr( VirtProcr *animatingPr ) |
| 328 { void *jmpPt, *stackPtrAddr, *framePtrAddr, *coreLoopStackPtr; | 341 { void *jmpPt, *stackPtrAddr, *framePtrAddr, *coreLoopStackPtr; |
| 329 void *coreLoopFramePtr; | 342 void *coreLoopFramePtr; |
| 330 | 343 |
| 331 //The request to master will cause this suspended virt procr to get | 344 //The request to master will cause this suspended virt procr to get |
| 332 // scheduled again at some future point -- to resume, core loop jumps | 345 // scheduled again at some future point -- to resume, core loop jumps |
| 333 // to the resume point (below), which causes restore of saved regs and | 346 // to the resume point (below), which causes restore of saved regs and |
| 334 // "return" from this call. | 347 // "return" from this call. |
| 335 callingPr->nextInstrPt = &&ResumePt; | 348 animatingPr->nextInstrPt = &&ResumePt; |
| 336 | 349 |
| 337 //return ownership of the virt procr and sched slot to Master virt pr | 350 //return ownership of the virt procr and sched slot to Master virt pr |
| 338 callingPr->schedSlot->workIsDone = TRUE; | 351 animatingPr->schedSlot->workIsDone = TRUE; |
| 339 // coreIdx = callingPr->coreAnimatedBy; | 352 // coreIdx = callingPr->coreAnimatedBy; |
| 340 | 353 |
| 341 stackPtrAddr = &(callingPr->stackPtr); | 354 stackPtrAddr = &(animatingPr->stackPtr); |
| 342 framePtrAddr = &(callingPr->framePtr); | 355 framePtrAddr = &(animatingPr->framePtr); |
| 343 | 356 |
| 344 jmpPt = _VMSMasterEnv->coreLoopStartPt; | 357 jmpPt = _VMSMasterEnv->coreLoopStartPt; |
| 345 coreLoopFramePtr = callingPr->coreLoopFramePtr;//need this only | 358 coreLoopFramePtr = animatingPr->coreLoopFramePtr;//need this only |
| 346 coreLoopStackPtr = callingPr->coreLoopStackPtr;//shouldn't need -- safety | 359 coreLoopStackPtr = animatingPr->coreLoopStackPtr;//safety |
| 347 | 360 |
| 348 //Eclipse's compilation sequence complains -- so break into two | |
| 349 // separate in-line assembly pieces | |
| 350 //Save the virt procr's stack and frame ptrs, | 361 //Save the virt procr's stack and frame ptrs, |
| 351 asm volatile("movl %0, %%eax; \ | 362 asm volatile("movl %0, %%eax; \ |
| 352 movl %%esp, (%%eax); \ | 363 movl %%esp, (%%eax); \ |
| 353 movl %1, %%eax; \ | 364 movl %1, %%eax; \ |
| 354 movl %%ebp, (%%eax) "\ | 365 movl %%ebp, (%%eax) "\ |
| 355 /* outputs */ : "=g" (stackPtrAddr), "=g" (framePtrAddr) \ | 366 /* outputs */ : "=g" (stackPtrAddr), "=g" (framePtrAddr) \ |
| 356 /* inputs */ : \ | 367 /* inputs */ : \ |
| 357 /* clobber */ : "%eax" \ | 368 /* clobber */ : "%eax" \ |
| 358 ); | 369 ); |
| 370 | |
| 371 #ifdef MEAS__TIME_STAMP_SUSP | |
| 372 //record time stamp into animating procr: compared to time-stamp | |
| 373 // recorded below, at the resume pt. | |
| 374 //NOTE: doing minimal work here 'cause only a few instrs executed in | |
| 375 // core loop, so only using bottom half of time-stamp -- have to | |
| 376 // externally do sanity check & throw out absurd values due to rollover | |
| 377 | |
| 378 saveLowTimeStampCountInto( animatingPr->preSuspTSCLow ); | |
| 379 #endif | |
| 359 | 380 |
| 360 //restore coreloop's frame ptr, then jump back to "start" of core loop | 381 //restore coreloop's frame ptr, then jump back to "start" of core loop |
| 361 //Note, GCC compiles to assembly that saves esp and ebp in the stack | 382 //Note, GCC compiles to assembly that saves esp and ebp in the stack |
| 362 // frame -- so have to explicitly do assembly that saves to memory | 383 // frame -- so have to explicitly do assembly that saves to memory |
| 363 asm volatile("movl %0, %%eax; \ | 384 asm volatile("movl %0, %%eax; \ |
| 370 ); //list everything as clobbered to force GCC to save all | 391 ); //list everything as clobbered to force GCC to save all |
| 371 // live vars that are in regs on stack before this | 392 // live vars that are in regs on stack before this |
| 372 // assembly, so that stack pointer is correct, before jmp | 393 // assembly, so that stack pointer is correct, before jmp |
| 373 | 394 |
| 374 ResumePt: | 395 ResumePt: |
| 396 #ifdef MEAS__TIME_STAMP_SUSP | |
| 397 saveLowTimeStampCountInto( animatingPr->postSuspTSCLow ); | |
| 398 //Take difference between the pre-suspend and post-suspend times | |
| 399 // and do sanity check to see if rollover happened between | |
| 400 int diff = animatingPr->postSuspTSCLow - animatingPr->preSuspTSCLow; | |
| 401 if( diff > 1000000 ) diff = 0; | |
| 402 addToHist( diff, _VMSMasterEnv->measSuspHist ); | |
| 403 | |
| 404 #endif | |
| 405 | |
| 375 return; | 406 return; |
| 376 } | 407 } |
| 377 | 408 |
| 378 | 409 |
| 379 | 410 |
| 380 | 411 |
| 381 /*Not sure yet the form going to put "dissipate" in, so this is the third | 412 /* |
| 382 * possibility -- the semantic layer can just make a macro that looks like | |
| 383 * a call to its name, then expands to a call to this. | |
| 384 * | |
| 385 *As of June 30, 2010 this looks like the top choice.. | |
| 386 * | |
| 387 *This adds a request to dissipate, then suspends the processor so that the | 413 *This adds a request to dissipate, then suspends the processor so that the |
| 388 * request handler will receive the request. The request handler is what | 414 * request handler will receive the request. The request handler is what |
| 389 * does the work of freeing memory and removing the processor from the | 415 * does the work of freeing memory and removing the processor from the |
| 390 * semantic environment's data structures. | 416 * semantic environment's data structures. |
| 391 *The request handler also is what figures out when to shutdown the VMS | 417 *The request handler also is what figures out when to shutdown the VMS |
| 431 req->nextReqst = callingPr->requests; | 457 req->nextReqst = callingPr->requests; |
| 432 callingPr->requests = req; | 458 callingPr->requests = req; |
| 433 } | 459 } |
| 434 | 460 |
| 435 | 461 |
| 436 | 462 /*Use this to get first request before starting request handler's loop |
| 437 //TODO: add a semantic-layer supplied "freer" for the semantic-data portion | 463 */ |
| 438 // of a request -- IE call with both a virt procr and a fn-ptr to request | 464 VMSReqst * |
| 439 // freer (or maybe put request freer as a field in virt procr?) | 465 VMS__take_top_request_from( VirtProcr *procrWithReq ) |
| 440 void | |
| 441 VMS__remove_and_free_top_request( VirtProcr *procrWithReq ) | |
| 442 { VMSReqst *req; | 466 { VMSReqst *req; |
| 443 | 467 |
| 444 req = procrWithReq->requests; | 468 req = procrWithReq->requests; |
| 445 if( req == NULL ) return; | 469 if( req == NULL ) return req; |
| 470 | |
| 471 procrWithReq->requests = procrWithReq->requests->nextReqst; | |
| 472 return req; | |
| 473 } | |
| 474 | |
| 475 /*A subtle bug due to freeing then accessing "next" after freed caused this | |
| 476 * form of call to be put in -- so call this at end of request handler loop | |
| 477 * that iterates through the requests. | |
| 478 */ | |
| 479 VMSReqst * | |
| 480 VMS__free_top_and_give_next_request_from( VirtProcr *procrWithReq ) | |
| 481 { VMSReqst *req; | |
| 482 | |
| 483 req = procrWithReq->requests; | |
| 484 if( req == NULL ) return NULL; | |
| 485 | |
| 446 procrWithReq->requests = procrWithReq->requests->nextReqst; | 486 procrWithReq->requests = procrWithReq->requests->nextReqst; |
| 447 VMS__free_request( req ); | 487 VMS__free_request( req ); |
| 488 return procrWithReq->requests; | |
| 448 } | 489 } |
| 449 | 490 |
| 450 | 491 |
| 451 //TODO: add a semantic-layer supplied "freer" for the semantic-data portion | 492 //TODO: add a semantic-layer supplied "freer" for the semantic-data portion |
| 452 // of a request -- IE call with both a virt procr and a fn-ptr to request | 493 // of a request -- IE call with both a virt procr and a fn-ptr to request |
| 453 // freer (also maybe put sem request freer as a field in virt procr?) | 494 // freer (also maybe put sem request freer as a field in virt procr?) |
| 454 //SSR relies right now on this only freeing VMS layer of request -- the | 495 //MeasVMS relies right now on this only freeing VMS layer of request -- the |
| 455 // semantic portion of request is alloc'd and freed by request handler | 496 // semantic portion of request is alloc'd and freed by request handler |
| 456 void | 497 void |
| 457 VMS__free_request( VMSReqst *req ) | 498 VMS__free_request( VMSReqst *req ) |
| 458 { | 499 { |
| 459 free( req ); | 500 free( req ); |
| 460 } | 501 } |
| 461 | 502 |
| 462 VMSReqst * | 503 |
| 463 VMS__take_top_request_from( VirtProcr *procrWithReq ) | |
| 464 { VMSReqst *req; | |
| 465 | |
| 466 req = procrWithReq->requests; | |
| 467 if( req == NULL ) return req; | |
| 468 | |
| 469 procrWithReq->requests = procrWithReq->requests->nextReqst; | |
| 470 return req; | |
| 471 } | |
| 472 | |
| 473 VMSReqst * | |
| 474 VMS__free_top_and_give_next_request_from( VirtProcr *procrWithReq ) | |
| 475 { VMSReqst *req; | |
| 476 | |
| 477 req = procrWithReq->requests; | |
| 478 if( req == NULL ) return req; | |
| 479 | |
| 480 procrWithReq->requests = procrWithReq->requests->nextReqst; | |
| 481 VMS__free_request( req ); | |
| 482 return procrWithReq->requests; | |
| 483 } | |
| 484 | 504 |
| 485 inline int | 505 inline int |
| 486 VMS__isSemanticReqst( VMSReqst *req ) | 506 VMS__isSemanticReqst( VMSReqst *req ) |
| 487 { | 507 { |
| 488 return ( req->reqType == semantic ); | 508 return ( req->reqType == semantic ); |
| 506 { | 526 { |
| 507 return ( req->reqType == regCreated ); | 527 return ( req->reqType == regCreated ); |
| 508 } | 528 } |
| 509 | 529 |
| 510 void | 530 void |
| 511 VMS__send_register_new_procr_request(VirtProcr *newPr, VirtProcr *reqstingPr) | 531 VMS__send_req_to_register_new_procr(VirtProcr *newPr, VirtProcr *reqstingPr) |
| 512 { VMSReqst *req; | 532 { VMSReqst *req; |
| 513 | 533 |
| 514 req = malloc( sizeof(VMSReqst) ); | 534 req = malloc( sizeof(VMSReqst) ); |
| 515 req->reqType = regCreated; | 535 req->reqType = regCreated; |
| 516 req->semReqData = newPr; | 536 req->semReqData = newPr; |
| 545 //dis-own all locations owned by this processor, causing to be freed | 565 //dis-own all locations owned by this processor, causing to be freed |
| 546 // any locations that it is (was) sole owner of | 566 // any locations that it is (was) sole owner of |
| 547 //TODO: implement VMS__malloc system, including "give up ownership" | 567 //TODO: implement VMS__malloc system, including "give up ownership" |
| 548 | 568 |
| 549 //The dissipate request might still be attached, so remove and free it | 569 //The dissipate request might still be attached, so remove and free it |
| 550 VMS__remove_and_free_top_request( animatingPr ); | 570 VMS__free_top_and_give_next_request_from( animatingPr ); |
| 551 | 571 |
| 552 //NOTE: initialData was given to the processor, so should either have | 572 //NOTE: initialData was given to the processor, so should either have |
| 553 // been alloc'd with VMS__malloc, or freed by the level above animPr. | 573 // been alloc'd with VMS__malloc, or freed by the level above animPr. |
| 554 //So, all that's left to free here is the stack and the VirtProcr struc | 574 //So, all that's left to free here is the stack and the VirtProcr struc |
| 555 // itself | 575 // itself |
