arch,cpu,dev,sim,mem: Collect System thread elements into a subclass.
authorGabe Black <gabeblack@google.com>
Thu, 6 Feb 2020 03:40:26 +0000 (19:40 -0800)
committerGabe Black <gabeblack@google.com>
Tue, 9 Jun 2020 23:37:29 +0000 (23:37 +0000)
The System class has a few different arrays of values which each
correspond to a thread of execution based on their position. This
change collects them together into a single class to make managing them
easier and less error prone. It also collects methods for manipulating
those threads as an API for that class.

This class acts as a collection point for thread based state which the
System class can look into to get at all its state. It also acts as an
interface for interacting with threads for other classes. This forces
external consumers to use the API instead of accessing the individual
arrays which improves consistency.

Change-Id: Idc4575c5a0b56fe75f5c497809ad91c22bfe26cc
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/25144
Reviewed-by: Bobby R. Bruce <bbruce@ucdavis.edu>
Maintainer: Bobby R. Bruce <bbruce@ucdavis.edu>
Tested-by: kokoro <noreply+kokoro@google.com>
50 files changed:
src/arch/arm/freebsd/fs_workload.cc
src/arch/arm/fs_workload.cc
src/arch/arm/isa.cc
src/arch/arm/isa/insts/misc.isa
src/arch/arm/kvm/gic.cc
src/arch/arm/linux/fs_workload.cc
src/arch/arm/linux/process.cc
src/arch/arm/process.cc
src/arch/arm/tlbi_op.hh
src/arch/mips/process.cc
src/arch/power/process.cc
src/arch/riscv/bare_metal/fs_workload.cc
src/arch/riscv/process.cc
src/arch/sparc/fs_workload.cc
src/arch/sparc/process.cc
src/arch/sparc/tlb.cc
src/arch/sparc/ua2005.cc
src/arch/x86/fs_workload.cc
src/arch/x86/interrupts.cc
src/arch/x86/linux/fs_workload.cc
src/arch/x86/process.cc
src/cpu/base.hh
src/cpu/intr_control.cc
src/cpu/kvm/vm.cc
src/cpu/o3/cpu.cc
src/dev/arm/a9scu.cc
src/dev/arm/fvp_base_pwr_ctrl.cc
src/dev/arm/generic_timer.cc
src/dev/arm/gic_v2.cc
src/dev/arm/gic_v2.hh
src/dev/arm/gic_v3.cc
src/dev/arm/gic_v3_cpu_interface.cc
src/dev/arm/gic_v3_distributor.cc
src/dev/arm/gic_v3_redistributor.cc
src/dev/arm/timer_cpulocal.cc
src/dev/arm/vgic.cc
src/dev/mips/malta_cchip.cc
src/dev/net/dist_iface.cc
src/dev/sparc/iob.cc
src/dev/x86/i82094aa.cc
src/kern/linux/linux.cc
src/mem/abstract_mem.cc
src/mem/cache/prefetch/queued.cc
src/sim/mem_state.cc
src/sim/process.cc
src/sim/pseudo_inst.cc
src/sim/syscall_emul.cc
src/sim/syscall_emul.hh
src/sim/system.cc
src/sim/system.hh

index d15e1a2e25d0f5d06c7574921c6fae82d7bbfe47..080dc35e9b5b301f98916805c14421fcd2c90e77 100644 (file)
@@ -113,7 +113,7 @@ FsFreebsd::initState()
     delete dtb_file;
 
     // Kernel boot requirements to set up r0, r1 and r2 in ARMv7
