VMS/VMS_Implementations/SSR_impls/SSR__MC_shared_impl

annotate SSR_PluginFns.c @ 77:833b31a8abc1

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