changeset 43:07fd95a5cd31 test_without_inline

Added NtoN construct -- but details of struct updates, aso not done yet
author Me@portablequad
date Tue, 06 Dec 2011 06:11:21 -0800
parents 4752161ff29d
children 0a77f80d11cf 90f38dca4132
files SSR_Request_Handlers.c SSR_lib.c
diffstat 2 files changed, 211 insertions(+), 3 deletions(-) [+]
line diff
     1.1 --- a/SSR_Request_Handlers.c	Tue Dec 06 05:13:00 2011 -0800
     1.2 +++ b/SSR_Request_Handlers.c	Tue Dec 06 06:11:21 2011 -0800
     1.3 @@ -64,7 +64,8 @@
     1.4  
     1.5  
     1.6  //===========================================================================
     1.7 -/*The semantic request has the receiving processor and the message type
     1.8 +/*SendType
     1.9 + *The semantic request has the receiving processor and the message type
    1.10   *
    1.11   *Note one value in this approach: without the extra VMS layer,
    1.12   * the send and receive would happen in real time instead of virtual time,
    1.13 @@ -146,6 +147,81 @@
    1.14      }
    1.15   }
    1.16  
    1.17 +/*Send NtoN
    1.18 + *
    1.19 + *For NtoN, the sender only specifies the setID, there is no receiving
    1.20 + * procr stated.
    1.21 + * 
    1.22 + *The semantic request has the SetID and ptr to message
    1.23 + *
    1.24 + *Each setID has its own entry in a circular buffer.  Collect the sends in
    1.25 + * a linked list inside the entry.
    1.26 + *Waiting receives also collect inside the entry -- if one there, pair
    1.27 + * it with this send.
    1.28 + *Sends can either be send-and-go or wait-for-receive.  But receives must
    1.29 + * wait for a send to pair with.
    1.30 + * 
    1.31 + *Q: how know when done with particular setID?
    1.32 + *A: requires info from app -- either register the ID w/num in set, or do a
    1.33 + *   start-end to bound it.
    1.34 + *<Dec 2011> try first with register the number in set -- means have to decr
    1.35 + * number of sends remaining, and if has a waiting receive, incr number of
    1.36 + * receives.
    1.37 + *
    1.38 + *When register a setID, state num in set, and state whether sends to that
    1.39 + * set wait to be paired with receive, or just resume right away
    1.40 + */
    1.41 +void
    1.42 +handleSendNtoN( SSRSemReq *semReq, SSRSemEnv *semEnv )
    1.43 + { SSRSemReq    *sendingReq, receiveReq;
    1.44 +   int32         setID;
    1.45 +   NtoNEntry    *entry;
    1.46 +   MovingWindow *movingWindow = semEnv->movingWindow;
    1.47 + 
    1.48 +   setID        = semReq->setID;
    1.49 +
    1.50 +   entry        = (NtoNEntry *)giveWindowEntry( setID, movingWindow );
    1.51 +   if( entry == NULL ) ERROR(); //prints this file & line
    1.52 +   
    1.53 +      //safety check: make sure number of sends not greater than expected
    1.54 +   entry->numSent += 1;
    1.55 +   if( entry->numSend > entry->numInSet ) ERROR(); //prints this file & line
    1.56 +   
    1.57 +      //check for waiting receivers
    1.58 +   receiveReq = entry->waitingReceives;
    1.59 +   if( receiveReq != NULL )
    1.60 +    { entry->waitingReceives = entry->waitingReceives->nextWaitingReq;
    1.61 +      entry->numReceived += 1;
    1.62 +      if( entry->numReceived == entry->numInSet ) 
    1.63 +         retireSet( setID, movingWindow ); //mark unused so can adv window
    1.64 +      
    1.65 +         //bring both processors back from suspend
    1.66 +      resume_procr( sendingReq->sendPr,    semEnv );
    1.67 +      resume_procr( receiveReq->receivePr, semEnv );
    1.68 +      
    1.69 +         //done
    1.70 +      return;
    1.71 +    }
    1.72 +   
    1.73 +      //Were no waiting receivers, so add this send to list
    1.74 +      // but how deps on whether sender waits or goes
    1.75 +   if( entry->senderDoesWait )
    1.76 +    { sendingReq->nextWaitingReq = entry->waitingSends;
    1.77 +      entry->waitingSends = sendingReq;
    1.78 +      return;  //sender waits, so it stays suspended, so nothing left to do
    1.79 +    }
    1.80 +   else
    1.81 +    {    //sender doesn't wait, so semReq, which is on stack, will disappear
    1.82 +         // so clone it before adding it to list, then resume sender
    1.83 +      SSRSemReq *clonedReq = cloneReq( semReq );
    1.84 +      clonedReq->nextWaitingReq = entry->waitingSends;
    1.85 +      entry->waitingSends = clonedReq;
    1.86 +      resume_procr( sendingReq->sendPr,    semEnv );
    1.87 +      return;
    1.88 +    }
    1.89 +//         DEBUG2( dbgRqstHdlr, ": %d, %d  |  ", , )
    1.90 + }
    1.91 +
    1.92  
    1.93  /*Looks like can make single handler for both sends..
    1.94   */
    1.95 @@ -235,6 +311,75 @@
    1.96   
    1.97   }
    1.98  
    1.99 +/*Receive NtoN
   1.100 + *
   1.101 + *For NtoN, the receiver only specifies the setID
   1.102 + * 
   1.103 + *The semantic request has the SetID and returns with ptr to message
   1.104 + *
   1.105 + *Each setID has its own entry in a circular buffer.  Collect the receives in
   1.106 + * a linked list inside the entry.
   1.107 + *Waiting sends also collect inside the entry -- if one there, pair
   1.108 + * it with this receive.
   1.109 + *Receives must wait for a send to pair with.
   1.110 + *  
   1.111 + *Q: how know when done with particular setID?
   1.112 + *A: requires info from app -- either register the ID w/num in set, or do a
   1.113 + *   start-end to bound it.
   1.114 + *<Dec 2011> try first with register the number in set -- means have to decr
   1.115 + * number of sends remaining, and if has a waiting receive, incr number of
   1.116 + * receives.
   1.117 + *
   1.118 + *When register a setID, state num in set, and state whether sends to that
   1.119 + * set wait to be paired with receive, or just resume right away
   1.120 + * 
   1.121 + *So, in this receive, if has a waiting send, check if it's the last
   1.122 + * receive of set.
   1.123 + *Also, either way, if the sending VPs don't wait to be paired, then any
   1.124 + * send-request that's waiting was cloned, so has to be freed.
   1.125 + */
   1.126 +void
   1.127 +handleReceiveNtoN( SSRSemReq *semReq, SSRSemEnv *semEnv )
   1.128 + { SSRSemReq    *sendReq, receiveReq = semReq;
   1.129 +   int32         setID;
   1.130 +   NtoNEntry    *entry;
   1.131 +   MovingWindow *movingWindow = semEnv->movingWindow;
   1.132 + 
   1.133 +   setID        = semReq->setID;
   1.134 +
   1.135 +   entry        = (NtoNEntry *)giveWindowEntry( setID, movingWindow );
   1.136 +   if( entry == NULL ) ERROR(); //prints this file & line
   1.137 +      
   1.138 +      //check for waiting sends
   1.139 +   sendReq = entry->waitingSends;
   1.140 +   if( sendReq != NULL )
   1.141 +    {    //remove the waiting send from list
   1.142 +      entry->waitingSends = sendReq->nextWaitingReq;
   1.143 +         //means this receive matched, so check if last in set
   1.144 +      entry->numReceived += 1;
   1.145 +      if( entry->numReceived == entry->numInSet ) 
   1.146 +         retireSet( setID, movingWindow ); //mark unused so can adv window
   1.147 +
   1.148 +         //check whether sending VP is waiting or not
   1.149 +      if( entry->senderDoesWait )
   1.150 +       {    //bring both processors back from suspend
   1.151 +         resume_procr( sendReq->sendPr,    semEnv );
   1.152 +         resume_procr( receiveReq->receivePr, semEnv );
   1.153 +       }
   1.154 +      else
   1.155 +       { VMSPlugin__free( sendReq );
   1.156 +         resume_procr( receiveReq->receivePr, semEnv );         
   1.157 +       }
   1.158 +         //done
   1.159 +      return;
   1.160 +    }
   1.161 +   
   1.162 +      //Was no waiting send, so add this to waiting receive list
   1.163 +   receiveReq->nextWaitingReq = entry->waitingReceives;
   1.164 +   entry->waitingReceives = receiveReq;
   1.165 +   return;
   1.166 +//         DEBUG2( dbgRqstHdlr, ": %d, %d  |  ", , )
   1.167 + }
   1.168  
   1.169  void
   1.170  handleReceiveType( SSRSemReq *semReq, SSRSemEnv *semEnv)
     2.1 --- a/SSR_lib.c	Tue Dec 06 05:13:00 2011 -0800
     2.2 +++ b/SSR_lib.c	Tue Dec 06 06:11:21 2011 -0800
     2.3 @@ -269,7 +269,7 @@
     2.4  
     2.5  /*
     2.6   */
     2.7 -  VirtProcr *
     2.8 +VirtProcr *
     2.9  SSR__create_procr_with( VirtProcrFnPtr fnPtr,   void *initData,
    2.10                          VirtProcr *creatingPr )
    2.11   { SSRSemReq reqData;
    2.12 @@ -288,7 +288,7 @@
    2.13     return creatingPr->dataRetFromReq;
    2.14   }
    2.15  
    2.16 -  VirtProcr *
    2.17 +VirtProcr *
    2.18  SSR__create_procr_with_affinity( VirtProcrFnPtr fnPtr, void *initData,
    2.19                          VirtProcr *creatingPr,  int32  coreToScheduleOnto )
    2.20   { SSRSemReq  reqData;
    2.21 @@ -394,6 +394,69 @@
    2.22  
    2.23  //===========================================================================
    2.24  
    2.25 +/*NtoN register a new set
    2.26 + * 
    2.27 + *Have to know when safe to retire a given setID, and also easier if make the
    2.28 + * wait-vs-go behavior of sender be defined by the set.  So, before doing
    2.29 + * and sends, perform this call to 'register' the set's ID.
    2.30 + *
    2.31 + *Give the call the setID, the number in the set, and TRUE if senders wait
    2.32 + * for a receive, else FALSE
    2.33 + */
    2.34 +void
    2.35 +SSR__register_NtoN_set( int32 setID, int32 numInSet, bool32 doesWait,
    2.36 +                        VirtProcr *animPr )
    2.37 + { SSRSemReq  reqData;
    2.38 +
    2.39 +   reqData.sendPr    = animPr;  //reuse field
    2.40 +   reqData.reqType   = register_NtoN;
    2.41 +   reqData.setID     = setID;
    2.42 +   reqData.numInSet  = numInSet;
    2.43 +   reqData.doesWait  = doesWait;
    2.44 +
    2.45 +   VMS__send_sem_request( &reqData, animPr );
    2.46 + }
    2.47 +
    2.48 +/*NtoN  send
    2.49 + *This construct doesn't specify a receiving processor, nor does it have the
    2.50 + * concept of a virtual physical communication channel.  Instead, the concept
    2.51 + * is of a set of things being sent, which are all received.  The set is
    2.52 + * unique within the computation.  The same line of code can be reused for
    2.53 + * multiple sets, by making the setID be a variable.
    2.54 + * 
    2.55 + *The benefit is in portability.  This construct specifies true
    2.56 + * non-determinism in a logically safe way, and with a pattern that exists
    2.57 + * directly in the problem being solved.
    2.58 + *For example, accumulation of results in
    2.59 + * matrix multiply has N result sends for a particular input pair, which all
    2.60 + * are accumulated into a particular result matrix.  Each input pair
    2.61 + * is a different set.
    2.62 + *The results gathering can be split amongst a variable
    2.63 + * number of processors, each owning a portion of the results matrix)
    2.64 + * 
    2.65 + *<Dec 2011> At some point, the setID can be made hierarchical.  Also, the
    2.66 + * creation of processors can be put under scheduler control with query-
    2.67 + * answer pattern for number to create.
    2.68 + * 
    2.69 + *The sending VP either waits to be matched to a receiver, or else just
    2.70 + * resumes right away.  The behavior is fixed when the setID is registered.
    2.71 + */
    2.72 +void
    2.73 +SSR__send_one_of_NtoN_set( VirtProcr *sendPr, void *msg, int setID )
    2.74 + { SSRSemReq  reqData;
    2.75 +
    2.76 +   reqData.sendPr    = sendPr;
    2.77 +   reqData.reqType   = send_NtoN;
    2.78 +   reqData.setID     = setID;
    2.79 +   reqData.msg       = msg;
    2.80 +   reqData.nextWaitingReq = NULL;
    2.81 +
    2.82 +   VMS__send_sem_request( &reqData, sendPr );
    2.83 +
    2.84 +      //When come back from suspend, no longer own data reachable from msg
    2.85 + }
    2.86 +
    2.87 +
    2.88  void
    2.89  SSR__send_of_type_to( VirtProcr *sendPr, void *msg, const int type,
    2.90                          VirtProcr *receivePr)