Mercurial > cgi-bin > hgwebdir.cgi > VMS > VMS_Implementations > SSR_impls > SSR__MC_shared_impl
changeset 17:bf57b83019e5
Added atomic fn exec, singleton, trans start and end and fixed bus (contd)
Fixed double-free of waiting requests bug
Fixed place didn't clone in request handling
Changed malloc and free handler prototypes
author | Me |
---|---|
date | Tue, 02 Nov 2010 16:57:45 -0700 |
parents | 6c6d7fbd7e25 |
children | cee3eecc5c22 |
files | SSR.h SSR_PluginFns.c SSR_Request_Handlers.c SSR_Request_Handlers.h SSR_lib.c |
diffstat | 5 files changed, 687 insertions(+), 248 deletions(-) [+] |
line diff
1.1 --- a/SSR.h Thu Oct 14 17:06:28 2010 -0700 1.2 +++ b/SSR.h Tue Nov 02 16:57:45 2010 -0700 1.3 @@ -13,10 +13,17 @@ 1.4 #include "VMS/Hash_impl/PrivateHash.h" 1.5 #include "VMS/VMS.h" 1.6 1.7 + 1.8 +//=========================================================================== 1.9 + 1.10 +#define NUM_STRUCS_IN_SEM_ENV 1000 1.11 + 1.12 +//=========================================================================== 1.13 /*This header defines everything specific to the SSR semantic plug-in 1.14 */ 1.15 typedef struct _SSRSemReq SSRSemReq; 1.16 - 1.17 +typedef void (*PtrToAtomicFn ) ( void * ); //executed atomically in master 1.18 +//=========================================================================== 1.19 1.20 /*Semantic layer-specific data sent inside a request from lib called in app 1.21 * to request handler called in MasterLoop 1.22 @@ -29,19 +36,48 @@ 1.23 receive_type, // and receive_any first of the receives -- Handlers 1.24 receive_from_to,// rely upon this ordering of enum 1.25 transfer_to, 1.26 - transfer_out 1.27 + transfer_out, 1.28 + malloc_req, 1.29 + free_req, 1.30 + singleton, 1.31 + atomic, 1.32 + trans_start, 1.33 + trans_end 1.34 }; 1.35 1.36 struct _SSRSemReq 1.37 { enum SSRReqType reqType; 1.38 - VirtProcr *sendPr; 1.39 - VirtProcr *receivePr; 1.40 - int32 msgType; 1.41 - void *msg; 1.42 + VirtProcr *sendPr; 1.43 + VirtProcr *receivePr; 1.44 + int32 msgType; 1.45 + void *msg; 1.46 SSRSemReq *nextReqInHashEntry; 1.47 + 1.48 + void *initData; 1.49 + VirtProcrFnPtr fnPtr; 1.50 + int32 coreToScheduleOnto; 1.51 + 1.52 + int32 sizeToMalloc; 1.53 + void *ptrToFree; 1.54 + 1.55 + int32 singletonID; 1.56 + void *endJumpPt; 1.57 + 1.58 + PtrToAtomicFn fnToExecInMaster; 1.59 + void *dataForFn; 1.60 + 1.61 + int32 transID; 1.62 } 1.63 /* SSRSemReq */; 1.64 1.65 + 1.66 +typedef struct 1.67 + { 1.68 + VirtProcr *VPCurrentlyExecuting; 1.69 + PrivQueueStruc *waitingVPQ; 1.70 + } 1.71 +SSRTrans; 1.72 + 1.73 typedef struct 1.74 { 1.75 PrivQueueStruc **readyVPQs; 1.76 @@ -49,10 +85,28 @@ 1.77 int32 numVirtPr; 1.78 int32 nextCoreToGetNewPr; 1.79 int32 primitiveStartTime; 1.80 + 1.81 + //fix limit on num with dynArray 1.82 + int32 singletonHasBeenExecutedFlags[NUM_STRUCS_IN_SEM_ENV]; 1.83 + SSRTrans transactionStrucs[NUM_STRUCS_IN_SEM_ENV]; 1.84 } 1.85 SSRSemEnv; 1.86 1.87 1.88 +typedef struct _TransListElem TransListElem; 1.89 +struct _TransListElem 1.90 + { 1.91 + int32 transID; 1.92 + TransListElem *nextTrans; 1.93 + }; 1.94 + 1.95 +typedef struct 1.96 + { 1.97 + int32 highestTransEntered; 1.98 + TransListElem *lastTransEntered; 1.99 + } 1.100 +SSRSemData; 1.101 + 1.102 //=========================================================================== 1.103 1.104 void 1.105 @@ -70,6 +124,9 @@ 1.106 int32 1.107 SSR__giveIdealNumWorkUnits(); 1.108 1.109 +int32 1.110 +SSR__give_number_of_cores_to_schedule_onto(); 1.111 + 1.112 //======================= 1.113 1.114 void 1.115 @@ -84,12 +141,19 @@ 1.116 SSR__create_procr_with( VirtProcrFnPtr fnPtr, void *initData, 1.117 VirtProcr *creatingPr ); 1.118 1.119 +inline VirtProcr * 1.120 +SSR__create_procr_with_affinity( VirtProcrFnPtr fnPtr, void *initData, 1.121 + VirtProcr *creatingPr, int32 coreToScheduleOnto); 1.122 + 1.123 void 1.124 SSR__dissipate_procr( VirtProcr *procrToDissipate ); 1.125 1.126 //======================= 1.127 void * 1.128 -SSR__malloc_size_to( int numBytes, VirtProcr *ownerPr ); 1.129 +SSR__malloc_to( int numBytes, VirtProcr *ownerPr ); 1.130 + 1.131 +void 1.132 +SSR__free( void *ptrToFree, VirtProcr *owningPr ); 1.133 1.134 void 1.135 SSR__transfer_ownership_of_from_to( void *data, VirtProcr *oldOwnerPr, 1.136 @@ -121,10 +185,20 @@ 1.137 SSR__receive_from_to( VirtProcr *sendPr, VirtProcr *receivePr ); 1.138 1.139 1.140 -//======================= 1.141 +//======================= Concurrency Stuff ====================== 1.142 +void 1.143 +SSR__start_singleton( int32 singletonID, void *endSingletonLabelAddr, 1.144 + VirtProcr *animPr ); 1.145 1.146 void 1.147 -SSR__free_semantic_request( SSRSemReq *semReq ); 1.148 +SSR__animate_short_fn_in_isolation( PtrToAtomicFn ptrToFnToExecInMaster, 1.149 + void *data, VirtProcr *animPr ); 1.150 + 1.151 +void 1.152 +SSR__start_transaction( int32 transactionID, VirtProcr *animPr ); 1.153 + 1.154 +void 1.155 +SSR__end_transaction( int32 transactionID, VirtProcr *animPr ); 1.156 1.157 1.158 //========================= Internal use only =============================
2.1 --- a/SSR_PluginFns.c Thu Oct 14 17:06:28 2010 -0700 2.2 +++ b/SSR_PluginFns.c Tue Nov 02 16:57:45 2010 -0700 2.3 @@ -6,13 +6,49 @@ 2.4 2.5 #include <stdio.h> 2.6 #include <stdlib.h> 2.7 -#include <malloc.h> 2.8 2.9 #include "VMS/Queue_impl/PrivateQueue.h" 2.10 #include "SSR.h" 2.11 #include "SSR_Request_Handlers.h" 2.12 2.13 +//=========================== Local Fn Prototypes =========================== 2.14 +void inline 2.15 +resumePr( VirtProcr *procr, SSRSemEnv *semEnv ); 2.16 2.17 +void inline 2.18 +handleSemReq( VMSReqst *req, VirtProcr *requestingPr, SSRSemEnv *semEnv ); 2.19 + 2.20 +void 2.21 +handleDissipate( VirtProcr *requestingPr, SSRSemEnv *semEnv ); 2.22 + 2.23 +void 2.24 +handleCreate( VMSReqst *req, VirtProcr *requestingPr, SSRSemEnv *semEnv ); 2.25 + 2.26 + 2.27 +//============================== Scheduler ================================== 2.28 +// 2.29 +/*For SSR, scheduling a slave simply takes the next work-unit off the 2.30 + * ready-to-go work-unit queue and assigns it to the slaveToSched. 2.31 + *If the ready-to-go work-unit queue is empty, then nothing to schedule 2.32 + * to the slave -- return FALSE to let Master loop know scheduling that 2.33 + * slave failed. 2.34 + */ 2.35 +VirtProcr * 2.36 +SSR__schedule_virt_procr( void *_semEnv, int coreNum ) 2.37 + { VirtProcr *schedPr; 2.38 + SSRSemEnv *semEnv; 2.39 + 2.40 + semEnv = (SSRSemEnv *)_semEnv; 2.41 + 2.42 + schedPr = readPrivQ( semEnv->readyVPQs[coreNum] ); 2.43 + //Note, using a non-blocking queue -- it returns NULL if queue empty 2.44 + 2.45 + return( schedPr ); 2.46 + } 2.47 + 2.48 + 2.49 +//=========================== Request Handler ============================= 2.50 +// 2.51 /*Will get requests to send, to receive, and to create new processors. 2.52 * Upon send, check the hash to see if a receive is waiting. 2.53 * Upon receive, check hash to see if a send has already happened. 2.54 @@ -27,99 +63,132 @@ 2.55 SSR__Request_Handler( VirtProcr *requestingPr, void *_semEnv ) 2.56 { SSRSemEnv *semEnv; 2.57 VMSReqst *req; 2.58 - SSRSemReq *semReq; 2.59 2.60 semEnv = (SSRSemEnv *)_semEnv; 2.61 2.62 - req = VMS__take_top_request_from( requestingPr ); 2.63 - 2.64 + req = VMS__take_next_request_out_of( requestingPr ); 2.65 + 2.66 while( req != NULL ) 2.67 { 2.68 - if( VMS__isSemanticReqst( req ) ) 2.69 - { 2.70 - semReq = VMS__take_sem_reqst_from( req ); 2.71 - if( semReq == NULL ) goto DoneHandlingReqst; 2.72 - switch( semReq->reqType ) 2.73 - { 2.74 - case send_type: handleSendType( semReq, semEnv); 2.75 - break; 2.76 - case send_from_to: handleSendFromTo( semReq, semEnv); 2.77 - break; 2.78 - case receive_type: handleReceiveType( semReq, semEnv); 2.79 - break; 2.80 - case receive_from_to: handleReceiveFromTo(semReq, semEnv); 2.81 - break; 2.82 - case transfer_to: handleTransferTo( semReq, semEnv); 2.83 - SSR__free_semantic_request( semReq ); 2.84 - break; 2.85 - case transfer_out: handleTransferOut( semReq, semEnv); 2.86 - SSR__free_semantic_request( semReq ); 2.87 - break; 2.88 - } 2.89 - //NOTE: freeing semantic request data strucs handled inside these 2.90 + switch( req->reqType ) 2.91 + { case semantic: handleSemReq( req, requestingPr, semEnv); 2.92 + break; 2.93 + case createReq: handleCreate( req, requestingPr, semEnv); 2.94 + break; 2.95 + case dissipate: handleDissipate( requestingPr, semEnv); 2.96 + break; 2.97 + case VMSSemantic: VMS__handle_VMSSemReq(req, requestingPr, semEnv, 2.98 + &resumePr); 2.99 + break; 2.100 + default: 2.101 + break; 2.102 } 2.103 - else if( VMS__isCreateReqst( req ) ) //only plugin can add to ready Q 2.104 - { VirtProcr * 2.105 - newPr = (VirtProcr *)req->semReqData; 2.106 - semEnv->numVirtPr += 1; 2.107 + 2.108 + req = VMS__take_next_request_out_of( requestingPr ); 2.109 + } //while( req != NULL ) 2.110 2.111 - //Assign new processor to next core in line & queue it up 2.112 - #ifdef DEBUG 2.113 - newPr->coreAnimatedBy = 0; 2.114 - #else 2.115 - newPr->coreAnimatedBy = semEnv->nextCoreToGetNewPr; 2.116 - if( semEnv->nextCoreToGetNewPr >= NUM_CORES - 1 ) 2.117 - semEnv->nextCoreToGetNewPr = 0; 2.118 - else 2.119 - semEnv->nextCoreToGetNewPr += 1; 2.120 - #endif 2.121 - writePrivQ( newPr, semEnv->readyVPQs[requestingPr->coreAnimatedBy]); 2.122 - 2.123 - //resume procr that asked for registration 2.124 - writePrivQ( requestingPr, 2.125 - semEnv->readyVPQs[requestingPr->coreAnimatedBy]); 2.126 - } 2.127 - else if( VMS__isDissipateReqst( req ) ) 2.128 - { 2.129 - //free any semantic data allocated to the virt procr 2.130 - 2.131 - //Now, call VMS to free_all AppVP state -- stack and so on 2.132 - VMS__handle_dissipate_reqst( requestingPr ); 2.133 - 2.134 - semEnv->numVirtPr -= 1; 2.135 - if( semEnv->numVirtPr == 0 ) 2.136 - { //no more work, so shutdown 2.137 - VMS__handle_shutdown_reqst( requestingPr ); 2.138 - } 2.139 - } 2.140 - 2.141 - DoneHandlingReqst: 2.142 - //Free VMS portion of request, no matter what -- sem request data 2.143 - // struc instances may still be around.. VMS__free_request doesn't 2.144 - // affect the semantic request that was carried by it 2.145 - req = VMS__free_top_and_give_next_request_from( requestingPr ); 2.146 - } //while( req != NULL ) 2.147 } 2.148 2.149 -//=========================================================================== 2.150 2.151 +void inline 2.152 +handleSemReq( VMSReqst *req, VirtProcr *reqPr, SSRSemEnv *semEnv ) 2.153 + { SSRSemReq *semReq; 2.154 2.155 -/*For SSR, scheduling a slave simply takes the next work-unit off the 2.156 - * ready-to-go work-unit queue and assigns it to the slaveToSched. 2.157 - *If the ready-to-go work-unit queue is empty, then nothing to schedule 2.158 - * to the slave -- return FALSE to let Master loop know scheduling that 2.159 - * slave failed. 2.160 - */ 2.161 -VirtProcr * 2.162 -SSR__schedule_virt_procr( void *_semEnv, int coreNum ) 2.163 - { VirtProcr *schedPr; 2.164 - SSRSemEnv *semEnv; 2.165 - 2.166 - semEnv = (SSRSemEnv *)_semEnv; 2.167 - 2.168 - schedPr = readPrivQ( semEnv->readyVPQs[coreNum] ); 2.169 - //Note, using a non-blocking queue -- it returns NULL if queue empty 2.170 - 2.171 - return( schedPr ); 2.172 + semReq = VMS__take_sem_reqst_from(req); 2.173 + if( semReq == NULL ) return; 2.174 + switch( semReq->reqType ) //sem handlers are all in other file 2.175 + { 2.176 + case send_type: handleSendType( semReq, semEnv); 2.177 + break; 2.178 + case send_from_to: handleSendFromTo( semReq, semEnv); 2.179 + break; 2.180 + case receive_type: handleReceiveType( semReq, semEnv); 2.181 + break; 2.182 + case receive_from_to: handleReceiveFromTo(semReq, semEnv); 2.183 + break; 2.184 + case transfer_to: handleTransferTo( semReq, semEnv); 2.185 + break; 2.186 + case transfer_out: handleTransferOut( semReq, semEnv); 2.187 + break; 2.188 + case malloc_req: handleMalloc( semReq, reqPr, semEnv); 2.189 + break; 2.190 + case free_req: handleFree( semReq, reqPr, semEnv); 2.191 + break; 2.192 + case singleton: handleSingleton( semReq, reqPr, semEnv); 2.193 + break; 2.194 + case atomic: handleAtomic( semReq, reqPr, semEnv); 2.195 + break; 2.196 + case trans_start: handleTransStart( semReq, reqPr, semEnv); 2.197 + break; 2.198 + case trans_end: handleTransEnd( semReq, reqPr, semEnv); 2.199 + break; 2.200 + } 2.201 } 2.202 2.203 + 2.204 + 2.205 +//=========================== VMS Request Handlers ============================== 2.206 +// 2.207 +void 2.208 +handleDissipate( VirtProcr *requestingPr, SSRSemEnv *semEnv ) 2.209 + { 2.210 + //free any semantic data allocated to the virt procr 2.211 + 2.212 + //Now, call VMS to free_all AppVP state -- stack and so on 2.213 + VMS__dissipate_procr( requestingPr ); 2.214 + 2.215 + semEnv->numVirtPr -= 1; 2.216 + if( semEnv->numVirtPr == 0 ) 2.217 + { //no more work, so shutdown 2.218 + VMS__shutdown(); 2.219 + } 2.220 + } 2.221 + 2.222 +void 2.223 +handleCreate( VMSReqst *req, VirtProcr *requestingPr, SSRSemEnv *semEnv ) 2.224 + { SSRSemReq *semReq; 2.225 + VirtProcr *newPr; 2.226 + 2.227 + semReq = VMS__take_sem_reqst_from( req ); 2.228 + 2.229 + //This is running in master, so use internal version 2.230 + newPr = VMS__create_procr( semReq->fnPtr, semReq->initData ); 2.231 + 2.232 + semEnv->numVirtPr += 1; 2.233 + 2.234 + //Assign new processor to a core & transition it to ready 2.235 + #ifdef SEQUENTIAL 2.236 + newPr->coreAnimatedBy = 0; 2.237 + 2.238 + #else 2.239 + int32 2.240 + coreToScheduleOnto = semReq->coreToScheduleOnto; 2.241 + 2.242 + if(coreToScheduleOnto < 0 || coreToScheduleOnto >= NUM_CORES ) 2.243 + { //out-of-range, so round-robin assignment 2.244 + newPr->coreAnimatedBy = semEnv->nextCoreToGetNewPr; 2.245 + 2.246 + if( semEnv->nextCoreToGetNewPr >= NUM_CORES - 1 ) 2.247 + semEnv->nextCoreToGetNewPr = 0; 2.248 + else 2.249 + semEnv->nextCoreToGetNewPr += 1; 2.250 + } 2.251 + else //core num in-range, so use it 2.252 + { newPr->coreAnimatedBy = coreToScheduleOnto; 2.253 + } 2.254 + #endif 2.255 + 2.256 + //For SSR, caller needs ptr to created processor returned to it 2.257 + requestingPr->dataRetFromReq = newPr; 2.258 + 2.259 + resumePr( newPr, semEnv ); 2.260 + resumePr( requestingPr, semEnv ); 2.261 + } 2.262 + 2.263 + 2.264 +//=========================== Helper ============================== 2.265 +void inline 2.266 +resumePr( VirtProcr *procr, SSRSemEnv *semEnv ) 2.267 + { 2.268 + writePrivQ( procr, semEnv->readyVPQs[ procr->coreAnimatedBy] ); 2.269 + }
3.1 --- a/SSR_Request_Handlers.c Thu Oct 14 17:06:28 2010 -0700 3.2 +++ b/SSR_Request_Handlers.c Tue Nov 02 16:57:45 2010 -0700 3.3 @@ -6,7 +6,6 @@ 3.4 3.5 #include <stdio.h> 3.6 #include <stdlib.h> 3.7 -#include <malloc.h> 3.8 3.9 #include "VMS/VMS.h" 3.10 #include "VMS/Queue_impl/PrivateQueue.h" 3.11 @@ -15,19 +14,41 @@ 3.12 3.13 3.14 3.15 +//=========================== Local Fn Prototypes =========================== 3.16 +void inline 3.17 +resumePr( VirtProcr *procr, SSRSemEnv *semEnv ); 3.18 + 3.19 + 3.20 + 3.21 //=========================================================================== 3.22 // Helpers 3.23 3.24 +/*Only clone the elements of req used in these reqst handlers 3.25 + */ 3.26 +inline SSRSemReq * 3.27 +cloneReq( SSRSemReq *semReq ) 3.28 + { SSRSemReq *clonedReq; 3.29 + 3.30 + clonedReq = VMS__malloc( sizeof(SSRSemReq) ); 3.31 + clonedReq->reqType = semReq->reqType; 3.32 + clonedReq->sendPr = semReq->sendPr; 3.33 + clonedReq->msg = semReq->msg; 3.34 + clonedReq->nextReqInHashEntry = NULL; 3.35 + 3.36 + return clonedReq; 3.37 + } 3.38 + 3.39 HashEntry * 3.40 giveEntryElseInsertReqst( char *key, SSRSemReq *semReq, 3.41 HashTable *commHashTbl ) 3.42 { HashEntry *entry; 3.43 - SSRSemReq *waitingReq; 3.44 + SSRSemReq *waitingReq; 3.45 3.46 entry = getEntryFromTable( (char *)key, commHashTbl ); 3.47 if( entry == NULL ) 3.48 { //no waiting sends or receives, so add this request and exit 3.49 - addValueIntoTable( key, semReq, commHashTbl ); 3.50 + // note: have to clone the request because it's on stack of sender 3.51 + addValueIntoTable( key, cloneReq( semReq ), commHashTbl ); 3.52 return NULL; 3.53 } 3.54 waitingReq = (SSRSemReq *)entry->content; 3.55 @@ -60,7 +81,7 @@ 3.56 * separate processors can send to the same receiver, and hashing on the 3.57 * receive processor, so they will stack up. 3.58 */ 3.59 -void 3.60 +void inline 3.61 handleSendType( SSRSemReq *semReq, SSRSemEnv *semEnv ) 3.62 { VirtProcr *sendPr, *receivePr; 3.63 int key[] = {0,0,0}; 3.64 @@ -82,7 +103,7 @@ 3.65 key[1] = (int)(semReq->msgType); 3.66 //key[2] acts as the 0 that terminates the string 3.67 3.68 - entry = giveEntryElseInsertReqst( key, semReq, commHashTbl); 3.69 + entry = giveEntryElseInsertReqst( (char *)key, semReq, commHashTbl); 3.70 if( entry == NULL ) return; //was just inserted 3.71 3.72 waitingReq = (SSRSemReq *)entry->content; 3.73 @@ -90,36 +111,36 @@ 3.74 //At this point, know have waiting request(s) -- either sends or recv 3.75 //Note, can only have max of one receive waiting, and cannot have both 3.76 // sends and receives waiting (they would have paired off) 3.77 - // but can have multiple send_type requests waiting (from diff senders) 3.78 + // but can have multiple sends from diff sending VPs, all same msg-type 3.79 if( waitingReq->reqType == send_type ) 3.80 { //waiting request is another send, so stack this up on list 3.81 - semReq-> nextReqInHashEntry = waitingReq->nextReqInHashEntry; 3.82 - waitingReq->nextReqInHashEntry = semReq; 3.83 - PRINT2_DEBUG("linked requests: %d, %d | ", semReq, waitingReq ) 3.84 - PRINT2_DEBUG("type: %d, %d\n", semReq->reqType, waitingReq->reqType) 3.85 + // but first clone the sending request so it persists. 3.86 + SSRSemReq *clonedReq = cloneReq( semReq ); 3.87 + clonedReq-> nextReqInHashEntry = waitingReq->nextReqInHashEntry; 3.88 + waitingReq->nextReqInHashEntry = clonedReq; 3.89 + PRINT2_DEBUG("linked requests: %d, %d | ", clonedReq, waitingReq ) 3.90 return; 3.91 } 3.92 else 3.93 - { //waiting request is a receive, so pair it to this send 3.94 - //first, remove the waiting receive request from the list in entry 3.95 + { //waiting request is a receive, so it pairs to this send 3.96 + //First, remove the waiting receive request from the entry 3.97 entry->content = waitingReq->nextReqInHashEntry; 3.98 + VMS__free( waitingReq ); //Don't use contents -- so free it 3.99 + 3.100 if( entry->content == NULL ) 3.101 { //TODO: mod hash table to double-link, so can delete entry from 3.102 // table without hashing the key and looking it up again 3.103 - deleteEntryFromTable( entry->key, commHashTbl ); //frees entry too 3.104 + deleteEntryFromTable( entry->key, commHashTbl ); //frees hashEntry 3.105 } 3.106 3.107 //attach msg that's in this send request to receiving procr 3.108 - // when comes back from suspend, will have msg in semanticData 3.109 - receivePr->semanticData = semReq->msg; 3.110 + // when comes back from suspend will have msg in dataRetFromReq 3.111 + receivePr->dataRetFromReq = semReq->msg; 3.112 3.113 //bring both processors back from suspend 3.114 - writePrivQ( sendPr, semEnv->readyVPQs[sendPr->coreAnimatedBy] ); 3.115 - writePrivQ( receivePr, semEnv->readyVPQs[receivePr->coreAnimatedBy] ); 3.116 + resumePr( sendPr, semEnv ); 3.117 + resumePr( receivePr, semEnv ); 3.118 3.119 - //don't need semReq anymore -- free it 3.120 - SSR__free_semantic_request( waitingReq ); 3.121 - SSR__free_semantic_request( semReq ); 3.122 return; 3.123 } 3.124 } 3.125 @@ -128,7 +149,7 @@ 3.126 /*Looks like can make single handler for both sends.. 3.127 */ 3.128 //TODO: combine both send handlers into single handler 3.129 -void 3.130 +void inline 3.131 handleSendFromTo( SSRSemReq *semReq, SSRSemEnv *semEnv) 3.132 { VirtProcr *sendPr, *receivePr; 3.133 int key[] = {0,0,0}; 3.134 @@ -143,47 +164,44 @@ 3.135 key[1] = (int)sendPr; 3.136 //key[2] acts at the 0 that terminates the string 3.137 3.138 - entry = giveEntryElseInsertReqst( key, semReq, commHashTbl); 3.139 + entry = giveEntryElseInsertReqst( (char *)key, semReq, commHashTbl); 3.140 if( entry == NULL ) return; //was just inserted 3.141 3.142 waitingReq = (SSRSemReq *)entry->content; 3.143 3.144 //At this point, know have waiting request(s) -- either sends or recv 3.145 if( waitingReq->reqType == send_from_to ) 3.146 - { printf("\n ERROR: shouldn't be two send from-tos waiting \n"); 3.147 + { printf("\n ERROR: shouldn't be two send-from-tos waiting \n"); 3.148 } 3.149 else 3.150 { //waiting request is a receive, so it completes pair with this send 3.151 - 3.152 - //remove the waiting receive request from the entry 3.153 + //First, remove the waiting receive request from the entry 3.154 entry->content = waitingReq->nextReqInHashEntry; 3.155 + VMS__free( waitingReq ); //Don't use contents -- so free it 3.156 + 3.157 //can only be one waiting req for "from-to" semantics 3.158 if( entry->content != NULL ) 3.159 { 3.160 printf("\nERROR in handleSendFromTo\n"); 3.161 - printf("waitReq: %d | next req: %d\n", waitingReq, entry->content); 3.162 } 3.163 - deleteEntryFromTable( entry->key, commHashTbl ); //frees entry too 3.164 + deleteEntryFromTable( entry->key, commHashTbl ); //frees HashEntry 3.165 3.166 //attach msg that's in this send request to receiving procr 3.167 - // when comes back from suspend, will have msg in semanticData 3.168 - receivePr->semanticData = semReq->msg; 3.169 + // when comes back from suspend, will have msg in dataRetFromReq 3.170 + receivePr->dataRetFromReq = semReq->msg; 3.171 3.172 //bring both processors back from suspend 3.173 writePrivQ( sendPr, semEnv->readyVPQs[sendPr->coreAnimatedBy] ); 3.174 writePrivQ( receivePr, semEnv->readyVPQs[receivePr->coreAnimatedBy] ); 3.175 3.176 - //done with requests, so free them 3.177 - SSR__free_semantic_request( waitingReq ); 3.178 - SSR__free_semantic_request( semReq ); 3.179 return; 3.180 } 3.181 } 3.182 3.183 3.184 3.185 -//======================================================= 3.186 - 3.187 +//============================== Receives =========================== 3.188 +// 3.189 /*Removed this one for now, because forces either a search or going to a 3.190 * two-level hash table, where one level the key is the receivePr, in the 3.191 * other level, the key is the type. 3.192 @@ -210,14 +228,14 @@ 3.193 * If ever add receive_any, looking like this second option easier and even 3.194 * less costly. 3.195 */ 3.196 -void 3.197 +void inline 3.198 handleReceiveAny( SSRSemReq *semReq, SSRSemEnv *semEnv) 3.199 { 3.200 3.201 } 3.202 3.203 3.204 -void 3.205 +void inline 3.206 handleReceiveType( SSRSemReq *semReq, SSRSemEnv *semEnv) 3.207 { VirtProcr *sendPr, *receivePr; 3.208 int key[] = {0,0,0}; 3.209 @@ -229,13 +247,13 @@ 3.210 3.211 key[0] = (int)receivePr; 3.212 key[1] = (int)(semReq->msgType); 3.213 - //key[2] acts at the 0 that terminates the string 3.214 + //key[2] acts as the 0 that terminates the string 3.215 3.216 3.217 - entry = giveEntryElseInsertReqst( key, semReq, commHashTbl); 3.218 + entry = giveEntryElseInsertReqst((char*)key, semReq, commHashTbl);//clones 3.219 if( entry == NULL ) return; //was just inserted 3.220 3.221 - waitingReq = (SSRSemReq *)entry->content; 3.222 + waitingReq = (SSRSemReq *)entry->content; //previously cloned by insert 3.223 3.224 //At this point, know have waiting request(s) -- should be send(s) 3.225 if( waitingReq->reqType == send_type ) 3.226 @@ -243,21 +261,20 @@ 3.227 //first, remove the waiting send request from the list in entry 3.228 entry->content = waitingReq->nextReqInHashEntry; 3.229 if( entry->content == NULL ) 3.230 - { deleteEntryFromTable( entry->key, commHashTbl ); //frees entry too 3.231 + { deleteEntryFromTable( entry->key, commHashTbl ); //frees HashEntry 3.232 } 3.233 3.234 //attach msg that's in the send request to receiving procr 3.235 - // when comes back from suspend, will have msg in semanticData 3.236 - receivePr->semanticData = waitingReq->msg; 3.237 + // when comes back from suspend, will have msg in dataReturnedFromReq 3.238 + receivePr->dataRetFromReq = waitingReq->msg; 3.239 3.240 //bring both processors back from suspend 3.241 sendPr = waitingReq->sendPr; 3.242 + VMS__free( waitingReq ); 3.243 + 3.244 writePrivQ( sendPr, semEnv->readyVPQs[sendPr->coreAnimatedBy] ); 3.245 writePrivQ( receivePr, semEnv->readyVPQs[receivePr->coreAnimatedBy] ); 3.246 3.247 - //done with requests, so free them 3.248 - SSR__free_semantic_request( waitingReq ); 3.249 - SSR__free_semantic_request( semReq ); 3.250 return; 3.251 } 3.252 printf("\nLang Impl Error: Should never be two waiting receives!\n"); 3.253 @@ -266,7 +283,7 @@ 3.254 3.255 /* 3.256 */ 3.257 -void 3.258 +void inline 3.259 handleReceiveFromTo( SSRSemReq *semReq, SSRSemEnv *semEnv) 3.260 { VirtProcr *sendPr, *receivePr; 3.261 int key[] = {0,0,0}; 3.262 @@ -281,7 +298,7 @@ 3.263 key[1] = (int)sendPr; 3.264 //key[2] acts at the 0 that terminates the string 3.265 3.266 - entry = giveEntryElseInsertReqst( key, semReq, commHashTbl); 3.267 + entry = giveEntryElseInsertReqst( (char *)key, semReq, commHashTbl); 3.268 if( entry == NULL ) return; //was just inserted 3.269 3.270 waitingReq = (SSRSemReq *)entry->content; 3.271 @@ -296,17 +313,16 @@ 3.272 deleteEntryFromTable( entry->key, commHashTbl ); //frees entry too 3.273 3.274 //attach msg that's in the send request to receiving procr 3.275 - // when comes back from suspend, will have msg in semanticData 3.276 - receivePr->semanticData = waitingReq->msg; 3.277 + // when comes back from suspend, will have msg in dataRetFromReq 3.278 + receivePr->dataRetFromReq = waitingReq->msg; 3.279 3.280 //bring both processors back from suspend 3.281 sendPr = waitingReq->sendPr; 3.282 + VMS__free( waitingReq ); 3.283 + 3.284 writePrivQ( sendPr, semEnv->readyVPQs[sendPr->coreAnimatedBy] ); 3.285 writePrivQ( receivePr, semEnv->readyVPQs[receivePr->coreAnimatedBy] ); 3.286 3.287 - //done with requests, so free them 3.288 - SSR__free_semantic_request( waitingReq ); 3.289 - SSR__free_semantic_request( semReq ); 3.290 return; 3.291 } 3.292 printf("\nLang Impl Error: Should never be two waiting receives!\n"); 3.293 @@ -315,16 +331,164 @@ 3.294 3.295 3.296 //=============================================== 3.297 -void 3.298 +void inline 3.299 handleTransferTo( SSRSemReq *semReq, SSRSemEnv *semEnv) 3.300 { 3.301 3.302 } 3.303 3.304 -void 3.305 +void inline 3.306 handleTransferOut( SSRSemReq *semReq, SSRSemEnv *semEnv) 3.307 { 3.308 3.309 } 3.310 3.311 3.312 +/* 3.313 + */ 3.314 +void inline 3.315 +handleMalloc( SSRSemReq *semReq, VirtProcr *requestingPr, SSRSemEnv *semEnv ) 3.316 + { void *ptr; 3.317 + 3.318 + ptr = VMS__malloc( semReq->sizeToMalloc ); 3.319 + requestingPr->dataRetFromReq = ptr; 3.320 + resumePr( requestingPr, semEnv ); 3.321 + } 3.322 + 3.323 +/* 3.324 + */ 3.325 +void inline 3.326 +handleFree( SSRSemReq *semReq, VirtProcr *requestingPr, SSRSemEnv *semEnv ) 3.327 + { 3.328 + VMS__free( semReq->ptrToFree ); 3.329 + resumePr( requestingPr, semEnv ); 3.330 + } 3.331 + 3.332 + 3.333 +//=========================================================================== 3.334 +// 3.335 +/*Uses ID as index into array of flags. If flag already set, resumes from 3.336 + * end-label. Else, sets flag and resumes normally. 3.337 + */ 3.338 +void inline 3.339 +handleSingleton( SSRSemReq *semReq, VirtProcr *requestingPr, 3.340 + SSRSemEnv *semEnv ) 3.341 + { 3.342 + if( semEnv->singletonHasBeenExecutedFlags[ semReq->singletonID ] ) 3.343 + requestingPr->nextInstrPt = semReq->endJumpPt; 3.344 + else 3.345 + semEnv->singletonHasBeenExecutedFlags[ semReq->singletonID ] = TRUE; 3.346 + 3.347 + resumePr( requestingPr, semEnv ); 3.348 + } 3.349 + 3.350 + 3.351 +/*This executes the function in the masterVP, take the function 3.352 + * pointer out of the request and call it, then resume the VP. 3.353 + */ 3.354 +void inline 3.355 +handleAtomic( SSRSemReq *semReq, VirtProcr *requestingPr, SSRSemEnv *semEnv ) 3.356 + { 3.357 + semReq->fnToExecInMaster( semReq->dataForFn ); 3.358 + resumePr( requestingPr, semEnv ); 3.359 + } 3.360 + 3.361 +/*First, it looks at the VP's semantic data, to see the highest transactionID 3.362 + * that VP 3.363 + * already has entered. If the current ID is not larger, it throws an 3.364 + * exception stating a bug in the code. 3.365 + *Otherwise it puts the current ID 3.366 + * there, and adds the ID to a linked list of IDs entered -- the list is 3.367 + * used to check that exits are properly ordered. 3.368 + *Next it is uses transactionID as index into an array of transaction 3.369 + * structures. 3.370 + *If the "VP_currently_executing" field is non-null, then put requesting VP 3.371 + * into queue in the struct. (At some point a holder will request 3.372 + * end-transaction, which will take this VP from the queue and resume it.) 3.373 + *If NULL, then write requesting into the field and resume. 3.374 + */ 3.375 +void inline 3.376 +handleTransStart( SSRSemReq *semReq, VirtProcr *requestingPr, 3.377 + SSRSemEnv *semEnv ) 3.378 + { SSRSemData *semData; 3.379 + TransListElem *nextTransElem; 3.380 + 3.381 + //check ordering of entering transactions is correct 3.382 + semData = requestingPr->semanticData; 3.383 + if( semData->highestTransEntered > semReq->transID ) 3.384 + { //throw VMS exception, which shuts down VMS. 3.385 + VMS__throw_exception( "transID smaller than prev", requestingPr, NULL); 3.386 + } 3.387 + //add this trans ID to the list of transactions entered -- check when 3.388 + // end a transaction 3.389 + semData->highestTransEntered = semReq->transID; 3.390 + nextTransElem = VMS__malloc( sizeof(TransListElem) ); 3.391 + nextTransElem->transID = semReq->transID; 3.392 + nextTransElem->nextTrans = semData->lastTransEntered; 3.393 + semData->lastTransEntered = nextTransElem; 3.394 + 3.395 + //get the structure for this transaction ID 3.396 + SSRTrans * 3.397 + transStruc = &(semEnv->transactionStrucs[ semReq->transID ]); 3.398 + 3.399 + if( transStruc->VPCurrentlyExecuting == NULL ) 3.400 + { 3.401 + transStruc->VPCurrentlyExecuting = requestingPr; 3.402 + resumePr( requestingPr, semEnv ); 3.403 + } 3.404 + else 3.405 + { //note, might make future things cleaner if save request with VP and 3.406 + // add this trans ID to the linked list when gets out of queue. 3.407 + // but don't need for now, and lazy.. 3.408 + writePrivQ( requestingPr, transStruc->waitingVPQ ); 3.409 + } 3.410 + } 3.411 + 3.412 + 3.413 +/*Use the trans ID to get the transaction structure from the array. 3.414 + *Look at VP_currently_executing to be sure it's same as requesting VP. 3.415 + * If different, throw an exception, stating there's a bug in the code. 3.416 + *Next, take the first element off the list of entered transactions. 3.417 + * Check to be sure the ending transaction is the same ID as the next on 3.418 + * the list. If not, incorrectly nested so throw an exception. 3.419 + * 3.420 + *Next, get from the queue in the structure. 3.421 + *If it's empty, set VP_currently_executing field to NULL and resume 3.422 + * requesting VP. 3.423 + *If get somethine, set VP_currently_executing to the VP from the queue, then 3.424 + * resume both. 3.425 + */ 3.426 +void inline 3.427 +handleTransEnd(SSRSemReq *semReq, VirtProcr *requestingPr, SSRSemEnv *semEnv) 3.428 + { SSRSemData *semData; 3.429 + VirtProcr *waitingPr; 3.430 + SSRTrans *transStruc; 3.431 + TransListElem *lastTrans; 3.432 + 3.433 + transStruc = &(semEnv->transactionStrucs[ semReq->transID ]); 3.434 + 3.435 + //make sure transaction ended in same VP as started it. 3.436 + if( transStruc->VPCurrentlyExecuting != requestingPr ) 3.437 + { 3.438 + VMS__throw_exception( "trans ended in diff VP", requestingPr, NULL ); 3.439 + } 3.440 + 3.441 + //make sure nesting is correct -- last ID entered should == this ID 3.442 + semData = requestingPr->semanticData; 3.443 + lastTrans = semData->lastTransEntered; 3.444 + if( lastTrans->transID != semReq->transID ) 3.445 + { 3.446 + VMS__throw_exception( "trans incorrectly nested", requestingPr, NULL ); 3.447 + } 3.448 + 3.449 + semData->lastTransEntered = semData->lastTransEntered->nextTrans; 3.450 + 3.451 + 3.452 + waitingPr = readPrivQ( transStruc->waitingVPQ ); 3.453 + transStruc->VPCurrentlyExecuting = waitingPr; 3.454 + 3.455 + if( waitingPr != NULL ) 3.456 + resumePr( waitingPr, semEnv ); 3.457 + 3.458 + resumePr( requestingPr, semEnv ); 3.459 + }
4.1 --- a/SSR_Request_Handlers.h Thu Oct 14 17:06:28 2010 -0700 4.2 +++ b/SSR_Request_Handlers.h Tue Nov 02 16:57:45 2010 -0700 4.3 @@ -14,20 +14,34 @@ 4.4 /*This header defines everything specific to the SSR semantic plug-in 4.5 */ 4.6 4.7 -void 4.8 +void inline 4.9 handleSendType( SSRSemReq *semReq, SSRSemEnv *semEnv); 4.10 -void 4.11 +void inline 4.12 handleSendFromTo( SSRSemReq *semReq, SSRSemEnv *semEnv); 4.13 -void 4.14 +void inline 4.15 handleReceiveAny( SSRSemReq *semReq, SSRSemEnv *semEnv); 4.16 -void 4.17 +void inline 4.18 handleReceiveType( SSRSemReq *semReq, SSRSemEnv *semEnv); 4.19 -void 4.20 +void inline 4.21 handleReceiveFromTo( SSRSemReq *semReq, SSRSemEnv *semEnv); 4.22 -void 4.23 +void inline 4.24 handleTransferTo( SSRSemReq *semReq, SSRSemEnv *semEnv); 4.25 -void 4.26 +void inline 4.27 handleTransferOut( SSRSemReq *semReq, SSRSemEnv *semEnv); 4.28 +void inline 4.29 +handleMalloc( SSRSemReq *semReq, VirtProcr *requestingPr, SSRSemEnv *semEnv); 4.30 +void inline 4.31 +handleFree( SSRSemReq *semReq, VirtProcr *requestingPr, SSRSemEnv *semEnv ); 4.32 +void inline 4.33 +handleTransEnd(SSRSemReq *semReq, VirtProcr *requestingPr, SSRSemEnv*semEnv); 4.34 +void inline 4.35 +handleTransStart( SSRSemReq *semReq, VirtProcr *requestingPr, 4.36 + SSRSemEnv *semEnv ); 4.37 +void inline 4.38 +handleAtomic( SSRSemReq *semReq, VirtProcr *requestingPr, SSRSemEnv *semEnv); 4.39 +void inline 4.40 +handleSingleton( SSRSemReq *semReq, VirtProcr *requestingPr, 4.41 + SSRSemEnv *semEnv ); 4.42 4.43 #endif /* _SSR_REQ_H */ 4.44
5.1 --- a/SSR_lib.c Thu Oct 14 17:06:28 2010 -0700 5.2 +++ b/SSR_lib.c Tue Nov 02 16:57:45 2010 -0700 5.3 @@ -94,7 +94,7 @@ 5.4 { SSRSemEnv *semEnv; 5.5 VirtProcr *seedPr; 5.6 5.7 - #ifdef DEBUG 5.8 + #ifdef SEQUENTIAL 5.9 SSR__init_Seq(); //debug sequential exe 5.10 #else 5.11 SSR__init(); //normal multi-thd 5.12 @@ -110,7 +110,7 @@ 5.13 writePrivQ( seedPr, semEnv->readyVPQs[seedPr->coreAnimatedBy] ); 5.14 semEnv->numVirtPr = 1; 5.15 5.16 - #ifdef DEBUG 5.17 + #ifdef SEQUENTIAL 5.18 VMS__start_the_work_then_wait_until_done_Seq(); //debug sequential exe 5.19 #else 5.20 VMS__start_the_work_then_wait_until_done(); //normal multi-thd 5.21 @@ -132,14 +132,19 @@ 5.22 return NUM_SCHED_SLOTS * NUM_CORES; 5.23 } 5.24 5.25 +int32 5.26 +SSR__give_number_of_cores_to_schedule_onto() 5.27 + { 5.28 + return NUM_CORES; 5.29 + } 5.30 + 5.31 /*For now, use TSC -- later, make these two macros with assembly that first 5.32 * saves jump point, and second jumps back several times to get reliable time 5.33 */ 5.34 void inline 5.35 SSR__start_primitive() 5.36 - { int32 *saveAddr; 5.37 - saveAddr = &(((SSRSemEnv *)(_VMSMasterEnv->semanticEnv))->primitiveStartTime); 5.38 - saveLowTimeStampCountInto( (((SSRSemEnv *)(_VMSMasterEnv->semanticEnv))->primitiveStartTime) ); 5.39 + { saveLowTimeStampCountInto( ((SSRSemEnv *)(_VMSMasterEnv->semanticEnv))-> 5.40 + primitiveStartTime ); 5.41 } 5.42 5.43 /*Just quick and dirty for now -- make reliable later 5.44 @@ -152,7 +157,7 @@ 5.45 { int32 endTime, startTime; 5.46 //TODO: fix by repeating time-measurement 5.47 saveLowTimeStampCountInto( endTime ); 5.48 - startTime = ((SSRSemEnv *)(_VMSMasterEnv->semanticEnv))->primitiveStartTime; 5.49 + startTime =((SSRSemEnv*)(_VMSMasterEnv->semanticEnv))->primitiveStartTime; 5.50 return (endTime - startTime); 5.51 } 5.52 5.53 @@ -161,6 +166,7 @@ 5.54 /*Initializes all the data-structures for a SSR system -- but doesn't 5.55 * start it running yet! 5.56 * 5.57 + *This runs in the main thread -- before VMS starts up 5.58 * 5.59 *This sets up the semantic layer over the VMS system 5.60 * 5.61 @@ -172,6 +178,7 @@ 5.62 { 5.63 VMS__init(); 5.64 //masterEnv, a global var, now is partially set up by init_VMS 5.65 + // after this, have VMS__malloc and VMS__free available 5.66 5.67 SSR__init_Helper(); 5.68 } 5.69 @@ -189,7 +196,7 @@ 5.70 SSR__init_Helper() 5.71 { SSRSemEnv *semanticEnv; 5.72 PrivQueueStruc **readyVPQs; 5.73 - int coreIdx; 5.74 + int coreIdx, i; 5.75 5.76 //Hook up the semantic layer's plug-ins to the Master virt procr 5.77 _VMSMasterEnv->requestHandler = &SSR__Request_Handler; 5.78 @@ -197,14 +204,14 @@ 5.79 5.80 //create the semantic layer's environment (all its data) and add to 5.81 // the master environment 5.82 - semanticEnv = malloc( sizeof( SSRSemEnv ) ); 5.83 + semanticEnv = VMS__malloc( sizeof( SSRSemEnv ) ); 5.84 _VMSMasterEnv->semanticEnv = semanticEnv; 5.85 5.86 //create the ready queue, hash tables used for pairing send to receive 5.87 // and so forth 5.88 //TODO: add hash tables for pairing sends with receives, and 5.89 // initialize the data ownership system 5.90 - readyVPQs = malloc( NUM_CORES * sizeof(PrivQueueStruc *) ); 5.91 + readyVPQs = VMS__malloc( NUM_CORES * sizeof(PrivQueueStruc *) ); 5.92 5.93 for( coreIdx = 0; coreIdx < NUM_CORES; coreIdx++ ) 5.94 { 5.95 @@ -215,7 +222,19 @@ 5.96 5.97 semanticEnv->nextCoreToGetNewPr = 0; 5.98 5.99 - semanticEnv->commHashTbl = makeHashTable( 1<<16, NULL ); //start big 5.100 + semanticEnv->commHashTbl = makeHashTable( 1<<16, &VMS__free );//start big 5.101 + 5.102 + //TODO: bug -- turn these arrays into dyn arrays to eliminate limit 5.103 + //semanticEnv->singletonHasBeenExecutedFlags = makeDynArrayInfo( ); 5.104 + //semanticEnv->transactionStrucs = makeDynArrayInfo( ); 5.105 + for( i = 0; i < NUM_STRUCS_IN_SEM_ENV; i++ ) 5.106 + { 5.107 + semanticEnv->singletonHasBeenExecutedFlags[i] = FALSE; 5.108 + semanticEnv->transactionStrucs[i].waitingVPQ = makePrivQ(); 5.109 + } 5.110 + 5.111 + 5.112 + 5.113 } 5.114 5.115 5.116 @@ -225,21 +244,22 @@ 5.117 SSR__cleanup_after_shutdown() 5.118 { SSRSemEnv *semanticEnv; 5.119 int coreIdx; 5.120 - 5.121 + 5.122 +/* It's all allocated inside VMS's big chunk -- that's about to be freed, so 5.123 + * nothing to do here 5.124 semanticEnv = _VMSMasterEnv->semanticEnv; 5.125 5.126 -//TODO: double check all sem env locations freed 5.127 - 5.128 for( coreIdx = 0; coreIdx < NUM_CORES; coreIdx++ ) 5.129 { 5.130 - free( semanticEnv->readyVPQs[coreIdx]->startOfData ); 5.131 - free( semanticEnv->readyVPQs[coreIdx] ); 5.132 + VMS__free( semanticEnv->readyVPQs[coreIdx]->startOfData ); 5.133 + VMS__free( semanticEnv->readyVPQs[coreIdx] ); 5.134 } 5.135 - free( semanticEnv->readyVPQs ); 5.136 + VMS__free( semanticEnv->readyVPQs ); 5.137 5.138 freeHashTable( semanticEnv->commHashTbl ); 5.139 - free( _VMSMasterEnv->semanticEnv ); 5.140 - VMS__cleanup_after_shutdown(); 5.141 + VMS__free( _VMSMasterEnv->semanticEnv ); 5.142 + */ 5.143 + VMS__cleanup_at_end_of_shutdown(); 5.144 } 5.145 5.146 5.147 @@ -248,38 +268,76 @@ 5.148 /* 5.149 */ 5.150 inline VirtProcr * 5.151 -SSR__create_procr_with( VirtProcrFnPtr fnPtr, void *initData, 5.152 - VirtProcr *creatingPr ) 5.153 - { VirtProcr *newPr; 5.154 +SSR__create_procr_with( VirtProcrFnPtr fnPtr, void *initData, 5.155 + VirtProcr *creatingPr ) 5.156 + { SSRSemReq reqData; 5.157 5.158 - newPr = VMS__create_procr( fnPtr, initData ); 5.159 + //the semantic request data is on the stack and disappears when this 5.160 + // call returns -- it's guaranteed to remain in the VP's stack for as 5.161 + // long as the VP is suspended. 5.162 + reqData.reqType = 0; //know type because in a VMS create req 5.163 + reqData.coreToScheduleOnto = -1; //means round-robin schedule 5.164 + reqData.fnPtr = fnPtr; 5.165 + reqData.initData = initData; 5.166 + reqData.sendPr = creatingPr; 5.167 5.168 - //After create, have to send request to plugin for any sem env 5.169 - // modifications -- such as putting the new procr into the ready Q 5.170 - //Need a processor to "animate" the creation -- it's one the register 5.171 - // request is attached to, and one suspended in order to send req 5.172 - // to plugin 5.173 - VMS__send_req_to_register_new_procr( newPr, creatingPr ); 5.174 + VMS__send_create_procr_req( &reqData, creatingPr ); 5.175 5.176 - return newPr; 5.177 + return creatingPr->dataRetFromReq; 5.178 + } 5.179 + 5.180 +inline VirtProcr * 5.181 +SSR__create_procr_with_affinity( VirtProcrFnPtr fnPtr, void *initData, 5.182 + VirtProcr *creatingPr, int32 coreToScheduleOnto ) 5.183 + { SSRSemReq reqData; 5.184 + 5.185 + //the semantic request data is on the stack and disappears when this 5.186 + // call returns -- it's guaranteed to remain in the VP's stack for as 5.187 + // long as the VP is suspended. 5.188 + reqData.reqType = 0; //know type because in a VMS create req 5.189 + reqData.coreToScheduleOnto = coreToScheduleOnto; 5.190 + reqData.fnPtr = fnPtr; 5.191 + reqData.initData = initData; 5.192 + reqData.sendPr = creatingPr; 5.193 + 5.194 + VMS__send_create_procr_req( &reqData, creatingPr ); 5.195 } 5.196 5.197 5.198 inline void 5.199 SSR__dissipate_procr( VirtProcr *procrToDissipate ) 5.200 { 5.201 - VMS__dissipate_procr( procrToDissipate ); 5.202 + VMS__send_dissipate_req( procrToDissipate ); 5.203 } 5.204 5.205 5.206 //=========================================================================== 5.207 5.208 void * 5.209 -SSR__malloc_size_to( int numBytes, VirtProcr *ownerPr ) 5.210 - { 5.211 -//TODO: Put in the ownership system from DKU -- have it working, just adapt 5.212 -// it to here 5.213 - return malloc( numBytes ); 5.214 +SSR__malloc_to( int32 sizeToMalloc, VirtProcr *owningPr ) 5.215 + { SSRSemReq reqData; 5.216 + 5.217 + reqData.reqType = malloc_req; 5.218 + reqData.sendPr = owningPr; 5.219 + reqData.sizeToMalloc = sizeToMalloc; 5.220 + 5.221 + VMS__send_sem_request( &reqData, owningPr ); 5.222 + 5.223 + return owningPr->dataRetFromReq; 5.224 + } 5.225 + 5.226 + 5.227 +/*Sends request to Master, which does the work of freeing 5.228 + */ 5.229 +void 5.230 +SSR__free( void *ptrToFree, VirtProcr *owningPr ) 5.231 + { SSRSemReq reqData; 5.232 + 5.233 + reqData.reqType = free_req; 5.234 + reqData.sendPr = owningPr; 5.235 + reqData.ptrToFree = ptrToFree; 5.236 + 5.237 + VMS__send_sem_request( &reqData, owningPr ); 5.238 } 5.239 5.240 5.241 @@ -287,7 +345,9 @@ 5.242 SSR__transfer_ownership_of_from_to( void *data, VirtProcr *oldOwnerPr, 5.243 VirtProcr *newOwnerPr ) 5.244 { 5.245 - 5.246 + //TODO: put in the ownership system that automatically frees when no 5.247 + // owners of data left -- will need keeper for keeping data around when 5.248 + // future created processors might need it but don't exist yet 5.249 } 5.250 5.251 5.252 @@ -333,22 +393,20 @@ 5.253 void 5.254 SSR__send_of_type_to( VirtProcr *sendPr, void *msg, const int type, 5.255 VirtProcr *receivePr) 5.256 - { SSRSemReq *reqData; 5.257 + { SSRSemReq reqData; 5.258 5.259 - reqData = malloc( sizeof(SSRSemReq) ); 5.260 - reqData->receivePr = receivePr; 5.261 - reqData->sendPr = sendPr; 5.262 - reqData->reqType = send_type; 5.263 - reqData->msgType = type; 5.264 - reqData->msg = msg; 5.265 - reqData->nextReqInHashEntry = NULL; 5.266 + reqData.receivePr = receivePr; 5.267 + reqData.sendPr = sendPr; 5.268 + reqData.reqType = send_type; 5.269 + reqData.msgType = type; 5.270 + reqData.msg = msg; 5.271 + reqData.nextReqInHashEntry = NULL; 5.272 5.273 //On ownership -- remove inside the send and let ownership sit in limbo 5.274 // as a potential in an entry in the hash table, when this receive msg 5.275 // gets paired to a send, the ownership gets added to the receivePr -- 5.276 // the next work-unit in the receivePr's trace will have ownership. 5.277 - VMS__add_sem_request( reqData, sendPr ); 5.278 - VMS__suspend_procr( sendPr ); //will suspend then resume and continue 5.279 + VMS__send_sem_request( &reqData, sendPr ); 5.280 5.281 //When come back from suspend, no longer own data reachable from msg 5.282 //TODO: release ownership here 5.283 @@ -356,27 +414,18 @@ 5.284 5.285 void 5.286 SSR__send_from_to( void *msg, VirtProcr *sendPr, VirtProcr *receivePr ) 5.287 - { SSRSemReq *reqData; 5.288 + { SSRSemReq reqData; 5.289 5.290 //hash on the receiver, 'cause always know it, but sometimes want to 5.291 // receive from anonymous sender 5.292 5.293 - reqData = malloc( sizeof(SSRSemReq) ); 5.294 - reqData->receivePr = receivePr; 5.295 - reqData->sendPr = sendPr; 5.296 - reqData->reqType = send_from_to; 5.297 - reqData->msg = msg; 5.298 - reqData->nextReqInHashEntry = NULL; 5.299 + reqData.receivePr = receivePr; 5.300 + reqData.sendPr = sendPr; 5.301 + reqData.reqType = send_from_to; 5.302 + reqData.msg = msg; 5.303 + reqData.nextReqInHashEntry = NULL; 5.304 5.305 - //On ownership -- remove inside the send and let ownership sit in limbo 5.306 - // as a potential in an entry in the hash table, when this receive msg 5.307 - // gets paired to a send, the ownership gets added to the receivePr -- 5.308 - // the next work-unit in the receivePr's trace will have ownership. 5.309 - VMS__add_sem_request( reqData, sendPr ); 5.310 - VMS__suspend_procr( sendPr ); //will suspend then resume and continue 5.311 - 5.312 - //When come back from suspend, no longer own data reachable from msg 5.313 - //TODO: release ownership here 5.314 + VMS__send_sem_request( &reqData, sendPr ); 5.315 } 5.316 5.317 5.318 @@ -390,19 +439,17 @@ 5.319 5.320 void * 5.321 SSR__receive_type_to( const int type, VirtProcr *receivePr ) 5.322 - { void *msg; 5.323 - SSRSemReq *reqData; 5.324 + { 5.325 + SSRSemReq reqData; 5.326 5.327 - reqData = malloc( sizeof(SSRSemReq) ); 5.328 - reqData->receivePr = receivePr; 5.329 - reqData->reqType = receive_type; 5.330 - reqData->msgType = type; 5.331 - reqData->nextReqInHashEntry = NULL; 5.332 + reqData.receivePr = receivePr; 5.333 + reqData.reqType = receive_type; 5.334 + reqData.msgType = type; 5.335 + reqData.nextReqInHashEntry = NULL; 5.336 5.337 - VMS__add_sem_request( reqData, receivePr ); 5.338 - VMS__suspend_procr( receivePr ); 5.339 - msg = receivePr->semanticData; 5.340 - return msg; 5.341 + VMS__send_sem_request( &reqData, receivePr ); 5.342 + 5.343 + return receivePr->dataRetFromReq; 5.344 } 5.345 5.346 5.347 @@ -415,39 +462,110 @@ 5.348 */ 5.349 void * 5.350 SSR__receive_from_to( VirtProcr *sendPr, VirtProcr *receivePr ) 5.351 - { SSRSemReq *reqData; 5.352 + { SSRSemReq reqData; 5.353 5.354 //hash on the receiver, 'cause always know it, but sometimes want to 5.355 // receive from anonymous sender 5.356 5.357 - reqData = malloc( sizeof(SSRSemReq) ); 5.358 - reqData->receivePr = receivePr; 5.359 - reqData->sendPr = sendPr; 5.360 - reqData->reqType = receive_from_to; 5.361 - reqData->nextReqInHashEntry = NULL; 5.362 + reqData.receivePr = receivePr; 5.363 + reqData.sendPr = sendPr; 5.364 + reqData.reqType = receive_from_to; 5.365 + reqData.nextReqInHashEntry = NULL; 5.366 5.367 - //On ownership -- remove inside the send after receive successful. 5.368 - // Below, add ownership when come back from suspend 5.369 - //Reason: Thinking of impl ownership mech such that it automatically 5.370 - // frees any data has no owners -- so have to add receiver before 5.371 - // remove sender 5.372 - VMS__add_sem_request( reqData, receivePr ); 5.373 - //TODO: add ownership of locs reachable from msg inside reqst handler 5.374 - VMS__suspend_procr( receivePr ); //will suspend then resume and continue 5.375 + VMS__send_sem_request( &reqData, receivePr ); 5.376 5.377 - //When come back from suspend, the msg data is in receivePr->semData 5.378 - return receivePr->semanticData; 5.379 + return receivePr->dataRetFromReq; 5.380 } 5.381 5.382 5.383 //=========================================================================== 5.384 5.385 -/*Just thin wrapper for now -- semantic request is still a simple thing 5.386 - * (July 3, 2010) 5.387 +/*Uses ID as index into array of flags. If flag already set, resumes from 5.388 + * end-label. Else, sets flag and resumes normally. 5.389 */ 5.390 -inline void 5.391 -SSR__free_semantic_request( SSRSemReq *semReq ) 5.392 +void 5.393 +SSR__start_singleton( int32 singletonID, void *endSingletonLabelAddr, 5.394 + VirtProcr *animPr ) 5.395 { 5.396 - free( semReq ); 5.397 + SSRSemReq reqData; 5.398 + 5.399 + // 5.400 + reqData.reqType = singleton; 5.401 + reqData.singletonID = singletonID; 5.402 + reqData.endJumpPt = endSingletonLabelAddr; 5.403 + 5.404 + VMS__send_sem_request( &reqData, animPr ); 5.405 } 5.406 5.407 +/*This executes the function in the masterVP, so it executes in isolation 5.408 + * from any other copies -- only one copy of the function can ever execute 5.409 + * at a time. 5.410 + * 5.411 + *It suspends to the master, and the request handler takes the function 5.412 + * pointer out of the request and calls it, then resumes the VP. 5.413 + *Only very short functions should be called this way -- for longer-running 5.414 + * isolation, use transaction-start and transaction-end, which run the code 5.415 + * between as work-code. 5.416 + */ 5.417 +void 5.418 +SSR__animate_short_fn_in_isolation( PtrToAtomicFn ptrToFnToExecInMaster, 5.419 + void *data, VirtProcr *animPr ) 5.420 + { 5.421 + SSRSemReq reqData; 5.422 + 5.423 + // 5.424 + reqData.reqType = atomic; 5.425 + reqData.fnToExecInMaster = ptrToFnToExecInMaster; 5.426 + reqData.dataForFn = data; 5.427 + 5.428 + VMS__send_sem_request( &reqData, animPr ); 5.429 + } 5.430 + 5.431 + 5.432 +/*This suspends to the master. 5.433 + *First, it looks at the VP's data, to see the highest transactionID that VP 5.434 + * already has entered. If the current ID is not larger, it throws an 5.435 + * exception stating a bug in the code. Otherwise it puts the current ID 5.436 + * there, and adds the ID to a linked list of IDs entered -- the list is 5.437 + * used to check that exits are properly ordered. 5.438 + *Next it is uses transactionID as index into an array of transaction 5.439 + * structures. 5.440 + *If the "VP_currently_executing" field is non-null, then put requesting VP 5.441 + * into queue in the struct. (At some point a holder will request 5.442 + * end-transaction, which will take this VP from the queue and resume it.) 5.443 + *If NULL, then write requesting into the field and resume. 5.444 + */ 5.445 +void 5.446 +SSR__start_transaction( int32 transactionID, VirtProcr *animPr ) 5.447 + { 5.448 + SSRSemReq reqData; 5.449 + 5.450 + // 5.451 + reqData.sendPr = animPr; 5.452 + reqData.reqType = trans_start; 5.453 + reqData.transID = transactionID; 5.454 + 5.455 + VMS__send_sem_request( &reqData, animPr ); 5.456 + } 5.457 + 5.458 +/*This suspends to the master, then uses transactionID as index into an 5.459 + * array of transaction structures. 5.460 + *It looks at VP_currently_executing to be sure it's same as requesting VP. 5.461 + * If different, throws an exception, stating there's a bug in the code. 5.462 + *Next it looks at the queue in the structure. 5.463 + *If it's empty, it sets VP_currently_executing field to NULL and resumes. 5.464 + *If something in, gets it, sets VP_currently_executing to that VP, then 5.465 + * resumes both. 5.466 + */ 5.467 +void 5.468 +SSR__end_transaction( int32 transactionID, VirtProcr *animPr ) 5.469 + { 5.470 + SSRSemReq reqData; 5.471 + 5.472 + // 5.473 + reqData.sendPr = animPr; 5.474 + reqData.reqType = trans_end; 5.475 + reqData.transID = transactionID; 5.476 + 5.477 + VMS__send_sem_request( &reqData, animPr ); 5.478 + } 5.479 \ No newline at end of file