9.3 CPU Instantiation and Identity

<< Click to Display Table of Contents >>

Navigation:  ASA-EMulatR Reference Guide > Introduction > Architecture Overview > Chapter 9 - SMP Architecture >

9.3 CPU Instantiation and Identity

9.3.1 ExecutionCoordinator

 

CPUs are created and managed by the ExecutionCoordinator (ExecutionCoordinator.h, 416 lines). This is the central SMP management class, responsible for instantiating AlphaCPU objects, assigning CPU identifiers, starting and stopping per-CPU run loops via QThread workers, and coordinating shutdown, reset, and global barriers.

 

The ExecutionCoordinator owns or provides access to all SMP subsystems:

m_cpuCount (quint16) — runtime-configured CPU count

m_cboxes (array<unique_ptr<CBox>, MAX_CPUS>) — per-CPU CBox instances (sparse array)

m_workers (array<CPUWorker, MAX_CPUS>) — per-CPU thread + AlphaCPU pairs

m_cpuStateManager (CPUStateManager) — per-CPU execution state tracking

m_reservationManager (ReservationManager) — global LL/SC reservation tracking

global_IPIManager() — IPI message routing (singleton)

global_MemoryBarrierCoordinator() — global barrier synchronization (singleton)

 

The maximum CPU count is statically bounded at MAX_CPUS (64). The active CPU count is runtime-configured and tracked via getActiveCPUCount(), which counts non-halted CPUs.

 


 

9.3.2 CPUWorker and Threading Model

 

Each CPU runs in its own QThread. The CPUWorker struct pairs a thread with its AlphaCPU instance:

 

struct CPUWorker {

 std::unique_ptr<QThread> thread;

 std::unique_ptr<AlphaCPU> alphaCPU;

};

 

The ExecutionCoordinator manages the lifecycle: createWorkers() instantiates threads, start()/pause()/stop()/reset() control system-wide execution, and per-CPU control is available via pauseCPU()/resumeCPU()/stopCPU(). Qt signals (systemStarted, systemPaused, systemStopped, cpuHalted, cpuError) provide event notification.

 


 

9.3.3 CPU Identity

 

Each CPU has a unique CPUIdType identifier (quint16), assigned at creation and carried through all subsystems. CPU identity is never inferred — it is explicit in every API call (CBox::m_cpuId, FaultDispatcher(cpuId), ReservationManager::setReservation(cpuId, ...), etc.). Each CPU has independent pipeline state, register files (integer + FP), TLBs (ITB/DTB), write buffers, LL/SC reservation slot, FaultDispatcher, and processor status (PS, IPL, CM, PAL mode flag).

 


 

9.3.4 CPUStateManager

 

The CPUStateManager tracks each CPU's execution state:

 

enum class CPUState : quint8 {

 Running, // Normal execution

 Halted, // CPU halted (HALT instruction)

 Waiting, // CPU in wait state

 Quiesced, // CPU memory operations drained

 Reset // CPU being reset

};

 

isCPUHalted() is used by getActiveCPUCount() to determine how many CPUs participate in barrier coordination. The Quiesced state indicates a CPU whose write buffers have been drained — a prerequisite for certain global operations.

 

See Also: emulatrLib/ExecutionCoordinator.h; emulatrLib/CPUStateManager.h.