Mercurial > cgi-bin > hgwebdir.cgi > VMS > VMS_Implementations > VMS_impls > VMS__MC_shared_impl
comparison MasterLoop.c @ 0:a5fe730dfc2e
Initial add -- for sourceforge repositories
| author | Me |
|---|---|
| date | Sat, 22 May 2010 19:37:58 -0700 |
| parents | |
| children | ca61f77ed417 |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:4c2da6146c19 |
|---|---|
| 1 /* | |
| 2 * Copyright 2010 OpenSourceCodeStewardshipFoundation | |
| 3 * | |
| 4 * Licensed under BSD | |
| 5 */ | |
| 6 | |
| 7 | |
| 8 | |
| 9 #include <stdio.h> | |
| 10 #include <malloc.h> | |
| 11 | |
| 12 #include "VMS.h" | |
| 13 | |
| 14 | |
| 15 | |
| 16 /*This code is animated by the virtual Master processor. | |
| 17 *Note, it is animated on a different level in virtual processor hierarchy | |
| 18 * than the CoreLoop -- this is the code pointed to in a work-unit that the | |
| 19 * coreLoop jumps to | |
| 20 * | |
| 21 *Polls each virtual slave exactly once, hands any requests made by the slave | |
| 22 * to the "request handler" plug-in function | |
| 23 * | |
| 24 *Any slaves that have no work-unit assigned are given to the "schedule" | |
| 25 * plug-in function, which tries to assign a work-unit to it. | |
| 26 * | |
| 27 *When all slaves that need work-units have been given to the schedule plug-in, | |
| 28 * half of the ones that were successfully scheduled are put into the work | |
| 29 * queue, then a continuation of this function is put in, then the rest of the | |
| 30 * slaves that were successfully scheduled. | |
| 31 * | |
| 32 *The first thing this function does is busy-wait until the previous work-unit | |
| 33 * running this function is done. This ensures it doesn't overlap with | |
| 34 * tail-end of previous -- IE, continuation may sneak through queue before | |
| 35 * previous done putting second half of scheduled slaves in. This is the only | |
| 36 * race condition. | |
| 37 * | |
| 38 */ | |
| 39 | |
| 40 void masterLoop( void *data ) | |
| 41 { bool8 success; | |
| 42 int slaveIdx, numScheduled, numInFirstHalf, schedSlaveIdx; | |
| 43 VMSProcr currSlave, *virtSlaves; | |
| 44 MasterEnv *masterEnv; | |
| 45 SlaveScheduler slaveScheduler; | |
| 46 RequestHandler requestHandler; | |
| 47 | |
| 48 | |
| 49 masterEnv = (MasterEnv *)data; | |
| 50 | |
| 51 requestHandler = masterEnv->requestHandler; | |
| 52 slaveScheduler = masterEnv->slaveScheduler; | |
| 53 virtSlaves = masterEnv->virtSlaves; | |
| 54 | |
| 55 //if another continuation of Master still running, busy-wait | |
| 56 while( masterEnv->stillRunning ) /*busy wait*/ ; | |
| 57 | |
| 58 //this is the only master running now, set flag again | |
| 59 masterEnv->stillRunning = 1; | |
| 60 | |
| 61 //prepare for scheduling | |
| 62 masterEnv->numScheduled = 0; | |
| 63 | |
| 64 //Poll each slave structure's Done flag | |
| 65 for( slaveIdx = 0; slaveIdx < NUM_SLAVES; slaveIdx++) | |
| 66 { | |
| 67 currSlave = virtSlaves[ slaveIdx ]; | |
| 68 | |
| 69 if( currSlave->workIsDone ) | |
| 70 { | |
| 71 currSlave->workIsDone = FALSE; | |
| 72 currSlave->needsWorkAssigned = TRUE; | |
| 73 | |
| 74 //process requests from slave to master | |
| 75 (*requestHandler)( currSlave ); | |
| 76 } | |
| 77 if( currSlave->needsWorkAssigned ) | |
| 78 { //give slave a new work-unit | |
| 79 success = | |
| 80 (*slaveScheduler)( currSlave, masterEnv ); | |
| 81 | |
| 82 if( success ) | |
| 83 { addToVect( currSlave, &(masterEnv->scheduledSlaves), | |
| 84 &(masterEnv->numScheduled) ); | |
| 85 currSlave->needsWorkAssigned = FALSE; | |
| 86 } | |
| 87 } | |
| 88 } | |
| 89 | |
| 90 //put half scheduled slaves in, then continuation, then other half | |
| 91 VMSProcr **scheduledSlaves; | |
| 92 numInFirstHalf = masterEnv->numScheduled / 2; | |
| 93 scheduledSlaves = masterEnv->scheduledSlaves; | |
| 94 for( schedSlaveIdx = 0; schedSlaveIdx < numInFirstHalf; schedSlaveIdx++) | |
| 95 { | |
| 96 writeQ( scheduledSlaves[ schedSlaveIdx ], workQ ); | |
| 97 } | |
| 98 | |
| 99 //enqueue continuation of this loop | |
| 100 // note that After this enqueue, continuation might sneak through | |
| 101 writeQ( masterEnv->masterWorkUnit, workQ ); | |
| 102 for( schedSlaveIdx = numInFirstHalf; | |
| 103 schedSlaveIdx < numScheduled; | |
| 104 schedSlaveIdx++) | |
| 105 { | |
| 106 writeQ( scheduledSlaves[ schedSlaveIdx ]->workUnitToDo, workQ ); | |
| 107 } | |
| 108 | |
| 109 //all done, so okay for continuation to proceed | |
| 110 masterEnv->stillRunning = 0; | |
| 111 } | |
| 112 | |
| 113 |
