# HG changeset patch # User Me # Date 1289690358 28800 # Node ID fef69b887df4de1e8b47e22deffe9620337d626f # Parent ad29ff7a02095401d12127bdb0f72beade34ea75 Working version of singleton! Woohoo. Messes with return addr on stack. diff -r ad29ff7a0209 -r fef69b887df4 SSR.h --- a/SSR.h Sat Nov 13 14:38:33 2010 -0800 +++ b/SSR.h Sat Nov 13 15:19:18 2010 -0800 @@ -37,9 +37,9 @@ typedef struct { + void *endInstrAddr; int32 hasBeenStarted; int32 hasFinished; - void *endInstrAddr; PrivQueueStruc *waitQ; } SSRSingleton; @@ -80,7 +80,7 @@ void *ptrToFree; int32 singletonID; - SSRSingleton **singletonAddr; + SSRSingleton **singletonPtrAddr; PtrToAtomicFn fnToExecInMaster; void *dataForFn; diff -r ad29ff7a0209 -r fef69b887df4 SSR_Request_Handlers.c --- a/SSR_Request_Handlers.c Sat Nov 13 14:38:33 2010 -0800 +++ b/SSR_Request_Handlers.c Sat Nov 13 15:19:18 2010 -0800 @@ -407,16 +407,16 @@ SSRSemEnv *semEnv ) { SSRSingleton *singleton; - if( *(semReq->singletonAddr) == NULL ) + if( *(semReq->singletonPtrAddr) == NULL ) { singleton = VMS__malloc( sizeof(SSRSingleton) ); singleton->waitQ = makeVMSPrivQ(); singleton->endInstrAddr = 0x0; singleton->hasBeenStarted = FALSE; singleton->hasFinished = FALSE; - *(semReq->singletonAddr) = singleton; + *(semReq->singletonPtrAddr) = singleton; } else - singleton = *(semReq->singletonAddr); + singleton = *(semReq->singletonPtrAddr); handleStartSingleton_helper( singleton, requestingPr, semEnv ); } @@ -462,7 +462,7 @@ { SSRSingleton *singleton; - singleton = *(semReq->singletonAddr); + singleton = *(semReq->singletonPtrAddr); handleEndSingleton_helper( singleton, requestingPr, semEnv ); } diff -r ad29ff7a0209 -r fef69b887df4 SSR_lib.c --- a/SSR_lib.c Sat Nov 13 14:38:33 2010 -0800 +++ b/SSR_lib.c Sat Nov 13 15:19:18 2010 -0800 @@ -526,18 +526,24 @@ // reqData.reqType = singleton_data_start; - reqData.singletonAddr = singletonAddr; + reqData.singletonPtrAddr = singletonAddr; VMS__send_sem_request( &reqData, animPr ); - if( animPr->dataRetFromReq ) //either 0 or addr of label in end singleton - { animPr->procrID += 10000; - asm volatile("movl %0, %%eax; \ - jmp *%%eax" \ + if( animPr->dataRetFromReq ) //either 0 or end singleton's return addr + { //Assembly code changes the return addr on the stack to the one + // saved into the singleton by the end-singleton-fn + //The return addr is at 0x4(%%ebp) + asm volatile("movl %0, %%eax; \ + movl (%%eax), %%ebx; \ + movl (%%ebx), %%eax; \ + movl %%eax, 0x4(%%ebp);" \ /* outputs */ : \ - /* inputs */ : "m"(animPr->dataRetFromReq) \ + /* inputs */ : "m"(singletonAddr) \ /* clobber */ : "memory", "%eax", "%ebx", "%ecx", "%edx","%edi","%esi"\ ); } + //now, simply return + //will exit either from the start singleton call or the end-singleton call } /*Uses ID as index into array of flags. If flag already set, resumes from @@ -566,25 +572,34 @@ } void -SSR__end_data_singleton( SSRSingleton **singletonAddr, VirtProcr *animPr ) +SSR__end_data_singleton( SSRSingleton **singletonPtrAddr, VirtProcr *animPr ) { SSRSemReq reqData; //don't need this addr until after singleton struct has reached // this function for first time -// write_return_addr_into_singleton( (*(singletonAddr))->endInstrAddr ); - (*(singletonAddr))->endInstrAddr = &&EndDataSingletonInstrAddr; + //do assembly that saves the return addr of this fn call into the + // data singleton -- that data-singleton can only be given to exactly + // one instance in the code of this function. However, can use this + // function in different places for different data-singletons. +// (*(singletonAddr))->endInstrAddr = &&EndDataSingletonInstrAddr; - reqData.reqType = singleton_data_end; - reqData.singletonAddr = singletonAddr; + //Assembly code takes the return addr off the stack and saves + // into the singleton. The first position in the singleton is the + // "endInstrAddr" field, and the return addr is at 0x4(%%ebp) + asm volatile("movl 0x4(%%ebp), %%eax; \ + movl %0, %%ebx; \ + movl (%%ebx), %%ecx; \ + movl %%eax, (%%ecx);" \ + /* outputs */ : \ + /* inputs */ : "m"(singletonPtrAddr) \ + /* clobber */ : "memory", "%eax", "%ebx", "%ecx", "%edx","%edi","%esi"\ + ); + + reqData.reqType = singleton_data_end; + reqData.singletonPtrAddr = singletonPtrAddr; VMS__send_sem_request( &reqData, animPr ); - printf("foo"); - return; -EndDataSingletonInstrAddr: - printf("bar"); - animPr->procrID += 2000; - return; } /*This executes the function in the masterVP, so it executes in isolation