Mercurial > cgi-bin > hgwebdir.cgi > VMS > VMS_Implementations > MeasVMS_impls > MeasVMS__MC_shared_impl
changeset 0:e123acb162f0
Initial add of MeasVMS semantic layer
Works, but has weird suspend-time histogram -- will try
moving hist updates out of coreloop & out of master and
into the app
| author | Me |
|---|---|
| date | Sat, 11 Sep 2010 03:25:03 -0700 |
| parents | |
| children | bfa2fe3552e4 |
| files | .hgignore MeasVMS.h MeasVMS_PluginFns.c MeasVMS_lib.c |
| diffstat | 3 files changed, 399 insertions(+), 0 deletions(-) [+] |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/MeasVMS.h Sat Sep 11 03:25:03 2010 -0700 1.3 @@ -0,0 +1,138 @@ 1.4 +/* 1.5 + * Copyright 2009 OpenSourceStewardshipFoundation.org 1.6 + * Licensed under GNU General Public License version 2 1.7 + * 1.8 + * Author: seanhalle@yahoo.com 1.9 + * 1.10 + */ 1.11 + 1.12 +#ifndef _MeasVMS_H 1.13 +#define _MeasVMS_H 1.14 + 1.15 +#include "VMS/Queue_impl/PrivateQueue.h" 1.16 +#include "VMS/Hash_impl/PrivateHash.h" 1.17 +#include "VMS/Histogram/Histogram.h" 1.18 +#include "VMS/VMS.h" 1.19 + 1.20 +/*This header defines everything specific to the MeasVMS semantic plug-in 1.21 + */ 1.22 +typedef struct _MeasVMSSemReq MeasVMSSemReq; 1.23 + 1.24 + 1.25 +/*Semantic layer-specific data sent inside a request from lib called in app 1.26 + * to request handler called in MasterLoop 1.27 + */ 1.28 +enum MeasVMSReqType 1.29 + { 1.30 + send_type = 1, 1.31 + send_from_to, 1.32 + receive_any, //order and grouping matter -- send before receive 1.33 + receive_type, // and receive_any first of the receives -- Handlers 1.34 + receive_from_to,// rely upon this ordering of enum 1.35 + transfer_to, 1.36 + transfer_out 1.37 + }; 1.38 + 1.39 +struct _MeasVMSSemReq 1.40 + { enum MeasVMSReqType reqType; 1.41 + VirtProcr *sendPr; 1.42 + VirtProcr *receivePr; 1.43 + int32 msgType; 1.44 + void *msg; 1.45 + MeasVMSSemReq *nextReqInHashEntry; 1.46 + } 1.47 +/* MeasVMSSemReq */; 1.48 + 1.49 +typedef struct 1.50 + { 1.51 + PrivQueueStruc **readyVPQs; 1.52 + int numVirtPr; 1.53 + int numTimesCalled; 1.54 + int firstOfTwo; 1.55 + int nextCoreToGetNewPr; 1.56 + 1.57 + Histogram **addrOfSuspHist; 1.58 + Histogram **addrOfMasterHist; 1.59 + } 1.60 +MeasVMSSemEnv; 1.61 + 1.62 + 1.63 +typedef struct 1.64 + { 1.65 + Histogram **suspHistAddr; 1.66 + Histogram **masterHistAddr; 1.67 + } 1.68 +PairOfHistAddresses; 1.69 + 1.70 +//=========================================================================== 1.71 + 1.72 +void 1.73 +MeasVMS__create_seed_procr_and_do_work( VirtProcrFnPtr fn, void *initData ); 1.74 + 1.75 +//======================= 1.76 + 1.77 +void 1.78 +MeasVMS__init(); 1.79 + 1.80 +void 1.81 +MeasVMS__cleanup_after_shutdown(); 1.82 + 1.83 +//======================= 1.84 + 1.85 +inline VirtProcr * 1.86 +MeasVMS__create_procr_with( VirtProcrFnPtr fnPtr, void *initData, 1.87 + VirtProcr *creatingPr ); 1.88 + 1.89 +void 1.90 +MeasVMS__dissipate_procr( VirtProcr *procrToDissipate ); 1.91 + 1.92 +//======================= 1.93 +void * 1.94 +MeasVMS__malloc_size_to( int numBytes, VirtProcr *ownerPr ); 1.95 + 1.96 +void 1.97 +MeasVMS__transfer_ownership_of_from_to( void *data, VirtProcr *oldOwnerPr, 1.98 + VirtProcr *newOwnerPr ); 1.99 + 1.100 +void 1.101 +MeasVMS__add_ownership_by_to( VirtProcr *newOwnerPr, void *data ); 1.102 + 1.103 +void 1.104 +MeasVMS__remove_ownership_by_from( VirtProcr *loserPr, void *dataLosing ); 1.105 + 1.106 +void 1.107 +MeasVMS__transfer_ownership_to_outside( void *dataToTransferOwnershipOf ); 1.108 + 1.109 + 1.110 + 1.111 +//======================= 1.112 +void 1.113 +MeasVMS__send_of_type_to( VirtProcr *sendPr, void *msg, const int type, 1.114 + VirtProcr *receivePr); 1.115 + 1.116 +void 1.117 +MeasVMS__send_from_to( void *msg, VirtProcr *sendPr, VirtProcr *receivePr); 1.118 + 1.119 +void * 1.120 +MeasVMS__receive_type_to( const int type, VirtProcr *receivePr ); 1.121 + 1.122 +void * 1.123 +MeasVMS__receive_from_to( VirtProcr *sendPr, VirtProcr *receivePr ); 1.124 + 1.125 + 1.126 +//======================= 1.127 + 1.128 +void 1.129 +MeasVMS__free_semantic_request( MeasVMSSemReq *semReq ); 1.130 + 1.131 + 1.132 +//========================= Internal use only ============================= 1.133 +void 1.134 +MeasVMS__Request_Handler( VirtProcr *requestingPr, void *_semEnv ); 1.135 + 1.136 +VirtProcr * 1.137 +MeasVMS__schedule_virt_procr( void *_semEnv, int coreNum ); 1.138 + 1.139 + 1.140 +#endif /* _MeasVMS_H */ 1.141 +
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/MeasVMS_PluginFns.c Sat Sep 11 03:25:03 2010 -0700 2.3 @@ -0,0 +1,92 @@ 2.4 +/* 2.5 + * Copyright 2010 OpenSourceStewardshipFoundation 2.6 + * 2.7 + * Licensed under BSD 2.8 + */ 2.9 + 2.10 +#include <stdio.h> 2.11 +#include <stdlib.h> 2.12 +#include <malloc.h> 2.13 + 2.14 +#include "VMS/Queue_impl/PrivateQueue.h" 2.15 +#include "MeasVMS.h" 2.16 + 2.17 + 2.18 +/*Sept 5, 2010: only measuring core loop for now -- to do this, have 2.19 + * an AppVP that has a loop that suspends itself then measures the time 2.20 + * from suspend to resume and updates a histogram, then suspends again. 2.21 + * 2.22 + *This request handler just queues up the same processor twice in a row -- 2.23 + * the first will suspend, the second will resume and capture the time 2.24 + * spent in the core loop between -- then it will suspend again, and there 2.25 + * will be no more AppVPs in the queue, so the MasterVP will be animated 2.26 + * by the core loop, and this request handler will be called again and 2.27 + * do the same thing. 2.28 + * 2.29 + *It keeps a count of how many times it does this, and shutsdown when enough. 2.30 + */ 2.31 +void 2.32 +MeasVMS__Request_Handler( VirtProcr *requestingPr, void *_semEnv ) 2.33 + { MeasVMSSemEnv *semEnv; 2.34 + 2.35 + semEnv = (MeasVMSSemEnv *)_semEnv; 2.36 + 2.37 + //Cheating normal request handler behavior here -- putting two of the 2.38 + // exact same virt procr into ready-queue at same time. Also breaking 2.39 + // abstraction inside that virt procr by accessing the VP vars inside 2.40 + // the application code. 2.41 + 2.42 + //NOTE: there are no requests attached to the AppVPs.. just do a fixed 2.43 + // thing each time called, don't process any requests. 2.44 + writePrivQ(requestingPr, semEnv->readyVPQs[requestingPr->coreAnimatedBy]); 2.45 + writePrivQ(requestingPr, semEnv->readyVPQs[requestingPr->coreAnimatedBy]); 2.46 + 2.47 + semEnv->numTimesCalled += 1; 2.48 + if( semEnv->numTimesCalled >= MEAS__NUM_TIMES_TO_RUN ) 2.49 + { 2.50 + #ifdef MEAS__TIME_STAMP_SUSP 2.51 + *(semEnv->addrOfSuspHist) = _VMSMasterEnv->measSuspHist; 2.52 + #endif 2.53 + #ifdef MEAS__TIME_MASTER 2.54 + *(semEnv->addrOfMasterHist) = _VMSMasterEnv->measMasterHist; 2.55 + #endif 2.56 + VMS__handle_shutdown_reqst( requestingPr ); 2.57 + } 2.58 + 2.59 + } 2.60 + 2.61 +//=========================================================================== 2.62 + 2.63 + 2.64 +/*For MeasVMS, thing s are a bit of a pain 2.65 + */ 2.66 +VirtProcr * 2.67 +MeasVMS__schedule_virt_procr( void *_semEnv, int coreNum ) 2.68 + { VirtProcr *schedPr; 2.69 + MeasVMSSemEnv *semEnv; 2.70 + 2.71 + semEnv = (MeasVMSSemEnv *)_semEnv; 2.72 + 2.73 + schedPr = readPrivQ( semEnv->readyVPQs[coreNum] ); 2.74 + 2.75 + //Note, using a non-blocking queue -- it returns NULL if queue empty 2.76 + if( schedPr == NULL ) return NULL; 2.77 + 2.78 + if( semEnv->firstOfTwo == TRUE ) 2.79 + { 2.80 + semEnv->firstOfTwo = FALSE; 2.81 + schedPr->schedSlot->workIsDone = FALSE; //slot from second assign 2.82 + schedPr->schedSlot->needsProcrAssigned = TRUE; 2.83 + } 2.84 + else 2.85 + { 2.86 + semEnv->firstOfTwo = TRUE; 2.87 + //================================================================== 2.88 + if( schedPr->schedSlot == NULL ) return schedPr; //seed pr first time 2.89 + //================================================================== 2.90 + schedPr->schedSlot->workIsDone = TRUE; //slot from first assign 2.91 + } 2.92 + 2.93 + return schedPr; 2.94 + } 2.95 +
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/MeasVMS_lib.c Sat Sep 11 03:25:03 2010 -0700 3.3 @@ -0,0 +1,169 @@ 3.4 +/* 3.5 + * Copyright 2010 OpenSourceStewardshipFoundation 3.6 + * 3.7 + * Licensed under BSD 3.8 + */ 3.9 + 3.10 +#include <stdio.h> 3.11 +#include <stdlib.h> 3.12 +#include <malloc.h> 3.13 + 3.14 +#include "VMS/VMS.h" 3.15 +#include "MeasVMS.h" 3.16 +#include "VMS/Queue_impl/PrivateQueue.h" 3.17 +#include "VMS/Hash_impl/PrivateHash.h" 3.18 + 3.19 + 3.20 +//========================================================================== 3.21 + 3.22 +void 3.23 +MeasVMS__init(); 3.24 + 3.25 +void 3.26 +MeasVMS__init_Seq(); 3.27 + 3.28 +void 3.29 +MeasVMS__init_Helper(); 3.30 + 3.31 + 3.32 +//=========================================================================== 3.33 + 3.34 +/*This is the "border crossing" function -- the thing that crosses from the 3.35 + * outside world, into the VMS_HW world. It initializes and starts up the 3.36 + * VMS system, then creates one processor from the specified function and 3.37 + * puts it into the readyQ. From that point, that one function is resp. 3.38 + * for creating all the other processors, that then create others, and so 3.39 + * forth. 3.40 + *When all the processors, including the seed, have dissipated, then this 3.41 + * function returns. The results will have been written by side-effect via 3.42 + * pointers read from, or written into initData. 3.43 + * 3.44 + *NOTE: no Threads should exist in the outside program that might touch 3.45 + * any of the data reachable from initData passed in to here 3.46 + */ 3.47 +void 3.48 +MeasVMS__create_seed_procr_and_do_work( VirtProcrFnPtr fnPtr, void *initData ) 3.49 + { MeasVMSSemEnv *semEnv; 3.50 + VirtProcr *seedPr; 3.51 + 3.52 + #ifdef SEQUENTIAL 3.53 + MeasVMS__init_Seq(); //debug sequential exe 3.54 + #else 3.55 + MeasVMS__init(); //normal multi-thd 3.56 + #endif 3.57 + 3.58 + semEnv = _VMSMasterEnv->semanticEnv; 3.59 + 3.60 + //MeasVMS starts with one processor, which is put into initial environ, 3.61 + // and which then calls create() to create more, thereby expanding work 3.62 + seedPr = VMS__create_procr( fnPtr, initData ); 3.63 + 3.64 + seedPr->coreAnimatedBy = semEnv->nextCoreToGetNewPr++; 3.65 + 3.66 + writePrivQ( seedPr, semEnv->readyVPQs[seedPr->coreAnimatedBy] ); 3.67 + semEnv->numVirtPr = 1; 3.68 + 3.69 + //============================= MEASUREMENT STUFF ======================== 3.70 + PairOfHistAddresses *histCarrier = (PairOfHistAddresses *)initData; 3.71 + 3.72 + semEnv->addrOfSuspHist = histCarrier->suspHistAddr; 3.73 + semEnv->addrOfMasterHist = histCarrier->masterHistAddr; 3.74 + //======================================================================== 3.75 + 3.76 + 3.77 + #ifdef SEQUENTIAL 3.78 + VMS__start_the_work_then_wait_until_done_Seq(); //debug sequential exe 3.79 + #else 3.80 + VMS__start_the_work_then_wait_until_done(); //normal multi-thd 3.81 + #endif 3.82 + 3.83 + MeasVMS__cleanup_after_shutdown(); 3.84 + } 3.85 + 3.86 + 3.87 +//=========================================================================== 3.88 + 3.89 +/*Initializes all the data-structures for a MeasVMS system -- but doesn't 3.90 + * start it running yet! 3.91 + * 3.92 + * 3.93 + *This sets up the semantic layer over the VMS system 3.94 + * 3.95 + *First, calls VMS_Setup, then creates own environment, making it ready 3.96 + * for creating the seed processor and then starting the work. 3.97 + */ 3.98 +void 3.99 +MeasVMS__init() 3.100 + { 3.101 + VMS__init(); 3.102 + //masterEnv, a global var, now is partially set up by init_VMS 3.103 + 3.104 + MeasVMS__init_Helper(); 3.105 + } 3.106 + 3.107 +void 3.108 +MeasVMS__init_Seq() 3.109 + { 3.110 + VMS__init_Seq(); 3.111 + //masterEnv, a global var, now is partially set up by init_VMS 3.112 + 3.113 + MeasVMS__init_Helper(); 3.114 + } 3.115 + 3.116 +void 3.117 +MeasVMS__init_Helper() 3.118 + { MeasVMSSemEnv *semEnv; 3.119 + PrivQueueStruc **readyVPQs; 3.120 + int coreIdx; 3.121 + 3.122 + //Hook up the semantic layer's plug-ins to the Master virt procr 3.123 + _VMSMasterEnv->requestHandler = &MeasVMS__Request_Handler; 3.124 + _VMSMasterEnv->slaveScheduler = &MeasVMS__schedule_virt_procr; 3.125 + 3.126 + //create the semantic layer's environment (all its data) and add to 3.127 + // the master environment 3.128 + semEnv = malloc( sizeof( MeasVMSSemEnv ) ); 3.129 + _VMSMasterEnv->semanticEnv = semEnv; 3.130 + 3.131 + //create the ready queue, hash tables used for pairing send to receive 3.132 + // and so forth 3.133 + //TODO: add hash tables for pairing sends with receives, and 3.134 + // initialize the data ownership system 3.135 + readyVPQs = malloc( NUM_CORES * sizeof(PrivQueueStruc *) ); 3.136 + 3.137 + for( coreIdx = 0; coreIdx < NUM_CORES; coreIdx++ ) 3.138 + { 3.139 + readyVPQs[ coreIdx ] = makePrivQ(); 3.140 + } 3.141 + 3.142 + semEnv->numTimesCalled = 0; 3.143 + semEnv->firstOfTwo = FALSE; 3.144 + 3.145 + semEnv->readyVPQs = readyVPQs; 3.146 + } 3.147 + 3.148 + 3.149 +/*Frees any memory allocated by MeasVMS__init() then calls VMS__shutdown 3.150 + */ 3.151 +void 3.152 +MeasVMS__cleanup_after_shutdown() 3.153 + { MeasVMSSemEnv *semanticEnv; 3.154 + int coreIdx; 3.155 + 3.156 + semanticEnv = _VMSMasterEnv->semanticEnv; 3.157 + 3.158 + 3.159 + for( coreIdx = 0; coreIdx < NUM_CORES; coreIdx++ ) 3.160 + { 3.161 + free( semanticEnv->readyVPQs[coreIdx]->startOfData ); 3.162 + free( semanticEnv->readyVPQs[coreIdx] ); 3.163 + } 3.164 + free( semanticEnv->readyVPQs ); 3.165 + 3.166 + free( _VMSMasterEnv->semanticEnv ); 3.167 + VMS__cleanup_after_shutdown(); 3.168 + } 3.169 + 3.170 + 3.171 +//=========================================================================== 3.172 +
