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