Mercurial > cgi-bin > hgwebdir.cgi > VMS > VMS_Implementations > VMS_impls > VMS__MC_shared_impl
diff MasterLoop.c @ 0:a5fe730dfc2e
Initial add -- for sourceforge repositories
| author | Me |
|---|---|
| date | Sat, 22 May 2010 19:37:58 -0700 |
| parents | |
| children | ca61f77ed417 |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/MasterLoop.c Sat May 22 19:37:58 2010 -0700 1.3 @@ -0,0 +1,113 @@ 1.4 +/* 1.5 + * Copyright 2010 OpenSourceCodeStewardshipFoundation 1.6 + * 1.7 + * Licensed under BSD 1.8 + */ 1.9 + 1.10 + 1.11 + 1.12 +#include <stdio.h> 1.13 +#include <malloc.h> 1.14 + 1.15 +#include "VMS.h" 1.16 + 1.17 + 1.18 + 1.19 +/*This code is animated by the virtual Master processor. 1.20 + *Note, it is animated on a different level in virtual processor hierarchy 1.21 + * than the CoreLoop -- this is the code pointed to in a work-unit that the 1.22 + * coreLoop jumps to 1.23 + * 1.24 + *Polls each virtual slave exactly once, hands any requests made by the slave 1.25 + * to the "request handler" plug-in function 1.26 + * 1.27 + *Any slaves that have no work-unit assigned are given to the "schedule" 1.28 + * plug-in function, which tries to assign a work-unit to it. 1.29 + * 1.30 + *When all slaves that need work-units have been given to the schedule plug-in, 1.31 + * half of the ones that were successfully scheduled are put into the work 1.32 + * queue, then a continuation of this function is put in, then the rest of the 1.33 + * slaves that were successfully scheduled. 1.34 + * 1.35 + *The first thing this function does is busy-wait until the previous work-unit 1.36 + * running this function is done. This ensures it doesn't overlap with 1.37 + * tail-end of previous -- IE, continuation may sneak through queue before 1.38 + * previous done putting second half of scheduled slaves in. This is the only 1.39 + * race condition. 1.40 + * 1.41 + */ 1.42 + 1.43 +void masterLoop( void *data ) 1.44 + { bool8 success; 1.45 + int slaveIdx, numScheduled, numInFirstHalf, schedSlaveIdx; 1.46 + VMSProcr currSlave, *virtSlaves; 1.47 + MasterEnv *masterEnv; 1.48 + SlaveScheduler slaveScheduler; 1.49 + RequestHandler requestHandler; 1.50 + 1.51 + 1.52 + masterEnv = (MasterEnv *)data; 1.53 + 1.54 + requestHandler = masterEnv->requestHandler; 1.55 + slaveScheduler = masterEnv->slaveScheduler; 1.56 + virtSlaves = masterEnv->virtSlaves; 1.57 + 1.58 + //if another continuation of Master still running, busy-wait 1.59 + while( masterEnv->stillRunning ) /*busy wait*/ ; 1.60 + 1.61 + //this is the only master running now, set flag again 1.62 + masterEnv->stillRunning = 1; 1.63 + 1.64 + //prepare for scheduling 1.65 + masterEnv->numScheduled = 0; 1.66 + 1.67 + //Poll each slave structure's Done flag 1.68 + for( slaveIdx = 0; slaveIdx < NUM_SLAVES; slaveIdx++) 1.69 + { 1.70 + currSlave = virtSlaves[ slaveIdx ]; 1.71 + 1.72 + if( currSlave->workIsDone ) 1.73 + { 1.74 + currSlave->workIsDone = FALSE; 1.75 + currSlave->needsWorkAssigned = TRUE; 1.76 + 1.77 + //process requests from slave to master 1.78 + (*requestHandler)( currSlave ); 1.79 + } 1.80 + if( currSlave->needsWorkAssigned ) 1.81 + { //give slave a new work-unit 1.82 + success = 1.83 + (*slaveScheduler)( currSlave, masterEnv ); 1.84 + 1.85 + if( success ) 1.86 + { addToVect( currSlave, &(masterEnv->scheduledSlaves), 1.87 + &(masterEnv->numScheduled) ); 1.88 + currSlave->needsWorkAssigned = FALSE; 1.89 + } 1.90 + } 1.91 + } 1.92 + 1.93 + //put half scheduled slaves in, then continuation, then other half 1.94 + VMSProcr **scheduledSlaves; 1.95 + numInFirstHalf = masterEnv->numScheduled / 2; 1.96 + scheduledSlaves = masterEnv->scheduledSlaves; 1.97 + for( schedSlaveIdx = 0; schedSlaveIdx < numInFirstHalf; schedSlaveIdx++) 1.98 + { 1.99 + writeQ( scheduledSlaves[ schedSlaveIdx ], workQ ); 1.100 + } 1.101 + 1.102 + //enqueue continuation of this loop 1.103 + // note that After this enqueue, continuation might sneak through 1.104 + writeQ( masterEnv->masterWorkUnit, workQ ); 1.105 + for( schedSlaveIdx = numInFirstHalf; 1.106 + schedSlaveIdx < numScheduled; 1.107 + schedSlaveIdx++) 1.108 + { 1.109 + writeQ( scheduledSlaves[ schedSlaveIdx ]->workUnitToDo, workQ ); 1.110 + } 1.111 + 1.112 + //all done, so okay for continuation to proceed 1.113 + masterEnv->stillRunning = 0; 1.114 + } 1.115 + 1.116 +
