changeset 21:ad29ff7a0209 test_without_inline

Buggy version of singltons -- data plus Fn singletons now -- about to fix
author Me
date Sat, 13 Nov 2010 14:38:33 -0800
parents 562e68094af7
children fef69b887df4
files SSR.h SSR_PluginFns.c SSR_Request_Handlers.c SSR_Request_Handlers.h SSR_lib.c
diffstat 5 files changed, 245 insertions(+), 32 deletions(-) [+]
line diff
     1.1 --- a/SSR.h	Fri Nov 12 08:43:20 2010 -0800
     1.2 +++ b/SSR.h	Sat Nov 13 14:38:33 2010 -0800
     1.3 @@ -27,6 +27,23 @@
     1.4  /*Semantic layer-specific data sent inside a request from lib called in app
     1.5   * to request handler called in MasterLoop
     1.6   */
     1.7 +
     1.8 +typedef struct
     1.9 + {
    1.10 +   VirtProcr      *VPCurrentlyExecuting;
    1.11 +   PrivQueueStruc *waitingVPQ;
    1.12 + }
    1.13 +SSRTrans;
    1.14 +
    1.15 +typedef struct
    1.16 + {
    1.17 +   int32           hasBeenStarted;
    1.18 +   int32           hasFinished;
    1.19 +   void           *endInstrAddr;
    1.20 +   PrivQueueStruc *waitQ;
    1.21 + }
    1.22 +SSRSingleton;
    1.23 +
    1.24  enum SSRReqType
    1.25   {
    1.26     send_type = 1,
    1.27 @@ -38,7 +55,10 @@
    1.28     transfer_out,
    1.29     malloc_req,
    1.30     free_req,
    1.31 -   singleton,
    1.32 +   singleton_fn_start,
    1.33 +   singleton_fn_end,
    1.34 +   singleton_data_start,
    1.35 +   singleton_data_end,
    1.36     atomic,
    1.37     trans_start,
    1.38     trans_end
    1.39 @@ -60,7 +80,7 @@
    1.40     void              *ptrToFree;
    1.41  
    1.42     int32              singletonID;
    1.43 -   void              *endJumpPt;
    1.44 +   SSRSingleton     **singletonAddr;
    1.45  
    1.46     PtrToAtomicFn      fnToExecInMaster;
    1.47     void              *dataForFn;
    1.48 @@ -72,13 +92,6 @@
    1.49  
    1.50  typedef struct
    1.51   {
    1.52 -   VirtProcr      *VPCurrentlyExecuting;
    1.53 -   PrivQueueStruc *waitingVPQ;
    1.54 - }
    1.55 -SSRTrans;
    1.56 -
    1.57 -typedef struct
    1.58 - {
    1.59     PrivQueueStruc **readyVPQs;
    1.60     HashTable       *commHashTbl;
    1.61     int32            numVirtPr;
    1.62 @@ -86,7 +99,7 @@
    1.63     int32            primitiveStartTime;
    1.64  
    1.65                         //fix limit on num with dynArray
    1.66 -   int32            singletonHasBeenExecutedFlags[NUM_STRUCS_IN_SEM_ENV];
    1.67 +   SSRSingleton     fnSingletons[NUM_STRUCS_IN_SEM_ENV];
    1.68     SSRTrans         transactionStrucs[NUM_STRUCS_IN_SEM_ENV];
    1.69   }
    1.70  SSRSemEnv;
    1.71 @@ -187,8 +200,16 @@
    1.72  
    1.73  //======================= Concurrency Stuff ======================
    1.74  void
    1.75 -SSR__start_singleton( int32 singletonID, void *endSingletonLabelAddr,
    1.76 -                      VirtProcr *animPr );
    1.77 +SSR__start_fn_singleton( int32 singletonID, VirtProcr *animPr );
    1.78 +
    1.79 +void
    1.80 +SSR__end_fn_singleton( int32 singletonID, VirtProcr *animPr );
    1.81 +
    1.82 +void
    1.83 +SSR__start_data_singleton( SSRSingleton **singeltonAddr, VirtProcr *animPr );
    1.84 +
    1.85 +void
    1.86 +SSR__end_data_singleton( SSRSingleton **singletonAddr, VirtProcr *animPr );
    1.87  
    1.88  void
    1.89  SSR__animate_short_fn_in_isolation( PtrToAtomicFn ptrToFnToExecInMaster,
     2.1 --- a/SSR_PluginFns.c	Fri Nov 12 08:43:20 2010 -0800
     2.2 +++ b/SSR_PluginFns.c	Sat Nov 13 14:38:33 2010 -0800
     2.3 @@ -114,7 +114,13 @@
     2.4           break;
     2.5        case free_req:        handleFree(         semReq, reqPr, semEnv);
     2.6           break;
     2.7 -      case singleton:       handleSingleton(    semReq, reqPr, semEnv);
     2.8 +      case singleton_fn_start:  handleStartFnSingleton(semReq, reqPr, semEnv);
     2.9 +         break;
    2.10 +      case singleton_fn_end:    handleEndFnSingleton(  semReq, reqPr, semEnv);
    2.11 +         break;
    2.12 +      case singleton_data_start:handleStartDataSingleton(semReq,reqPr,semEnv);
    2.13 +         break;
    2.14 +      case singleton_data_end:  handleEndDataSingleton(semReq, reqPr, semEnv);
    2.15           break;
    2.16        case atomic:          handleAtomic(       semReq, reqPr, semEnv);
    2.17           break;
     3.1 --- a/SSR_Request_Handlers.c	Fri Nov 12 08:43:20 2010 -0800
     3.2 +++ b/SSR_Request_Handlers.c	Sat Nov 13 14:38:33 2010 -0800
     3.3 @@ -371,17 +371,100 @@
     3.4  /*Uses ID as index into array of flags.  If flag already set, resumes from
     3.5   * end-label.  Else, sets flag and resumes normally.
     3.6   */
     3.7 -void
     3.8 -handleSingleton( SSRSemReq *semReq, VirtProcr *requestingPr,
     3.9 -                 SSRSemEnv *semEnv )
    3.10 +void inline
    3.11 +handleStartSingleton_helper( SSRSingleton *singleton, VirtProcr *reqstingPr,
    3.12 +                             SSRSemEnv    *semEnv )
    3.13   {
    3.14 -   if( semEnv->singletonHasBeenExecutedFlags[ semReq->singletonID ] )
    3.15 -      requestingPr->nextInstrPt = semReq->endJumpPt;
    3.16 +   if( singleton->hasFinished )
    3.17 +    {    //the code that sets the flag to true first sets the end instr addr
    3.18 +      reqstingPr->dataRetFromReq = singleton->endInstrAddr;
    3.19 +      resume_procr( reqstingPr, semEnv );
    3.20 +      return;
    3.21 +    }
    3.22 +   else if( singleton->hasBeenStarted )
    3.23 +    {    //singleton is in-progress in a diff slave, so wait for it to finish
    3.24 +      writePrivQ(reqstingPr, singleton->waitQ );
    3.25 +      return;
    3.26 +    }
    3.27     else
    3.28 -      semEnv->singletonHasBeenExecutedFlags[ semReq->singletonID ] = TRUE;
    3.29 +    {    //hasn't been started, so this is the first attempt at the singleton
    3.30 +      singleton->hasBeenStarted = TRUE;
    3.31 +      reqstingPr->dataRetFromReq = 0x0;
    3.32 +      resume_procr( reqstingPr, semEnv );
    3.33 +      return;
    3.34 +    }
    3.35 + }
    3.36 +void inline
    3.37 +handleStartFnSingleton( SSRSemReq *semReq, VirtProcr *requestingPr,
    3.38 +                      SSRSemEnv *semEnv )
    3.39 + { SSRSingleton *singleton;
    3.40 +
    3.41 +   singleton = &(semEnv->fnSingletons[ semReq->singletonID ]);
    3.42 +   handleStartSingleton_helper( singleton, requestingPr, semEnv );
    3.43 + }
    3.44 +void inline
    3.45 +handleStartDataSingleton( SSRSemReq *semReq, VirtProcr *requestingPr,
    3.46 +                      SSRSemEnv *semEnv )
    3.47 + { SSRSingleton *singleton;
    3.48 +
    3.49 +   if( *(semReq->singletonAddr) == NULL )
    3.50 +    { singleton                 = VMS__malloc( sizeof(SSRSingleton) );
    3.51 +      singleton->waitQ          = makeVMSPrivQ();
    3.52 +      singleton->endInstrAddr   = 0x0;
    3.53 +      singleton->hasBeenStarted = FALSE;
    3.54 +      singleton->hasFinished    = FALSE;
    3.55 +      *(semReq->singletonAddr)  = singleton;
    3.56 +    }
    3.57 +   else
    3.58 +      singleton = *(semReq->singletonAddr);
    3.59 +   handleStartSingleton_helper( singleton, requestingPr, semEnv );
    3.60 + }
    3.61 +
    3.62 +
    3.63 +void inline
    3.64 +handleEndSingleton_helper( SSRSingleton *singleton, VirtProcr *requestingPr,
    3.65 +                           SSRSemEnv    *semEnv )
    3.66 + { PrivQueueStruc *waitQ;
    3.67 +   int32           numWaiting, i;
    3.68 +   VirtProcr      *resumingPr;
    3.69 +
    3.70 +   if( singleton->hasFinished )
    3.71 +    { //by definition, only one slave should ever be able to run end singleton
    3.72 +      // so if this is true, is an error
    3.73 +      //VMS__throw_exception( "singleton code ran twice", requestingPr, NULL);
    3.74 +    }
    3.75 +
    3.76 +   singleton->hasFinished = TRUE;
    3.77 +   waitQ = singleton->waitQ;
    3.78 +   numWaiting = numInPrivQ( waitQ );
    3.79 +   for( i = 0; i < numWaiting; i++ )
    3.80 +    {    //they will resume inside start singleton, then jmp to end singleton
    3.81 +      resumingPr = readPrivQ( waitQ );
    3.82 +      resumingPr->dataRetFromReq = singleton->endInstrAddr;
    3.83 +      resume_procr( resumingPr, semEnv );
    3.84 +    }
    3.85  
    3.86     resume_procr( requestingPr, semEnv );
    3.87 - }
    3.88 +
    3.89 +}
    3.90 +void inline
    3.91 +handleEndFnSingleton( SSRSemReq *semReq, VirtProcr *requestingPr,
    3.92 +                        SSRSemEnv *semEnv )
    3.93 + {
    3.94 +   SSRSingleton   *singleton;
    3.95 +
    3.96 +   singleton = &(semEnv->fnSingletons[ semReq->singletonID ]);
    3.97 +   handleEndSingleton_helper( singleton, requestingPr, semEnv );
    3.98 +  }
    3.99 +void inline
   3.100 +handleEndDataSingleton( SSRSemReq *semReq, VirtProcr *requestingPr,
   3.101 +                        SSRSemEnv *semEnv )
   3.102 + {
   3.103 +   SSRSingleton   *singleton;
   3.104 +
   3.105 +   singleton = *(semReq->singletonAddr);
   3.106 +   handleEndSingleton_helper( singleton, requestingPr, semEnv );
   3.107 +  }
   3.108  
   3.109  
   3.110  /*This executes the function in the masterVP, take the function
     4.1 --- a/SSR_Request_Handlers.h	Fri Nov 12 08:43:20 2010 -0800
     4.2 +++ b/SSR_Request_Handlers.h	Sat Nov 13 14:38:33 2010 -0800
     4.3 @@ -40,8 +40,17 @@
     4.4  void
     4.5  handleAtomic( SSRSemReq *semReq, VirtProcr *requestingPr, SSRSemEnv *semEnv);
     4.6  void
     4.7 -handleSingleton( SSRSemReq *semReq, VirtProcr *requestingPr,
     4.8 -                 SSRSemEnv *semEnv );
     4.9 +handleStartFnSingleton( SSRSemReq *semReq, VirtProcr *reqstingPr,
    4.10 +                      SSRSemEnv *semEnv );
    4.11 +void
    4.12 +handleEndFnSingleton( SSRSemReq *semReq, VirtProcr *requestingPr,
    4.13 +                    SSRSemEnv *semEnv );
    4.14 +void
    4.15 +handleStartDataSingleton( SSRSemReq *semReq, VirtProcr *reqstingPr,
    4.16 +                      SSRSemEnv *semEnv );
    4.17 +void
    4.18 +handleEndDataSingleton( SSRSemReq *semReq, VirtProcr *requestingPr,
    4.19 +                    SSRSemEnv *semEnv );
    4.20  
    4.21  #endif	/* _SSR_REQ_H */
    4.22  
     5.1 --- a/SSR_lib.c	Fri Nov 12 08:43:20 2010 -0800
     5.2 +++ b/SSR_lib.c	Sat Nov 13 14:38:33 2010 -0800
     5.3 @@ -213,7 +213,7 @@
     5.4  
     5.5     for( coreIdx = 0; coreIdx < NUM_CORES; coreIdx++ )
     5.6      {
     5.7 -      readyVPQs[ coreIdx ] = makePrivQ();
     5.8 +      readyVPQs[ coreIdx ] = makeVMSPrivQ();
     5.9      }
    5.10     
    5.11     semanticEnv->readyVPQs = readyVPQs;
    5.12 @@ -228,8 +228,11 @@
    5.13     //semanticEnv->transactionStrucs = makeDynArrayInfo( );
    5.14     for( i = 0; i < NUM_STRUCS_IN_SEM_ENV; i++ )
    5.15      {
    5.16 -      semanticEnv->singletonHasBeenExecutedFlags[i] = FALSE;
    5.17 -      semanticEnv->transactionStrucs[i].waitingVPQ = makePrivQ();
    5.18 +      semanticEnv->fnSingletons[i].hasBeenStarted    = FALSE;
    5.19 +      semanticEnv->fnSingletons[i].hasFinished       = FALSE;
    5.20 +      semanticEnv->fnSingletons[i].endInstrAddr      = NULL;
    5.21 +      semanticEnv->fnSingletons[i].waitQ             = makeVMSPrivQ();
    5.22 +      semanticEnv->transactionStrucs[i].waitingVPQ = makeVMSPrivQ();
    5.23      }
    5.24   }
    5.25  
    5.26 @@ -285,7 +288,7 @@
    5.27    VirtProcr *
    5.28  SSR__create_procr_with_affinity( VirtProcrFnPtr fnPtr, void *initData,
    5.29                          VirtProcr *creatingPr,  int32  coreToScheduleOnto )
    5.30 - { SSRSemReq reqData;
    5.31 + { SSRSemReq  reqData;
    5.32  
    5.33        //the semantic request data is on the stack and disappears when this
    5.34        // call returns -- it's guaranteed to remain in the VP's stack for as
    5.35 @@ -297,6 +300,8 @@
    5.36     reqData.sendPr             = creatingPr;
    5.37  
    5.38     VMS__send_create_procr_req( &reqData, creatingPr );
    5.39 +
    5.40 +   return creatingPr->dataRetFromReq;
    5.41   }
    5.42  
    5.43  
    5.44 @@ -476,21 +481,110 @@
    5.45  
    5.46  //===========================================================================
    5.47  
    5.48 -/*Uses ID as index into array of flags.  If flag already set, resumes from
    5.49 - * end-label.  Else, sets flag and resumes normally.
    5.50 +/*A function singleton is a function whose body executes exactly once, on a
    5.51 + * single core, no matter how many times the fuction is called and no
    5.52 + * matter how many cores or the timing of cores calling it.
    5.53 + *
    5.54 + *A data singleton is a ticket attached to data.  That ticket can be used
    5.55 + * to get the data through the function exactly once, no matter how many
    5.56 + * times the data is given to the function, and no matter the timing of
    5.57 + * trying to get the data through from different cores.
    5.58 + */
    5.59 +
    5.60 +/*Fn singleton uses ID as index into array of singleton structs held in the
    5.61 + * semantic environment.
    5.62   */
    5.63  void
    5.64 -SSR__start_singleton( int32 singletonID, void *endSingletonLabelAddr,
    5.65 -                      VirtProcr *animPr )
    5.66 +SSR__start_fn_singleton( int32 singletonID,   VirtProcr *animPr )
    5.67   {
    5.68     SSRSemReq  reqData;
    5.69  
    5.70        //
    5.71 -   reqData.reqType     = singleton;
    5.72 +   reqData.reqType     = singleton_fn_start;
    5.73     reqData.singletonID = singletonID;
    5.74 -   reqData.endJumpPt   = endSingletonLabelAddr;
    5.75  
    5.76     VMS__send_sem_request( &reqData, animPr );
    5.77 +   if( animPr->dataRetFromReq ) //will be 0 or addr of label in end singleton
    5.78 +    {
    5.79 +      asm volatile("movl         %0,      %%eax;  \
    5.80 +                    jmp                  *%%eax"  \
    5.81 +      /* outputs */ :                             \
    5.82 +      /* inputs  */ : "g"(animPr->dataRetFromReq) \
    5.83 +      /* clobber */ : "memory", "%eax", "%ebx", "%ecx", "%edx","%edi","%esi"\
    5.84 +                   );
    5.85 +    }
    5.86 + }
    5.87 +
    5.88 +/*Data singleton hands addr of loc holding a pointer to a singleton struct.
    5.89 + * The start_data_singleton makes the structure and puts its addr into the
    5.90 + * location.
    5.91 + */
    5.92 +void
    5.93 +SSR__start_data_singleton( SSRSingleton **singletonAddr,  VirtProcr *animPr )
    5.94 + {
    5.95 +   SSRSemReq  reqData;
    5.96 +
    5.97 +      //
    5.98 +   reqData.reqType       = singleton_data_start;
    5.99 +   reqData.singletonAddr = singletonAddr;
   5.100 +
   5.101 +   VMS__send_sem_request( &reqData, animPr );
   5.102 +   if( animPr->dataRetFromReq ) //either 0 or addr of label in end singleton
   5.103 +    { animPr->procrID += 10000;
   5.104 +      asm volatile("movl         %0,      %%eax;  \
   5.105 +                    jmp                  *%%eax"  \
   5.106 +      /* outputs */ :                             \
   5.107 +      /* inputs  */ : "m"(animPr->dataRetFromReq) \
   5.108 +      /* clobber */ : "memory", "%eax", "%ebx", "%ecx", "%edx","%edi","%esi"\
   5.109 +                   );
   5.110 +    }
   5.111 + }
   5.112 +
   5.113 +/*Uses ID as index into array of flags.  If flag already set, resumes from
   5.114 + * end-label.  Else, sets flag and resumes normally.
   5.115 + *
   5.116 + *Note, this call cannot be inlined because the instr addr at the label
   5.117 + * inside is shared by all invocations of a given singleton ID.
   5.118 + */
   5.119 +void
   5.120 +SSR__end_fn_singleton( int32 singletonID, VirtProcr *animPr )
   5.121 + {
   5.122 +   SSRSemReq  reqData;
   5.123 +
   5.124 +      //don't need this addr until after at least one singleton has reached
   5.125 +      // this function
   5.126 +   SSRSemEnv *semEnv = VMS__give_sem_env_for( animPr );
   5.127 +   semEnv->fnSingletons[ singletonID].endInstrAddr = &&EndSingletonInstrAddr;
   5.128 +
   5.129 +   reqData.reqType     = singleton_fn_end;
   5.130 +   reqData.singletonID = singletonID;
   5.131 +
   5.132 +   VMS__send_sem_request( &reqData, animPr );
   5.133 +
   5.134 +EndSingletonInstrAddr:
   5.135 +   return;
   5.136 + }
   5.137 +
   5.138 +void
   5.139 +SSR__end_data_singleton(  SSRSingleton **singletonAddr, VirtProcr *animPr )
   5.140 + {
   5.141 +   SSRSemReq  reqData;
   5.142 +
   5.143 +      //don't need this addr until after singleton struct has reached
   5.144 +      // this function for first time
   5.145 +//   write_return_addr_into_singleton( (*(singletonAddr))->endInstrAddr );
   5.146 +   (*(singletonAddr))->endInstrAddr =  &&EndDataSingletonInstrAddr;
   5.147 +
   5.148 +   reqData.reqType     = singleton_data_end;
   5.149 +   reqData.singletonAddr = singletonAddr;
   5.150 +
   5.151 +   VMS__send_sem_request( &reqData, animPr );
   5.152 +   printf("foo");
   5.153 +   return;
   5.154 +EndDataSingletonInstrAddr:
   5.155 +   printf("bar");
   5.156 +   animPr->procrID += 2000;
   5.157 +   return;
   5.158   }
   5.159  
   5.160  /*This executes the function in the masterVP, so it executes in isolation