rev |
line source |
Me@6
|
1 /*
|
Me@6
|
2 * Copyright 2010 OpenSourceCodeStewardshipFoundation
|
Me@6
|
3 *
|
Me@6
|
4 * Licensed under BSD
|
Me@6
|
5 */
|
Me@6
|
6
|
Me@6
|
7 #include <stdio.h>
|
Me@6
|
8 #include <stdlib.h>
|
Me@6
|
9
|
seanhalle@64
|
10 #include "Queue_impl/PrivateQueue.h"
|
Me@6
|
11 #include "SSR.h"
|
Me@6
|
12 #include "SSR_Request_Handlers.h"
|
Me@6
|
13
|
Me@17
|
14 //=========================== Local Fn Prototypes ===========================
|
Me@20
|
15 void
|
seanhalle@60
|
16 resume_slaveVP( SlaveVP *procr, SSRSemEnv *semEnv );
|
Me@6
|
17
|
Me@20
|
18 void
|
seanhalle@60
|
19 handleSemReq( VMSReqst *req, SlaveVP *requestingPr, SSRSemEnv *semEnv );
|
Me@17
|
20
|
Me@17
|
21 void
|
seanhalle@60
|
22 handleDissipate( SlaveVP *requestingPr, SSRSemEnv *semEnv );
|
Me@17
|
23
|
Me@17
|
24 void
|
seanhalle@60
|
25 handleCreate( VMSReqst *req, SlaveVP *requestingPr, SSRSemEnv *semEnv );
|
Me@17
|
26
|
Me@17
|
27
|
seanhalle@64
|
28 //============================== Assigner ==================================
|
Me@17
|
29 //
|
seanhalle@64
|
30 /*For SSR, assigning a slave simply takes the next work-unit off the
|
seanhalle@67
|
31 * ready-to-go work-unit queue and assigns it to the offered slot.
|
seanhalle@64
|
32 *If the ready-to-go work-unit queue is empty, then nothing to assign
|
seanhalle@67
|
33 * to the animation slot -- return FALSE to let Master loop know assigning
|
seanhalle@67
|
34 * that slot failed.
|
Me@17
|
35 */
|
seanhalle@60
|
36 SlaveVP *
|
seanhalle@67
|
37 SSR__assign_slaveVP_to_slot( void *_semEnv, AnimSlot *slot )
|
seanhalle@67
|
38 { SlaveVP *assignPr;
|
Me@17
|
39 SSRSemEnv *semEnv;
|
seanhalle@67
|
40 int32 coreNum, slotNum;
|
seanhalle@64
|
41
|
seanhalle@70
|
42 coreNum = slot->coreSlotIsOn;
|
seanhalle@64
|
43 slotNum = slot->slotIdx;
|
seanhalle@64
|
44
|
Me@17
|
45 semEnv = (SSRSemEnv *)_semEnv;
|
Me@17
|
46
|
seanhalle@67
|
47 assignPr = readPrivQ( semEnv->readyVPQs[coreNum] );
|
Me@17
|
48 //Note, using a non-blocking queue -- it returns NULL if queue empty
|
seanhalle@67
|
49 if(!assignPr){
|
seanhalle@67
|
50 assignPr = semEnv->idlePr[coreNum][slotNum];
|
nengel@66
|
51
|
nengel@66
|
52 if(semEnv->shutdownInitiated) {
|
seanhalle@69
|
53 assignPr = VMS_SS__create_shutdown_slave();
|
nengel@66
|
54 }
|
nengel@58
|
55 //things that would normally happen in resume(), but these VPs never go there
|
seanhalle@60
|
56 #ifdef HOLISTIC__TURN_ON_OBSERVE_UCC
|
nengel@71
|
57 else{
|
seanhalle@67
|
58 assignPr->assignCount++; //Somewhere here!
|
nengel@58
|
59 Unit newu;
|
seanhalle@67
|
60 newu.vp = assignPr->slaveID;
|
seanhalle@67
|
61 newu.task = assignPr->assignCount;
|
nengel@58
|
62 addToListOfArrays(Unit,newu,semEnv->unitList);
|
nengel@58
|
63
|
seanhalle@67
|
64 if (assignPr->assignCount > 1){
|
nengel@58
|
65 Dependency newd;
|
seanhalle@67
|
66 newd.from_vp = assignPr->slaveID;
|
seanhalle@67
|
67 newd.from_task = assignPr->assignCount - 1;
|
seanhalle@67
|
68 newd.to_vp = assignPr->slaveID;
|
seanhalle@67
|
69 newd.to_task = assignPr->assignCount;
|
nengel@58
|
70 addToListOfArrays(Dependency, newd ,semEnv->ctlDependenciesList);
|
nengel@58
|
71 }
|
nengel@71
|
72 }
|
nengel@58
|
73 #endif
|
nengel@58
|
74 }
|
seanhalle@60
|
75 #ifdef HOLISTIC__TURN_ON_OBSERVE_UCC
|
nengel@71
|
76 if (assignPr && assignPr->typeOfVP == Slave) {
|
seanhalle@67
|
77 //assignPr->numTimesAssigned++;
|
seanhalle@69
|
78 Unit prev_in_slot = semEnv->last_in_slot[coreNum * NUM_ANIM_SLOTS + slotNum];
|
nengel@52
|
79 if(prev_in_slot.vp != 0){
|
nengel@52
|
80 Dependency newd;
|
nengel@52
|
81 newd.from_vp = prev_in_slot.vp;
|
nengel@52
|
82 newd.from_task = prev_in_slot.task;
|
seanhalle@67
|
83 newd.to_vp = assignPr->slaveID;
|
seanhalle@67
|
84 newd.to_task = assignPr->assignCount;
|
nengel@52
|
85 addToListOfArrays(Dependency,newd,semEnv->hwArcs);
|
nengel@52
|
86 }
|
seanhalle@67
|
87 prev_in_slot.vp = assignPr->slaveID;
|
seanhalle@67
|
88 prev_in_slot.task = assignPr->assignCount;
|
seanhalle@69
|
89 semEnv->last_in_slot[coreNum * NUM_ANIM_SLOTS + slotNum] = prev_in_slot;
|
nengel@49
|
90 }
|
nengel@52
|
91 #endif
|
seanhalle@67
|
92 return( assignPr );
|
Me@17
|
93 }
|
Me@17
|
94
|
Me@17
|
95
|
Me@17
|
96 //=========================== Request Handler =============================
|
Me@17
|
97 //
|
Me@6
|
98 /*Will get requests to send, to receive, and to create new processors.
|
Me@6
|
99 * Upon send, check the hash to see if a receive is waiting.
|
Me@6
|
100 * Upon receive, check hash to see if a send has already happened.
|
Me@6
|
101 * When other is not there, put in. When other is there, the comm.
|
seanhalle@64
|
102 * completes, which means the receiver P gets assigned and
|
Me@6
|
103 * picks up right after the receive request. So make the work-unit
|
Me@6
|
104 * and put it into the queue of work-units ready to go.
|
Me@6
|
105 * Other request is create a new Processor, with the function to run in the
|
Me@6
|
106 * Processor, and initial data.
|
Me@6
|
107 */
|
Me@6
|
108 void
|
seanhalle@60
|
109 SSR__Request_Handler( SlaveVP *requestingPr, void *_semEnv )
|
Me@6
|
110 { SSRSemEnv *semEnv;
|
Me@6
|
111 VMSReqst *req;
|
Me@23
|
112
|
Me@6
|
113 semEnv = (SSRSemEnv *)_semEnv;
|
Me@6
|
114
|
seanhalle@60
|
115 req = VMS_PI__take_next_request_out_of( requestingPr );
|
Me@17
|
116
|
Me@6
|
117 while( req != NULL )
|
Me@6
|
118 {
|
Me@17
|
119 switch( req->reqType )
|
Me@17
|
120 { case semantic: handleSemReq( req, requestingPr, semEnv);
|
Me@17
|
121 break;
|
Me@17
|
122 case createReq: handleCreate( req, requestingPr, semEnv);
|
Me@17
|
123 break;
|
Me@17
|
124 case dissipate: handleDissipate( requestingPr, semEnv);
|
Me@17
|
125 break;
|
seanhalle@60
|
126 case VMSSemantic: VMS_PI__handle_VMSSemReq(req, requestingPr, semEnv,
|
seanhalle@63
|
127 (ResumeSlvFnPtr) &resume_slaveVP);
|
Me@17
|
128 break;
|
Me@17
|
129 default:
|
Me@17
|
130 break;
|
Me@6
|
131 }
|
Me@17
|
132
|
seanhalle@60
|
133 req = VMS_PI__take_next_request_out_of( requestingPr );
|
Me@17
|
134 } //while( req != NULL )
|
Me@6
|
135
|
Me@6
|
136 }
|
Me@6
|
137
|
Me@6
|
138
|
Me@20
|
139 void
|
seanhalle@60
|
140 handleSemReq( VMSReqst *req, SlaveVP *reqPr, SSRSemEnv *semEnv )
|
Me@17
|
141 { SSRSemReq *semReq;
|
Me@6
|
142
|
seanhalle@60
|
143 semReq = VMS_PI__take_sem_reqst_from(req);
|
Me@17
|
144 if( semReq == NULL ) return;
|
Me@17
|
145 switch( semReq->reqType ) //sem handlers are all in other file
|
Me@17
|
146 {
|
Me@17
|
147 case send_type: handleSendType( semReq, semEnv);
|
Me@17
|
148 break;
|
Me@17
|
149 case send_from_to: handleSendFromTo( semReq, semEnv);
|
Me@17
|
150 break;
|
Me@17
|
151 case receive_type: handleReceiveType( semReq, semEnv);
|
Me@17
|
152 break;
|
Me@17
|
153 case receive_from_to: handleReceiveFromTo(semReq, semEnv);
|
Me@17
|
154 break;
|
Me@17
|
155 case transfer_to: handleTransferTo( semReq, semEnv);
|
Me@17
|
156 break;
|
Me@17
|
157 case transfer_out: handleTransferOut( semReq, semEnv);
|
Me@17
|
158 break;
|
Me@17
|
159 case malloc_req: handleMalloc( semReq, reqPr, semEnv);
|
Me@17
|
160 break;
|
Me@17
|
161 case free_req: handleFree( semReq, reqPr, semEnv);
|
Me@17
|
162 break;
|
Me@21
|
163 case singleton_fn_start: handleStartFnSingleton(semReq, reqPr, semEnv);
|
Me@21
|
164 break;
|
Me@21
|
165 case singleton_fn_end: handleEndFnSingleton( semReq, reqPr, semEnv);
|
Me@21
|
166 break;
|
Me@21
|
167 case singleton_data_start:handleStartDataSingleton(semReq,reqPr,semEnv);
|
Me@21
|
168 break;
|
Me@21
|
169 case singleton_data_end: handleEndDataSingleton(semReq, reqPr, semEnv);
|
Me@17
|
170 break;
|
Me@17
|
171 case atomic: handleAtomic( semReq, reqPr, semEnv);
|
Me@17
|
172 break;
|
Me@17
|
173 case trans_start: handleTransStart( semReq, reqPr, semEnv);
|
Me@17
|
174 break;
|
Me@17
|
175 case trans_end: handleTransEnd( semReq, reqPr, semEnv);
|
Me@17
|
176 break;
|
Me@17
|
177 }
|
Me@6
|
178 }
|
Me@6
|
179
|
Me@17
|
180
|
Me@17
|
181
|
Me@17
|
182 //=========================== VMS Request Handlers ==============================
|
Me@17
|
183 //
|
Me@17
|
184 void
|
seanhalle@60
|
185 handleDissipate( SlaveVP *requestingPr, SSRSemEnv *semEnv )
|
Me@17
|
186 {
|
seanhalle@67
|
187 DEBUG__printf1(dbgRqstHdlr,"Dissipate request from processor %d",requestingPr->slaveID)
|
Me@17
|
188 //free any semantic data allocated to the virt procr
|
seanhalle@60
|
189 VMS_PI__free( requestingPr->semanticData );
|
Me@17
|
190
|
Me@17
|
191 //Now, call VMS to free_all AppVP state -- stack and so on
|
seanhalle@60
|
192 VMS_PI__dissipate_slaveVP( requestingPr );
|
Me@17
|
193
|
seanhalle@60
|
194 semEnv->numSlaveVP -= 1;
|
seanhalle@60
|
195 if( semEnv->numSlaveVP == 0 )
|
Me@17
|
196 { //no more work, so shutdown
|
nengel@66
|
197 semEnv->shutdownInitiated = TRUE;
|
nengel@66
|
198 //VMS_SS__shutdown();
|
Me@17
|
199 }
|
Me@17
|
200 }
|
Me@17
|
201
|
Me@18
|
202 /*Re-use this in the entry-point fn
|
Me@18
|
203 */
|
seanhalle@60
|
204 SlaveVP *
|
seanhalle@60
|
205 SSR__create_procr_helper( TopLevelFnPtr fnPtr, void *initData,
|
seanhalle@64
|
206 SSRSemEnv *semEnv, int32 coreToAssignOnto )
|
seanhalle@60
|
207 { SlaveVP *newPr;
|
Me@20
|
208 SSRSemData *semData;
|
Me@17
|
209
|
Me@17
|
210 //This is running in master, so use internal version
|
seanhalle@60
|
211 newPr = VMS_PI__create_slaveVP( fnPtr, initData );
|
Me@17
|
212
|
seanhalle@60
|
213 semEnv->numSlaveVP += 1;
|
Me@17
|
214
|
seanhalle@60
|
215 semData = VMS_PI__malloc( sizeof(SSRSemData) );
|
Me@18
|
216 semData->highestTransEntered = -1;
|
Me@18
|
217 semData->lastTransEntered = NULL;
|
Me@18
|
218
|
nengel@52
|
219 newPr->semanticData = semData;
|
nengel@52
|
220
|
Me@18
|
221 //=================== Assign new processor to a core =====================
|
seanhalle@60
|
222 #ifdef DEBUG__TURN_ON_SEQUENTIAL_MODE
|
Me@17
|
223 newPr->coreAnimatedBy = 0;
|
Me@17
|
224
|
Me@17
|
225 #else
|
Me@17
|
226
|
seanhalle@64
|
227 if(coreToAssignOnto < 0 || coreToAssignOnto >= NUM_CORES )
|
Me@17
|
228 { //out-of-range, so round-robin assignment
|
Me@17
|
229 newPr->coreAnimatedBy = semEnv->nextCoreToGetNewPr;
|
Me@17
|
230
|
Me@17
|
231 if( semEnv->nextCoreToGetNewPr >= NUM_CORES - 1 )
|
Me@17
|
232 semEnv->nextCoreToGetNewPr = 0;
|
Me@17
|
233 else
|
Me@17
|
234 semEnv->nextCoreToGetNewPr += 1;
|
Me@17
|
235 }
|
Me@17
|
236 else //core num in-range, so use it
|
seanhalle@64
|
237 { newPr->coreAnimatedBy = coreToAssignOnto;
|
Me@17
|
238 }
|
Me@17
|
239 #endif
|
Me@18
|
240 //========================================================================
|
nengel@47
|
241
|
Me@18
|
242 return newPr;
|
Me@18
|
243 }
|
Me@17
|
244
|
Me@18
|
245 void
|
seanhalle@60
|
246 handleCreate( VMSReqst *req, SlaveVP *requestingPr, SSRSemEnv *semEnv )
|
Me@18
|
247 { SSRSemReq *semReq;
|
seanhalle@60
|
248 SlaveVP *newPr;
|
Nina@36
|
249
|
Nina@36
|
250
|
seanhalle@60
|
251 semReq = VMS_PI__take_sem_reqst_from( req );
|
Nina@36
|
252
|
Me@18
|
253 newPr = SSR__create_procr_helper( semReq->fnPtr, semReq->initData, semEnv,
|
seanhalle@64
|
254 semReq->coreToAssignOnto );
|
Me@18
|
255
|
seanhalle@67
|
256 DEBUG__printf2(dbgRqstHdlr,"Create from: %d, new VP: %d", requestingPr->slaveID, newPr->slaveID)
|
Nina@36
|
257
|
seanhalle@60
|
258 #ifdef HOLISTIC__TURN_ON_OBSERVE_UCC
|
nengel@46
|
259 Dependency newd;
|
seanhalle@60
|
260 newd.from_vp = requestingPr->slaveID;
|
seanhalle@67
|
261 newd.from_task = requestingPr->assignCount;
|
seanhalle@60
|
262 newd.to_vp = newPr->slaveID;
|
nengel@52
|
263 newd.to_task = 1;
|
nengel@48
|
264 //addToListOfArraysDependency(newd,semEnv->commDependenciesList);
|
nengel@46
|
265 addToListOfArrays(Dependency,newd,semEnv->commDependenciesList);
|
Nina@36
|
266 #endif
|
Nina@36
|
267
|
Me@17
|
268 //For SSR, caller needs ptr to created processor returned to it
|
Me@17
|
269 requestingPr->dataRetFromReq = newPr;
|
Me@17
|
270
|
seanhalle@60
|
271 resume_slaveVP( newPr, semEnv );
|
seanhalle@60
|
272 resume_slaveVP( requestingPr, semEnv );
|
Me@17
|
273 }
|
Me@17
|
274
|
Me@17
|
275
|
Me@17
|
276 //=========================== Helper ==============================
|
Me@20
|
277 void
|
seanhalle@60
|
278 resume_slaveVP( SlaveVP *procr, SSRSemEnv *semEnv )
|
Me@17
|
279 {
|
seanhalle@60
|
280 #ifdef HOLISTIC__TURN_ON_PERF_COUNTERS
|
nengel@50
|
281 /*
|
Nina@36
|
282 int lastRecordIdx = procr->counter_history_array_info->numInArray -1;
|
Nina@36
|
283 CounterRecord* lastRecord = procr->counter_history[lastRecordIdx];
|
Nina@36
|
284 saveLowTimeStampCountInto(lastRecord->unblocked_timestamp);
|
nengel@50
|
285 */
|
Nina@36
|
286 #endif
|
seanhalle@60
|
287 #ifdef HOLISTIC__TURN_ON_OBSERVE_UCC
|
seanhalle@67
|
288 procr->assignCount++; //Somewhere here!
|
nengel@47
|
289 Unit newu;
|
seanhalle@60
|
290 newu.vp = procr->slaveID;
|
seanhalle@67
|
291 newu.task = procr->assignCount;
|
nengel@47
|
292 addToListOfArrays(Unit,newu,semEnv->unitList);
|
nengel@51
|
293
|
seanhalle@67
|
294 if (procr->assignCount > 1){
|
nengel@51
|
295 Dependency newd;
|
seanhalle@60
|
296 newd.from_vp = procr->slaveID;
|
seanhalle@67
|
297 newd.from_task = procr->assignCount - 1;
|
seanhalle@60
|
298 newd.to_vp = procr->slaveID;
|
seanhalle@67
|
299 newd.to_task = procr->assignCount;
|
nengel@51
|
300 addToListOfArrays(Dependency, newd ,semEnv->ctlDependenciesList);
|
nengel@51
|
301 }
|
Nina@39
|
302 #endif
|
Me@17
|
303 writePrivQ( procr, semEnv->readyVPQs[ procr->coreAnimatedBy] );
|
Me@17
|
304 }
|