diff --git a/CMakeLists.txt b/CMakeLists.txt
index 968ace73..79d297df 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -19,6 +19,7 @@ set(mi_sources
src/page.c
src/alloc.c
src/alloc-aligned.c
+ src/alloc-posix.c
src/heap.c
src/options.c
src/init.c)
diff --git a/ide/vs2017/mimalloc-override.vcxproj b/ide/vs2017/mimalloc-override.vcxproj
index d82bce8c..98429052 100644
--- a/ide/vs2017/mimalloc-override.vcxproj
+++ b/ide/vs2017/mimalloc-override.vcxproj
@@ -218,6 +218,7 @@
true
+
diff --git a/ide/vs2017/mimalloc-override.vcxproj.filters b/ide/vs2017/mimalloc-override.vcxproj.filters
index 7a8abd74..c3c9675c 100644
--- a/ide/vs2017/mimalloc-override.vcxproj.filters
+++ b/ide/vs2017/mimalloc-override.vcxproj.filters
@@ -58,5 +58,8 @@
Source Files
+
+ Source Files
+
\ No newline at end of file
diff --git a/ide/vs2017/mimalloc.vcxproj b/ide/vs2017/mimalloc.vcxproj
index 05cf745c..98a3a230 100644
--- a/ide/vs2017/mimalloc.vcxproj
+++ b/ide/vs2017/mimalloc.vcxproj
@@ -217,6 +217,7 @@
true
true
+
diff --git a/ide/vs2017/mimalloc.vcxproj.filters b/ide/vs2017/mimalloc.vcxproj.filters
index 9b1e0971..2f54485b 100644
--- a/ide/vs2017/mimalloc.vcxproj.filters
+++ b/ide/vs2017/mimalloc.vcxproj.filters
@@ -50,6 +50,9 @@
Source Files
+
+ Source Files
+
diff --git a/include/mimalloc.h b/include/mimalloc.h
index efb1f381..192a0cfb 100644
--- a/include/mimalloc.h
+++ b/include/mimalloc.h
@@ -232,6 +232,26 @@ mi_decl_export long mi_option_get(mi_option_t option);
mi_decl_export void mi_option_set(mi_option_t option, long value);
mi_decl_export void mi_option_set_default(mi_option_t option, long value);
+
+// ------------------------------------------------------
+// mi prefixed implementations of various posix, unix,
+// and C++ allocation functions.
+// ------------------------------------------------------
+
+mi_decl_export size_t mi_malloc_size(void* p) mi_attr_noexcept;
+mi_decl_export size_t mi_malloc_usable_size(void *p) mi_attr_noexcept;
+mi_decl_export void mi_cfree(void* p) mi_attr_noexcept;
+
+mi_decl_export int mi_posix_memalign(void** p, size_t alignment, size_t size) mi_attr_noexcept;
+mi_decl_export int mi__posix_memalign(void** p, size_t alignment, size_t size) mi_attr_noexcept;
+mi_decl_export mi_decl_allocator void* mi_memalign(size_t alignment, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2);
+mi_decl_export mi_decl_allocator void* mi_valloc(size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1);
+
+mi_decl_export mi_decl_allocator void* mi_pvalloc(size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1);
+mi_decl_export mi_decl_allocator void* mi_aligned_alloc(size_t alignment, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2);
+mi_decl_export mi_decl_allocator void* mi_reallocarray(void* p, size_t count, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(2,3);
+
+
#ifdef __cplusplus
}
#endif
diff --git a/src/alloc-override.c b/src/alloc-override.c
index 7c052690..1cae7cfb 100644
--- a/src/alloc-override.c
+++ b/src/alloc-override.c
@@ -25,15 +25,17 @@ terms of the MIT license. A copy of the license can be found in the file
#if (defined(__GNUC__) || defined(__clang__)) && !defined(__MACH__)
// use aliasing to alias the exported function to one of our `mi_` functions
- #define MI_FORWARD(fun) __attribute__((alias(#fun), used, visibility("default")))
- #define MI_FORWARD1(fun,x) MI_FORWARD(fun)
- #define MI_FORWARD2(fun,x,y) MI_FORWARD(fun)
- #define MI_FORWARD0(fun,x) MI_FORWARD(fun)
+ #define MI_FORWARD(fun) __attribute__((alias(#fun), used, visibility("default")))
+ #define MI_FORWARD1(fun,x) MI_FORWARD(fun)
+ #define MI_FORWARD2(fun,x,y) MI_FORWARD(fun)
+ #define MI_FORWARD3(fun,x,y,z) MI_FORWARD(fun)
+ #define MI_FORWARD0(fun,x) MI_FORWARD(fun)
#else
// use forwarding by calling our `mi_` function
- #define MI_FORWARD1(fun,x) { return fun(x); }
- #define MI_FORWARD2(fun,x,y) { return fun(x,y); }
- #define MI_FORWARD0(fun,x) { fun(x); }
+ #define MI_FORWARD1(fun,x) { return fun(x); }
+ #define MI_FORWARD2(fun,x,y) { return fun(x,y); }
+ #define MI_FORWARD3(fun,x,y,z) { return fun(x,y,z); }
+ #define MI_FORWARD0(fun,x) { fun(x); }
#endif
#if defined(__APPLE__) && defined(MI_SHARED_LIB_EXPORT) && defined(MI_INTERPOSE)
@@ -59,9 +61,7 @@ terms of the MIT license. A copy of the license can be found in the file
void* malloc(size_t size) mi_attr_noexcept MI_FORWARD1(mi_malloc, size);
void* calloc(size_t size, size_t n) mi_attr_noexcept MI_FORWARD2(mi_calloc, size, n);
void* realloc(void* p, size_t newsize) mi_attr_noexcept MI_FORWARD2(mi_realloc, p, newsize);
- void free(void* p) mi_attr_noexcept MI_FORWARD0(mi_free, p);
- //char* strdup(const char* s) MI_FORWARD1(mi_strdup, s);
- //char* strndup(const char* s, size_t n) MI_FORWARD2(mi_strndup, s, n);
+ void free(void* p) mi_attr_noexcept MI_FORWARD0(mi_free, p);
#endif
#if (defined(__GNUC__) || defined(__clang__)) && !defined(__MACH__)
@@ -121,57 +121,18 @@ extern "C" {
// Posix & Unix functions definitions
// ------------------------------------------------------
-#include
-
-#ifndef EINVAL
-#define EINVAL 22
-#endif
-#ifndef ENOMEM
-#define ENOMEM 12
-#endif
-
void* reallocf(void* p, size_t newsize) MI_FORWARD2(mi_reallocf,p,newsize);
size_t malloc_size(void* p) MI_FORWARD1(mi_usable_size,p);
size_t malloc_usable_size(void *p) MI_FORWARD1(mi_usable_size,p);
void cfree(void* p) MI_FORWARD0(mi_free, p);
-
-int posix_memalign(void** p, size_t alignment, size_t size) {
- // TODO: the spec says we should return EINVAL also if alignment is not a power of 2.
- // The spec also dictates we should not modify `*p` on an error. (issue#27)
- //
- if (alignment % sizeof(void*) != 0) return EINVAL; // no `p==NULL` check as it is declared as non-null
- if ((alignment & (~alignment + 1)) != alignment) return EINVAL; // not a power of 2
- void* q = mi_malloc_aligned(size, alignment);
- if (q==NULL && size != 0) return ENOMEM;
- *p = q;
- return 0;
-}
-
-void* memalign(size_t alignment, size_t size) {
- return mi_malloc_aligned(size, alignment);
-}
-
-void* valloc(size_t size) {
- return mi_malloc_aligned(size, _mi_os_page_size());
-}
-
-void* pvalloc(size_t size) {
- size_t psize = _mi_os_page_size();
- if (size >= SIZE_MAX - psize) return NULL; // overflow
- size_t asize = ((size + psize - 1) / psize) * psize;
- return mi_malloc_aligned(asize, psize);
-}
-
-void* aligned_alloc(size_t alignment, size_t size) {
- return mi_malloc_aligned(size, alignment);
-}
-
-void* reallocarray( void* p, size_t count, size_t size ) { // BSD
- void* newp = mi_reallocn(p,count,size);
- if (newp==NULL) errno = ENOMEM;
- return newp;
-}
+// no forwarding here due to aliasing/name mangling issues
+void* valloc(size_t size) { return mi_valloc(size); }
+void* pvalloc(size_t size) { return mi_pvalloc(size); }
+void* reallocarray(void* p, size_t count, size_t size) { return mi_reallocarray(p, count, size); }
+void* memalign(size_t alignment, size_t size) { return mi_memalign(alignment, size); }
+void* aligned_alloc(size_t alignment, size_t size) { return mi_aligned_alloc(alignment, size); }
+int posix_memalign(void** p, size_t alignment, size_t size) { return mi_posix_memalign(p, alignment, size); }
#if defined(__GLIBC__) && defined(__linux__)
// forward __libc interface (needed for glibc-based Linux distributions)
@@ -181,18 +142,10 @@ void* reallocarray( void* p, size_t count, size_t size ) { // BSD
void __libc_free(void* p) MI_FORWARD0(mi_free,p);
void __libc_cfree(void* p) MI_FORWARD0(mi_free,p);
- void* __libc_memalign(size_t alignment, size_t size) {
- return memalign(alignment,size);
- }
- void* __libc_valloc(size_t size) {
- return valloc(size);
- }
- void* __libc_pvalloc(size_t size) {
- return pvalloc(size);
- }
- int __posix_memalign(void** p, size_t alignment, size_t size) {
- return posix_memalign(p,alignment,size);
- }
+ void* __libc_valloc(size_t size) { return mi_valloc(size); }
+ void* __libc_pvalloc(size_t size) { return mi_pvalloc(size); }
+ void* __libc_memalign(size_t alignment, size_t size) { return mi_memalign(alignment,size); }
+ int __posix_memalign(void** p, size_t alignment, size_t size) { return mi_posix_memalign(p,alignment,size); }
#endif
#ifdef __cplusplus
diff --git a/src/alloc-posix.c b/src/alloc-posix.c
new file mode 100644
index 00000000..9fb2890b
--- /dev/null
+++ b/src/alloc-posix.c
@@ -0,0 +1,82 @@
+/* ----------------------------------------------------------------------------
+Copyright (c) 2018,2019, Microsoft Research, Daan Leijen
+This is free software; you can redistribute it and/or modify it under the
+terms of the MIT license. A copy of the license can be found in the file
+"LICENSE" at the root of this distribution.
+-----------------------------------------------------------------------------*/
+
+// ------------------------------------------------------------------------
+// mi prefixed publi definitions of various Posix, Unix, and C++ functions
+// for convenience and used when overriding these functions.
+// ------------------------------------------------------------------------
+
+#include "mimalloc.h"
+#include "mimalloc-internal.h"
+
+// ------------------------------------------------------
+// Posix & Unix functions definitions
+// ------------------------------------------------------
+
+#include
+
+#ifndef EINVAL
+#define EINVAL 22
+#endif
+#ifndef ENOMEM
+#define ENOMEM 12
+#endif
+
+
+size_t mi_malloc_size(void* p) mi_attr_noexcept {
+ return mi_usable_size(p);
+}
+
+size_t mi_malloc_usable_size(void *p) mi_attr_noexcept {
+ return mi_usable_size(p);
+}
+
+void mi_cfree(void* p) mi_attr_noexcept {
+ mi_free(p);
+}
+
+int mi_posix_memalign(void** p, size_t alignment, size_t size) mi_attr_noexcept {
+ // Note: The spec dictates we should not modify `*p` on an error. (issue#27)
+ //
+ if (p == NULL) return EINVAL;
+ if (alignment % sizeof(void*) != 0) return EINVAL; // natural alignment
+ if ((alignment & (alignment - 1)) != 0) return EINVAL; // not a power of 2
+ void* q = mi_malloc_aligned(size, alignment);
+ if (q==NULL && size != 0) return ENOMEM;
+ *p = q;
+ return 0;
+}
+
+int mi__posix_memalign(void** p, size_t alignment, size_t size) mi_attr_noexcept {
+ return mi_posix_memalign(p, alignment, size);
+}
+
+void* mi_memalign(size_t alignment, size_t size) mi_attr_noexcept {
+ return mi_malloc_aligned(size, alignment);
+}
+
+void* mi_valloc(size_t size) mi_attr_noexcept {
+ return mi_malloc_aligned(size, _mi_os_page_size());
+}
+
+void* mi_pvalloc(size_t size) mi_attr_noexcept {
+ size_t psize = _mi_os_page_size();
+ if (size >= SIZE_MAX - psize) return NULL; // overflow
+ size_t asize = ((size + psize - 1) / psize) * psize;
+ return mi_malloc_aligned(asize, psize);
+}
+
+void* mi_aligned_alloc(size_t alignment, size_t size) mi_attr_noexcept {
+ return mi_malloc_aligned(size, alignment);
+}
+
+void* mi_reallocarray( void* p, size_t count, size_t size ) mi_attr_noexcept { // BSD
+ void* newp = mi_reallocn(p,count,size);
+ if (newp==NULL) errno = ENOMEM;
+ return newp;
+}
+
diff --git a/src/static.c b/src/static.c
index b4378b43..679d1c10 100644
--- a/src/static.c
+++ b/src/static.c
@@ -20,5 +20,6 @@ terms of the MIT license. A copy of the license can be found in the file
#include "heap.c"
#include "alloc.c"
#include "alloc-aligned.c"
+#include "alloc-posix.c"
#include "init.c"
#include "options.c"
diff --git a/test/main-override.cpp b/test/main-override.cpp
index c42884be..4c22fbd7 100644
--- a/test/main-override.cpp
+++ b/test/main-override.cpp
@@ -21,7 +21,7 @@ public:
};
int main() {
- mi_stats_reset();
+ mi_stats_reset();
atexit(free_p);
void* p1 = malloc(78);
void* p2 = malloc(24);
@@ -36,8 +36,10 @@ int main() {
free(s);
Test* t = new Test(42);
delete t;
+ int err = mi_posix_memalign(&p1,32,60);
+ if (!err) free(p);
mi_collect(true);
- // mi_stats_print(NULL); // MIMALLOC_VERBOSE env is set to 2
+ mi_stats_print(NULL); // MIMALLOC_VERBOSE env is set to 2
return 0;
}
diff --git a/test/main.cpp b/test/main.cpp
deleted file mode 100644
index 4eab4edb..00000000
--- a/test/main.cpp
+++ /dev/null
@@ -1,17 +0,0 @@
-#include
-#include
-#include
-
-int main() {
- void* p1 = rc_malloc(16);
- void* p2 = rc_malloc(16);
- rc_free(p1);
- rc_free(p2);
- p1 = rc_malloc(16);
- p2 = rc_malloc(16);
- rc_free(p1);
- rc_free(p2);
- rc_collect(true);
- rc_stats_print();
- return 0;
-}