Refactor CPU mutex code

master
vhaudiquet 1 year ago
parent 02114ea7d8
commit 71f3fbc8b5
  1. 2
      src/cpu/exception.c
  2. 4
      src/cpu/interrupt.c
  3. 11
      src/cpu/rv32cpu.c
  4. 3
      src/cpu/rv32cpu.h
  5. 26
      src/gdbstub/gdbstub.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; cpu->pc = cpu->csr[CSR_STVEC] & 0xFFFFFFFC;
// Unlock cpu mutex, cpu_loop will lock it just after // 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 (attribute noreturn should erase previous stack)
cpu_loop(cpu); cpu_loop(cpu);

@ -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 // but we know it is not in the middle of an instruction
// (we got the mutex) ; this way we can just change // (we got the mutex) ; this way we can just change
// registers to set interrupt handler execution // registers to set interrupt handler execution
pthread_mutex_lock(&cpu0_mutex); pthread_mutex_lock(&cpu->mutex);
// Set xCAUSE with interrupt bit set // Set xCAUSE with interrupt bit set
cpu->csr[CSR_SCAUSE] = 0x80000000 | scause; cpu->csr[CSR_SCAUSE] = 0x80000000 | scause;
@ -67,7 +67,7 @@ void interrupt_trigger(rv32_cpu_t* cpu, uint32_t scause)
break; break;
} }
pthread_mutex_unlock(&cpu0_mutex); pthread_mutex_unlock(&cpu->mutex);
} }
void interrupt_timer_thread() void interrupt_timer_thread()

@ -11,7 +11,6 @@
#include <stdio.h> #include <stdio.h>
rv32_cpu_t* cpu0; rv32_cpu_t* cpu0;
pthread_mutex_t cpu0_mutex;
typedef union RAW_INSTRUCTION typedef union RAW_INSTRUCTION
{ {
@ -43,7 +42,7 @@ static void cpu_print_instruction(instruction_t* instruction);
void cpu_init() void cpu_init()
{ {
cpu0 = calloc(1, sizeof(rv32_cpu_t)); 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); pthread_cond_init(&cpu0->sim_condition, 0);
cpu0->regs.zero = 0; cpu0->regs.zero = 0;
cpu0->privilege_mode = MACHINE; cpu0->privilege_mode = MACHINE;
@ -716,14 +715,14 @@ __attribute__((noreturn)) void cpu_loop(rv32_cpu_t* cpu)
while(1) while(1)
{ {
// Aquire CPU mutex // Aquire CPU mutex
pthread_mutex_lock(&cpu0_mutex); pthread_mutex_lock(&cpu->mutex);
// No simulation ticks left : wakeup people waiting on sim end // No simulation ticks left : wakeup people waiting on sim end
if(!cpu->sim_ticks_left) 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 // Then, wait for simulation state to change until we get more ticks to simulate
while(!cpu->sim_ticks_left) while(!cpu->sim_ticks_left)
pthread_cond_wait(&cpu0->sim_condition, &cpu0_mutex); pthread_cond_wait(&cpu->sim_condition, &cpu->mutex);
// Fetch // Fetch
raw_instruction_t raw_instruction; raw_instruction_t raw_instruction;
@ -758,7 +757,7 @@ __attribute__((noreturn)) void cpu_loop(rv32_cpu_t* cpu)
cpu->sim_ticks_left--; cpu->sim_ticks_left--;
// Let go of cpu mutex // Let go of cpu mutex
pthread_mutex_unlock(&cpu0_mutex); pthread_mutex_unlock(&cpu->mutex);
} }
} }

@ -205,13 +205,14 @@ typedef struct RV32_CPU
ssize_t sim_ticks_left; // -1 : simulate forever ssize_t sim_ticks_left; // -1 : simulate forever
size_t sim_ticks_done; size_t sim_ticks_done;
pthread_cond_t sim_condition; pthread_cond_t sim_condition;
pthread_mutex_t mutex;
} rv32_cpu_t; } rv32_cpu_t;
uint32_t csr_read(struct RV32_CPU* cpu, uint32_t csr); uint32_t csr_read(struct RV32_CPU* cpu, uint32_t csr);
void csr_write(struct RV32_CPU* cpu, uint32_t csr, uint32_t value); void csr_write(struct RV32_CPU* cpu, uint32_t csr, uint32_t value);
extern rv32_cpu_t* cpu0; extern rv32_cpu_t* cpu0;
extern pthread_mutex_t cpu0_mutex;
void cpu_init(); void cpu_init();
__attribute__((noreturn)) void cpu_loop(rv32_cpu_t* cpu); __attribute__((noreturn)) void cpu_loop(rv32_cpu_t* cpu);

