[patch] Checking for valid cache lines

Dave Brolley <[email protected]>
Newsgroups gmane.comp.emulators.sid.devel
Message-ID <[email protected]>
Hi,

I've committed the attached patch which adds some checks to make sure 
cache lines are valid before they are returned as a hit or flushed. The 
patch also move a call to 'addr_to_tag' past a possible return point to 
the place where the result is first needed.

Dave
sid-cache.ChangeLog (text/plain, 345 B)
2004-07-20  Dave Brolley  <[email protected]>

	* cacheutil.cxx (find): Make sure cache line is valid before returning
	it.
	* cache.cxx (write_any): Move call to addr_to_tag to a later point when
	the result is actually needed. Make sure cache line is valid before
	flushing it.
	(read_any): Make sure cache line is valid before flushing it.
sid-cache.patch.txt (text/plain, 2.8 KB)
Index: sid/component/cache/cache.cxx
===================================================================
RCS file: /cvs/src/src/sid/component/cache/cache.cxx,v
retrieving revision 1.18
diff -c -p -r1.18 cache.cxx
*** sid/component/cache/cache.cxx	1 Jul 2004 16:55:09 -0000	1.18
--- sid/component/cache/cache.cxx	20 Jul 2004 17:07:13 -0000
*************** cache_component::write_any (host_int_4 a
*** 180,186 ****
    if (LIKELY (collect_p))
      stats.writes++;
  
-   cache_tag tag = acache.addr_to_tag (addr);
    if (UNLIKELY (addr % sizeof (data) != 0))
      {
        if (LIKELY (collect_p))
--- 180,185 ----
*************** cache_component::write_any (host_int_4 a
*** 191,196 ****
--- 190,196 ----
    if (UNLIKELY (addr % line_size + sizeof (data) > line_size))
      return bus::misaligned;
  
+   cache_tag tag = acache.addr_to_tag (addr);
    cache_line* line = acache.find (tag);
    if (LIKELY (line))
      {
*************** cache_component::write_any (host_int_4 a
*** 215,221 ****
  
  	  if (! write_through_p)
  	    {
! 	      if (expelled_line->dirty_p ())
  		{
  		  // flush a dirty line being replaced
  		  if ((st = write_line (*expelled_line)) != bus::ok)
--- 215,221 ----
  
  	  if (! write_through_p)
  	    {
! 	      if (expelled_line->valid_p () && expelled_line->dirty_p ())
  		{
  		  // flush a dirty line being replaced
  		  if ((st = write_line (*expelled_line)) != bus::ok)
*************** cache_component::read_any (host_int_4 ad
*** 291,297 ****
  	  
  	  cache_line *expelled_line = acache.expell_line (tag);
  	  assert (expelled_line);
! 	  if (expelled_line->dirty_p ())
  	    {
  	      // flush a dirty line being replaced
  	      if ((st = write_line (*expelled_line)) != bus::ok)
--- 291,297 ----
  	  
  	  cache_line *expelled_line = acache.expell_line (tag);
  	  assert (expelled_line);
! 	  if (expelled_line->valid_p () && expelled_line->dirty_p ())
  	    {
  	      // flush a dirty line being replaced
  	      if ((st = write_line (*expelled_line)) != bus::ok)
Index: sid/component/cache/cacheutil.cxx
===================================================================
RCS file: /cvs/src/src/sid/component/cache/cacheutil.cxx,v
retrieving revision 1.9
diff -c -p -r1.9 cacheutil.cxx
*** sid/component/cache/cacheutil.cxx	10 May 2004 21:51:10 -0000	1.9
--- sid/component/cache/cacheutil.cxx	20 Jul 2004 17:07:13 -0000
*************** cache_set::find (const cache_tag& tag)
*** 173,179 ****
    // order of associativity will be small.
  
    for (const_iterator_t it = lines.begin (); it != lines.end (); it++)
!     if (tag == *(*it))
        {
  	replacer.update (*this, *(*it));
  	return *it;
--- 173,179 ----
    // order of associativity will be small.
  
    for (const_iterator_t it = lines.begin (); it != lines.end (); it++)
!     if (tag == *(*it) && (*it)->valid_p ())
        {
  	replacer.update (*this, *(*it));
  	return *it;
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.