mirror of
https://github.com/microsoft/mimalloc.git
synced 2025-01-14 00:27:59 +08:00
merge from dev
This commit is contained in:
commit
c4220e43b6
@ -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)
|
||||||
|
@ -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
|
||||||
```
|
```
|
||||||
|
@ -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>
|
||||||
|
@ -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;
|
||||||
|
@ -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) {
|
||||||
|
@ -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;
|
||||||
|
@ -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.
|
||||||
|
@ -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 {
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user