This is the mail archive of the sid@sources.redhat.com mailing list for the SID project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch][rfa] Inheriting from cache_component and friends


Following up on my recent posting regarding specializing on the existing cache_component. Here is the patch which allows use of cache_component and cache_line as base classes. The purpose of this is to allow me to implement a target-specific cache with a unique cache line implementation. The main changes are:

1) Make cache_line into a virtual base class. The original cache_line class is now called internal_cache_line (it keeps its data internally) and its functionality is unchanged.

2) Introduce a new cache_line_factory class which is used to allocate cache lines. Each cache_component is now passed a reference to a cache_line_factory which it uses to allocate its cache lines. An instance called internal_line_factory is used to create lines of type internal_cache_line.

3) The find mechanism of cache and cache_set previously passed cache lines by assignment via reference arguments. This is no longer possible with a virtual class implementation. The mechanism now returns a pointer to the found line (if found) and NULL otherwise.

4) Similarly, the 'replace' method of cache_replacement_algorithm previously passed in a new line and returned the old one by assignment using reference arguments. Now, a pointer to the expelled line is returned (if any --- all lines might be locked) and NULL otherwise. The expelled line is updated using access methods. The 'replace' method has been renamed to 'expell' since the line is no longer replaced. This also eliminates construction and destruction overhead for each cache miss. Also, the copy constructor and assignment operator for cache_line are no longer necessary.

5) The 'insert' and 'extract' methods of cache_line are now declared using a macro for the cartesian product of possible datatypes as is common elsewhere. It was not possible to instantiate the necessary termplate methods automatically in the virtual base class.

6) The changes the sid/component/cfgroot were found necessary while debugging problems in my implementation.

7) The changes to main/dynamic/commonCfg.h were necessary in order to allow me to inherit from CacheCfg for my specialized cache configurator and to get a handle to the loader configuration from the SessionCfg so that I could connect the loader's "set-endian" pin to my cache line implementation.

I have tested this against my own port (with specialized cache and cache lines) as well as against xstormy16. All of the sid testsuite checks without regression (including the cache-specific tests). I'm seeking comments and approval to commit.

Regards,
Dave


2004-04-27  Dave Brolley  <brolley@redhat.com>

	* cache.cxx: Update calls to cache::find.
	* cacheutil.cxx (cache_set::allocate_lines): Now takes cache index as
	an argument. Update all callers.
	(cache_set::find): Now returns a pointer to the line, if found. Update
	all callers.
	(cache::find): Ditto.
	(cache_set::expell_line): Update the status of the expelled line.
	* cacheutil.h (cache_line_factory::make_line): Now takes cache index as
	an argument. Update all callers.
	(cache_set::allocate_lines): Now takes cache index as
	an argument. Update all callers.
	(cache_set::find): Now returns a pointer to the line, if found. Update
	all callers.
	(cache::find): Ditto.

2004-04-27  Dave Brolley  <brolley@redhat.com>

	* cacheutil.h (cache_line): Removed copy constructor. Now virtual base
	class.
	(cache_line::operator=): Removed.
	(internal_cache_line): New class implements former cache_line class.
	(cache_set): Now takes cache_line_factory.
	(allocate_lines): New method moves line allocation from the constructor.
	(cache_set::set_line): Now takes reference to cache_line.
	(cache_set::replace_line): Renamed to expell_line. Now returns a pointer
	to the expelled line.
	(cache): Now takes cache_line_factory argument.
	(cache::init): New method moves set allocation from the constructor.
	(cache_set::expell_line): Renamed to expell_line. Now returns a pointer
	to the expelled line.
	(cache_line_factory): New class.
	* cacheutil.cxx (cache_line): Removed copy constructor. Now virtual base
	class.
	(cache_line::operator=): Removed.
	(internal_cache_line): New class implements former cache_line class.
	(cache_set): Now takes cache_line_factory.
	(allocate_lines): New method moves line allocation from the constructor.
	(cache_set::set_line): Now takes reference to cache_line.
	(dummy): Now internal to cache_set::find.
	(cache_set::replace_line): Renamed to expell_line. Now returns a pointer
	to the expelled line.
	(cache): Now takes cache_line_factory argument.
	(cache::init): New method moves set allocation from the constructor.
	(cache_set::expell_line): Renamed to expell_line. Now returns a pointer
	to the expelled line.
	* cache.h (cache_replacement_algorithm::expell): Renamed from 'replace'.
	Returns a pointer to the expelled line. Update specializations.
	(cache_component): Now takes a cache_line_factory as an argument.
	Private data now protected.
	(line_factory): New member of cache_component.
	(~cache_component): Now virtual.
	(CacheCreate): Pass internal_line_factory to cache_component.
	* cache.cxx (line_sizes): Make it static.
	(line_sizes): Ditto.
	(replacement_algorithms): Ditto.
	(internal_line_factory): New static cache_line_factory.
	(cache_component): Now takes a cache_line_factory as an argument. Pass
	the cache line factory to the constructor for acache. Save a reference
	to the line factory. Call acache.init
	(write_any): Rewrite to use cache::expell_line instead of the former
	cache::replace.
	(read_any): Ditto.
	(cache_replacement_algorithm::expell): Renamed from 'replace'. Returns
	a pointer to the expelled line. Update all callers and specializations.
	(CacheCreate): Pass internal_line_factory to cache_component.

2004-04-27  Dave Brolley  <brolley@redhat.com>

	* compConfig.cxx (register_dso): Check dl_handle before attempting to
	open ".a".
	* Makefile.am (libconfig_la_DEPENDENCIES): Add @LIBLTDL@.
	* Makefile.in: Regenerated.

2004-04-27  Dave Brolley  <brolley@redhat.com>

	* commonCfg.h (CacheCfg::compute_comptype): Now virtual.
	(SessionCfg::get_loader): New method.

Index: sid/component/cache/cache.cxx
===================================================================
RCS file: /cvs/src/src/sid/component/cache/cache.cxx,v
retrieving revision 1.16
diff -c -p -r1.16 cache.cxx
*** sid/component/cache/cache.cxx	8 Jan 2003 02:51:57 -0000	1.16
--- sid/component/cache/cache.cxx	27 Apr 2004 20:20:26 -0000
***************
*** 1,6 ****
  // cache.cxx -- A universal memory cache. -*- C++ -*-
  
! // Copyright (C) 2001, 2002 Red Hat.
  // This file is part of SID and is licensed under the GPL.
  // See the file COPYING.SID for conditions for redistribution.
  
--- 1,6 ----
  // cache.cxx -- A universal memory cache. -*- C++ -*-
  
! // Copyright (C) 2001, 2002, 2004 Red Hat.
  // This file is part of SID and is licensed under the GPL.
  // See the file COPYING.SID for conditions for redistribution.
  
*************** using std::endl;
*** 26,41 ****
  
  #include "cache.h"
  
! string line_sizes[] =
    { "16", "32", "64", "128" };
  
! string cache_sizes[] =
    { "1", "2", "4", "8", "16", "32", "64", "128", "256", "512" };
  
! string assocs[] =
    { "direct", "full", "2way", "4way" };
  
! string replacement_algorithms[] =
    { "lru", "fifo", "random" }; 
  
  // One per replacement policy
