diff options
| author | Kimplul <kimi.h.kuparinen@gmail.com> | 2024-09-24 16:51:51 +0300 |
|---|---|---|
| committer | Kimplul <kimi.h.kuparinen@gmail.com> | 2024-09-24 18:47:13 +0300 |
| commit | fecb86f6093c1e8aed6ab05c29c5af9d0cb93157 (patch) | |
| tree | 10171c839d77167fc98fbae0b315d2c87aa13fa5 /src/components/grid/router.c | |
| parent | b1d67364b4b4832b8efed112f7b0ead1a0b3cd3b (diff) | |
| download | gran-fecb86f6093c1e8aed6ab05c29c5af9d0cb93157.tar.gz gran-fecb86f6093c1e8aed6ab05c29c5af9d0cb93157.zip | |
initial work towards message passing interface
+ As they are currently implemented, grid *may* get stuck if two nodes
try to send to eachother at the same time, I should probably add in
some kind of input buffer as well
Diffstat (limited to 'src/components/grid/router.c')
| -rw-r--r-- | src/components/grid/router.c | 72 |
1 files changed, 47 insertions, 25 deletions
diff --git a/src/components/grid/router.c b/src/components/grid/router.c index bdb05c8..63c4011 100644 --- a/src/components/grid/router.c +++ b/src/components/grid/router.c @@ -1,3 +1,6 @@ +#include <stdbool.h> + +#include <gran/grid/node.h> #include <gran/grid/router.h> #include <gran/vec.h> @@ -12,6 +15,10 @@ struct node_router { struct component *ascend; struct vec regions; uint8_t u, v, x, y; + + struct component *send; + struct packet pkt; + bool busy; }; static struct router_region *find_region(struct node_router *router, uint32_t addr) @@ -26,40 +33,55 @@ static struct router_region *find_region(struct node_router *router, uint32_t ad return NULL; } -static stat router_write(struct node_router *router, struct packet *pkt) +static stat router_clock(struct node_router *router) { - uint64_t addr = packet_addr(pkt); - uint8_t u = (addr >> 56) & 0xff; - uint8_t v = (addr >> 48) & 0xff; - uint8_t x = (addr >> 40) & 0xff; - uint8_t y = (addr >> 32) & 0xff; + if (!router->busy) + return OK; - if (router->u != u || router->v != v || router->x != x || router->y != y) - return write(router->ascend, pkt); + stat r = SEND(router, router->send, router->pkt); + if (r == EBUSY) + return OK; - struct router_region *region = find_region(router, addr); - if (!region) - return write(router->ascend, pkt); - - return write(region->component, pkt); + router->busy = false; + return OK; } -static stat router_read(struct node_router *router, struct packet *pkt) +static stat router_receive(struct node_router *router, struct component *from, struct packet pkt) { - uint64_t addr = packet_addr(pkt); - uint8_t u = (addr >> 56) & 0xff; - uint8_t v = (addr >> 48) & 0xff; - uint8_t x = (addr >> 40) & 0xff; - uint8_t y = (addr >> 32) & 0xff; + if (router->busy) + return EBUSY; + + router->busy = true; - if (router->u != u || router->v != v || router->x != x || router->y != y) - return read(router->ascend, pkt); + uint64_t addr = pkt.to; + uint8_t u; + uint8_t v; + uint8_t x; + uint8_t y; + addr_grid(addr, NULL, &x, &y, &u, &v); + + router->pkt = pkt; + + if (router->u != u || router->v != v || router->x != x || router->y != y) { + if (!router->ascend) + goto nosuch; + + router->send = router->ascend; + return OK; + } struct router_region *region = find_region(router, addr); if (!region) - return read(router->ascend, pkt); + goto nosuch; - return read(region->component, pkt); + router->send = region->component; + return OK; + +nosuch: + router->send = from; + router->pkt = response(pkt); + set_flags(&router->pkt, PACKET_ERROR); + return OK; } struct component *create_node_router(uint8_t u, uint8_t v, uint8_t x, uint8_t y) @@ -73,8 +95,8 @@ struct component *create_node_router(uint8_t u, uint8_t v, uint8_t x, uint8_t y) router->x = x; router->y = y; - router->component.write = (write_callback)router_write; - router->component.read = (read_callback)router_read; + router->component.receive = (receive_callback)router_receive; + router->component.clock = (clock_callback)router_clock; router->regions = vec_create(sizeof(struct router_region)); return (struct component *)router; |
