2017-04-11 09:17:55 +08:00
|
|
|
#ifndef JEMALLOC_INTERNAL_EXTERNS_H
|
|
|
|
#define JEMALLOC_INTERNAL_EXTERNS_H
|
|
|
|
|
2017-04-11 10:04:40 +08:00
|
|
|
#include "jemalloc/internal/atomic.h"
|
2017-04-27 09:37:44 +08:00
|
|
|
#include "jemalloc/internal/tsd_types.h"
|
2020-06-02 21:42:44 +08:00
|
|
|
#include "jemalloc/internal/nstime.h"
|
2017-04-11 10:04:40 +08:00
|
|
|
|
2017-04-12 14:13:45 +08:00
|
|
|
/* TSD checks this to set thread local slow state accordingly. */
|
2017-05-26 06:30:11 +08:00
|
|
|
extern bool malloc_slow;
|
2017-04-12 14:13:45 +08:00
|
|
|
|
|
|
|
/* Run-time options. */
|
2017-05-26 06:30:11 +08:00
|
|
|
extern bool opt_abort;
|
|
|
|
extern bool opt_abort_conf;
|
Add runtime detection for MADV_DONTNEED zeroes pages (mostly for qemu)
qemu does not support this, yet [1], and you can get very tricky assert
if you will run program with jemalloc in use under qemu:
<jemalloc>: ../contrib/jemalloc/src/extent.c:1195: Failed assertion: "p[i] == 0"
[1]: https://patchwork.kernel.org/patch/10576637/
Here is a simple example that shows the problem [2]:
// Gist to check possible issues with MADV_DONTNEED
// For example it does not supported by qemu user
// There is a patch for this [1], but it hasn't been applied.
// [1]: https://lists.gnu.org/archive/html/qemu-devel/2018-08/msg05422.html
#include <sys/mman.h>
#include <stdio.h>
#include <stddef.h>
#include <assert.h>
#include <string.h>
int main(int argc, char **argv)
{
void *addr = mmap(NULL, 1<<16, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
if (addr == MAP_FAILED) {
perror("mmap");
return 1;
}
memset(addr, 'A', 1<<16);
if (!madvise(addr, 1<<16, MADV_DONTNEED)) {
puts("MADV_DONTNEED does not return error. Check memory.");
for (int i = 0; i < 1<<16; ++i) {
assert(((unsigned char *)addr)[i] == 0);
}
} else {
perror("madvise");
}
if (munmap(addr, 1<<16)) {
perror("munmap");
return 1;
}
return 0;
}
### unpatched qemu
$ qemu-x86_64-static /tmp/test-MADV_DONTNEED
MADV_DONTNEED does not return error. Check memory.
test-MADV_DONTNEED: /tmp/test-MADV_DONTNEED.c:19: main: Assertion `((unsigned char *)addr)[i] == 0' failed.
qemu: uncaught target signal 6 (Aborted) - core dumped
Aborted (core dumped)
### patched qemu (by returning ENOSYS error)
$ qemu-x86_64 /tmp/test-MADV_DONTNEED
madvise: Success
### patch for qemu to return ENOSYS
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 897d20c076..5540792e0e 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -11775,7 +11775,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
turns private file-backed mappings into anonymous mappings.
This will break MADV_DONTNEED.
This is a hint, so ignoring and returning success is ok. */
- return 0;
+ return ENOSYS;
#endif
#ifdef TARGET_NR_fcntl64
case TARGET_NR_fcntl64:
[2]: https://gist.github.com/azat/12ba2c825b710653ece34dba7f926ece
v2:
- review fixes
- add opt_dont_trust_madvise
v3:
- review fixes
- rename opt_dont_trust_madvise to opt_trust_madvise
2020-12-19 03:23:35 +08:00
|
|
|
extern bool opt_trust_madvise;
|
2019-05-01 04:54:00 +08:00
|
|
|
extern bool opt_confirm_conf;
|
2020-08-15 04:36:41 +08:00
|
|
|
extern bool opt_hpa;
|
2020-09-05 06:22:47 +08:00
|
|
|
extern size_t opt_hpa_slab_max_alloc;
|
2020-10-17 04:14:59 +08:00
|
|
|
|
|
|
|
extern size_t opt_hpa_sec_max_alloc;
|
|
|
|
extern size_t opt_hpa_sec_max_bytes;
|
|
|
|
extern size_t opt_hpa_sec_nshards;
|
|
|
|
|
2017-05-26 06:30:11 +08:00
|
|
|
extern const char *opt_junk;
|
|
|
|
extern bool opt_junk_alloc;
|
|
|
|
extern bool opt_junk_free;
|
2020-02-29 03:37:39 +08:00
|
|
|
extern void (*junk_free_callback)(void *ptr, size_t size);
|
|
|
|
extern void (*junk_alloc_callback)(void *ptr, size_t size);
|
2017-05-26 06:30:11 +08:00
|
|
|
extern bool opt_utrace;
|
|
|
|
extern bool opt_xmalloc;
|
|
|
|
extern bool opt_zero;
|
|
|
|
extern unsigned opt_narenas;
|
2019-09-24 08:56:19 +08:00
|
|
|
extern zero_realloc_action_t opt_zero_realloc_action;
|
|
|
|
extern const char *zero_realloc_mode_names[];
|
2019-10-27 02:04:46 +08:00
|
|
|
extern atomic_zu_t zero_realloc_count;
|
2017-04-11 09:17:55 +08:00
|
|
|
|
|
|
|
/* Number of CPUs. */
|
2017-05-26 06:30:11 +08:00
|
|
|
extern unsigned ncpus;
|
2017-04-11 09:17:55 +08:00
|
|
|
|
|
|
|
/* Number of arenas used for automatic multiplexing of threads and arenas. */
|
2017-05-26 06:30:11 +08:00
|
|
|
extern unsigned narenas_auto;
|
2017-04-11 09:17:55 +08:00
|
|
|
|
2018-06-02 06:06:36 +08:00
|
|
|
/* Base index for manual arenas. */
|
|
|
|
extern unsigned manual_arena_base;
|
|
|
|
|
2017-04-11 09:17:55 +08:00
|
|
|
/*
|
|
|
|
* Arenas that are used to service external requests. Not all elements of the
|
|
|
|
* arenas array are necessarily used; arenas are created lazily as needed.
|
|
|
|
*/
|
|
|
|
extern atomic_p_t arenas[];
|
|
|
|
|
|
|
|
void *a0malloc(size_t size);
|
|
|
|
void a0dalloc(void *ptr);
|
|
|
|
void *bootstrap_malloc(size_t size);
|
|
|
|
void *bootstrap_calloc(size_t num, size_t size);
|
|
|
|
void bootstrap_free(void *ptr);
|
|
|
|
void arena_set(unsigned ind, arena_t *arena);
|
|
|
|
unsigned narenas_total_get(void);
|
|
|
|
arena_t *arena_init(tsdn_t *tsdn, unsigned ind, extent_hooks_t *extent_hooks);
|
|
|
|
arena_t *arena_choose_hard(tsd_t *tsd, bool internal);
|
|
|
|
void arena_migrate(tsd_t *tsd, unsigned oldind, unsigned newind);
|
|
|
|
void iarena_cleanup(tsd_t *tsd);
|
|
|
|
void arena_cleanup(tsd_t *tsd);
|
2020-04-24 06:46:45 +08:00
|
|
|
size_t batch_alloc(void **ptrs, size_t num, size_t size, int flags);
|
2017-04-11 09:17:55 +08:00
|
|
|
void jemalloc_prefork(void);
|
|
|
|
void jemalloc_postfork_parent(void);
|
|
|
|
void jemalloc_postfork_child(void);
|
|
|
|
bool malloc_initialized(void);
|
2019-03-09 03:50:30 +08:00
|
|
|
void je_sdallocx_noflags(void *ptr, size_t size);
|
2017-04-11 09:17:55 +08:00
|
|
|
|
|
|
|
#endif /* JEMALLOC_INTERNAL_EXTERNS_H */
|