extern uint pool_debugging;
int is_trim_enabled(void);
+int malloc_trim(size_t pad);
+
void *pool_get_from_os(struct pool_head *pool);
void pool_put_to_os(struct pool_head *pool, void *ptr);
void *pool_alloc_nocache(struct pool_head *pool);
static int using_default_allocator __read_mostly = 1;
static int disable_trim __read_mostly = 0;
static int(*my_mallctl)(const char *, void *, size_t *, void *, size_t) = NULL;
+static int(*_malloc_trim)(size_t) = NULL;
/* ask the allocator to trim memory pools.
* This must run under thread isolation so that competing threads trying to
using_default_allocator = (malloc_default_zone() != NULL);
#endif
}
+
+ /* detect presence of malloc_trim() */
+ _malloc_trim = get_sym_next_addr("malloc_trim");
}
int is_trim_enabled(void)
return !disable_trim && using_default_allocator;
}
+/* replace the libc's malloc_trim() so that we can also intercept the calls
+ * from child libraries when the allocator is not the default one.
+ */
+int malloc_trim(size_t pad)
+{
+ int ret = 0;
+
+ if (disable_trim)
+ return ret;
+
+ if (_malloc_trim && using_default_allocator) {
+ /* we're typically on glibc and not overridden */
+ ret = _malloc_trim(pad);
+ }
+ return ret;
+}
+
static int mem_should_fail(const struct pool_head *pool)
{
int ret = 0;
/* Report in build options if trim is supported */
static void pools_register_build_options(void)
{
- if (is_trim_enabled()) {
+ if (is_trim_enabled() && _malloc_trim) {
char *ptr = NULL;
memprintf(&ptr, "Support for malloc_trim() is enabled.");
hap_register_build_opts(ptr, 1);