Mercurial > cgi-bin > hgwebdir.cgi > VMS > VMS_Implementations > VMS_impls > VMS__MC_shared_impl
changeset 25:c556193f7211
Linux Version -- first set of mods changing from win to linux
| author | Me |
|---|---|
| date | Sat, 24 Jul 2010 08:58:47 -0700 |
| parents | 2b161e1a50ee |
| children | 668278fa7a63 |
| files | CoreLoop.c VMS.c VMS.h |
| diffstat | 3 files changed, 77 insertions(+), 45 deletions(-) [+] |
line diff
1.1 --- a/CoreLoop.c Wed Jul 07 13:15:54 2010 -0700 1.2 +++ b/CoreLoop.c Sat Jul 24 08:58:47 2010 -0700 1.3 @@ -8,9 +8,10 @@ 1.4 #include "VMS.h" 1.5 #include "Queue_impl/BlockingQueue.h" 1.6 1.7 -#include <windows.h> 1.8 #include <stdio.h> 1.9 #include <time.h> 1.10 +#include <pthread.h> 1.11 +#include <sched.h> 1.12 1.13 1.14 /*This is the loop that runs in the PThread pinned to each core 1.15 @@ -20,18 +21,35 @@ 1.16 * write the slave's "Done" flag and repeat. 1.17 */ 1.18 //pthread_create requires ptr to func that takes void * and returns void * 1.19 -DWORD WINAPI 1.20 -coreLoop( LPVOID paramsIn ) 1.21 +void * 1.22 +coreLoop( void *paramsIn ) 1.23 { 1.24 ThdParams *coreLoopThdParams; 1.25 VirtProcr *currPr; 1.26 CASQueueStruc *workQ; 1.27 + unsigned long coreMask; //has 1 in bit positions of allowed cores 1.28 + int errorCode; 1.29 1.30 // Get the communication queues out of the param passed in 1.31 coreLoopThdParams = (ThdParams *)paramsIn; 1.32 - //Winblows requires pinning thd to core inside thread-function 1.33 + 1.34 + //wait until signalled that setup is complete 1.35 + pthread_mutex_lock( _VMSMasterEnv->suspend_mutex ); 1.36 + while( !(_VMSMasterEnv->setupComplete) ) 1.37 + { 1.38 + pthread_cond_wait( _VMSMasterEnv->suspend_cond, 1.39 + _VMSMasterEnv->suspend_mutex ); 1.40 + } 1.41 + pthread_mutex_unlock( _VMSMasterEnv->suspend_mutex ); 1.42 + 1.43 + //set thread affinity 1.44 + //Linux requires pinning thd to core inside thread-function 1.45 //Designate a core by a 1 in bit-position corresponding to the core 1.46 - SetThreadAffinityMask(GetCurrentThread(),1 << coreLoopThdParams->coreNum); 1.47 + coreMask = 1 << coreLoopThdParams->coreNum 1.48 + errorCode = 1.49 + pthread_setaffinity_np( pthread_self(), sizeof(coreMask), coreMask); 1.50 + 1.51 + if(errorCode){ printf("\nset affinity failure\n"); exit(); } 1.52 1.53 1.54 //Save addr of "end core loop" label - jump to it to shut down coreloop 1.55 @@ -57,7 +75,7 @@ 1.56 currPr = (VirtProcr *) readCASQ( workQ ); 1.57 1.58 // printf("core %d loop procr addr: %d\n", coreLoopThdParams->coreNum, \ 1.59 - (int)currPr ); fflush(stdin); 1.60 +// (int)currPr ); fflush(stdin); 1.61 currPr->coreLoopStartPt = &&CoreLoopStartPt; //to be sure.(GCC specific) 1.62 1.63 currPr->coreAnimatedBy = coreLoopThdParams->coreNum; 1.64 @@ -99,5 +117,5 @@ 1.65 1.66 //jmp to here when want to shut down the VMS system 1.67 EndCoreLoop: 1.68 - ExitThread( 0 ); 1.69 + pthread_exit( NULL ); 1.70 }
2.1 --- a/VMS.c Wed Jul 07 13:15:54 2010 -0700 2.2 +++ b/VMS.c Sat Jul 24 08:58:47 2010 -0700 2.3 @@ -81,27 +81,33 @@ 2.4 2.5 //======================================================================== 2.6 // Create the Threads 2.7 - int coreIdx; 2.8 + int coreIdx, retCode; 2.9 + #define thdAttrs NULL 2.10 2.11 + _VMSMasterEnv->setupComplete = 0; 2.12 + _VMSMasterEnv->suspend_mutex = PTHREAD_MUTEX_INITIALIZER; 2.13 + _VMSMasterEnv->suspend_cond = PTHREAD_COND_INITIALIZER; 2.14 + 2.15 + //Need the threads to be created suspended, and wait for a signal 2.16 + // before proceeding -- gives time after creating to initialize other 2.17 + // stuff before the coreLoops set off. 2.18 + 2.19 //Make params given to the win threads that animate the core loops 2.20 for( coreIdx=0; coreIdx < NUM_CORES; coreIdx++ ) 2.21 { coreLoopThdParams[coreIdx] = malloc( sizeof(ThdParams) ); 2.22 coreLoopThdParams[coreIdx]->coreNum = coreIdx; 2.23 2.24 - //make the core loop threads, born in suspended state 2.25 - coreLoopThdHandles[ coreIdx ] = 2.26 - CreateThread ( NULL, // Security attributes 2.27 - 0, // Stack size 2.28 - coreLoop, 2.29 - coreLoopThdParams[coreIdx], 2.30 - CREATE_SUSPENDED, 2.31 - &(coreLoopThdIds[coreIdx]) 2.32 - ); 2.33 + retCode = 2.34 + pthread_create( &(coreLoopThdHandles[coreIdx]), 2.35 + thdAttrs, 2.36 + &coreLoop, 2.37 + (void *)(coreLoopThdParams[coreIdx]) ); 2.38 + if(!retCode){printf("ERROR creating thread: %d\n", retCode); exit();} 2.39 } 2.40 2.41 + 2.42 } 2.43 2.44 - 2.45 void 2.46 create_sched_slots( MasterEnv *masterEnv ) 2.47 { SchedSlot **schedSlots, **filledSlots; 2.48 @@ -132,37 +138,39 @@ 2.49 { int coreIdx; 2.50 //Start the core loops running 2.51 //=========================================================================== 2.52 - LARGE_INTEGER stPerfCount, endPerfCount, countFreq; 2.53 + TSCount startCount, endCount; 2.54 unsigned long long count = 0, freq = 0; 2.55 - double runTime; 2.56 + double runTime; 2.57 2.58 - QueryPerformanceCounter( &stPerfCount ); 2.59 - 2.60 - //start them running 2.61 - for( coreIdx=0; coreIdx < NUM_CORES; coreIdx++ ) 2.62 - { //Create the threads 2.63 - ResumeThread( coreLoopThdHandles[coreIdx] ); //starts thread 2.64 - } 2.65 - 2.66 + startCount = getTSCount(); 2.67 + 2.68 + //tell the core loop threads that setup is complete 2.69 + //get lock, to lock out any threads still starting up -- they'll see 2.70 + // that setupComplete is true before entering while loop, and so never 2.71 + // wait on the condition 2.72 + pthread_mutex_lock( _VMSMasterEnv->suspend_mutex ); 2.73 + _VMSMasterEnv->setupComplete = 1; 2.74 + pthread_mutex_unlock( _VMSMasterEnv->suspend_mutex ); 2.75 + pthread_cond_broadcast( _VMSMasterEnv->suspend_cond ); 2.76 + 2.77 + 2.78 //wait for all to complete 2.79 for( coreIdx=0; coreIdx < NUM_CORES; coreIdx++ ) 2.80 { 2.81 - WaitForSingleObject(coreLoopThdHandles[coreIdx], INFINITE); 2.82 + pthread_join( coreLoopThdHandles[coreIdx], NULL ); 2.83 } 2.84 - 2.85 + 2.86 //NOTE: do not clean up VMS env here -- semantic layer has to have 2.87 // a chance to clean up its environment first, then do a call to free 2.88 // the Master env and rest of VMS locations 2.89 2.90 - QueryPerformanceCounter( &endPerfCount ); 2.91 - count = endPerfCount.QuadPart - stPerfCount.QuadPart; 2.92 2.93 - QueryPerformanceFrequency( &countFreq ); 2.94 - freq = countFreq.QuadPart; 2.95 - runTime = (double)count / (double)freq; 2.96 + endCount = getTSCount(); 2.97 + count = endCount - startCount; 2.98 2.99 - printf("\n Time startup to shutdown: %f\n", runTime); 2.100 - fflush( stdin ); 2.101 + runTime = (double)count / (double)TSCOUNT_FREQ; 2.102 + 2.103 + printf("\n Time startup to shutdown: %f\n", runTime); fflush( stdin ); 2.104 } 2.105 2.106
3.1 --- a/VMS.h Wed Jul 07 13:15:54 2010 -0700 3.2 +++ b/VMS.h Sat Jul 24 08:58:47 2010 -0700 3.3 @@ -8,11 +8,11 @@ 3.4 3.5 #ifndef _VMS_H 3.6 #define _VMS_H 3.7 +#define __USE_GNU 3.8 3.9 #include "VMS_primitive_data_types.h" 3.10 #include "Queue_impl/BlockingQueue.h" 3.11 -#include <windows.h> 3.12 -#include <winbase.h> 3.13 +#include "pthread.h" 3.14 3.15 //This value is the number of hardware threads in the shared memory 3.16 // machine 3.17 @@ -108,34 +108,36 @@ 3.18 int stillRunning; 3.19 3.20 VirtProcr *masterVirtPr; 3.21 + 3.22 void *semanticEnv; 3.23 void *OSEventStruc; //for future, when add I/O to BLIS 3.24 3.25 void *coreLoopShutDownPt; //addr to jump to to shut down a coreLoop 3.26 + 3.27 + int setupComplete; 3.28 + pthread_mutex_t suspend_mutex; 3.29 + pthread_cond_t suspend_cond; 3.30 } 3.31 MasterEnv; 3.32 3.33 3.34 //========================================================== 3.35 3.36 -DWORD WINAPI coreLoop( LPVOID paramsIn ); 3.37 -//void * coreLoop( void *paramsIn ); //standard PThreads fn prototype 3.38 +void * coreLoop( void *paramsIn ); //standard PThreads fn prototype 3.39 void masterLoop( void *initData, VirtProcr *masterPr ); 3.40 3.41 3.42 //===================== Global Vars =================== 3.43 3.44 3.45 -HANDLE coreLoopThdHandles[ NUM_CORES ]; //windows handle to thread 3.46 +pthread_t coreLoopThdHandles[ NUM_CORES ]; //pthread's virt-procr state 3.47 ThdParams *coreLoopThdParams[ NUM_CORES ]; 3.48 -DWORD coreLoopThdIds[ NUM_CORES ]; 3.49 3.50 - //TODO: Debug: figure out if need to be volatile or not 3.51 volatile MasterEnv *_VMSMasterEnv; 3.52 3.53 //workQ is global, static, and volatile so that core loop has its location 3.54 // hard coded, and reloads every time through the loop -- that way don't 3.55 - // need to save any regs used by core loop (will see if this really works) 3.56 + // need to save any regs used by core loop 3.57 volatile CASQueueStruc *_VMSWorkQ; 3.58 3.59 //========================== 3.60 @@ -195,6 +197,10 @@ 3.61 3.62 typedef unsigned long long TSCount; 3.63 3.64 + //Frequency of TS counts 3.65 + //TODO: change freq for each machine 3.66 +#define TSCOUNT_FREQ 3180000000 3.67 + 3.68 #define saveTimeStampCountInto(low, high) \ 3.69 asm volatile("RDTSC; \ 3.70 movl %%eax, %0; \
