GenericGraphSlot
Description
Type-erased slot layout used by the runtime helpers in Source/Misra/Std/Container/Graph.c. GraphSlot(T) below is the typed variant; both have identical layout (the data field is a pointer, and void * / T * share representation).
Usage example (Cross-references)
Usage examples (Cross-references)
- In
Type.h:92:
u32 generation;
u32 flags;
} GenericGraphSlot;
typedef Vec(GenericGraphSlot) GraphSlots;- In
Type.h:94:
} GenericGraphSlot;
typedef Vec(GenericGraphSlot) GraphSlots;
typedef Vec(u32) GraphFreeIndices;- In
Graph.c:42:
}
static bool graph_slot_is_occupied(const GenericGraphSlot *slot) {
return (slot->flags & GRAPH_SLOT_OCCUPIED) != 0;
}- In
Graph.c:46:
}
static bool graph_slot_is_marked(const GenericGraphSlot *slot) {
return (slot->flags & GRAPH_SLOT_MARKED) != 0;
}- In
Graph.c:56:
}
static GenericGraphSlot *graph_slot_ptr_raw(GenericGraph *graph, u32 index) {
return VecPtrAt(&graph->slots, index);
}- In
Graph.c:60:
}
static const GenericGraphSlot *graph_slot_ptr_const_raw(const GenericGraph *graph, u32 index) {
return VecPtrAt((GraphSlots *)&graph->slots, index);
}- In
Graph.c:67:
u32 index;
u32 generation;
const GenericGraphSlot *slot;
index = GraphNodeIdIndex(node_id);- In
Graph.c:88:
}
static GenericGraphSlot *graph_require_live_slot(GenericGraph *graph, GraphNodeId node_id) {
graph_validate_node_id(graph, node_id);
return graph_slot_ptr_raw(graph, GraphNodeIdIndex(node_id));- In
Graph.c:93:
}
static const GenericGraphSlot *graph_require_live_slot_const(const GenericGraph *graph, GraphNodeId node_id) {
graph_validate_node_id(graph, node_id);
return graph_slot_ptr_const_raw(graph, GraphNodeIdIndex(node_id));- In
Graph.c:147:
}
static void graph_ensure_slot_generation_available(GenericGraphSlot *slot) {
if (slot->generation == UINT32_MAX) {
LOG_FATAL("graph slot generation exhausted");- In
Graph.c:153:
}
static void graph_release_slot(GenericGraph *graph, GenericGraphSlot *slot, size item_size) {
if (!graph_slot_is_occupied(slot)) {
return;- In
Graph.c:265:
while (idx < VecLen(neighbors)) {
GraphNodeId neighbor_id = VecAt(neighbors, idx);
const GenericGraphSlot *slot;
graph_validate_node_index_raw(graph, GraphNodeIdIndex(neighbor_id));- In
Graph.c:356:
for (slot_index = 0; slot_index < VecLen(&graph->slots); slot_index++) {
const GenericGraphSlot *slot = VecPtrAt((GraphSlots *)&graph->slots, slot_index);
GraphNodeId self_id = graph_make_node_id((u32)slot_index, slot->generation);
u64 neighbor_i;- In
Graph.c:379:
for (neighbor_i = 0; neighbor_i < VecLen(&slot->out_neighbors); neighbor_i++) {
GraphNodeId neighbor_id = VecAt(&slot->out_neighbors, neighbor_i);
const GenericGraphSlot *target_slot;
graph_validate_node_id(graph, neighbor_id);- In
Graph.c:390:
for (neighbor_i = 0; neighbor_i < VecLen(&slot->in_neighbors); neighbor_i++) {
GraphNodeId predecessor_id = VecAt(&slot->in_neighbors, neighbor_i);
const GenericGraphSlot *source_slot;
graph_validate_node_id(graph, predecessor_id);- In
Graph.c:461:
clear_graph(graph, item_size);
deinit_vec(GENERIC_VEC(&graph->slots), sizeof(GenericGraphSlot));
deinit_vec(GENERIC_VEC(&graph->free_indices), sizeof(u32));
deinit_vec(GENERIC_VEC(&graph->pending_edge_removals), sizeof(GraphPendingEdgeRemoval));- In
Graph.c:474:
for (slot_index = 0; slot_index < VecLen(&graph->slots); slot_index++) {
GenericGraphSlot *slot = VecPtrAt(&graph->slots, slot_index);
if (graph_slot_is_occupied(slot)) {
graph_release_slot(graph, slot, item_size);- In
Graph.c:510:
success = reserve_vec(GENERIC_VEC(&graph->free_indices), sizeof(u32), n) &&
reserve_vec(GENERIC_VEC(&graph->slots), sizeof(GenericGraphSlot), n);
if (!success) {
return false;- In
Graph.c:524:
GraphNodeId graph_push_node(GenericGraph *graph, const void *item_data, size item_size) {
GraphNodeId node_id;
GenericGraphSlot slot;
GenericGraphSlot *slot_ptr;
u32 slot_index;- In
Graph.c:525:
GraphNodeId node_id;
GenericGraphSlot slot;
GenericGraphSlot *slot_ptr;
u32 slot_index;- In
Graph.c:590:
GENERIC_VEC(&graph->slots),
(const u8 *)&slot,
sizeof(GenericGraphSlot),
VecLen(&graph->slots),
1- In
Graph.c:627:
u32 index;
u32 generation;
GenericGraphSlot *slot;
if (!graph) {- In
Graph.c:766:
u64 GraphNodeVisit(GraphNode node) {
GenericGraph *graph;
GenericGraphSlot *slot;
node = graph_validate_node_handle(node);- In
Graph.c:782:
void GraphNodeUnvisit(GraphNode node) {
GenericGraph *graph;
GenericGraphSlot *slot;
node = graph_validate_node_handle(node);- In
Graph.c:793:
u64 GraphNodeVisitCount(GraphNode node) {
GenericGraph *graph;
const GenericGraphSlot *slot;
node = graph_validate_node_handle(node);- In
Graph.c:807:
bool GraphMarkNodeForDeletion(GraphNode node) {
GenericGraph *graph;
GenericGraphSlot *slot;
node = graph_validate_node_handle(node);- In
Graph.c:824:
bool GraphNodeMarkedForDeletion(GraphNode node) {
GenericGraph *graph;
const GenericGraphSlot *slot;
node = graph_validate_node_handle(node);- In
Graph.c:835:
bool GraphUnmarkNodeForDeletion(GraphNode node) {
GenericGraph *graph;
GenericGraphSlot *slot;
node = graph_validate_node_handle(node);- In
Graph.c:920:
for (slot_index = 0; slot_index < VecLen(&graph->slots); slot_index++) {
GenericGraphSlot *slot = VecPtrAt(&graph->slots, slot_index);
if (graph_slot_is_occupied(slot) && graph_slot_is_marked(slot)) {
GraphNodeId marked_id = graph_make_node_id((u32)slot_index, slot->generation);- In
Graph.c:928:
for (slot_index = 0; slot_index < VecLen(&graph->slots); slot_index++) {
GenericGraphSlot *slot = VecPtrAt(&graph->slots, slot_index);
if (graph_slot_is_occupied(slot) && !graph_slot_is_marked(slot)) {
GraphNodeId live_id = graph_make_node_id((u32)slot_index, slot->generation);- In
Graph.c:936:
for (slot_index = 0; slot_index < VecLen(&graph->slots); slot_index++) {
GenericGraphSlot *slot = VecPtrAt(&graph->slots, slot_index);
if (graph_slot_is_occupied(slot) && graph_slot_is_marked(slot)) {
if (VecLen(&slot->out_neighbors) || VecLen(&slot->in_neighbors)) {- In
Graph.c:980:
while (iter->slot_index < VecLen(&iter->graph->slots)) {
u32 index = (u32)iter->slot_index;
GenericGraphSlot *slot = VecPtrAt(&iter->graph->slots, iter->slot_index);
iter->slot_index += 1; // logical lengths to 0 (stale b remains in a.out's buffer at index 0) so
// the graph looks edge-free while the pending removal still names a->b.
GenericGraphSlot *slot_a = (GenericGraphSlot *)VecPtrAt(&GENERIC_GRAPH(&graph)->slots, GraphNodeIdIndex(a));
GenericGraphSlot *slot_b = (GenericGraphSlot *)VecPtrAt(&GENERIC_GRAPH(&graph)->slots, GraphNodeIdIndex(b));
slot_a->out_neighbors.length = 0; // the graph looks edge-free while the pending removal still names a->b.
GenericGraphSlot *slot_a = (GenericGraphSlot *)VecPtrAt(&GENERIC_GRAPH(&graph)->slots, GraphNodeIdIndex(a));
GenericGraphSlot *slot_b = (GenericGraphSlot *)VecPtrAt(&GENERIC_GRAPH(&graph)->slots, GraphNodeIdIndex(b));
slot_a->out_neighbors.length = 0;
slot_b->in_neighbors.length = 0; // neighbor id so its generation is 0 (an always-invalid generation),
// without bumping the mutation epoch or re-flagging the validated bit.
GenericGraphSlot *slot_a = (GenericGraphSlot *)VecPtrAt(&GENERIC_GRAPH(&graph)->slots, GraphNodeIdIndex(a));
GraphNodeId *entry = VecPtrAt(&slot_a->out_neighbors, 0);
*entry = (GraphNodeId)GraphNodeIdIndex(b); // Intentional bypass: rewrite `b`'s sole in-neighbor (a) so its generation
// is 0, leaving the epoch and validated bit untouched.
GenericGraphSlot *slot_b = (GenericGraphSlot *)VecPtrAt(&GENERIC_GRAPH(&graph)->slots, GraphNodeIdIndex(b));
GraphNodeId *entry = VecPtrAt(&slot_b->in_neighbors, 0);
*entry = (GraphNodeId)GraphNodeIdIndex(a);- In
Graph.Type.c:10:
// Fetch the type-erased slot for a node id (slots vec is shared-layout).
static GenericGraphSlot *mutant_slot(void *graph_handle, GraphNodeId id) {
GenericGraph *g = GENERIC_GRAPH(graph_handle);
return (GenericGraphSlot *)VecPtrAt(&g->slots, GraphNodeIdIndex(id));- In
Graph.Type.c:12:
static GenericGraphSlot *mutant_slot(void *graph_handle, GraphNodeId id) {
GenericGraph *g = GENERIC_GRAPH(graph_handle);
return (GenericGraphSlot *)VecPtrAt(&g->slots, GraphNodeIdIndex(id));
}- In
Graph.Type.c:248:
GraphAddEdge(&graph, c, b);
GenericGraphSlot *b_slot = mutant_slot(&graph, b);
// b.in_neighbors is [a, c]; overwrite the 'a' entry with 'c' -> [c, c].
*VecPtrAt(&b_slot->in_neighbors, 0) = c;- In
Graph.Type.c:280:
GraphAddEdge(&graph, b, c);
GenericGraphSlot *c_slot = mutant_slot(&graph, c);
// c.in_neighbors is [a, b]; overwrite the 'a' entry with 'b' -> [b, b].
*VecPtrAt(&c_slot->in_neighbors, 0) = b;- In
Graph.Type.c:314:
GraphAddEdge(&graph, b, c);
GenericGraphSlot *b_slot = mutant_slot(&graph, b);
// b.out_neighbors is [a, c]; overwrite the 'a' entry with 'c' -> [c, c].
*VecPtrAt(&b_slot->out_neighbors, 0) = c;- In
Graph.Type.c:346:
GraphAddEdge(&graph, c, b);
GenericGraphSlot *c_slot = mutant_slot(&graph, c);
// c.out_neighbors is [a, b]; overwrite the 'a' entry with 'b' -> [b, b].
*VecPtrAt(&c_slot->out_neighbors, 0) = b;- In
Graph.Init.c:56:
// `graph.slots` is the typed `Vec(GraphSlot(int))`, so iterate via
// the runtime-shared layout to avoid an anonymous-struct annotation.
GenericGraphSlot *slot = (GenericGraphSlot *)VecPtrAt(&GENERIC_GRAPH(&graph)->slots, slot_index);
result = result && (slot->data == NULL);
result = result && (slot->visit_count == 0);
Last updated on