--- 26,41 ----
  
  #include "cache.h"
  
! static string line_sizes[] =
    { "16", "32", "64", "128" };
  
! static string cache_sizes[] =
    { "1", "2", "4", "8", "16", "32", "64", "128", "256", "512" };
  
! static string assocs[] =
    { "direct", "full", "2way", "4way" };
  
! static string replacement_algorithms[] =
    { "lru", "fifo", "random" }; 
  
  // One per replacement policy
*************** static cache_replacement_null null_repla
*** 43,54 ****
  static cache_replacement_lru lru_replacement;
  static cache_replacement_fifo fifo_replacement;
  static cache_replacement_random random_replacement;
  
  cache_component::cache_component (unsigned assocy,
  				  unsigned cache_sz, 
  				  unsigned line_sz,
! 				  cache_replacement_algorithm& replacer)
!   :acache (cache_sz, line_sz, assocy, replacer),
     upstream (*this),
     downstream (0),
     report_pin (this, &cache_component::emit_report),
--- 43,56 ----
  static cache_replacement_lru lru_replacement;
  static cache_replacement_fifo fifo_replacement;
  static cache_replacement_random random_replacement;
+ static cache_line_factory internal_line_factory;
  
  cache_component::cache_component (unsigned assocy,
  				  unsigned cache_sz, 
  				  unsigned line_sz,
! 				  cache_replacement_algorithm& replacer,
! 				  cache_line_factory& factory)
!   :acache (cache_sz, line_sz, assocy, replacer, factory),
     upstream (*this),
     downstream (0),
     report_pin (this, &cache_component::emit_report),
