aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/memory.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/memory.c')
-rw-r--r--src/memory.c31
1 files changed, 20 insertions, 11 deletions
diff --git a/src/memory.c b/src/memory.c
index 6d7645c..26cde55 100644
--- a/src/memory.c
+++ b/src/memory.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012-2023 Robin Haberkorn
+ * Copyright (C) 2012-2024 Robin Haberkorn
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -288,7 +288,7 @@
* Current memory usage.
* Access must be synchronized using atomic operations.
*/
-static gint teco_memory_usage = 0;
+static guint teco_memory_usage = 0;
/*
* NOTE: This implementation based on malloc_usable_size() might
@@ -495,6 +495,16 @@ teco_memory_get_usage(void)
return procstk.ki_rssize * page_size;
}
+/**
+ * Options passed to jemalloc.
+ *
+ * It's crucial to disable opt.retain, so that freeing memory after
+ * recovering from memory limit hits actually decreases the RSS.
+ * The reasons for activating the option, mentioned in jemalloc(3),
+ * shouldn't be relevant on FreeBSD.
+ */
+const gchar *malloc_conf = "retain:false";
+
#define NEED_POLL_THREAD
#elif defined(G_OS_UNIX) && defined(HAVE_SYSCONF) && defined(HAVE_PROCFS)
@@ -628,8 +638,7 @@ teco_memory_stop_limiting(void)
g_mutex_unlock(&teco_memory_mutex);
}
-#ifndef NDEBUG
-static void __attribute__((destructor))
+static void TECO_DEBUG_CLEANUP
teco_memory_cleanup(void)
{
if (!teco_memory_thread)
@@ -642,7 +651,6 @@ teco_memory_cleanup(void)
g_thread_join(teco_memory_thread);
}
-#endif
#else /* !NEED_POLL_THREAD */
@@ -660,7 +668,7 @@ gsize teco_memory_limit = 500*1000*1000;
gboolean
teco_memory_set_limit(gsize new_limit, GError **error)
{
- gsize memory_usage = g_atomic_int_get(&teco_memory_usage);
+ gsize memory_usage = (guint)g_atomic_int_get(&teco_memory_usage);
if (G_UNLIKELY(new_limit && memory_usage > new_limit)) {
g_autofree gchar *usage_str = g_format_size(memory_usage);
@@ -693,18 +701,19 @@ teco_memory_set_limit(gsize new_limit, GError **error)
gboolean
teco_memory_check(gsize request, GError **error)
{
- gsize memory_usage = g_atomic_int_get(&teco_memory_usage) + request;
+ gsize memory_usage = (guint)g_atomic_int_get(&teco_memory_usage);
+ gsize requested_memory_usage = memory_usage+request;
/*
* Check for overflows.
* NOTE: Glib 2.48 has g_size_checked_add().
*/
- if (G_UNLIKELY(memory_usage < request))
+ if (G_UNLIKELY(requested_memory_usage < memory_usage))
/* guaranteed to fail if memory limiting is enabled */
- memory_usage = G_MAXSIZE;
+ requested_memory_usage = G_MAXSIZE;
- if (G_UNLIKELY(teco_memory_limit && memory_usage >= teco_memory_limit)) {
- g_autofree gchar *limit_str = g_format_size(memory_usage);
+ if (G_UNLIKELY(teco_memory_limit && requested_memory_usage >= teco_memory_limit)) {
+ g_autofree gchar *limit_str = g_format_size(requested_memory_usage);
g_set_error(error, TECO_ERROR, TECO_ERROR_MEMLIMIT,
"Memory limit (%s) exceeded. See <EJ> command.",