aboutsummaryrefslogtreecommitdiff
path: root/riscv
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:05:40 -0800
commit6b44190063477a68f8e27728c7240c9b790760bd (patch)
treecd6d3aa2ebc03b43d983aa172065878ba7c82e9e /riscv
parent9874c1767179250e25094ccc6757a5faad9d99d1 (diff)
downloadspike-6b44190063477a68f8e27728c7240c9b790760bd.zip
spike-6b44190063477a68f8e27728c7240c9b790760bd.tar.gz
spike-6b44190063477a68f8e27728c7240c9b790760bd.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.
Diffstat (limited to 'riscv')
-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);