*************** cache_component::cache_component (unsign
*** 67,72 ****
--- 69,75 ----
     write_through_p (false),
     collect_p (true),
     report_heading ("cache profile report"),
+    line_factory (factory),
     line_size (line_sz),
     cache_size (cache_sz),
     assoc (assocy),
*************** cache_component::cache_component (unsign
*** 75,80 ****
--- 78,84 ----
     refill_latency (0),
     refill_latency_specified (false)
  {
+   acache.init ();
    memset (&stats, 0, sizeof (stats));
  
    add_bus ("upstream", &upstream);
*************** template <typename DataType>
*** 168,174 ****
  bus::status
  cache_component::write_any (host_int_4 addr, DataType data)
  {
-   bool hit;
    bus::status st, read_status;
  
    if (UNLIKELY (downstream == 0))
--- 172,177 ----
*************** cache_component::write_any (host_int_4 a
*** 177,198 ****
    if (LIKELY (collect_p))
      stats.writes++;
  
    if (UNLIKELY (addr % sizeof (data) != 0))
      {
        // Punt on misaligned accesses
        if (LIKELY (collect_p))
  	stats.misaligned_writes++;
  
!       cache_line& line = acache.find (acache.addr_to_tag (addr), hit);
!       if (hit)
        {
! 	if (line.dirty_p ())
          {	
  	  // flush a dirty line being replaced
! 	  if ((st = write_line (line)) != bus::ok)
  	    return st;
  	}
! 	acache.expunge (line);
        }
  
        st = downstream->read (addr, data);
--- 180,202 ----
    if (LIKELY (collect_p))
      stats.writes++;
  
+   cache_tag tag = acache.addr_to_tag (addr);
    if (UNLIKELY (addr % sizeof (data) != 0))
      {
        // Punt on misaligned accesses
        if (LIKELY (collect_p))
  	stats.misaligned_writes++;
  
!       cache_line* line = acache.find (tag);
!       if (line)
        {
! 	if (line->dirty_p ())
          {	
  	  // flush a dirty line being replaced
! 	  if ((st = write_line (*line)) != bus::ok)
  	    return st;
  	}
! 	acache.expunge (*line);
        }
  
        st = downstream->read (addr, data);
*************** cache_component::write_any (host_int_4 a
*** 200,211 ****
        return st;
      }
  
!   cache_line& line = acache.find (acache.addr_to_tag (addr), hit);
!   if (LIKELY (hit))
      {
        if (LIKELY (collect_p))
  	stats.write_hits++;
!       line.insert (line_offset (line, addr), data);
        if (write_through_p)
  	{
  	  if ((st = downstream->write (addr, data)) != bus::ok)
--- 204,215 ----
        return st;
      }
  
!   cache_line* line = acache.find (tag);
!   if (LIKELY (line))
      {
        if (LIKELY (collect_p))
  	stats.write_hits++;
!       line->insert (line_offset (*line, addr), data);
        if (write_through_p)
  	{
  	  if ((st = downstream->write (addr, data)) != bus::ok)
*************** cache_component::write_any (host_int_4 a
*** 214,247 ****
      }
    else
      {
!       if (write_allocate_p)
  	{
! 	  if (acache.vacancy_p (addr))
  	    {
! 	      cache_line expelled_line (line_size);
! 	      cache_line new_line (line_size, acache.addr_to_tag (addr));
! 	      if ((read_status = read_line (new_line)) != bus::ok)
! 		return read_status;
! 	      
! 	      new_line.insert (line_offset (new_line, addr), data);
! 	      acache.replace (expelled_line, new_line);
! 	      
! 	      if (collect_p)
! 		stats.replacements++;
! 	      
! 	      if (expelled_line.dirty_p () && !write_through_p)
  		{
  		  // flush a dirty line being replaced
! 		  if ((st = write_line (expelled_line)) != bus::ok)
! 		    return st;
! 		}
! 	      
! 	      if (write_through_p)
! 		{
! 		  if ((st = downstream->write (addr, data)) != bus::ok)
  		    return st;
  		}
  	    }
  	}
        else
  	{
--- 218,251 ----
      }
    else
      {
!       if (write_allocate_p && acache.vacancy_p (addr))
  	{
! 	  if (collect_p)
! 	    stats.replacements++;
! 
! 	  cache_line *expelled_line = acache.expell_line (tag);
! 	  assert (expelled_line);
! 
! 	  if (! write_through_p)
  	    {
! 	      if (expelled_line->dirty_p ())
  		{
  		  // flush a dirty line being replaced
! 		  if ((st = write_line (*expelled_line)) != bus::ok)
  		    return st;
  		}
  	    }
+ 	  else
+ 	    {
+ 	      if ((st = downstream->write (addr, data)) != bus::ok)
+ 		return st;
+ 	    }
+ 
+ 	  expelled_line->set_tag (tag);
+ 	  if ((read_status = read_line (*expelled_line)) != bus::ok)
+ 	    return read_status;
+ 	      
+ 	  expelled_line->insert (line_offset (*expelled_line, addr), data);
  	}
        else
  	{
*************** cache_component::write_any (host_int_4 a
*** 252,258 ****
      }
  
    st = bus::ok;
!   if (hit)
      st.latency = hit_latency;
    else
      st.latency = read_status.latency + miss_latency;
--- 256,262 ----
      }
  
    st = bus::ok;
!   if (line)
      st.latency = hit_latency;
    else
      st.latency = read_status.latency + miss_latency;
*************** cache_component::read_any (host_int_4 ad
*** 282,317 ****
        return st;
      }
  
!   bool hit;
!   cache_line& line = acache.find (acache.addr_to_tag (addr), hit);
!   if (LIKELY (hit))
      {
        if (LIKELY (collect_p))
  	stats.read_hits++;
!       line.extract (line_offset (line, addr), data);
      }
    else
      {
        // miss!
        if (acache.vacancy_p (addr))
  	{
! 	  cache_line expelled_line (line_size);
! 	  cache_line new_line (line_size, acache.addr_to_tag (addr));
! 
! 	  if ((read_status = read_line (new_line)) != bus::ok)
! 	    return read_status;
! 	  new_line.extract (line_offset (new_line, addr), data);
! 	  acache.replace (expelled_line, new_line);
! 
! 	  if (collect_p)
  	    stats.replacements++;
  	  
! 	  if (expelled_line.dirty_p ())
  	    {
  	      // flush a dirty line being replaced
! 	      if ((st = write_line (expelled_line)) != bus::ok)
  		  return st;
  	    }
  	}
        else
  	{
--- 286,319 ----
        return st;
      }
  
!   cache_tag tag = acache.addr_to_tag (addr);
!   cache_line* line = acache.find (tag);
!   if (LIKELY (line))
      {
        if (LIKELY (collect_p))
  	stats.read_hits++;
!       line->extract (line_offset (*line, addr), data);
      }
    else
      {
        // miss!
        if (acache.vacancy_p (addr))
  	{
! 	  if (LIKELY (collect_p))
  	    stats.replacements++;
  	  
! 	  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)
  		  return st;
  	    }
+ 	  expelled_line->set_tag (tag);
+ 	  if ((read_status = read_line (*expelled_line)) != bus::ok)
+ 	    return read_status;
+ 	  expelled_line->extract (line_offset (*expelled_line, addr), data);
  	}
        else
  	{
*************** cache_component::read_any (host_int_4 ad
*** 322,328 ****
      }
  
    st = bus::ok;
!   if (hit)
      st.latency += hit_latency;
    else
      st.latency = read_status.latency + miss_latency;
--- 324,330 ----
      }
  
    st = bus::ok;
!   if (line)
      st.latency += hit_latency;
    else
      st.latency = read_status.latency + miss_latency;
*************** cache_component::flush_all_lines (host_i
*** 391,400 ****
  void
  cache_component::flush_line (host_int_4 addr)
  {
!   bool hit;
!   cache_line& line = acache.find (acache.addr_to_tag (addr), hit);
!   if (hit && line.dirty_p ())
!     (void) write_line (line);
  }
  
  void
--- 393,401 ----
  void
  cache_component::flush_line (host_int_4 addr)
  {
!   cache_line* line = acache.find (acache.addr_to_tag (addr));
!   if (line && line->dirty_p ())
!     (void) write_line (*line);
  }
  
  void
*************** cache_component::invalidate_all_lines (h
*** 439,459 ****
  void
  cache_component::invalidate_line (host_int_4 addr)
  {
!   bool hit;
!   cache_line& line = acache.find (acache.addr_to_tag (addr), hit);
!   if (hit)
!     line.invalidate ();
  }
  
  void
  cache_component::flush_and_invalidate_line (host_int_4 addr)
  {
!   bool hit;
!   cache_line& line = acache.find (acache.addr_to_tag (addr), hit);
!   if (hit && line.dirty_p ())
      {
!       (void) write_line (line);
!       line.invalidate ();
      }
  }
  
--- 440,458 ----
  void
  cache_component::invalidate_line (host_int_4 addr)
  {
!   cache_line* line = acache.find (acache.addr_to_tag (addr));
!   if (line)
!     line->invalidate ();
  }
  
  void
  cache_component::flush_and_invalidate_line (host_int_4 addr)
  {
!   cache_line* line = acache.find (acache.addr_to_tag (addr));
!   if (line && line->dirty_p ())
      {
!       (void) write_line (*line);
!       line->invalidate ();
      }
  }
  
*************** cache_component::prefetch_line (host_int
*** 473,491 ****
  void
  cache_component::lock_line (host_int_4 addr)
  {
!   bool hit;
!   cache_line& line = acache.find (acache.addr_to_tag (addr), hit);
!   if (hit)
!     line.lock ();
  }
  
  void
  cache_component::unlock_line (host_int_4 addr)
  {
!   bool hit;
!   cache_line& line = acache.find (acache.addr_to_tag (addr), hit);
!   if (hit)
!     line.unlock ();
  }
  
  void
--- 472,488 ----
  void
  cache_component::lock_line (host_int_4 addr)
  {
!   cache_line* line = acache.find (acache.addr_to_tag (addr));
!   if (line)
!     line->lock ();
  }
  
  void
  cache_component::unlock_line (host_int_4 addr)
  {
!   cache_line* line = acache.find (acache.addr_to_tag (addr));
!   if (line)
!     line->unlock ();
  }
  
  void
*************** cache_component::write_hit_rate ()
*** 602,609 ****
      }
  }
  
! void
! cache_replacement_fifo::replace (cache_set& cset, cache_line& old_line, cache_line new_line)
  {
    // If this is the first time through, expand fifo accordingly.
    if (fifo.size () != cset.num_lines ())
--- 599,606 ----
      }
  }
  
! cache_line *
! cache_replacement_fifo::expell (cache_set& cset)
  {
    // If this is the first time through, expand fifo accordingly.
    if (fifo.size () != cset.num_lines ())
*************** cache_replacement_fifo::replace (cache_s
*** 628,647 ****
  	}
        else 
  	{
- 	  old_line = line;
- 	  old_line.invalidate ();
- 	  cset.set_line (i, new_line);
- 
  	  // update state
  	  fifo[i] = 0;
! 	  return;
  	}
        n--;
      }
  }
  
! void
! cache_replacement_lru::replace (cache_set& cset, cache_line& old_line, cache_line new_line)
  {
    unsigned oldest = 0;
    int index = -1;
--- 625,642 ----
  	}
        else 
  	{
  	  // update state
  	  fifo[i] = 0;
! 	  return &line;
  	}
        n--;
      }
+ 
+   return 0;
  }
  
! cache_line *
! cache_replacement_lru::expell (cache_set& cset)
  {
    unsigned oldest = 0;
    int index = -1;
*************** cache_replacement_lru::replace (cache_se
*** 663,674 ****
      }
  
    if (index < 0)
!     return;
!   
!   old_line = cset.get_line (index);
!   old_line.invalidate ();
!   cset.set_line (index, new_line);
    lru[index] = 0;
  }
  
  void
--- 658,667 ----
      }
  
    if (index < 0)
!     return 0;
! 
    lru[index] = 0;
+   return &cset.get_line (index);
  }
  
  void
*************** cache_replacement_lru::update (cache_set
*** 684,714 ****
      }
  }
  
! void
! cache_replacement_null::replace (cache_set& cset, cache_line& old_line, cache_line new_line)
  {
    cache_line& line = cset.get_line (0);
    if (!line.locked_p ())
!     {
!       old_line = line;
!       old_line.invalidate ();
!       cset.set_line (0, new_line);
!     }
  }
  
! void
! cache_replacement_random::replace (cache_set& cset, cache_line& old_line, cache_line new_line)
  {
    for (unsigned i = 0; i < cset.num_lines (); i++)
      {
        cache_line& line = cset.get_line (i);
        if (!line.valid_p ())
! 	{
! 	  old_line = line;
! 	  old_line.invalidate ();
! 	  cset.set_line (i, new_line);
! 	  return;
! 	}
      }
  
    unsigned n = cset.num_lines ();
--- 677,700 ----
      }
  }
  
! cache_line *
! cache_replacement_null::expell (cache_set& cset)
  {
    cache_line& line = cset.get_line (0);
    if (!line.locked_p ())
!     return &line;
! 
!   return 0;
  }
  
! cache_line *
! cache_replacement_random::expell (cache_set& cset)
  {
    for (unsigned i = 0; i < cset.num_lines (); i++)
      {
        cache_line& line = cset.get_line (i);
        if (!line.valid_p ())
! 	return &line;
      }
  
    unsigned n = cset.num_lines ();
*************** cache_replacement_random::replace (cache
*** 723,740 ****
  
        cache_line& line = cset.get_line (i);
        if (!line.locked_p ())
! 	{
! 	  old_line = line;
! 	  old_line.invalidate ();
! 	  cset.set_line (i, new_line);
! 	  return;
! 	}
!       else
! 	{
! 	  candidates[i] = false;
! 	  n--;
! 	}
      }
  }
  
  
--- 709,721 ----
  
        cache_line& line = cset.get_line (i);
        if (!line.locked_p ())
! 	return &line;
! 
!       candidates[i] = false;
!       n--;
      }
+ 
+   return 0;
  }
  
  
*************** CacheCreate (const string& typeName)
*** 782,791 ****
    bool match;
  
    if (typeName == "hw-cache-basic")
!     return new cache_component (1, 16384, 32, null_replacement);
  
    if (typeName == "hw-cache-buffer-8")
!     return new cache_component (0, 8, 8, null_replacement);
    
    vector<string> parts = sidutil::tokenize (typeName, "-/");
  
--- 763,772 ----
    bool match;
  
    if (typeName == "hw-cache-basic")
!     return new cache_component (1, 16384, 32, null_replacement, internal_line_factory);
  
    if (typeName == "hw-cache-buffer-8")
!     return new cache_component (0, 8, 8, null_replacement, internal_line_factory);
    
    vector<string> parts = sidutil::tokenize (typeName, "-/");
  
*************** CacheCreate (const string& typeName)
*** 856,869 ****
      }
  
    if (assoc == 1)
!     return new cache_component (assoc, cache_sz, line_sz, null_replacement);
    
    if (replace_alg_string == "lru")
!     return new cache_component (assoc, cache_sz, line_sz, lru_replacement);
    else if (replace_alg_string == "fifo")
!     return new cache_component (assoc, cache_sz, line_sz, fifo_replacement);
    else if (replace_alg_string == "random")
!     return new cache_component (assoc, cache_sz, line_sz, random_replacement);
  
    return 0;
  }
--- 837,850 ----
      }
  
    if (assoc == 1)
