From 6d0e7c5eba49efc171e63ff2631722a5c7f95460 Mon Sep 17 00:00:00 2001 From: Kimplul Date: Wed, 25 Sep 2024 21:00:16 +0300 Subject: technically speaking deadlock free, but starves --- src/mem/simple_mem.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/mem/source.mk | 1 + 2 files changed, 79 insertions(+) create mode 100644 src/mem/simple_mem.c create mode 100644 src/mem/source.mk (limited to 'src/mem') diff --git a/src/mem/simple_mem.c b/src/mem/simple_mem.c new file mode 100644 index 0000000..0a3a3ce --- /dev/null +++ b/src/mem/simple_mem.c @@ -0,0 +1,78 @@ +/* SPDX-License-Identifier: copyleft-next-0.3.1 */ +/* Copyright 2023 Kim Kuparinen < kimi.h.kuparinen@gmail.com > */ + +#include +#include +#include + +#include + +struct simple_mem { + struct component component; + struct component *send; + struct packet pkt; + bool busy; + + size_t size; + uint8_t buf[]; +}; + +static stat simple_mem_clock(struct simple_mem *mem) +{ + if (!mem->busy) + return OK; + + stat r = SEND(mem, mem->send, mem->pkt); + if (r == EBUSY) + return OK; + + mem->busy = false; + return OK; +} + +static stat simple_mem_receive(struct simple_mem *mem, struct component *from, struct packet pkt) +{ + if (mem->busy) + return EBUSY; + + mem->busy = true; + mem->send = from; + + uint64_t offset = pkt.to % mem->size; + if (offset >= mem->size) { + error("read outside memory"); + mem->pkt = response(pkt); + set_flags(&mem->pkt, PACKET_ERROR); + return OK; + } + + if (is_set(&pkt, PACKET_READ)) + checked_copyto(&pkt, mem->buf + offset); + else if (is_set(&pkt, PACKET_WRITE)) + checked_copyfrom(&pkt, mem->buf + offset); + else + abort(); + + mem->pkt = response(pkt); + set_flags(&mem->pkt, PACKET_DONE); + return OK; +} + +struct component *create_simple_mem(size_t size) +{ + struct simple_mem *new = calloc(1, sizeof(struct simple_mem) + size); + if (!new) + return NULL; + + new->size = size; + new->component.receive = (receive_callback)simple_mem_receive; + new->component.clock = (clock_callback)simple_mem_clock; + return (struct component *)new; +} + +void init_simple_mem(struct component *m, uintptr_t addr, size_t size, + void *data) +{ + struct simple_mem *mem = (struct simple_mem *)m; + memcpy(mem->buf + addr, data, size); +} diff --git a/src/mem/source.mk b/src/mem/source.mk new file mode 100644 index 0000000..7d1a717 --- /dev/null +++ b/src/mem/source.mk @@ -0,0 +1 @@ +SOURCES += src/mem/simple_mem.c -- cgit v1.3