|
@@ -10,6 +10,7 @@
|
|
|
#include <AK/JsonObject.h>
|
|
|
#include <AK/NumberFormat.h>
|
|
|
#include <LibCore/File.h>
|
|
|
+#include <LibCore/Object.h>
|
|
|
#include <LibGUI/BoxLayout.h>
|
|
|
#include <LibGUI/Label.h>
|
|
|
#include <LibGUI/Painter.h>
|
|
@@ -39,6 +40,8 @@ MemoryStatsWidget::MemoryStatsWidget(GraphWidget* graph)
|
|
|
VERIFY(!s_the);
|
|
|
s_the = this;
|
|
|
|
|
|
+ REGISTER_STRING_PROPERTY("memory_graph", graph_widget_name, set_graph_widget_via_name);
|
|
|
+
|
|
|
set_fixed_height(110);
|
|
|
|
|
|
set_layout<GUI::VerticalBoxLayout>();
|
|
@@ -73,6 +76,29 @@ void MemoryStatsWidget::set_graph_widget(GraphWidget& graph)
|
|
|
m_graph = &graph;
|
|
|
}
|
|
|
|
|
|
+void MemoryStatsWidget::set_graph_widget_via_name(String name)
|
|
|
+{
|
|
|
+ m_graph_widget_name = move(name);
|
|
|
+ if (!m_graph_widget_name.is_null()) {
|
|
|
+ // FIXME: We assume here that the graph widget is a sibling or descendant of a sibling. This prevents more complex hierarchies.
|
|
|
+ auto* maybe_graph = parent_widget()->find_descendant_of_type_named<GraphWidget>(m_graph_widget_name);
|
|
|
+ if (maybe_graph) {
|
|
|
+ m_graph = maybe_graph;
|
|
|
+ // Delete the stored graph name to signal that we found the widget
|
|
|
+ m_graph_widget_name = {};
|
|
|
+ } else {
|
|
|
+ dbgln("MemoryStatsWidget: Couldn't find graph of name '{}', retrying later.", m_graph_widget_name);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+String MemoryStatsWidget::graph_widget_name()
|
|
|
+{
|
|
|
+ if (m_graph)
|
|
|
+ return m_graph->name();
|
|
|
+ return m_graph_widget_name;
|
|
|
+}
|
|
|
+
|
|
|
static inline u64 page_count_to_bytes(size_t count)
|
|
|
{
|
|
|
return count * 4096;
|
|
@@ -115,6 +141,11 @@ void MemoryStatsWidget::refresh()
|
|
|
m_kfree_count_label->set_text(String::formatted("{}", kfree_call_count));
|
|
|
m_kmalloc_difference_label->set_text(String::formatted("{:+}", kmalloc_call_count - kfree_call_count));
|
|
|
|
|
|
+ // Because the initialization order of us and the graph is unknown, we might get a couple of updates where the graph widget lookup fails.
|
|
|
+ // Therefore, we can retry indefinitely. (Should not be too much of a performance hit, as we don't update that often.)
|
|
|
+ if (!m_graph)
|
|
|
+ set_graph_widget_via_name(move(m_graph_widget_name));
|
|
|
+
|
|
|
if (m_graph) {
|
|
|
m_graph->set_max(page_count_to_bytes(total_userphysical_and_swappable_pages) + kmalloc_bytes_total);
|
|
|
m_graph->add_value({ page_count_to_bytes(user_physical_committed), page_count_to_bytes(user_physical_allocated), kmalloc_bytes_total });
|