!     return new cache_component (assoc, cache_sz, line_sz, null_replacement, internal_line_factory);
    
    if (replace_alg_string == "lru")
!     return new cache_component (assoc, cache_sz, line_sz, lru_replacement, internal_line_factory);
    else if (replace_alg_string == "fifo")
!     return new cache_component (assoc, cache_sz, line_sz, fifo_replacement, internal_line_factory);
    else if (replace_alg_string == "random")
!     return new cache_component (assoc, cache_sz, line_sz, random_replacement, internal_line_factory);
  
    return 0;
  }
Index: sid/component/cache/cache.h
===================================================================
RCS file: /cvs/src/src/sid/component/cache/cache.h,v
retrieving revision 1.9
diff -c -p -r1.9 cache.h
*** sid/component/cache/cache.h	8 Jan 2003 02:51:57 -0000	1.9
--- sid/component/cache/cache.h	27 Apr 2004 20:20:26 -0000
***************
*** 1,6 ****
  // cache.h -- A universal memory cache. -*- C++ -*-
  
! // Copyright (C) 2001, 2002 Red Hat.
  // This file is part of SID and is licensed under the GPL.
  // See the file COPYING.SID for conditions for redistribution.
  
--- 1,6 ----
  // cache.h -- A universal memory cache. -*- C++ -*-
  
! // Copyright (C) 2001, 2002, 2004 Red Hat.
  // This file is part of SID and is licensed under the GPL.
  // See the file COPYING.SID for conditions for redistribution.
  