@ -203,7 +203,7 @@ void gdbstub_thread_gdb()
char resp[32 * 8 + 8 + 1] = {0}; char resp[32 * 8 + 8 + 1] = {0};
// Obtain CPU0 mutex // Obtain CPU0 mutex
pthread_mutex_lock(&cpu0_mutex); pthread_mutex_lock(&cpu0->mutex);
// All general purpose registers in host byte order as chars // All general purpose registers in host byte order as chars
for(size_t i = 0; i < 32; i++) for(size_t i = 0; i < 32; i++)
@ -217,7 +217,7 @@ void gdbstub_thread_gdb()
snprintf(resp + 32 * 8, 9, "%08x", pc); snprintf(resp + 32 * 8, 9, "%08x", pc);
// Let go of CPU0 mutex // Let go of CPU0 mutex
pthread_mutex_unlock(&cpu0_mutex); pthread_mutex_unlock(&cpu0->mutex);
// Final packet size, send packet // Final packet size, send packet
size_t size = 32 * 8 + 8; size_t size = 32 * 8 + 8;
@ -228,7 +228,7 @@ void gdbstub_thread_gdb()
// G : write all registers -> read and set all registers // G : write all registers -> read and set all registers
// Obtain CPU0 mutex // Obtain CPU0 mutex
pthread_mutex_lock(&cpu0_mutex); pthread_mutex_lock(&cpu0->mutex);
// All general purpose registers in host byte order as chars // All general purpose registers in host byte order as chars
for(size_t i = 1; i < 32; i++) for(size_t i = 1; i < 32; i++)
@ -247,7 +247,7 @@ void gdbstub_thread_gdb()
cpu0->pc = pc; cpu0->pc = pc;
// Let go of CPU0 Mutex // Let go of CPU0 Mutex
pthread_mutex_unlock(&cpu0_mutex); pthread_mutex_unlock(&cpu0->mutex);
gdbstub_send_packet("OK", 2); gdbstub_send_packet("OK", 2);
} }
@ -296,9 +296,9 @@ void gdbstub_thread_gdb()
send(gdb_socket, "+", 1, 0); send(gdb_socket, "+", 1, 0);
// Continue simulation, for 1 tick // Continue simulation, for 1 tick
pthread_mutex_lock(&cpu0_mutex); pthread_mutex_lock(&cpu0->mutex);
cpu0->sim_ticks_left = 1; cpu0->sim_ticks_left = 1;
pthread_mutex_unlock(&cpu0_mutex); pthread_mutex_unlock(&cpu0->mutex);
pthread_cond_signal(&cpu0->sim_condition); pthread_cond_signal(&cpu0->sim_condition);
} }
else if(packet[0] == 'c') else if(packet[0] == 'c')
@ -309,9 +309,9 @@ void gdbstub_thread_gdb()
send(gdb_socket, "+", 1, 0); send(gdb_socket, "+", 1, 0);
// Continue simulation // Continue simulation
pthread_mutex_lock(&cpu0_mutex); pthread_mutex_lock(&cpu0->mutex);
cpu0->sim_ticks_left = -1; cpu0->sim_ticks_left = -1;
pthread_mutex_unlock(&cpu0_mutex); pthread_mutex_unlock(&cpu0->mutex);
pthread_cond_signal(&cpu0->sim_condition); pthread_cond_signal(&cpu0->sim_condition);
} }
else gdbstub_send_unsupported(); else gdbstub_send_unsupported();
@ -322,8 +322,8 @@ void gdbstub_cpu_watcher_thread()
{ {
while(1) while(1)
{ {
pthread_mutex_lock(&cpu0_mutex); pthread_mutex_lock(&cpu0->mutex);
pthread_cond_wait(&cpu0->sim_condition, &cpu0_mutex); pthread_cond_wait(&cpu0->sim_condition, &cpu0->mutex);
if(!cpu0->sim_ticks_left && cpu0->sim_ticks_done > 0) if(!cpu0->sim_ticks_left && cpu0->sim_ticks_done > 0)
{ {
// Send back halt reason // Send back halt reason
@ -331,7 +331,7 @@ void gdbstub_cpu_watcher_thread()
char* resp = "S05"; char* resp = "S05";
gdbstub_send_packet(resp, 3); 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() static void gdbstub_handle_ctrlc()
{ {
// Halt the simulation // Halt the simulation
pthread_mutex_lock(&cpu0_mutex); pthread_mutex_lock(&cpu0->mutex);
cpu0->sim_ticks_left = 0; cpu0->sim_ticks_left = 0;
pthread_mutex_unlock(&cpu0_mutex); pthread_mutex_unlock(&cpu0->mutex);
} }

Loading…
Cancel
Save