Пример #1
0
void vars_check_ctv_privacy(vars_chare c)
{
  int me = (size_t)CthSelf();
  CtvAccess(ctv1) = me;
  vars_ack(c);
  CthSuspend();
  if (CtvAccess(ctv1) != me) {
    CmiPrintf("ctv privacy test failed.\n");
    exit(1);
  }
  vars_ack(c);
  CthFree(CthSelf());
  CthSuspend();
}
Пример #2
0
/// If we're waiting for any pages, suspend our thread.
void MSA_Thread_Listener::suspend(void) {
	bool verbose=false;
	if (count>0) {
		thread=CthSelf();
		if (verbose) CkPrintf("Thread %p suspending for %d signals\n",
			CthSelf(),count);
		CthSuspend();
		if (verbose) CkPrintf("Thread %p resumed\n",CthSelf());
	}
}
Пример #3
0
void waitqd_QDChare::waitQD(void) {
  if (waitStarted == 1) {
    CdsFifo_Enqueue((CdsFifo)threadList, (void *)CthSelf());
  } else {
    waitStarted = 1;
    threadList = (void*) CdsFifo_Create();
    CdsFifo_Enqueue((CdsFifo) threadList, (void *)CthSelf());
    CkStartQD(CkIndex_waitqd_QDChare::onQD((CkQdMsg*)0), &thishandle);
  }
  CthSuspend();
}
Пример #4
0
CpmInvokable vars_control()
{
  struct vars_chare c; CthThread t1,t2;

  t1 = CthCreate(vars_check_ctv_privacy, (void *)&c, 0);
  t2 = CthCreate(vars_check_ctv_privacy, (void *)&c, 0);
  CthSetStrategyDefault(t1);
  CthSetStrategyDefault(t2);

  CthAwaken(t1); CthAwaken(t2);
  c.countdown = 2; c.pending = CthSelf(); CthSuspend();
  
  CthAwaken(t1); CthAwaken(t2);
  c.countdown = 2; c.pending = CthSelf(); CthSuspend();
  
  Cpm_vars_set_cpv_and_csv(CpmSend(CpmALL), &c);
  c.countdown = CmiNumPes(); c.pending = CthSelf(); CthSuspend();
  
  Cpm_vars_check_cpv_and_csv(CpmSend(CpmALL), &c);
  c.countdown = CmiNumPes(); c.pending = CthSelf(); CthSuspend();
  
  Cpm_megacon_ack(CpmSend(0));
}
Пример #5
0
void LdbCoordinator::rebalance(Controller *c)
{
  if (Node::Object()->simParameters->ldBalancer == LDBAL_NONE)
    return;

  iout << "LDB: ============= START OF LOAD BALANCING ============== " << CmiWallTimer() << "\n" << endi;
  DebugM(3, "Controller reached load balance barrier.\n");
  controllerReported = 1;
  controllerThread = c;

  CProxy_LdbCoordinator(thisgroup).barrier();

  CthSuspend();
}
Пример #6
0
// require the data from a thread
void ReductionMgr::require(RequireReduction* handle) {
  int setID = handle->reductionSetID;
  ReductionSet *set = reductionSets[setID];
  int seqNum = handle->sequenceNumber;
  ReductionSetData *data = set->getData(seqNum);
  if ( data->submitsRecorded < set->submitsRegistered ) {
    set->threadIsWaiting = 1;
    set->waitingForSequenceNumber = seqNum;
    set->waitingThread = CthSelf();
//iout << "seq " << seqNum << " waiting\n" << endi;
    CthSuspend();
  }
  set->threadIsWaiting = 0;

//iout << "seq " << seqNum << " consumed\n" << endi;
  delete handle->currentData;
  handle->currentData = set->removeData(seqNum);
  handle->data = handle->currentData->data;
  handle->sequenceNumber = ++seqNum;
}
Пример #7
0
/**
  threadInfo methods
*/
void commThreadInfo::run()
{
  CpvAccess(CthResumeBigSimThreadIdx) = BgRegisterHandler((BgHandler)CthResumeNormalThread);

  tSTARTTIME = CmiWallTimer();

  if (!tSTARTED) {
    tSTARTED = 1;
//    InitHandlerTable();
    BgNodeStart(BgGetArgc(), BgGetArgv());
    /* bnv should be initialized */
  }

  threadQueue *commQ = myNode->commThQ;

  //int recvd=0; //for debugging only
  for (;;) {
    char *msg = getFullBuffer();
    if (!msg) { 
//      tCURRTIME += (CmiWallTimer()-tSTARTTIME);
      commQ->enq(CthSelf());
      DEBUGF(("[%d] comm thread suspend.\n", BgMyNode()));
      CthSuspend(); 
      DEBUGF(("[%d] comm thread assume.\n", BgMyNode()));
//      tSTARTTIME = CmiWallTimer();
      continue;
    }
    DEBUGF(("[%d] comm thread has a msg.\n", BgMyNode()));
	
	//printf("on node %d, comm thread process a msg %p with type %d\n", BgMyNode(), msg, CmiBgMsgType(msg));
    /* schedule a worker thread, if small work do it itself */
    if (CmiBgMsgType(msg) == SMALL_WORK) {
      if (CmiBgMsgRecvTime(msg) > tCURRTIME)  tCURRTIME = CmiBgMsgRecvTime(msg);
//      tSTARTTIME = CmiWallTimer();
      /* call user registered handler function */
      BgProcessMessage(this, msg);
    }
    else {
#if BIGSIM_TIMING
      correctMsgTime(msg);
#endif
    
    //recvd++;
    //DEBUGM(4, ("[N%d] C[%d] will add a msg (handler=%d | cnt=%d", BgMyNode(), id, CmiBgMsgHandle(msg), recvd));
    int msgLen = CmiBgMsgLength(msg);
    DEBUGM(4, (" | len: %d | type: %d | node id: %d | src pe: %d\n" , msgLen, CmiBgMsgType(msg), CmiBgMsgNodeID(msg), CmiBgMsgSrcPe(msg)));
      
     if (CmiBgMsgThreadID(msg) == ANYTHREAD) {
        DEBUGF(("anythread, call addBgNodeMessage\n"));
        addBgNodeMessage(msg);			/* non-affinity message */
	DEBUGM(4, ("The message is added to node\n\n"));
      }
      else {
        DEBUGF(("[N%d] affinity msg, call addBgThreadMessage to tID:%d\n", 
			BgMyNode(), CmiBgMsgThreadID(msg)));
	
        addBgThreadMessage(msg, CmiBgMsgThreadID(msg));
	DEBUGM(4, ("The message is added to thread(%d)\n\n", CmiBgMsgThreadID(msg)));
      }
    }
    /* let other communication thread do their jobs */
//    tCURRTIME += (CmiWallTimer()-tSTARTTIME);
    if (!schedule_flag) CthYield();
    tSTARTTIME = CmiWallTimer();
  }
}
Пример #8
0
//The original version of scheduler
void workThreadInfo::scheduler(int count)
{
  ckMsgQueue &q1 = myNode->nodeQ;
  ckMsgQueue &q2 = myNode->affinityQ[id];

  int cycle = CsdStopFlag;

  int recvd = 0;
  for (;;) {
    char *msg=NULL;
    int e1 = q1.isEmpty();
    int e2 = q2.isEmpty();
    int fromQ2 = 0;		// delay the deq of msg from affinity queue

    // not deq from nodeQ assuming no interrupt in the handler
    if (e1 && !e2) { msg = q2[0]; fromQ2 = 1;}
//    else if (e2 && !e1) { msg = q1.deq(); }
    else if (e2 && !e1) { msg = q1[0]; }
    else if (!e1 && !e2) {
      if (CmiBgMsgRecvTime(q1[0]) < CmiBgMsgRecvTime(q2[0])) {
//        msg = q1.deq();
        msg = q1[0];
      }
      else {
        msg = q2[0];
        fromQ2 = 1;
      }
    }
    /* if no msg is ready, go back to sleep */
    if ( msg == NULL ) {
//      tCURRTIME += (CmiWallTimer()-tSTARTTIME);
      DEBUGM(4,("N[%d] work thread %d has no msg and go to sleep!\n", BgMyNode(), id));
      if (watcher) watcher->replay();
#if BIGSIM_OUT_OF_CORE && BIGSIM_OOC_PREFETCH
      if(bgUseOutOfCore){
          //thread scheduling point!!            
          workThreadInfo *thisThd = schedWorkThds->pop();
          //CmiPrintf("thisThd=%p, actualThd=%p, equal=%d qsize=%d\n", thisThd, this, thisThd==this, schedWorkThds->size()); 
          assert(thisThd==this);
      }
#endif     
      CthSuspend();

      DEBUGM(4, ("N[%d] work thread %d awakened!\n", BgMyNode(), id));      
      continue;
    }
#if BIGSIM_TIMING
    correctMsgTime(msg);
#if THROTTLE_WORK
    if (correctTimeLog) {
      if (CmiBgMsgRecvTime(msg) > gvt+ BG_LEASH) {
	double nextT = CmiBgMsgRecvTime(msg);
	int prio = (int)(nextT*PRIO_FACTOR)+1;
	if (prio < 0) {
	  CmiPrintf("PRIO_FACTOR %e is too small. \n", PRIO_FACTOR);
	  CmiAbort("BigSim time correction abort!\n");
	}
//CmiPrintf("Thread %d YieldPrio: %g gvt: %g leash: %g\n", id, nextT, gvt, BG_LEASH);
	CthYieldPrio(CQS_QUEUEING_IFIFO, sizeof(int), (unsigned int*)&prio);
	continue;
      }
    }
#endif
#endif   /* TIMING */
    DEBUGM(2, ("[N%d] work thread T%d has a msg with recvT:%e msgId:%d.\n", BgMyNode(), id, CmiBgMsgRecvTime(msg), CmiBgMsgID(msg)));

//if (tMYNODEID==0)
//CmiPrintf("[%d] recvT: %e\n", tMYNODEID, CmiBgMsgRecvTime(msg));

    if (CmiBgMsgRecvTime(msg) > currTime) {
      tCURRTIME = CmiBgMsgRecvTime(msg);
    }

#if 1
    if (fromQ2 == 1) q2.deq();
    else q1.deq();
#endif


    recvd ++;  
    DEBUGM(4, ("[N%d] W[%d] will process a msg (handler=%d | cnt=%d", BgMyNode(), id, CmiBgMsgHandle(msg), recvd));
    int msgLen = CmiBgMsgLength(msg);
    DEBUGM(4, (" | len: %d | type: %d | node id: %d | src pe: %d\n" , msgLen, CmiBgMsgType(msg), CmiBgMsgNodeID(msg), CmiBgMsgSrcPe(msg)));
    for(int msgIndex=CmiBlueGeneMsgHeaderSizeBytes-1; msgIndex<msgLen; msgIndex++)
        DEBUGM(2, ("%d,", msg[msgIndex]));
    DEBUGM(2,("\n"));

    DEBUGM(4, ("[N%d] W[%d] now has %d msgs from own queue and %d from affinity before processing msg\n", BgMyNode(), id, q1.length(), q2.length()));


    //CmiMemoryCheck();

    // BgProcessMessage may trap into scheduler
    if(bgUseOutOfCore){
#if 0
    	if(startOutOfCore){
    	    DEBUGM(4, ("to execute in ooc mode\n"));
    	    if(isCoreOnDisk) this->broughtIntoMem();  
    	    BgProcessMessage(this, msg); //startOutOfCore may be changed in processing this msg (AMPI_Init)    
    
    	    if(startOOCChanged){ 
                //indicate AMPI_Init is called and before it is finished, out-of-core is not executed
                //just to track the 0->1 change phase (which means MPI_Init is finished)
                //the 1->0 phase is not tracked because "startOutOfCore" is unset so that
                //the next processing of a msg will not go into this part of code
                startOOCChanged=0;
    	    }else{
                //if(!isCoreOnDisk) { //the condition is added for virtual process
                    this->takenOutofMem();
                //}
    	    }
    	}else{
    	    DEBUGM(4, ("to execute not in ooc mode\n"));
    	    if(isCoreOnDisk) {
                CmiAbort("This should never be entered!\n");
                this->broughtIntoMem();  
    	    }
    	    //put before processing msg since thread may be scheduled during processing the msg
    	    BgProcessMessage(this, msg);
    	}
#else
        //schedWorkThds->print();
        bgOutOfCoreSchedule(this);
        BG_ENTRYSTART(msg);
#if BIGSIM_OOC_PREFETCH 
#if !BIGSIM_OOC_NOPREFETCH_AIO
        //do prefetch here for the next different thread in queue (schedWorkThds)
		assert(schedWorkThds->peek(0)==this);
        for(int offset=1; offset<schedWorkThds->size(); offset++) {
            workThreadInfo *nThd = schedWorkThds->peek(offset);
            //if nThd's core has been dumped to disk, then we could prefetch its core.
            //otherwise, it is the first time for the thread to process a message, thus
            //no need to resort to disk to find its core
            if(nThd!=this && !checkThreadInCore(nThd) 
               && nThd->isCoreOnDisk && oocPrefetchSpace->occupiedThd==NULL) {
                oocPrefetchSpace->newPrefetch(nThd);
            }
        }
#endif
#endif
        BgProcessMessage(this, msg);
#endif
    }else{
        DEBUGM(4, ("to execute not in ooc mode\n"));
        BG_ENTRYSTART(msg);
        BgProcessMessage(this, msg);
    }
    
    DEBUGM(4, ("[N%d] W[%d] now has %d msgs from own queue and %d from affinity after processing msg\n\n", BgMyNode(), id, q1.length(), q2.length()));
    BG_ENTRYEND();

    // counter of processed real mesgs
    stateCounters.realMsgProcCnt++;

    // NOTE: I forgot why I delayed the dequeue after processing it
#if 0
    if (fromQ2 == 1) q2.deq();
    else q1.deq();
#endif

    //recvd ++;

    //DEBUGF(("[N%d] work thread T%d finish a msg.\n", BgMyNode(), id));
    //CmiPrintf("[N%d] work thread T%d finish a msg (msg=%s, cnt=%d).\n", BgMyNode(), id, msg, recvd);
    
    if ( recvd == count) return;

    if (cycle != CsdStopFlag) break;

    /* let other work thread do their jobs */
    if (schedule_flag) {
    DEBUGF(("[N%d] work thread T%d suspend when done - %d to go.\n", BgMyNode(), tMYID, q2.length()));
    CthSuspend();
    DEBUGF(("[N%d] work thread T%d awakened here.\n", BgMyNode(), id));
    }
    else {
#if BIGSIM_OUT_OF_CORE && BIGSIM_OOC_PREFETCH
    //thread scheduling point!!
    //Suspend and put itself back to the end of the queue
      if(bgUseOutOfCore){
          workThreadInfo *thisThd = schedWorkThds->pop();
          //CmiPrintf("thisThd=%p, actualThd=%p, equal=%d qsize=%d\n", thisThd, this, thisThd==this, schedWorkThds->size()); 
          assert(thisThd==this);
          schedWorkThds->push(this);
      }
#endif
    CthYield();

    }
  }

  CsdStopFlag --;
}
Пример #9
0
 void barrier() {
   contribute (CkCallback(CkReductionTarget(Worker,  barrierH), workerarray));
   t = CthSelf();
   CthSuspend();
 }