mirror of
https://github.com/microsoft/mimalloc.git
synced 2025-07-06 11:34:38 +03:00
merge from dev
This commit is contained in:
commit
ae1c06d940
7 changed files with 441 additions and 70 deletions
41
src/init.c
41
src/init.c
|
@ -520,6 +520,14 @@ void mi_process_init(void) mi_attr_noexcept {
|
|||
#endif
|
||||
_mi_verbose_message("secure level: %d\n", MI_SECURE);
|
||||
mi_thread_init();
|
||||
#if defined(_WIN32) && !defined(MI_SHARED_LIB)
|
||||
/* When building as a static lib the FLS cleanup happens to early for the main thread.
|
||||
* To avoid that set the FLS value for the main thread to NULL; the eventual
|
||||
* mi_fls_done() execution won't call _mi_thread_done().
|
||||
* The latter function is later called explicitly from mi_process_done().
|
||||
* See GitHub issue #508 for more background and explanation. */
|
||||
FlsSetValue(mi_fls_key, NULL);
|
||||
#endif
|
||||
mi_stats_reset(); // only call stat reset *after* thread init (or the heap tld == NULL)
|
||||
|
||||
if (mi_option_is_enabled(mi_option_reserve_huge_os_pages)) {
|
||||
|
@ -549,7 +557,8 @@ static void mi_process_done(void) {
|
|||
process_done = true;
|
||||
|
||||
#if defined(_WIN32) && !defined(MI_SHARED_LIB)
|
||||
FlsSetValue(mi_fls_key, NULL); // don't call main-thread callback
|
||||
// Explicitly clean up main thread. See comment in mi_process_init() for reason
|
||||
_mi_thread_done(_mi_heap_default);
|
||||
FlsFree(mi_fls_key); // call thread-done on all threads to prevent dangling callback pointer if statically linked with a DLL; Issue #208
|
||||
#endif
|
||||
|
||||
|
@ -584,20 +593,6 @@ static void mi_process_done(void) {
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
#elif defined(__cplusplus)
|
||||
// C++: use static initialization to detect process start
|
||||
static bool _mi_process_init(void) {
|
||||
mi_process_load();
|
||||
return (_mi_heap_main.thread_id != 0);
|
||||
}
|
||||
static bool mi_initialized = _mi_process_init();
|
||||
|
||||
#elif defined(__GNUC__) || defined(__clang__)
|
||||
// GCC,Clang: use the constructor attribute
|
||||
static void __attribute__((constructor)) _mi_process_init(void) {
|
||||
mi_process_load();
|
||||
}
|
||||
|
||||
#elif defined(_MSC_VER)
|
||||
// MSVC: use data section magic for static libraries
|
||||
// See <https://www.codeguru.com/cpp/misc/misc/applicationcontrol/article.php/c6945/Running-Code-Before-and-After-Main.htm>
|
||||
|
@ -613,9 +608,23 @@ static void mi_process_done(void) {
|
|||
__pragma(comment(linker, "/include:" "__mi_msvc_initu"))
|
||||
#endif
|
||||
#pragma data_seg(".CRT$XIU")
|
||||
_crt_cb _mi_msvc_initu[] = { &_mi_process_init };
|
||||
extern "C" _crt_cb _mi_msvc_initu[] = { &_mi_process_init };
|
||||
#pragma data_seg()
|
||||
|
||||
#elif defined(__cplusplus)
|
||||
// C++: use static initialization to detect process start
|
||||
static bool _mi_process_init(void) {
|
||||
mi_process_load();
|
||||
return (_mi_heap_main.thread_id != 0);
|
||||
}
|
||||
static bool mi_initialized = _mi_process_init();
|
||||
|
||||
#elif defined(__GNUC__) || defined(__clang__)
|
||||
// GCC,Clang: use the constructor attribute
|
||||
static void __attribute__((constructor)) _mi_process_init(void) {
|
||||
mi_process_load();
|
||||
}
|
||||
|
||||
#else
|
||||
#pragma message("define a way to call mi_process_load on your platform")
|
||||
#endif
|
||||
|
|
28
src/os.c
28
src/os.c
|
@ -231,7 +231,7 @@ static void os_detect_overcommit(void) {
|
|||
#if defined(__linux__)
|
||||
int fd = open("/proc/sys/vm/overcommit_memory", O_RDONLY);
|
||||
if (fd < 0) return;
|
||||
char buf[128];
|
||||
char buf[32];
|
||||
ssize_t nread = read(fd, &buf, sizeof(buf));
|
||||
close(fd);
|
||||
// <https://www.kernel.org/doc/Documentation/vm/overcommit-accounting>
|
||||
|
@ -263,6 +263,17 @@ void _mi_os_init() {
|
|||
#endif
|
||||
|
||||
|
||||
#if defined(MADV_NORMAL)
|
||||
static int mi_madvise(void* addr, size_t length, int advice) {
|
||||
#if defined(__sun)
|
||||
return madvise((caddr_t)addr, length, advice); // Solaris needs cast (issue #520)
|
||||
#else
|
||||
return madvise(addr, length, advice);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* -----------------------------------------------------------
|
||||
free memory
|
||||
-------------------------------------------------------------- */
|
||||
|
@ -469,7 +480,7 @@ static void* mi_unix_mmapx(void* addr, size_t size, size_t try_alignment, int pr
|
|||
}
|
||||
#elif defined(MAP_ALIGN) // Solaris
|
||||
if (addr == NULL && try_alignment > 1 && (try_alignment % _mi_os_page_size()) == 0) {
|
||||
void* p = mmap(try_alignment, size, protect_flags, flags | MAP_ALIGN, fd, 0);
|
||||
void* p = mmap((void*)try_alignment, size, protect_flags, flags | MAP_ALIGN, fd, 0); // addr parameter is the required alignment
|
||||
if (p!=MAP_FAILED) return p;
|
||||
// fall back to regular mmap
|
||||
}
|
||||
|
@ -586,7 +597,7 @@ static void* mi_unix_mmap(void* addr, size_t size, size_t try_alignment, int pro
|
|||
// However, some systems only allow THP if called with explicit `madvise`, so
|
||||
// when large OS pages are enabled for mimalloc, we call `madvise` anyways.
|
||||
if (allow_large && use_large_os_page(size, try_alignment)) {
|
||||
if (madvise(p, size, MADV_HUGEPAGE) == 0) {
|
||||
if (mi_madvise(p, size, MADV_HUGEPAGE) == 0) {
|
||||
*is_large = true; // possibly
|
||||
};
|
||||
}
|
||||
|
@ -595,7 +606,7 @@ static void* mi_unix_mmap(void* addr, size_t size, size_t try_alignment, int pro
|
|||
struct memcntl_mha cmd = {0};
|
||||
cmd.mha_pagesize = large_os_page_size;
|
||||
cmd.mha_cmd = MHA_MAPSIZE_VA;
|
||||
if (memcntl(p, size, MC_HAT_ADVISE, (caddr_t)&cmd, 0, 0) == 0) {
|
||||
if (memcntl((caddr_t)p, size, MC_HAT_ADVISE, (caddr_t)&cmd, 0, 0) == 0) {
|
||||
*is_large = true;
|
||||
}
|
||||
}
|
||||
|
@ -915,6 +926,9 @@ static bool mi_os_commitx(void* addr, size_t size, bool commit, bool conservativ
|
|||
err = mprotect(start, csize, PROT_NONE);
|
||||
if (err != 0) { err = errno; }
|
||||
#endif
|
||||
//#if defined(MADV_FREE_REUSE)
|
||||
// while ((err = mi_madvise(start, csize, MADV_FREE_REUSE)) != 0 && errno == EAGAIN) { errno = 0; }
|
||||
//#endif
|
||||
}
|
||||
#endif
|
||||
if (err != 0) {
|
||||
|
@ -979,16 +993,16 @@ static bool mi_os_resetx(void* addr, size_t size, bool reset, mi_stats_t* stats)
|
|||
static _Atomic(size_t) advice = ATOMIC_VAR_INIT(MADV_FREE);
|
||||
int oadvice = (int)mi_atomic_load_relaxed(&advice);
|
||||
int err;
|
||||
while ((err = madvise(start, csize, oadvice)) != 0 && errno == EAGAIN) { errno = 0; };
|
||||
while ((err = mi_madvise(start, csize, oadvice)) != 0 && errno == EAGAIN) { errno = 0; };
|
||||
if (err != 0 && errno == EINVAL && oadvice == MADV_FREE) {
|
||||
// if MADV_FREE is not supported, fall back to MADV_DONTNEED from now on
|
||||
mi_atomic_store_release(&advice, (size_t)MADV_DONTNEED);
|
||||
err = madvise(start, csize, MADV_DONTNEED);
|
||||
err = mi_madvise(start, csize, MADV_DONTNEED);
|
||||
}
|
||||
#elif defined(__wasi__)
|
||||
int err = 0;
|
||||
#else
|
||||
int err = madvise(start, csize, MADV_DONTNEED);
|
||||
int err = mi_madvise(start, csize, MADV_DONTNEED);
|
||||
#endif
|
||||
if (err != 0) {
|
||||
_mi_warning_message("madvise reset error: start: %p, csize: 0x%zx, errno: %i\n", start, csize, errno);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue