# HG changeset patch # User Nina Engelhardt # Date 1368805775 -7200 # Node ID b58fb13433779bc75940ccc310118c331f9c3023 # Parent 67b684afa7366a60c782eccf30c9c2a4b83c30f9 remove need for end_thread() diff -r 67b684afa736 -r b58fb1343377 HW_Dependent_Primitives/VMS__primitives.c --- a/HW_Dependent_Primitives/VMS__primitives.c Wed May 15 15:21:46 2013 +0200 +++ b/HW_Dependent_Primitives/VMS__primitives.c Fri May 17 17:49:35 2013 +0200 @@ -52,7 +52,41 @@ slaveVP->stackPtr = stackPtr; slaveVP->framePtr = 0; } +void +VMS_int__reset_slaveVP_to_TopLvlFnWrapper( SlaveVP *slaveVP, TopLevelFnWrapper fnWrapper, TopLevelFnPtr fnPtr, + void *dataParam){ + void *stackPtr; +// Start of Hardware dependent part + + //Set slave's instr pointer to a helper Fn that copies params from stack + slaveVP->resumeInstrPtr = (TopLevelFnPtr)&startUpTopLevelFn; + + //fnPtr takes two params -- void *dataParam & void *animSlv + // Stack grows *down*, so start it at highest stack addr, minus room + // for 2 params + return addr. Do ptr arith in terms of bytes.. + stackPtr = + (uint8 *)slaveVP->startOfStack + VIRT_PROCR_STACK_SIZE - 3*sizeof(void*); + + //setup __cdecl on stack + //Normally, return Addr is in loc pointed to by stackPtr, but doing a + // trick for 64 bit arch, where put ptr to top-level fn there instead, + // and set resumeInstrPtr to a helper-fn that copies the top-level + // fn ptr and params into registers. + //Then, dataParam is at stackPtr + 8 bytes, & animating SlaveVP above + //Do ptr arith in terms of pointers + *((void**)stackPtr + 2 ) = dataParam; //rightmost param + *((void**)stackPtr + 1 ) = fnPtr; //next param to left + *((void**)stackPtr) = (void*)fnWrapper; //copied to reg by helper Fn + + +// end of Hardware dependent part + + //core controller will switch to stack & frame pointers stored in slave, + // can't use this fn if have state on stack that needs preserving. + slaveVP->stackPtr = stackPtr; + slaveVP->framePtr = 0; +} /*Preserve the stack, pushing the __cdecl structure onto it * For 64 bits, params passed in regs, so point slave to helper assembly diff -r 67b684afa736 -r b58fb1343377 HW_Dependent_Primitives/VMS__primitives_asm.s --- a/HW_Dependent_Primitives/VMS__primitives_asm.s Wed May 15 15:21:46 2013 +0200 +++ b/HW_Dependent_Primitives/VMS__primitives_asm.s Fri May 17 17:49:35 2013 +0200 @@ -16,7 +16,7 @@ // the top-level function, which was pointed to by the stack-ptr .globl startUpTopLevelFn startUpTopLevelFn: - movq %rdi , %rsi #get second argument from first argument of switchSlv + movq 0x10(%rsp), %rsi #get second argument from stack movq 0x08(%rsp), %rdi #get first argument from stack movq (%rsp) , %rax #get top-level function's addr from stack jmp *%rax #jump to the top-level function diff -r 67b684afa736 -r b58fb1343377 VMS.h --- a/VMS.h Wed May 15 15:21:46 2013 +0200 +++ b/VMS.h Fri May 17 17:49:35 2013 +0200 @@ -45,6 +45,7 @@ typedef SlaveVP *(*SlaveAssigner) ( void *, AnimSlot*); //semEnv, slot for HW info typedef void (*RequestHandler) ( SlaveVP *, void * ); //prWReqst, semEnv typedef void (*TopLevelFnPtr) ( void * ); //initData, animSlv +typedef void (*TopLevelFnWrapper)( TopLevelFnPtr, void*); //(*fn)(arg) typedef void TopLevelFn ( void * ); //initData, animSlv typedef void (*ResumeSlvFnPtr) ( SlaveVP *, void * ); //=========== MEASUREMENT STUFF ========== @@ -293,6 +294,9 @@ #define VMS_PI__create_slaveVP VMS_int__create_slaveVP #define VMS_WL__create_slaveVP VMS_int__create_slaveVP +SlaveVP * +VMS_int__create_slaveVP_with_wrapper( TopLevelFnWrapper fnWrapper, TopLevelFnPtr fnPtr, void *dataParam ); + //Use this to create processor inside entry point & other places outside // the VMS system boundary (IE, don't animate with a SlaveVP or MasterVP) SlaveVP * @@ -302,6 +306,10 @@ VMS_int__create_slaveVP_helper( SlaveVP *newSlv, TopLevelFnPtr fnPtr, void *dataParam, void *stackLocs ); +SlaveVP * +VMS_int__create_slaveVP_helper_with_wrapper( SlaveVP *newSlv, TopLevelFnWrapper fnWrapper, TopLevelFnPtr fnPtr, + void *dataParam, void *stackLocs ); + void VMS_int__reset_slaveVP_to_TopLvlFn( SlaveVP *slaveVP, TopLevelFnPtr fnPtr, void *dataParam); @@ -315,6 +323,10 @@ void *param1, void *param2); void +VMS_int__reset_slaveVP_to_TopLvlFnWrapper( SlaveVP *slaveVP, TopLevelFnWrapper fnWrapper, TopLevelFnPtr fnPtr, + void *dataParam); + +void VMS_int__dissipate_slaveVP( SlaveVP *slaveToDissipate ); #define VMS_PI__dissipate_slaveVP VMS_int__dissipate_slaveVP //WL: dissipate a SlaveVP by sending a request diff -r 67b684afa736 -r b58fb1343377 VMS__int.c --- a/VMS__int.c Wed May 15 15:21:46 2013 +0200 +++ b/VMS__int.c Fri May 17 17:49:35 2013 +0200 @@ -42,6 +42,21 @@ return VMS_int__create_slaveVP_helper( newSlv, fnPtr, dataParam, stackLocs ); } +SlaveVP * +VMS_int__create_slaveVP_with_wrapper( TopLevelFnWrapper fnWrapper, TopLevelFnPtr fnPtr, void *dataParam ) + { SlaveVP *newSlv; + void *stackLocs; + + newSlv = VMS_int__malloc( sizeof(SlaveVP) ); + stackLocs = memalign(16, VIRT_PROCR_STACK_SIZE ); + if( stackLocs == 0 ) + { perror("VMS_int__malloc stack"); exit(1); } + + _VMSMasterEnv->numSlavesAlive += 1; + + return VMS_int__create_slaveVP_helper_with_wrapper( newSlv, fnWrapper, fnPtr, dataParam, stackLocs ); + } + /* "ext" designates that it's for use outside the VMS system -- should only * be called from main thread or other thread -- never from code animated by * a VMS virtual processor. @@ -205,6 +220,32 @@ return newSlv; } +SlaveVP * +VMS_int__create_slaveVP_helper_with_wrapper( SlaveVP *newSlv, TopLevelFnWrapper fnWrapper, TopLevelFnPtr fnPtr, + void *dataParam, void *stackLocs ) + { + newSlv->startOfStack = stackLocs; + newSlv->slaveID = _VMSMasterEnv->numSlavesCreated++; + newSlv->requests = NULL; + newSlv->animSlotAssignedTo = NULL; + newSlv->typeOfVP = Slave; + newSlv->assignCount = 0; + + VMS_int__reset_slaveVP_to_TopLvlFnWrapper( newSlv, fnWrapper, fnPtr, dataParam ); + + //============================= MEASUREMENT STUFF ======================== + #ifdef SERVICE__TURN_ON_STATS_PROBES + //TODO: make this TSCHiLow or generic equivalent + //struct timeval timeStamp; + //gettimeofday( &(timeStamp), NULL); + //newSlv->createPtInSecs = timeStamp.tv_sec +(timeStamp.tv_usec/1000000.0) - + // _VMSMasterEnv->createPtInSecs; + #endif + //======================================================================== + + return newSlv; + } + /*Later, improve this -- for now, just exits the application after printing * the error message.