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