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); CMDLINE_OPTION("initgraph", "Print the init graph in DOT format after running", initgraph_option);
static bool edges_linked = false; static bool edges_linked = false;
static struct init_node* failed_node = nullptr;
struct init_queue { struct init_queue {
struct init_node* head; 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); log_status("Skipping stage \"%s\"\n", node->name);
} else { } else {
log_status("Running stage \"%s\"\n", node->name); log_status("Running stage \"%s\"\n", node->name);
failed_node = node;
switch (node->action) { switch (node->action) {
case INIT_EMPTY: case INIT_EMPTY:
break; break;
@@ -103,10 +105,14 @@ static void reach_node(struct init_node* node, struct boot_info* info) {
node->callback(info); node->callback(info);
break; break;
case INIT_GATE: case INIT_GATE:
if (!node->gate(info)) if (!node->gate(info)) {
node->disabled = true; node->disabled = true;
node->failed = true;
}
break; break;
} }
failed_node = nullptr;
node->executed = true;
} }
node->done = true; node->done = true;
} }
@@ -115,13 +121,31 @@ static void dump() {
kprintf("digraph initgraph {\n"); kprintf("digraph initgraph {\n");
for (auto cur = __ld_initgraph_nodes_start; cur < __ld_initgraph_nodes_end; cur++) { for (auto cur = __ld_initgraph_nodes_start; cur < __ld_initgraph_nodes_end; cur++) {
struct init_node* node = *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) 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"); 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) { void initgraph_run(struct init_node* goal, struct boot_info* info) {
if (!edges_linked) if (!edges_linked)
link_edges(); 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++) { for (auto cur = __ld_initgraph_nodes_start; cur < __ld_initgraph_nodes_end; cur++) {
if ((*cur)->wanted && !(*cur)->done)
failed_node = *cur;
assert( assert(
!(*cur)->wanted || (*cur)->done, !(*cur)->wanted || (*cur)->done,
"The dependencies for stage \"%s\" could not be resolved", "The dependencies for stage \"%s\" could not be resolved",
+3
View File
@@ -1,4 +1,5 @@
#include <zinnia/alloc.h> #include <zinnia/alloc.h>
#include <zinnia/initgraph.h>
#include <zinnia/irq.h> #include <zinnia/irq.h>
#include <zinnia/ksyms.h> #include <zinnia/ksyms.h>
#include <zinnia/panic.h> #include <zinnia/panic.h>
@@ -64,6 +65,8 @@ void panic(const char* msg, ...) {
print_backtrace(); print_backtrace();
panic_log("End of panic message\n"); panic_log("End of panic message\n");
initgraph_panic();
while (true) { while (true) {
irq_wait(); irq_wait();
} }
+8 -4
View File
@@ -41,6 +41,8 @@ struct init_node {
bool wanted; bool wanted;
bool done; bool done;
bool disabled; bool disabled;
bool executed;
bool failed;
struct init_edge* in_edges; struct init_edge* in_edges;
struct init_edge* out_edges; struct init_edge* out_edges;
struct init_node* queue_next; struct init_node* queue_next;
@@ -49,8 +51,8 @@ struct init_node {
#define INIT_EXTERN(node) extern struct init_node node[1] #define INIT_EXTERN(node) extern struct init_node node[1]
#define INIT_TASK(node, display, ...) \ #define INIT_TASK(node, display, ...) \
struct init_node node[1] = {{ \ struct init_node node[1] = { \
.name = (display), \ {.name = (display), \
__VA_OPT__( \ __VA_OPT__( \
.action = _Generic( \ .action = _Generic( \
(__VA_ARGS__), \ (__VA_ARGS__), \
@@ -58,8 +60,8 @@ struct init_node {
bool (*)(struct boot_info*): INIT_GATE \ bool (*)(struct boot_info*): INIT_GATE \
), \ ), \
.func = (void*)(__VA_ARGS__), \ .func = (void*)(__VA_ARGS__), \
) \ )} \
}}; \ }; \
[[__used, __section(".initgraph.nodes")]] \ [[__used, __section(".initgraph.nodes")]] \
static struct init_node* const CONCAT(node, _initgraph_node) = node 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__) #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_run(struct init_node* goal, struct boot_info* info);
void initgraph_panic();