From 0ed7b4970920714594d69a9d31b4ecc638e994df Mon Sep 17 00:00:00 2001
From: nekobit <nekobit@noemail.net>
Date: Mon, 17 Oct 2022 20:38:40 +0000
Subject: [PATCH] Memory page

FossilOrigin-Name: d99c3ec4b0090f12c8c3a4fbc26254a65ed3d37b2aaa2c7ef3fb45ff345dbe6d
---
 perl/meta.pm        | 18 ++++++++++++++++-
 src/global_perl.c   |  2 ++
 src/main.c          |  3 +++
 src/memory.c        |  4 ++--
 src/memory_page.c   | 48 +++++++++++++++++++++++++++++++++++++++++++++
 src/memory_page.h   | 27 +++++++++++++++++++++++++
 templates/memory.tt | 27 +++++++++++++++++++++++++
 7 files changed, 126 insertions(+), 3 deletions(-)
 create mode 100644 src/memory_page.c
 create mode 100644 src/memory_page.h
 create mode 100644 templates/memory.tt

diff --git a/perl/meta.pm b/perl/meta.pm
index 5db57fd..8f8b99b 100644
--- a/perl/meta.pm
+++ b/perl/meta.pm
@@ -6,7 +6,7 @@ our @EXPORT = qw(  );
 
 use Exporter 'import';
 
-use template_helpers 'simple_page';
+use template_helpers qw( simple_page to_template );
 
 sub about
 {
@@ -18,4 +18,20 @@ sub license
     simple_page @_, 'license.tt';
 }
 
+sub memory
+{
+    my ($ssn, $data, $mem_alloc_est, $mem_alloc, $mem_free, $mem_time_alloc, $mem_time_freed) = @_;
+
+    my %vars = (
+        ssn => $ssn,
+        mem_alloc_est => $mem_alloc_est,
+        mem_alloc => $mem_alloc,
+        mem_free => $mem_free,
+        mem_time_alloc => $mem_time_alloc,
+        mem_time_freed => $mem_time_freed,
+        );
+    
+    to_template(\%vars, \$data->{'memory.tt'});
+}
+
 1;
diff --git a/src/global_perl.c b/src/global_perl.c
index d649478..9c682e8 100644
--- a/src/global_perl.c
+++ b/src/global_perl.c
@@ -51,6 +51,7 @@
 #include "../templates/license.ctt"
 #include "../templates/login.ctt"
 #include "../templates/status_interactions.ctt"
+#include "../templates/memory.ctt"
 
 PerlInterpreter* my_perl;
 HV* template_files;
@@ -92,6 +93,7 @@ void init_template_files(pTHX)
     hv_stores(template_files, "license.tt", newSVpv(data_license_tt, data_license_tt_size));
     hv_stores(template_files, "login.tt", newSVpv(data_login_tt, data_login_tt_size));
     hv_stores(template_files, "status_interactions.tt", newSVpv(data_status_interactions_tt, data_status_interactions_tt_size));
+    hv_stores(template_files, "memory.tt", newSVpv(data_memory_tt, data_memory_tt_size));
 }
 
 void cleanup_template_files()
diff --git a/src/main.c b/src/main.c
index 0bcfc75..fca3619 100644
--- a/src/main.c
+++ b/src/main.c
@@ -31,6 +31,7 @@
 #include "login.h"
 #include "local_config.h"
 #include "cookie.h"
+#include "memory_page.h"
 #include "query.h"
 #include "status.h"
 #include "lists.h"
@@ -120,6 +121,8 @@ static struct path_info paths[] = {
     { "/quit", exit_treebird },
     { "/exit", exit_treebird },
 #endif
+    // Debug, but cool to see
+    { "/memory_stats", content_memory_stats },
     // API
     { "/treebird_api/v1/notifications", api_notifications },
     { "/treebird_api/v1/interact", api_status_interact },
diff --git a/src/memory.c b/src/memory.c
index e26acac..f13a7cf 100644
--- a/src/memory.c
+++ b/src/memory.c
@@ -51,13 +51,13 @@ void* tb_malloc(size_t size)
 // Nothing....
 void* tb_calloc(size_t nmemb, size_t size)
 {
-    tb_memory_allocated_est += size * nmemb;
+    tb_memory_allocated_est = size * nmemb;
     return calloc(nmemb, size);
 }
 
 void* tb_realloc(void* ptr, size_t size)
 {
-    tb_memory_allocated_est += size;
+    tb_memory_allocated_est = size;
     return realloc(ptr, size);
 }
 
diff --git a/src/memory_page.c b/src/memory_page.c
new file mode 100644
index 0000000..a74b2c5
--- /dev/null
+++ b/src/memory_page.c
@@ -0,0 +1,48 @@
+/*
+ * Treebird - Lightweight frontend for Pleroma
+ * Copyright (C) 2022 Nekobit
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include "memory_page.h"
+#include "base_page.h"
+#include "memory.h"
+
+void content_memory_stats(PATH_ARGS)
+{
+    PERL_STACK_INIT;
+    HV* session_hv = perlify_session(ssn);
+    mXPUSHs(newRV_inc((SV*)session_hv));
+    mXPUSHs(newRV_inc((SV*)template_files));
+    // Args
+    mXPUSHi(tb_memory_allocated_est);
+    mXPUSHi(tb_memory_allocated);
+    mXPUSHi(tb_memory_free);
+    mXPUSHi(tb_memory_times_allocated);
+    mXPUSHi(tb_memory_times_freed);
+
+    PERL_STACK_SCALAR_CALL("meta::memory");
+    char* dup = PERL_GET_STACK_EXIT;
+    
+    struct base_page b = {
+        .category = BASE_CAT_NONE,
+        .content = dup,
+        .session = session_hv,
+        .sidebar_left = NULL
+    };
+
+    render_base_page(&b, req, ssn, api);
+    tb_free(dup);
+}
diff --git a/src/memory_page.h b/src/memory_page.h
new file mode 100644
index 0000000..94fe8ef
--- /dev/null
+++ b/src/memory_page.h
@@ -0,0 +1,27 @@
+/*
+ * Treebird - Lightweight frontend for Pleroma
+ * Copyright (C) 2022 Nekobit
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef MEMORY_PAGE_H
+#define MEMORY_PAGE_H
+#include "memory.h"
+#include "session.h"
+#include "path.h"
+
+void content_memory_stats(PATH_ARGS);
+
+#endif // MEMORY_PAGE_H
diff --git a/templates/memory.tt b/templates/memory.tt
new file mode 100644
index 0000000..87e11ac
--- /dev/null
+++ b/templates/memory.tt
@@ -0,0 +1,27 @@
+
+<div class="simple-page">
+    <h1>Memory information</h1>
+    <p>Information scaling doesn't mean there is a memleak! Memory free'd won't match because we haven't hit the next free since this page was rendered.</p>
+    <table class="present">
+        <tr>
+            <th>Memory Allocated (malloc)</th>
+            <td>$mem_alloc</td>
+        </tr>
+        <tr>
+            <th>Memory Allocated Total (estimated)</th>
+            <td>$mem_alloc_est</td>
+        </tr>
+        <tr>
+            <th>Memory Free</th>
+            <td>$mem_free</td>
+        </tr>
+        <tr>
+            <th>Times Allocated (total)</th>
+            <td>$mem_time_alloc</td>
+        </tr>
+        <tr>
+            <th>Times Free'd (total)</th>
+            <td>$mem_time_freed</td>
+        </tr>
+    </table>
+</div>
