Browse Source

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.
pull/1225/head
Andrew Waterman 4 years ago
parent
commit
6b44190063
  1. 39
      riscv/sim.cc
  2. 6
      riscv/sim.h

39
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)

6
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);

Loading…
Cancel
Save