diff options
Diffstat (limited to 'src/memory.c')
-rw-r--r-- | src/memory.c | 31 |
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.", |