annotate VSs.c @ 30:a40859b8dc33

ML_dev -- compiles and runs, may still have shutdown issues
author Sean Halle <seanhalle@yahoo.com>
date Sat, 02 Mar 2013 10:07:58 -0800
parents dd1efbf29ff9
children 0162554f6ef5
rev   line source
seanhalle@0 1 /*
seanhalle@0 2 * Copyright 2010 OpenSourceCodeStewardshipFoundation
seanhalle@0 3 *
seanhalle@0 4 * Licensed under BSD
seanhalle@0 5 */
seanhalle@0 6
seanhalle@0 7 #include <stdio.h>
seanhalle@0 8 #include <stdlib.h>
seanhalle@0 9 #include <malloc.h>
seanhalle@0 10
seanhalle@0 11 #include "Queue_impl/PrivateQueue.h"
seanhalle@0 12 #include "Hash_impl/PrivateHash.h"
seanhalle@0 13
seanhalle@2 14 #include "VSs.h"
seanhalle@29 15 #include "PR_impl/Services_Offered_by_PR/Measurement_and_Stats/PR_MEAS__Counter_Recording.h"
seanhalle@0 16 //==========================================================================
seanhalle@27 17 void
seanhalle@27 18 VSs__init_Helper();
seanhalle@27 19
seanhalle@27 20 SlaveVP *
seanhalle@27 21 VSs__create_thread_w_ID_and_affinity( TopLevelFnPtr fnPtr, void *initData,
seanhalle@27 22 int32 *thdID, int32 coreToAssignOnto, SlaveVP *creatingThd );
seanhalle@0 23
seanhalle@0 24 //==========================================================================
seanhalle@0 25
seanhalle@0 26
seanhalle@0 27
seanhalle@0 28 //===========================================================================
seanhalle@0 29
seanhalle@0 30
seanhalle@0 31 /*These are the library functions *called in the application*
seanhalle@0 32 *
seanhalle@0 33 *There's a pattern for the outside sequential code to interact with the
seanhalle@26 34 * PR_HW code.
seanhalle@26 35 *The PR_HW system is inside a boundary.. every VSs system is in its
seanhalle@0 36 * own directory that contains the functions for each of the processor types.
seanhalle@0 37 * One of the processor types is the "seed" processor that starts the
seanhalle@0 38 * cascade of creating all the processors that do the work.
seanhalle@0 39 *So, in the directory is a file called "EntryPoint.c" that contains the
seanhalle@0 40 * function, named appropriately to the work performed, that the outside
seanhalle@0 41 * sequential code calls. This function follows a pattern:
seanhalle@2 42 *1) it calls VSs__init()
seanhalle@0 43 *2) it creates the initial data for the seed processor, which is passed
seanhalle@0 44 * in to the function
seanhalle@2 45 *3) it creates the seed VSs processor, with the data to start it with.
seanhalle@2 46 *4) it calls startVSsThenWaitUntilWorkDone
seanhalle@0 47 *5) it gets the returnValue from the transfer struc and returns that
seanhalle@0 48 * from the function
seanhalle@0 49 *
seanhalle@2 50 *For now, a new VSs system has to be created via VSs__init every
seanhalle@0 51 * time an entry point function is called -- later, might add letting the
seanhalle@2 52 * VSs system be created once, and let all the entry points just reuse
seanhalle@0 53 * it -- want to be as simple as possible now, and see by using what makes
seanhalle@0 54 * sense for later..
seanhalle@0 55 */
seanhalle@0 56
seanhalle@0 57
seanhalle@0 58
seanhalle@0 59 //===========================================================================
seanhalle@0 60
seanhalle@0 61 int32
seanhalle@2 62 VSs__giveMinWorkUnitCycles( float32 percentOverhead )
seanhalle@0 63 {
seanhalle@0 64 return MIN_WORK_UNIT_CYCLES;
seanhalle@0 65 }
seanhalle@0 66
seanhalle@0 67 int32
seanhalle@2 68 VSs__giveIdealNumWorkUnits()
seanhalle@0 69 {
seanhalle@0 70 return NUM_ANIM_SLOTS * NUM_CORES;
seanhalle@0 71 }
seanhalle@0 72
seanhalle@0 73 int32
seanhalle@2 74 VSs__give_number_of_cores_to_schedule_onto()
seanhalle@0 75 {
seanhalle@0 76 return NUM_CORES;
seanhalle@0 77 }
seanhalle@0 78
seanhalle@0 79 /*For now, use TSC -- later, make these two macros with assembly that first
seanhalle@0 80 * saves jump point, and second jumps back several times to get reliable time
seanhalle@0 81 */
seanhalle@0 82 void
seanhalle@27 83 VSs__begin_primitive( SlaveVP *animSlv )
seanhalle@27 84 { VSsLangData *langData;
seanhalle@26 85
seanhalle@27 86 langData = (VSsLangData *)PR_WL__give_lang_data( animSlv, VSs_MAGIC_NUMBER);
seanhalle@26 87
seanhalle@27 88 saveLowTimeStampCountInto( langData->primitiveStartTime );
seanhalle@0 89 }
seanhalle@0 90
seanhalle@0 91 /*Just quick and dirty for now -- make reliable later
seanhalle@0 92 * will want this to jump back several times -- to be sure cache is warm
seanhalle@0 93 * because don't want comm time included in calc-time measurement -- and
seanhalle@0 94 * also to throw out any "weird" values due to OS interrupt or TSC rollover
seanhalle@0 95 */
seanhalle@0 96 int32
seanhalle@27 97 VSs__end_primitive_and_give_cycles( SlaveVP *animSlv )
seanhalle@0 98 { int32 endTime, startTime;
seanhalle@27 99 VSsLangData *langData;
seanhalle@26 100
seanhalle@0 101 //TODO: fix by repeating time-measurement
seanhalle@0 102 saveLowTimeStampCountInto( endTime );
seanhalle@27 103 langData = (VSsLangData *)PR_WL__give_lang_data( animSlv, VSs_MAGIC_NUMBER);
seanhalle@27 104 startTime = langData->primitiveStartTime;
seanhalle@0 105 return (endTime - startTime);
seanhalle@0 106 }
seanhalle@0 107
seanhalle@26 108
seanhalle@0 109
seanhalle@0 110 //===========================================================================
seanhalle@0 111
seanhalle@2 112 SlaveVP *
seanhalle@7 113 VSs__create_thread( TopLevelFnPtr fnPtr, void *initData,
seanhalle@7 114 SlaveVP *creatingThd )
seanhalle@26 115 {
seanhalle@26 116 return VSs__create_thread_w_ID_and_affinity( fnPtr, initData, NO_ID,
seanhalle@26 117 ANY_CORE, creatingThd );
seanhalle@26 118 }
seanhalle@26 119
seanhalle@26 120 SlaveVP *
seanhalle@26 121 VSs__create_thread_w_ID( TopLevelFnPtr fnPtr, void *initData, int32 *thdID,
seanhalle@26 122 SlaveVP *creatingThd )
seanhalle@26 123 {
seanhalle@26 124 return VSs__create_thread_w_ID_and_affinity( fnPtr, initData, thdID,
seanhalle@26 125 ANY_CORE, creatingThd );
seanhalle@26 126 }
seanhalle@26 127
seanhalle@27 128
seanhalle@26 129
seanhalle@26 130 SlaveVP *
seanhalle@26 131 VSs__create_thread_w_ID_and_affinity( TopLevelFnPtr fnPtr, void *initData,
seanhalle@26 132 int32 *thdID, int32 coreToAssignOnto, SlaveVP *creatingThd )
seanhalle@27 133 { VSsLangReq reqData;
seanhalle@0 134
seanhalle@27 135 //the lang request data is on the stack and disappears when this
seanhalle@0 136 // call returns -- it's guaranteed to remain in the VP's stack for as
seanhalle@0 137 // long as the VP is suspended.
seanhalle@27 138 reqData.reqType = create_slave; //know type because in a PR create req
seanhalle@27 139 reqData.coreToAssignOnto = coreToAssignOnto;
seanhalle@27 140 reqData.fnPtr = fnPtr;
seanhalle@27 141 reqData.initData = initData;
seanhalle@26 142
seanhalle@30 143 PR_WL__send_create_slaveVP_req( &reqData, thdID, (CreateHandler)&VSs__handleCreateThd,
seanhalle@26 144 creatingThd, VSs_MAGIC_NUMBER );
seanhalle@27 145 return (SlaveVP *)creatingThd->dataRetFromReq;
seanhalle@0 146 }
seanhalle@0 147
seanhalle@10 148 /*This is always the last thing done in the code animated by a thread VP.
seanhalle@7 149 * Normally, this would be the last line of the thread's top level function.
seanhalle@7 150 * But, if the thread exits from any point, it has to do so by calling
seanhalle@7 151 * this.
seanhalle@10 152 *
seanhalle@10 153 *It simply sends a dissipate request, which handles all the state cleanup.
seanhalle@7 154 */
seanhalle@2 155 void
seanhalle@7 156 VSs__end_thread( SlaveVP *thdToEnd )
seanhalle@26 157 {
seanhalle@27 158 //the lang request is null for VSs version of end slave
seanhalle@30 159 PR_WL__send_end_slave_req( NULL, (RequestHandler)&VSs__handleDissipate, thdToEnd,
seanhalle@28 160 VSs_MAGIC_NUMBER );
seanhalle@0 161 }
seanhalle@0 162
seanhalle@0 163
seanhalle@10 164
seanhalle@0 165 //===========================================================================
seanhalle@0 166
seanhalle@0 167
seanhalle@4 168 //======================= task submit and end ==============================
seanhalle@4 169 /*
seanhalle@2 170 */
seanhalle@4 171 void
seanhalle@2 172 VSs__submit_task( VSsTaskType *taskType, void *args, SlaveVP *animSlv)
seanhalle@27 173 { VSsLangReq reqData;
seanhalle@0 174
seanhalle@2 175 reqData.reqType = submit_task;
seanhalle@4 176
seanhalle@2 177 reqData.taskType = taskType;
seanhalle@2 178 reqData.args = args;
seanhalle@4 179 reqData.callingSlv = animSlv;
seanhalle@4 180
seanhalle@26 181 //Create task is a special form, so have to pass as parameters, the
seanhalle@26 182 // top-level-fn of task and the data for that fn, plus lang's req,
seanhalle@26 183 // animating slave, and lang's magic number
seanhalle@27 184 PR_WL__send_create_task_req( taskType->fn, args, &reqData, NO_ID,
seanhalle@30 185 &VSs__handleSubmitTask, animSlv, VSs_MAGIC_NUMBER );
seanhalle@4 186 }
seanhalle@4 187
seanhalle@4 188 void
seanhalle@4 189 VSs__submit_task_with_ID( VSsTaskType *taskType, void *args, int32 *taskID,
seanhalle@27 190 SlaveVP *animSlv )
seanhalle@27 191 { VSsLangReq reqData;
seanhalle@26 192
seanhalle@4 193 reqData.reqType = submit_task;
seanhalle@4 194
seanhalle@30 195 reqData.taskType = taskType; //VSs info about args, dependencies, etc
seanhalle@4 196 reqData.args = args;
seanhalle@4 197 reqData.callingSlv = animSlv;
seanhalle@4 198
seanhalle@27 199 PR_WL__send_create_task_req( taskType->fn, args, &reqData, taskID,
seanhalle@30 200 &VSs__handleSubmitTask, animSlv, VSs_MAGIC_NUMBER );
seanhalle@4 201 }
seanhalle@4 202
seanhalle@4 203
seanhalle@4 204 /*This call is the last to happen in every task. It causes the slave to
seanhalle@2 205 * suspend and get the next task out of the task-queue. Notice there is no
seanhalle@2 206 * assigner here.. only one slave, no slave ReadyQ, and so on..
seanhalle@2 207 *Can either make the assigner take the next task out of the taskQ, or can
seanhalle@2 208 * leave all as it is, and make task-end take the next task.
seanhalle@26 209 *Note: this fits the case in the new PR for no-context tasks, so will use
seanhalle@26 210 * the built-in taskQ of new PR, and should be local and much faster.
seanhalle@2 211 *
seanhalle@2 212 *The task-stub is saved in the animSlv, so the request handler will get it
seanhalle@2 213 * from there, along with the task-type which has arg types, and so on..
seanhalle@4 214 *
seanhalle@4 215 * NOTE: if want, don't need to send the animating SlaveVP around..
seanhalle@4 216 * instead, can make a single slave per core, and coreCtrlr looks up the
seanhalle@4 217 * slave from having the core number.
seanhalle@4 218 *
seanhalle@26 219 *But, to stay compatible with all the other PR languages, leave it in..
seanhalle@0 220 */
seanhalle@0 221 void
seanhalle@2 222 VSs__end_task( SlaveVP *animSlv )
seanhalle@27 223 { VSsLangReq reqData;
seanhalle@2 224
seanhalle@27 225 //VSs has nothing extra to communicate to end task handler, so lang req is NULL
seanhalle@30 226 PR_WL__send_end_task_request( NULL, &VSs__handleEndTask, animSlv, VSs_MAGIC_NUMBER );
seanhalle@0 227 }
seanhalle@0 228
seanhalle@4 229
seanhalle@26 230 /*Waits for all tasks that are direct children to end, then resumes calling
seanhalle@26 231 * task or thread
seanhalle@26 232 */
nengel@5 233 void
nengel@5 234 VSs__taskwait(SlaveVP *animSlv)
seanhalle@26 235 {
seanhalle@27 236 VSsLangReq reqData;
nengel@5 237
nengel@5 238 reqData.reqType = taskwait;
nengel@5 239 reqData.callingSlv = animSlv;
nengel@5 240
seanhalle@30 241 PR_WL__send_lang_request( &reqData, (RequestHandler)&VSs__handleTaskwait, animSlv,
seanhalle@28 242 VSs_MAGIC_NUMBER );
seanhalle@26 243 }
nengel@5 244
seanhalle@30 245 void
seanhalle@30 246 VSs__wait_for_all_VSs_created_work_to_end( SlaveVP *seedSlv )
seanhalle@30 247 {
seanhalle@30 248 VSsLangReq reqData;
nengel@5 249
seanhalle@30 250 reqData.reqType = activity_cease_wait;
seanhalle@30 251 reqData.callingSlv = seedSlv;
seanhalle@30 252
seanhalle@30 253 PR_WL__send_lang_request( &reqData, (RequestHandler)&VSs__handleWaitForVSsWorkToEnd, seedSlv,
seanhalle@30 254 VSs_MAGIC_NUMBER );
seanhalle@30 255 }
seanhalle@30 256
seanhalle@30 257
seanhalle@30 258
seanhalle@30 259 /*This is called by the application -- normally the seed slave. It causes a
seanhalle@30 260 * request to be sent that frees the VSs lang env and all its contents.
seanhalle@30 261 *The seed slave resumes from the built-in PRServ langlet's environment. It
seanhalle@30 262 * will be PRServ that causes return from this call.
seanhalle@30 263 */
seanhalle@30 264 void
seanhalle@30 265 VSs__shutdown( SlaveVP *seedSlv )
seanhalle@30 266 {
seanhalle@30 267 PR_WL__send_lang_shutdown_request( seedSlv, VSs_MAGIC_NUMBER );
seanhalle@30 268 }
nengel@5 269
seanhalle@4 270 //========================== send and receive ============================
seanhalle@4 271 //
seanhalle@4 272
seanhalle@28 273 inline
seanhalle@28 274 int32 *
seanhalle@4 275 VSs__give_self_taskID( SlaveVP *animSlv )
seanhalle@30 276 { void *metaTask;
seanhalle@30 277 metaTask = PR_WL__give_lang_meta_task_from_slave( animSlv, VSs_MAGIC_NUMBER );
seanhalle@30 278 return PR__give_ID_from_lang_meta_task( metaTask );
seanhalle@4 279 }
seanhalle@4 280
seanhalle@4 281 //================================ send ===================================
seanhalle@4 282
seanhalle@4 283 void
seanhalle@4 284 VSs__send_of_type_to( void *msg, const int32 type, int32 *receiverID,
seanhalle@4 285 SlaveVP *senderSlv )
seanhalle@27 286 { VSsLangReq reqData;
seanhalle@4 287
seanhalle@4 288 reqData.reqType = send_type_to;
seanhalle@4 289
seanhalle@4 290 reqData.msg = msg;
seanhalle@4 291 reqData.msgType = type;
seanhalle@4 292 reqData.receiverID = receiverID;
seanhalle@4 293 reqData.senderSlv = senderSlv;
seanhalle@4 294
seanhalle@4 295 reqData.nextReqInHashEntry = NULL;
seanhalle@4 296
seanhalle@30 297 PR_WL__send_lang_request( &reqData, (RequestHandler)&VSs__handleSendTypeTo,
seanhalle@28 298 senderSlv, VSs_MAGIC_NUMBER );
seanhalle@4 299
seanhalle@4 300 //When come back from suspend, no longer own data reachable from msg
seanhalle@4 301 }
seanhalle@4 302
seanhalle@4 303 void
seanhalle@4 304 VSs__send_from_to( void *msg, int32 *senderID, int32 *receiverID, SlaveVP *senderSlv )
seanhalle@27 305 { VSsLangReq reqData;
seanhalle@4 306
seanhalle@4 307 reqData.reqType = send_from_to;
seanhalle@4 308
seanhalle@4 309 reqData.msg = msg;
seanhalle@4 310 reqData.senderID = senderID;
seanhalle@4 311 reqData.receiverID = receiverID;
seanhalle@4 312 reqData.senderSlv = senderSlv;
seanhalle@4 313
seanhalle@4 314 reqData.nextReqInHashEntry = NULL;
seanhalle@4 315
seanhalle@30 316 PR_WL__send_lang_request( &reqData, (RequestHandler)&VSs__handleSendFromTo,
seanhalle@28 317 senderSlv, VSs_MAGIC_NUMBER );
seanhalle@4 318 }
seanhalle@4 319
seanhalle@4 320
seanhalle@4 321 //================================ receive ================================
seanhalle@4 322
seanhalle@4 323 /*The "type" version of send and receive creates a many-to-one relationship.
seanhalle@4 324 * The sender is anonymous, and many sends can stack up, waiting to be
seanhalle@4 325 * received. The same receiver can also have send from-to's
seanhalle@4 326 * waiting for it, and those will be kept separate from the "type"
seanhalle@4 327 * messages.
seanhalle@4 328 */
seanhalle@4 329 void *
seanhalle@4 330 VSs__receive_type_to( const int32 type, int32* receiverID, SlaveVP *receiverSlv )
seanhalle@4 331 { DEBUG__printf1(dbgRqstHdlr,"WL: receive type to %d",receiverID[1] );
seanhalle@27 332 VSsLangReq reqData;
seanhalle@4 333
seanhalle@4 334 reqData.reqType = receive_type_to;
seanhalle@4 335
seanhalle@4 336 reqData.msgType = type;
seanhalle@4 337 reqData.receiverID = receiverID;
seanhalle@4 338 reqData.receiverSlv = receiverSlv;
seanhalle@4 339
seanhalle@4 340 reqData.nextReqInHashEntry = NULL;
seanhalle@4 341
seanhalle@30 342 PR_WL__send_lang_request( &reqData, (RequestHandler)&VSs__handleReceiveTypeTo,
seanhalle@28 343 receiverSlv, VSs_MAGIC_NUMBER );
seanhalle@4 344
seanhalle@4 345 return receiverSlv->dataRetFromReq;
seanhalle@4 346 }
seanhalle@4 347
seanhalle@4 348
seanhalle@4 349
seanhalle@4 350 /*Call this at the point a receiving task wants in-coming data.
seanhalle@4 351 * Use this from-to form when know senderID -- it makes a direct channel
seanhalle@4 352 * between sender and receiver.
seanhalle@4 353 */
seanhalle@4 354 void *
seanhalle@4 355 VSs__receive_from_to( int32 *senderID, int32 *receiverID, SlaveVP *receiverSlv )
seanhalle@4 356 {
seanhalle@27 357 VSsLangReq reqData;
seanhalle@4 358
seanhalle@4 359 reqData.reqType = receive_from_to;
seanhalle@4 360
seanhalle@4 361 reqData.senderID = senderID;
seanhalle@4 362 reqData.receiverID = receiverID;
seanhalle@4 363 reqData.receiverSlv = receiverSlv;
seanhalle@4 364
seanhalle@4 365 reqData.nextReqInHashEntry = NULL;
seanhalle@4 366 DEBUG__printf2(dbgRqstHdlr,"WL: receive from %d to: %d", reqData.senderID[1], reqData.receiverID[1]);
seanhalle@4 367
seanhalle@30 368 PR_WL__send_lang_request( &reqData, (RequestHandler)&VSs__handleReceiveFromTo,
seanhalle@28 369 receiverSlv, VSs_MAGIC_NUMBER );
seanhalle@4 370
seanhalle@4 371 return receiverSlv->dataRetFromReq;
seanhalle@4 372 }
seanhalle@4 373
seanhalle@4 374
seanhalle@4 375
seanhalle@4 376
seanhalle@0 377