From 71f3fbc8b55005d4fc1b7ef92a5d86006445cc62 Mon Sep 17 00:00:00 2001 From: vhaudiquet Date: Sun, 22 Oct 2023 19:30:42 +0200 Subject: [PATCH] Refactor CPU mutex code --- src/cpu/exception.c | 2 +- src/cpu/interrupt.c | 4 ++-- src/cpu/rv32cpu.c | 11 +++++------ src/cpu/rv32cpu.h | 3 ++- src/gdbstub/gdbstub.c | 26 +++++++++++++------------- 5 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/cpu/exception.c b/src/cpu/exception.c index 005e6d3..5d23403 100644 --- a/src/cpu/exception.c +++ b/src/cpu/exception.c @@ -42,7 +42,7 @@ void exception_trigger(rv32_cpu_t* cpu, uint32_t scause, uint32_t tval) cpu->pc = cpu->csr[CSR_STVEC] & 0xFFFFFFFC; // Unlock cpu mutex, cpu_loop will lock it just after - pthread_mutex_unlock(&cpu0_mutex); + pthread_mutex_unlock(&cpu->mutex); // cpu loop (attribute noreturn should erase previous stack) cpu_loop(cpu); diff --git a/src/cpu/interrupt.c b/src/cpu/interrupt.c index 9306cc7..c05f0b8 100644 --- a/src/cpu/interrupt.c +++ b/src/cpu/interrupt.c @@ -33,7 +33,7 @@ void interrupt_trigger(rv32_cpu_t* cpu, uint32_t scause) // but we know it is not in the middle of an instruction // (we got the mutex) ; this way we can just change // registers to set interrupt handler execution - pthread_mutex_lock(&cpu0_mutex); + pthread_mutex_lock(&cpu->mutex); // Set xCAUSE with interrupt bit set cpu->csr[CSR_SCAUSE] = 0x80000000 | scause; @@ -67,7 +67,7 @@ void interrupt_trigger(rv32_cpu_t* cpu, uint32_t scause) break; } - pthread_mutex_unlock(&cpu0_mutex); + pthread_mutex_unlock(&cpu->mutex); } void interrupt_timer_thread() diff --git a/src/cpu/rv32cpu.c b/src/cpu/rv32cpu.c index 57f19a1..a6b0bdd 100644 --- a/src/cpu/rv32cpu.c +++ b/src/cpu/rv32cpu.c @@ -11,7 +11,6 @@ #include rv32_cpu_t* cpu0; -pthread_mutex_t cpu0_mutex; typedef union RAW_INSTRUCTION { @@ -43,7 +42,7 @@ static void cpu_print_instruction(instruction_t* instruction); void cpu_init() { cpu0 = calloc(1, sizeof(rv32_cpu_t)); - pthread_mutex_init(&cpu0_mutex, 0); + pthread_mutex_init(&cpu0->mutex, 0); pthread_cond_init(&cpu0->sim_condition, 0); cpu0->regs.zero = 0; cpu0->privilege_mode = MACHINE; @@ -716,14 +715,14 @@ __attribute__((noreturn)) void cpu_loop(rv32_cpu_t* cpu) while(1) { // Aquire CPU mutex - pthread_mutex_lock(&cpu0_mutex); + pthread_mutex_lock(&cpu->mutex); // No simulation ticks left : wakeup people waiting on sim end if(!cpu->sim_ticks_left) - pthread_cond_signal(&cpu0->sim_condition); + pthread_cond_signal(&cpu->sim_condition); // Then, wait for simulation state to change until we get more ticks to simulate while(!cpu->sim_ticks_left) - pthread_cond_wait(&cpu0->sim_condition, &cpu0_mutex); + pthread_cond_wait(&cpu->sim_condition, &cpu->mutex); // Fetch raw_instruction_t raw_instruction; @@ -758,7 +757,7 @@ __attribute__((noreturn)) void cpu_loop(rv32_cpu_t* cpu) cpu->sim_ticks_left--; // Let go of cpu mutex - pthread_mutex_unlock(&cpu0_mutex); + pthread_mutex_unlock(&cpu->mutex); } } diff --git a/src/cpu/rv32cpu.h b/src/cpu/rv32cpu.h index e931784..9c416b8 100644 --- a/src/cpu/rv32cpu.h +++ b/src/cpu/rv32cpu.h @@ -205,13 +205,14 @@ typedef struct RV32_CPU ssize_t sim_ticks_left; // -1 : simulate forever size_t sim_ticks_done; pthread_cond_t sim_condition; + + pthread_mutex_t mutex; } rv32_cpu_t; uint32_t csr_read(struct RV32_CPU* cpu, uint32_t csr); void csr_write(struct RV32_CPU* cpu, uint32_t csr, uint32_t value); extern rv32_cpu_t* cpu0; -extern pthread_mutex_t cpu0_mutex; void cpu_init(); __attribute__((noreturn)) void cpu_loop(rv32_cpu_t* cpu); diff --git a/src/gdbstub/gdbstub.c b/src/gdbstub/gdbstub.c index 484d95f..b986287 100644 --- a/src/gdbstub/gdbstub.c +++ b/src/gdbstub/gdbstub.c @@ -203,7 +203,7 @@ void gdbstub_thread_gdb() char resp[32 * 8 + 8 + 1] = {0}; // Obtain CPU0 mutex - pthread_mutex_lock(&cpu0_mutex); + pthread_mutex_lock(&cpu0->mutex); // All general purpose registers in host byte order as chars for(size_t i = 0; i < 32; i++) @@ -217,7 +217,7 @@ void gdbstub_thread_gdb() snprintf(resp + 32 * 8, 9, "%08x", pc); // Let go of CPU0 mutex - pthread_mutex_unlock(&cpu0_mutex); + pthread_mutex_unlock(&cpu0->mutex); // Final packet size, send packet size_t size = 32 * 8 + 8; @@ -228,7 +228,7 @@ void gdbstub_thread_gdb() // G : write all registers -> read and set all registers // Obtain CPU0 mutex - pthread_mutex_lock(&cpu0_mutex); + pthread_mutex_lock(&cpu0->mutex); // All general purpose registers in host byte order as chars for(size_t i = 1; i < 32; i++) @@ -247,7 +247,7 @@ void gdbstub_thread_gdb() cpu0->pc = pc; // Let go of CPU0 Mutex - pthread_mutex_unlock(&cpu0_mutex); + pthread_mutex_unlock(&cpu0->mutex); gdbstub_send_packet("OK", 2); } @@ -296,9 +296,9 @@ void gdbstub_thread_gdb() send(gdb_socket, "+", 1, 0); // Continue simulation, for 1 tick - pthread_mutex_lock(&cpu0_mutex); + pthread_mutex_lock(&cpu0->mutex); cpu0->sim_ticks_left = 1; - pthread_mutex_unlock(&cpu0_mutex); + pthread_mutex_unlock(&cpu0->mutex); pthread_cond_signal(&cpu0->sim_condition); } else if(packet[0] == 'c') @@ -309,9 +309,9 @@ void gdbstub_thread_gdb() send(gdb_socket, "+", 1, 0); // Continue simulation - pthread_mutex_lock(&cpu0_mutex); + pthread_mutex_lock(&cpu0->mutex); cpu0->sim_ticks_left = -1; - pthread_mutex_unlock(&cpu0_mutex); + pthread_mutex_unlock(&cpu0->mutex); pthread_cond_signal(&cpu0->sim_condition); } else gdbstub_send_unsupported(); @@ -322,8 +322,8 @@ void gdbstub_cpu_watcher_thread() { while(1) { - pthread_mutex_lock(&cpu0_mutex); - pthread_cond_wait(&cpu0->sim_condition, &cpu0_mutex); + pthread_mutex_lock(&cpu0->mutex); + pthread_cond_wait(&cpu0->sim_condition, &cpu0->mutex); if(!cpu0->sim_ticks_left && cpu0->sim_ticks_done > 0) { // Send back halt reason @@ -331,7 +331,7 @@ void gdbstub_cpu_watcher_thread() char* resp = "S05"; gdbstub_send_packet(resp, 3); } - pthread_mutex_unlock(&cpu0_mutex); + pthread_mutex_unlock(&cpu0->mutex); } } @@ -342,7 +342,7 @@ void gdbstub_cpu_watcher_thread() static void gdbstub_handle_ctrlc() { // Halt the simulation - pthread_mutex_lock(&cpu0_mutex); + pthread_mutex_lock(&cpu0->mutex); cpu0->sim_ticks_left = 0; - pthread_mutex_unlock(&cpu0_mutex); + pthread_mutex_unlock(&cpu0->mutex); }