diff options
| author | Kimplul <kimi.h.kuparinen@gmail.com> | 2024-09-25 21:00:16 +0300 |
|---|---|---|
| committer | Kimplul <kimi.h.kuparinen@gmail.com> | 2024-09-25 21:00:16 +0300 |
| commit | 6d0e7c5eba49efc171e63ff2631722a5c7f95460 (patch) | |
| tree | 9159d22c6ee1ee2949dcf8455998405b031cb351 /src/mem/simple_mem.c | |
| parent | fecb86f6093c1e8aed6ab05c29c5af9d0cb93157 (diff) | |
| download | gran-6d0e7c5eba49efc171e63ff2631722a5c7f95460.tar.gz gran-6d0e7c5eba49efc171e63ff2631722a5c7f95460.zip | |
technically speaking deadlock free, but starves
Diffstat (limited to 'src/mem/simple_mem.c')
| -rw-r--r-- | src/mem/simple_mem.c | 78 |
1 files changed, 78 insertions, 0 deletions
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 <string.h> +#include <stdlib.h> +#include <stdbool.h> + +#include <gran/mem/simple_mem.h> + +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); +} |
