summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/SConscript2
-rw-r--r--cpu/SConscript32
-rw-r--r--dev/pktfifo.cc34
-rw-r--r--dev/pktfifo.hh29
-rw-r--r--dev/sinic.cc23
-rw-r--r--dev/sinic.hh1
-rw-r--r--util/stats/barchart.py62
-rw-r--r--util/stats/categories.py6
-rw-r--r--util/stats/chart.py1
-rw-r--r--util/stats/db.py2
-rw-r--r--util/stats/output.py37
-rwxr-xr-xutil/stats/stats.py7
12 files changed, 186 insertions, 50 deletions
diff --git a/arch/SConscript b/arch/SConscript
index d237b0b1f..142bd763b 100644
--- a/arch/SConscript
+++ b/arch/SConscript
@@ -70,7 +70,7 @@ def gen_switch_hdr_string(target, source, env):
return "Generating ISA switch header " + str(target[0])
# Build SCons Action object. 'varlist' specifies env vars that this
-# action depdnds on; when env['ALL_ISA_LIST'] changes these actions
+# action depends on; when env['ALL_ISA_LIST'] changes these actions
# should get re-executed.
switch_hdr_action = Action(gen_switch_hdr, gen_switch_hdr_string,
varlist=['ALL_ISA_LIST'])
diff --git a/cpu/SConscript b/cpu/SConscript
index dbe174660..af6bab4eb 100644
--- a/cpu/SConscript
+++ b/cpu/SConscript
@@ -32,13 +32,28 @@ import os.path
# Import build environment variable from SConstruct.
Import('env')
+#################################################################
+#
+# Generate StaticInst execute() method signatures.
+#
+# There must be one signature for each CPU model compiled in.
+# Since the set of compiled-in models is flexible, we generate a
+# header containing the appropriate set of signatures on the fly.
+#
+#################################################################
+
+# CPU model-specific data is contained in cpu_models.py
+# Convert to SCons File node to get path handling
models_db = File('cpu_models.py')
+# slurp in contents of file
execfile(models_db.srcnode().abspath)
+# Template for execute() signature.
exec_sig_template = '''
virtual Fault execute(%s *xc, Trace::InstRecord *traceData) const = 0;
'''
+# Generate header.
def gen_cpu_exec_signatures(target, source, env):
f = open(str(target[0]), 'w')
print >> f, '''
@@ -52,7 +67,22 @@ def gen_cpu_exec_signatures(target, source, env):
#endif // __CPU_STATIC_INST_EXEC_SIGS_HH__
'''
-env.Command('static_inst_exec_sigs.hh', models_db, gen_cpu_exec_signatures)
+# Generate string that gets printed when header is rebuilt
+def gen_sigs_string(target, source, env):
+ return "Generating static_inst_exec_sigs.hh: " \
+ + ', '.join(env['CPU_MODELS'])
+
+# Add command to generate header to environment.
+env.Command('static_inst_exec_sigs.hh', models_db,
+ Action(gen_cpu_exec_signatures, gen_sigs_string,
+ varlist = ['CPU_MODELS']))
+
+#################################################################
+#
+# Include CPU-model-specific files based on set of models
+# specified in CPU_MODELS build option.
+#
+#################################################################
sources = []
diff --git a/dev/pktfifo.cc b/dev/pktfifo.cc
index b4fab2d6f..639009be9 100644
--- a/dev/pktfifo.cc
+++ b/dev/pktfifo.cc
@@ -31,6 +31,36 @@
using namespace std;
+bool
+PacketFifo::copyout(void *dest, int offset, int len)
+{
+ char *data = (char *)dest;
+ if (offset + len >= size())
+ return false;
+
+ list<PacketPtr>::iterator p = fifo.begin();
+ list<PacketPtr>::iterator end = fifo.end();
+ while (len > 0) {
+ while (offset >= (*p)->length) {
+ offset -= (*p)->length;
+ ++p;
+ }
+
+ if (p == end)
+ panic("invalid fifo");
+
+ int size = min((*p)->length - offset, len);
+ memcpy(data, (*p)->data, size);
+ offset = 0;
+ len -= size;
+ data += size;
+ ++p;
+ }
+
+ return true;
+}
+
+
void
PacketFifo::serialize(const string &base, ostream &os)
{
@@ -40,8 +70,8 @@ PacketFifo::serialize(const string &base, ostream &os)
paramOut(os, base + ".packets", fifo.size());
int i = 0;
- std::list<PacketPtr>::iterator p = fifo.begin();
- std::list<PacketPtr>::iterator end = fifo.end();
+ list<PacketPtr>::iterator p = fifo.begin();
+ list<PacketPtr>::iterator end = fifo.end();
while (p != end) {
(*p)->serialize(csprintf("%s.packet%d", base, i), os);
++p;
diff --git a/dev/pktfifo.hh b/dev/pktfifo.hh
index e63fd291f..e245840a8 100644
--- a/dev/pktfifo.hh
+++ b/dev/pktfifo.hh
@@ -127,6 +127,35 @@ class PacketFifo
fifo.erase(i);
}
+ bool copyout(void *dest, int offset, int len);
+
+ int countPacketsBefore(iterator end)
+ {
+ iterator i = fifo.begin();
+ int count = 0;
+
+ while (i != end) {
+ ++count;
+ ++i;
+ }
+
+ return count;
+ }
+
+ int countPacketsAfter(iterator i)
+ {
+ iterator end = fifo.end();
+ int count = 0;
+
+ while (i != end) {
+ ++count;
+ ++i;
+ }
+
+ return count;
+ }
+
+
/**
* Serialization stuff
*/
diff --git a/dev/sinic.cc b/dev/sinic.cc
index c499d2f49..a9363954b 100644
--- a/dev/sinic.cc
+++ b/dev/sinic.cc
@@ -489,30 +489,17 @@ Device::writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data)
panic("invalid size for %s: cpu=%d da=%#x pa=%#x va=%#x size=%d",
info.name, cpu, daddr, req->paddr, req->vaddr, req->size);
- //uint32_t reg32 = *(uint32_t *)data;
+ uint32_t reg32 = *(uint32_t *)data;
uint64_t reg64 = *(uint64_t *)data;
+ VirtualReg &vnic = virtualRegs[index];
+
DPRINTF(EthernetPIO,
"write %s: cpu=%d val=%#x da=%#x pa=%#x va=%#x size=%d\n",
- info.name, cpu, info.size == 4 ? (*(uint32_t *)data) : reg64, daddr,
+ info.name, cpu, info.size == 4 ? reg32 : reg64, daddr,
req->paddr, req->vaddr, req->size);
prepareWrite(cpu, index);
- regWrite(daddr, cpu, data);
-
- return NoFault;
-}
-
-void
-Device::regWrite(Addr daddr, int cpu, const uint8_t *data)
-{
- Addr index = daddr >> Regs::VirtualShift;
- Addr raddr = daddr & Regs::VirtualMask;
-
- uint32_t reg32 = *(uint32_t *)data;
- uint64_t reg64 = *(uint64_t *)data;
- VirtualReg &vnic = virtualRegs[index];
-
switch (raddr) {
case Regs::Config:
changeConfig(reg32);
@@ -559,6 +546,8 @@ Device::regWrite(Addr daddr, int cpu, const uint8_t *data)
}
break;
}
+
+ return NoFault;
}
void
diff --git a/dev/sinic.hh b/dev/sinic.hh
index 97ebf4c30..c4027be86 100644
--- a/dev/sinic.hh
+++ b/dev/sinic.hh
@@ -280,7 +280,6 @@ class Device : public Base
Fault iprRead(Addr daddr, int cpu, uint64_t &result);
Fault readBar0(MemReqPtr &req, Addr daddr, uint8_t *data);
Fault writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data);
- void regWrite(Addr daddr, int cpu, const uint8_t *data);
Tick cacheAccess(MemReqPtr &req);
/**
diff --git a/util/stats/barchart.py b/util/stats/barchart.py
index dd3bf0180..5d6dd0ab1 100644
--- a/util/stats/barchart.py
+++ b/util/stats/barchart.py
@@ -42,13 +42,18 @@ class BarChart(ChartOptions):
super(BarChart, self).__init__(default, **kwargs)
self.inputdata = None
self.chartdata = None
+ self.inputerr = None
+ self.charterr = None
def gen_colors(self, count):
cmap = matplotlib.cm.get_cmap(self.colormap)
if count == 1:
return cmap([ 0.5 ])
- else:
- return cmap(arange(count) / float(count - 1))
+
+ if count < 5:
+ return cmap(arange(5) / float(4))[:count]
+
+ return cmap(arange(count) / float(count - 1))
# The input data format does not match the data format that the
# graph function takes because it is intuitive. The conversion
@@ -89,6 +94,32 @@ class BarChart(ChartOptions):
data = property(get_data, set_data)
+ def set_err(self, err):
+ if err is None:
+ self.inputerr = None
+ self.charterr = None
+ return
+
+ err = array(err)
+ dim = len(shape(err))
+ if dim not in (1, 2, 3):
+ raise AttributeError, "Input err must be a 1, 2, or 3d matrix"
+ self.inputerr = err
+
+ if dim == 1:
+ self.charterr = array([[err]])
+
+ if dim == 2:
+ self.charterr = transpose([err], axes=(2,0,1))
+
+ if dim == 3:
+ self.charterr = transpose(err, axes=(1,2,0))
+
+ def get_err(self):
+ return self.inputerr
+
+ err = property(get_err, set_err)
+
# Graph the chart data.
# Input is a 3d matrix that describes a plot that has multiple
# groups, multiple bars in each group, and multiple values stacked
@@ -123,6 +154,9 @@ class BarChart(ChartOptions):
dim = len(shape(self.inputdata))
cshape = shape(self.chartdata)
+ if self.charterr is not None and shape(self.charterr) != cshape:
+ raise AttributeError, 'Dimensions of error and data do not match'
+
if dim == 1:
colors = self.gen_colors(cshape[2])
colors = [ [ colors ] * cshape[1] ] * cshape[0]
@@ -143,7 +177,8 @@ class BarChart(ChartOptions):
inner_axes = None
if self.xsubticks is not None:
color = self.figure.get_facecolor()
- self.metaaxes = self.figure.add_axes(self.figure_size, axisbg=color, frameon=False)
+ self.metaaxes = self.figure.add_axes(self.figure_size,
+ axisbg=color, frameon=False)
for tick in self.metaaxes.xaxis.majorTicks:
tick.tick1On = False
tick.tick2On = False
@@ -174,8 +209,11 @@ class BarChart(ChartOptions):
for j,bardata in enumerate(stackdata):
bardata = array(bardata)
ind = arange(len(bardata)) + i * width + center
+ yerr = None
+ if self.charterr is not None:
+ yerr = self.charterr[i][j]
bar = self.axes.bar(ind, bardata, width, bottom=bottom,
- color=colors[i][j])
+ color=colors[i][j], yerr=yerr)
if self.xsubticks is not None:
self.metaaxes.bar(ind, [0] * len(bardata), width)
stack.append(bar)
@@ -202,9 +240,11 @@ class BarChart(ChartOptions):
outer_axes.set_xticklabels(self.xticks)
if self.xsubticks is not None:
- inner_axes.set_xticks(arange((cshape[0] + 1)*cshape[2])*width + 2*center)
+ numticks = (cshape[0] + 1) * cshape[2]
+ inner_axes.set_xticks(arange(numticks) * width + 2 * center)
self.xsubticks.append('')
- inner_axes.set_xticklabels(self.xsubticks * cshape[2], fontsize=7, rotation=90)
+ inner_axes.set_xticklabels(self.xsubticks * cshape[2], fontsize=7,
+ rotation=90)
if self.legend is not None:
if dim == 1:
@@ -215,8 +255,12 @@ class BarChart(ChartOptions):
number = len(bars[0])
lbars = [ bars[0][number - j - 1][0] for j in xrange(number)]
- self.figure.legend(lbars, self.legend, self.legend_loc,
- prop=FontProperties(size=self.legend_size))
+ if self.fig_legend:
+ self.figure.legend(lbars, self.legend, self.legend_loc,
+ prop=FontProperties(size=self.legend_size))
+ else:
+ self.axes.legend(lbars, self.legend, self.legend_loc,
+ prop=FontProperties(size=self.legend_size))
if self.title is not None:
self.axes.set_title(self.title)
@@ -240,7 +284,7 @@ class BarChart(ChartOptions):
ylabel = []
#if self.ylabel:
# ylabel = [ self.ylabel[i] ]
- f.write(', '.join(ylabel + [ '%f' % val for val in row]) + '\n')
+ f.write(', '.join(ylabel + [ '%f' % v for v in row]) + '\n')
if dim == 3:
f.write("don't do 3D csv files\n")
pass
diff --git a/util/stats/categories.py b/util/stats/categories.py
index 8d5d506a2..6d8568879 100644
--- a/util/stats/categories.py
+++ b/util/stats/categories.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2005 The Regents of The University of Michigan
+# Copyright (c) 2005-2006 The Regents of The University of Michigan
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -33,10 +33,14 @@ func_categories = { \
'skb_clone_fraglist' : 'buffer',
'skb_seq_read' : 'buffer',
'sock_alloc_send_skb' : 'buffer',
+ 'sinic_rxskb_alloc' : 'buffer',
# Copy functions
+ 'sinic_copyfrom' : 'copy',
'__copy_user' : 'copy',
'skb_copy_bits' : 'copy',
+ 'skb_copy_datagram_iovec' : 'copy',
+ 'sinic_vcopy_iov' : 'idle',
# Driver functions
'do_tx_done' : 'driver',
diff --git a/util/stats/chart.py b/util/stats/chart.py
index 095620172..369a57fc6 100644
--- a/util/stats/chart.py
+++ b/util/stats/chart.py
@@ -31,6 +31,7 @@ class ChartOptions(object):
defaults = { 'chart_size' : (8, 4),
'figure_size' : [0.1, 0.1, 0.6, 0.85],
'title' : None,
+ 'fig_legend' : True,
'legend' : None,
'legend_loc' : 'upper right',
'legend_size' : 6,
diff --git a/util/stats/db.py b/util/stats/db.py
index d9b78c7d1..c0e7796eb 100644
--- a/util/stats/db.py
+++ b/util/stats/db.py
@@ -158,7 +158,7 @@ class Database(object):
return None
from info import ProxyError, scalar, vector, value, values, total, len
- if system is None and hasattr('system', job):
+ if system is None and hasattr(job, 'system'):
system = job.system
if system is not None:
diff --git a/util/stats/output.py b/util/stats/output.py
index e67751bbc..abfb8d901 100644
--- a/util/stats/output.py
+++ b/util/stats/output.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2005 The Regents of The University of Michigan
+# Copyright (c) 2005-2006 The Regents of The University of Michigan
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -103,15 +103,17 @@ class StatOutput(ChartOptions):
else:
groups.append(group)
- if not groupopts:
- raise AttributeError, 'No group selected for graph group'
+ has_group = bool(groupopts)
+ if has_group:
+ groupopts = [ group for group in crossproduct(groupopts) ]
+ else:
+ groupopts = [ None ]
- if not baropts:
+ if baropts:
+ baropts = [ bar for bar in crossproduct(baropts) ]
+ else:
raise AttributeError, 'No group selected for graph bars'
- groupopts = [ group for group in crossproduct(groupopts) ]
- baropts = [ bar for bar in crossproduct(baropts) ]
-
directory = expanduser(graphdir)
if not isdir(directory):
os.mkdir(directory)
@@ -124,12 +126,13 @@ class StatOutput(ChartOptions):
for options in self.jobfile.options(groups):
chart = BarChart(self)
- data = zeros((len(groupopts), len(baropts)), Float)
data = [ [ None ] * len(baropts) for i in xrange(len(groupopts)) ]
enabled = False
stacked = 0
for g,gopt in enumerate(groupopts):
for b,bopt in enumerate(baropts):
+ if gopt is None:
+ gopt = []
job = self.jobfile.job(options + gopt + bopt)
if not job:
continue
@@ -168,19 +171,24 @@ class StatOutput(ChartOptions):
if data.sum() == 0:
continue
+ dim = len(data.shape)
x = data.shape[0]
- y = data.shape[1]
xkeep = [ i for i in xrange(x) if data[i].sum() != 0 ]
+ y = data.shape[1]
ykeep = [ i for i in xrange(y) if data[:,i].sum() != 0 ]
data = data.take(xkeep, axis=0)
data = data.take(ykeep, axis=1)
+ if not has_group:
+ data = data.take([ 0 ], axis=0)
chart.data = data
- gopts = [ groupopts[i] for i in xkeep ]
- bopts = [ baropts[i] for i in ykeep ]
+ bopts = [ baropts[i] for i in ykeep ]
bdescs = [ ' '.join([o.desc for o in opt]) for opt in bopts]
- gdescs = [ ' '.join([o.desc for o in opt]) for opt in gopts]
+
+ if has_group:
+ gopts = [ groupopts[i] for i in xkeep ]
+ gdescs = [ ' '.join([o.desc for o in opt]) for opt in gopts]
if chart.legend is None:
if stacked:
@@ -192,7 +200,10 @@ class StatOutput(ChartOptions):
chart.legend = bdescs
if chart.xticks is None:
- chart.xticks = gdescs
+ if has_group:
+ chart.xticks = gdescs
+ else:
+ chart.xticks = []
chart.graph()
names = [ opt.name for opt in options ]
diff --git a/util/stats/stats.py b/util/stats/stats.py
index b75d9fec0..08281287f 100755
--- a/util/stats/stats.py
+++ b/util/stats/stats.py
@@ -262,6 +262,7 @@ def commands(options, command, args):
from output import StatOutput
output = StatOutput(options.jobfile, source)
output.xlabel = 'System Configuration'
+ output.colormap = 'RdYlGn'
if command == 'stat' or command == 'formula':
if len(args) != 1:
@@ -286,7 +287,6 @@ def commands(options, command, args):
raise CommandException
from info import ProxyGroup
- sim_seconds = source['sim_seconds']
proxy = ProxyGroup(system = source[options.system])
system = proxy.system
@@ -294,7 +294,6 @@ def commands(options, command, args):
bytes = etherdev.rxBytes + etherdev.txBytes
kbytes = bytes / 1024
packets = etherdev.rxPackets + etherdev.txPackets
- bps = etherdev.rxBandwidth + etherdev.txBandwidth
def display():
if options.graph:
@@ -337,7 +336,7 @@ def commands(options, command, args):
return
if command == 'pps':
- output.stat = packets / sim_seconds
+ output.stat = packets / source['sim_seconds']
output.ylabel = 'Packets/s'
display()
return
@@ -355,7 +354,7 @@ def commands(options, command, args):
if command == 'txbps':
output.stat = etherdev.txBandwidth / 1e9
if command == 'bps':
- output.stat = bps / 1e9
+ output.stat = (etherdev.rxBandwidth + etherdev.txBandwidth) / 1e9
output.ylabel = 'Bandwidth (Gbps)'
output.ylim = [ 0.0, 10.0 ]