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