mark initgraph nodes red and dimmed if not run
This commit is contained in:
+29
-3
@@ -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",
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
Reference in New Issue
Block a user