summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cpu/BaseCPU.py1
-rw-r--r--src/cpu/base.cc6
-rw-r--r--src/cpu/base.hh12
-rw-r--r--src/python/m5/simulate.py10
4 files changed, 28 insertions, 1 deletions
diff --git a/src/cpu/BaseCPU.py b/src/cpu/BaseCPU.py
index 697be87e1..957203150 100644
--- a/src/cpu/BaseCPU.py
+++ b/src/cpu/BaseCPU.py
@@ -95,6 +95,7 @@ class BaseCPU(MemObject):
code('''
void switchOut();
void takeOverFrom(BaseCPU *cpu);
+ bool switchedOut();
''')
def takeOverFrom(self, old_cpu):
diff --git a/src/cpu/base.cc b/src/cpu/base.cc
index 2b1df6696..b8cd60f63 100644
--- a/src/cpu/base.cc
+++ b/src/cpu/base.cc
@@ -119,6 +119,7 @@ BaseCPU::BaseCPU(Params *p, bool is_checker)
_instMasterId(p->system->getMasterId(name() + ".inst")),
_dataMasterId(p->system->getMasterId(name() + ".data")),
_taskId(ContextSwitchTaskId::Unknown), _pid(Request::invldPid),
+ _switchedOut(p->defer_registration),
interrupts(p->interrupts), profileEvent(NULL),
numThreads(p->numThreads), system(p->system)
{
@@ -356,6 +357,8 @@ BaseCPU::findContext(ThreadContext *tc)
void
BaseCPU::switchOut()
{
+ assert(!_switchedOut);
+ _switchedOut = true;
if (profileEvent && profileEvent->scheduled())
deschedule(profileEvent);
}
@@ -365,8 +368,11 @@ BaseCPU::takeOverFrom(BaseCPU *oldCPU)
{
assert(threadContexts.size() == oldCPU->threadContexts.size());
assert(_cpuId == oldCPU->cpuId());
+ assert(_switchedOut);
+ assert(oldCPU != this);
_pid = oldCPU->getPid();
_taskId = oldCPU->taskId();
+ _switchedOut = false;
ThreadID size = threadContexts.size();
for (ThreadID i = 0; i < size; ++i) {
diff --git a/src/cpu/base.hh b/src/cpu/base.hh
index 6552be0d6..633b7f2a7 100644
--- a/src/cpu/base.hh
+++ b/src/cpu/base.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011 ARM Limited
+ * Copyright (c) 2011-2012 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -114,6 +114,9 @@ class BaseCPU : public MemObject
* used to generate a taskId */
uint32_t _pid;
+ /** Is the CPU switched out or active? */
+ bool _switchedOut;
+
/**
* Define a base class for the CPU ports (instruction and data)
* that is refined in the subclasses. This class handles the
@@ -321,6 +324,13 @@ class BaseCPU : public MemObject
virtual void takeOverFrom(BaseCPU *cpu);
/**
+ * Determine if the CPU is switched out.
+ *
+ * @return True if the CPU is switched out, false otherwise.
+ */
+ bool switchedOut() const { return _switchedOut; }
+
+ /**
* Number of threads we're actually simulating (<= SMT_MAX_THREADS).
* This is a constant for the duration of the simulation.
*/
diff --git a/src/python/m5/simulate.py b/src/python/m5/simulate.py
index 8ad273225..a30648929 100644
--- a/src/python/m5/simulate.py
+++ b/src/python/m5/simulate.py
@@ -228,11 +228,21 @@ def switchCpus(cpuList):
if not isinstance(item, tuple) or len(item) != 2:
raise RuntimeError, "List must have tuples of (oldCPU,newCPU)"
+ old_cpu_set = set([old_cpu for old_cpu, new_cpu in cpuList])
for old_cpu, new_cpu in cpuList:
if not isinstance(old_cpu, objects.BaseCPU):
raise TypeError, "%s is not of type BaseCPU" % old_cpu
if not isinstance(new_cpu, objects.BaseCPU):
raise TypeError, "%s is not of type BaseCPU" % new_cpu
+ if new_cpu in old_cpu_set:
+ raise RuntimeError, \
+ "New CPU (%s) is in the list of old CPUs." % (old_cpu,)
+ if not new_cpu.switchedOut():
+ raise RuntimeError, \
+ "New CPU (%s) is already active." % (new_cpu,)
+ if old_cpu.switchedOut():
+ raise RuntimeError, \
+ "Old CPU (%s) is inactive." % (new_cpu,)
# Now all of the CPUs are ready to be switched out
for old_cpu, new_cpu in cpuList: