Skip to content

Commit

Permalink
Merge branch 'fix-perf-bug' into 'master'
Browse files Browse the repository at this point in the history
Fix perf bug

See merge request projectn/nemu!113
  • Loading branch information
sashimi-yzh committed Mar 30, 2021
2 parents 4e19255 + cbda50d commit e24051f
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 25 deletions.
62 changes: 40 additions & 22 deletions src/cpu/tcache.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ typedef struct bb_t {
static Decode tcache_pool[TCACHE_SIZE] = {};
static int tc_idx = 0;
static Decode tcache_tmp_pool[TCACHE_TMP_SIZE] = {};
static bool tcache_tmp_bitmap[TCACHE_TMP_SIZE] = {};
static Decode *tcache_tmp_freelist = NULL;
static bb_t bb_pool[BB_POOL_SIZE] = {};
static int bb_idx = 0;
static bb_t bb_list [BB_LIST_SIZE] = {};
Expand All @@ -26,7 +26,7 @@ static const void* get_nemu_decode() {
}

static inline Decode* tcache_entry_init(Decode *s, vaddr_t pc) {
memset(s, 0, sizeof(*s));
s->tnext = s->ntnext = NULL;
s->pc = pc;
s->EHelper = get_nemu_decode();
return s;
Expand All @@ -35,26 +35,37 @@ static inline Decode* tcache_entry_init(Decode *s, vaddr_t pc) {
static inline Decode* tcache_new(vaddr_t pc) {
if (tc_idx == TCACHE_SIZE) return NULL;
assert(tc_idx < TCACHE_SIZE);
tcache_entry_init(&tcache_pool[tc_idx], pc);
return &tcache_pool[tc_idx ++];
Decode *s = &tcache_pool[tc_idx];
tc_idx ++;
return tcache_entry_init(s, pc);
}

#ifdef DEBUG
#define tcache_tmp_check(s) do { \
int idx = s - tcache_tmp_pool; \
Assert(idx >= 0 && idx < TCACHE_TMP_SIZE, "idx = %d, s = %p", idx, s); \
} while (0)
#else
#define tcache_tmp_check(s)
#endif

static inline Decode* tcache_tmp_new(vaddr_t pc) {
int i;
for (i = 0; i < TCACHE_TMP_SIZE; i ++) {
if (tcache_tmp_bitmap[i] == 0) {
tcache_tmp_bitmap[i] = 1;
return tcache_entry_init(&tcache_tmp_pool[i], pc);
}
}
assert(0);
return NULL;
Decode *s = tcache_tmp_freelist;
assert(s != NULL);
tcache_tmp_check(s);
tcache_tmp_check(tcache_tmp_freelist->tnext);
tcache_tmp_freelist = tcache_tmp_freelist->tnext;
tcache_tmp_check(tcache_tmp_freelist);
tcache_tmp_check(tcache_tmp_freelist->tnext);
return tcache_entry_init(s, pc);
}

static inline void tcache_tmp_free(Decode *s) {
int idx = s - tcache_tmp_pool;
assert(idx >= 0 && idx < TCACHE_TMP_SIZE);
tcache_tmp_bitmap[idx] = 0;
tcache_tmp_check(s);
tcache_tmp_check(tcache_tmp_freelist);
s->tnext = tcache_tmp_freelist;
tcache_tmp_freelist = s;
tcache_tmp_check(tcache_tmp_freelist->tnext);
}


Expand Down Expand Up @@ -124,7 +135,13 @@ static void tcache_flush() {
tc_idx = 0;
bb_idx = 0;
memset(bb_list, -1, sizeof(bb_list));
memset(tcache_tmp_bitmap, 0, sizeof(tcache_tmp_bitmap));

int i;
for (i = 0; i < TCACHE_TMP_SIZE - 1; i ++) {
tcache_tmp_pool[i].tnext = &tcache_tmp_pool[i + 1];
}
tcache_tmp_pool[TCACHE_TMP_SIZE - 1].tnext = NULL;
tcache_tmp_freelist = &tcache_tmp_pool[0];
}

enum { TCACHE_BB_BUILDING, TCACHE_RUNNING };
Expand Down Expand Up @@ -161,13 +178,14 @@ Decode* tcache_decode(Decode *s, const void **exec_table) {
s->EHelper = exec_table[idx];

if (bb_start) {
s = tcache_new(old->pc);
vaddr_t thispc = old->pc;
s = tcache_new(thispc);
if (s == NULL) goto full;
bb_t *ret = bb_insert(old->pc, s);
bb_t *ret = bb_insert(thispc, s);
if (ret == NULL) { // basic block list is full
full: old->EHelper = get_nemu_decode(); // decode again
save_globals(old);
tcache_flush();
full: tcache_flush();
s = tcache_tmp_new(thispc); // decode again
save_globals(s);
longjmp_exec(NEMU_EXEC_AGAIN);
}

Expand Down
5 changes: 5 additions & 0 deletions src/isa/riscv64/clint.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ void update_clint() {
mip->mtip = (clint_base[CLINT_MTIME] >= clint_base[CLINT_MTIMECMP]);
}

uint64_t clint_uptime() {
update_clint();
return clint_base[CLINT_MTIME];
}

static void clint_io_handler(uint32_t offset, int len, bool is_write) {
update_clint();
}
Expand Down
6 changes: 5 additions & 1 deletion src/isa/riscv64/local-include/csr.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
f(sscratch , 0x140) f(sepc , 0x141) f(scause , 0x142) \
f(stval , 0x143) f(sip , 0x144) \
f(satp , 0x180) \
f(fflags , 0x001) f(frm , 0x002) f(fcsr , 0x003)
f(fflags , 0x001) f(frm , 0x002) f(fcsr , 0x003) \
f(mtime , 0xc01)

#define CSR_STRUCT_START(name) \
typedef union { \
Expand Down Expand Up @@ -220,6 +221,9 @@ CSR_STRUCT_START(fcsr)
};
CSR_STRUCT_END(fcsr)

CSR_STRUCT_START(mtime)
CSR_STRUCT_END(mtime)

#define CSRS_DECL(name, addr) extern concat(name, _t)* const name;
MAP(CSRS, CSRS_DECL)

Expand Down
4 changes: 2 additions & 2 deletions src/isa/riscv64/system/priv.c
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#include "../local-include/csr.h"
#include "../local-include/rtl.h"
#include "../local-include/intr.h"
#include <cpu/cpu.h>

int update_mmu_state();
uint64_t clint_uptime();

static word_t csr_array[4096] = {};

Expand Down Expand Up @@ -39,6 +39,7 @@ static inline word_t csr_read(word_t *src) {
else if (is_read(fcsr)) { return fcsr->val & FCSR_MASK; }
else if (is_read(fflags)) { return fcsr->fflags.val; }
else if (is_read(frm)) { return fcsr->frm; }
else if (is_read(mtime)) { return clint_uptime(); }
return *src;
}

Expand Down Expand Up @@ -76,7 +77,6 @@ word_t csrid_read(uint32_t csrid) {
}

static void csrrw(rtlreg_t *dest, const rtlreg_t *src, uint32_t csrid) {
if (csrid == 0xc01) { longjmp_exception(EX_II); } // time
word_t *csr = csr_decode(csrid);
word_t tmp = (src != NULL ? *src : 0);
if (dest != NULL) { *dest = csr_read(csr); }
Expand Down

0 comments on commit e24051f

Please sign in to comment.