VMS/VMS_Implementations/SSR_impls/SSR__MC_shared_impl

view SSR_PluginFns.c @ 84:ce07f1a42ddf

Added skeleton for data tracking assigner + design notes
author Sean Halle <seanhalle@yahoo.com>
date Thu, 10 Jan 2013 11:16:42 -0800
parents 833b31a8abc1
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 "SSR.h"
12 #include "SSR_Request_Handlers.h"
14 //=========================== Local Fn Prototypes ===========================
15 void
16 resume_slaveVP( SlaveVP *procr, SSRSemEnv *semEnv );
18 void
19 handleSemReq( VMSReqst *req, SlaveVP *requestingPr, SSRSemEnv *semEnv );
21 void
22 handleDissipate( SlaveVP *requestingPr, SSRSemEnv *semEnv );
24 void
25 handleCreate( VMSReqst *req, SlaveVP *requestingPr, SSRSemEnv *semEnv );
28 //============================== Assigner ==================================
29 //
30 /*
31 */
32 SlaveVP *
33 SSR__assign_slaveVP_to_slot( void *_semEnv, AnimSlot *slot )
34 { SlaveVP *assignPr;
35 SSRSemEnv *semEnv;
36 int32 coreNum, slotNum;
38 coreNum = slot->coreSlotIsOn;
39 slotNum = slot->slotIdx;
41 semEnv = (SSRSemEnv *)_semEnv;
43 // assignPr = readPrivQ( semEnv->readyVPQs[coreNum] );
44 assignPr = pickASlave( slot, coreNum );
46 //Note, using a non-blocking queue -- it returns NULL if queue empty
47 #ifdef IDLE_SLAVES
48 if(!assignPr){
49 assignPr = semEnv->idlePr[coreNum][slotNum];
51 if(semEnv->shutdownInitiated) {
52 assignPr = VMS_SS__create_shutdown_slave();
53 }
54 //things that would normally happen in resume(), but these VPs never go there
55 #ifdef HOLISTIC__TURN_ON_OBSERVE_UCC
56 else{
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 }
72 #endif
73 }
74 #endif
75 #ifdef HOLISTIC__TURN_ON_OBSERVE_UCC
76 if (assignPr && (assignPr->typeOfVP == Slave || assignPr->typeOfVP == Idle)) {
77 //assignPr->numTimesAssigned++;
78 Unit prev_in_slot = semEnv->last_in_slot[coreNum * NUM_ANIM_SLOTS + slotNum];
79 if(prev_in_slot.vp != 0){
80 Dependency newd;
81 newd.from_vp = prev_in_slot.vp;
82 newd.from_task = prev_in_slot.task;
83 newd.to_vp = assignPr->slaveID;
84 newd.to_task = assignPr->assignCount;
85 addToListOfArrays(Dependency,newd,semEnv->hwArcs);
86 }
87 prev_in_slot.vp = assignPr->slaveID;
88 prev_in_slot.task = assignPr->assignCount;
89 semEnv->last_in_slot[coreNum * NUM_ANIM_SLOTS + slotNum] = prev_in_slot;
90 }
91 #endif
92 return( assignPr );
93 }
96 //=========================== Request Handler =============================
97 //
98 /*Will get requests to send, to receive, and to create new processors.
99 * Upon send, check the hash to see if a receive is waiting.
100 * Upon receive, check hash to see if a send has already happened.
101 * When other is not there, put in. When other is there, the comm.
102 * completes, which means the receiver P gets assigned and
103 * picks up right after the receive request. So make the work-unit
104 * and put it into the queue of work-units ready to go.
105 * Other request is create a new Processor, with the function to run in the
106 * Processor, and initial data.
107 */
108 void
109 SSR__Request_Handler( SlaveVP *requestingPr, void *_semEnv )
110 { SSRSemEnv *semEnv;
111 VMSReqst *req;
113 semEnv = (SSRSemEnv *)_semEnv;
115 req = VMS_PI__take_next_request_out_of( requestingPr );
117 while( req != NULL )
118 {
119 #ifdef HOLISTIC__TURN_ON_OBSERVE_UCC
120 semEnv->lastReqType = 0;
121 #endif
122 switch( req->reqType )
123 { case semantic: handleSemReq( req, requestingPr, semEnv);
124 break;
125 case createReq: handleCreate( req, requestingPr, semEnv);
126 break;
127 case dissipate: handleDissipate( requestingPr, semEnv);
128 break;
129 case VMSSemantic: VMS_PI__handle_VMSSemReq(req, requestingPr, semEnv,
130 (ResumeSlvFnPtr) &resume_slaveVP);
131 break;
132 default:
133 break;
134 }
136 req = VMS_PI__take_next_request_out_of( requestingPr );
137 } //while( req != NULL )
139 }
142 void
143 handleSemReq( VMSReqst *req, SlaveVP *reqPr, SSRSemEnv *semEnv )
144 { SSRSemReq *semReq;
146 semReq = VMS_PI__take_sem_reqst_from(req);
147 if( semReq == NULL ) return;
148 switch( semReq->reqType ) //sem handlers are all in other file
149 {
150 case send_type: handleSendType( semReq, semEnv);
151 break;
152 case send_from_to: handleSendFromTo( semReq, semEnv);
153 break;
154 case receive_type: handleReceiveType( semReq, semEnv);
155 break;
156 case receive_from_to: handleReceiveFromTo(semReq, semEnv);
157 break;
158 case transfer_to: handleTransferTo( semReq, semEnv);
159 break;
160 case transfer_out: handleTransferOut( semReq, semEnv);
161 break;
162 case malloc_req: handleMalloc( semReq, reqPr, semEnv);
163 break;
164 case free_req: handleFree( semReq, reqPr, semEnv);
165 break;
166 case singleton_fn_start: handleStartFnSingleton(semReq, reqPr, semEnv);
167 break;
168 case singleton_fn_end: handleEndFnSingleton( semReq, reqPr, semEnv);
169 break;
170 case singleton_data_start:handleStartDataSingleton(semReq,reqPr,semEnv);
171 break;
172 case singleton_data_end: handleEndDataSingleton(semReq, reqPr, semEnv);
173 break;
174 case atomic: handleAtomic( semReq, reqPr, semEnv);
175 break;
176 case trans_start: handleTransStart( semReq, reqPr, semEnv);
177 break;
178 case trans_end: handleTransEnd( semReq, reqPr, semEnv);
179 break;
180 }
181 }
185 //=========================== VMS Request Handlers ==============================
186 //
187 void
188 handleDissipate( SlaveVP *requestingPr, SSRSemEnv *semEnv )
189 {
190 DEBUG__printf1(dbgRqstHdlr,"Dissipate request from processor %d",requestingPr->slaveID)
191 //free any semantic data allocated to the virt procr
192 VMS_PI__free( requestingPr->semanticData );
194 //Now, call VMS to free_all AppVP state -- stack and so on
195 VMS_PI__dissipate_slaveVP( requestingPr );
197 semEnv->numSlaveVP -= 1;
198 if( semEnv->numSlaveVP == 0 )
199 { //no more work, so shutdown
200 #ifdef IDLE_SLAVES
201 semEnv->shutdownInitiated = TRUE;
202 #else
203 VMS_SS__shutdown();
204 #endif
205 }
206 }
208 /*Re-use this in the entry-point fn
209 */
210 SlaveVP *
211 SSR__create_procr_helper( TopLevelFnPtr fnPtr, void *initData,
212 SSRSemEnv *semEnv, int32 coreToAssignOnto )
213 { SlaveVP *newPr;
214 SSRSemData *semData;
216 //This is running in master, so use internal version
217 newPr = VMS_PI__create_slaveVP( fnPtr, initData );
219 semEnv->numSlaveVP += 1;
221 semData = VMS_PI__malloc( sizeof(SSRSemData) );
222 semData->highestTransEntered = -1;
223 semData->lastTransEntered = NULL;
225 newPr->semanticData = semData;
227 //=================== Assign new processor to a core =====================
228 #ifdef DEBUG__TURN_ON_SEQUENTIAL_MODE
229 newPr->coreAnimatedBy = 0;
231 #else
233 if(coreToAssignOnto < 0 || coreToAssignOnto >= NUM_CORES )
234 { //out-of-range, so round-robin assignment
235 newPr->coreAnimatedBy = semEnv->nextCoreToGetNewPr;
237 if( semEnv->nextCoreToGetNewPr >= NUM_CORES - 1 )
238 semEnv->nextCoreToGetNewPr = 0;
239 else
240 semEnv->nextCoreToGetNewPr += 1;
241 }
242 else //core num in-range, so use it
243 { newPr->coreAnimatedBy = coreToAssignOnto;
244 }
245 #endif
246 //========================================================================
248 return newPr;
249 }
251 void
252 handleCreate( VMSReqst *req, SlaveVP *requestingPr, SSRSemEnv *semEnv )
253 { SSRSemReq *semReq;
254 SlaveVP *newPr;
257 semReq = VMS_PI__take_sem_reqst_from( req );
259 newPr = SSR__create_procr_helper( semReq->fnPtr, semReq->initData, semEnv,
260 semReq->coreToAssignOnto );
262 DEBUG__printf2(dbgRqstHdlr,"Create from: %d, new VP: %d", requestingPr->slaveID, newPr->slaveID)
264 #ifdef HOLISTIC__TURN_ON_OBSERVE_UCC
265 Dependency newd;
266 newd.from_vp = requestingPr->slaveID;
267 newd.from_task = requestingPr->assignCount;
268 newd.to_vp = newPr->slaveID;
269 newd.to_task = 1;
270 addToListOfArrays(Dependency,newd,semEnv->commDependenciesList);
271 #endif
273 //For SSR, caller needs ptr to created processor returned to it
274 requestingPr->dataRetFromReq = newPr;
276 resume_slaveVP( newPr, semEnv );
277 resume_slaveVP( requestingPr, semEnv );
278 }
281 //=========================== Helper ==============================
282 void
283 resume_slaveVP( SlaveVP *procr, SSRSemEnv *semEnv )
284 {
285 #ifdef HOLISTIC__TURN_ON_PERF_COUNTERS
286 /*
287 int lastRecordIdx = procr->counter_history_array_info->numInArray -1;
288 CounterRecord* lastRecord = procr->counter_history[lastRecordIdx];
289 saveLowTimeStampCountInto(lastRecord->unblocked_timestamp);
290 */
291 #endif
292 #ifdef HOLISTIC__TURN_ON_OBSERVE_UCC
293 procr->assignCount++; //Somewhere here!
294 Unit newu;
295 newu.vp = procr->slaveID;
296 newu.task = procr->assignCount;
297 newu.reqType = semEnv->lastReqType;
298 if(procr->assignCount <= 1){
299 newu.ret_ptr = procr->resumeInstrPtr;
300 } else {
301 /*void* frame_ptr0 = procr->framePtr;
302 void* frame_ptr1 = *((void**)frame_ptr0);
303 void* frame_ptr2 = *((void**)frame_ptr1);
304 void* frame_ptr3 = *((void**)frame_ptr2);
305 void* ret_addr = *((void**)frame_ptr3 + 1);
306 newu.ret_ptr = ret_addr; */
307 newu.ret_ptr = procr->resumeInstrPtr;
308 }
309 addToListOfArrays(Unit,newu,semEnv->unitList);
311 if (procr->assignCount > 1){
312 Dependency newd;
313 newd.from_vp = procr->slaveID;
314 newd.from_task = procr->assignCount - 1;
315 newd.to_vp = procr->slaveID;
316 newd.to_task = procr->assignCount;
317 addToListOfArrays(Dependency, newd ,semEnv->ctlDependenciesList);
318 }
319 #endif
320 writePrivQ( procr, semEnv->readyVPQs[ procr->coreAnimatedBy] );
321 }