aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Waterman <andrew@sifive.com>2023-01-11 15:57:44 -0800
committerAndrew Waterman <andrew@sifive.com>2023-01-11 16:39:34 -0800
commita4d62fd274ae64cb06cff2d97789c29a3c2e0da4 (patch)
tree3320275da770cf4cf2a2f24bbbc45ea8e6e0be2f
parentd97ad271eeb8d435c7f53c05cf39d6ff9ee0be41 (diff)
downloadspike-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.cc39
-rw-r--r--riscv/sim.h6
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);