From: Nathan Binkert Date: Tue, 29 Mar 2005 12:55:44 +0000 (-0500) Subject: expose variables for number of global events per simulated second, X-Git-Tag: m5_1.0_tutorial~65^2~18 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=43a9caa2214faffaa1fd5ce1730063f9959a8ce8;p=gem5.git expose variables for number of global events per simulated second, millisecond, microsecond, etc. so that the user can explicitly convert between system ticks and time and know what sorts of expensive operations are being used for that conversion. arch/alpha/alpha_tru64_process.cc: arch/alpha/pseudo_inst.cc: dev/etherdump.cc: dev/etherlink.cc: dev/ns_gige.cc: dev/sinic.cc: dev/tsunami_io.cc: dev/uart.cc: sim/stat_control.cc: sim/syscall_emul.hh: Use the new variables for getting the event clock dev/etherdump.hh: delete variables that are no longer needed. --HG-- extra : convert_revision : d95fc7d44909443e1b7952a24ef822ef051c7cf2 --- diff --git a/arch/alpha/alpha_tru64_process.cc b/arch/alpha/alpha_tru64_process.cc index a211e0ae8..441e7c89f 100644 --- a/arch/alpha/alpha_tru64_process.cc +++ b/arch/alpha/alpha_tru64_process.cc @@ -716,7 +716,7 @@ class Tru64 { TypedBufferArg elp(xc->getSyscallArg(2)); const int clk_hz = one_million; - elp->si_user = curTick / (ticksPerSecond / clk_hz); + elp->si_user = curTick / (Clock::Frequency / clk_hz); elp->si_nice = 0; elp->si_sys = 0; elp->si_idle = 0; diff --git a/arch/alpha/pseudo_inst.cc b/arch/alpha/pseudo_inst.cc index 22d65638b..3c3b37928 100644 --- a/arch/alpha/pseudo_inst.cc +++ b/arch/alpha/pseudo_inst.cc @@ -95,7 +95,7 @@ namespace AlphaPseudo m5exit(ExecContext *xc) { Tick delay = xc->regs.intRegFile[16]; - Tick when = curTick + NS2Ticks(delay); + Tick when = curTick + delay * Clock::Int::ns; SimExit(when, "m5_exit instruction encountered"); } @@ -108,8 +108,8 @@ namespace AlphaPseudo Tick delay = xc->regs.intRegFile[16]; Tick period = xc->regs.intRegFile[17]; - Tick when = curTick + NS2Ticks(delay); - Tick repeat = NS2Ticks(period); + Tick when = curTick + delay * Clock::Int::ns; + Tick repeat = period * Clock::Int::ns; using namespace Stats; SetupEvent(Reset, when, repeat); @@ -124,8 +124,8 @@ namespace AlphaPseudo Tick delay = xc->regs.intRegFile[16]; Tick period = xc->regs.intRegFile[17]; - Tick when = curTick + NS2Ticks(delay); - Tick repeat = NS2Ticks(period); + Tick when = curTick + delay * Clock::Int::ns; + Tick repeat = period * Clock::Int::ns; using namespace Stats; SetupEvent(Dump, when, repeat); @@ -140,8 +140,8 @@ namespace AlphaPseudo Tick delay = xc->regs.intRegFile[16]; Tick period = xc->regs.intRegFile[17]; - Tick when = curTick + NS2Ticks(delay); - Tick repeat = NS2Ticks(period); + Tick when = curTick + delay * Clock::Int::ns; + Tick repeat = period * Clock::Int::ns; using namespace Stats; SetupEvent(Dump|Reset, when, repeat); @@ -156,8 +156,8 @@ namespace AlphaPseudo Tick delay = xc->regs.intRegFile[16]; Tick period = xc->regs.intRegFile[17]; - Tick when = curTick + NS2Ticks(delay); - Tick repeat = NS2Ticks(period); + Tick when = curTick + delay * Clock::Int::ns; + Tick repeat = period * Clock::Int::ns; Checkpoint::setup(when, repeat); } diff --git a/dev/etherdump.cc b/dev/etherdump.cc index 3de417bdc..39b94f923 100644 --- a/dev/etherdump.cc +++ b/dev/etherdump.cc @@ -74,9 +74,6 @@ void EtherDump::init() { curtime = time(NULL); - s_freq = ticksPerSecond; - us_freq = ticksPerSecond / ULL(1000000); - struct pcap_file_header hdr; hdr.magic = TCPDUMP_MAGIC; hdr.version_major = PCAP_VERSION_MAJOR; @@ -108,8 +105,8 @@ void EtherDump::dumpPacket(PacketPtr &packet) { pcap_pkthdr pkthdr; - pkthdr.seconds = curtime + (curTick / s_freq); - pkthdr.microseconds = (curTick / us_freq) % ULL(1000000); + pkthdr.seconds = curtime + (curTick / Clock::Int::s); + pkthdr.microseconds = (curTick / Clock::Int::us) % ULL(1000000); pkthdr.caplen = std::min(packet->length, maxlen); pkthdr.len = packet->length; stream.write(reinterpret_cast(&pkthdr), sizeof(pkthdr)); diff --git a/dev/etherdump.hh b/dev/etherdump.hh index ba15796c8..1296ebb10 100644 --- a/dev/etherdump.hh +++ b/dev/etherdump.hh @@ -49,8 +49,6 @@ class EtherDump : public SimObject void init(); Tick curtime; - Tick s_freq; - Tick us_freq; public: EtherDump(const std::string &name, const std::string &file, int max); diff --git a/dev/etherlink.cc b/dev/etherlink.cc index 81cdbc20f..ba0fa705c 100644 --- a/dev/etherlink.cc +++ b/dev/etherlink.cc @@ -52,7 +52,7 @@ EtherLink::EtherLink(const string &name, EtherInt *peer0, EtherInt *peer1, : SimObject(name) { double rate = ((double)ticksPerSecond * 8.0) / (double)speed; - Tick delay = US2Ticks(dly); + Tick delay = dly * Clock::Int::us; link[0] = new Link(name + ".link0", this, 0, rate, delay, dump); link[1] = new Link(name + ".link1", this, 1, rate, delay, dump); diff --git a/dev/ns_gige.cc b/dev/ns_gige.cc index 53a881ef7..bc3103540 100644 --- a/dev/ns_gige.cc +++ b/dev/ns_gige.cc @@ -138,7 +138,7 @@ NSGigE::NSGigE(Params *p) } - intrDelay = US2Ticks(p->intr_delay); + intrDelay = p->intr_delay * Clock::Int::us; dmaReadDelay = p->dma_read_delay; dmaWriteDelay = p->dma_write_delay; dmaReadFactor = p->dma_read_factor; diff --git a/dev/sinic.cc b/dev/sinic.cc index fa4cd570f..13e16afae 100644 --- a/dev/sinic.cc +++ b/dev/sinic.cc @@ -79,7 +79,7 @@ const char *TxStateStrings[] = // Base::Base(Params *p) : PciDev(p), rxEnable(false), txEnable(false), - intrDelay(US2Ticks(p->intr_delay)), + intrDelay(p->intr_delay * Clock::Int::us), intrTick(0), cpuIntrEnable(false), cpuPendingIntr(false), intrEvent(0), interface(NULL) { diff --git a/dev/tsunami_io.cc b/dev/tsunami_io.cc index 6c9195bff..1e4f44346 100644 --- a/dev/tsunami_io.cc +++ b/dev/tsunami_io.cc @@ -95,6 +95,13 @@ TsunamiIO::RTCEvent::unserialize(Checkpoint *cp, const std::string §ion) TsunamiIO::ClockEvent::ClockEvent() : Event(&mainEventQueue) { + /* This is the PIT Tick Rate. A constant for the 8254 timer. The + * Tsunami platform has one of these cycle counters on the Cypress + * South Bridge and it is used by linux for estimating the cycle + * frequency of the machine it is running on. --Ali + */ + interval = (Tick)(Clock::Float::s / 1193180.0); + DPRINTF(Tsunami, "Clock Event Initilizing\n"); mode = 0; } @@ -113,9 +120,7 @@ void TsunamiIO::ClockEvent::Program(int count) { DPRINTF(Tsunami, "Timer set to curTick + %d\n", count); - // should be count * (cpufreq/pitfreq) - interval = count * ticksPerSecond/1193180UL; - schedule(curTick + interval); + schedule(curTick + count * interval); status = 0; } diff --git a/dev/uart.cc b/dev/uart.cc index 3c4ab6d04..caa169a2e 100644 --- a/dev/uart.cc +++ b/dev/uart.cc @@ -73,17 +73,28 @@ Uart::IntrEvent::process() } +/* The linux serial driver (8250.c about line 1182) loops reading from + * the device until the device reports it has no more data to + * read. After a maximum of 255 iterations the code prints "serial8250 + * too much work for irq X," and breaks out of the loop. Since the + * simulated system is so much slower than the actual system, if a + * user is typing on the keyboard it is very easy for them to provide + * input at a fast enough rate to not allow the loop to exit and thus + * the error to be printed. This magic number provides a delay between + * the time the UART receives a character to send to the simulated + * system and the time it actually notifies the system it has a + * character to send to alleviate this problem. --Ali + */ void Uart::IntrEvent::scheduleIntr() { + static const Tick interval = (Tick)((Clock::Float::s / 2e9) * 450); DPRINTF(Uart, "Scheduling IER interrupt for %#x, at cycle %lld\n", intrBit, - curTick + (ticksPerSecond/2000) * 350); + curTick + interval); if (!scheduled()) - /* @todo Make this cleaner, will be much easier with - * nanosecond time everywhere. Hint hint Nate. */ - schedule(curTick + (ticksPerSecond/2000000000) * 450); + schedule(curTick + interval); else - reschedule(curTick + (ticksPerSecond/2000000000) * 450); + reschedule(curTick + interval); } Uart::Uart(const string &name, SimConsole *c, MemoryController *mmu, Addr a, diff --git a/sim/stat_control.cc b/sim/stat_control.cc index 8a8eaa790..4d72ce213 100644 --- a/sim/stat_control.cc +++ b/sim/stat_control.cc @@ -105,7 +105,7 @@ InitSimStats() ; simFreq - .scalar(ticksPerSecond) + .scalar(Clock::Frequency) .name("sim_freq") .desc("Frequency of simulated ticks") ; diff --git a/sim/syscall_emul.hh b/sim/syscall_emul.hh index 69c17c330..cc1692bfb 100644 --- a/sim/syscall_emul.hh +++ b/sim/syscall_emul.hh @@ -222,9 +222,7 @@ template void getElapsedTime(T1 &sec, T2 &usec) { - int cycles_per_usec = ticksPerSecond / one_million; - - int elapsed_usecs = curTick / cycles_per_usec; + int elapsed_usecs = curTick / Clock::Int::us; sec = elapsed_usecs / one_million; usec = elapsed_usecs % one_million; } diff --git a/sim/universe.cc b/sim/universe.cc index 9137baaf0..8419e1fe4 100644 --- a/sim/universe.cc +++ b/sim/universe.cc @@ -42,16 +42,41 @@ using namespace std; Tick curTick = 0; -Tick ticksPerSecond; -double __ticksPerMS; -double __ticksPerUS; -double __ticksPerNS; -double __ticksPerPS; - bool fullSystem; ostream *outputStream; ostream *configStream; +/// The simulated frequency of curTick. (This is only here for a short time) +Tick ticksPerSecond; + +namespace Clock { +/// The simulated frequency of curTick. (In ticks per second) +Tick Frequency; + +namespace Float { +double s; +double ms; +double us; +double ns; +double ps; + +double Hz; +double kHz; +double MHz; +double GHZ; +/* namespace Float */ } + +namespace Int { +Tick s; +Tick ms; +Tick us; +Tick ns; +Tick ps; +/* namespace Float */ } + +/* namespace Clock */ } + + // Dummy Object class Root : public SimObject { @@ -92,17 +117,31 @@ CREATE_SIM_OBJECT(Root) panic("FULL_SYSTEM not compiled but configuration is full_system"); #endif - ticksPerSecond = frequency; - double freq = double(ticksPerSecond); - __ticksPerMS = freq / 1.0e3; - __ticksPerUS = freq / 1.0e6; - __ticksPerNS = freq / 1.0e9; - __ticksPerPS = freq / 1.0e12; - outputStream = simout.find(output_file); + Root *root = new Root(getInstanceName()); - return new Root(getInstanceName()); + ticksPerSecond = frequency; + + using namespace Clock; + Frequency = frequency; + Float::s = static_cast(Frequency); + Float::ms = Float::s / 1.0e3; + Float::us = Float::s / 1.0e6; + Float::ns = Float::s / 1.0e9; + Float::ps = Float::s / 1.0e12; + + Float::Hz = 1.0 / Float::s; + Float::kHz = 1.0 / Float::ms; + Float::MHz = 1.0 / Float::us; + Float::GHZ = 1.0 / Float::ns; + + Int::s = Frequency; + Int::ms = Int::s / 1000; + Int::us = Int::ms / 1000; + Int::ns = Int::us / 1000; + Int::ps = Int::ns / 1000; + + return root; } REGISTER_SIM_OBJECT("Root", Root) -