Adding gem5 source to svn.

git-svn-id: https://www4.informatik.uni-erlangen.de/i4svn/danceos/trunk/devel/fail@1819 8c4709b5-6ec9-48aa-a5cd-a96041d1645a
This commit is contained in:
friemel
2012-10-24 19:18:57 +00:00
parent f7ff71bd46
commit b41eec3f65
3222 changed files with 658579 additions and 1 deletions

View File

@ -0,0 +1,136 @@
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "mem/ruby/common/Address.hh"
#include "mem/ruby/system/System.hh"
physical_address_t
Address::getLineAddress() const
{
return bitSelect(RubySystem::getBlockSizeBits(), ADDRESS_WIDTH);
}
physical_address_t
Address::getOffset() const
{
return bitSelect(0, RubySystem::getBlockSizeBits() - 1);
}
void
Address::makeLineAddress()
{
m_address = maskLowOrderBits(RubySystem::getBlockSizeBits());
}
// returns the next stride address based on line address
void
Address::makeNextStrideAddress(int stride)
{
m_address = maskLowOrderBits(RubySystem::getBlockSizeBits())
+ RubySystem::getBlockSizeBytes()*stride;
}
integer_t
Address::memoryModuleIndex() const
{
integer_t index =
bitSelect(RubySystem::getBlockSizeBits() +
RubySystem::getMemorySizeBits(), ADDRESS_WIDTH);
assert (index >= 0);
return index;
// Index indexHighPortion =
// address.bitSelect(MEMORY_SIZE_BITS - 1,
// PAGE_SIZE_BITS + NUMBER_OF_MEMORY_MODULE_BITS);
// Index indexLowPortion =
// address.bitSelect(DATA_BLOCK_BITS, PAGE_SIZE_BITS - 1);
//
// Index index = indexLowPortion |
// (indexHighPortion << (PAGE_SIZE_BITS - DATA_BLOCK_BITS));
/*
Round-robin mapping of addresses, at page size granularity
ADDRESS_WIDTH MEMORY_SIZE_BITS PAGE_SIZE_BITS DATA_BLOCK_BITS
| | | |
\ / \ / \ / \ / 0
-----------------------------------------------------------------------
| unused |xxxxxxxxxxxxxxx| |xxxxxxxxxxxxxxx| |
| |xxxxxxxxxxxxxxx| |xxxxxxxxxxxxxxx| |
-----------------------------------------------------------------------
indexHighPortion indexLowPortion
<------->
NUMBER_OF_MEMORY_MODULE_BITS
*/
}
void
Address::print(std::ostream& out) const
{
using namespace std;
out << "[" << hex << "0x" << m_address << "," << " line 0x"
<< maskLowOrderBits(RubySystem::getBlockSizeBits()) << dec << "]"
<< flush;
}
void
Address::output(std::ostream& out) const
{
// Note: this outputs addresses in the form "ffff", not "0xffff".
// This code should always be able to write out addresses in a
// format that can be read in by the below input() method. Please
// don't change this without talking to Milo first.
out << std::hex << m_address << std::dec;
}
void
Address::input(std::istream& in)
{
// Note: this only works with addresses in the form "ffff", not
// "0xffff". This code should always be able to read in addresses
// written out by the above output() method. Please don't change
// this without talking to Milo first.
in >> std::hex >> m_address >> std::dec;
}
Address::Address(const Address& obj)
{
m_address = obj.m_address;
}
Address&
Address::operator=(const Address& obj)
{
if (this == &obj) {
// assert(false);
} else {
m_address = obj.m_address;
}
return *this;
}

View File

@ -0,0 +1,227 @@
/*
* Copyright (c) 1999 Mark D. Hill and David A. Wood
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __MEM_RUBY_COMMON_ADDRESS_HH__
#define __MEM_RUBY_COMMON_ADDRESS_HH__
#include <cassert>
#include <iomanip>
#include <iostream>
#include "base/hashmap.hh"
#include "mem/ruby/common/TypeDefines.hh"
const int ADDRESS_WIDTH = 64; // address width in bytes
class Address;
typedef Address PhysAddress;
typedef Address VirtAddress;
class Address
{
public:
Address()
: m_address(0)
{ }
explicit
Address(physical_address_t address)
: m_address(address)
{ }
Address(const Address& obj);
Address& operator=(const Address& obj);
void setAddress(physical_address_t address) { m_address = address; }
physical_address_t getAddress() const {return m_address;}
// selects bits inclusive
physical_address_t bitSelect(int small, int big) const;
physical_address_t bitRemove(int small, int big) const;
physical_address_t maskLowOrderBits(int number) const;
physical_address_t maskHighOrderBits(int number) const;
physical_address_t shiftLowOrderBits(int number) const;
physical_address_t getLineAddress() const;
physical_address_t getOffset() const;
void makeLineAddress();
void makeNextStrideAddress(int stride);
int getBankSetNum() const;
int getBankSetDist() const;
Index memoryModuleIndex() const;
void print(std::ostream& out) const;
void output(std::ostream& out) const;
void input(std::istream& in);
void
setOffset(int offset)
{
// first, zero out the offset bits
makeLineAddress();
m_address |= (physical_address_t) offset;
}
private:
physical_address_t m_address;
};
inline Address
line_address(const Address& addr)
{
Address temp(addr);
temp.makeLineAddress();
return temp;
}
inline bool
operator<(const Address& obj1, const Address& obj2)
{
return obj1.getAddress() < obj2.getAddress();
}
inline std::ostream&
operator<<(std::ostream& out, const Address& obj)
{
obj.print(out);
out << std::flush;
return out;
}
inline bool
operator==(const Address& obj1, const Address& obj2)
{
return (obj1.getAddress() == obj2.getAddress());
}
inline bool
operator!=(const Address& obj1, const Address& obj2)
{
return (obj1.getAddress() != obj2.getAddress());
}
// rips bits inclusive
inline physical_address_t
Address::bitSelect(int small, int big) const
{
physical_address_t mask;
assert((unsigned)big >= (unsigned)small);
if (big >= ADDRESS_WIDTH - 1) {
return (m_address >> small);
} else {
mask = ~((physical_address_t)~0 << (big + 1));
// FIXME - this is slow to manipulate a 64-bit number using 32-bits
physical_address_t partial = (m_address & mask);
return (partial >> small);
}
}
// removes bits inclusive
inline physical_address_t
Address::bitRemove(int small, int big) const
{
physical_address_t mask;
assert((unsigned)big >= (unsigned)small);
if (small >= ADDRESS_WIDTH - 1) {
return m_address;
} else if (big >= ADDRESS_WIDTH - 1) {
mask = (physical_address_t)~0 >> small;
return (m_address & mask);
} else if (small == 0) {
mask = (physical_address_t)~0 << big;
return (m_address & mask);
} else {
mask = ~((physical_address_t)~0 << small);
physical_address_t lower_bits = m_address & mask;
mask = (physical_address_t)~0 << (big + 1);
physical_address_t higher_bits = m_address & mask;
// Shift the valid high bits over the removed section
higher_bits = higher_bits >> (big - small + 1);
return (higher_bits | lower_bits);
}
}
inline physical_address_t
Address::maskLowOrderBits(int number) const
{
physical_address_t mask;
if (number >= ADDRESS_WIDTH - 1) {
mask = ~0;
} else {
mask = (physical_address_t)~0 << number;
}
return (m_address & mask);
}
inline physical_address_t
Address::maskHighOrderBits(int number) const
{
physical_address_t mask;
if (number >= ADDRESS_WIDTH - 1) {
mask = ~0;
} else {
mask = (physical_address_t)~0 >> number;
}
return (m_address & mask);
}
inline physical_address_t
Address::shiftLowOrderBits(int number) const
{
return (m_address >> number);
}
__hash_namespace_begin
template <> struct hash<Address>
{
size_t
operator()(const Address &s) const
{
return (size_t)s.getAddress();
}
};
__hash_namespace_end
namespace std {
template <> struct equal_to<Address>
{
bool
operator()(const Address& s1, const Address& s2) const
{
return s1 == s2;
}
};
} // namespace std
#endif // __MEM_RUBY_COMMON_ADDRESS_HH__

View File

@ -0,0 +1,117 @@
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* This is the virtual base class of all classes that can be the
* targets of wakeup events. There is only two methods, wakeup() and
* print() and no data members.
*/
#ifndef __MEM_RUBY_COMMON_CONSUMER_HH__
#define __MEM_RUBY_COMMON_CONSUMER_HH__
#include <iostream>
#include <set>
#include "mem/ruby/common/Global.hh"
#include "mem/ruby/eventqueue/RubyEventQueue.hh"
class MessageBuffer;
class Consumer
{
public:
Consumer()
: m_last_scheduled_wakeup(0), m_last_wakeup(0)
{
}
virtual
~Consumer()
{ }
void
triggerWakeup(RubyEventQueue *eventQueue)
{
Time time = eventQueue->getTime();
if (m_last_wakeup != time) {
wakeup();
m_last_wakeup = time;
}
}
virtual void wakeup() = 0;
virtual void print(std::ostream& out) const = 0;
virtual void storeEventInfo(int info) {}
const Time&
getLastScheduledWakeup() const
{
return m_last_scheduled_wakeup;
}
void
setLastScheduledWakeup(const Time& time)
{
m_last_scheduled_wakeup = time;
}
bool
alreadyScheduled(Time time)
{
return m_scheduled_wakeups.find(time) != m_scheduled_wakeups.end();
}
void
insertScheduledWakeupTime(Time time)
{
m_scheduled_wakeups.insert(time);
}
void
removeScheduledWakeupTime(Time time)
{
assert(alreadyScheduled(time));
m_scheduled_wakeups.erase(time);
}
private:
Time m_last_scheduled_wakeup;
std::set<Time> m_scheduled_wakeups;
Time m_last_wakeup;
};
inline std::ostream&
operator<<(std::ostream& out, const Consumer& obj)
{
obj.print(out);
out << std::flush;
return out;
}
#endif // __MEM_RUBY_COMMON_CONSUMER_HH__

View File