*************** private:
*** 62,68 ****
  class cache_replacement_fifo: public cache_replacement_algorithm
  {
  public:
!   void replace (cache_set& cset, cache_line& old_line, cache_line new_line);
  
  private:
    vector <int> fifo;
--- 62,68 ----
  class cache_replacement_fifo: public cache_replacement_algorithm
  {
  public:
!   cache_line *expell (cache_set& set);
  
  private:
    vector <int> fifo;
*************** private:
*** 73,79 ****
  class cache_replacement_lru: public cache_replacement_algorithm
  {
  public:
!   void replace (cache_set& cset, cache_line& old_line, cache_line new_line);
    void update (cache_set& cset, cache_line& selected);
  
  private:
--- 73,79 ----
  class cache_replacement_lru: public cache_replacement_algorithm
  {
  public:
!   cache_line *expell (cache_set& set);
    void update (cache_set& cset, cache_line& selected);
  
  private:
*************** private:
*** 85,91 ****
  class cache_replacement_random: public cache_replacement_algorithm
  {
  public:
!   void replace (cache_set& cset, cache_line& old_line, cache_line new_line);
  };
  
  // Null replacement algorithm; used by direct mapped caches
--- 85,91 ----
  class cache_replacement_random: public cache_replacement_algorithm
  {
  public:
!   cache_line *expell (cache_set& set);
  };
  
  // Null replacement algorithm; used by direct mapped caches
*************** public:
*** 93,99 ****
  class cache_replacement_null: public cache_replacement_algorithm
  {
  public:
!   void replace (cache_set& cset, cache_line& old_line, cache_line new_line);
  };
  
  
--- 93,99 ----
  class cache_replacement_null: public cache_replacement_algorithm
  {
  public:
!   cache_line *expell (cache_set& set);
  };
  
  
*************** class cache_component: public virtual co
*** 106,114 ****
  {
  public:
    cache_component (unsigned asoctvty, unsigned cache_sz,
! 		   unsigned line_sz, cache_replacement_algorithm& replacer);
  
!   ~cache_component () throw();
  
    template <typename DataType> bus::status 
    write_any (host_int_4 addr, DataType data);
--- 106,115 ----
  {
  public:
    cache_component (unsigned asoctvty, unsigned cache_sz,
! 		   unsigned line_sz, cache_replacement_algorithm& replacer,
! 		   cache_line_factory &line_factory);
  
!   virtual ~cache_component () throw();
  
    template <typename DataType> bus::status 
    write_any (host_int_4 addr, DataType data);
*************** public:
*** 116,122 ****
    template <typename DataType> bus::status
    read_any (host_int_4 addr, DataType& data);
  
! private:
    cache acache;
  
    cache_bus upstream;
--- 117,123 ----
    template <typename DataType> bus::status
    read_any (host_int_4 addr, DataType& data);
  
! protected:
    cache acache;
  
    cache_bus upstream;
*************** private:
*** 193,198 ****
--- 194,200 ----
      unsigned long replacements;
    } stats;
  
+   cache_line_factory &line_factory;
    unsigned line_size;
    unsigned cache_size;
    unsigned assoc;
Index: sid/component/cache/cacheutil.cxx
===================================================================
RCS file: /cvs/src/src/sid/component/cache/cacheutil.cxx,v
retrieving revision 1.7
diff -c -p -r1.7 cacheutil.cxx
*** sid/component/cache/cacheutil.cxx	8 Jun 2002 20:33:18 -0000	1.7
--- sid/component/cache/cacheutil.cxx	27 Apr 2004 20:20:26 -0000
***************
*** 1,6 ****
  // cacheutil.cxx -- Helper classes for a generic memory cache. -*- C++ -*-
  
! // Copyright (C) 2001, 2002 Red Hat.
  // This file is part of SID and is licensed under the GPL.
  // See the file COPYING.SID for conditions for redistribution.
  
--- 1,6 ----
  // cacheutil.cxx -- Helper classes for a generic memory cache. -*- C++ -*-
  
! // Copyright (C) 2001, 2002, 2004 Red Hat.
  // This file is part of SID and is licensed under the GPL.
  // See the file COPYING.SID for conditions for redistribution.
  
*************** operator== (const cache_line& line, cons
*** 18,52 ****
    return (line.valid_p () && tag == line.tag ());
  }
  
- cache_line::cache_line (const cache_line& other)
- {
-   size = other.size;
-   valid_bit = other.valid_bit;
-   dirty_bit = other.dirty_bit;
-   lock_bit = other.lock_bit;
-   atag = other.atag;
-   data = new byte [size];
-   memcpy (data, other.data, size);
- }
- 
- cache_line&
- cache_line::operator= (const cache_line& other)
- {
-   if (this != &other)
-     {
-       // Beware of self-assignment.
-       size = other.size;
-       valid_bit = other.valid_bit;
-       dirty_bit = other.dirty_bit;
-       lock_bit = other.lock_bit;
-       atag = other.atag;
-       delete [] data;
-       data = new byte [size];
-       memcpy (data, other.data, size);
-     }
-   return *this;
- }
- 
  using std::cerr;
  using std::hex;
  using std::setw;
--- 18,23 ----
*************** cache_line::dump () const
*** 63,175 ****
    if (valid_p ())  cerr << 'V'; else cerr << '-';
    if (locked_p ()) cerr << 'L'; else cerr << '-';
  
!   cerr << "  " << hex << setw (4) << setfill ('0') << atag << "\t";
!   for (unsigned i = 0; i < size; i++)
!     cerr << setw (2) << setfill ('0') << static_cast<unsigned> (data[i]);
! 
    cerr << dec << endl;
  }
  
! cache_line::cache_line (unsigned line_size)
!   :size (line_size), valid_bit (false), dirty_bit (false), lock_bit (false), atag (0)
  {
!   data = new byte [line_size];
!   memset (data, 0, line_size);
  }
  
! cache_line::cache_line (unsigned line_size, cache_tag t)
!   :size (line_size), valid_bit (false), dirty_bit (false), lock_bit (false), atag (t)
  {
    data = new byte [line_size];
    memset (data, 0, line_size);
  }
  
! cache_line::cache_line (unsigned line_size, cache_tag t, std::vector <byte> initial_data)
!   :size (line_size), valid_bit (false), dirty_bit (false), lock_bit (false), atag (t)
! {
!   assert (initial_data.size () == line_size);
!   data = new byte [line_size];
!   for (unsigned i = 0; i < line_size; i++)
!     data[i] = initial_data[i];
! }
! 
! cache_line::~cache_line ()
  {
    delete [] data;
  }
  
  void
! cache_line::dirty ()
  {
    dirty_bit = true;
  }
  
  void
! cache_line::clean ()
  {
    dirty_bit = false;
  }
  
  void
! cache_line::validate ()
  {
    valid_bit = true;
  }
  
  void
! cache_line::invalidate ()
  {
    valid_bit = false;
  }
  
  void
! cache_line::lock ()
  {
    lock_bit = true;
  }
  
  void
! cache_line::unlock ()
  {
    lock_bit = false;
  }
  
  cache_tag
! cache_line::tag () const
  {
    return atag;
  }
  
  bool
! cache_line::dirty_p () const
  {
    return dirty_bit;
  }
  
  bool
! cache_line::valid_p () const
  {
    return valid_bit;
  }
  
  bool
! cache_line::locked_p () const
  {
    return lock_bit;
  }
  
! cache_set::cache_set (unsigned line_size, unsigned nlines, cache_replacement_algorithm& alg)
!   :replacer (alg)
  {
    lines.resize (nlines);
    for (iterator_t it = lines.begin(); it != lines.end (); it++)
!     *it = new cache_line (line_size);
  }
  
  cache_set::~cache_set ()
  {
    for (iterator_t it = lines.begin (); it != lines.end (); it++)
!     delete *it;
  }
  
  unsigned
--- 34,151 ----
    if (valid_p ())  cerr << 'V'; else cerr << '-';
    if (locked_p ()) cerr << 'L'; else cerr << '-';
  
!   cerr << "  " << hex << setw (4) << setfill ('0') << tag () << "\t";
!   dump_data ();
    cerr << dec << endl;
  }
  
! void
! internal_cache_line::dump_data () const
  {
!   for (unsigned i = 0; i < size; i++)
!     cerr << setw (2) << setfill ('0') << static_cast<unsigned> (data[i]);
  }
  
! internal_cache_line::internal_cache_line (unsigned line_size)
!   :size (line_size), valid_bit (false), dirty_bit (false), lock_bit (false), atag (0)
  {
    data = new byte [line_size];
    memset (data, 0, line_size);
  }
  
! internal_cache_line::~internal_cache_line ()
  {
    delete [] data;
  }
  
  void
! internal_cache_line::dirty ()
  {
    dirty_bit = true;
  }
  
  void
! internal_cache_line::clean ()
  {
    dirty_bit = false;
  }
  
  void
! internal_cache_line::validate ()
  {
    valid_bit = true;
  }
  
  void
! internal_cache_line::invalidate ()
  {
    valid_bit = false;
  }
  
  void
! internal_cache_line::lock ()
  {
    lock_bit = true;
  }
  
  void
! internal_cache_line::unlock ()
  {
    lock_bit = false;
  }
  
+ void
+ internal_cache_line::set_tag (cache_tag tag)
+ {
+   atag = tag;
+ }
+ 
  cache_tag
! internal_cache_line::tag () const
  {
    return atag;
  }
  
  bool
! internal_cache_line::dirty_p () const
  {
    return dirty_bit;
  }
  
  bool
! internal_cache_line::valid_p () const
  {
    return valid_bit;
  }
  
  bool
! internal_cache_line::locked_p () const
  {
    return lock_bit;
  }
  
! cache_set::cache_set (unsigned line_sz, unsigned nlines, cache_replacement_algorithm& alg, cache_line_factory &f)
!   :replacer (alg),
!    line_factory (f),
!    line_size (line_sz)
  {
    lines.resize (nlines);
    for (iterator_t it = lines.begin(); it != lines.end (); it++)
!     *it = NULL;
  }
  
  cache_set::~cache_set ()
  {
    for (iterator_t it = lines.begin (); it != lines.end (); it++)
!     line_factory.destroy_line (*it);
! }
! 
! void
! cache_set::allocate_lines (unsigned index)
! {
!   unsigned way = 0;
!   for (iterator_t it = lines.begin(); it != lines.end (); way++, it++)
!     *it = line_factory.make_line (line_size, index, way);
  }
  
  unsigned
*************** cache_set::get_line (unsigned i) const
*** 185,212 ****
  }
  
  void
! cache_set::set_line (unsigned i, const cache_line line)
  {
!   *lines[i] = line;
  }
  
! cache_line&
! cache_set::find (const cache_tag& tag, bool& hit)
  {
-   static cache_line dummy(0);
- 
    // Scan the lines in this set for tag. Might as well be linear; the
    // order of associativity will be small.
  
    for (const_iterator_t it = lines.begin (); it != lines.end (); it++)
      if (tag == *(*it))
        {
- 	hit = true;
  	replacer.update (*this, *(*it));
! 	return *(*it);
        }
!   hit = false;
!   return dummy;
  }
  
  
--- 161,185 ----
  }
  
  void
! cache_set::set_line (unsigned i, cache_line &line)
  {
!   lines[i] = &line;
  }
  
! cache_line*
! cache_set::find (const cache_tag& tag)
  {
    // Scan the lines in this set for tag. Might as well be linear; the
    // 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;
        }
! 
!   return NULL;
  }
  
  
