From 67fda02dda290d614de233846fee434b3713b1dc Mon Sep 17 00:00:00 2001 From: Lisa Hsu Date: Sun, 2 Nov 2008 21:57:06 -0500 Subject: Make it so that all thread contexts are registered with the System, even in SE. Process still keeps track of the tc's it owns, but registration occurs with the System, this eases the way for system-wide context Ids based on registration. --- src/sim/process.cc | 60 +++++++++++++++++++++--------------------------------- src/sim/process.hh | 17 +++++++++------- src/sim/system.cc | 14 +++++++------ src/sim/system.hh | 7 ++++++- 4 files changed, 47 insertions(+), 51 deletions(-) (limited to 'src/sim') 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 threadContexts; + std::vector contextIds; // remote gdb objects std::vector 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 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 §ion); -- cgit v1.2.3