aboutsummaryrefslogtreecommitdiff
path: root/src/components/grid
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2024-09-24 16:51:51 +0300
committerKimplul <kimi.h.kuparinen@gmail.com>2024-09-24 18:47:13 +0300
commitfecb86f6093c1e8aed6ab05c29c5af9d0cb93157 (patch)
tree10171c839d77167fc98fbae0b315d2c87aa13fa5 /src/components/grid
parentb1d67364b4b4832b8efed112f7b0ead1a0b3cd3b (diff)
downloadgran-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')
-rw-r--r--src/components/grid/node.c91
-rw-r--r--src/components/grid/router.c72
2 files changed, 106 insertions, 57 deletions
diff --git a/src/components/grid/node.c b/src/components/grid/node.c
index 0aed768..57ef7ed 100644
--- a/src/components/grid/node.c
+++ b/src/components/grid/node.c
@@ -5,73 +5,101 @@
* Each node should have a router beneath it, just to simplify my life. A router
* is basically a bus with a fallback ascension path.
*/
+#include <stdbool.h>
+
#include <gran/grid/node.h>
struct grid_node {
struct component component;
uint8_t u, v, x, y;
struct component *left, *right, *up, *down, *ascend, *lower;
+
+ struct component *send;
+ struct packet pkt;
+ bool busy;
};
-typedef read_callback callback;
+static stat grid_clock(struct grid_node *grid)
+{
+ if (!grid->busy)
+ return OK;
+
+ stat r = SEND(grid, grid->send, grid->pkt);
+ if (r == EBUSY)
+ return OK;
+
+ grid->busy = false;
+ return r;
+}
-static stat grid_route(struct grid_node *grid, struct packet *pkt, callback op)
+static stat grid_receive(struct grid_node *grid, 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 (grid->busy)
+ return EBUSY;
- if (grid->u == u && grid->v == v && grid->x == x && grid->y == y)
- return op(grid->lower, pkt);
+ uint8_t u;
+ uint8_t v;
+ uint8_t x;
+ uint8_t y;
+ uint64_t addr = pkt.to;
+ addr_grid(addr, NULL, &x, &y, &u, &v);
+
+ grid->busy = true;
+ grid->pkt = pkt;
+
+ if (grid->u == u && grid->v == v && grid->x == x && grid->y == y) {
+ if (!grid->lower)
+ goto nosuch;
+
+ grid->send = grid->lower;
+ return OK;
+ }
if (grid->u != u || grid->v != v) {
if (!grid->ascend)
- return EBUS;
+ goto nosuch;
- return op(grid->ascend, pkt);
+ grid->send = grid->ascend;
+ return OK;
}
if (y < grid->y) {
if (!grid->down)
- return EBUS;
+ goto nosuch;
- return op(grid->down, pkt);
+ grid->send = grid->down;
+ return OK;
}
if (y > grid->y) {
if (!grid->up)
- return EBUS;
+ goto nosuch;
- return op(grid->up, pkt);
+ grid->send = grid->up;
+ return OK;
}
if (x < grid->x) {
if (!grid->left)
- return EBUS;
+ goto nosuch;
- return op(grid->left, pkt);
+ grid->send = grid->left;
+ return OK;
}
if (x > grid->x) {
if (!grid->right)
return EBUS;
- return op(grid->right, pkt);
+ grid->send = grid->right;
+ return OK;
}
- return EBUS;
-}
-
-static stat grid_write(struct grid_node *node, struct packet *pkt)
-{
- return grid_route(node, pkt, write);
-}
-
-static stat grid_read(struct grid_node *node, struct packet *pkt)
-{
- return grid_route(node, pkt, read);
+nosuch:
+ grid->send = from;
+ grid->pkt = response(pkt);
+ set_flags(&grid->pkt, PACKET_ERROR);
+ return OK;
}
struct component *create_grid_node(uint8_t u, uint8_t v, uint8_t x, uint8_t y)
@@ -80,13 +108,12 @@ struct component *create_grid_node(uint8_t u, uint8_t v, uint8_t x, uint8_t y)
if (!node)
return NULL;
+ node->component.receive = (receive_callback)grid_receive;
+ node->component.clock = (clock_callback)grid_clock;
node->u = u;
node->v = v;
node->x = x;
node->y = y;
- node->component.write = (write_callback)grid_write;
- node->component.read = (read_callback)grid_read;
-
return (struct component *)node;
}
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;