Make CPU and memory thread-safe

master
vhaudiquet 12 months ago
parent c878dee7e0
commit f2c573bfc6
  1. 14
      src/cpu/rv32cpu.c
  2. 2
      src/cpu/rv32cpu.h
  3. 20
      src/gdbstub/gdbstub.c
  4. 2
      src/memory/memory.c
  5. 2
      src/memory/memory.h

@ -9,7 +9,7 @@
#include <stdio.h> #include <stdio.h>
rv32_cpu_t* cpu0; rv32_cpu_t* cpu0;
pthread_mutex_t* cpu0_mutex; pthread_mutex_t cpu0_mutex;
typedef union RAW_INSTRUCTION typedef union RAW_INSTRUCTION
{ {
@ -41,7 +41,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);
cpu0->regs.zero = 0; cpu0->regs.zero = 0;
} }
@ -647,8 +647,9 @@ void cpu_loop(rv32_cpu_t* cpu)
{ {
while(1) while(1)
{ {
// Aquire CPU mutex // Aquire CPU and memory mutex
pthread_mutex_lock(cpu0_mutex); pthread_mutex_lock(&cpu0_mutex);
pthread_mutex_lock(&memory_mutex);
// Fetch // Fetch
raw_instruction_t raw_instruction; raw_instruction_t raw_instruction;
@ -674,8 +675,9 @@ void cpu_loop(rv32_cpu_t* cpu)
cpu->pc += 4; cpu->pc += 4;
// Let go of cpu mutex // Let go of cpu and memory mutex
pthread_mutex_unlock(cpu0_mutex); pthread_mutex_unlock(&cpu0_mutex);
pthread_mutex_unlock(&memory_mutex);
} }
} }

@ -189,7 +189,7 @@ typedef struct RV32_CPU
} rv32_cpu_t; } rv32_cpu_t;
extern rv32_cpu_t* cpu0; extern rv32_cpu_t* cpu0;
extern pthread_mutex_t* cpu0_mutex; extern pthread_mutex_t cpu0_mutex;
void cpu_init(); void cpu_init();
void cpu_loop(rv32_cpu_t* cpu); void cpu_loop(rv32_cpu_t* cpu);

@ -184,7 +184,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++)
@ -198,7 +198,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;
@ -209,7 +209,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++)
@ -228,7 +228,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);
} }
@ -239,6 +239,9 @@ void gdbstub_thread_gdb()
uint32_t length; uint32_t length;
sscanf(packet + 1, "%x,%x", &address, &length); sscanf(packet + 1, "%x,%x", &address, &length);
// Aquire memory mutex
pthread_mutex_lock(&memory_mutex);
char data[length * 2 + 1]; char data[length * 2 + 1];
for(size_t i = 0; i < length; i++) for(size_t i = 0; i < length; i++)
{ {
@ -246,6 +249,9 @@ void gdbstub_thread_gdb()
snprintf(data + i * 2, 3, "%02x", value); snprintf(data + i * 2, 3, "%02x", value);
} }
// Let go of memory mutex
pthread_mutex_unlock(&memory_mutex);
gdbstub_send_packet(data, length * 2); gdbstub_send_packet(data, length * 2);
} }
else if(packet[0] == 'M') else if(packet[0] == 'M')
@ -260,6 +266,9 @@ void gdbstub_thread_gdb()
data_start++; data_start++;
data_start++; data_start++;
// Aquire memory mutex
pthread_mutex_lock(&memory_mutex);
for(size_t i = 0; i < length; i++) for(size_t i = 0; i < length; i++)
{ {
uint32_t value; uint32_t value;
@ -267,6 +276,9 @@ void gdbstub_thread_gdb()
memory[mmu_translate(address + i)] = value; memory[mmu_translate(address + i)] = value;
} }
// Let go of memory mutex
pthread_mutex_unlock(&memory_mutex);
gdbstub_send_packet("OK", 2); gdbstub_send_packet("OK", 2);
} }
else if(packet[0] == 's') else if(packet[0] == 's')

@ -2,8 +2,10 @@
#include "vriscv.h" #include "vriscv.h"
uint8_t* memory; uint8_t* memory;
pthread_mutex_t memory_mutex;
void mem_init() void mem_init()
{ {
memory = malloc(memory_size); memory = malloc(memory_size);
pthread_mutex_init(&memory_mutex, 0);
} }

@ -2,8 +2,10 @@
#define MEMORY_H #define MEMORY_H
#include <stdint.h> #include <stdint.h>
#include <pthread.h>
extern uint8_t* memory; extern uint8_t* memory;
extern pthread_mutex_t memory_mutex;
void mem_init(); void mem_init();

Loading…
Cancel
Save