DL_TUNABLE_CALLBACK_FNDECL (set_trim_threshold, size_t)
DL_TUNABLE_CALLBACK_FNDECL (set_arena_max, size_t)
DL_TUNABLE_CALLBACK_FNDECL (set_arena_test, size_t)
+DL_TUNABLE_CALLBACK_FNDECL (set_tcache_max, size_t)
+DL_TUNABLE_CALLBACK_FNDECL (set_tcache_count, size_t)
+DL_TUNABLE_CALLBACK_FNDECL (set_tcache_unsorted_limit, size_t)
#else
/* Initialization routine. */
#include <string.h>
TUNABLE_SET_VAL_WITH_CALLBACK (mmap_max, NULL, set_mmaps_max);
TUNABLE_SET_VAL_WITH_CALLBACK (arena_max, NULL, set_arena_max);
TUNABLE_SET_VAL_WITH_CALLBACK (arena_test, NULL, set_arena_test);
+#if USE_TCACHE
+ TUNABLE_SET_VAL_WITH_CALLBACK (tcache_max, NULL, set_tcache_max);
+ TUNABLE_SET_VAL_WITH_CALLBACK (tcache_count, NULL, set_tcache_count);
+ TUNABLE_SET_VAL_WITH_CALLBACK (tcache_unsorted_limit, NULL, set_tcache_unsorted_limit);
+#endif
__libc_lock_unlock (main_arena.mutex);
#else
const char *s = NULL;
if (memcmp (envline, "ARENA_TEST", 10) == 0)
__libc_mallopt (M_ARENA_TEST, atoi (&envline[11]));
}
+#if USE_TCACHE
+ if (!__builtin_expect (__libc_enable_secure, 0))
+ {
+ if (memcmp (envline, "TCACHE_MAX", 10) == 0)
+ __libc_mallopt (M_TCACHE_MAX, atoi (&envline[11]));
+ }
+#endif
break;
+#if USE_TCACHE
+ case 12:
+ if (!__builtin_expect (__libc_enable_secure, 0))
+ {
+ if (memcmp (envline, "TCACHE_COUNT", 12) == 0)
+ __libc_mallopt (M_TCACHE_COUNT, atoi (&envline[13]));
+ }
+ break;
+#endif
case 15:
if (!__builtin_expect (__libc_enable_secure, 0))
{
__libc_mallopt (M_MMAP_THRESHOLD, atoi (&envline[16]));
}
break;
+#if USE_TCACHE
+ case 21:
+ if (!__builtin_expect (__libc_enable_secure, 0))
+ {
+ if (memcmp (envline, "TCACHE_UNSORTED_LIMIT", 21) == 0)
+ __libc_mallopt (M_TCACHE_UNSORTED_LIMIT, atoi (&envline[22]));
+ }
+ break;
+#endif
default:
break;
}
size_t tcache_max;
/* Maximum number of chunks in each bucket. */
size_t tcache_count;
+ /* Maximum number of chunks to remove from the unsorted list, which
+ don't match. */
+ size_t tcache_unsorted_limit;
#endif
};
#if USE_TCACHE
,
.tcache_count = TCACHE_FILL_COUNT,
- .tcache_max = TCACHE_IDX-1
+ .tcache_max = TCACHE_IDX-1,
+ .tcache_unsorted_limit = 0 /* No limit */
#endif
};
#if USE_TCACHE
#define M_TCACHE_COUNT -9
#define M_TCACHE_MAX -10
+#define M_TCACHE_UNSORTED_LIMIT -11
#endif
/* Maximum size of memory handled in fastbins. */
mchunkptr fwd; /* misc temp for linking */
mchunkptr bck; /* misc temp for linking */
+#if USE_TCACHE
+ size_t tcache_unsorted_count; /* count of unsorted chunks processed */
+#endif
+
const char *errstr = NULL;
/*
tcache_nb = nb;
size_t tc_idx = size2tidx (nb-SIZE_SZ);
int return_cached = 0;
+
+ tcache_unsorted_count = 0;
#endif
for (;; )
fwd->bk = victim;
bck->fd = victim;
+#if USE_TCACHE
+ /* If we've processed as many chunks as we're allowed while
+ filling the cache, return one of the cached ones. */
+ tcache_unsorted_count ++;
+ if (return_cached
+ && mp_.tcache_unsorted_limit > 0
+ && tcache_unsorted_count > mp_.tcache_unsorted_limit)
+ {
+ TCacheEntry *e = tcache.entries[tc_idx];
+ tcache.entries[tc_idx] = e->next;
+ tcache.counts[tc_idx] --;
+ return (void *) e;
+ }
+#endif
+
#define MAX_ITERS 10000
if (++iters >= MAX_ITERS)
break;
return 1;
}
+#ifdef USE_TCACHE
+static inline int
+__always_inline
+do_set_tcache_max (size_t value)
+{
+ LIBC_PROBE (memory_mallopt_tcache_max, 2, value, mp_.tcache_max);
+ mp_.tcache_max = value;
+ return 1;
+}
+
+static inline int
+__always_inline
+do_set_tcache_count (size_t value)
+{
+ LIBC_PROBE (memory_mallopt_tcache_count, 2, value, mp_.tcache_count);
+ mp_.tcache_count = value;
+ return 1;
+}
+
+static inline int
+__always_inline
+do_set_tcache_unsorted_limit (size_t value)
+{
+ LIBC_PROBE (memory_mallopt_tcache_unsorted_limit, 2, value, mp_.tcache_unsorted_limit);
+ mp_.tcache_unsorted_limit = value;
+ return 1;
+}
+#endif
int
__libc_mallopt (int param_number, int value)
#if USE_TCACHE
case M_TCACHE_COUNT:
if (value >= 0)
- {
- LIBC_PROBE (memory_mallopt_tcache_count, 2, value, mp_.tcache_count);
- mp_.tcache_count = value;
- }
+ do_set_tcache_max (value);
break;
case M_TCACHE_MAX:
if (value >= 0)
{
value = size2tidx (value);
if (value < TCACHE_IDX)
- {
- LIBC_PROBE (memory_mallopt_tcache_max, 2, value, mp_.tcache_max);
- mp_.tcache_max = value;
- }
+ do_set_tcache_max (value);
}
break;
+ case M_TCACHE_UNSORTED_LIMIT:
+ if (value >= 0)
+ do_set_tcache_unsorted_limit (value);
+ break;
#endif
}
__libc_lock_unlock (av->mutex);