feat(v4.0.0): the wait in the engine -- a node offers a word and sleeps
A node stores a word to offer on any of its ports and fetches the wait: it is blocked until a word comes for it or one of its offers is taken, and the fabric does the handing over in one step. The port block moves in the nucleus's map to make room for the new addresses. Nothing uses it yet. MESH.md 7c; plan step 6d task 1. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
dfabfa46f6
commit
075385ab63
@@ -209,6 +209,36 @@ unsigned v4_fabric_step(v4_fabric *f)
|
||||
for (i = 0; i < f->capacity; i++)
|
||||
if (awake(f, i) && f->place[i].node->n.reading && !f->place[i].node->n.given) done += hand_over_read(f, i);
|
||||
|
||||
/* THE WAIT (docs/v4.0.0/MESH.md 7c). A node in the wait that was given a
|
||||
* word above is no longer in it: a word for a node comes before its own
|
||||
* offer. Of the rest, each offer is taken by whoever is ready for it: a
|
||||
* device that takes, or a node blocked reading that port or any -- which
|
||||
* a node in the wait is, so of two that offer to each other the one at
|
||||
* the lower place writes and the other's offers are withdrawn. */
|
||||
for (i = 0; i < f->capacity; i++) {
|
||||
v4_node *n;
|
||||
unsigned k;
|
||||
if (!awake(f, i)) continue;
|
||||
n = &f->place[i].node->n;
|
||||
if (!v4_node_in_wait(n)) continue;
|
||||
for (k = 0; k < V4_PORTS; k++) {
|
||||
const v4_wire *w = &f->place[i].wire[k];
|
||||
if (!(n->offers & (1u << k))) continue;
|
||||
if (w->kind == V4_WIRE_DEVICE) {
|
||||
if (w->device->take && w->device->take(w->device->self, n->offer[k])) { (void)v4_node_offer_taken(n, k); done++; break; }
|
||||
} else if (w->kind == V4_WIRE_NODE && awake(f, w->node)) {
|
||||
v4_node *r = &f->place[w->node].node->n;
|
||||
if (r->reading && !r->given && (r->read_port == w->port || r->read_port == V4_PORT_ANY)) {
|
||||
v4_cell word = n->offer[k];
|
||||
(void)v4_node_offer_taken(n, k);
|
||||
v4_node_port_give(r, w->port, word);
|
||||
done++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* a node blocked on the first word of a message to a node that is not
|
||||
* reading, while a device of its own has something for it */
|
||||
if (f->interrupt_error != 0)
|
||||
@@ -236,6 +266,11 @@ unsigned v4_fabric_step(v4_fabric *f)
|
||||
if ((n->asking && f->place[i].wire[n->ask_port].kind == V4_WIRE_NONE)
|
||||
|| (n->reading && !n->given && n->read_port != V4_PORT_ANY && f->place[i].wire[n->read_port].kind == V4_WIRE_NONE))
|
||||
done += (unsigned)v4_node_port_gone(n, f->gone_error);
|
||||
else if (v4_node_in_wait(n)) { /* an offer on a port with nothing on it */
|
||||
unsigned k;
|
||||
for (k = 0; k < V4_PORTS; k++)
|
||||
if ((n->offers & (1u << k)) && f->place[i].wire[k].kind == V4_WIRE_NONE) { done += (unsigned)v4_node_port_gone(n, f->gone_error); break; }
|
||||
}
|
||||
}
|
||||
|
||||
return done;
|
||||
|
||||
Reference in New Issue
Block a user