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