*************** cache_set::expunge_line (cache_line& lin
*** 247,256 ****
    line.invalidate ();
  }
  
! void
! cache_set::replace_line (cache_line& old_line, cache_line new_line)
  {
!   return replacer.replace (*this, old_line, new_line);
  }
  
  void
--- 220,232 ----
    line.invalidate ();
  }
  
! cache_line *
! cache_set::expell_line ()
  {
!   cache_line *line = replacer.expell (*this);
!   if (line)
!     replacer.update (*this, *line);
!   return line;
  }
  
  void
*************** cache_set::dump () const
*** 261,267 ****
  }
  
  cache::cache (unsigned cache_size, unsigned line_size, unsigned assoc,
! 	      cache_replacement_algorithm& replacer)
  {
    assert (power_of_two_p (line_size));
    assert (cache_size >= line_size);
--- 237,244 ----
  }
  
  cache::cache (unsigned cache_size, unsigned line_size, unsigned assoc,
! 	      cache_replacement_algorithm& replacer,
! 	      cache_line_factory& line_factory)
  {
    assert (power_of_two_p (line_size));
    assert (cache_size >= line_size);
*************** cache::cache (unsigned cache_size, unsig
*** 284,290 ****
    int lines_per_set = (assoc == 0) ? num_lines : assoc;
   
    for (iterator_t it = sets.begin (); it != sets.end (); it++)
!     *it = new cache_set (line_size, lines_per_set, replacer);
    
    num_non_tag_bits = log2 (line_size);
  
--- 261,267 ----
    int lines_per_set = (assoc == 0) ? num_lines : assoc;
   
    for (iterator_t it = sets.begin (); it != sets.end (); it++)
!     *it = new cache_set (line_size, lines_per_set, replacer, line_factory);
    
    num_non_tag_bits = log2 (line_size);
  
*************** cache::~cache ()
*** 300,305 ****
--- 277,290 ----
      delete sets[i];
  }
  
+ void
+ cache::init ()
+ {
+   unsigned index = 0;
+   for (iterator_t it = sets.begin (); it != sets.end (); it++, index++)
+     (*it)->allocate_lines (index);
+ }
+   
  cache_tag
  cache::addr_to_tag (const sid::host_int_4& addr) const
  {
*************** cache::tag_to_addr (const cache_tag& tag
*** 312,322 ****
    return tag << num_non_tag_bits;
  }
  
! cache_line&
! cache::find (cache_tag tag, bool& hit)
  {
    unsigned index = hash_fn (tag);
!   return sets[index]->find (tag, hit);
  }
  
  cache_line*
--- 297,307 ----
    return tag << num_non_tag_bits;
  }
  
! cache_line*
! cache::find (cache_tag tag)
  {
    unsigned index = hash_fn (tag);
!   return sets[index]->find (tag);
  }
  
  cache_line*
*************** cache::expunge (cache_line& line)
*** 370,380 ****
  // Replace a line in the cache with 'new_line'.  If the expelled
  // line is dirty, set 'old_line' to it and return true, otherwise
  // false.
! void
! cache::replace (cache_line& old_line, cache_line new_line)
  {
!   unsigned index = hash_fn (new_line.tag ());
!   return sets[index]->replace_line (old_line, new_line);
  }
  
  unsigned
--- 355,365 ----
  // Replace a line in the cache with 'new_line'.  If the expelled
  // line is dirty, set 'old_line' to it and return true, otherwise
  // false.
! cache_line *
! cache::expell_line (cache_tag tag)
  {
!   unsigned index = hash_fn (tag);
!   return sets[index]->expell_line ();
  }
  
  unsigned
Index: sid/component/cache/cacheutil.h
===================================================================
RCS file: /cvs/src/src/sid/component/cache/cacheutil.h,v
retrieving revision 1.6
diff -c -p -r1.6 cacheutil.h
*** sid/component/cache/cacheutil.h	8 Jun 2002 20:33:18 -0000	1.6
--- sid/component/cache/cacheutil.h	27 Apr 2004 20:20:26 -0000
***************
*** 1,6 ****
  // cacheutil.h -- Helper classes for a generic memory cache. -*- C++ -*-
  
! // Copyright (C) 2001, 2002 Red Hat.
  // This file is part of SID and is licensed under the GPL.
  // See the file COPYING.SID for conditions for redistribution.
  
--- 1,6 ----
  // cacheutil.h -- Helper classes for a generic memory cache. -*- C++ -*-
  
! // Copyright (C) 2001, 2002, 2004 Red Hat.
  // This file is part of SID and is licensed under the GPL.
  // See the file COPYING.SID for conditions for redistribution.
  
***************
*** 17,40 ****
  typedef sid::host_int_4 cache_tag;
  typedef sid::host_int_1 byte;
  
! // The cache_line class represents a line in a cache:
  
  // +-------+-----+----------------+ M = modified (dirty) bit
  // | M V L | tag |     data       | V = valid bit
  // +-------+-----+----------------+ L = lock bit
  //           byte 0              N
  
! class cache_line
  {
  public:
!   cache_line (unsigned line_size);
!   cache_line (unsigned line_size, cache_tag tag);
!   cache_line (unsigned line_size, cache_tag tag, std::vector <byte> intial_data);
!   cache_line (const cache_line&);
!   cache_line& operator= (const cache_line&);
!   virtual ~cache_line ();
  
    // Get the line's tag.
    cache_tag tag () const;
  
    // Mark the line dirty or clean.
--- 17,91 ----
  typedef sid::host_int_4 cache_tag;
  typedef sid::host_int_1 byte;
  
! // The cache_line class represents a line in a cache. It is a virtual base
! // class which requires an implementation.
! 
! class cache_line
! {
! public:
!   virtual ~cache_line () {}
! 
!   // Get the line's tag.
!   virtual void set_tag (cache_tag tag) = 0;
!   virtual cache_tag tag () const = 0;
! 
!   // Mark the line dirty or clean.
!   virtual void dirty () = 0;
!   virtual void clean () = 0;
! 
!   // Mark the line valid or invalid.
!   virtual void validate () = 0;
!   virtual void invalidate () = 0;
! 
!   // Lock or unlock the line.
!   virtual void lock () = 0;
!   virtual void unlock () = 0;
! 
!   // Is the line dirty?
!   virtual bool dirty_p () const = 0;
! 
!   // Is the line valid?
!   virtual bool valid_p () const = 0;
! 
!   // Is the line locked?
!   virtual bool locked_p () const = 0;
! 
!   // Insert or extract a datum from the line, starting at byte offset.
! #define DEFN_METHOD(DataType) \
!   virtual void insert (unsigned offset, DataType new_data) = 0; \
!   virtual void extract (unsigned offset, DataType& new_data) const = 0;
! 
!   DEFN_METHOD (sid::big_int_1)
!   DEFN_METHOD (sid::big_int_2)
!   DEFN_METHOD (sid::big_int_4)
!   DEFN_METHOD (sid::big_int_8)
!   DEFN_METHOD (sid::little_int_1)
!   DEFN_METHOD (sid::little_int_2)
!   DEFN_METHOD (sid::little_int_4)
!   DEFN_METHOD (sid::little_int_8)
! #undef DEFN_METHOD
! 
!   // Dump a line in human readable form to cout.
!   virtual void dump () const;
!   virtual void dump_data () const = 0;
! };
! 
! // The internal_cache_line class keeps its data internally and is the default
! // cache_line implementation.
  
  // +-------+-----+----------------+ M = modified (dirty) bit
  // | M V L | tag |     data       | V = valid bit
  // +-------+-----+----------------+ L = lock bit
  //           byte 0              N
  
! class internal_cache_line : public cache_line
  {
  public:
!   internal_cache_line (unsigned line_size);
!   ~internal_cache_line ();
  
    // Get the line's tag.
+   void set_tag (cache_tag tag);
    cache_tag tag () const;
  
    // Mark the line dirty or clean.
*************** public:
*** 58,85 ****
    // Is the line locked?
    bool locked_p () const;
  
!   // Insert a datum into the line, starting at byte offset.
!   template <typename DataType>
!   void insert (unsigned offset, DataType new_data)
!   {
!     assert (offset + sizeof (new_data) <= size);
!     typename DataType::value_type mem_image = new_data.target_memory_value ();
!     memcpy (& data[offset], & mem_image, sizeof (new_data));
!     dirty_bit = true;
    }
  
!   // Extract a datum from the line, starting at byte offset.
!   template <typename DataType>
!   void extract (unsigned offset, DataType& new_data) const
!   {
!     assert (offset + sizeof (new_data) <= size);
!     typename DataType::value_type mem_image;
!     memcpy (& mem_image, & data[offset], sizeof (new_data));
!     new_data.set_target_memory_value (mem_image);
!   }
  
    // Dump a line in human readable form to cout.
!   void dump () const;
  
  private:
    unsigned size;
--- 109,144 ----
    // Is the line locked?
    bool locked_p () const;
  
! #define DEFN_METHOD(DataType) \
!   /* Insert a datum into the line, starting at byte offset.  */ \
!   virtual void insert (unsigned offset, DataType new_data) \
!   { \
!     assert (offset + sizeof (new_data) <= size); \
!     DataType::value_type mem_image = new_data.target_memory_value (); \
!     memcpy (& data[offset], & mem_image, sizeof (new_data)); \
!     dirty_bit = true; \
!   } \
!   /* Extract a datum from the line, starting at byte offset.  */ \
!   virtual void extract (unsigned offset, DataType& new_data) const \
!   { \
!     assert (offset + sizeof (new_data) <= size); \
!     DataType::value_type mem_image; \
!     memcpy (& mem_image, & data[offset], sizeof (new_data)); \
!     new_data.set_target_memory_value (mem_image); \
    }
  
!   DEFN_METHOD (sid::big_int_1)
!   DEFN_METHOD (sid::big_int_2)
!   DEFN_METHOD (sid::big_int_4)
!   DEFN_METHOD (sid::big_int_8)
!   DEFN_METHOD (sid::little_int_1)
!   DEFN_METHOD (sid::little_int_2)
!   DEFN_METHOD (sid::little_int_4)
!   DEFN_METHOD (sid::little_int_8)
! #undef DEFN_METHOD
  
    // Dump a line in human readable form to cout.
!   void dump_data () const;
  
  private:
    unsigned size;
*************** class cache_replacement_algorithm
*** 102,115 ****
  public:
    virtual ~cache_replacement_algorithm () {}
  
!   // Place new_line in a cache slot. Point old_line to the existing line.
!   // Return true if successful, false otherwise.
!   virtual void replace (cache_set& cset, cache_line& old_line, cache_line new_line) = 0;
  
    // Update state (for example, treating LRU bits), if required.
!   virtual void update (cache_set& cset, cache_line& accessed_line) {}
  };
  
  
  // The cache_set class represents a set of cache_lines.  For a 2-way
  // associative cache, there will be just two lines in the set.
--- 161,190 ----
  public:
    virtual ~cache_replacement_algorithm () {}
  
!   // Choose a line to replace in a cache set. Return it, if successful
!   virtual cache_line *expell (cache_set &set) = 0;
  
    // Update state (for example, treating LRU bits), if required.
!   virtual void update (cache_set& cset, cache_line &accessed_line) {}
  };
  
+ // The cache_line_factory creates and destroys cache lines. This default
+ // implementation creates lines of type internal_cache_line.
+ 
+ class cache_line_factory
+ {
+ public:
+   virtual ~cache_line_factory () {}
+ 
+   virtual cache_line *make_line (unsigned line_size, unsigned index, unsigned way)
+   {
+     return new internal_cache_line (line_size);
+   }
+   virtual void destroy_line (cache_line *line)
+   {
+     delete line;
+   }
+ };
  
  // The cache_set class represents a set of cache_lines.  For a 2-way
  // associative cache, there will be just two lines in the set.
*************** class cache_set
*** 118,133 ****
  {
  public:
    cache_set (unsigned line_size, unsigned nlines,
! 	     cache_replacement_algorithm& alg);
    virtual ~cache_set ();
!  
    // Try to find a line in the cache with a matching tag. 
!   // If found, set "hit" to true and return a ref to the line.
!   // Otherwise, set "hit" to false.
!   virtual cache_line& find (const cache_tag& tag, bool& hit);
  
!   // Find any dirty cache line.  If found, set hit to true and return it.
!   // Otherwise, set hit to false.
    virtual cache_line* find_any_dirty ();
  
    // Invalidate the entire set.
--- 193,208 ----
  {
  public:
    cache_set (unsigned line_size, unsigned nlines,
! 	     cache_replacement_algorithm& alg, cache_line_factory &f);
    virtual ~cache_set ();
! 
!   void allocate_lines (unsigned index);
! 
    // Try to find a line in the cache with a matching tag. 
!   // If found, return it.
!   virtual cache_line* find (const cache_tag& tag);
  
!   // Find any dirty cache line.  If found, return the line
    virtual cache_line* find_any_dirty ();
  
    // Invalidate the entire set.
*************** public:
*** 142,150 ****
    // Flush the entire set.
    void expunge (unsigned index);
  
!   // Replace a line in the set with new_line.
!   // Return false if the line cannot be placed, true otherwise.
!   void replace_line (cache_line& old_line, cache_line new_line);
  
    // Return the number of lines in the set.
    unsigned num_lines () const;
--- 217,224 ----
    // Flush the entire set.
    void expunge (unsigned index);
  
!   // Choose a line to be replaced. Return it, if successful.
!   cache_line *expell_line ();
  
    // Return the number of lines in the set.
    unsigned num_lines () const;
*************** public:
*** 153,159 ****
    cache_line& get_line (unsigned i) const;
  
    // Place a cache line into slot `i' of the set.
!   void set_line (unsigned i, const cache_line line);
  
    // Dump diagnostics to cerr.
    virtual void dump () const;
--- 227,233 ----
    cache_line& get_line (unsigned i) const;
  
    // Place a cache line into slot `i' of the set.
!   void set_line (unsigned i, cache_line &line);
  
    // Dump diagnostics to cerr.
    virtual void dump () const;
*************** public:
*** 166,172 ****
--- 240,248 ----
  
  private:
    cache_replacement_algorithm& replacer;
+   cache_line_factory& line_factory;
    std::vector <cache_line*> lines;
+   unsigned line_size;
    typedef std::vector <cache_line*>::iterator iterator_t;
    typedef std::vector <cache_line*>::const_iterator const_iterator_t;
  };
*************** class cache
*** 185,202 ****
  {
  public:
    cache (unsigned cache_size, unsigned line_size,
! 	 unsigned assoc, cache_replacement_algorithm& replacer);
    virtual ~cache ();
  
    // Calculate a tag.
    cache_tag addr_to_tag (const sid::host_int_4& addr) const;
  
    // Perform the inverse operation.
    sid::host_int_4 tag_to_addr (const cache_tag& tag) const;
    
!   // Find a line, given a tag.  If found, set hit to true and return it.
!   // Otherwise, set hit to false.
!   cache_line& find (cache_tag tag, bool& hit);
  
    // Find any dirty cache line.  If found, set hit to true and return it.
    // Otherwise, set hit to false.
--- 261,280 ----
  {
  public:
    cache (unsigned cache_size, unsigned line_size,
! 	 unsigned assoc, cache_replacement_algorithm& replacer,
! 	 cache_line_factory &line_factory);
    virtual ~cache ();
  
+   void init ();
+ 
    // Calculate a tag.
    cache_tag addr_to_tag (const sid::host_int_4& addr) const;
  
    // Perform the inverse operation.
    sid::host_int_4 tag_to_addr (const cache_tag& tag) const;
    
!   // Find a line, given a tag.  If found, return it.
!   cache_line* find (cache_tag tag);
  
    // Find any dirty cache line.  If found, set hit to true and return it.
    // Otherwise, set hit to false.
*************** public:
*** 208,217 ****
    // Vacancy in the cache?
    bool vacancy_p (const sid::host_int_4& addr) const;
  
!   // Replace a line in the cache with 'new_line'.  If the expelled
!   // line is dirty, set 'old_line' to it and return true, otherwise
!   // false.
!   void replace (cache_line& old_line, cache_line new_line);
  
    // Invalidate the entire cache.
    void invalidate ();
--- 286,294 ----
    // Vacancy in the cache?
    bool vacancy_p (const sid::host_int_4& addr) const;
  
!   // Choose a line in the cache to expell in place of one
!   // representing 'tag'. Return it, if successful.
!   cache_line *expell_line (cache_tag tag);
  
    // Invalidate the entire cache.
    void invalidate ();
Index: sid/component/cfgroot/Makefile.am
===================================================================
RCS file: /cvs/src/src/sid/component/cfgroot/Makefile.am,v
retrieving revision 1.5
diff -c -p -r1.5 Makefile.am
*** sid/component/cfgroot/Makefile.am	4 Aug 2001 11:46:29 -0000	1.5
--- sid/component/cfgroot/Makefile.am	27 Apr 2004 20:20:26 -0000
*************** INCLUDES = -I. -I../../include -I$(srcdi
*** 12,17 ****
--- 12,18 ----
  libconfig_la_SOURCES = compConfig.cxx
  libconfig_la_LDFLAGS = -module -no-undefined
  libconfig_la_LIBADD = @LIBLTDL@
+ libconfig_la_DEPENDENCIES = @LIBLTDL@
  
  pkgdata_DATA = sid-control-cfgroot.txt
  
Index: sid/component/cfgroot/compConfig.cxx
===================================================================
RCS file: /cvs/src/src/sid/component/cfgroot/compConfig.cxx,v
retrieving revision 1.8
diff -c -p -r1.8 compConfig.cxx
*** sid/component/cfgroot/compConfig.cxx	30 May 2002 15:23:59 -0000	1.8
--- sid/component/cfgroot/compConfig.cxx	27 Apr 2004 20:20:26 -0000
*************** cfgroot_component::register_dso(const st
*** 726,732 ****
    dl_handle = lt_dlopen(dso_name.c_str());
  
    // Second, try ".la"->".a" kludge.
!   if ((dso_name.length() > 3) &&
        (dso_name[dso_name.length()-3] == '.') &&
        (dso_name[dso_name.length()-2] == 'l') &&
        (dso_name[dso_name.length()-1] == 'a'))
--- 726,733 ----
    dl_handle = lt_dlopen(dso_name.c_str());
  
    // Second, try ".la"->".a" kludge.
!   if (! dl_handle &&
!       (dso_name.length() > 3) &&
        (dso_name[dso_name.length()-3] == '.') &&
        (dso_name[dso_name.length()-2] == 'l') &&
        (dso_name[dso_name.length()-1] == 'a'))
Index: sid/main/dynamic/commonCfg.h
===================================================================
RCS file: /cvs/src/src/sid/main/dynamic/commonCfg.h,v
retrieving revision 1.5
diff -c -p -r1.5 commonCfg.h
*** sid/main/dynamic/commonCfg.h	1 Apr 2004 23:35:37 -0000	1.5
--- sid/main/dynamic/commonCfg.h	27 Apr 2004 20:20:30 -0000
*************** public:
*** 63,69 ****
    sid::host_int_4 get_size () const { return my_size; }
    sid::host_int_4 get_line_size () const {return my_line_size; }
   protected:
!   void compute_comptype ();
    string my_assoc;
    sid::host_int_4 my_size;
    sid::host_int_4 my_line_size;
--- 63,69 ----
    sid::host_int_4 get_size () const { return my_size; }
    sid::host_int_4 get_line_size () const {return my_line_size; }
   protected:
!   virtual void compute_comptype ();
    string my_assoc;
    sid::host_int_4 my_size;
    sid::host_int_4 my_line_size;
*************** struct SessionCfg :
*** 209,214 ****
--- 209,215 ----
    void use_tcl_bridge();
    void use_no_stdio ();
    virtual void set_loader (LoaderCfg *l);
+   LoaderCfg *get_loader () const { return loader; }
    AtomicCfg *audio;
    AtomicCfg *tksched;
    AtomicCfg *tksm;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]