⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cache.c

📁 这个是LINUX下的GDB调度工具的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
/* Requeu the given request from the last of the given pipeline.  */static voidpipeline_requeue_request (FRV_CACHE_PIPELINE *p){  FRV_CACHE_STAGE *stage = & p->stages[LAST_STAGE];  FRV_CACHE_REQUEST *req = stage->request;  stage->request = NULL;  pipeline_add_request (p, req);}/* Return the priority lower than the lowest one in this cache pipeline.   0 is the highest priority.  */static intnext_priority (FRV_CACHE *cache, FRV_CACHE_PIPELINE *pipeline){  int i, j;  int pipe;  int lowest = 0;  FRV_CACHE_REQUEST *req;  /* Check the priorities of any queued items.  */  for (req = pipeline->requests; req != NULL; req = req->next)    if (req->priority > lowest)      lowest = req->priority;  /* Check the priorities of items in the pipeline stages.  */  for (i = FIRST_STAGE; i < FRV_CACHE_STAGES; ++i)    {      FRV_CACHE_STAGE *stage = & pipeline->stages[i];      if (stage->request != NULL && stage->request->priority > lowest)        lowest = stage->request->priority;    }  /* Check the priorities of load requests waiting in WAR.  These are one     higher than the request that spawned them.  */  for (i = 0; i < NUM_WARS; ++i)    {      FRV_CACHE_WAR *war = & pipeline->WAR[i];      if (war->valid && war->priority > lowest)	lowest = war->priority + 1;    }  /* Check the priorities of any BARS or NARS associated with this pipeline.     These are one higher than the request that spawned them.  */  pipe = pipeline - cache->pipeline;  if (cache->BARS.valid && cache->BARS.pipe == pipe       && cache->BARS.priority > lowest)    lowest = cache->BARS.priority + 1;  if (cache->NARS.valid && cache->NARS.pipe == pipe       && cache->NARS.priority > lowest)    lowest = cache->NARS.priority + 1;  /* Return a priority 2 lower than the lowest found.  This allows a WAR     request to be generated with a priority greater than this but less than     the next higher priority request.  */  return lowest + 2;}static voidadd_WAR_request (FRV_CACHE_PIPELINE* pipeline, FRV_CACHE_WAR *war){  /* Add the load request to the indexed pipeline.  */  FRV_CACHE_REQUEST *req = new_cache_request ();  req->kind = req_WAR;  req->reqno = war->reqno;  req->priority = war->priority;  req->address = war->address;  req->u.WAR.preload = war->preload;  req->u.WAR.lock = war->lock;  pipeline_add_request (pipeline, req);}/* Remove the next request from the given pipeline and return it.  */static FRV_CACHE_REQUEST *pipeline_next_request (FRV_CACHE_PIPELINE *p){  FRV_CACHE_REQUEST *first = p->requests;  if (first != NULL)    pipeline_remove_request (p, first);  return first;}/* Return the request which is at the given stage of the given pipeline.  */static FRV_CACHE_REQUEST *pipeline_stage_request (FRV_CACHE_PIPELINE *p, int stage){  return p->stages[stage].request;}static voidadvance_pipelines (FRV_CACHE *cache){  int stage;  int pipe;  FRV_CACHE_PIPELINE *pipelines = cache->pipeline;  /* Free the final stage requests.  */  for (pipe = 0; pipe < FRV_CACHE_PIPELINES; ++pipe)    {      FRV_CACHE_REQUEST *req = pipelines[pipe].stages[LAST_STAGE].request;      if (req != NULL)	free_cache_request (req);    }  /* Shuffle the requests along the pipeline.  */  for (stage = LAST_STAGE; stage > FIRST_STAGE; --stage)    {      for (pipe = 0; pipe < FRV_CACHE_PIPELINES; ++pipe)	pipelines[pipe].stages[stage] = pipelines[pipe].stages[stage - 1];    }  /* Add a new request to the pipeline.  */  for (pipe = 0; pipe < FRV_CACHE_PIPELINES; ++pipe)    pipelines[pipe].stages[FIRST_STAGE].request      = pipeline_next_request (& pipelines[pipe]);}/* Handle a request for a load from the given address.  */voidfrv_cache_request_load (FRV_CACHE *cache, unsigned reqno, SI address, int slot){  FRV_CACHE_REQUEST *req;  /* slot is a UNIT_*.  Convert it to a cache pipeline index.  */  int pipe = convert_slot_to_index (slot);  FRV_CACHE_PIPELINE *pipeline = & cache->pipeline[pipe];  /* Add the load request to the indexed pipeline.  */  req = new_cache_request ();  req->kind = req_load;  req->reqno = reqno;  req->priority = next_priority (cache, pipeline);  req->address = address;  pipeline_add_request (pipeline, req);}voidfrv_cache_request_store (FRV_CACHE *cache, SI address,			 int slot, char *data, unsigned length){  FRV_CACHE_REQUEST *req;  /* slot is a UNIT_*.  Convert it to a cache pipeline index.  */  int pipe = convert_slot_to_index (slot);  FRV_CACHE_PIPELINE *pipeline = & cache->pipeline[pipe];  /* Add the load request to the indexed pipeline.  */  req = new_store_request (length);  req->kind = req_store;  req->reqno = NO_REQNO;  req->priority = next_priority (cache, pipeline);  req->address = address;  req->u.store.length = length;  memcpy (req->u.store.data, data, length);  pipeline_add_request (pipeline, req);  invalidate_return_buffer (cache, address);}/* Handle a request to invalidate the cache line containing the given address.   Flush the data if requested.  */voidfrv_cache_request_invalidate (FRV_CACHE *cache, unsigned reqno, SI address,			      int slot, int all, int flush){  FRV_CACHE_REQUEST *req;  /* slot is a UNIT_*.  Convert it to a cache pipeline index.  */  int pipe = convert_slot_to_index (slot);  FRV_CACHE_PIPELINE *pipeline = & cache->pipeline[pipe];  /* Add the load request to the indexed pipeline.  */  req = new_cache_request ();  req->kind = req_invalidate;  req->reqno = reqno;  req->priority = next_priority (cache, pipeline);  req->address = address;  req->u.invalidate.all = all;  req->u.invalidate.flush = flush;  pipeline_add_request (pipeline, req);}/* Handle a request to preload the cache line containing the given address.  */voidfrv_cache_request_preload (FRV_CACHE *cache, SI address,			   int slot, int length, int lock){  FRV_CACHE_REQUEST *req;  /* slot is a UNIT_*.  Convert it to a cache pipeline index.  */  int pipe = convert_slot_to_index (slot);  FRV_CACHE_PIPELINE *pipeline = & cache->pipeline[pipe];  /* Add the load request to the indexed pipeline.  */  req = new_cache_request ();  req->kind = req_preload;  req->reqno = NO_REQNO;  req->priority = next_priority (cache, pipeline);  req->address = address;  req->u.preload.length = length;  req->u.preload.lock = lock;  pipeline_add_request (pipeline, req);  invalidate_return_buffer (cache, address);}/* Handle a request to unlock the cache line containing the given address.  */voidfrv_cache_request_unlock (FRV_CACHE *cache, SI address, int slot){  FRV_CACHE_REQUEST *req;  /* slot is a UNIT_*.  Convert it to a cache pipeline index.  */  int pipe = convert_slot_to_index (slot);  FRV_CACHE_PIPELINE *pipeline = & cache->pipeline[pipe];  /* Add the load request to the indexed pipeline.  */  req = new_cache_request ();  req->kind = req_unlock;  req->reqno = NO_REQNO;  req->priority = next_priority (cache, pipeline);  req->address = address;  pipeline_add_request (pipeline, req);}/* Check whether this address interferes with a pending request of   higher priority.  */static intaddress_interference (FRV_CACHE *cache, SI address, FRV_CACHE_REQUEST *req,		      int pipe){  int i, j;  int line_mask = ~(cache->line_size - 1);  int other_pipe;  int priority = req->priority;  FRV_CACHE_REQUEST *other_req;  SI other_address;  SI all_address;  address &= line_mask;  all_address = -1 & line_mask;  /* Check for collisions in the queue for this pipeline.  */  for (other_req = cache->pipeline[pipe].requests;       other_req != NULL;       other_req = other_req->next)    {      other_address = other_req->address & line_mask;      if ((address == other_address || address == all_address)	  && priority > other_req->priority)	return 1;    }  /* Check for a collision in the the other pipeline.  */  other_pipe = pipe ^ 1;  other_req = cache->pipeline[other_pipe].stages[LAST_STAGE].request;  if (other_req != NULL)    {      other_address = other_req->address & line_mask;      if (address == other_address || address == all_address)	return 1;    }  /* Check for a collision with load requests waiting in WAR.  */  for (i = LS; i < FRV_CACHE_PIPELINES; ++i)    {      for (j = 0; j < NUM_WARS; ++j)	{	  FRV_CACHE_WAR *war = & cache->pipeline[i].WAR[j];	  if (war->valid	      && (address == (war->address & line_mask) 		  || address == all_address)	      && priority > war->priority)	    return 1;	}      /* If this is not a WAR request, then yield to any WAR requests in	 either pipeline or to a higher priority request in the same pipeline.      */      if (req->kind != req_WAR)	{	  for (j = FIRST_STAGE; j < FRV_CACHE_STAGES; ++j)	    {	      other_req = cache->pipeline[i].stages[j].request;	      if (other_req != NULL)		{		  if (other_req->kind == req_WAR)		    return 1;		  if (i == pipe		      && (address == (other_req->address & line_mask) 			  || address == all_address)		      && priority > other_req->priority)		    return 1;		}	    }	}    }  /* Check for a collision with load requests waiting in ARS.  */  if (cache->BARS.valid      && (address == (cache->BARS.address & line_mask)	  || address == all_address)      && priority > cache->BARS.priority)    return 1;  if (cache->NARS.valid      && (address == (cache->NARS.address & line_mask)	  || address == all_address)      && priority > cache->NARS.priority)    return 1;  return 0;}/* Wait for a free WAR register in BARS or NARS.  */static voidwait_for_WAR (FRV_CACHE* cache, int pipe, FRV_CACHE_REQUEST *req){  FRV_CACHE_WAR war;  FRV_CACHE_PIPELINE *pipeline = & cache->pipeline[pipe];  if (! cache->BARS.valid)    {      cache->BARS.pipe = pipe;      cache->BARS.reqno = req->reqno;      cache->BARS.address = req->address;      cache->BARS.priority = req->priority - 1;      switch (req->kind)	{	case req_load:	  cache->BARS.preload = 0;	  cache->BARS.lock = 0;	  break;	case req_store:	  cache->BARS.preload = 1;	  cache->BARS.lock = 0;	  break;	case req_preload:	  cache->BARS.preload = 1;	  cache->BARS.lock = req->u.preload.lock;	  break;	}      cache->BARS.valid = 1;      return;    }  if (! cache->NARS.valid)    {      cache->NARS.pipe = pipe;      cache->NARS.reqno = req->reqno;      cache->NARS.address = req->address;      cache->NARS.priority = req->priority - 1;      switch (req->kind)	{	case req_load:	  cache->NARS.preload = 0;	  cache->NARS.lock = 0;	  break;	case req_store:	  cache->NARS.preload = 1;	  cache->NARS.lock = 0;	  break;	case req_preload:	  cache->NARS.preload = 1;	  cache->NARS.lock = req->u.preload.lock;	  break;	}      cache->NARS.valid = 1;      return;    }  /* All wait registers are busy, so resubmit this request.  */  pipeline_requeue_request (pipeline);}/* Find a free WAR register and wait for memory to fetch the data.  */static voidwait_in_WAR (FRV_CACHE* cache, int pipe, FRV_CACHE_REQUEST *req){  int war;  FRV_CACHE_PIPELINE *pipeline = & cache->pipeline[pipe];  /* Find a valid WAR to  hold this request.  */  for (war = 0; war < NUM_WARS; ++war)    if (! pipeline->WAR[war].valid)      break;  if (war >= NUM_WARS)    {      wait_for_WAR (cache, pipe, req);      return;    }  pipeline->WAR[war].address = req->address;  pipeline->WAR[war].reqno = req->reqno;  pipeline->WAR[war].priority = req->priority - 1;  pipeline->WAR[war].latency = cache->memory_latency + 1;  switch (req->kind)    {    case req_load:      pipeline->WAR[war].preload = 0;      pipeline->WAR[war].lock = 0;      break;    case req_store:      pipeline->WAR[war].preload = 1;      pipeline->WAR[war].lock = 0;      break;    case req_preload:      pipeline->WAR[war].preload = 1;      pipeline->WAR[war].lock = req->u.preload.lock;      break;    }  pipeline->WAR[war].valid = 1;}static voidhandle_req_load (FRV_CACHE *cache, int pipe, FRV_CACHE_REQUEST *req){  FRV_CACHE_TAG *tag;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -