diff -r f75ee4849c40 -r 3027f0730042 configs/example/se.py --- a/configs/example/se.py Wed Jun 27 19:23:02 2012 -0400 +++ b/configs/example/se.py Mon Jul 02 14:22:07 2012 -0400 @@ -92,6 +92,11 @@ except: print >>sys.stderr, "Unable to find workload for %s: %s" % (buildEnv['TARGET_ISA'], app) sys.exit(1) +elif len(options.cmd.split(';')) > 1: + process = LiveProcess() + process.executable = options.cmd + process.cmd = [options.cmd] + options.options.split() + multiprocesses.append(process) elif options.cmd: process = LiveProcess() process.executable = options.cmd @@ -117,6 +122,7 @@ if options.cpu_type == "detailed" or options.cpu_type == "inorder": #check for SMT workload workloads = options.cmd.split(';') + multiprocesses = [] if len(workloads) > 1: process = [] smt_idx = 0 @@ -142,6 +148,7 @@ if errouts and errouts[smt_idx]: smt_process.errout = errouts[smt_idx] process += [smt_process, ] + multiprocesses.append(process) smt_idx += 1 numThreads = len(workloads) @@ -160,10 +167,7 @@ fatal("You cannot use fastmem in combination with caches!") for i in xrange(np): - if len(multiprocesses) == 1: - system.cpu[i].workload = multiprocesses[0] - else: - system.cpu[i].workload = multiprocesses[i] + system.cpu[i].workload = multiprocesses[i] if options.fastmem: system.cpu[i].fastmem = True diff -r f75ee4849c40 -r 3027f0730042 src/arch/x86/X86TLB.py --- a/src/arch/x86/X86TLB.py Wed Jun 27 19:23:02 2012 -0400 +++ b/src/arch/x86/X86TLB.py Mon Jul 02 14:22:07 2012 -0400 @@ -51,5 +51,6 @@ type = 'X86TLB' cxx_class = 'X86ISA::TLB' size = Param.Int(64, "TLB size") + numThreads = Param.Int(16, "Maximum number of threads") walker = Param.X86PagetableWalker(\ X86PagetableWalker(), "page table walker") diff -r f75ee4849c40 -r 3027f0730042 src/arch/x86/linux/syscalls.cc --- a/src/arch/x86/linux/syscalls.cc Wed Jun 27 19:23:02 2012 -0400 +++ b/src/arch/x86/linux/syscalls.cc Mon Jul 02 14:22:07 2012 -0400 @@ -444,7 +444,7 @@ /* 228 */ SyscallDesc("clock_gettime", unimplementedFunc), /* 229 */ SyscallDesc("clock_getres", unimplementedFunc), /* 230 */ SyscallDesc("clock_nanosleep", unimplementedFunc), - /* 231 */ SyscallDesc("exit_group", exitGroupFunc), + /* 231 */ SyscallDesc("exit_group", exitFunc), /* 232 */ SyscallDesc("epoll_wait", unimplementedFunc), /* 233 */ SyscallDesc("epoll_ctl", unimplementedFunc), /* 234 */ SyscallDesc("tgkill", unimplementedFunc), diff -r f75ee4849c40 -r 3027f0730042 src/arch/x86/pagetable.hh --- a/src/arch/x86/pagetable.hh Wed Jun 27 19:23:02 2012 -0400 +++ b/src/arch/x86/pagetable.hh Mon Jul 02 14:22:07 2012 -0400 @@ -83,6 +83,8 @@ // The size of the page this represents, in address bits. unsigned logBytes; + ThreadID tid; + // Read permission is always available, assuming it isn't blocked by // other mechanisms. bool writable; diff -r f75ee4849c40 -r 3027f0730042 src/arch/x86/pagetable.cc --- a/src/arch/x86/pagetable.cc Wed Jun 27 19:23:02 2012 -0400 +++ b/src/arch/x86/pagetable.cc Mon Jul 02 14:22:07 2012 -0400 @@ -45,7 +45,7 @@ { TlbEntry::TlbEntry(Addr asn, Addr _vaddr, Addr _paddr) : - paddr(_paddr), vaddr(_vaddr), logBytes(PageShift), writable(true), + paddr(_paddr), vaddr(_vaddr), logBytes(PageShift), tid(asn), writable(true), user(true), uncacheable(false), global(false), patBit(0), noExec(false) {} diff -r f75ee4849c40 -r 3027f0730042 src/arch/x86/pagetable_walker.cc --- a/src/arch/x86/pagetable_walker.cc Wed Jun 27 19:23:02 2012 -0400 +++ b/src/arch/x86/pagetable_walker.cc Mon Jul 02 14:22:07 2012 -0400 @@ -482,7 +482,7 @@ if (doEndWalk) { if (doTLBInsert) if (!functional) - walker->tlb->insert(entry.vaddr, entry); + walker->tlb->insert(entry.vaddr, tc->threadId(), entry); endWalk(); } else { PacketPtr oldRead = read; diff -r f75ee4849c40 -r 3027f0730042 src/arch/x86/tlb.hh --- a/src/arch/x86/tlb.hh Wed Jun 27 19:23:02 2012 -0400 +++ b/src/arch/x86/tlb.hh Mon Jul 02 14:22:07 2012 -0400 @@ -77,13 +77,13 @@ void dumpAll(); - TlbEntry *lookup(Addr va, bool update_lru = true); + TlbEntry *lookup(Addr va, ThreadID tid, bool update_lru = true); void setConfigAddress(uint32_t addr); protected: - EntryList::iterator lookupIt(Addr va, bool update_lru = true); + EntryList::iterator lookupIt(Addr va, ThreadID tid, bool update_lru = true); Walker * walker; @@ -99,12 +99,14 @@ protected: int size; - TlbEntry * tlb; + int numThreads; - EntryList freeList; - EntryList entryList; + std::vector tlb; - TlbEntryTrie trie; + std::vector freeList; + std::vector entryList; + + std::vector trie; uint64_t lruSeq; Fault translateInt(RequestPtr req, ThreadContext *tc); @@ -115,7 +117,7 @@ public: - void evictLRU(); + void evictLRU(ThreadID tid); uint64_t nextSeq() @@ -131,7 +133,7 @@ */ Fault translateFunctional(RequestPtr req, ThreadContext *tc, Mode mode); - TlbEntry * insert(Addr vpn, TlbEntry &entry); + TlbEntry * insert(Addr vpn, ThreadID tid, TlbEntry &entry); // Checkpointing virtual void serialize(std::ostream &os); diff -r f75ee4849c40 -r 3027f0730042 src/arch/x86/tlb.cc --- a/src/arch/x86/tlb.cc Wed Jun 27 19:23:02 2012 -0400 +++ b/src/arch/x86/tlb.cc Mon Jul 02 14:22:07 2012 -0400 @@ -60,17 +60,29 @@ namespace X86ISA { -TLB::TLB(const Params *p) : BaseTLB(p), configAddress(0), size(p->size), - lruSeq(0) +TLB::TLB(const Params *p) : BaseTLB(p), configAddress(0), size(p->size), numThreads(p->numThreads), lruSeq(0) { if (!size) fatal("TLBs must have a non-zero size.\n"); - tlb = new TlbEntry[size]; - std::memset(tlb, 0, sizeof(TlbEntry) * size); - for (int x = 0; x < size; x++) { - tlb[x].trieHandle = NULL; - freeList.push_back(&tlb[x]); + for (int i = 0; i < numThreads; i++) { + + TlbEntry* i_tlb = new TlbEntry[size]; + std::memset(i_tlb, 0, sizeof(TlbEntry) * size); + tlb.push_back(i_tlb); + + EntryList i_freeList; + EntryList i_entryList; + + for (int x = 0; x < size; x++) { + i_freeList.push_back(&tlb[i][x]); + } + + freeList.push_back(i_freeList); + entryList.push_back(i_entryList); + + TlbEntryTrie trie_entry; + trie.push_back(trie_entry); } walker = p->walker; @@ -78,51 +90,51 @@ } void -TLB::evictLRU() +TLB::evictLRU(ThreadID tid) { // Find the entry with the lowest (and hence least recently updated) // sequence number. unsigned lru = 0; for (unsigned i = 1; i < size; i++) { - if (tlb[i].lruSeq < tlb[lru].lruSeq) + if (tlb[tid][i].lruSeq < tlb[tid][lru].lruSeq) lru = i; } - assert(tlb[lru].trieHandle); - trie.remove(tlb[lru].trieHandle); - tlb[lru].trieHandle = NULL; - freeList.push_back(&tlb[lru]); + assert(tlb[tid][lru].trieHandle); + trie[tid].remove(tlb[tid][lru].trieHandle); + tlb[tid][lru].trieHandle = NULL; + freeList[tid].push_back(&tlb[tid][lru]); } TlbEntry * -TLB::insert(Addr vpn, TlbEntry &entry) +TLB::insert(Addr vpn, ThreadID tid, TlbEntry &entry) { // If somebody beat us to it, just use that existing entry. - TlbEntry *newEntry = trie.lookup(vpn); + TlbEntry *newEntry = trie[tid].lookup(vpn); if (newEntry) { assert(newEntry->vaddr == vpn); return newEntry; } - if (freeList.empty()) - evictLRU(); + if (freeList[tid].empty()) + evictLRU(tid); - newEntry = freeList.front(); - freeList.pop_front(); + newEntry = freeList[tid].front(); + freeList[tid].pop_front(); *newEntry = entry; newEntry->lruSeq = nextSeq(); newEntry->vaddr = vpn; newEntry->trieHandle = - trie.insert(vpn, TlbEntryTrie::MaxBits - entry.logBytes, newEntry); + trie[tid].insert(vpn, TlbEntryTrie::MaxBits - entry.logBytes, newEntry); return newEntry; } TlbEntry * -TLB::lookup(Addr va, bool update_lru) +TLB::lookup(Addr va, ThreadID tid, bool update_lru) { - TlbEntry *entry = trie.lookup(va); + TlbEntry *entry = trie[tid].lookup(va); if (entry && update_lru) entry->lruSeq = nextSeq(); return entry; @@ -132,11 +144,13 @@ TLB::invalidateAll() { DPRINTF(TLB, "Invalidating all entries.\n"); - for (unsigned i = 0; i < size; i++) { - if (tlb[i].trieHandle) { - trie.remove(tlb[i].trieHandle); - tlb[i].trieHandle = NULL; - freeList.push_back(&tlb[i]); + for (int i_t = 0; i_t < numThreads; i_t++) { + for (unsigned i = 0; i < size; i++) { + if (tlb[i_t][i].trieHandle) { + trie[i_t].remove(tlb[i_t][i].trieHandle); + tlb[i_t][i].trieHandle = NULL; + freeList[i_t].push_back(&tlb[i_t][i]); + } } } } @@ -151,11 +165,13 @@ TLB::invalidateNonGlobal() { DPRINTF(TLB, "Invalidating all non global entries.\n"); - for (unsigned i = 0; i < size; i++) { - if (tlb[i].trieHandle && !tlb[i].global) { - trie.remove(tlb[i].trieHandle); - tlb[i].trieHandle = NULL; - freeList.push_back(&tlb[i]); + for (int i_t = 0; i_t < numThreads; i_t++) { + for (unsigned i = 0; i < size; i++) { + if (tlb[i_t][i].trieHandle && !tlb[i_t][i].global) { + trie[i_t].remove(tlb[i_t][i].trieHandle); + tlb[i_t][i].trieHandle = NULL; + freeList[i_t].push_back(&tlb[i_t][i]); + } } } } @@ -163,11 +179,11 @@ void TLB::demapPage(Addr va, uint64_t asn) { - TlbEntry *entry = trie.lookup(va); + TlbEntry *entry = trie[asn].lookup(va); if (entry) { - trie.remove(entry->trieHandle); + trie[asn].remove(entry->trieHandle); entry->trieHandle = NULL; - freeList.push_back(entry); + freeList[asn].push_back(entry); } } @@ -292,7 +308,7 @@ if (m5Reg.paging) { DPRINTF(TLB, "Paging enabled.\n"); // The vaddr already has the segment base applied. - TlbEntry *entry = lookup(vaddr); + TlbEntry *entry = lookup(vaddr, tc->threadId()); if (!entry) { if (FullSystem) { Fault fault = walker->start(tc, translation, req, mode); @@ -301,7 +317,7 @@ delayedResponse = true; return fault; } - entry = lookup(vaddr); + entry = lookup(vaddr, tc->threadId()); assert(entry); } else { DPRINTF(TLB, "Handling a TLB miss for " @@ -324,7 +340,7 @@ Addr alignedVaddr = p->pTable->pageAlign(vaddr); DPRINTF(TLB, "Mapping %#x to %#x\n", alignedVaddr, newEntry.pageStart()); - entry = insert(alignedVaddr, newEntry); + entry = insert(alignedVaddr, tc->threadId(), newEntry); } DPRINTF(TLB, "Miss was serviced.\n"); } diff -r f75ee4849c40 -r 3027f0730042 src/cpu/o3/rename_map.cc --- a/src/cpu/o3/rename_map.cc Wed Jun 27 19:23:02 2012 -0400 +++ b/src/cpu/o3/rename_map.cc Mon Jul 02 14:22:07 2012 -0400 @@ -158,6 +158,7 @@ } else { // Otherwise return the zero register so nothing bad happens. renamed_reg = intZeroReg; + prev_reg = intZeroReg; } } else if (arch_reg < numLogicalRegs) { // Record the current physical register that is renamed to the