# HG changeset patch # User Me # Date 1279987127 25200 # Node ID c556193f7211ca3759f3e563179de364e2614850 # Parent 2b161e1a50ee9f97cca1f4637f14f89e80da14c9 Linux Version -- first set of mods changing from win to linux diff -r 2b161e1a50ee -r c556193f7211 CoreLoop.c --- a/CoreLoop.c Wed Jul 07 13:15:54 2010 -0700 +++ b/CoreLoop.c Sat Jul 24 08:58:47 2010 -0700 @@ -8,9 +8,10 @@ #include "VMS.h" #include "Queue_impl/BlockingQueue.h" -#include #include #include +#include +#include /*This is the loop that runs in the PThread pinned to each core @@ -20,18 +21,35 @@ * write the slave's "Done" flag and repeat. */ //pthread_create requires ptr to func that takes void * and returns void * -DWORD WINAPI -coreLoop( LPVOID paramsIn ) +void * +coreLoop( void *paramsIn ) { ThdParams *coreLoopThdParams; VirtProcr *currPr; CASQueueStruc *workQ; + unsigned long coreMask; //has 1 in bit positions of allowed cores + int errorCode; // Get the communication queues out of the param passed in coreLoopThdParams = (ThdParams *)paramsIn; - //Winblows requires pinning thd to core inside thread-function + + //wait until signalled that setup is complete + pthread_mutex_lock( _VMSMasterEnv->suspend_mutex ); + while( !(_VMSMasterEnv->setupComplete) ) + { + pthread_cond_wait( _VMSMasterEnv->suspend_cond, + _VMSMasterEnv->suspend_mutex ); + } + pthread_mutex_unlock( _VMSMasterEnv->suspend_mutex ); + + //set thread affinity + //Linux requires pinning thd to core inside thread-function //Designate a core by a 1 in bit-position corresponding to the core - SetThreadAffinityMask(GetCurrentThread(),1 << coreLoopThdParams->coreNum); + coreMask = 1 << coreLoopThdParams->coreNum + errorCode = + pthread_setaffinity_np( pthread_self(), sizeof(coreMask), coreMask); + + if(errorCode){ printf("\nset affinity failure\n"); exit(); } //Save addr of "end core loop" label - jump to it to shut down coreloop @@ -57,7 +75,7 @@ currPr = (VirtProcr *) readCASQ( workQ ); // printf("core %d loop procr addr: %d\n", coreLoopThdParams->coreNum, \ - (int)currPr ); fflush(stdin); +// (int)currPr ); fflush(stdin); currPr->coreLoopStartPt = &&CoreLoopStartPt; //to be sure.(GCC specific) currPr->coreAnimatedBy = coreLoopThdParams->coreNum; @@ -99,5 +117,5 @@ //jmp to here when want to shut down the VMS system EndCoreLoop: - ExitThread( 0 ); + pthread_exit( NULL ); } diff -r 2b161e1a50ee -r c556193f7211 VMS.c --- a/VMS.c Wed Jul 07 13:15:54 2010 -0700 +++ b/VMS.c Sat Jul 24 08:58:47 2010 -0700 @@ -81,27 +81,33 @@ //======================================================================== // Create the Threads - int coreIdx; + int coreIdx, retCode; + #define thdAttrs NULL + _VMSMasterEnv->setupComplete = 0; + _VMSMasterEnv->suspend_mutex = PTHREAD_MUTEX_INITIALIZER; + _VMSMasterEnv->suspend_cond = PTHREAD_COND_INITIALIZER; + + //Need the threads to be created suspended, and wait for a signal + // before proceeding -- gives time after creating to initialize other + // stuff before the coreLoops set off. + //Make params given to the win threads that animate the core loops for( coreIdx=0; coreIdx < NUM_CORES; coreIdx++ ) { coreLoopThdParams[coreIdx] = malloc( sizeof(ThdParams) ); coreLoopThdParams[coreIdx]->coreNum = coreIdx; - //make the core loop threads, born in suspended state - coreLoopThdHandles[ coreIdx ] = - CreateThread ( NULL, // Security attributes - 0, // Stack size - coreLoop, - coreLoopThdParams[coreIdx], - CREATE_SUSPENDED, - &(coreLoopThdIds[coreIdx]) - ); + retCode = + pthread_create( &(coreLoopThdHandles[coreIdx]), + thdAttrs, + &coreLoop, + (void *)(coreLoopThdParams[coreIdx]) ); + if(!retCode){printf("ERROR creating thread: %d\n", retCode); exit();} } + } - void create_sched_slots( MasterEnv *masterEnv ) { SchedSlot **schedSlots, **filledSlots; @@ -132,37 +138,39 @@ { int coreIdx; //Start the core loops running //=========================================================================== - LARGE_INTEGER stPerfCount, endPerfCount, countFreq; + TSCount startCount, endCount; unsigned long long count = 0, freq = 0; - double runTime; + double runTime; - QueryPerformanceCounter( &stPerfCount ); - - //start them running - for( coreIdx=0; coreIdx < NUM_CORES; coreIdx++ ) - { //Create the threads - ResumeThread( coreLoopThdHandles[coreIdx] ); //starts thread - } - + startCount = getTSCount(); + + //tell the core loop threads that setup is complete + //get lock, to lock out any threads still starting up -- they'll see + // that setupComplete is true before entering while loop, and so never + // wait on the condition + pthread_mutex_lock( _VMSMasterEnv->suspend_mutex ); + _VMSMasterEnv->setupComplete = 1; + pthread_mutex_unlock( _VMSMasterEnv->suspend_mutex ); + pthread_cond_broadcast( _VMSMasterEnv->suspend_cond ); + + //wait for all to complete for( coreIdx=0; coreIdx < NUM_CORES; coreIdx++ ) { - WaitForSingleObject(coreLoopThdHandles[coreIdx], INFINITE); + pthread_join( coreLoopThdHandles[coreIdx], NULL ); } - + //NOTE: do not clean up VMS env here -- semantic layer has to have // a chance to clean up its environment first, then do a call to free // the Master env and rest of VMS locations - QueryPerformanceCounter( &endPerfCount ); - count = endPerfCount.QuadPart - stPerfCount.QuadPart; - QueryPerformanceFrequency( &countFreq ); - freq = countFreq.QuadPart; - runTime = (double)count / (double)freq; + endCount = getTSCount(); + count = endCount - startCount; - printf("\n Time startup to shutdown: %f\n", runTime); - fflush( stdin ); + runTime = (double)count / (double)TSCOUNT_FREQ; + + printf("\n Time startup to shutdown: %f\n", runTime); fflush( stdin ); } diff -r 2b161e1a50ee -r c556193f7211 VMS.h --- a/VMS.h Wed Jul 07 13:15:54 2010 -0700 +++ b/VMS.h Sat Jul 24 08:58:47 2010 -0700 @@ -8,11 +8,11 @@ #ifndef _VMS_H #define _VMS_H +#define __USE_GNU #include "VMS_primitive_data_types.h" #include "Queue_impl/BlockingQueue.h" -#include -#include +#include "pthread.h" //This value is the number of hardware threads in the shared memory // machine @@ -108,34 +108,36 @@ int stillRunning; VirtProcr *masterVirtPr; + void *semanticEnv; void *OSEventStruc; //for future, when add I/O to BLIS void *coreLoopShutDownPt; //addr to jump to to shut down a coreLoop + + int setupComplete; + pthread_mutex_t suspend_mutex; + pthread_cond_t suspend_cond; } MasterEnv; //========================================================== -DWORD WINAPI coreLoop( LPVOID paramsIn ); -//void * coreLoop( void *paramsIn ); //standard PThreads fn prototype +void * coreLoop( void *paramsIn ); //standard PThreads fn prototype void masterLoop( void *initData, VirtProcr *masterPr ); //===================== Global Vars =================== -HANDLE coreLoopThdHandles[ NUM_CORES ]; //windows handle to thread +pthread_t coreLoopThdHandles[ NUM_CORES ]; //pthread's virt-procr state ThdParams *coreLoopThdParams[ NUM_CORES ]; -DWORD coreLoopThdIds[ NUM_CORES ]; - //TODO: Debug: figure out if need to be volatile or not volatile MasterEnv *_VMSMasterEnv; //workQ is global, static, and volatile so that core loop has its location // hard coded, and reloads every time through the loop -- that way don't - // need to save any regs used by core loop (will see if this really works) + // need to save any regs used by core loop volatile CASQueueStruc *_VMSWorkQ; //========================== @@ -195,6 +197,10 @@ typedef unsigned long long TSCount; + //Frequency of TS counts + //TODO: change freq for each machine +#define TSCOUNT_FREQ 3180000000 + #define saveTimeStampCountInto(low, high) \ asm volatile("RDTSC; \ movl %%eax, %0; \