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

📄 disk_cache.c

📁 ml-rsim 多处理器模拟器 支持类bsd操作系统
💻 C
📖 第 1 页 / 共 2 页
字号:
int DISK_cache_insert(SCSI_DISK *pdisk, int start_block, int length,		       int segment){  int n;  int segment_size = (pdisk->cache_size * 1024) /    (pdisk->cache_segments * SCSI_BLOCK_SIZE);  int segment_full = pdisk->cache[segment].end_block -    pdisk->cache[segment].start_block;  DISK_cache_touch_segment(pdisk, segment);  if (segment_full + length > segment_size)    length = segment_size - segment_full;  /* append to end of segment -----------------------------------------------*/  if (start_block == pdisk->cache[segment].end_block)    pdisk->cache[segment].end_block += length;  /* overwrite end of segment -----------------------------------------------*/  else if ((start_block >= pdisk->cache[segment].start_block) &&	   (start_block < pdisk->cache[segment].end_block) &&	   (start_block + length > pdisk->cache[segment].end_block))    pdisk->cache[segment].end_block = start_block + length;  /* overwrite entire segment -----------------------------------------------*/  else    {      pdisk->cache[segment].start_block = start_block;      pdisk->cache[segment].end_block = start_block + length;    }  pdisk->cache[segment].committed = 1;    return(length);}/*===========================================================================*//* touch an entire block number range: look for segment containing           *//* start_block and touch it, adjust start_block and length and repeat search *//*===========================================================================*/void DISK_cache_touch(SCSI_DISK *pdisk, int start_block, int length){  int n;  for (n = 0; n < pdisk->cache_segments; n++)    {      if ((start_block >= pdisk->cache[n].start_block) &&	  (start_block < pdisk->cache[n].end_block) &&	  (start_block + length > pdisk->cache[n].end_block))	{	  DISK_cache_touch_segment(pdisk, n);	  length -= (pdisk->cache[n].end_block - start_block);	  start_block = pdisk->cache[n].end_block;	  n = -1;	  continue;	}      if ((start_block >= pdisk->cache[n].start_block) &&	  (start_block < pdisk->cache[n].end_block) &&	  (start_block + length <= pdisk->cache[n].end_block))	DISK_cache_touch_segment(pdisk, n);    }}/*===========================================================================*//* Update LRU counters so that this segment is the youngest.                 *//* Set counter to the maximum value, and decrement all counters that are     *//* greater than that counters old value.                                     *//*===========================================================================*/void DISK_cache_touch_segment(SCSI_DISK *pdisk, int segment){  int n, old_age = pdisk->cache[segment].lru;  for (n = 0; n < pdisk->cache_segments; n++)    if (pdisk->cache[n].lru > old_age)      pdisk->cache[n].lru--;  pdisk->cache[segment].lru = pdisk->cache_segments - 1;}/*===========================================================================*//* Insert write data into the cache: check if number of write segments       *//* exceed maximum number, otherwise get a new segment, insert data and set   *//* set write flag. Repeat until all data is written or out of write segments *//*===========================================================================*/int DISK_cache_write(SCSI_DISK *pdisk, int start_block, int length){  int n, writes, current_length = 0, rc;  writes = 0;  for (n = 0; n < pdisk->cache_segments; n++)    {      if (pdisk->cache[n].write)	writes++;    }  if (writes >= pdisk->cache_write_segments)    return(0);  do    {      n = DISK_cache_newsegment(pdisk);      rc = DISK_cache_insert(pdisk, start_block, length, n);      length -= rc;      start_block += rc;      current_length += rc;      writes++;      pdisk->cache[n].write = 1;      pdisk->cache[n].committed = 0;    }  while ((writes < pdisk->cache_write_segments) && (length > 0));    return(current_length);}/*===========================================================================*//* Find first committed write segment and return start block/length and      *//* segment number.                                                           *//*===========================================================================*/int DISK_cache_getwsegment(SCSI_DISK *pdisk, int *start_block, int *length){  int n;  for (n = 0; n < pdisk->cache_segments; n++)    if ((pdisk->cache[n].write == 1) &&	(pdisk->cache[n].committed == 1) &&	(*start_block <= pdisk->cache[n].start_block) &&	(*start_block + *length >= pdisk->cache[n].end_block))      {	*start_block = pdisk->cache[n].start_block;	*length      = pdisk->cache[n].end_block - pdisk->cache[n].start_block;	DISK_cache_touch_segment(pdisk, n);	return(n);      }  return(-1);}/*===========================================================================*//* Commit a write request: find first write segment that contains            *//* start_block, set the committed-flag, adjust start_block and length and    *//* repeat until length is zero. In addition, invalidate all read segments    *//* that overlap the write request.                                           *//*===========================================================================*/void DISK_cache_commit_write(SCSI_DISK *pdisk, int start_block, int length){  int s;  for (s = 0; s < pdisk->cache_segments; s++)    {      if (pdisk->cache[s].write)	continue;      if ((start_block <= pdisk->cache[s].start_block) &&	  (start_block + length > pdisk->cache[s].start_block) &&	  (start_block + length < pdisk->cache[s].end_block))	{	  pdisk->cache[s].start_block = start_block + length;	  continue;	}      if ((start_block > pdisk->cache[s].start_block) &&	  (start_block + length <= pdisk->cache[s].end_block))	{	  pdisk->cache[s].start_block = 0;	  pdisk->cache[s].end_block   = 0;	  pdisk->cache[s].committed   = 0;	  pdisk->cache[s].lru = 0;	  continue;	}      if ((start_block > pdisk->cache[s].start_block) &&	  (start_block <= pdisk->cache[s].end_block) &&	  (start_block + length > pdisk->cache[s].start_block) &&	  (start_block + length >= pdisk->cache[s].end_block))	{	  pdisk->cache[s].end_block = start_block;	  continue;	}      if ((start_block <= pdisk->cache[s].start_block) &&	  (start_block + length >= pdisk->cache[s].end_block))	{	  pdisk->cache[s].start_block = 0;	  pdisk->cache[s].end_block   = 0;	  pdisk->cache[s].committed   = 0;	  pdisk->cache[s].lru = 0;	  continue;	}      }    s = 0;  do    {      if ((pdisk->cache[s].start_block == start_block) &&	  (pdisk->cache[s].write == 1))	{	  pdisk->cache[s].committed = 1;	  start_block = pdisk->cache[s].end_block;	  length -= pdisk->cache[s].end_block - pdisk->cache[s].start_block;	  s = 0;	  continue;	}      s++;    }  while (s < pdisk->cache_segments);}/*===========================================================================*//* Complete a write operation by clearing the write bit.                     *//*===========================================================================*/void DISK_cache_complete_write(SCSI_DISK *pdisk, int segment){  pdisk->cache[segment].write = 0;}/*===========================================================================*//* Check if segment is full.                                                 *//*===========================================================================*/int DISK_cache_segment_full(SCSI_DISK *pdisk, int segment){  return(pdisk->cache[segment].end_block - pdisk->cache[segment].start_block >=	 (pdisk->cache_size*1024) / (pdisk->cache_segments*SCSI_BLOCK_SIZE));}

⌨️ 快捷键说明

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