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 *** 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 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 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 fifo; --- 62,68 ---- class cache_replacement_fifo: public cache_replacement_algorithm { public: ! cache_line *expell (cache_set& set); private: vector 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 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 bus::status write_any (host_int_4 addr, DataType data); *************** public: *** 116,122 **** template bus::status read_any (host_int_4 addr, DataType& data); ! private: cache acache; cache_bus upstream; --- 117,123 ---- template 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 (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 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 (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 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 ! 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 ! 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 lines; + unsigned line_size; typedef std::vector ::iterator iterator_t; typedef std::vector ::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;