-    for (auto tc: system->threadContexts) {
+    for (auto *tc: system->threads) {
         tc->setIntReg(0, 0);
         tc->setIntReg(1, params()->machine_type);
         tc->setIntReg(2, params()->atags_addr + _loadAddrOffset);
index 5bd534fb480c8e8b221448eb0a1be88e536e8d06..0cafb1b70efafab0615fc732174cfdb854d46d02 100644 (file)
@@ -103,7 +103,7 @@ FsWorkload::initState()
 
     // FPEXC.EN = 0
 
-    for (auto *tc: system->threadContexts) {
+    for (auto *tc: system->threads) {
         Reset().invoke(tc);
         tc->activate();
     }
@@ -126,7 +126,7 @@ FsWorkload::initState()
         fatal_if(!arm_sys->params()->gic_cpu_addr && is_gic_v2,
                  "gic_cpu_addr must be set with bootloader");
 
-        for (auto tc: arm_sys->threadContexts) {
+        for (auto *tc: arm_sys->threads) {
             if (!arm_sys->highestELIs64())
                 tc->setIntReg(3, kernelEntry);
             if (is_gic_v2)
@@ -137,7 +137,7 @@ FsWorkload::initState()
     } else {
         // Set the initial PC to be at start of the kernel code
         if (!arm_sys->highestELIs64())
-            arm_sys->threadContexts[0]->pcState(kernelObj->entryPoint());
+            arm_sys->threads[0]->pcState(kernelObj->entryPoint());
     }
 }
 
index b18bbb05539f04060687f1e0026428f03093f2a5..b3ea91ef40cae5bd2e9de7529129251f231b123d 100644 (file)
@@ -683,7 +683,7 @@ ISA::readMiscReg(int misc_reg, ThreadContext *tc)
             // mostly unimplemented, just set NumCPUs field from sim and return
             L2CTLR l2ctlr = 0;
             // b00:1CPU to b11:4CPUs
-            l2ctlr.numCPUs = tc->getSystemPtr()->numContexts() - 1;
+            l2ctlr.numCPUs = tc->getSystemPtr()->threads.size() - 1;
             return l2ctlr;
         }
       case MISCREG_DBGDIDR:
index 88c473d6aeb0de13ff1dc2e8d8f58b5ad3bc1c28..cd44387337e01fe10d7b989eb522a3bdfdafb7ef 100644 (file)
@@ -780,8 +780,8 @@ let {{
     sevCode = '''
     SevMailbox = 1;
     System *sys = xc->tcBase()->getSystemPtr();
-    for (int x = 0; x < sys->numContexts(); x++) {
-        ThreadContext *oc = sys->getThreadContext(x);
+    for (int x = 0; x < sys->threads.size(); x++) {
+        ThreadContext *oc = sys->threads[x];
         if (oc == xc->tcBase())
             continue;
 
index 14829b3863ef605b45e289aa4965dcec1a8a682b..97f0fa383dcdc452c96b44b650ed950b0ba2bebf 100644 (file)
@@ -302,7 +302,7 @@ void
 MuxingKvmGic::copyBankedDistRange(BaseGicRegisters* from, BaseGicRegisters* to,
                                   Addr daddr, size_t size)
 {
-    for (int ctx = 0; ctx < system.numContexts(); ++ctx)
+    for (int ctx = 0; ctx < system.threads.size(); ++ctx)
         for (auto a = daddr; a < daddr + size; a += 4)
             copyDistRegister(from, to, ctx, a);
 }
@@ -311,7 +311,7 @@ void
 MuxingKvmGic::clearBankedDistRange(BaseGicRegisters* to,
                                    Addr daddr, size_t size)
 {
-    for (int ctx = 0; ctx < system.numContexts(); ++ctx)
+    for (int ctx = 0; ctx < system.threads.size(); ++ctx)
         for (auto a = daddr; a < daddr + size; a += 4)
             to->writeDistributor(ctx, a, 0xFFFFFFFF);
 }
@@ -342,7 +342,7 @@ MuxingKvmGic::copyGicState(BaseGicRegisters* from, BaseGicRegisters* to)
     // Copy CPU Interface Control Register (CTLR),
     //      Interrupt Priority Mask Register (PMR), and
     //      Binary Point Register (BPR)
-    for (int ctx = 0; ctx < system.numContexts(); ++ctx) {
+    for (int ctx = 0; ctx < system.threads.size(); ++ctx) {
         copyCpuRegister(from, to, ctx, GICC_CTLR);
         copyCpuRegister(from, to, ctx, GICC_PMR);
         copyCpuRegister(from, to, ctx, GICC_BPR);
@@ -420,7 +420,7 @@ MuxingKvmGic::fromKvmToGicV2()
     // have been shifted by three bits due to its having been emulated by
     // a VGIC with only 5 PMR bits in its VMCR register.  Presently the
     // Linux kernel does not repair this inaccuracy, so we correct it here.
-    for (int cpu = 0; cpu < system.numContexts(); ++cpu) {
+    for (int cpu = 0; cpu < system.threads.size(); ++cpu) {
        cpuPriority[cpu] <<= 3;
        assert((cpuPriority[cpu] & ~0xff) == 0);
     }
index d45c7f02cfd37f9081a164dae5042db47f98f9e2..12e3164c38a644157a37577ac84d6bdeb5aa3bcd 100644 (file)
@@ -159,7 +159,7 @@ FsLinux::initState()
     }
 
     // Kernel boot requirements to set up r0, r1 and r2 in ARMv7
-    for (auto tc: system->threadContexts) {
+    for (auto *tc: system->threads) {
         tc->setIntReg(0, 0);
         tc->setIntReg(1, params()->machine_type);
         tc->setIntReg(2, params()->atags_addr + _loadAddrOffset);
@@ -194,7 +194,7 @@ FsLinux::startup()
         std::string task_filename = "tasks.txt";
         taskFile = simout.create(name() + "." + task_filename);
 
-        for (const auto tc : system->threadContexts) {
+        for (auto *tc: system->threads) {
             uint32_t pid = tc->getCpuPtr()->getPid();
             if (pid != BaseCPU::invldPid) {
                 mapPid(tc, pid);
@@ -265,7 +265,7 @@ FsLinux::mapPid(ThreadContext *tc, uint32_t pid)
 void
 FsLinux::dumpDmesg()
 {
-    Linux::dumpDmesg(system->getThreadContext(0), std::cout);
+    Linux::dumpDmesg(system->threads[0], std::cout);
 }
 
 /**
index 4c679b3ca31be8df3d361e8d9fb7a07e106e984c..a78c8e2ac87171baf4ef659ac51780232634c7a9 100644 (file)
@@ -866,7 +866,7 @@ ArmLinuxProcess32::initState()
 {
     ArmProcess32::initState();
     allocateMem(commPage, PageBytes);
-    ThreadContext *tc = system->getThreadContext(contextIds[0]);
+    ThreadContext *tc = system->threads[contextIds[0]];
 
     uint8_t swiNeg1[] = {
         0xff, 0xff, 0xff, 0xef  // swi -1
index 93598b0b3cd66244f39c247926727599bbceaf70..c5ef141e320675a45288b745f147c1760000d4fc 100644 (file)
@@ -104,8 +104,8 @@ ArmProcess32::initState()
 {
     Process::initState();
     argsInit<uint32_t>(PageBytes, INTREG_SP);
-    for (int i = 0; i < contextIds.size(); i++) {
-        ThreadContext * tc = system->getThreadContext(contextIds[i]);
+    for (auto id: contextIds) {
+        ThreadContext *tc = system->threads[id];
         CPACR cpacr = tc->readMiscReg(MISCREG_CPACR);
         // Enable the floating point coprocessors.
         cpacr.cp10 = 0x3;
@@ -123,8 +123,8 @@ ArmProcess64::initState()
 {
     Process::initState();
     argsInit<uint64_t>(PageBytes, INTREG_SP0);
-    for (int i = 0; i < contextIds.size(); i++) {
-        ThreadContext * tc = system->getThreadContext(contextIds[i]);
+    for (auto id: contextIds) {
+        ThreadContext *tc = system->threads[id];
         CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
         cpsr.mode = MODE_EL0T;
         tc->setMiscReg(MISCREG_CPSR, cpsr);
@@ -206,7 +206,7 @@ ArmProcess64::armHwcapImpl() const
 
     uint32_t hwcap = 0;
 
-    ThreadContext *tc = system->getThreadContext(contextIds[0]);
+    ThreadContext *tc = system->threads[contextIds[0]];
 
     const AA64PFR0 pf_r0 = tc->readMiscReg(MISCREG_ID_AA64PFR0_EL1);
 
@@ -441,7 +441,7 @@ ArmProcess::argsInit(int pageSize, IntRegIndex spIndex)
 
     initVirtMem->writeBlob(argc_base, &guestArgc, intSize);
 
-    ThreadContext *tc = system->getThreadContext(contextIds[0]);
+    ThreadContext *tc = system->threads[contextIds[0]];
     //Set the stack pointer register
     tc->setIntReg(spIndex, memState->getStackMin());
     //A pointer to a function to run when the program exits. We'll set this
index 03a0a3ee9df715f2d17c2a0b07a85772f4506ab4..8706d3d7afdcdc514c13a02a2ee4c04ed4b7218c 100644 (file)
@@ -68,11 +68,8 @@ class TLBIOp
     void
     broadcast(ThreadContext *tc)
     {
-        System *sys = tc->getSystemPtr();
-        for (int x = 0; x < sys->numContexts(); x++) {
-            ThreadContext *oc = sys->getThreadContext(x);
+        for (auto *oc: tc->getSystemPtr()->threads)
             (*this)(oc);
-        }
     }
 
   protected:
index f6587ab8dde1160ad00392734052820a6185f890..cdda2b2936049b43992eac2becda8a7e4edb8d0a 100644 (file)
@@ -193,7 +193,7 @@ MipsProcess::argsInit(int pageSize)
     initVirtMem->write(auxv_array_end, zero);
     auxv_array_end += sizeof(zero);
 
-    ThreadContext *tc = system->getThreadContext(contextIds[0]);
+    ThreadContext *tc = system->threads[contextIds[0]];
 
     tc->setIntReg(FirstArgumentReg, argc);
     tc->setIntReg(FirstArgumentReg + 1, argv_array_base);
index 01a2c9faf5b6f25d7d6ca4c71be326b52c583ff5..767c3ebeff4ad55ded93b43fb8085e21abe97bdc 100644 (file)
@@ -267,7 +267,7 @@ PowerProcess::argsInit(int intSize, int pageSize)
 
     initVirtMem->writeBlob(argc_base, &guestArgc, intSize);
 
-    ThreadContext *tc = system->getThreadContext(contextIds[0]);
+    ThreadContext *tc = system->threads[contextIds[0]];
 
     //Set the stack pointer register
     tc->setIntReg(StackPointerReg, stack_min);
index 6a0c86ce6c5082fa50d7431a5193286c414568c3..9c90c681173f5b519db4380a31f851bf00df28c6 100644 (file)
@@ -54,7 +54,7 @@ BareMetal::initState()
 {
     RiscvISA::FsWorkload::initState();
 
-    for (auto *tc: system->threadContexts) {
+    for (auto *tc: system->threads) {
         RiscvISA::Reset().invoke(tc);
         tc->activate();
     }
@@ -62,7 +62,7 @@ BareMetal::initState()
     warn_if(!bootloader->buildImage().write(system->physProxy),
             "Could not load sections to memory.");
 
-    for (auto *tc: system->threadContexts) {
+    for (auto *tc: system->threads) {
         RiscvISA::Reset().invoke(tc);
         tc->activate();
     }
index 9c0540012e3f075a6e05e4a66747eb7b83b80c11..a17b5154ad9dfae3d632fd32fb72fdef69bec563 100644 (file)
@@ -99,7 +99,7 @@ RiscvProcess64::initState()
 
     argsInit<uint64_t>(PageBytes);
     for (ContextID ctx: contextIds)
-        system->getThreadContext(ctx)->setMiscRegNoEffect(MISCREG_PRV, PRV_U);
+        system->threads[ctx]->setMiscRegNoEffect(MISCREG_PRV, PRV_U);
 }
 
 void
@@ -109,10 +109,11 @@ RiscvProcess32::initState()
 
     argsInit<uint32_t>(PageBytes);
     for (ContextID ctx: contextIds) {
-        system->getThreadContext(ctx)->setMiscRegNoEffect(MISCREG_PRV, PRV_U);
-        PCState pc = system->getThreadContext(ctx)->pcState();
+        auto *tc = system->threads[ctx];
+        tc->setMiscRegNoEffect(MISCREG_PRV, PRV_U);
+        PCState pc = tc->pcState();
         pc.rv32(true);
-        system->getThreadContext(ctx)->pcState(pc);
+        tc->pcState(pc);
     }
 }
 
@@ -239,7 +240,7 @@ RiscvProcess::argsInit(int pageSize)
         pushOntoStack(aux.val);
     }
 
-    ThreadContext *tc = system->getThreadContext(contextIds[0]);
+    ThreadContext *tc = system->threads[contextIds[0]];
     tc->setIntReg(StackPointerReg, memState->getStackMin());
     tc->pcState(getStartPC());
 
index 71c3b45146c1f24e41dbf330512918e03c74c137..b812f5967490f916ef2bace6b592085f94807ebc 100644 (file)
@@ -40,11 +40,11 @@ FsWorkload::initState()
 {
     Workload::initState();
 
-    if (system->threadContexts.empty())
+    if (system->threads.empty())
         return;
 
     // Other CPUs will get activated by IPIs.
-    auto *tc = system->threadContexts[0];
+    auto *tc = system->threads[0];
     SparcISA::PowerOnReset().invoke(tc);
     tc->activate();
 }
index 3edbdf57d9a0e9c9f170e28be441c39d809596e4..ca0df08e62b6cca3f8414e496443100e7d8e3687 100644 (file)
@@ -111,7 +111,7 @@ SparcProcess::initState()
 {
     Process::initState();
 
-    ThreadContext *tc = system->getThreadContext(contextIds[0]);
+    ThreadContext *tc = system->threads[contextIds[0]];
     // From the SPARC ABI
 
     // Setup default FP state
@@ -155,7 +155,7 @@ Sparc32Process::initState()
 {
     SparcProcess::initState();
 
-    ThreadContext *tc = system->getThreadContext(contextIds[0]);
+    ThreadContext *tc = system->threads[contextIds[0]];
     // The process runs in user mode with 32 bit addresses
     PSTATE pstate = 0;
     pstate.ie = 1;
@@ -170,7 +170,7 @@ Sparc64Process::initState()
 {
     SparcProcess::initState();
 
-    ThreadContext *tc = system->getThreadContext(contextIds[0]);
+    ThreadContext *tc = system->threads[contextIds[0]];
     // The process runs in user mode
     PSTATE pstate = 0;
     pstate.ie = 1;
@@ -393,7 +393,7 @@ SparcProcess::argsInit(int pageSize)
     fillStart = memState->getStackBase();
     spillStart = fillStart + sizeof(MachInst) * numFillInsts;
 
-    ThreadContext *tc = system->getThreadContext(contextIds[0]);
+    ThreadContext *tc = system->threads[contextIds[0]];
     // Set up the thread context to start running the process
     // assert(NumArgumentRegs >= 2);
     // tc->setIntReg(ArgumentReg[0], argc);
index e67ae9aa71699a49b4f89b8881b556c4f24ea8e3..fcb09734562bb9343da0a68afcade2d78582cfc5 100644 (file)
@@ -1372,8 +1372,8 @@ TLB::doMmuRegWrite(ThreadContext *tc, Packet *pkt)
         }
         break;
       case ASI_SWVR_UDB_INTR_W:
-            tc->getSystemPtr()->threadContexts[bits(data,12,8)]->getCpuPtr()->
-            postInterrupt(0, bits(data, 5, 0), 0);
+            tc->getSystemPtr()->threads[bits(data,12,8)]->
+                getCpuPtr()->postInterrupt(0, bits(data, 5, 0), 0);
         break;
       default:
 doMmuWriteError:
index 389549b40c42ab1ed764a337a8fd83c291b7c35b..3403451b5bd42447c599a94695e0d2776238ccf7 100644 (file)
@@ -287,12 +287,12 @@ ISA::readFSReg(int miscReg, ThreadContext * tc)
         temp = readMiscRegNoEffect(miscReg) & (STS::active | STS::speculative);
         // Check that the CPU array is fully populated
         // (by calling getNumCPus())
-        assert(sys->numContexts() > tc->contextId());
+        assert(sys->threads.size() > tc->contextId());
 
         temp |= tc->contextId()  << STS::shft_id;
 
-        for (x = tc->contextId() & ~3; x < sys->threadContexts.size(); x++) {
-            switch (sys->threadContexts[x]->status()) {
+        for (x = tc->contextId() & ~3; x < sys->threads.size(); x++) {
+            switch (sys->threads[x]->status()) {
               case ThreadContext::Active:
                 temp |= STS::st_run << (STS::shft_fsm0 -
                         ((x & 0x3) * (STS::shft_fsm0-STS::shft_fsm1)));
index 3f46ebaf3618f10e5eb2bf07e3974afd6f95fc62..44c01d779f7cb8005e42e77967ec7796cbfec9e7 100644 (file)
@@ -106,7 +106,7 @@ FsWorkload::initState()
 {
     KernelWorkload::initState();
 
-    for (auto *tc: system->threadContexts) {
+    for (auto *tc: system->threads) {
         X86ISA::InitInterrupt(0).invoke(tc);
 
         if (tc->contextId() == 0) {
@@ -124,7 +124,7 @@ FsWorkload::initState()
     fatal_if(kernelObj->getArch() == Loader::I386,
              "Loading a 32 bit x86 kernel is not supported.");
 
-    ThreadContext *tc = system->threadContexts[0];
+    ThreadContext *tc = system->threads[0];
     auto phys_proxy = system->physProxy;
 
     // This is the boot strap processor (BSP). Initialize it to look like
index c2dcb32491a9b4c8cb6754efd32e18104966d148..c81cf62c5eaf18fdf2026afdfb3de0dc038984aa 100644 (file)
@@ -479,7 +479,7 @@ X86ISA::Interrupts::setReg(ApicRegIndex reg, uint32_t val)
             message.level = low.level;
             message.trigger = low.trigger;
             std::list<int> apics;
-            int numContexts = sys->numContexts();
+            int numContexts = sys->threads.size();
             switch (low.destShorthand) {
               case 0:
                 if (message.deliveryMode == DeliveryMode::LowestPriority) {
index 4f83884587f0a0d300a256772aee7f33711548c5..0303cc80039b3504cd511b6791423a9ad97dc805 100644 (file)
@@ -123,7 +123,7 @@ FsLinux::initState()
      * Pass the location of the real mode data structure to the kernel
      * using register %esi. We'll use %rsi which should be equivalent.
      */
-    system->threadContexts[0]->setIntReg(INTREG_RSI, realModeData);
+    system->threads[0]->setIntReg(INTREG_RSI, realModeData);
 }
 
 } // namespace X86ISA
index 1b7fd3e8b52d28c8707f15ce556f3874ee00c7a9..0324e9420d060c4ac6af9c87ccbdd9607c226b00 100644 (file)
@@ -303,7 +303,7 @@ X86_64Process::initState()
         tss_attr.unusable = 0;
 
         for (int i = 0; i < contextIds.size(); i++) {
-            ThreadContext * tc = system->getThreadContext(contextIds[i]);
+            ThreadContext *tc = system->threads[contextIds[i]];
 
             tc->setMiscReg(MISCREG_CS, cs);
             tc->setMiscReg(MISCREG_DS, ds);
@@ -514,7 +514,7 @@ X86_64Process::initState()
                     16 * PageBytes, false);
     } else {
         for (int i = 0; i < contextIds.size(); i++) {
-            ThreadContext * tc = system->getThreadContext(contextIds[i]);
+            ThreadContext * tc = system->threads[contextIds[i]];
 
             SegAttr dataAttr = 0;
             dataAttr.dpl = 3;
@@ -625,7 +625,7 @@ I386Process::initState()
             vsysexitBlob, sizeof(vsysexitBlob));
 
     for (int i = 0; i < contextIds.size(); i++) {
-        ThreadContext * tc = system->getThreadContext(contextIds[i]);
+        ThreadContext * tc = system->threads[contextIds[i]];
 
         SegAttr dataAttr = 0;
         dataAttr.dpl = 3;
@@ -975,7 +975,7 @@ X86Process::argsInit(int pageSize,
 
     initVirtMem->writeBlob(argc_base, &guestArgc, intSize);
 
-    ThreadContext *tc = system->getThreadContext(contextIds[0]);
+    ThreadContext *tc = system->threads[contextIds[0]];
     // Set the stack pointer register
     tc->setIntReg(StackPointerReg, stack_min);
 
index a33d1bd8fad25ea7c5010660496056886bb9c379..810f2672c08e0ee2588a1c473b747127e1fd11c0 100644 (file)
@@ -54,6 +54,7 @@
 #include "arch/isa_traits.hh"
 #include "arch/microcode_rom.hh"
 #include "base/statistics.hh"
+#include "mem/port_proxy.hh"
 #include "sim/clocked_object.hh"
 #include "sim/eventq.hh"
 #include "sim/full_system.hh"
index 9274b375d2c38543df58bde2d0cc791207a51e79..9b4a352c1f58ea8720a7414e8e5b41ecf7ea3156 100644 (file)
@@ -47,7 +47,7 @@ void
 IntrControl::post(int cpu_id, int int_num, int index)
 {
     DPRINTF(IntrControl, "post  %d:%d (cpu %d)\n", int_num, index, cpu_id);
-    ThreadContext *tc = sys->getThreadContext(cpu_id);
+    auto *tc = sys->threads[cpu_id];
     tc->getCpuPtr()->postInterrupt(tc->threadId(), int_num, index);
 }
 
@@ -55,7 +55,7 @@ void
 IntrControl::clear(int cpu_id, int int_num, int index)
 {
     DPRINTF(IntrControl, "clear %d:%d (cpu %d)\n", int_num, index, cpu_id);
-    ThreadContext *tc = sys->getThreadContext(cpu_id);
+    auto *tc = sys->threads[cpu_id];
     tc->getCpuPtr()->clearInterrupt(tc->threadId(), int_num, index);
 }
 
@@ -63,7 +63,7 @@ void
 IntrControl::clearAll(int cpu_id)
 {
     DPRINTF(IntrControl, "Clear all pending interrupts for CPU %d\n", cpu_id);
-    ThreadContext *tc = sys->getThreadContext(cpu_id);
+    auto *tc = sys->threads[cpu_id];
     tc->getCpuPtr()->clearInterrupts(tc->threadId());
 }
 
@@ -71,7 +71,7 @@ bool
 IntrControl::havePosted(int cpu_id) const
 {
     DPRINTF(IntrControl, "Check pending interrupts for CPU %d\n", cpu_id);
-    ThreadContext *tc = sys->getThreadContext(cpu_id);
+    auto *tc = sys->threads[cpu_id];
     return tc->getCpuPtr()->checkInterrupts(tc);
 }
 
index 9808d61e90cf975b34e6bb5bc49670470d126d4c..720548c8f4bf2d1930776ce74922fa4734246ac3 100644 (file)
@@ -539,7 +539,7 @@ KvmVM::contextIdToVCpuId(ContextID ctx) const
 {
     assert(system != nullptr);
     return dynamic_cast<BaseKvmCPU*>
-        (system->getThreadContext(ctx)->getCpuPtr())->getVCpuID();
+        (system->threads[ctx]->getCpuPtr())->getVCpuID();
 }
 
 int
index 5f0a98b24cedd915f3768dce74528de1e5edf08e..5230ee944ba8ef752f511e2485316dac570df08e 100644 (file)
@@ -757,7 +757,7 @@ FullO3CPU<Impl>::insertThread(ThreadID tid)
     // and not in the ThreadContext.
     ThreadContext *src_tc;
     if (FullSystem)
-        src_tc = system->threadContexts[tid];
+        src_tc = system->threads[tid];
     else
         src_tc = tcBase(tid);
 
index 629fdd922263dbd933ce34293fd7c982c6388ba6..5101682a2a71e293ec02ce38f7b880b38c915da5 100644 (file)
@@ -60,20 +60,23 @@ A9SCU::read(PacketPtr pkt)
         pkt->setLE(1); // SCU already enabled
         break;
       case Config:
-        /* Without making a completely new SCU, we can use the core count field
-         * as 4 bits and inform the OS of up to 16 CPUs.  Although the core
-         * count is technically bits [1:0] only, bits [3:2] are SBZ for future
-         * expansion like this.
-         */
-        if (sys->numContexts() > 4) {
-            warn_once("A9SCU with >4 CPUs is unsupported\n");
-            if (sys->numContexts() > 15)
-                fatal("Too many CPUs (%d) for A9SCU!\n", sys->numContexts());
+        {
+            /* Without making a completely new SCU, we can use the core count
+             * field as 4 bits and inform the OS of up to 16 CPUs.  Although
+             * the core count is technically bits [1:0] only, bits [3:2] are
+             * SBZ for future expansion like this.
+             */
+            int threads = sys->threads.size();
+            if (threads > 4) {
+                warn_once("A9SCU with >4 CPUs is unsupported");
+                fatal_if(threads > 15,
+                        "Too many CPUs (%d) for A9SCU!", threads);
+            }
+            int smp_bits, core_cnt;
+            smp_bits = (1 << threads) - 1;
+            core_cnt = threads - 1;
+            pkt->setLE(smp_bits << 4 | core_cnt);
         }
-        int smp_bits, core_cnt;
-        smp_bits = (1 << sys->numContexts()) - 1;
-        core_cnt = sys->numContexts() - 1;
-        pkt->setLE(smp_bits << 4 | core_cnt);
         break;
       default:
         // Only configuration register is implemented
index 5113c926e588d2440e4d2e0863d1cf2a683acf04..7ab4e4091cda52c35d1bb9d762988d0a2f7f876b 100644 (file)
@@ -61,8 +61,8 @@ void
 FVPBasePwrCtrl::init()
 {
     // All cores are ON by default (PwrStatus.{l0,l1} = 0b1)
-    corePwrStatus.resize(sys->numContexts(), 0x60000000);
-    for (const auto &tc : sys->threadContexts)
+    corePwrStatus.resize(sys->threads.size(), 0x60000000);
+    for (const auto &tc : sys->threads)
         poweredCoresPerCluster[tc->socketId()] += 1;
     BasicPioDevice::init();
 }
@@ -200,7 +200,7 @@ FVPBasePwrCtrl::write(PacketPtr pkt)
             regs.pcoffr = ~0;
         } else if (pwrs->l0) {
             // Power off all cores in the cluster
-            for (const auto &tco : sys->threadContexts) {
+            for (const auto &tco : sys->threads) {
                 if (tc->socketId() == tco->socketId()) {
                     PwrStatus *npwrs = getCorePwrStatus(tco);
                     // Set pending cluster power off
@@ -257,7 +257,7 @@ FVPBasePwrCtrl::getCorePwrStatus(ThreadContext *const tc)
 ThreadContext *
 FVPBasePwrCtrl::getThreadContextByMPID(uint32_t mpid) const
 {
-    for (auto &tc : sys->threadContexts) {
+    for (auto &tc : sys->threads) {
         if (mpid == ArmISA::getAffinity(&system, tc))
             return tc;
     }
@@ -274,7 +274,7 @@ FVPBasePwrCtrl::powerCoreOn(ThreadContext *const tc, PwrStatus *const pwrs)
     // Clear pending power-offs to the core
     pwrs->pp = 0;
     // Clear pending power-offs to the core's cluster
-    for (const auto &tco : sys->threadContexts) {
+    for (const auto &tco : sys->threads) {
         if (tc->socketId() == tco->socketId()) {
             PwrStatus *npwrs = getCorePwrStatus(tco);
             npwrs->pc = 0;
index 51a52c723f587be29df04862ed28f7d1474ff0e6..4f92dac876204af3e38280e93b8b435c0d73a4bf 100644 (file)
@@ -440,7 +440,7 @@ GenericTimer::createTimers(unsigned cpus)
     timers.resize(cpus);
     for (unsigned i = old_cpu_count; i < cpus; ++i) {
 
-        ThreadContext *tc = system.getThreadContext(i);
+        ThreadContext *tc = system.threads[i];
 
         timers[i].reset(
             new CoreTimers(*this, system, i,
@@ -481,7 +481,7 @@ void
 GenericTimer::setMiscReg(int reg, unsigned cpu, RegVal val)
 {
     CoreTimers &core(getTimers(cpu));
-    ThreadContext *tc = system.getThreadContext(cpu);
+    ThreadContext *tc = system.threads[cpu];
 
     switch (reg) {
       case MISCREG_CNTFRQ:
@@ -695,7 +695,7 @@ GenericTimer::CoreTimers::CoreTimers(GenericTimer &_parent,
     ArmInterruptPin *_irqVirt, ArmInterruptPin *_irqHyp)
       : parent(_parent),
         cntfrq(parent.params()->cntfrq),
-        threadContext(system.getThreadContext(cpu)),
+        threadContext(system.threads[cpu]),
         irqPhysS(_irqPhysS),
         irqPhysNS(_irqPhysNS),
         irqVirt(_irqVirt),
index c4834eccb9c6ca872d15ca31f9db5bbe26f61102..4ef15173dd474b96aa28cc3a71cb4743331f72ca 100644 (file)
@@ -263,7 +263,7 @@ GicV2::readDistributor(ContextID ctx, Addr daddr, size_t resp_sz)
         /* The 0x100 is a made-up flag to show that gem5 extensions
          * are available,
          * write 0x200 to this register to enable it.  */
-        return (((sys->numRunningContexts() - 1) << 5) |
+        return (((sys->threads.numRunning() - 1) << 5) |
                 (itLines/INT_BITS_MAX -1) |
                 (haveGem5Extensions ? 0x100 : 0x0));
       case GICD_PIDR0:
@@ -291,10 +291,9 @@ GicV2::readCpu(PacketPtr pkt)
 
     assert(pkt->req->hasContextId());
     const ContextID ctx = pkt->req->contextId();
-    assert(ctx < sys->numRunningContexts());
+    assert(ctx < sys->threads.numRunning());
 
-    DPRINTF(GIC, "gic cpu read register %#x cpu context: %d\n", daddr,
-            ctx);
+    DPRINTF(GIC, "gic cpu read register %#x cpu context: %d\n", daddr, ctx);
 
     pkt->setLE<uint32_t>(readCpu(ctx, daddr));
 
@@ -326,7 +325,7 @@ GicV2::readCpu(ContextID ctx, Addr daddr)
                     panic_if(!cpuSgiPending[active_int],
                             "Interrupt %d active but no CPU generated it?\n",
                             active_int);
-                    for (int x = 0; x < sys->numRunningContexts(); x++) {
+                    for (int x = 0; x < sys->threads.numRunning(); x++) {
                         // See which CPU generated the interrupt
                         uint8_t cpugen =
                             bits(cpuSgiPending[active_int], 7 + 8 * x, 8 * x);
@@ -660,7 +659,7 @@ GicV2::softInt(ContextID ctx, SWI swi)
           } break;
           case 1: {
              // interrupt all
-             for (int i = 0; i < sys->numContexts(); i++) {
+             for (int i = 0; i < sys->threads.size(); i++) {
                  DPRINTF(IPI, "Processing CPU %d\n", i);
                  if (!cpuEnabled(i))
                      continue;
@@ -686,7 +685,7 @@ GicV2::softInt(ContextID ctx, SWI swi)
             // interrupt all
             uint8_t cpu_list;
             cpu_list = 0;
-            for (int x = 0; x < sys->numContexts(); x++)
+            for (int x = 0; x < sys->threads.size(); x++)
                 cpu_list |= cpuEnabled(x) ? 1 << x : 0;
             swi.cpu_list = cpu_list;
             break;
@@ -699,7 +698,7 @@ GicV2::softInt(ContextID ctx, SWI swi)
 
         DPRINTF(IPI, "Generating softIRQ from CPU %d for %#x\n", ctx,
                 swi.cpu_list);
-        for (int i = 0; i < sys->numContexts(); i++) {
+        for (int i = 0; i < sys->threads.size(); i++) {
             DPRINTF(IPI, "Processing CPU %d\n", i);
             if (!cpuEnabled(i))
                 continue;
@@ -715,8 +714,7 @@ GicV2::softInt(ContextID ctx, SWI swi)
 uint64_t
 GicV2::genSwiMask(int cpu)
 {
-    if (cpu > sys->numContexts())
-        panic("Invalid CPU ID\n");
+    panic_if(cpu > sys->threads.size(), "Invalid CPU ID.");
     return ULL(0x0101010101010101) << cpu;
 }
 
@@ -734,7 +732,7 @@ GicV2::getCpuPriority(unsigned cpu)
 void
 GicV2::updateIntState(int hint)
 {
-    for (int cpu = 0; cpu < sys->numContexts(); cpu++) {
+    for (int cpu = 0; cpu < sys->threads.size(); cpu++) {
         if (!cpuEnabled(cpu))
             continue;
 
@@ -773,7 +771,7 @@ GicV2::updateIntState(int hint)
             }
         }
 
-        bool mp_sys = sys->numRunningContexts() > 1;
+        bool mp_sys = sys->threads.numRunning() > 1;
         // Check other ints
         for (int x = 0; x < (itLines/INT_BITS_MAX); x++) {
             if (getIntEnabled(cpu, x) & getPendingInt(cpu, x)) {
@@ -832,7 +830,7 @@ GicV2::updateIntState(int hint)
 void
 GicV2::updateRunPri()
 {
-    for (int cpu = 0; cpu < sys->numContexts(); cpu++) {
+    for (int cpu = 0; cpu < sys->threads.size(); cpu++) {
         if (!cpuEnabled(cpu))
             continue;
         uint8_t maxPriority = 0xff;
index 5bc74b2a4cf31a03f210cfc6591035a7f64a9a68..600f9afa80725c814ecb6d6069c9f1426738f700 100644 (file)
@@ -297,7 +297,7 @@ class GicV2 : public BaseGic, public BaseGicRegisters
     uint8_t cpuTarget[GLOBAL_INT_LINES];
 
     uint8_t getCpuTarget(ContextID ctx, uint32_t ix) {
-        assert(ctx < sys->numRunningContexts());
+        assert(ctx < sys->threads.numRunning());
         assert(ix < INT_LINES_MAX);
         if (ix < SGI_MAX + PPI_MAX) {
             // "GICD_ITARGETSR0 to GICD_ITARGETSR7 are read-only, and each
index 2103c0e6c797699dac69ba9e627853b040ec59e1..b4046017a2a84653534a691824b9c75715674287 100644 (file)
@@ -60,15 +60,15 @@ void
 Gicv3::init()
 {
     distributor = new Gicv3Distributor(this, params()->it_lines);
-    redistributors.resize(sys->numContexts(), nullptr);
-    cpuInterfaces.resize(sys->numContexts(), nullptr);
+    int threads = sys->threads.size();
+    redistributors.resize(threads, nullptr);
+    cpuInterfaces.resize(threads, nullptr);
 
-    panic_if(sys->numContexts() > params()->cpu_max,
+    panic_if(threads > params()->cpu_max,
         "Exceeding maximum number of PEs supported by GICv3: "
-        "using %u while maximum is %u\n", sys->numContexts(),
-        params()->cpu_max);
+        "using %u while maximum is %u.", threads, params()->cpu_max);
 
-    for (int i = 0; i < sys->numContexts(); i++) {
+    for (int i = 0; i < threads; i++) {
         redistributors[i] = new Gicv3Redistributor(this, i);
         cpuInterfaces[i] = new Gicv3CPUInterface(this, i);
     }
@@ -77,14 +77,13 @@ Gicv3::init()
         Gicv3Distributor::ADDR_RANGE_SIZE - 1);
 
     redistSize = redistributors[0]->addrRangeSize;
-    redistRange = RangeSize(params()->redist_addr,
-         redistSize * sys->numContexts() - 1);
+    redistRange = RangeSize(params()->redist_addr, redistSize * threads - 1);
 
     addrRanges = {distRange, redistRange};
 
     distributor->init();
 
-    for (int i = 0; i < sys->numContexts(); i++) {
+    for (int i = 0; i < threads; i++) {
         redistributors[i]->init();
         cpuInterfaces[i]->init();
     }
@@ -205,7 +204,7 @@ void
 Gicv3::postInt(uint32_t cpu, ArmISA::InterruptTypes int_type)
 {
     platform->intrctrl->post(cpu, int_type, 0);
-    ArmSystem::callClearStandByWfi(sys->getThreadContext(cpu));
+    ArmSystem::callClearStandByWfi(sys->threads[cpu]);
 }
 
 bool
index 73bd3bc6647b89413ccb5ffbee8de69cf722e06a..5e1f8719e0d744116005bc51deadf9d361ad9daa 100644 (file)
@@ -1776,7 +1776,7 @@ Gicv3CPUInterface::generateSGI(RegVal val, Gicv3::GroupId group)
 
     bool ns = !inSecureState();
 
-    for (int i = 0; i < gic->getSystem()->numContexts(); i++) {
+    for (int i = 0; i < gic->getSystem()->threads.size(); i++) {
         Gicv3Redistributor * redistributor_i =
             gic->getRedistributor(i);
         uint32_t affinity_i = redistributor_i->getAffinity();
@@ -2587,7 +2587,7 @@ Gicv3CPUInterface::clearPendingInterrupts()
 void
 Gicv3CPUInterface::assertWakeRequest()
 {
-    ThreadContext *tc = gic->getSystem()->getThreadContext(cpuId);
+    auto *tc = gic->getSystem()->threads[cpuId];
     if (ArmSystem::callSetWakeRequest(tc)) {
         Reset().invoke(tc);
         tc->activate();
@@ -2597,7 +2597,7 @@ Gicv3CPUInterface::assertWakeRequest()
 void
 Gicv3CPUInterface::deassertWakeRequest()
 {
-    ThreadContext *tc = gic->getSystem()->getThreadContext(cpuId);
+    auto *tc = gic->getSystem()->threads[cpuId];
     ArmSystem::callClearWakeRequest(tc);
 }
 
index 4ce97822c3a4ca1335cbab29c1b17ea15722d906..485ba7284dab442a45c3d4131c87c19982fdac52 100644 (file)
@@ -1021,7 +1021,7 @@ Gicv3Distributor::route(uint32_t int_id)
 
     if (affinity_routing.IRM) {
         // Interrupts routed to any PE defined as a participating node
-        for (int i = 0; i < gic->getSystem()->numContexts(); i++) {
+        for (int i = 0; i < gic->getSystem()->threads.size(); i++) {
             Gicv3Redistributor * redistributor_i =
                 gic->getRedistributor(i);
 
@@ -1086,7 +1086,7 @@ Gicv3Distributor::update()
     }
 
     // Update all redistributors
-    for (int i = 0; i < gic->getSystem()->numContexts(); i++) {
+    for (int i = 0; i < gic->getSystem()->threads.size(); i++) {
         gic->getRedistributor(i)->update();
     }
 }
index 7408949470b4fc13ae5075d795dcee9d95dfc456..5fceed573eeeee4fe909e52b85636f1b6bae97dd 100644 (file)
@@ -158,7 +158,7 @@ Gicv3Redistributor::read(Addr addr, size_t size, bool is_secure_access)
            * (physical LPIs supported)
            */
           uint64_t affinity = getAffinity();
-          int last = cpuId == (gic->getSystem()->numContexts() - 1);
+          int last = cpuId == (gic->getSystem()->threads.size() - 1);
           return (affinity << 32) | (1 << 24) | (cpuId << 8) |
               (1 << 5) | (last << 4) | (1 << 3) | (1 << 0);
       }
@@ -990,7 +990,7 @@ Gicv3Redistributor::deactivateIRQ(uint32_t int_id)
 uint32_t
 Gicv3Redistributor::getAffinity() const
 {
-    ThreadContext * tc = gic->getSystem()->getThreadContext(cpuId);
+    ThreadContext *tc = gic->getSystem()->threads[cpuId];
     uint64_t mpidr = getMPIDR(gic->getSystem(), tc);
     /*
      * Aff3 = MPIDR[39:32]
index 41cdbc387382e6578f00e18c5ba04ef4f0803f42..5ba0b16baf3466450072dfbfffbd01f0457f0cf6 100644 (file)
@@ -56,8 +56,8 @@ CpuLocalTimer::init()
 {
    auto p = params();
    // Initialize the timer registers for each per cpu timer
-   for (int i = 0; i < sys->numContexts(); i++) {
-        ThreadContext* tc = sys->getThreadContext(i);
+   for (int i = 0; i < sys->threads.size(); i++) {
+        ThreadContext* tc = sys->threads[i];
         std::stringstream oss;
         oss << name() << ".timer" << i;
 
@@ -429,14 +429,14 @@ CpuLocalTimer::Timer::unserialize(CheckpointIn &cp)
 void
 CpuLocalTimer::serialize(CheckpointOut &cp) const
 {
-    for (int i = 0; i < sys->numContexts(); i++)
+    for (int i = 0; i < sys->threads.size(); i++)
         localTimer[i]->serializeSection(cp, csprintf("timer%d", i));
 }
 
 void
 CpuLocalTimer::unserialize(CheckpointIn &cp)
 {
-    for (int i = 0; i < sys->numContexts(); i++)
+    for (int i = 0; i < sys->threads.size(); i++)
         localTimer[i]->unserializeSection(cp, csprintf("timer%d", i));
 }
 
index 0bb1fef38e9ced2fe9af91cca8dbd29e55c83cd0..5ac597ba855ba3b3f6edb29338f36636c7390d65 100644 (file)
@@ -56,7 +56,7 @@ VGic::VGic(const Params *p)
         maintIntPosted[x] = false;
         vIntPosted[x] = false;
     }
-    assert(sys->numRunningContexts() <= VGIC_CPU_MAX);
+    assert(sys->threads.numRunning() <= VGIC_CPU_MAX);
 }
 
 VGic::~VGic()
@@ -414,8 +414,8 @@ VGic::updateIntState(ContextID ctx_id)
         }
     }
 
-    assert(sys->numRunningContexts() <= VGIC_CPU_MAX);
-    for (int i = 0; i < sys->numRunningContexts(); i++) {
+    assert(sys->threads.numRunning() <= VGIC_CPU_MAX);
+    for (int i = 0; i < sys->threads.numRunning(); i++) {
         struct vcpuIntData *vid = &vcpuData[i];
         // Are any LRs active that weren't before?
         if (!vIntPosted[i]) {
index 001202eac40af1a0e37f60bdc53c33e6808ec7cc..c8fe7a8400685d7247abdcf41f90379c4cfc8749 100644 (file)
@@ -102,7 +102,7 @@ MaltaCChip::postRTC()
 void
 MaltaCChip::postIntr(uint32_t interrupt)
 {
-    uint64_t size = sys->threadContexts.size();
+    uint64_t size = sys->threads.size();
     assert(size <= Malta::Max_CPUs);
 
     for (int i=0; i < size; i++) {
@@ -117,7 +117,7 @@ MaltaCChip::postIntr(uint32_t interrupt)
 void
 MaltaCChip::clearIntr(uint32_t interrupt)
 {
-    uint64_t size = sys->threadContexts.size();
+    uint64_t size = sys->threads.size();
     assert(size <= Malta::Max_CPUs);
 
     for (int i=0; i < size; i++) {
index 46933507c92e498117c393ca7ccbf9fcae929356..cc408e0c1c22e20641a0c214cdc448fbcc4421eb 100644 (file)
@@ -410,9 +410,7 @@ DistIface::SyncEvent::process()
             start();
         } else {
             // Wake up thread contexts on non-switch nodes.
-            for (int i = 0; i < DistIface::master->sys->numContexts(); i++) {
-                ThreadContext *tc =
-                    DistIface::master->sys->getThreadContext(i);
+            for (auto *tc: master->sys->threads) {
                 if (tc->status() == ThreadContext::Suspended)
                     tc->activate();
                 else
@@ -868,8 +866,7 @@ DistIface::toggleSync(ThreadContext *tc)
         // Dist-gem5 will reactivate all thread contexts when everyone has
         // reached the sync stop point.
 #if THE_ISA != NULL_ISA
-        for (int i = 0; i < master->sys->numContexts(); i++) {
-            ThreadContext *tc = master->sys->getThreadContext(i);
+        for (auto *tc: master->sys->threads) {
             if (tc->status() == ThreadContext::Active)
                 tc->quiesce();
         }
@@ -883,8 +880,7 @@ DistIface::toggleSync(ThreadContext *tc)
         // activation here, since we know exactly when the next sync will
         // occur.
 #if THE_ISA != NULL_ISA
-        for (int i = 0; i < master->sys->numContexts(); i++) {
-            ThreadContext *tc = master->sys->getThreadContext(i);
+        for (auto *tc: master->sys->threads) {
             if (tc->status() == ThreadContext::Active)
                 tc->quiesceTick(master->syncEvent->when() + 1);
         }
index 347872ee62ccc8e7920b31bde53cf04d9b85a1b5..44e7dc8679da9b60b5336c6fc551bf39e007faf8 100644 (file)
@@ -58,7 +58,7 @@ Iob::Iob(const Params *p)
     iobManSize = ULL(0x0100000000);
     iobJBusAddr = ULL(0x9F00000000);
     iobJBusSize = ULL(0x0100000000);
-    assert (params()->system->threadContexts.size() <= MaxNiagaraProcs);
+    assert(params()->system->threads.size() <= MaxNiagaraProcs);
 
     pioDelay = p->pio_latency;
 
@@ -276,7 +276,7 @@ void
 Iob::generateIpi(Type type, int cpu_id, int vector)
 {
     SparcISA::SparcFault<SparcISA::PowerOnReset> *por = new SparcISA::PowerOnReset();
-    if (cpu_id >= sys->numContexts())
+    if (cpu_id >= sys->threads.size())
         return;
 
     switch (type) {
@@ -289,16 +289,16 @@ Iob::generateIpi(Type type, int cpu_id, int vector)
         warn("Sending reset to CPU: %d\n", cpu_id);
         if (vector != por->trapType())
             panic("Don't know how to set non-POR reset to cpu\n");
-        por->invoke(sys->threadContexts[cpu_id]);
-        sys->threadContexts[cpu_id]->activate();
+        por->invoke(sys->threads[cpu_id]);
+        sys->threads[cpu_id]->activate();
         break;
       case 2: // idle -- this means stop executing and don't wake on interrupts
         DPRINTF(Iob, "Idling CPU because of I/O write cpu: %d\n", cpu_id);
-        sys->threadContexts[cpu_id]->halt();
+        sys->threads[cpu_id]->halt();
         break;
       case 3: // resume
         DPRINTF(Iob, "Resuming CPU because of I/O write cpu: %d\n", cpu_id);
-        sys->threadContexts[cpu_id]->activate();
+        sys->threads[cpu_id]->activate();
         break;
       default:
         panic("Invalid type to generate ipi\n");
index cc51d5c70eeedb804a13c480d826eb3355308a24..8d91cc61ab546c392b80fc87ba631184b240bbd5 100644 (file)
@@ -198,7 +198,7 @@ X86ISA::I82094AA::signalInterrupt(int line)
         message.level = entry.polarity;
         message.trigger = entry.trigger;
         std::list<int> apics;
-        int numContexts = sys->numContexts();
+        int numContexts = sys->threads.size();
         if (message.destMode == 0) {
             if (message.deliveryMode == DeliveryMode::LowestPriority) {
                 panic("Lowest priority delivery mode from the "
@@ -214,7 +214,7 @@ X86ISA::I82094AA::signalInterrupt(int line)
             }
         } else {
             for (int i = 0; i < numContexts; i++) {
-                BaseInterrupts *base_int = sys->getThreadContext(i)->
+                BaseInterrupts *base_int = sys->threads[i]->
                     getCpuPtr()->getInterruptController(0);
                 auto *localApic = dynamic_cast<Interrupts *>(base_int);
                 if ((localApic->readReg(APIC_LOGICAL_DESTINATION) >> 24) &
index ae1d47c3f652c62790ec1292831b1258d67461d5..c27d0533841c802252a4d59a73e8d240bb8bb11b 100644 (file)
@@ -110,8 +110,7 @@ Linux::procSelfMaps(Process *process, ThreadContext *tc)
 std::string
 Linux::cpuOnline(Process *process, ThreadContext *tc)
 {
-    return csprintf("0-%d\n",
-                    tc->getSystemPtr()->numContexts() - 1);
+    return csprintf("0-%d\n", tc->getSystemPtr()->threads.size() - 1);
 }
 
 std::string
index 70d4626159ed65c3dfe006745f77bfaee95cc954..2f72ebef0a22626ea76c4297542f8c6449b964e2 100644 (file)
@@ -328,7 +328,7 @@ AbstractMemory::checkLockedAddrList(PacketPtr pkt)
                                            req->contextId() :
                                            InvalidContextID;
                 if (owner_cid != requester_cid) {
-                    ThreadContext* ctx = system()->getThreadContext(owner_cid);
+                    ThreadContext* ctx = system()->threads[owner_cid];
                     TheISA::globalClearExclusive(ctx);
                 }
                 i = lockedAddrList.erase(i);
index e6d2b7cd8b134cda1731c9e55b59e87888797832..c2ae090d37c142a58c2c9abc969a7107d40ec7fd 100644 (file)
@@ -439,7 +439,7 @@ Queued::insert(const PacketPtr &pkt, PrefetchInfo &new_pfi,
     } else {
         // Add the translation request and try to resolve it later
         dpp.setTranslationRequest(translation_req);
-        dpp.tc = cache->system->getThreadContext(translation_req->contextId());
+        dpp.tc = cache->system->threads[translation_req->contextId()];
         DPRINTF(HWPrefetch, "Prefetch queued with no translation. "
                 "addr:%#x priority: %3d\n", new_pfi.getAddr(), priority);
         addToQueue(pfqMissingTranslation, dpp);
index f998fffe9a24eaa693b4ed6c25caa8489e672ffd..bfee9dab53fd82799ddde680c65b69ea7b66184c 100644 (file)
@@ -256,7 +256,7 @@ MemState::unmapRegion(Addr start_addr, Addr length)
      * There is currently no general method across all TLB implementations
      * that can flush just part of the address space.
      */
-    for (auto tc : _ownerProcess->system->threadContexts) {
+    for (auto *tc: _ownerProcess->system->threads) {
         tc->getDTBPtr()->flushAll();
         tc->getITBPtr()->flushAll();
     }
@@ -358,7 +358,7 @@ MemState::remapRegion(Addr start_addr, Addr new_start_addr, Addr length)
      * There is currently no general method across all TLB implementations
      * that can flush just part of the address space.
      */
-    for (auto tc : _ownerProcess->system->threadContexts) {
+    for (auto *tc: _ownerProcess->system->threads) {
         tc->getDTBPtr()->flushAll();
         tc->getITBPtr()->flushAll();
     }
@@ -405,8 +405,7 @@ MemState::fixupFault(Addr vaddr)
                  * ThreadContexts associated with this process.
                  */
                 for (auto &cid : _ownerProcess->contextIds) {
-                    ThreadContext *tc =
-                        _ownerProcess->system->getThreadContext(cid);
+                    auto *tc = _ownerProcess->system->threads[cid];
                     SETranslatingPortProxy
                         virt_mem(tc, SETranslatingPortProxy::Always);
                     vma.fillMemPages(vpage_start, _pageBytes, virt_mem);
index 3fab8536d7b48571106dbfaa30b75084570ca5cb..28c0b542ea976d2f968aef705add133da625343c 100644 (file)
@@ -293,7 +293,7 @@ Process::initState()
         fatal("Process %s is not associated with any HW contexts!\n", name());
 
     // first thread context for this process... initialize & enable
-    ThreadContext *tc = system->getThreadContext(contextIds[0]);
+    ThreadContext *tc = system->threads[contextIds[0]];
 
     // mark this context as active so it will start ticking.
     tc->activate();
index 2d87b059515516dfbb14251c69f0badb1fa9975d..41201eae7c5cb6d5fceba69e93d1adbedde69709 100644 (file)
@@ -170,13 +170,13 @@ wakeCPU(ThreadContext *tc, uint64_t cpuid)
     DPRINTF(PseudoInst, "PseudoInst::wakeCPU(%i)\n", cpuid);
     System *sys = tc->getSystemPtr();
 
-    if (sys->numContexts() <= cpuid) {
+    if (sys->threads.size() <= cpuid) {
         warn("PseudoInst::wakeCPU(%i), cpuid greater than number of contexts"
-             "(%i)\n",cpuid, sys->numContexts());
+             "(%i)\n", cpuid, sys->threads.size());
         return;
     }
 
-    ThreadContext *other_tc = sys->threadContexts[cpuid];
+    ThreadContext *other_tc = sys->threads[cpuid];
     if (other_tc->status() == ThreadContext::Suspended)
         other_tc->activate();
 }
index 6d39823b4257738685f6508eb826311e78d3787a..4a41609638060e41b87ff7a80b5a49f8556dac48 100644 (file)
@@ -119,9 +119,9 @@ exitImpl(SyscallDesc *desc, ThreadContext *tc, bool group, int status)
 
     bool last_thread = true;
     Process *parent = nullptr, *tg_lead = nullptr;
-    for (int i = 0; last_thread && i < sys->numContexts(); i++) {
+    for (int i = 0; last_thread && i < sys->threads.size(); i++) {
         Process *walk;
-        if (!(walk = sys->threadContexts[i]->getProcessPtr()))
+        if (!(walk = sys->threads[i]->getProcessPtr()))
             continue;
 
         /**
@@ -133,8 +133,9 @@ exitImpl(SyscallDesc *desc, ThreadContext *tc, bool group, int status)
         if (walk->pid() == p->tgid())
             tg_lead = walk;
 
-        if ((sys->threadContexts[i]->status() != ThreadContext::Halted) &&
-            (sys->threadContexts[i]->status() != ThreadContext::Halting) &&
+        auto *tc = sys->threads[i];
+        if ((tc->status() != ThreadContext::Halted) &&
+            (tc->status() != ThreadContext::Halting) &&
             (walk != p)) {
             /**
              * Check if we share thread group with the pointer; this denotes
@@ -156,7 +157,7 @@ exitImpl(SyscallDesc *desc, ThreadContext *tc, bool group, int status)
                  * all threads in the group.
                  */
                 if (*(p->exitGroup)) {
-                    sys->threadContexts[i]->halt();
+                    tc->halt();
                 } else {
                     last_thread = false;
                 }
@@ -201,7 +202,7 @@ exitImpl(SyscallDesc *desc, ThreadContext *tc, bool group, int status)
      */
     int activeContexts = 0;
     for (auto &system: sys->systemList)
-        activeContexts += system->numRunningContexts();
+        activeContexts += system->threads.numRunning();
 
     if (activeContexts == 0) {
         /**
@@ -905,9 +906,9 @@ setpgidFunc(SyscallDesc *desc, ThreadContext *tc, int pid, int pgid)
     System *sysh = tc->getSystemPtr();
 
     // Retrieves process pointer from active/suspended thread contexts.
-    for (int i = 0; i < sysh->numContexts(); i++) {
-        if (sysh->threadContexts[i]->status() != ThreadContext::Halted) {
-            Process *temp_h = sysh->threadContexts[i]->getProcessPtr();
+    for (auto *tc: sysh->threads) {
+        if (tc->status() != ThreadContext::Halted) {
+            Process *temp_h = tc->getProcessPtr();
             Process *walk_ph = (Process*)temp_h;
 
             if (walk_ph && walk_ph->pid() == process->pid())
index f2cc22c2ac83d4605b857293f464783e69e8ea39..aa81e14b3537854260966f883117b22b36f40656 100644 (file)
@@ -1440,7 +1440,7 @@ cloneFunc(SyscallDesc *desc, ThreadContext *tc, RegVal flags, RegVal newStack,
         return -EINVAL;
 
     ThreadContext *ctc;
-    if (!(ctc = tc->getSystemPtr()->findFreeContext())) {
+    if (!(ctc = tc->getSystemPtr()->threads.findFree())) {
         DPRINTF_SYSCALL(Verbose, "clone: no spare thread context in system"
                         "[cpu %d, thread %d]", tc->cpuId(), tc->threadId());
         return -EAGAIN;
@@ -1861,7 +1861,7 @@ getrlimitFunc(SyscallDesc *desc, ThreadContext *tc,
         break;
 
       case OS::TGT_RLIMIT_NPROC:
-        rlp->rlim_cur = rlp->rlim_max = tc->getSystemPtr()->numContexts();
+        rlp->rlim_cur = rlp->rlim_max = tc->getSystemPtr()->threads.size();
         rlp->rlim_cur = htog(rlp->rlim_cur, bo);
         rlp->rlim_max = htog(rlp->rlim_max, bo);
         break;
@@ -2198,8 +2198,8 @@ tgkillFunc(SyscallDesc *desc, ThreadContext *tc, int tgid, int tid, int sig)
 
     System *sys = tc->getSystemPtr();
     Process *tgt_proc = nullptr;
-    for (int i = 0; i < sys->numContexts(); i++) {
-        Process *temp = sys->threadContexts[i]->getProcessPtr();
+    for (auto *tc: sys->threads) {
+        Process *temp = tc->getProcessPtr();
         if (temp->pid() == tid) {
             tgt_proc = temp;
             break;
index 0bae99aeb1f1ea6e413e67366404f2f5ed278e08..557ad7dc6eafe8c54f41e901456494da3a565c27 100644 (file)
@@ -57,6 +57,7 @@
 #include "cpu/base.hh"
 #include "cpu/thread_context.hh"
 #include "debug/Loader.hh"
+#include "debug/Quiesce.hh"
 #include "debug/WorkItems.hh"
 #include "mem/abstract_mem.hh"
 #include "mem/physical.hh"
@@ -80,6 +81,68 @@ using namespace TheISA;
 
 vector<System *> System::systemList;
 
+ContextID
+System::Threads::insert(ThreadContext *tc, ContextID id)
+{
+    if (id == InvalidContextID) {
+        for (id = 0; id < size(); id++) {
+            if (!threads[id].context)
+                break;
+        }
+    }
+
+    if (id >= size())
+        threads.resize(id + 1);
+
+    fatal_if(threads[id].context,
+            "Cannot have two thread contexts with the same id (%d).", id);
+
+    auto &t = thread(id);
+    t.context = tc;
+#   if THE_ISA != NULL_ISA
+    int port = getRemoteGDBPort();
+    if (port) {
+        t.gdb = new RemoteGDB(tc->getSystemPtr(), tc, port + id);
+        t.gdb->listen();
+    }
+#   endif
+
+    return id;
+}
+
+void
+System::Threads::replace(ThreadContext *tc, ContextID id)
+{
+    auto &t = thread(id);
+    t.context = tc;
+    if (t.gdb)
+        t.gdb->replaceThreadContext(tc);
+}
+
+ThreadContext *
+System::Threads::findFree()
+{
+    for (auto &thread: threads) {
+        if (thread.context->status() == ThreadContext::Halted)
+            return thread.context;
+    }
+    return nullptr;
+}
+
+int
+System::Threads::numRunning() const
+{
+    int count = 0;
+    for (auto &thread: threads) {
+        auto status = thread.context->status();
+        if (status != ThreadContext::Halted &&
+                status != ThreadContext::Halting) {
+            count++;
+        }
+    }
+    return count;
+}
+
 int System::numSystemsRunning = 0;
 
 System::System(Params *p)
@@ -164,18 +227,13 @@ System::startup()
     // Now that we're about to start simulation, wait for GDB connections if
     // requested.
 #if THE_ISA != NULL_ISA
-    for (auto *tc: threadContexts) {
-        auto *cpu = tc->getCpuPtr();
-        auto id = tc->contextId();
-        if (remoteGDB.size() <= id)
-            continue;
-        auto *rgdb = remoteGDB[id];
-
-        if (cpu->waitForRemoteGDB()) {
-            inform("%s: Waiting for a remote GDB connection on port %d.\n",
-                   cpu->name(), rgdb->port());
-
-            rgdb->connect();
+    for (int i = 0; i < threads.size(); i++) {
+        auto *gdb = threads.thread(i).gdb;
+        auto *cpu = threads[i]->getCpuPtr();
+        if (gdb && cpu->waitForRemoteGDB()) {
+            inform("%s: Waiting for a remote GDB connection on port %d.",
+                   cpu->name(), gdb->port());
+            gdb->connect();
         }
     }
 #endif
@@ -197,66 +255,31 @@ System::setMemoryMode(Enums::MemoryMode mode)
 
 bool System::breakpoint()
 {
-    if (remoteGDB.size())
-        return remoteGDB[0]->breakpoint();
-    return false;
+    if (!threads.size())
+        return false;
+    auto *gdb = threads.thread(0).gdb;
+    if (!gdb)
+        return false;
+    return gdb->breakpoint();
 }
 
 ContextID
 System::registerThreadContext(ThreadContext *tc, ContextID assigned)
 {
-    int id = assigned;
-    if (id == InvalidContextID) {
-        // Find an unused context ID for this thread.
-        id = 0;
-        while (id < threadContexts.size() && threadContexts[id])
-            id++;
-    }
-
-    if (threadContexts.size() <= id)
-        threadContexts.resize(id + 1);
+    ContextID id = threads.insert(tc, assigned);
 
-    fatal_if(threadContexts[id],
-             "Cannot have two CPUs with the same id (%d)\n", id);
-
-    threadContexts[id] = tc;
     for (auto *e: liveEvents)
         tc->schedule(e);
 
-#if THE_ISA != NULL_ISA
-    int port = getRemoteGDBPort();
-    if (port) {
-        RemoteGDB *rgdb = new RemoteGDB(this, tc, port + id);
-        rgdb->listen();
-
-        if (remoteGDB.size() <= id)
-            remoteGDB.resize(id + 1);
-
-        remoteGDB[id] = rgdb;
-    }
-#endif
-
-    activeCpus.push_back(false);
-
     return id;
 }
 
-ThreadContext *
-System::findFreeContext()
-{
-    for (auto &it : threadContexts) {
-        if (ThreadContext::Halted == it->status())
-            return it;
-    }
-    return nullptr;
-}
-
 bool
 System::schedule(PCEvent *event)
 {
     bool all = true;
     liveEvents.push_back(event);
-    for (auto *tc: threadContexts)
+    for (auto *tc: threads)
         all = tc->schedule(event) && all;
     return all;
 }
@@ -266,53 +289,35 @@ System::remove(PCEvent *event)
 {
     bool all = true;
     liveEvents.remove(event);
-    for (auto *tc: threadContexts)
+    for (auto *tc: threads)
         all = tc->remove(event) && all;
     return all;
 }
 
-int
-System::numRunningContexts()
-{
-    return std::count_if(
-        threadContexts.cbegin(),
-        threadContexts.cend(),
-        [] (ThreadContext* tc) {
-            return ((tc->status() != ThreadContext::Halted) &&
-                    (tc->status() != ThreadContext::Halting));
-        }
-    );
-}
-
 void
 System::replaceThreadContext(ThreadContext *tc, ContextID context_id)
 {
-    if (context_id >= threadContexts.size()) {
-        panic("replaceThreadContext: bad id, %d >= %d\n",
-              context_id, threadContexts.size());
-    }
+    auto *otc = threads[context_id];
+    threads.replace(tc, context_id);
 
     for (auto *e: liveEvents) {
-        threadContexts[context_id]->remove(e);
+        otc->remove(e);
         tc->schedule(e);
     }
-    threadContexts[context_id] = tc;
-    if (context_id < remoteGDB.size())
-        remoteGDB[context_id]->replaceThreadContext(tc);
 }
 
 bool
 System::validKvmEnvironment() const
 {
 #if USE_KVM
-    if (threadContexts.empty())
+    if (threads.empty())
         return false;
 
-    for (auto tc : threadContexts) {
-        if (dynamic_cast<BaseKvmCPU*>(tc->getCpuPtr()) == nullptr) {
+    for (auto *tc: threads) {
+        if (!dynamic_cast<BaseKvmCPU *>(tc->getCpuPtr()))
             return false;
-        }
     }
+
     return true;
 #else
     return false;
index fa59765ba9782a139b70cc29a6538c74f213be2b..530c5ea06d67c63db1a48561bdb3cb1366caea4c 100644 (file)
@@ -52,6 +52,7 @@
 #include "base/loader/symtab.hh"
 #include "base/statistics.hh"
 #include "config/the_isa.hh"
+#include "cpu/base.hh"
 #include "cpu/pc_event.hh"
 #include "enums/MemoryMode.hh"
 #include "mem/mem_master.hh"
@@ -99,6 +100,123 @@ class System : public SimObject, public PCEventScope
 
   public:
 
+    class Threads
+    {
+      private:
+        struct Thread
+        {
+            ThreadContext *context = nullptr;
+            bool active = false;
+            BaseRemoteGDB *gdb = nullptr;
+        };
+
+        std::vector<Thread> threads;
+
+        Thread &
+        thread(ContextID id)
+        {
+            assert(id < size());
+            return threads[id];
+        }
+
+        const Thread &
+        thread(ContextID id) const
+        {
+            assert(id < size());
+            return threads[id];
+        }
+
+        ContextID insert(ThreadContext *tc, ContextID id=InvalidContextID);
+        void replace(ThreadContext *tc, ContextID id);
+
+        friend class System;
+
+      public:
+        class const_iterator
+        {
+          private:
+            const Threads &threads;
+            int pos;
+
+            friend class Threads;
+
+            const_iterator(const Threads &_threads, int _pos) :
+                threads(_threads), pos(_pos)
+            {}
+
+          public:
+            const_iterator(const const_iterator &) = default;
+            const_iterator &operator = (const const_iterator &) = default;
+
+            using iterator_category = std::forward_iterator_tag;
+            using value_type = ThreadContext *;
+            using difference_type = int;
+            using pointer = const value_type *;
+            using reference = const value_type &;
+
+            const_iterator &
+            operator ++ ()
+            {
+                pos++;
+                return *this;
+            }
+
+            const_iterator
+            operator ++ (int)
+            {
+                return const_iterator(threads, pos++);
+            }
+
+            reference operator * () { return threads.thread(pos).context; }
+            pointer operator -> () { return &threads.thread(pos).context; }
+
+            bool
+            operator == (const const_iterator &other) const
+            {
+                return &threads == &other.threads && pos == other.pos;
+            }
+
+            bool
+            operator != (const const_iterator &other) const
+            {
+                return !(*this == other);
+            }
+        };
+
+        ThreadContext *findFree();
+
+        ThreadContext *
+        operator [](ContextID id) const
+        {
+            return thread(id).context;
+        }
+
+        void markActive(ContextID id) { thread(id).active = true; }
+
+        int size() const { return threads.size(); }
+        bool empty() const { return threads.empty(); }
+        int numRunning() const;
+        int
+        numActive() const
+        {
+            int count = 0;
+            for (auto &thread: threads) {
+                if (thread.active)
+                    count++;
+            }
+            return count;
+        }
+
+        void resume(ContextID id, Tick when);
+
+        const_iterator begin() const { return const_iterator(*this, 0); }
+        const_iterator end() const { return const_iterator(*this, size()); }
+    };
+
+    /**
+     * After all objects have been created and all ports are
+     * connected, check that the system port is connected.
+     */
     void init() override;
     void startup() override;
 
@@ -179,14 +297,7 @@ class System : public SimObject, public PCEventScope
      */
     unsigned int cacheLineSize() const { return _cacheLineSize; }
 
-    std::vector<ThreadContext *> threadContexts;
-    ThreadContext *findFreeContext();
-
-    ThreadContext *
-    getThreadContext(ContextID tid) const
-    {
-        return threadContexts[tid];
-    }
+    Threads threads;
 
     const bool multiThread;
 
@@ -195,12 +306,6 @@ class System : public SimObject, public PCEventScope
     bool schedule(PCEvent *event) override;
     bool remove(PCEvent *event) override;
 
-    unsigned numContexts() const { return threadContexts.size(); }
-
-    /** Return number of running (non-halted) thread contexts in
-     * system.  These threads could be Active or Suspended. */
-    int numRunningContexts();
-
     Addr pagePtr;
 
     uint64_t init_param;
@@ -288,7 +393,6 @@ class System : public SimObject, public PCEventScope
     uint64_t workItemsBegin;
     uint64_t workItemsEnd;
     uint32_t numWorkIds;
-    std::vector<bool> activeCpus;
 
     /** This array is a per-system list of all devices capable of issuing a
      * memory system request and an associated string for each master id.
@@ -415,14 +519,8 @@ class System : public SimObject, public PCEventScope
     int
     markWorkItem(int index)
     {
-        int count = 0;
-        assert(index < activeCpus.size());
-        activeCpus[index] = true;
-        for (std::vector<bool>::iterator i = activeCpus.begin();
-             i < activeCpus.end(); i++) {
-            if (*i) count++;
-        }
-        return count;
+        threads.markActive(index);
+        return threads.numActive();
     }
 
     inline void workItemBegin(uint32_t tid, uint32_t workid)
@@ -467,8 +565,8 @@ class System : public SimObject, public PCEventScope
     /// @return Starting address of first page
     Addr allocPhysPages(int npages);
 
-    ContextID registerThreadContext(ThreadContext *tc,
-                                    ContextID assigned = InvalidContextID);
+    ContextID registerThreadContext(
+            ThreadContext *tc, ContextID assigned=InvalidContextID);
     void replaceThreadContext(ThreadContext *tc, ContextID context_id);
 
     void serialize(CheckpointOut &cp) const override;