summaryrefslogtreecommitdiff
path: root/src/sim
diff options
context:
space:
mode:
Diffstat (limited to 'src/sim')
-rw-r--r--src/sim/process.cc60
-rw-r--r--src/sim/process.hh17
-rw-r--r--src/sim/system.cc14
-rw-r--r--src/sim/system.hh7
4 files changed, 47 insertions, 51 deletions
diff --git a/src/sim/process.cc b/src/sim/process.cc
index 23e890b06..50bc5e034 100644
--- a/src/sim/process.cc
+++ b/src/sim/process.cc
@@ -204,35 +204,29 @@ Process::openOutputFile(const string &filename)
return fd;
}
-
-int
-Process::registerThreadContext(ThreadContext *tc)
+ThreadContext *
+Process::findFreeContext()
{
- // add to list
- int myIndex = threadContexts.size();
- threadContexts.push_back(tc);
-
- int port = getRemoteGDBPort();
- if (port) {
- RemoteGDB *rgdb = new RemoteGDB(system, tc);
- GDBListener *gdbl = new GDBListener(rgdb, port + myIndex);
- gdbl->listen();
-
- remoteGDB.push_back(rgdb);
+ int size = contextIds.size();
+ ThreadContext *tc;
+ for (int i = 0; i < size; ++i) {
+ tc = system->getThreadContext(contextIds[i]);
+ if (tc->status() == ThreadContext::Unallocated) {
+ // inactive context, free to use
+ return tc;
+ }
}
-
- // return CPU number to caller
- return myIndex;
+ return NULL;
}
void
Process::startup()
{
- if (threadContexts.empty())
- fatal("Process %s is not associated with any CPUs!\n", name());
+ if (contextIds.empty())
+ fatal("Process %s is not associated with any HW contexts!\n", name());
// first thread context for this process... initialize & enable
- ThreadContext *tc = threadContexts[0];
+ ThreadContext *tc = system->getThreadContext(contextIds[0]);
// mark this context as active so it will start ticking.
tc->activate(0);
@@ -245,17 +239,6 @@ Process::startup()
initVirtMem->setPeer(mem_port);
}
-void
-Process::replaceThreadContext(ThreadContext *tc, int tcIndex)
-{
- if (tcIndex >= threadContexts.size()) {
- panic("replaceThreadContext: bad tcIndex, %d >= %d\n",
- tcIndex, threadContexts.size());
- }
-
- threadContexts[tcIndex] = tc;
-}
-
// map simulator fd sim_fd to target fd tgt_fd
void
Process::dup_fd(int sim_fd, int tgt_fd)
@@ -624,16 +607,19 @@ LiveProcess::argsInit(int intSize, int pageSize)
copyStringArray(envp, envp_array_base, env_data_base, initVirtMem);
assert(NumArgumentRegs >= 2);
- threadContexts[0]->setIntReg(ArgumentReg[0], argc);
- threadContexts[0]->setIntReg(ArgumentReg[1], argv_array_base);
- threadContexts[0]->setIntReg(StackPointerReg, stack_min);
+
+ ThreadContext *tc = system->getThreadContext(contextIds[0]);
+
+ tc->setIntReg(ArgumentReg[0], argc);
+ tc->setIntReg(ArgumentReg[1], argv_array_base);
+ tc->setIntReg(StackPointerReg, stack_min);
Addr prog_entry = objFile->entryPoint();
- threadContexts[0]->setPC(prog_entry);
- threadContexts[0]->setNextPC(prog_entry + sizeof(MachInst));
+ tc->setPC(prog_entry);
+ tc->setNextPC(prog_entry + sizeof(MachInst));
#if THE_ISA != ALPHA_ISA //e.g. MIPS or Sparc
- threadContexts[0]->setNextNPC(prog_entry + (2 * sizeof(MachInst)));
+ tc->setNextNPC(prog_entry + (2 * sizeof(MachInst)));
#endif
num_processes++;
diff --git a/src/sim/process.hh b/src/sim/process.hh
index cb59fed64..d6ed59ced 100644
--- a/src/sim/process.hh
+++ b/src/sim/process.hh
@@ -77,7 +77,7 @@ class Process : public SimObject
bool checkpointRestored;
// thread contexts associated with this process
- std::vector<ThreadContext *> threadContexts;
+ std::vector<int> contextIds;
// remote gdb objects
std::vector<TheISA::RemoteGDB *> remoteGDB;
@@ -85,7 +85,7 @@ class Process : public SimObject
bool breakpoint();
// number of CPUs (esxec contexts, really) assigned to this process.
- unsigned int numCpus() { return threadContexts.size(); }
+ unsigned int numCpus() { return contextIds.size(); }
// record of blocked context
struct WaitRec
@@ -187,12 +187,15 @@ class Process : public SimObject
// override of virtual SimObject method: register statistics
virtual void regStats();
- // register a thread context for this process.
- // returns tc's cpu number (index into threadContexts[])
- int registerThreadContext(ThreadContext *tc);
-
+ // After getting registered with system object, tell process which
+ // system-wide context id it is assigned.
+ void assignThreadContext(int context_id)
+ {
+ contextIds.push_back(context_id);
+ }
- void replaceThreadContext(ThreadContext *tc, int tcIndex);
+ // Find a free context to use
+ ThreadContext * findFreeContext();
// map simulator fd sim_fd to target fd tgt_fd
void dup_fd(int sim_fd, int tgt_fd);
diff --git a/src/sim/system.cc b/src/sim/system.cc
index 41075e9d0..8f25b4bb8 100644
--- a/src/sim/system.cc
+++ b/src/sim/system.cc
@@ -208,22 +208,24 @@ System::registerThreadContext(ThreadContext *tc)
void
System::startup()
{
+#if FULL_SYSTEM
int i;
for (i = 0; i < threadContexts.size(); i++)
TheISA::startupCPU(threadContexts[i], i);
+#endif
}
void
-System::replaceThreadContext(ThreadContext *tc, int id)
+System::replaceThreadContext(ThreadContext *tc, int context_id)
{
- if (id >= threadContexts.size()) {
+ if (context_id >= threadContexts.size()) {
panic("replaceThreadContext: bad id, %d >= %d\n",
- id, threadContexts.size());
+ context_id, threadContexts.size());
}
- threadContexts[id] = tc;
- if (id < remoteGDB.size())
- remoteGDB[id]->replaceThreadContext(tc);
+ threadContexts[context_id] = tc;
+ if (context_id < remoteGDB.size())
+ remoteGDB[context_id]->replaceThreadContext(tc);
}
#if !FULL_SYSTEM
diff --git a/src/sim/system.hh b/src/sim/system.hh
index f67d39c67..26cac714b 100644
--- a/src/sim/system.hh
+++ b/src/sim/system.hh
@@ -89,6 +89,11 @@ class System : public SimObject
std::vector<ThreadContext *> threadContexts;
int numcpus;
+ ThreadContext * getThreadContext(int tid)
+ {
+ return threadContexts[tid];
+ }
+
int getNumCPUs()
{
if (numcpus != threadContexts.size())
@@ -220,7 +225,7 @@ class System : public SimObject
#endif // FULL_SYSTEM
int registerThreadContext(ThreadContext *tc);
- void replaceThreadContext(ThreadContext *tc, int tcIndex);
+ void replaceThreadContext(ThreadContext *tc, int context_id);
void serialize(std::ostream &os);
void unserialize(Checkpoint *cp, const std::string &section);