changeset 245:f1267bc7b342 Common_Ancestor

added exceptions, make malloc in WL and App get master lock, added rand num
author Sean Halle <seanhalle@yahoo.com>
date Wed, 30 May 2012 14:23:47 -0700
parents 5e315ce69d82
children 4c7414df4f0e
files CoreController.c Defines/VMS_defs__HW_constants.h Services_Offered_by_VMS/Measurement_and_Stats/probes.c Services_Offered_by_VMS/Memory_Handling/vmalloc.c Services_Offered_by_VMS/Memory_Handling/vmalloc.h VMS.h VMS__PI.c VMS__WL.c VMS__int.c VMS__startup_and_shutdown.c
diffstat 10 files changed, 199 insertions(+), 46 deletions(-) [+]
line diff
     1.1 --- a/CoreController.c	Fri May 25 12:23:03 2012 +0200
     1.2 +++ b/CoreController.c	Wed May 30 14:23:47 2012 -0700
     1.3 @@ -72,7 +72,7 @@
     1.4     int32           thisCoresIdx;
     1.5     int32           numRepetitionsWithNoWork;
     1.6     SlaveVP        *currVP;
     1.7 -   AnimSlot      *currSlot, **animSlots;
     1.8 +   AnimSlot       *currSlot, **animSlots;
     1.9     int32           currSlotIdx;
    1.10     volatile int32 *addrOfMasterLock; //thing pointed to is volatile, not ptr
    1.11     SlaveVP        *thisCoresMasterVP;
    1.12 @@ -223,18 +223,6 @@
    1.13   }
    1.14  
    1.15  
    1.16 -/*Used by the backoff to pick a random amount of busy-wait.  Can't use the
    1.17 - * system rand because it takes much too long.
    1.18 - *Note, are passing pointers to the seeds, which are then modified
    1.19 - */
    1.20 -inline uint32_t
    1.21 -randomNumber(uint32_t* seed1, uint32_t* seed2)
    1.22 - {
    1.23 -	*seed1 = 36969 * (*seed1 & 65535) + (*seed1 >> 16);
    1.24 -	*seed2 = 18000 * (*seed2 & 65535) + (*seed2 >> 16);
    1.25 -	return (*seed1 << 16) + *seed2;
    1.26 - }
    1.27 -
    1.28  /*Busy-wait for a random number of cycles -- chooses number of cycles 
    1.29   * differently than for the too-many-tries-to-get-lock backoff
    1.30   */
    1.31 @@ -265,7 +253,7 @@
    1.32  
    1.33     waitIterations = 
    1.34      randomNumber(seed1, seed2) % 
    1.35 -    (numTriesToGetLock * NUM_TRIES_TO_GET_LOCK_BACKOFF_WEIGHT);   
    1.36 +    (numTriesToGetLock * GET_LOCK_BACKOFF_WEIGHT);   
    1.37     //addToHist( wait_iterations, coreLoopThdParams->wait_iterations_hist );
    1.38     for( i = 0; i < waitIterations; i++ )
    1.39      { fakeWorkVar += (fakeWorkVar + 32.0) / 2.0; //busy-wait
     2.1 --- a/Defines/VMS_defs__HW_constants.h	Fri May 25 12:23:03 2012 +0200
     2.2 +++ b/Defines/VMS_defs__HW_constants.h	Wed May 30 14:23:47 2012 -0700
     2.3 @@ -25,7 +25,7 @@
     2.4  #define NUM_REPS_W_NO_WORK_BEFORE_BACKOFF    2
     2.5  #define MASTERLOCK_RETRIES_BEFORE_YIELD      100
     2.6  #define NUM_TRIES_BEFORE_DO_BACKOFF          10
     2.7 -#define NUM_TRIES_TO_GET_LOCK_BACKOFF_WEIGHT 100
     2.8 +#define GET_LOCK_BACKOFF_WEIGHT 100
     2.9     
    2.10     // stack size in virtual processors created
    2.11  #define VIRT_PROCR_STACK_SIZE 0x8000 /* 32K */
     3.1 --- a/Services_Offered_by_VMS/Measurement_and_Stats/probes.c	Fri May 25 12:23:03 2012 +0200
     3.2 +++ b/Services_Offered_by_VMS/Measurement_and_Stats/probes.c	Wed May 30 14:23:47 2012 -0700
     3.3 @@ -51,7 +51,7 @@
     3.4   {
     3.5     VMSSemReq reqData;
     3.6  
     3.7 -   reqData.reqType  = createProbe;
     3.8 +   reqData.reqType  = make_probe;
     3.9     reqData.nameStr  = nameStr;
    3.10  
    3.11     VMS_WL__send_VMSSem_request( &reqData, animSlv );
     4.1 --- a/Services_Offered_by_VMS/Memory_Handling/vmalloc.c	Fri May 25 12:23:03 2012 +0200
     4.2 +++ b/Services_Offered_by_VMS/Memory_Handling/vmalloc.c	Wed May 30 14:23:47 2012 -0700
     4.3 @@ -284,6 +284,15 @@
     4.4     return foundChunk + 1;
     4.5   }
     4.6  
     4.7 +void *
     4.8 +VMS_WL__malloc( int32 sizeRequested )
     4.9 + { 
    4.10 +   VMS_int__get_master_lock();
    4.11 +   VMS_int__malloc( sizeRequested );
    4.12 +   VMS_int__release_master_lock();
    4.13 + }
    4.14 +
    4.15 +
    4.16  /*
    4.17   * This is sequential code, meant to only be called from the Master, not from
    4.18   * any slave Slvs.
    4.19 @@ -337,6 +346,14 @@
    4.20           MEAS__Capture_Post_Free_Point;
    4.21   }
    4.22  
    4.23 +void
    4.24 +VMS_WL__free( void *ptrToFree )
    4.25 + {
    4.26 +   VMS_int__get_master_lock();
    4.27 +   VMS_int__free( ptrToFree );
    4.28 +   VMS_int__release_master_lock();
    4.29 + }
    4.30 +
    4.31  /*
    4.32   * Designed to be called from the main thread outside of VMS, during init
    4.33   */
     5.1 --- a/Services_Offered_by_VMS/Memory_Handling/vmalloc.h	Fri May 25 12:23:03 2012 +0200
     5.2 +++ b/Services_Offered_by_VMS/Memory_Handling/vmalloc.h	Wed May 30 14:23:47 2012 -0700
     5.3 @@ -55,19 +55,22 @@
     5.4  void *
     5.5  VMS_int__malloc( size_t sizeRequested );
     5.6  #define VMS_PI__malloc  VMS_int__malloc
     5.7 -#define VMS_WL__malloc  VMS_int__malloc /*TODO: Bug -- get master lock */
     5.8 -#define VMS_App__malloc VMS_int__malloc /*TODO: Bug -- get master lock */
     5.9 +
    5.10 +void *
    5.11 +VMS_WL__malloc( int32  sizeRequested ); /*BUG: -- get master lock */
    5.12 +#define VMS_App__malloc  VMS_WL__malloc
    5.13  
    5.14  void *
    5.15  VMS_int__malloc_aligned( size_t sizeRequested );
    5.16  #define VMS_PI__malloc_aligned VMS_int__malloc_aligned
    5.17 -#define VMS_WL__malloc_aligned VMS_int__malloc_aligned
    5.18  
    5.19  void
    5.20  VMS_int__free( void *ptrToFree );
    5.21  #define VMS_PI__free  VMS_int__free
    5.22 -#define VMS_WL__free  VMS_int__free /*TODO: Bug -- Not protected!! */
    5.23 -#define VMS_App__free VMS_int__free /*TODO: Bug -- Not protected!! */
    5.24 +
    5.25 +void
    5.26 +VMS_WL__free( void *ptrToFree );
    5.27 +#define VMS_App__free  VMS_WL__free
    5.28  
    5.29  
    5.30  
     6.1 --- a/VMS.h	Fri May 25 12:23:03 2012 +0200
     6.2 +++ b/VMS.h	Wed May 30 14:23:47 2012 -0700
     6.3 @@ -76,15 +76,18 @@
     6.4  
     6.5  enum VMSSemReqstType   //These are equivalent to semantic requests, but for
     6.6   {                     // VMS's services available directly to app, like OS
     6.7 -   createProbe = 1,    // and probe services -- like a VMS-wide built-in lang
     6.8 +   make_probe = 1,    // and probe services -- like a VMS-wide built-in lang
     6.9 +   throw_excp,
    6.10     openFile,
    6.11     otherIO
    6.12   };
    6.13  
    6.14  typedef struct
    6.15   { enum VMSSemReqstType reqType;
    6.16 -   SlaveVP           *requestingSlv;
    6.17 +   SlaveVP             *requestingSlv;
    6.18     char                *nameStr;  //for create probe
    6.19 +   char                *msgStr;   //for exception
    6.20 +   void                *exceptionData;
    6.21   }
    6.22   VMSSemReq;
    6.23  
    6.24 @@ -182,7 +185,11 @@
    6.25        //Memory management related
    6.26     MallocArrays    *freeLists;
    6.27     int32            amtOfOutstandingMem;//total currently allocated
    6.28 -      
    6.29 +
    6.30 +      //Random number seeds -- random nums used in various places  
    6.31 +   uint32_t seed1;
    6.32 +   uint32_t seed2;
    6.33 +
    6.34        //=========== MEASUREMENT STUFF =============
    6.35         IntervalProbe   **intervalProbes;
    6.36         PrivDynArrayInfo *dynIntervalProbesInfo;
    6.37 @@ -311,8 +318,10 @@
    6.38  
    6.39  void
    6.40  VMS_int__throw_exception( char *msgStr, SlaveVP *reqstSlv, VMSExcp *excpData );
    6.41 -#define VMS_PI__throw_exception VMS_int__throw_exception
    6.42 -#define VMS_WL__throw_exception VMS_int__throw_exception
    6.43 +#define VMS_PI__throw_exception  VMS_int__throw_exception
    6.44 +void
    6.45 +VMS_WL__throw_exception( char *msgStr, SlaveVP *reqstSlv,  VMSExcp *excpData );
    6.46 +#define VMS_App__throw_exception VMS_WL__throw_exception
    6.47  
    6.48  void *
    6.49  VMS_int__give_sem_env_for( SlaveVP *animSlv );
    6.50 @@ -320,6 +329,15 @@
    6.51  #define VMS_SS__give_sem_env_for  VMS_int__give_sem_env_for
    6.52  //No WL version -- not safe!  if use in WL, be sure data rd & wr is stable
    6.53  
    6.54 +
    6.55 +inline void
    6.56 +VMS_int__get_master_lock();
    6.57 +
    6.58 +#define VMS_int__release_master_lock() _VMSMasterEnv->masterLock = UNLOCKED
    6.59 +
    6.60 +inline uint32_t
    6.61 +VMS_int__randomNumber();
    6.62 +
    6.63  //==============  Request Related  ===============
    6.64  
    6.65  void
     7.1 --- a/VMS__PI.c	Fri May 25 12:23:03 2012 +0200
     7.2 +++ b/VMS__PI.c	Wed May 30 14:23:47 2012 -0700
     7.3 @@ -22,9 +22,17 @@
     7.4   * int: internal to the VMS implementation
     7.5   */
     7.6  
     7.7 +//=========================  Local Declarations  ========================
     7.8 +void inline
     7.9 +handleMakeProbe( VMSSemReq *semReq, void *semEnv, ResumeSlvFnPtr resumeFn );
    7.10  
    7.11 -/*
    7.12 - */
    7.13 +void inline
    7.14 +handleThrowException( VMSSemReq *semReq, void *semEnv, ResumeSlvFnPtr resumeFn );
    7.15 +//=======================================================================
    7.16 +
    7.17 +/*May 2012
    7.18 + *DEPRECATED -- turn into a macro, that just accesses the request field 
    7.19 + 
    7.20  VMSReqst *
    7.21  VMS_PI__take_next_request_out_of( SlaveVP *slaveWithReq )
    7.22   { VMSReqst *req;
    7.23 @@ -35,14 +43,22 @@
    7.24     slaveWithReq->requests = slaveWithReq->requests->nextReqst;
    7.25     return req;
    7.26   }
    7.27 +*/
    7.28 +#define VMS_PI__take_next_request_out_of( slave ) slave->requests
    7.29 + 
    7.30  
    7.31 -
    7.32 +/*May 2012
    7.33 + *DEPRECATED
    7.34 + *
    7.35 + *Turn function into macro that just accesses the request field
    7.36 + *
    7.37  inline void *
    7.38  VMS_PI__take_sem_reqst_from( VMSReqst *req )
    7.39   {
    7.40     return req->semReqData;
    7.41   }
    7.42 -
    7.43 +*/
    7.44 +#define VMS_PI__take_sem_reqst_from( req ) req->semReqData
    7.45  
    7.46  
    7.47  /* This is for OS requests and VMS infrastructure requests, such as to create
    7.48 @@ -61,11 +77,25 @@
    7.49   */
    7.50  void inline
    7.51  VMS_PI__handle_VMSSemReq( VMSReqst *req, SlaveVP *requestingSlv, void *semEnv,
    7.52 -                       ResumeSlvFnPtr resumeSlvFnPtr )
    7.53 - { VMSSemReq     *semReq;
    7.54 -   IntervalProbe *newProbe;
    7.55 +                       ResumeSlvFnPtr resumeFn )
    7.56 + { VMSSemReq *semReq;
    7.57  
    7.58 -   semReq = req->semReqData;
    7.59 +   semReq = VMS_PI__take_sem_reqst_from(req);
    7.60 +   if( semReq == NULL ) return;
    7.61 +   switch( semReq->reqType )  //sem handlers are all in other file
    7.62 +    {
    7.63 +      case make_probe:      handleMakeProbe(   semReq, semEnv, resumeFn);
    7.64 +         break;
    7.65 +      case throw_excp:  handleThrowException(  semReq, semEnv, resumeFn);
    7.66 +         break;
    7.67 +    }
    7.68 + }
    7.69 +
    7.70 +/*
    7.71 + */
    7.72 +void inline
    7.73 +handleMakeProbe( VMSSemReq *semReq, void *semEnv, ResumeSlvFnPtr resumeFn )
    7.74 + { IntervalProbe *newProbe;
    7.75  
    7.76     newProbe          = VMS_int__malloc( sizeof(IntervalProbe) );
    7.77     newProbe->nameStr = VMS_int__strDup( semReq->nameStr );
    7.78 @@ -74,23 +104,22 @@
    7.79  
    7.80        //This runs in masterVP, so no race-condition worries
    7.81     newProbe->probeID =
    7.82 -             addToDynArray( newProbe, _VMSMasterEnv->dynIntervalProbesInfo );
    7.83 +            addToDynArray( newProbe, _VMSMasterEnv->dynIntervalProbesInfo );
    7.84  
    7.85 -   requestingSlv->dataRetFromReq = newProbe;
    7.86 +   semReq->requestingSlv->dataRetFromReq = newProbe;
    7.87  
    7.88 -   (*resumeSlvFnPtr)( requestingSlv, semEnv );
    7.89 +   //This in inside VMS, while resume_slaveVP fn is inside language, so pass
    7.90 +   // pointer from lang to here, then call it.
    7.91 +   (*resumeFn)( semReq->requestingSlv, semEnv );
    7.92   }
    7.93  
    7.94 -
    7.95 -/*Later, improve this -- for now, just exits the application after printing
    7.96 - * the error message.
    7.97 - */
    7.98 -void
    7.99 -VMS_PI__throw_exception( char *msgStr, SlaveVP *reqstSlv, VMSExcp *excpData )
   7.100 +void inline
   7.101 +handleThrowException( VMSSemReq *semReq, void *semEnv, ResumeSlvFnPtr resumeFn )
   7.102   {
   7.103 -   printf("%s",msgStr);
   7.104 -   fflush(stdin);
   7.105 -   exit(1);
   7.106 +   VMS_int__throw_exception(  semReq->msgStr, semReq->requestingSlv, semReq->exceptionData );
   7.107 +   
   7.108 +   (*resumeFn)( semReq->requestingSlv, semEnv );
   7.109   }
   7.110  
   7.111  
   7.112 +
     8.1 --- a/VMS__WL.c	Fri May 25 12:23:03 2012 +0200
     8.2 +++ b/VMS__WL.c	Wed May 30 14:23:47 2012 -0700
     8.3 @@ -124,6 +124,9 @@
     8.4   }
     8.5  
     8.6  
     8.7 +/*May 2012 Not sure what this is..  looks like old idea for VMS semantic
     8.8 + * request
     8.9 + */
    8.10  inline void
    8.11  VMS_WL__send_VMSSem_request( void *semReqData, SlaveVP *callingSlv )
    8.12   { VMSReqst req;
    8.13 @@ -136,4 +139,21 @@
    8.14     VMS_int__suspend_slaveVP_and_send_req( callingSlv );
    8.15   }
    8.16  
    8.17 +/*May 2012
    8.18 + *To throw exception from wrapper lib or application, first turn
    8.19 + * it into a request, then send the request
    8.20 + */
    8.21 +VMS_WL__throw_exception( char *msgStr, SlaveVP *reqstSlv,  VMSExcp *excpData )
    8.22 + { VMSReqst req;
    8.23 +   VMSSemReq semReq;
    8.24  
    8.25 +   req.reqType         = VMSSemantic;
    8.26 +   req.semReqData      = &semReq;
    8.27 +   req.nextReqst       = reqstSlv->requests; //gab any other preceeding 
    8.28 +   reqstSlv->requests   = &req;
    8.29 +
    8.30 +   semReq.msgStr        = msgStr;
    8.31 +   semReq.exceptionData = excpData;
    8.32 +   
    8.33 +   VMS_int__suspend_slaveVP_and_send_req( reqstSlv );
    8.34 + }
     9.1 --- a/VMS__int.c	Fri May 25 12:23:03 2012 +0200
     9.2 +++ b/VMS__int.c	Wed May 30 14:23:47 2012 -0700
     9.3 @@ -200,6 +200,18 @@
     9.4   }
     9.5  
     9.6  
     9.7 +/*Later, improve this -- for now, just exits the application after printing
     9.8 + * the error message.
     9.9 + */
    9.10 +void
    9.11 +VMS_int__throw_exception( char *msgStr, SlaveVP *reqstSlv, VMSExcp *excpData )
    9.12 + {
    9.13 +   printf("%s",msgStr);
    9.14 +   fflush(stdin);
    9.15 +   exit(1);
    9.16 + }
    9.17 +
    9.18 +
    9.19  inline char *
    9.20  VMS_int__strDup( char *str )
    9.21   { char *retStr;
    9.22 @@ -210,3 +222,67 @@
    9.23  
    9.24     return (char *)retStr;
    9.25   }
    9.26 +
    9.27 +
    9.28 +inline void
    9.29 +VMS_int__backoff_for_TooLongToGetLock( int32 numTriesToGetLock );
    9.30 +
    9.31 +inline void
    9.32 +VMS_int__get_master_lock()
    9.33 + { int32 *addrOfMasterLock;
    9.34 + 
    9.35 +   addrOfMasterLock = &(_VMSMasterEnv->masterLock);
    9.36 +
    9.37 +   int numTriesToGetLock = 0;
    9.38 +   int gotLock = 0;
    9.39 +   
    9.40 +            MEAS__Capture_Pre_Master_Lock_Point;
    9.41 +
    9.42 +   while( !gotLock ) //keep going until get master lock
    9.43 +    { 
    9.44 +      numTriesToGetLock++;   //if too many, means too much contention
    9.45 +      if( numTriesToGetLock > NUM_TRIES_BEFORE_DO_BACKOFF )
    9.46 +       { VMS_int__backoff_for_TooLongToGetLock( numTriesToGetLock );
    9.47 +       }
    9.48 +      if( numTriesToGetLock > MASTERLOCK_RETRIES_BEFORE_YIELD ) 
    9.49 +       { numTriesToGetLock = 0; 
    9.50 +         pthread_yield();
    9.51 +       }
    9.52 +   
    9.53 +         //try to get the lock
    9.54 +      gotLock = __sync_bool_compare_and_swap( addrOfMasterLock,                                              UNLOCKED, LOCKED );
    9.55 +    }
    9.56 +            MEAS__Capture_Post_Master_Lock_Point;
    9.57 + }
    9.58 +
    9.59 +/*Used by the backoff to pick a random amount of busy-wait.  Can't use the
    9.60 + * system rand because it takes much too long.
    9.61 + *Note, are passing pointers to the seeds, which are then modified
    9.62 + */
    9.63 +inline uint32_t
    9.64 +VMS_int__randomNumber()
    9.65 + {
    9.66 +	_VMSMasterEnv->seed1 = 36969 * (_VMSMasterEnv->seed1 & 65535) + 
    9.67 +                          (_VMSMasterEnv->seed1 >> 16);
    9.68 +	_VMSMasterEnv->seed2 = 18000 * (_VMSMasterEnv->seed2 & 65535) + 
    9.69 +                          (_VMSMasterEnv->seed2 >> 16);
    9.70 +	return (_VMSMasterEnv->seed1 << 16) + _VMSMasterEnv->seed2;
    9.71 + }
    9.72 +
    9.73 +
    9.74 +/*Busy-waits for a random number of cycles -- chooses number of cycles 
    9.75 + * differently than for the no-work backoff
    9.76 + */
    9.77 +inline void
    9.78 +VMS_int__backoff_for_TooLongToGetLock( int32 numTriesToGetLock )
    9.79 + { int32 i, waitIterations;
    9.80 +   volatile double fakeWorkVar; //busy-wait fake work
    9.81 +
    9.82 +   waitIterations = 
    9.83 +    VMS_int__randomNumber()% (numTriesToGetLock * GET_LOCK_BACKOFF_WEIGHT);   
    9.84 +   //addToHist( wait_iterations, coreLoopThdParams->wait_iterations_hist );
    9.85 +   for( i = 0; i < waitIterations; i++ )
    9.86 +    { fakeWorkVar += (fakeWorkVar + 32.0) / 2.0; //busy-wait
    9.87 +    }
    9.88 + }
    9.89 +
    10.1 --- a/VMS__startup_and_shutdown.c	Fri May 25 12:23:03 2012 +0200
    10.2 +++ b/VMS__startup_and_shutdown.c	Wed May 30 14:23:47 2012 -0700
    10.3 @@ -311,6 +311,8 @@
    10.4      }
    10.5     _VMSMasterEnv->masterVPs        = masterVPs;
    10.6     _VMSMasterEnv->masterLock       = UNLOCKED;
    10.7 +   _VMSMasterEnv->seed1 = rand()%1000; // init random number generator
    10.8 +   _VMSMasterEnv->seed2 = rand()%1000; // init random number generator
    10.9     _VMSMasterEnv->allAnimSlots    = allAnimSlots;
   10.10     _VMSMasterEnv->measHistsInfo = NULL; 
   10.11