mirror of
https://github.com/microsoft/mimalloc.git
synced 2025-07-06 19:38:41 +03:00
Expose mi prefixed public standard implementations of various posix, unix, and c++ allocation functions. See issue #75
This commit is contained in:
parent
5ff037f8f8
commit
dd59a917ce
11 changed files with 137 additions and 87 deletions
|
@ -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 <errno.h>
|
||||
|
||||
#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)
|
||||
// <http://man7.org/linux/man-pages/man3/posix_memalign.3.html>
|
||||
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
|
||||
|
|
82
src/alloc-posix.c
Normal file
82
src/alloc-posix.c
Normal file
|
@ -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 <errno.h>
|
||||
|
||||
#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)
|
||||
// <http://man7.org/linux/man-pages/man3/posix_memalign.3.html>
|
||||
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;
|
||||
}
|
||||
|
|
@ -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"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue