📄 cpu.cc
字号:
#include "assert.hh"#include "checkpoint.hh"#include "clock.hh"#include "cpu.hh"#include "module.hh"#include "sulima.hh"// Scheduler data.int CPU::cpu_count = 0;CPU *CPU::first_cpu = 0;CPU *CPU::last_cpu = 0;// Static constructor.CPU::CPU(const char *n, ClockValue f) : Module(n), Clock(f){ ++cpu_count; if (!last_cpu) first_cpu = last_cpu = next_cpu = this; else { next_cpu = first_cpu; last_cpu->next_cpu = this; last_cpu = this; }}// Dynamic constructor.CPU::CPU(const SimArgs &args) : Module(args), Clock((long)args[2]){ ++cpu_count; if (!last_cpu) first_cpu = last_cpu = next_cpu = this; else { next_cpu = first_cpu; last_cpu->next_cpu = this; last_cpu = this; }}// Serialized constructor.CPU::CPU(Checkpoint &cp) : Serializable(cp), Module(cp), Clock(cp){ ++cpu_count; if (!last_cpu) first_cpu = last_cpu = next_cpu = this; else { next_cpu = first_cpu; last_cpu->next_cpu = this; last_cpu = this; }}// Serialization support.voidCPU::checkpoint(Checkpoint &cp, bool parent) const{ assert(!parent); Module::checkpoint(cp); Clock::checkpoint(cp);}// GCD(x, y) using Euclid's algorithm.// Note that GCD(x, y, z) == GCD(GCD(x, y), z).static ClockValuegcd(ClockValue x, ClockValue y){ if (x < y) { ClockValue t = x; x = y; y = t; } while (y) { ClockValue t = x % y; x = y; y = t; } return x;}// Run the whole simulator.SimArgCPU::run_all(const SimArgs &args){ // Detect recursive invocations. static bool running = false; if (running) throw Error("Recursive call to \"sim::run\"."); running = true; // Detect bogus syntax. if (args.length() > 2) throw Error("Unexpected arguments to \"sim::run\"."); // Handle uniprocessor mode. if (args.length() == 1 || cpu_count == 1) { CPU *cpu; if (!args.length()) cpu = first_cpu; else { const char *name = args[0]; cpu = dynamic_cast<CPU *>(find_module(name)); if (!cpu) { throw Error("\"%#s\" is not a CPU module.", name); } } // Prepare the console for boot sulima->enable_console(cpu); // Run the module. sulima->msg("Simulation started (1 CPU)."); cpu->run(Clock::infinity); assert(UNREACHABLE); } // Otherwise, we're in a multiprocessor mode. if (!cpu_count) throw Error("No CPU modules have been installed."); // Compute the timeslices. // Find the GCD of all CPU clock frequencies ClockValue freq = first_cpu->freq; for (CPU *cpu = first_cpu->next_cpu; cpu->next_cpu != first_cpu; cpu = cpu->next_cpu) { freq = gcd(freq, cpu->freq); } // Compute the initial timeslices. ClockValue min = infinity, max = 0; for (CPU *cpu = first_cpu; cpu->next_cpu != first_cpu; cpu = cpu->next_cpu) { cpu->timeslice = cpu->freq / freq; if (cpu->timeslice < min) min = cpu->timeslice; if (cpu->timeslice > max) max = cpu->timeslice; } // Fix the timeslices so that each CPU gets at least 32 cycles, // but not if that makes the longest cycle longer than 1024. ClockValue repeat = (min + min_timeslice - 1) / min; if (max * repeat > max_timeslice) throw Error("The range of CPU frequencies is too large."); // Fix the timeslices. for (CPU *cpu = first_cpu; cpu->next_cpu != first_cpu; cpu = cpu->next_cpu) { cpu->timeslice *= repeat; } // Enjoy. Yeah right. sulima->msg("Simulation started (%d CPUs).", cpu_count); for (CPU *cpu = first_cpu;; cpu = cpu->next_cpu) cpu->run(cpu->timeslice);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -