merge from dev

This commit is contained in:
Daan Leijen 2023-03-29 16:24:55 -07:00
commit c4220e43b6
9 changed files with 19 additions and 14 deletions

View File

@ -25,7 +25,7 @@ option(MI_BUILD_OBJECT "Build object library" ON)
option(MI_BUILD_TESTS "Build test executables" ON) option(MI_BUILD_TESTS "Build test executables" ON)
option(MI_DEBUG_TSAN "Build with thread sanitizer (needs clang)" OFF) option(MI_DEBUG_TSAN "Build with thread sanitizer (needs clang)" OFF)
option(MI_DEBUG_UBSAN "Build with undefined-behavior sanitizer (needs clang++)" OFF) option(MI_DEBUG_UBSAN "Build with undefined-behavior sanitizer (needs clang++)" OFF)
option(MI_SKIP_COLLECT_ON_EXIT, "Skip collecting memory on program exit" OFF) option(MI_SKIP_COLLECT_ON_EXIT "Skip collecting memory on program exit" OFF)
option(MI_NO_PADDING "Force no use of padding even in DEBUG mode etc." OFF) option(MI_NO_PADDING "Force no use of padding even in DEBUG mode etc." OFF)
# deprecated options # deprecated options
@ -262,6 +262,11 @@ if(MI_USE_CXX)
endif() endif()
endif() endif()
if(CMAKE_SYSTEM_NAME MATCHES "Haiku")
SET(CMAKE_INSTALL_LIBDIR ~/config/non-packaged/lib)
SET(CMAKE_INSTALL_INCLUDEDIR ~/config/non-packaged/headers)
endif()
# Compiler flags # Compiler flags
if(CMAKE_C_COMPILER_ID MATCHES "AppleClang|Clang|GNU") if(CMAKE_C_COMPILER_ID MATCHES "AppleClang|Clang|GNU")
list(APPEND mi_cflags -Wall -Wextra -Wno-unknown-pragmas -fvisibility=hidden) list(APPEND mi_cflags -Wall -Wextra -Wno-unknown-pragmas -fvisibility=hidden)

View File