@ -0,0 +1,100 @@
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "mem/ruby/common/DataBlock.hh"
#include "mem/ruby/system/System.hh"
DataBlock::DataBlock(const DataBlock &cp)
{
m_data = new uint8[RubySystem::getBlockSizeBytes()];
memcpy(m_data, cp.m_data, RubySystem::getBlockSizeBytes());
m_alloc = true;
}
void
DataBlock::alloc()
{
m_data = new uint8[RubySystem::getBlockSizeBytes()];
m_alloc = true;
clear();
}
void
DataBlock::clear()
{
memset(m_data, 0, RubySystem::getBlockSizeBytes());
}
bool
DataBlock::equal(const DataBlock& obj) const
{
return !memcmp(m_data, obj.m_data, RubySystem::getBlockSizeBytes());
}
void
DataBlock::print(std::ostream& out) const
{
using namespace std;
int size = RubySystem::getBlockSizeBytes();
out << "[ ";
for (int i = 0; i < size; i++) {
out << setw(2) << setfill('0') << hex << "0x" << (int)m_data[i] << " ";
out << setfill(' ');
}
out << dec << "]" << flush;
}
const uint8*
DataBlock::getData(int offset, int len) const
{
assert(offset + len <= RubySystem::getBlockSizeBytes());
return &m_data[offset];
}
void
DataBlock::setData(uint8* data, int offset, int len)
{
assert(offset + len <= RubySystem::getBlockSizeBytes());
memcpy(&m_data[offset], data, len);
}
DataBlock &
DataBlock::operator=(const DataBlock & obj)
{
if (this == &obj) {
// assert(false);
} else {
if (!m_alloc)
m_data = new uint8[RubySystem::getBlockSizeBytes()];
memcpy(m_data, obj.m_data, RubySystem::getBlockSizeBytes());
m_alloc = true;
}
return *this;
}

View File

@ -0,0 +1,114 @@
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __MEM_RUBY_COMMON_DATABLOCK_HH__
#define __MEM_RUBY_COMMON_DATABLOCK_HH__
#include <iomanip>
#include <iostream>
#include "mem/ruby/common/TypeDefines.hh"
class DataBlock
{
public:
DataBlock()
{
alloc();
}
DataBlock(const DataBlock &cp);
~DataBlock()
{
if (m_alloc)
delete [] m_data;
}
DataBlock& operator=(const DataBlock& obj);
void assign(uint8* data);
void clear();
uint8 getByte(int whichByte) const;
const uint8* getData(int offset, int len) const;
void setByte(int whichByte, uint8 data);
void setData(uint8* data, int offset, int len);
void copyPartial(const DataBlock & dblk, int offset, int len);
bool equal(const DataBlock& obj) const;
void print(std::ostream& out) const;
private:
void alloc();
uint8* m_data;
bool m_alloc;
};
inline void
DataBlock::assign(uint8* data)
{
if (m_alloc) {
delete [] m_data;
}
m_data = data;
m_alloc = false;
}
inline uint8
DataBlock::getByte(int whichByte) const
{
return m_data[whichByte];
}
inline void
DataBlock::setByte(int whichByte, uint8 data)
{
m_data[whichByte] = data;
}
inline void
DataBlock::copyPartial(const DataBlock & dblk, int offset, int len)
{
setData(&dblk.m_data[offset], offset, len);
}
inline std::ostream&
operator<<(std::ostream& out, const DataBlock& obj)
{
obj.print(out);
out << std::flush;
return out;
}
inline bool
operator==(const DataBlock& obj1,const DataBlock& obj2)
{
return obj1.equal(obj2);
}
#endif // __MEM_RUBY_COMMON_DATABLOCK_HH__

View File

@ -0,0 +1,33 @@
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "mem/ruby/common/Global.hh"
RubyEventQueue* g_eventQueue_ptr = 0;
RubySystem* g_system_ptr = 0;

View File

@ -0,0 +1,48 @@
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __MEM_RUBY_COMMON_GLOBAL_HH__
#define __MEM_RUBY_COMMON_GLOBAL_HH__
#include "base/str.hh"
class RubyEventQueue;
extern RubyEventQueue* g_eventQueue_ptr;
class RubySystem;
extern RubySystem* g_system_ptr;
// FIXME: this is required by the contructor of Directory_Entry.hh.
// It can't go into slicc_util.hh because it opens a can of ugly worms
extern inline int max_tokens()
{
return 1024;
}
#endif // __MEM_RUBY_COMMON_GLOBAL_HH__

View File

@ -0,0 +1,194 @@
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <cmath>
#include <iomanip>
#include "base/intmath.hh"
#include "mem/ruby/common/Histogram.hh"
using namespace std;
Histogram::Histogram(int binsize, int bins)
{
m_binsize = binsize;
m_bins = bins;
clear();
}
Histogram::~Histogram()
{
}
void
Histogram::clear(int binsize, int bins)
{
m_binsize = binsize;
clear(bins);
}
void
Histogram::clear(int bins)
{
m_bins = bins;
m_largest_bin = 0;
m_max = 0;
m_data.resize(m_bins);
for (int i = 0; i < m_bins; i++) {
m_data[i] = 0;
}
m_count = 0;
m_max = 0;
m_sumSamples = 0;
m_sumSquaredSamples = 0;
}
void
Histogram::add(int64 value)
{
assert(value >= 0);
m_max = max(m_max, value);
m_count++;
m_sumSamples += value;
m_sumSquaredSamples += (value*value);
int index;
if (m_binsize == -1) {
// This is a log base 2 histogram
if (value == 0) {
index = 0;
} else {
index = floorLog2(value) + 1;
if (index >= m_data.size()) {
index = m_data.size() - 1;
}
}
} else {
// This is a linear histogram
while (m_max >= (m_bins * m_binsize)) {
for (int i = 0; i < m_bins/2; i++) {
m_data[i] = m_data[i*2] + m_data[i*2 + 1];
}
for (int i = m_bins/2; i < m_bins; i++) {
m_data[i] = 0;
}
m_binsize *= 2;
}
index = value/m_binsize;
}
assert(index >= 0);
m_data[index]++;
m_largest_bin = max(m_largest_bin, index);
}
void
Histogram::add(const Histogram& hist)
{
assert(hist.getBins() == m_bins);
assert(hist.getBinSize() == -1); // assume log histogram
assert(m_binsize == -1);
for (int j = 0; j < hist.getData(0); j++) {
add(0);
}
for (int i = 1; i < m_bins; i++) {
for (int j = 0; j < hist.getData(i); j++) {
add(1<<(i-1)); // account for the + 1 index
}
}
}
// Computation of standard deviation of samples a1, a2, ... aN
// variance = [SUM {ai^2} - (SUM {ai})^2/N]/(N-1)
// std deviation equals square root of variance
double
Histogram::getStandardDeviation() const
{
if (m_count <= 1)
return 0.0;
double variance =
(double)(m_sumSquaredSamples - m_sumSamples * m_sumSamples / m_count)
/ (m_count - 1);
return sqrt(variance);
}
void
Histogram::print(ostream& out) const
{
printWithMultiplier(out, 1.0);
}
void
Histogram::printPercent(ostream& out) const
{
if (m_count == 0) {
printWithMultiplier(out, 0.0);
} else {
printWithMultiplier(out, 100.0 / double(m_count));
}
}
void
Histogram::printWithMultiplier(ostream& out, double multiplier) const
{
if (m_binsize == -1) {
out << "[binsize: log2 ";
} else {
out << "[binsize: " << m_binsize << " ";
}
out << "max: " << m_max << " ";
out << "count: " << m_count << " ";
// out << "total: " << m_sumSamples << " ";
if (m_count == 0) {
out << "average: NaN |";
out << "standard deviation: NaN |";
} else {
out << "average: " << setw(5) << ((double) m_sumSamples)/m_count
<< " | ";
out << "standard deviation: " << getStandardDeviation() << " |";
}
for (int i = 0; i < m_bins && i <= m_largest_bin; i++) {
if (multiplier == 1.0) {
out << " " << m_data[i];
} else {
out << " " << double(m_data[i]) * multiplier;
}
}
out << " ]";
}
bool
node_less_then_eq(const Histogram* n1, const Histogram* n2)
{
return (n1->size() > n2->size());
}

View File

@ -0,0 +1,82 @@
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __MEM_RUBY_COMMON_HISTOGRAM_HH__
#define __MEM_RUBY_COMMON_HISTOGRAM_HH__
#include <iostream>
#include <vector>
#include "mem/ruby/common/TypeDefines.hh"
class Histogram
{
public:
Histogram(int binsize = 1, int bins = 50);
~Histogram();
void add(int64 value);
void add(const Histogram& hist);
void clear() { clear(m_bins); }
void clear(int bins);
void clear(int binsize, int bins);
int64 size() const { return m_count; }
int getBins() const { return m_bins; }
int getBinSize() const { return m_binsize; }
int64 getTotal() const { return m_sumSamples; }
int64 getData(int index) const { return m_data[index]; }
void printWithMultiplier(std::ostream& out, double multiplier) const;
void printPercent(std::ostream& out) const;
void print(std::ostream& out) const;
private:
std::vector<int64> m_data;
int64 m_max; // the maximum value seen so far
int64 m_count; // the number of elements added
int m_binsize; // the size of each bucket
int m_bins; // the number of buckets
int m_largest_bin; // the largest bin used
int64 m_sumSamples; // the sum of all samples
int64 m_sumSquaredSamples; // the sum of the square of all samples
double getStandardDeviation() const;
};
bool node_less_then_eq(const Histogram* n1, const Histogram* n2);
inline std::ostream&
operator<<(std::ostream& out, const Histogram& obj)
{
obj.print(out);
out << std::flush;
return out;
}
#endif // __MEM_RUBY_COMMON_HISTOGRAM_HH__

View File

@ -0,0 +1,276 @@
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <algorithm>
#include "mem/ruby/common/NetDest.hh"
NetDest::NetDest()
{
resize();
}
void
NetDest::add(MachineID newElement)
{
m_bits[vecIndex(newElement)].add(bitIndex(newElement.num));
}
void
NetDest::addNetDest(const NetDest& netDest)
{
assert(m_bits.size() == netDest.getSize());
for (int i = 0; i < m_bits.size(); i++) {
m_bits[i].addSet(netDest.m_bits[i]);
}
}
void
NetDest::addRandom()
{
int i = random()%m_bits.size();
m_bits[i].addRandom();
}
void
NetDest::setNetDest(MachineType machine, const Set& set)
{
// assure that there is only one set of destinations for this machine
assert(MachineType_base_level((MachineType)(machine + 1)) -
MachineType_base_level(machine) == 1);
m_bits[MachineType_base_level(machine)] = set;
}
void
NetDest::remove(MachineID oldElement)
{
m_bits[vecIndex(oldElement)].remove(bitIndex(oldElement.num));
}
void
NetDest::removeNetDest(const NetDest& netDest)
{
assert(m_bits.size() == netDest.getSize());
for (int i = 0; i < m_bits.size(); i++) {
m_bits[i].removeSet(netDest.m_bits[i]);
}
}
void
NetDest::clear()
{
for (int i = 0; i < m_bits.size(); i++) {
m_bits[i].clear();
}
}
void
NetDest::broadcast()
{
for (MachineType machine = MachineType_FIRST;
machine < MachineType_NUM; ++machine) {
broadcast(machine);
}
}
void
NetDest::broadcast(MachineType machineType)
{
for (int i = 0; i < MachineType_base_count(machineType); i++) {
MachineID mach = {machineType, i};
add(mach);
}
}
//For Princeton Network
std::vector<NodeID>
NetDest::getAllDest()
{
std::vector<NodeID> dest;
dest.clear();
for (int i = 0; i < m_bits.size(); i++) {
for (int j = 0; j < m_bits[i].getSize(); j++) {
if (m_bits[i].isElement(j)) {
int id = MachineType_base_number((MachineType)i) + j;
dest.push_back((NodeID)id);
}
}
}
return dest;
}
int
NetDest::count() const
{
int counter = 0;
for (int i = 0; i < m_bits.size(); i++) {
counter += m_bits[i].count();
}
return counter;
}
NodeID
NetDest::elementAt(MachineID index)
{
return m_bits[vecIndex(index)].elementAt(bitIndex(index.num));
}
MachineID
NetDest::smallestElement() const
{
assert(count() > 0);
for (int i = 0; i < m_bits.size(); i++) {
for (int j = 0; j < m_bits[i].getSize(); j++) {
if (m_bits[i].isElement(j)) {
MachineID mach = {MachineType_from_base_level(i), j};
return mach;
}
}
}
panic("No smallest element of an empty set.");
}
MachineID
NetDest::smallestElement(MachineType machine) const
{
int size = m_bits[MachineType_base_level(machine)].getSize();
for (int j = 0; j < size; j++) {
if (m_bits[MachineType_base_level(machine)].isElement(j)) {
MachineID mach = {machine, j};
return mach;
}
}
panic("No smallest element of given MachineType.");
}
// Returns true iff all bits are set
bool
NetDest::isBroadcast() const
{
for (int i = 0; i < m_bits.size(); i++) {
if (!m_bits[i].isBroadcast()) {
return false;
}
}
return true;
}
// Returns true iff no bits are set
bool
NetDest::isEmpty() const
{
for (int i = 0; i < m_bits.size(); i++) {
if (!m_bits[i].isEmpty()) {
return false;
}
}
return true;
}
// returns the logical OR of "this" set and orNetDest
NetDest
NetDest::OR(const NetDest& orNetDest) const
{
assert(m_bits.size() == orNetDest.getSize());
NetDest result;
for (int i = 0; i < m_bits.size(); i++) {
result.m_bits[i] = m_bits[i].OR(orNetDest.m_bits[i]);
}
return result;
}
// returns the logical AND of "this" set and andNetDest
NetDest
NetDest::AND(const NetDest& andNetDest) const
{
assert(m_bits.size() == andNetDest.getSize());
NetDest result;
for (int i = 0; i < m_bits.size(); i++) {
result.m_bits[i] = m_bits[i].AND(andNetDest.m_bits[i]);
}
return result;
}
// Returns true if the intersection of the two sets is non-empty
bool
NetDest::intersectionIsNotEmpty(const NetDest& other_netDest) const
{
assert(m_bits.size() == other_netDest.getSize());
for (int i = 0; i < m_bits.size(); i++) {
if (!m_bits[i].intersectionIsEmpty(other_netDest.m_bits[i])) {
return true;
}
}
return false;
}
bool
NetDest::isSuperset(const NetDest& test) const
{
assert(m_bits.size() == test.getSize());
for (int i = 0; i < m_bits.size(); i++) {
if (!m_bits[i].isSuperset(test.m_bits[i])) {
return false;
}
}
return true;
}
bool
NetDest::isElement(MachineID element) const
{
return ((m_bits[vecIndex(element)])).isElement(bitIndex(element.num));
}
void
NetDest::resize()
{
m_bits.resize(MachineType_base_level(MachineType_NUM));
assert(m_bits.size() == MachineType_NUM);
for (int i = 0; i < m_bits.size(); i++) {
m_bits[i].setSize(MachineType_base_count((MachineType)i));
}
}
void
NetDest::print(std::ostream& out) const
{
out << "[NetDest (" << m_bits.size() << ") ";
for (int i = 0; i < m_bits.size(); i++) {
for (int j = 0; j < m_bits[i].getSize(); j++) {
out << (bool) m_bits[i].isElement(j) << " ";
}
out << " - ";
}
out << "]";
}

View File

@ -0,0 +1,132 @@
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// NetDest specifies the network destination of a NetworkMessage
// This is backward compatible with the Set class that was previously
// used to specify network destinations.
// NetDest supports both node networks and component networks
#ifndef __MEM_RUBY_COMMON_NETDEST_HH__
#define __MEM_RUBY_COMMON_NETDEST_HH__
#include <iostream>
#include <vector>
#include "debug/RubyMemory.hh"
#include "mem/protocol/MachineType.hh"
#include "mem/ruby/common/Global.hh"
#include "mem/ruby/common/Set.hh"
#include "mem/ruby/system/MachineID.hh"
class NetDest
{
public:
// Constructors
// creates and empty set
NetDest();
explicit NetDest(int bit_size);
NetDest& operator=(const Set& obj);
~NetDest()
{ }
void add(MachineID newElement);
void addNetDest(const NetDest& netDest);
void addRandom();
void setNetDest(MachineType machine, const Set& set);
void remove(MachineID oldElement);
void removeNetDest(const NetDest& netDest);
void clear();
void broadcast();
void broadcast(MachineType machine);
int count() const;
bool isEqual(const NetDest& netDest);
// return the logical OR of this netDest and orNetDest
NetDest OR(const NetDest& orNetDest) const;
// return the logical AND of this netDest and andNetDest
NetDest AND(const NetDest& andNetDest) const;
// Returns true if the intersection of the two netDests is non-empty
bool intersectionIsNotEmpty(const NetDest& other_netDest) const;
// Returns true if the intersection of the two netDests is empty
bool intersectionIsEmpty(const NetDest& other_netDest) const;
bool isSuperset(const NetDest& test) const;
bool isSubset(const NetDest& test) const { return test.isSuperset(*this); }
bool isElement(MachineID element) const;
bool isBroadcast() const;
bool isEmpty() const;
// For Princeton Network
std::vector<NodeID> getAllDest();
MachineID smallestElement() const;
MachineID smallestElement(MachineType machine) const;
void resize();
int getSize() const { return m_bits.size(); }
// get element for a index
NodeID elementAt(MachineID index);
void print(std::ostream& out) const;
private:
// returns a value >= MachineType_base_level("this machine")
// and < MachineType_base_level("next highest machine")
int
vecIndex(MachineID m) const
{
int vec_index = MachineType_base_level(m.type);
assert(vec_index < m_bits.size());
return vec_index;
}
NodeID
bitIndex(NodeID index) const
{
return index;
}
std::vector<Set> m_bits; // a vector of bit vectors - i.e. Sets
};
inline std::ostream&
operator<<(std::ostream& out, const NetDest& obj)
{
obj.print(out);
out << std::flush;
return out;
}
#endif // __MEM_RUBY_COMMON_NETDEST_HH__

View File

@ -0,0 +1,42 @@
# -*- mode:python -*-
# Copyright (c) 2009 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Authors: Nathan Binkert
Import('*')
if env['PROTOCOL'] == 'None':
Return()
Source('Address.cc')
Source('DataBlock.cc')
Source('Global.cc')
Source('Histogram.cc')
Source('NetDest.cc')
Source('Set.cc')
Source('SubBlock.cc')

View File

@ -0,0 +1,361 @@
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// modified (rewritten) 05/20/05 by Dan Gibson to accomimdate FASTER
// >32 bit set sizes
#include <cstdio>
#include "base/misc.hh"
#include "mem/ruby/common/Set.hh"
#include "mem/ruby/system/System.hh"
Set::Set()
{
m_p_nArray = NULL;
m_nArrayLen = 0;
m_nSize = 0;
}
Set::Set(const Set& obj)
{
m_p_nArray = NULL;
setSize(obj.m_nSize);
// copy from the host to this array
for (int i = 0; i < m_nArrayLen; i++)
m_p_nArray[i] = obj.m_p_nArray[i];
}
Set::Set(int size)
{
m_p_nArray = NULL;
m_nArrayLen = 0;
m_nSize = 0;
if (size > 0)
setSize(size);
}
Set::~Set()
{
if (m_p_nArray && m_p_nArray != &m_p_nArray_Static[0])
delete [] m_p_nArray;
m_p_nArray = NULL;
}
void
Set::clearExcess()
{
// now just ensure that no bits over the maximum size were set
#ifdef _LP64
long mask = 0x7FFFFFFFFFFFFFFF;
#else
long mask = 0x7FFFFFFF;
#endif
// the number of populated spaces in the higest-order array slot
// is: m_nSize % LONG_BITS, so the uppermost LONG_BITS -
// m_nSize%64 bits should be cleared
if ((m_nSize % LONG_BITS) != 0) {
for (int j = 0; j < 64 - (m_nSize & INDEX_MASK); j++) {
m_p_nArray[m_nArrayLen - 1] &= mask;
mask = mask >> 1;
}
}
}
/*
* This function should set all the bits in the current set that are
* already set in the parameter set
*/
void
Set::addSet(const Set& set)
{
assert(getSize()==set.getSize());
for (int i = 0; i < m_nArrayLen; i++)
m_p_nArray[i] |= set.m_p_nArray[i];
}
/*
* This function should randomly assign 1 to the bits in the set--it
* should not clear the bits bits first, though?
*/
void
Set::addRandom()
{
for (int i = 0; i < m_nArrayLen; i++) {
// this ensures that all 32 bits are subject to random effects,
// as RAND_MAX typically = 0x7FFFFFFF
m_p_nArray[i] |= random() ^ (random() << 4);
}
clearExcess();
}
/*
* This function clears bits that are =1 in the parameter set
*/
void
Set::removeSet(const Set& set)
{
assert(m_nSize == set.m_nSize);
for (int i = 0; i < m_nArrayLen; i++)
m_p_nArray[i] &= ~set.m_p_nArray[i];
}
/*
* this function sets all bits in the set
*/
void
Set::broadcast()
{
for (int i = 0; i < m_nArrayLen; i++)
m_p_nArray[i] = -1; // note that -1 corresponds to all 1's in 2's comp.
clearExcess();
}
/*
* This function returns the population count of 1's in the set
*/
int
Set::count() const
{
int counter = 0;
long mask;
for (int i = 0; i < m_nArrayLen; i++) {
mask = (long)0x01;
for (int j = 0; j < LONG_BITS; j++) {
// FIXME - significant performance loss when array
// population << LONG_BITS
if ((m_p_nArray[i] & mask) != 0) {
counter++;
}
mask = mask << 1;
}
}
return counter;
}
/*
* This function checks for set equality
*/
bool
Set::isEqual(const Set& set) const
{
assert(m_nSize == set.m_nSize);
for (int i = 0; i < m_nArrayLen; i++)
if (m_p_nArray[i] != set.m_p_nArray[i])
return false;
return true;
}
/*
* This function returns the NodeID (int) of the least set bit
*/
NodeID
Set::smallestElement() const
{
assert(count() > 0);
long x;
for (int i = 0; i < m_nArrayLen; i++) {
if (m_p_nArray[i] != 0) {
// the least-set bit must be in here
x = m_p_nArray[i];
for (int j = 0; j < LONG_BITS; j++) {
if (x & (unsigned long)1) {
return LONG_BITS * i + j;
}
x = x >> 1;
}
panic("No smallest element of an empty set.");
}
}
panic("No smallest element of an empty set.");
}
/*
* this function returns true iff all bits are set
*/
bool
Set::isBroadcast() const
{
// check the fully-loaded words by equal to 0xffffffff
// only the last word may not be fully loaded, it is not
// fully loaded iff m_nSize % 32 or 64 !=0 => fully loaded iff
// m_nSize % 32 or 64 == 0
int max = (m_nSize % LONG_BITS) == 0 ? m_nArrayLen : m_nArrayLen - 1;
for (int i = 0; i < max; i++) {
if (m_p_nArray[i] != -1) {
return false;
}
}
// now check the last word, which may not be fully loaded
long mask = 1;
for (int j = 0; j < (m_nSize % LONG_BITS); j++) {
if ((mask & m_p_nArray[m_nArrayLen-1]) == 0) {
return false;
}
mask = mask << 1;
}
return true;
}
/*
* this function returns true iff no bits are set
*/
bool
Set::isEmpty() const
{
// here we can simply check if all = 0, since we ensure
// that "extra slots" are all zero
for (int i = 0; i < m_nArrayLen ; i++)
if (m_p_nArray[i])
return false;
return true;
}
// returns the logical OR of "this" set and orSet
Set
Set::OR(const Set& orSet) const
{
Set result(m_nSize);
assert(m_nSize == orSet.m_nSize);
for (int i = 0; i < m_nArrayLen; i++)
result.m_p_nArray[i] = m_p_nArray[i] | orSet.m_p_nArray[i];
return result;
}
// returns the logical AND of "this" set and andSet
Set
Set::AND(const Set& andSet) const
{
Set result(m_nSize);
assert(m_nSize == andSet.m_nSize);
for (int i = 0; i < m_nArrayLen; i++) {
result.m_p_nArray[i] = m_p_nArray[i] & andSet.m_p_nArray[i];
}
return result;
}
/*
* Returns false if a bit is set in the parameter set that is NOT set
* in this set
*/
bool
Set::isSuperset(const Set& test) const
{
assert(m_nSize == test.m_nSize);
for (int i = 0; i < m_nArrayLen; i++)
if (((test.m_p_nArray[i] & m_p_nArray[i]) | ~test.m_p_nArray[i]) != -1)
return false;
return true;
}
void
Set::setSize(int size)
{
m_nSize = size;
m_nArrayLen = (m_nSize + LONG_BITS - 1) / LONG_BITS;
// decide whether to use dynamic or static alloction
if (m_nArrayLen <= NUMBER_WORDS_PER_SET) {
// constant defined in RubySystem.hh
// its OK to use the static allocation, and it will
// probably be faster (as m_nArrayLen is already in the
// cache and they will probably share the same cache line)
// if switching from dyanamic to static allocation (which
// is probably rare, but why not be complete?), must delete
// the dynamically allocated space
if (m_p_nArray && m_p_nArray != &m_p_nArray_Static[0])
delete [] m_p_nArray;
m_p_nArray = &m_p_nArray_Static[0];
} else {
// can't use static allocation...simply not enough room
// so dynamically allocate some space
if (m_p_nArray && m_p_nArray != &m_p_nArray_Static[0])
delete [] m_p_nArray;
m_p_nArray = new long[m_nArrayLen];
}
clear();
}
Set&
Set::operator=(const Set& obj)
{
if (this != &obj) {
// resize this item
setSize(obj.getSize());
// copy the elements from obj to this
for (int i = 0; i < m_nArrayLen; i++)
m_p_nArray[i] = obj.m_p_nArray[i];
}
return *this;
}
void
Set::print(std::ostream& out) const
{
if (!m_p_nArray) {
out << "[Set {Empty}]";
return;
}
char buff[24];
out << "[Set (" << m_nSize << ")";
for (int i = m_nArrayLen - 1; i >= 0; i--) {
csprintf(buff," 0x%08X", m_p_nArray[i]);
out << buff;
}
out << " ]";
}

View File

@ -0,0 +1,167 @@
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// modified by Dan Gibson on 05/20/05 to accomidate FASTER
// >32 set lengths, using an array of ints w/ 32 bits/int
#ifndef __MEM_RUBY_COMMON_SET_HH__
#define __MEM_RUBY_COMMON_SET_HH__
#include <iostream>
#include <limits>
#include "mem/ruby/common/TypeDefines.hh"
/*
* This defines the number of longs (32-bits on 32 bit machines,
* 64-bit on 64-bit AMD machines) to use to hold the set...
* the default is 4, allowing 128 or 256 different members
* of the set.
*
* This should never need to be changed for correctness reasons,
* though increasing it will increase performance for larger
* set sizes at the cost of a (much) larger memory footprint
*
*/
const int NUMBER_WORDS_PER_SET = 1;
class Set
{
private:
int m_nSize; // the number of bits in this set
int m_nArrayLen; // the number of 32-bit words that are
// held in the array
// Changed 5/24/05 for static allocation of array
// note that "long" corresponds to 32 bits on a 32-bit machine,
// 64 bits if the -m64 parameter is passed to g++, which it is
// for an AMD opteron under our configuration
long *m_p_nArray; // an word array to hold the bits in the set
long m_p_nArray_Static[NUMBER_WORDS_PER_SET];
static const int LONG_BITS = std::numeric_limits<long>::digits + 1;
static const int INDEX_SHIFT = LONG_BITS == 64 ? 6 : 5;
static const int INDEX_MASK = (1 << INDEX_SHIFT) - 1;
void clearExcess();
public:
Set();
Set(int size);
Set(const Set& obj);
~Set();
Set& operator=(const Set& obj);
void
add(NodeID index)
{
m_p_nArray[index >> INDEX_SHIFT] |=
(((unsigned long) 1) << (index & INDEX_MASK));
}
void addSet(const Set& set);
void addRandom();
void
remove(NodeID index)
{
m_p_nArray[index >> INDEX_SHIFT] &=
~(((unsigned long)1) << (index & INDEX_MASK));
}
void removeSet(const Set& set);
void
clear()
{
for (int i = 0; i < m_nArrayLen; i++)
m_p_nArray[i] = 0;
}
void broadcast();
int count() const;
bool isEqual(const Set& set) const;
// return the logical OR of this set and orSet
Set OR(const Set& orSet) const;
// return the logical AND of this set and andSet
Set AND(const Set& andSet) const;
// Returns true if the intersection of the two sets is empty
bool
intersectionIsEmpty(const Set& other_set) const
{
for (int i = 0; i < m_nArrayLen; i++)
if (m_p_nArray[i] & other_set.m_p_nArray[i])
return false;
return true;
}
bool isSuperset(const Set& test) const;
bool isSubset(const Set& test) const { return test.isSuperset(*this); }
bool
isElement(NodeID element) const
{
return (m_p_nArray[element>>INDEX_SHIFT] &
(((unsigned long)1) << (element & INDEX_MASK))) != 0;
}
bool isBroadcast() const;
bool isEmpty() const;
NodeID smallestElement() const;
void setSize(int size);
NodeID
elementAt(int index) const
{
if (isElement(index))
return (NodeID)true;
else
return 0;
}
int getSize() const { return m_nSize; }
void print(std::ostream& out) const;
};
inline std::ostream&
operator<<(std::ostream& out, const Set& obj)
{
obj.print(out);
out << std::flush;
return out;
}
#endif // __MEM_RUBY_COMMON_SET_HH__

View File

@ -0,0 +1,73 @@
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "base/stl_helpers.hh"
#include "mem/ruby/common/SubBlock.hh"
using m5::stl_helpers::operator<<;
SubBlock::SubBlock(const Address& addr, int size)
{
m_address = addr;
resize(size);
for (int i = 0; i < size; i++) {
setByte(i, 0);
}
}
void
SubBlock::internalMergeFrom(const DataBlock& data)
{
int size = getSize();
assert(size > 0);
int offset = m_address.getOffset();
for (int i = 0; i < size; i++) {
this->setByte(i, data.getByte(offset + i));
}
}
void
SubBlock::internalMergeTo(DataBlock& data) const
{
int size = getSize();
assert(size > 0);
int offset = m_address.getOffset();
for (int i = 0; i < size; i++) {
// This will detect crossing a cache line boundary
data.setByte(offset + i, this->getByte(i));
}
}
void
SubBlock::print(std::ostream& out) const
{
out << "[" << m_address << ", " << getSize() << ", " << m_data << "]";
}

View File

@ -0,0 +1,82 @@
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __MEM_RUBY_COMMON_SUBBLOCK_HH__
#define __MEM_RUBY_COMMON_SUBBLOCK_HH__
#include <iostream>
#include <vector>
#include "mem/ruby/common/Address.hh"
#include "mem/ruby/common/DataBlock.hh"
#include "mem/ruby/common/Global.hh"
class SubBlock
{
public:
SubBlock() { }
SubBlock(const Address& addr, int size);
~SubBlock() { }
const Address& getAddress() const { return m_address; }
void setAddress(const Address& addr) { m_address = addr; }
int getSize() const { return m_data.size(); }
void resize(int size) { m_data.resize(size); }
uint8 getByte(int offset) const { return m_data[offset]; }
void setByte(int offset, uint8 data) { m_data[offset] = data; }
// Shorthands
uint8 readByte() const { return getByte(0); }
void writeByte(uint8 data) { setByte(0, data); }
// Merging to and from DataBlocks - We only need to worry about
// updates when we are using DataBlocks
void mergeTo(DataBlock& data) const { internalMergeTo(data); }
void mergeFrom(const DataBlock& data) { internalMergeFrom(data); }
void print(std::ostream& out) const;
private:
void internalMergeTo(DataBlock& data) const;
void internalMergeFrom(const DataBlock& data);
// Data Members (m_ prefix)
Address m_address;
std::vector<uint8_t> m_data;
};
inline std::ostream&
operator<<(std::ostream& out, const SubBlock& obj)
{
obj.print(out);
out << std::flush;
return out;
}
#endif // __MEM_RUBY_COMMON_SUBBLOCK_HH__

View File

@ -0,0 +1,52 @@
/*
* Copyright (c) 2009 Mark D. Hill and David A. Wood
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef TYPEDEFINES_H
#define TYPEDEFINES_H
typedef unsigned char uint8;
typedef unsigned int uint32;
typedef unsigned long long uint64;
typedef signed char int8;
typedef int int32;
typedef long long int64;
typedef long long integer_t;
typedef int64 Time;
typedef uint64 physical_address_t;
typedef int64 Index; // what the address bit ripper returns
typedef int LinkID;
typedef int NodeID;
typedef int SwitchID;
#endif