Mercurial > cgi-bin > hgwebdir.cgi > VMS > VMS_Implementations > SSR_impls > SSR__MC_shared_impl
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)
