示例#1
0
文件: vartree.c 项目: dzhus/knr
/**
   Return a pointer to a new line node with count of occurencies in line equal to 1.
*/
Line * newLine(int line)
{
  Line * l = allocateLine();
  l->number = line;
  l->count = 1;
  l->prev = NULL;

  return l;
}
示例#2
0
void CCache::doReqAck(MemRequest *mreq)
/* CCache reqAck {{{1 */
{
  trackAddress(mreq);

  mreq->recoverReqAction();

  AddrType addr = mreq->getAddr();
  Line *l = cacheBank->readLine(addr);
  // It could be l!=0 if we requested a check in the lower levels to change state.
  if (l == 0) {
    l = allocateLine(addr, mreq);
  }else{
    if (notifyHigherLevels(l,mreq)) {
      // FIXME I(0);
      I(mreq->hasPendingSetStateAck());
      return;
    }
  }

  s_reqSetState[mreq->getAction()]->inc(mreq->getStatsFlag());

  int16_t portid = router->getCreatorPort(mreq);
  GI(portid<0,mreq->isHomeNode());
	l->adjustState(mreq, portid);

  Time_t when = port->reqDone(mreq)+dyn_hitDelay;
  mshr->retire(addr);

  avgMissLat.sample(mreq->getTimeDelay(when), mreq->getStatsFlag());
  avgMemLat.sample(mreq->getTimeDelay(when));

  if(mreq->isHomeNode()) {
		mreq->ackAbs(when);
  }else {
    router->scheduleReqAckAbs(mreq,when); 
  }
}
示例#3
0
void LMVCache::pushLine(VMemPushLineReq *pushReq)
{
  PAddr paddr = pushReq->getPAddr();
  I(paddr);

  rdRevLVIDEnergy->inc();

  // pushLine steps (LMVCache)
  //
  // 1-Check if combining that address was initiated
  //
  // 2-cleanupSet (may free LVIDs and/or lines)
  //
  // 3-Otherwise forwardLine

  if (isCombining(paddr) && (pushReq->getVersionRef()->isSafe())) {
    // Already combining, so add this line too
    // when the first push cauesd by displace() in allocateLine() in FMVCache,
    // if it hit the combine, it will enter this func.
    // Also, if it is not hit, then if is safe, it will enter the combineInit();
    // this fuc will init a askPushLine(), and combine all the possible cacheline
    // from the upper level FMVCache.
    // add by hr
    combinePushLine(pushReq);
#ifdef DEBUG
    if (isCombining(paddr) ){
      ulong index = calcIndex4PAddr(paddr);
      for(ulong i=0; i < cache->getAssoc(); i++) {
	CacheLine *cl = cache->getPLine(index+i);
	if (cl->isInvalid())
	  continue;

	// All the cache lines for this addre must be gone
	I(!(cl->isHit(paddr) && cl->isSafe()));
      }
    }
#endif
    //if the pushReq is in combing, and it is safe, so just return the req to FMVCache,
    //the FMVCache do nothing but destroy thr req. add by hr
    if (pushReq->getVersionRef()->isSafe()) {
      ackPushLine(pushReq);
      return;
    }
  }else{
    // We can not loose messages
    I(pushReq->getAskPushReq() == 0);
  }

  if (pushReq->getVersionRef()->isKilled()) {
    ackPushLine(pushReq);
    return;
  }

  // when the pushReq is not safe and it is NOT getAskPushReq(), 
  // then put it in the victim. add by hr
  //
  // first, try to transform the version in the pushReq to lvid. add by hr
  LVID *lvid = findCreateLVID(pushReq);
  
  if (lvid==0) {
    wrRevLVIDEnergy->inc();
    if (pushReq->getVersionRef()->isSafe()) {
      I(!isCombining(pushReq->getPAddr()));
      combineInit(pushReq); // This func deal with the safe and not hit combine pushReq. It will 
      			    // combine all the possible safe cacheline. and just put the safe line 
			    // in the combine, that is cMap. and init the askReq, which will later 
			    // hit the combine. add by hr
      ackPushLine(pushReq);
    }else{
      recycleAllCache(pushReq->getVersionRef());// bao li!!!! add by hr
      forwardPushLine(pushReq);
      pushMiss.inc();
    }
    return;
  }
  I(!lvid->isKilled());

  LPAddr addr = lvid->calcLPAddr(paddr);

  CacheLine *cl = cache->findLine2Replace(addr);
  if (cl == 0) {
    cleanupSet(paddr);
    I(!lvid->isGarbageCollected());
    cl = allocateLine(lvid, addr);
    GI(cl, cl->isInvalid() || (cl->getLVID() == lvid && cl->isHit(paddr)) );

    if (cl == 0) {
      if (pushReq->getVersionRef()->isSafe()) {
	// initiate combine
	I(!isCombining(paddr));
	combineInit(pushReq);
	ackPushLine(pushReq);
      }else{
	I(!pushReq->getVersionRef()->isSafe());
	forwardPushLine(pushReq);
	pushHalfMiss.inc();
      }
      lvid->garbageCollect();
      return;
    }
  }else{
    cl->accessLine();
    if (!cl->isInvalid()) {
      if(cl->isHit(addr)) {
	// The line was already here??? Race detected
	ackPushLine(pushReq);
	return;
      }
      I(!cl->isLocked());

      if(!cl->hasState())
	cl->invalidate();
      else if(cl->isSafe()) {
	I(cl->isLeastSpecLine()); // It can be displaced at will (no combine)
#ifdef TS_VICTIM_DISPLACE_CLEAN
	writeMemory(paddr);
#else
	if (cl->isDirty())
	  writeMemory(paddr);
#endif
	cl->invalidate();
      }else{
	I(0);
      }
    }
    I(cl->isInvalid());
  }

#ifdef DEBUG
  if (isCombining(paddr) ){
    ulong index = calcIndex4PAddr(paddr);
    for(ulong i=0; i < cache->getAssoc(); i++) {
      CacheLine *cl = cache->getPLine(index+i);
      if (cl->isInvalid())
	continue;

      // All the cache lines for this addre must be gone
      I(!(cl->isHit(paddr) && cl->isSafe()));
    }
  }
#endif

  if (!pushReq->getVersionRef()->isKilled()) {
    if (!cl->isInvalid()) {
      GI(cl->hasState(), cl->getLVID() == lvid && cl->isHit(paddr));
      cl->invalidate(); 
    }
    if (lvid->getVersionRef()==0) {
      lvid = findCreateLVID(pushReq);
      I(lvid);
    }
    cl->resetState(addr, lvid, pushReq->getStateRef());
    cl->setMsgSerialNumber(pushReq->getSerialNumber()); 
  }

  ackPushLine(pushReq);
}