From c878dee7e0593c98836349fa98e76e7ee4a8c941 Mon Sep 17 00:00:00 2001 From: vhaudiquet Date: Sun, 8 Oct 2023 16:40:03 +0200 Subject: [PATCH] Make CPU code thread safe --- Makefile | 2 +- src/cpu/rv32cpu.c | 8 ++++++++ src/cpu/rv32cpu.h | 2 ++ src/gdbstub/gdbstub.c | 12 ++++++++++++ 4 files changed, 23 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index b696ce1..f1f1728 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ NAME=vriscv CC=gcc CFLAGS=-O3 -Wall -I src -LDFLAGS= +LDFLAGS=-lpthread BUILD_DIR=build C_FILES := $(shell find src/ -name '*.c') diff --git a/src/cpu/rv32cpu.c b/src/cpu/rv32cpu.c index c3d26a8..603ccff 100644 --- a/src/cpu/rv32cpu.c +++ b/src/cpu/rv32cpu.c @@ -9,6 +9,7 @@ #include rv32_cpu_t* cpu0; +pthread_mutex_t* cpu0_mutex; typedef union RAW_INSTRUCTION { @@ -40,6 +41,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); cpu0->regs.zero = 0; } @@ -645,6 +647,9 @@ void cpu_loop(rv32_cpu_t* cpu) { while(1) { + // Aquire CPU mutex + pthread_mutex_lock(cpu0_mutex); + // Fetch raw_instruction_t raw_instruction; if(cpu->pc > memory_size - 4) @@ -668,6 +673,9 @@ void cpu_loop(rv32_cpu_t* cpu) cpu->regs.zero = 0; cpu->pc += 4; + + // Let go of cpu mutex + pthread_mutex_unlock(cpu0_mutex); } } diff --git a/src/cpu/rv32cpu.h b/src/cpu/rv32cpu.h index 5925c88..a2f947d 100644 --- a/src/cpu/rv32cpu.h +++ b/src/cpu/rv32cpu.h @@ -2,6 +2,7 @@ #define RV32CPU_H #include +#include /* * This is a structure encoding for the registers of @@ -188,6 +189,7 @@ typedef struct RV32_CPU } rv32_cpu_t; extern rv32_cpu_t* cpu0; +extern pthread_mutex_t* cpu0_mutex; void cpu_init(); void cpu_loop(rv32_cpu_t* cpu); diff --git a/src/gdbstub/gdbstub.c b/src/gdbstub/gdbstub.c index 2caa5c8..b22911f 100644 --- a/src/gdbstub/gdbstub.c +++ b/src/gdbstub/gdbstub.c @@ -183,6 +183,9 @@ void gdbstub_thread_gdb() // g : read all registers -> send back all registers char resp[32 * 8 + 8 + 1] = {0}; + // Obtain 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++) { @@ -194,6 +197,9 @@ void gdbstub_thread_gdb() uint32_t pc = htonl(cpu0->pc); snprintf(resp + 32 * 8, 9, "%08x", pc); + // Let go of CPU0 mutex + pthread_mutex_unlock(cpu0_mutex); + // Final packet size, send packet size_t size = 32 * 8 + 8; gdbstub_send_packet(resp, size); @@ -202,6 +208,9 @@ void gdbstub_thread_gdb() { // G : write all registers -> read and set all registers + // Obtain 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++) { @@ -218,6 +227,9 @@ void gdbstub_thread_gdb() pc = ntohl(pc); cpu0->pc = pc; + // Let go of CPU0 Mutex + pthread_mutex_unlock(cpu0_mutex); + gdbstub_send_packet("OK", 2); } else if(packet[0] == 'm')