diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/init.c | 41 | ||||
-rw-r--r-- | src/os.c | 28 |
2 files changed, 46 insertions, 23 deletions
@@ -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 @@ -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); |