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 +