mark initgraph nodes red and dimmed if not run

This commit is contained in:
2026-10-12 16:03:36 +02:00
parent 350e65837b
commit bc5f01dab6
3 changed files with 47 additions and 14 deletions
+29 -3
View File
@@ -17,6 +17,7 @@ static void initgraph_option(bool value) {
CMDLINE_OPTION("initgraph", "Print the init graph in DOT format after running", initgraph_option);
static bool edges_linked = false;
static struct init_node* failed_node = nullptr;
struct init_queue {
struct init_node* head;
@@ -96,6 +97,7 @@ static void reach_node(struct init_node* node, struct boot_info* info) {
log_status("Skipping stage \"%s\"\n", node->name);
} else {
log_status("Running stage \"%s\"\n", node->name);
failed_node = node;
switch (node->action) {
case INIT_EMPTY:
break;
@@ -103,10 +105,14 @@ static void reach_node(struct init_node* node, struct boot_info* info) {
node->callback(info);
break;
case INIT_GATE:
if (!node->gate(info))
if (!node->gate(info)) {
node->disabled = true;
node->failed = true;
}
break;
}
failed_node = nullptr;
node->executed = true;
}
node->done = true;
}
@@ -115,13 +121,31 @@ static void dump() {
kprintf("digraph initgraph {\n");
for (auto cur = __ld_initgraph_nodes_start; cur < __ld_initgraph_nodes_end; cur++) {
struct init_node* node = *cur;
kprintf("\tn%p [label=\"%s\"];\n", node, node->name);
const char* style = "";
if (node->failed || node == failed_node)
style = ", color=red, fontcolor=red";
else if (!node->executed)
style = ", color=gray, fontcolor=gray";
kprintf("\tn%p [label=\"%s\"%s];\n", node, node->name, style);
for (struct init_edge* edge = node->in_edges; edge; edge = edge->next_in)
kprintf("\tn%p -> n%p;\n", edge->source, edge->target);
kprintf(
"\tn%p -> n%p%s;\n",
edge->source,
edge->target,
edge->source->executed && edge->target->executed ? "" : " [color=gray]"
);
}
kprintf("}\n");
}
void initgraph_panic() {
static bool dumping = false;
if (!dump_graph || !failed_node || dumping)
return;
dumping = true;
dump();
}
void initgraph_run(struct init_node* goal, struct boot_info* info) {
if (!edges_linked)
link_edges();
@@ -153,6 +177,8 @@ void initgraph_run(struct init_node* goal, struct boot_info* info) {
}
for (auto cur = __ld_initgraph_nodes_start; cur < __ld_initgraph_nodes_end; cur++) {
if ((*cur)->wanted && !(*cur)->done)
failed_node = *cur;
assert(
!(*cur)->wanted || (*cur)->done,
"The dependencies for stage \"%s\" could not be resolved",
+3
View File
@@ -1,4 +1,5 @@
#include <zinnia/alloc.h>
#include <zinnia/initgraph.h>
#include <zinnia/irq.h>
#include <zinnia/ksyms.h>
#include <zinnia/panic.h>
@@ -64,6 +65,8 @@ void panic(const char* msg, ...) {
print_backtrace();
panic_log("End of panic message\n");
initgraph_panic();
while (true) {
irq_wait();
}
+8 -4
View File
@@ -41,6 +41,8 @@ struct init_node {
bool wanted;
bool done;
bool disabled;
bool executed;
bool failed;
struct init_edge* in_edges;
struct init_edge* out_edges;
struct init_node* queue_next;
@@ -49,8 +51,8 @@ struct init_node {
#define INIT_EXTERN(node) extern struct init_node node[1]
#define INIT_TASK(node, display, ...) \
struct init_node node[1] = {{ \
.name = (display), \
struct init_node node[1] = { \
{.name = (display), \
__VA_OPT__( \
.action = _Generic( \
(__VA_ARGS__), \
@@ -58,8 +60,8 @@ struct init_node {
bool (*)(struct boot_info*): INIT_GATE \
), \
.func = (void*)(__VA_ARGS__), \
) \
}}; \
)} \
}; \
[[__used, __section(".initgraph.nodes")]] \
static struct init_node* const CONCAT(node, _initgraph_node) = node
@@ -80,3 +82,5 @@ struct init_node {
#define INIT_ENTAILS(node, ...) _INIT_EDGES(UNIQUE_IDENT(init_edges), node, false, __VA_ARGS__)
void initgraph_run(struct init_node* goal, struct boot_info* info);
void initgraph_panic();