diff options
author | Andrew Waterman <andrew@sifive.com> | 2023-01-11 15:57:44 -0800 |
---|---|---|
committer | Andrew Waterman <andrew@sifive.com> | 2023-01-11 16:39:34 -0800 |
commit | a4d62fd274ae64cb06cff2d97789c29a3c2e0da4 (patch) | |
tree | 3320275da770cf4cf2a2f24bbbc45ea8e6e0be2f | |
parent | d97ad271eeb8d435c7f53c05cf39d6ff9ee0be41 (diff) | |
download | spike-a4d62fd274ae64cb06cff2d97789c29a3c2e0da4.zip spike-a4d62fd274ae64cb06cff2d97789c29a3c2e0da4.tar.gz spike-a4d62fd274ae64cb06cff2d97789c29a3c2e0da4.tar.bz2 |
Run Spike and HTIF in a single thread, rather than two
The two-thread approach was originally motivated by making Spike look
as similar as possible to other HTIF targets. But we can get the same
semantics without threading by running the simulator inside of the HTIF
host's idle loop instead of performing a context switch.
This was motivated by speeding up the simulator on Mac OS (it's worth
around 20% because using pthread condition variables to force strict
alternation is very slow). But I think it also simplifies the control
flow enough to justify it on that basis, too.
-rw-r--r-- | riscv/sim.cc | 39 | ||||
-rw-r--r-- | riscv/sim.h | 6 |
2 files changed, 14 insertions, 31 deletions
diff --git a/riscv/sim.cc b/riscv/sim.cc index 1de3906..74b3523 100644 --- a/riscv/sim.cc +++ b/riscv/sim.cc @@ -220,33 +220,15 @@ sim_t::~sim_t() delete debug_mmu; } -void sim_thread_main(void* arg) -{ - ((sim_t*)arg)->main(); -} - -void sim_t::main() +int sim_t::run() { if (!debug && log) set_procs_debug(true); - while (!done()) - { - if (debug || ctrlc_pressed) - interactive(); - else - step(INTERLEAVE); - if (remote_bitbang) { - remote_bitbang->tick(); - } - } -} - -int sim_t::run() -{ - host = context_t::current(); - target.init(sim_thread_main, this); htif_t::set_expected_xlen(isa.get_max_xlen()); + + // htif_t::run() will repeatedly call back into sim_t::idle(), each + // invocation of which will advance target time return htif_t::run(); } @@ -267,8 +249,6 @@ void sim_t::step(size_t n) if (clint) clint->increment(INTERLEAVE / INSNS_PER_RTC_TICK); if (ns16550) ns16550->tick(); } - - host->switch_to(); } } } @@ -427,7 +407,16 @@ void sim_t::reset() void sim_t::idle() { - target.switch_to(); + if (done()) + return; + + if (debug || ctrlc_pressed) + interactive(); + else + step(INTERLEAVE); + + if (remote_bitbang) + remote_bitbang->tick(); } void sim_t::read_chunk(addr_t taddr, size_t len, void* dst) diff --git a/riscv/sim.h b/riscv/sim.h index 21b1616..350d82f 100644 --- a/riscv/sim.h +++ b/riscv/sim.h @@ -11,7 +11,6 @@ #include "simif.h" #include <fesvr/htif.h> -#include <fesvr/context.h> #include <vector> #include <string> #include <memory> @@ -137,11 +136,6 @@ private: friend class debug_module_t; // htif - friend void sim_thread_main(void*); - void main(); - - context_t* host; - context_t target; void reset(); void idle(); void read_chunk(addr_t taddr, size_t len, void* dst); |