@ -927,7 +927,7 @@ template<class T> struct mi_stl_allocator { }
/*! \page build Building /*! \page build Building
Checkout the sources from Github: Checkout the sources from GitHub:
``` ```
git clone https://github.com/microsoft/mimalloc git clone https://github.com/microsoft/mimalloc
``` ```

View File

@ -98,7 +98,7 @@ $(document).ready(function(){initNavTree('build.html',''); initResizable(); });
<div class="title">Building </div> </div> <div class="title">Building </div> </div>
</div><!--header--> </div><!--header-->
<div class="contents"> <div class="contents">
<div class="textblock"><p>Checkout the sources from Github: </p><div class="fragment"><div class="line">git clone https:<span class="comment">//github.com/microsoft/mimalloc</span></div> <div class="textblock"><p>Checkout the sources from GitHub: </p><div class="fragment"><div class="line">git clone https://github.com/microsoft/mimalloc</div>
</div><!-- fragment --><h2>Windows</h2> </div><!-- fragment --><h2>Windows</h2>
<p>Open <code>ide/vs2019/mimalloc.sln</code> in Visual Studio 2019 and build (or <code>ide/vs2017/mimalloc.sln</code>). The <code>mimalloc</code> project builds a static library (in <code>out/msvc-x64</code>), while the <code>mimalloc-override</code> project builds a DLL for overriding malloc in the entire program.</p> <p>Open <code>ide/vs2019/mimalloc.sln</code> in Visual Studio 2019 and build (or <code>ide/vs2017/mimalloc.sln</code>). The <code>mimalloc</code> project builds a static library (in <code>out/msvc-x64</code>), while the <code>mimalloc-override</code> project builds a DLL for overriding malloc in the entire program.</p>
<h2>macOS, Linux, BSD, etc.</h2> <h2>macOS, Linux, BSD, etc.</h2>

View File

@ -246,9 +246,6 @@ static void mi_heap_reset_pages(mi_heap_t* heap) {
mi_assert_internal(mi_heap_is_initialized(heap)); mi_assert_internal(mi_heap_is_initialized(heap));
// TODO: copy full empty heap instead? // TODO: copy full empty heap instead?
memset(&heap->pages_free_direct, 0, sizeof(heap->pages_free_direct)); memset(&heap->pages_free_direct, 0, sizeof(heap->pages_free_direct));
#ifdef MI_MEDIUM_DIRECT
memset(&heap->pages_free_medium, 0, sizeof(heap->pages_free_medium));
#endif
_mi_memcpy_aligned(&heap->pages, &_mi_heap_empty.pages, sizeof(heap->pages)); _mi_memcpy_aligned(&heap->pages, &_mi_heap_empty.pages, sizeof(heap->pages));
heap->thread_delayed_free = NULL; heap->thread_delayed_free = NULL;
heap->page_count = 0; heap->page_count = 0;

View File

@ -536,7 +536,7 @@ static void mi_detect_cpu_features(void) {
// FSRM for fast rep movsb support (AMD Zen3+ (~2020) or Intel Ice Lake+ (~2017)) // FSRM for fast rep movsb support (AMD Zen3+ (~2020) or Intel Ice Lake+ (~2017))
int32_t cpu_info[4]; int32_t cpu_info[4];
__cpuid(cpu_info, 7); __cpuid(cpu_info, 7);
_mi_cpu_has_fsrm = ((cpu_info[3] & (1 << 4)) != 0); // bit 4 of EDX : see <https ://en.wikipedia.org/wiki/CPUID#EAX=7,_ECX=0:_Extended_Features> _mi_cpu_has_fsrm = ((cpu_info[3] & (1 << 4)) != 0); // bit 4 of EDX : see <https://en.wikipedia.org/wiki/CPUID#EAX=7,_ECX=0:_Extended_Features>
} }
#else #else
static void mi_detect_cpu_features(void) { static void mi_detect_cpu_features(void) {

View File

@ -50,7 +50,7 @@ terms of the MIT license. A copy of the license can be found in the file
#include <sys/sysctl.h> #include <sys/sysctl.h>
#endif #endif
#if !defined(__HAIKU__) && !defined(__APPLE__) #if !defined(__HAIKU__) && !defined(__APPLE__) && !defined(__CYGWIN__)
#define MI_HAS_SYSCALL_H #define MI_HAS_SYSCALL_H
#include <sys/syscall.h> #include <sys/syscall.h>
#endif #endif
@ -166,7 +166,6 @@ static void* unix_mmap_prim(void* addr, size_t size, size_t try_alignment, int p
if (addr == NULL && try_alignment > 1 && (try_alignment % _mi_os_page_size()) == 0) { if (addr == NULL && try_alignment > 1 && (try_alignment % _mi_os_page_size()) == 0) {
size_t n = mi_bsr(try_alignment); size_t n = mi_bsr(try_alignment);
if (((size_t)1 << n) == try_alignment && n >= 12 && n <= 30) { // alignment is a power of 2 and 4096 <= alignment <= 1GiB if (((size_t)1 << n) == try_alignment && n >= 12 && n <= 30) { // alignment is a power of 2 and 4096 <= alignment <= 1GiB
flags |= MAP_ALIGNED(n);
p = mmap(addr, size, protect_flags, flags | MAP_ALIGNED(n), fd, 0); p = mmap(addr, size, protect_flags, flags | MAP_ALIGNED(n), fd, 0);
if (p==MAP_FAILED || !_mi_is_aligned(p,try_alignment)) { if (p==MAP_FAILED || !_mi_is_aligned(p,try_alignment)) {
int err = errno; int err = errno;
@ -410,7 +409,7 @@ int _mi_prim_protect(void* start, size_t size, bool protect) {
// Huge page allocation // Huge page allocation
//--------------------------------------------- //---------------------------------------------
#if (MI_INTPTR_SIZE >= 8) && !defined(__HAIKU__) #if (MI_INTPTR_SIZE >= 8) && !defined(__HAIKU__) && !defined(__CYGWIN__)
#ifndef MPOL_PREFERRED #ifndef MPOL_PREFERRED
#define MPOL_PREFERRED 1 #define MPOL_PREFERRED 1
@ -652,7 +651,7 @@ void _mi_prim_out_stderr( const char* msg ) {
//---------------------------------------------------------------- //----------------------------------------------------------------
#if !defined(MI_USE_ENVIRON) || (MI_USE_ENVIRON!=0) #if !defined(MI_USE_ENVIRON) || (MI_USE_ENVIRON!=0)
// On Posix systemsr use `environ` to acces environment variables // On Posix systemsr use `environ` to access environment variables
// even before the C runtime is initialized. // even before the C runtime is initialized.
#if defined(__APPLE__) && defined(__has_include) && __has_include(<crt_externs.h>) #if defined(__APPLE__) && defined(__has_include) && __has_include(<crt_externs.h>)
#include <crt_externs.h> #include <crt_externs.h>
@ -759,7 +758,7 @@ bool _mi_prim_random_buf(void* buf, size_t buf_len) {
ssize_t ret = syscall(SYS_getrandom, buf, buf_len, GRND_NONBLOCK); ssize_t ret = syscall(SYS_getrandom, buf, buf_len, GRND_NONBLOCK);
if (ret >= 0) return (buf_len == (size_t)ret); if (ret >= 0) return (buf_len == (size_t)ret);
if (errno != ENOSYS) return false; if (errno != ENOSYS) return false;
mi_atomic_store_release(&no_getrandom, 1UL); // don't call again, and fall back to /dev/urandom mi_atomic_store_release(&no_getrandom, (uintptr_t)1); // don't call again, and fall back to /dev/urandom
} }
#endif #endif
int flags = O_RDONLY; int flags = O_RDONLY;

View File

@ -1070,7 +1070,7 @@ We maintain a global list of abandoned segments that are
reclaimed on demand. Since this is shared among threads reclaimed on demand. Since this is shared among threads
the implementation needs to avoid the A-B-A problem on the implementation needs to avoid the A-B-A problem on
popping abandoned segments: <https://en.wikipedia.org/wiki/ABA_problem> popping abandoned segments: <https://en.wikipedia.org/wiki/ABA_problem>
We use tagged pointers to avoid accidentially identifying We use tagged pointers to avoid accidentally identifying
reused segments, much like stamped references in Java. reused segments, much like stamped references in Java.
Secondly, we maintain a reader counter to avoid resetting Secondly, we maintain a reader counter to avoid resetting
or decommitting segments that have a pending read operation. or decommitting segments that have a pending read operation.

View File

@ -105,6 +105,10 @@ static void various_tests() {
delete t; delete t;
t = new (std::nothrow) Test(42); t = new (std::nothrow) Test(42);
delete t; delete t;
auto tbuf = new unsigned char[sizeof(Test)];
t = new (tbuf) Test(42);
t->~Test();
delete tbuf;
} }
class Static { class Static {

View File

@ -7,7 +7,7 @@ terms of the MIT license.
/* This is a stress test for the allocator, using multiple threads and /* This is a stress test for the allocator, using multiple threads and
transferring objects between threads. It tries to reflect real-world workloads: transferring objects between threads. It tries to reflect real-world workloads:
- allocation size is distributed linearly in powers of two - allocation size is distributed linearly in powers of two
- with some fraction extra large (and some extra extra large) - with some fraction extra large (and some very large)
- the allocations are initialized and read again at free - the allocations are initialized and read again at free
- pointers transfer between threads - pointers transfer between threads
- threads are terminated and recreated with some objects surviving in between - threads are terminated and recreated with some objects surviving in between