mirror of
https://github.com/microsoft/mimalloc.git
synced 2024-12-27 13:33:18 +08:00
add getcwd and fullpath wrappers
This commit is contained in:
parent
ff2fe673e5
commit
c04881ef8a
@ -127,6 +127,7 @@ void* _mi_page_malloc(mi_heap_t* heap, mi_page_t* page, size_t size MI_SO
|
||||
mi_block_t* _mi_page_ptr_unalign(const mi_segment_t* segment, const mi_page_t* page, const void* p);
|
||||
bool _mi_free_delayed_block(mi_block_t* block);
|
||||
void _mi_block_zero_init(const mi_page_t* page, void* p, size_t size);
|
||||
size_t _mi_path_max(void);
|
||||
|
||||
mi_decl_restrict void* _mi_base_malloc_zero(mi_heap_t* heap, size_t size, bool zero MI_SOURCE_XPARAM) mi_attr_malloc mi_attr_alloc_size(2);
|
||||
void* _mi_base_realloc_zero(mi_heap_t* heap, void* p, size_t newsize, bool zero MI_SOURCE_XPARAM) mi_attr_alloc_size(2);
|
||||
|
@ -27,17 +27,25 @@ not accidentally mix pointers from different allocators).
|
||||
#define strndup(s) mi_strndup(s)
|
||||
#define realpath(f,n) mi_realpath(f,n)
|
||||
|
||||
#define wcsdup(s) mi_wcsdup(s)
|
||||
#define mbsdup(s) mi_mbsdup(s)
|
||||
#define getcwd(b,n) mi_getcwd(b,n)
|
||||
|
||||
// Microsoft extensions
|
||||
#define _expand(p,n) mi_expand(p,n)
|
||||
#define _expand(p,n) mi__expand(p,n)
|
||||
#define _msize(p) mi_usable_size(p)
|
||||
#define _recalloc(p,n,c) mi_recalloc(p,n,c)
|
||||
|
||||
#define _strdup(s) mi_strdup(s)
|
||||
#define _strndup(s) mi_strndup(s)
|
||||
#define _wcsdup(s) (wchar_t*)mi_wcsdup((const unsigned short*)(s))
|
||||
#define _wcsdup(s) mi_wcsdup(s)
|
||||
#define _mbsdup(s) mi_mbsdup(s)
|
||||
#define _dupenv_s(b,n,v) mi_dupenv_s(b,n,v)
|
||||
#define _wdupenv_s(b,n,v) mi_wdupenv_s((unsigned short*)(b),n,(const unsigned short*)(v))
|
||||
#define _getcwd(b,n) mi_getcwd(b,n)
|
||||
#define _dupenv_s(b,n,v) mi__dupenv_s(b,n,v)
|
||||
#define _wdupenv_s(b,n,v) mi__wdupenv_s(b,n,v)
|
||||
#define _fullpath(b,p,n) mi__fullpath(b,p,n)
|
||||
#define _wfullpath(b,p,n) mi__wfullpath(b,p,n)
|
||||
#define _wgetcwd(b,n) mi__wgetcwd(b,n)
|
||||
|
||||
// Various Posix and Unix variants
|
||||
#define reallocf(p,n) mi_reallocf(p,n)
|
||||
@ -56,7 +64,7 @@ not accidentally mix pointers from different allocators).
|
||||
// Microsoft aligned variants
|
||||
#define _aligned_malloc(n,a) mi_malloc_aligned(n,a)
|
||||
#define _aligned_realloc(p,n,a) mi_realloc_aligned(p,n,a)
|
||||
#define _aligned_recalloc(p,s,n,a) mi_aligned_recalloc(p,s,n,a)
|
||||
#define _aligned_recalloc(p,s,n,a) mi_recalloc_aligned(p,s,n,a)
|
||||
#define _aligned_msize(p,a,o) mi_usable_size(p)
|
||||
#define _aligned_free(p) mi_free(p)
|
||||
#define _aligned_offset_malloc(n,a,o) mi_malloc_aligned_at(n,a,o)
|
||||
|
@ -86,6 +86,7 @@ terms of the MIT license. A copy of the license can be found in the file
|
||||
|
||||
#include <stddef.h> // size_t
|
||||
#include <stdbool.h> // bool
|
||||
#include <stdlib.h> // wchar_t
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -110,15 +111,15 @@ mi_decl_export mi_source_t mi_source_loc(const char* fname, int lineno);
|
||||
mi_decl_export void* mi_source_unpack(mi_source_t source, const char** fname, int* lineno);
|
||||
|
||||
#define mi_declx(tp,name,attrs,...) \
|
||||
mi_decl_export tp dbg_##name( __VA_ARGS__, mi_source_t dbg_source) attrs; \
|
||||
mi_decl_export tp name(__VA_ARGS__) attrs
|
||||
tp dbg_##name( __VA_ARGS__, mi_source_t dbg_source) attrs; \
|
||||
tp name(__VA_ARGS__) attrs
|
||||
|
||||
#endif
|
||||
|
||||
#define mi_decl_malloc(tp,name,...) mi_declx(mi_decl_nodiscard mi_decl_restrict tp, name, mi_attr_noexcept mi_attr_malloc, __VA_ARGS__)
|
||||
#define mi_decl_new(tp,name,...) mi_declx(mi_decl_nodiscard mi_decl_restrict tp, name, mi_attr_malloc, __VA_ARGS__)
|
||||
#define mi_decl_realloc(tp,name,...) mi_declx(mi_decl_nodiscard tp, name, mi_attr_noexcept, __VA_ARGS__)
|
||||
#define mi_decl_noexcpt(tp,name,...) mi_declx(tp, name, mi_attr_noexcept, __VA_ARGS__)
|
||||
#define mi_decl_malloc(tp,name,...) mi_declx(mi_decl_nodiscard mi_decl_export mi_decl_restrict tp, name, mi_attr_noexcept mi_attr_malloc, __VA_ARGS__)
|
||||
#define mi_decl_new(tp,name,...) mi_declx(mi_decl_nodiscard mi_decl_export mi_decl_restrict tp, name, mi_attr_malloc, __VA_ARGS__)
|
||||
#define mi_decl_realloc(tp,name,...) mi_declx(mi_decl_nodiscard mi_decl_export tp, name, mi_attr_noexcept, __VA_ARGS__)
|
||||
#define mi_decl_noexcpt(tp,name,...) mi_declx(mi_decl_export tp, name, mi_attr_noexcept, __VA_ARGS__)
|
||||
|
||||
|
||||
// ------------------------------------------------------
|
||||
@ -152,8 +153,8 @@ mi_decl_malloc( void*, mi_mallocn, size_t count, size_t size) mi_attr
|
||||
mi_decl_realloc(void*, mi_reallocn, void* p, size_t count, size_t size) mi_attr_alloc_size2(2,3);
|
||||
mi_decl_realloc(void*, mi_reallocf, void* p, size_t newsize) mi_attr_alloc_size(2);
|
||||
|
||||
mi_decl_export mi_decl_nodiscard size_t mi_usable_size(const void* p) mi_attr_noexcept;
|
||||
mi_decl_export mi_decl_nodiscard size_t mi_good_size(size_t size) mi_attr_noexcept;
|
||||
mi_decl_nodiscard mi_decl_export size_t mi_usable_size(const void* p) mi_attr_noexcept;
|
||||
mi_decl_nodiscard mi_decl_export size_t mi_good_size(size_t size) mi_attr_noexcept;
|
||||
|
||||
|
||||
// ------------------------------------------------------
|
||||
@ -206,7 +207,7 @@ mi_decl_realloc(void*, mi_realloc_aligned_at, void* p, size_t newsize, size_t al
|
||||
struct mi_heap_s;
|
||||
typedef struct mi_heap_s mi_heap_t;
|
||||
|
||||
mi_decl_export mi_decl_nodiscard mi_heap_t* mi_heap_new(void);
|
||||
mi_decl_nodiscard mi_decl_export mi_heap_t* mi_heap_new(void);
|
||||
mi_decl_export void mi_heap_delete(mi_heap_t* heap);
|
||||
mi_decl_export void mi_heap_destroy(mi_heap_t* heap);
|
||||
mi_decl_export mi_heap_t* mi_heap_set_default(mi_heap_t* heap);
|
||||
@ -266,9 +267,9 @@ mi_decl_realloc(void*, mi_heap_recalloc_aligned_at, mi_heap_t* heap, void* p, si
|
||||
// Analysis
|
||||
// ------------------------------------------------------
|
||||
|
||||
mi_decl_export mi_decl_nodiscard bool mi_heap_contains_block(mi_heap_t* heap, const void* p);
|
||||
mi_decl_export mi_decl_nodiscard bool mi_heap_check_owned(mi_heap_t* heap, const void* p);
|
||||
mi_decl_export mi_decl_nodiscard bool mi_check_owned(const void* p);
|
||||
mi_decl_nodiscard mi_decl_export bool mi_heap_contains_block(mi_heap_t* heap, const void* p);
|
||||
mi_decl_nodiscard mi_decl_export bool mi_heap_check_owned(mi_heap_t* heap, const void* p);
|
||||
mi_decl_nodiscard mi_decl_export bool mi_check_owned(const void* p);
|
||||
|
||||
// An area of heap space contains blocks of a single size.
|
||||
typedef struct mi_heap_area_s {
|
||||
@ -284,8 +285,8 @@ typedef bool (mi_cdecl mi_block_visit_fun)(const mi_heap_t* heap, const mi_heap_
|
||||
mi_decl_export bool mi_heap_visit_blocks(const mi_heap_t* heap, bool visit_all_blocks, mi_block_visit_fun* visitor, void* arg);
|
||||
|
||||
// Experimental
|
||||
mi_decl_export mi_decl_nodiscard bool mi_is_in_heap_region(const void* p) mi_attr_noexcept;
|
||||
mi_decl_export mi_decl_nodiscard bool mi_is_redirected() mi_attr_noexcept;
|
||||
mi_decl_nodiscard mi_decl_export bool mi_is_in_heap_region(const void* p) mi_attr_noexcept;
|
||||
mi_decl_nodiscard mi_decl_export bool mi_is_redirected() mi_attr_noexcept;
|
||||
|
||||
mi_decl_export int mi_reserve_huge_os_pages_interleave(size_t pages, size_t numa_nodes, size_t timeout_msecs) mi_attr_noexcept;
|
||||
mi_decl_export int mi_reserve_huge_os_pages_at(size_t pages, int numa_node, size_t timeout_msecs) mi_attr_noexcept;
|
||||
@ -342,13 +343,13 @@ typedef enum mi_option_e {
|
||||
} mi_option_t;
|
||||
|
||||
|
||||
mi_decl_export mi_decl_nodiscard bool mi_option_is_enabled(mi_option_t option);
|
||||
mi_decl_nodiscard mi_decl_export bool mi_option_is_enabled(mi_option_t option);
|
||||
mi_decl_export void mi_option_enable(mi_option_t option);
|
||||
mi_decl_export void mi_option_disable(mi_option_t option);
|
||||
mi_decl_export void mi_option_set_enabled(mi_option_t option, bool enable);
|
||||
mi_decl_export void mi_option_set_enabled_default(mi_option_t option, bool enable);
|
||||
|
||||
mi_decl_export mi_decl_nodiscard long mi_option_get(mi_option_t option);
|
||||
mi_decl_nodiscard 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);
|
||||
|
||||
@ -359,8 +360,8 @@ mi_decl_export void mi_option_set_default(mi_option_t option, long value);
|
||||
// note: we use `mi_cfree` as "checked free" and it checks if the pointer is in our heap before free-ing.
|
||||
// -------------------------------------------------------------------------------------------------------
|
||||
|
||||
mi_decl_export mi_decl_nodiscard size_t mi_malloc_size(const void* p) mi_attr_noexcept;
|
||||
mi_decl_export mi_decl_nodiscard size_t mi_malloc_usable_size(const void *p) mi_attr_noexcept;
|
||||
mi_decl_nodiscard mi_decl_export size_t mi_malloc_size(const void* p) mi_attr_noexcept;
|
||||
mi_decl_nodiscard mi_decl_export size_t mi_malloc_usable_size(const void *p) mi_attr_noexcept;
|
||||
|
||||
mi_decl_export void mi_cfree(void* p) mi_attr_noexcept;
|
||||
mi_decl_export void mi_free_size(void* p, size_t size) mi_attr_noexcept;
|
||||
@ -376,12 +377,17 @@ mi_decl_realloc(void*, mi_reallocarray, void* p, size_t count, size_t size) mi_
|
||||
mi_decl_realloc(void*, mi_aligned_recalloc, void* p, size_t newcount, size_t size, size_t alignment) mi_attr_alloc_size2(2, 3) mi_attr_alloc_align(4);
|
||||
mi_decl_realloc(void*, mi_aligned_offset_recalloc, void* p, size_t newcount, size_t size, size_t alignment, size_t offset) mi_attr_alloc_size2(2, 3);
|
||||
|
||||
mi_decl_malloc( unsigned short*, mi_wcsdup, const unsigned short* s);
|
||||
mi_decl_malloc( unsigned char*, mi_mbsdup, const unsigned char* s);
|
||||
mi_decl_noexcpt(int, mi_dupenv_s, char** buf, size_t* size, const char* name);
|
||||
mi_decl_noexcpt(int, mi_wdupenv_s, unsigned short** buf, size_t* size, const unsigned short* name);
|
||||
mi_decl_noexcpt(void*, mi__expand, void* p, size_t newsize);
|
||||
mi_decl_malloc(wchar_t*, mi_wcsdup, const wchar_t* s);
|
||||
mi_decl_malloc(unsigned char*, mi_mbsdup, const unsigned char* s);
|
||||
mi_decl_malloc(char*, mi_getcwd, char* buf, size_t buf_len);
|
||||
|
||||
mi_decl_noexcpt(int, mi__dupenv_s, char** buf, size_t* size, const char* name);
|
||||
mi_decl_noexcpt(int, mi__wdupenv_s, wchar_t** buf, size_t* size, const wchar_t* name);
|
||||
mi_decl_noexcpt(void*, mi__expand, void* p, size_t newsize);
|
||||
mi_decl_malloc( char*, mi__fullpath, char* buf, const char* path, size_t buf_len);
|
||||
mi_decl_malloc( wchar_t*, mi__wfullpath, wchar_t* buf, const wchar_t* path, size_t buf_len);
|
||||
mi_decl_malloc( wchar_t*, mi__wgetcwd, wchar_t* buf, size_t buf_len);
|
||||
// todo: tempnam, _wgetdcwd, and _wgetdcwd_nolock
|
||||
|
||||
// The `mi_new` wrappers implement C++ semantics on out-of-memory instead of directly returning `NULL`.
|
||||
// (and call `std::get_new_handler` and potentially raise a `std::bad_alloc` exception).
|
||||
@ -390,8 +396,8 @@ mi_decl_new(void*, mi_new_aligned, size_t size, size_t alignment) mi_attr_alloc_
|
||||
mi_decl_new(void*, mi_new_n, size_t count, size_t size) mi_attr_alloc_size2(1, 2);
|
||||
mi_decl_malloc(void*, mi_new_nothrow, size_t size) mi_attr_alloc_size(1);
|
||||
mi_decl_malloc(void*, mi_new_aligned_nothrow, size_t size, size_t alignment) mi_attr_alloc_size(1) mi_attr_alloc_align(2);
|
||||
mi_declx(mi_decl_nodiscard void*, mi_new_realloc, , void* p, size_t newsize) mi_attr_alloc_size(2) ;
|
||||
mi_declx(mi_decl_nodiscard void*, mi_new_reallocn, , void* p, size_t newcount, size_t size) mi_attr_alloc_size2(2, 3) ;
|
||||
mi_declx(mi_decl_nodiscard mi_decl_export void*, mi_new_realloc, , void* p, size_t newsize) mi_attr_alloc_size(2) ;
|
||||
mi_declx(mi_decl_nodiscard mi_decl_export void*, mi_new_reallocn, , void* p, size_t newcount, size_t size) mi_attr_alloc_size2(2, 3) ;
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
@ -553,8 +559,13 @@ template<class T1, class T2> bool operator!=(const mi_stl_allocator<T1>&, const
|
||||
|
||||
#define mi_wcsdup(s) MI_SOURCE_LOC(mi_wcsdup,s)
|
||||
#define mi_mbsdup(s) MI_SOURCE_LOC(mi_mbsdup,s)
|
||||
#define mi_dupenv_s(b,s,n) MI_SOURCE_LOC(mi_dupenv_s,b,s,n)
|
||||
#define mi_wdupenv_s(b,s,n) MI_SOURCE_LOC(mi_wdupenv_s,b,s,n)
|
||||
#define mi_getcwd(b,n) MI_SOURCE_LOC(mi_getcwd(b,n)
|
||||
#define mi__dupenv_s(b,s,n) MI_SOURCE_LOC(mi__dupenv_s,b,s,n)
|
||||
#define mi__wdupenv_s(b,s,n) MI_SOURCE_LOC(mi__wdupenv_s,b,s,n)
|
||||
#define mi__expand(p,n) MI_SOURCE_LOC(mi__expand,p,n)
|
||||
#define mi__fullpath(b,p,n) MI_SOURCE_LOC(mi__fullpath,b,p,n)
|
||||
#define mi__wfullpath(b,p,n) MI_SOURCE_LOC(mi__wfullpath,b,p,n)
|
||||
#define mi__wgetcwd(b,n) MI_SOURCE_LOC(mi__wgetcwd,b,n)
|
||||
|
||||
#define mi_posix_memalign(p,a,s) MI_SOURCE_LOC(mi_posix_memalign,p,a,s)
|
||||
#define mi_memalign(a,s) MI_SOURCE_LOC(mi_memalign,a,s)
|
||||
|
@ -176,6 +176,13 @@ void* memalign(size_t alignment, size_t size) { return MI_SOURCE_R
|
||||
void* aligned_alloc(size_t alignment, size_t size) { return MI_SOURCE_RET(mi_aligned_alloc, alignment, size); }
|
||||
int posix_memalign(void** p, size_t alignment, size_t size) { return MI_SOURCE_RET(mi_posix_memalign, p, alignment, size); }
|
||||
|
||||
char* strdup(const char* s) { return MI_SOURCE_RET(mi_strdup, s); }
|
||||
wchar_t* wcsdup(const wchar_t* s) { return MI_SOURCE_RET(mi_wcsdup, s); }
|
||||
|
||||
// gives compile errors if we override :-(
|
||||
// char* get_current_dir_name(void) { return MI_SOURCE_RET(mi_getcwd, NULL, 0); }
|
||||
// char* getcwd(char* buf, size_t buf_len) { return MI_SOURCE_RET(mi_getcwd, buf, buf_len); }
|
||||
|
||||
#if defined(__GLIBC__) && defined(__linux__)
|
||||
// forward __libc interface (needed for glibc-based Linux distributions)
|
||||
void* __libc_malloc(size_t size) MI_FORWARD1(mi_malloc,size);
|
||||
|
@ -10,6 +10,7 @@ terms of the MIT license. A copy of the license can be found in the file
|
||||
// for convenience and used when overriding these functions.
|
||||
// ------------------------------------------------------------------------
|
||||
#define MI_NO_SOURCE_DEBUG
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#include "mimalloc.h"
|
||||
#include "mimalloc-internal.h"
|
||||
|
||||
@ -20,6 +21,7 @@ terms of the MIT license. A copy of the license can be found in the file
|
||||
#include <errno.h>
|
||||
#include <string.h> // memcpy
|
||||
#include <stdlib.h> // getenv
|
||||
#include <wchar.h> // wcslen, wcrcpy
|
||||
|
||||
#ifndef EINVAL
|
||||
#define EINVAL 22
|
||||
@ -97,7 +99,7 @@ MI_SOURCE_API2(mi_decl_restrict void*, aligned_alloc, size_t, alignment, size_t,
|
||||
return p;
|
||||
}
|
||||
|
||||
static int mi_base_posix_memalign(void** p, size_t alignment, size_t size MI_SOURCE_XPARAM)
|
||||
MI_SOURCE_API3(int, posix_memalign, void**, p, size_t, alignment, size_t, size)
|
||||
{
|
||||
// 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>
|
||||
@ -117,24 +119,13 @@ static int mi_base_posix_memalign(void** p, size_t alignment, size_t size MI_SO
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
int dbg_mi_posix_memalign(void** p, size_t alignment, size_t size, mi_source_t __mi_source) mi_attr_noexcept {
|
||||
UNUSED(__mi_source);
|
||||
return mi_base_posix_memalign(p, alignment, size MI_SOURCE_XARG);
|
||||
}
|
||||
#endif
|
||||
|
||||
int mi_posix_memalign(void** p, size_t alignment, size_t size) mi_attr_noexcept {
|
||||
return mi_base_posix_memalign(p, alignment, size MI_SOURCE_XRET());
|
||||
}
|
||||
|
||||
MI_SOURCE_API1(mi_decl_restrict unsigned short*, wcsdup, const unsigned short*, s)
|
||||
MI_SOURCE_API1(mi_decl_restrict wchar_t*, wcsdup, const wchar_t*, s)
|
||||
{
|
||||
if (s==NULL) return NULL;
|
||||
size_t len;
|
||||
for(len = 0; s[len] != 0; len++) { }
|
||||
size_t size = (len+1)*sizeof(unsigned short);
|
||||
unsigned short* p = (unsigned short*)MI_SOURCE_ARG(mi_malloc, size);
|
||||
size_t size = (len+1)*sizeof(wchar_t);
|
||||
wchar_t* p = (wchar_t*)MI_SOURCE_ARG(mi_malloc, size);
|
||||
if (p != NULL) {
|
||||
memcpy(p,s,size);
|
||||
}
|
||||
@ -146,7 +137,112 @@ MI_SOURCE_API1(mi_decl_restrict unsigned char*, mbsdup, const unsigned char*, s)
|
||||
return (unsigned char*)MI_SOURCE_ARG(mi_strdup,(const char*)s);
|
||||
}
|
||||
|
||||
static int mi_base_dupenv_s(char** buf, size_t* size, const char* name MI_SOURCE_XPARAM)
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <direct.h> // getcwd
|
||||
#else
|
||||
#include <unistd.h> // getcwd
|
||||
#endif
|
||||
|
||||
MI_SOURCE_API2(mi_decl_restrict char*, getcwd, char*, buf, size_t, buf_len) {
|
||||
if (buf!=NULL && buf_len > 0) {
|
||||
#pragma warning(suppress:4996)
|
||||
return getcwd(buf, (int)buf_len);
|
||||
}
|
||||
else {
|
||||
size_t pmax = _mi_path_max();
|
||||
char* cbuf = (char*)MI_SOURCE_ARG(mi_malloc, pmax+1);
|
||||
#pragma warning(suppress:4996)
|
||||
char* res = getcwd(cbuf, (int)pmax);
|
||||
if (res != NULL) {
|
||||
res = MI_SOURCE_ARG(mi_strdup, cbuf); // shrink
|
||||
}
|
||||
mi_free(cbuf);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
MI_SOURCE_API3(mi_decl_restrict char*, _fullpath, char*, buf, const char*, path, size_t, buf_len) {
|
||||
if (path==NULL) return NULL;
|
||||
char* full = MI_SOURCE_ARG(mi_realpath, path, NULL);
|
||||
if (full==NULL) return NULL;
|
||||
if (buf==NULL) {
|
||||
return full;
|
||||
}
|
||||
else {
|
||||
size_t len = strlen(full);
|
||||
if (len < buf_len) {
|
||||
strcpy(buf, full);
|
||||
}
|
||||
mi_free(full);
|
||||
return (len < buf_len ? buf : NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Microsoft: _wgetcwd, _wfullpath, _(w)dupenv, _aligned_recalloc, _aligned_offset_recalloc
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
static wchar_t* mi_mbstowcs_dup(const char* s MI_SOURCE_XPARAM) {
|
||||
if (s==NULL) return NULL;
|
||||
size_t len = strlen(s);
|
||||
wchar_t* ws = (wchar_t*)MI_SOURCE_ARG(mi_malloc, (len + 1)*sizeof(wchar_t)); // over allocate by a factor 2
|
||||
mbstowcs(ws, s, len + 1);
|
||||
return ws;
|
||||
}
|
||||
|
||||
static char* mi_wcstombs_dup(const wchar_t* ws MI_SOURCE_XPARAM) {
|
||||
if (ws==NULL) return NULL;
|
||||
size_t len = wcslen(ws);
|
||||
size_t sz = (len + 1)*sizeof(wchar_t)*2; // over allocate by a factor 4 :( ok for our purposes though
|
||||
char* s = (char*)MI_SOURCE_ARG(mi_malloc, sz);
|
||||
wcstombs(s, ws, sz);
|
||||
return s;
|
||||
}
|
||||
|
||||
MI_SOURCE_API3(mi_decl_restrict wchar_t*, _wfullpath, wchar_t*, wbuf, const wchar_t*, wpath, size_t, wbuf_len) {
|
||||
if (wpath==NULL) return NULL;
|
||||
char* path = mi_wcstombs_dup(wbuf MI_SOURCE_XARG);
|
||||
char* full = MI_SOURCE_ARG(mi_realpath, path, NULL);
|
||||
mi_free(path);
|
||||
if (full==NULL) return NULL;
|
||||
wchar_t* wfull = mi_mbstowcs_dup( full MI_SOURCE_XARG);
|
||||
mi_free(full);
|
||||
if (wbuf==NULL) {
|
||||
return wfull;
|
||||
}
|
||||
else {
|
||||
size_t len = wcslen(wfull);
|
||||
if (len < wbuf_len) {
|
||||
wcscpy(wbuf, wfull);
|
||||
}
|
||||
mi_free(wfull);
|
||||
return (len < wbuf_len ? wbuf : NULL);
|
||||
}
|
||||
}
|
||||
|
||||
MI_SOURCE_API2(mi_decl_restrict wchar_t*, _wgetcwd, wchar_t*, wbuf, size_t, wbuf_len)
|
||||
{
|
||||
char* res = MI_SOURCE_ARG(mi_getcwd, NULL, 0);
|
||||
if (res == NULL) return NULL;
|
||||
wchar_t* wres = mi_mbstowcs_dup( res MI_SOURCE_XARG);
|
||||
mi_free(res);
|
||||
if (wbuf == NULL || wbuf_len == 0) {
|
||||
return wres;
|
||||
}
|
||||
else {
|
||||
size_t len = wcslen(wres);
|
||||
if (len < wbuf_len) {
|
||||
wcscpy(wbuf, wres);
|
||||
}
|
||||
mi_free(wres);
|
||||
return (len < wbuf_len ? wbuf : NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
MI_SOURCE_API3(int, _dupenv_s, char**, buf, size_t*, size, const char*, name)
|
||||
{
|
||||
if (buf==NULL || name==NULL) return EINVAL;
|
||||
if (size != NULL) *size = 0;
|
||||
@ -163,19 +259,7 @@ static int mi_base_dupenv_s(char** buf, size_t* size, const char* name MI_SOURC
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
int dbg_mi_dupenv_s(char** buf, size_t* size, const char* name, mi_source_t __mi_source) mi_attr_noexcept {
|
||||
UNUSED(__mi_source);
|
||||
return mi_base_dupenv_s(buf, size, name MI_SOURCE_XARG);
|
||||
}
|
||||
#endif
|
||||
|
||||
int mi_dupenv_s(char** buf, size_t* size, const char* name) mi_attr_noexcept {
|
||||
return mi_base_dupenv_s(buf, size, name MI_SOURCE_XRET());
|
||||
}
|
||||
|
||||
|
||||
static int mi_base_wdupenv_s(unsigned short** buf, size_t* size, const unsigned short* name MI_SOURCE_XPARAM)
|
||||
MI_SOURCE_API3(int, _wdupenv_s, wchar_t**, buf, size_t*, size, const wchar_t*, name)
|
||||
{
|
||||
if (buf==NULL || name==NULL) return EINVAL;
|
||||
if (size != NULL) *size = 0;
|
||||
@ -188,30 +272,19 @@ static int mi_base_wdupenv_s(unsigned short** buf, size_t* size, const unsigned
|
||||
return EINVAL;
|
||||
#else
|
||||
#pragma warning(suppress:4996)
|
||||
unsigned short* p = (unsigned short*)_wgetenv((const wchar_t*)name);
|
||||
wchar_t* p = (wchar_t*)_wgetenv(name);
|
||||
if (p==NULL) {
|
||||
*buf = NULL;
|
||||
}
|
||||
else {
|
||||
*buf = MI_SOURCE_ARG(mi_wcsdup, p);
|
||||
if (*buf==NULL) return ENOMEM;
|
||||
if (size != NULL) *size = wcslen((const wchar_t*)p);
|
||||
if (size != NULL) *size = wcslen(p);
|
||||
}
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
int dbg_mi_wdupenv_s(unsigned short** buf, size_t* size, const unsigned short* name, mi_source_t __mi_source) mi_attr_noexcept {
|
||||
UNUSED(__mi_source);
|
||||
return mi_base_wdupenv_s(buf, size, name MI_SOURCE_XARG);
|
||||
}
|
||||
#endif
|
||||
|
||||
int mi_wdupenv_s(unsigned short** buf, size_t* size, const unsigned short* name) mi_attr_noexcept {
|
||||
return mi_base_wdupenv_s(buf, size, name MI_SOURCE_XRET());
|
||||
}
|
||||
|
||||
|
||||
#ifndef NDEBUG
|
||||
void* dbg_mi_aligned_offset_recalloc(void* p, size_t newcount, size_t size, size_t alignment, size_t offset, mi_source_t __mi_source) mi_attr_noexcept { // Microsoft
|
||||
|
38
src/alloc.c
38
src/alloc.c
@ -11,6 +11,7 @@ terms of the MIT license. A copy of the license can be found in the file
|
||||
|
||||
#include <string.h> // memset, memcpy, strlen
|
||||
#include <stdlib.h> // malloc, exit
|
||||
#include <wchar.h> // wcslen
|
||||
|
||||
#define MI_IN_ALLOC_C
|
||||
#include "alloc-override.c"
|
||||
@ -599,18 +600,16 @@ MI_ALLOC_API3(void*, recalloc, mi_heap_t*, heap, void*, p, size_t, count, size_t
|
||||
return _mi_base_realloc_zero(heap, p, total, true MI_SOURCE_XARG);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ------------------------------------------------------
|
||||
// strdup, strndup, and realpath
|
||||
// ------------------------------------------------------
|
||||
/*-------------------------------------------------------
|
||||
strdup, strndup, and realpath
|
||||
-------------------------------------------------------*/
|
||||
|
||||
// `strdup` using mi_malloc
|
||||
MI_ALLOC_API1(mi_decl_restrict char*, strdup, mi_heap_t*,heap, const char*,s)
|
||||
MI_ALLOC_API1(mi_decl_restrict char*, strdup, mi_heap_t*, heap, const char*, s)
|
||||
{
|
||||
if (s == NULL) return NULL;
|
||||
size_t n = strlen(s);
|
||||
char* t = (char*)mi_base_malloc(heap, n+1 MI_SOURCE_XARG);
|
||||
char* t = (char*)MI_SOURCE_ARG(mi_heap_malloc, heap, n+1);
|
||||
if (t != NULL) memcpy(t, s, n + 1);
|
||||
return t;
|
||||
}
|
||||
@ -621,20 +620,23 @@ MI_ALLOC_API2(mi_decl_restrict char*, strndup, mi_heap_t*, heap, const char*, s,
|
||||
if (s == NULL) return NULL;
|
||||
size_t m = strlen(s);
|
||||
if (n > m) n = m;
|
||||
char* t = (char*)mi_base_malloc(heap, n+1 MI_SOURCE_XARG);
|
||||
char* t = (char*)MI_SOURCE_ARG(mi_heap_malloc, heap, n+1);
|
||||
if (t == NULL) return NULL;
|
||||
memcpy(t, s, n);
|
||||
t[n] = 0;
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
#ifndef __wasi__
|
||||
// `realpath` using mi_malloc
|
||||
#ifdef _WIN32
|
||||
#ifndef PATH_MAX
|
||||
#define PATH_MAX MAX_PATH
|
||||
#endif
|
||||
size_t _mi_path_max(void) {
|
||||
return PATH_MAX;
|
||||
}
|
||||
|
||||
#include <windows.h>
|
||||
MI_ALLOC_API2(mi_decl_restrict char*, realpath, mi_heap_t*, heap, const char*, fname, char*, resolved_name)
|
||||
{
|
||||
@ -651,15 +653,15 @@ MI_ALLOC_API2(mi_decl_restrict char*, realpath, mi_heap_t*, heap, const char*, f
|
||||
return resolved_name;
|
||||
}
|
||||
else {
|
||||
return mi_base_strndup(heap, buf, PATH_MAX MI_SOURCE_XARG);
|
||||
return MI_SOURCE_ARG(mi_heap_strndup, heap, buf, PATH_MAX);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#include <unistd.h> // pathconf
|
||||
static size_t mi_path_max() {
|
||||
size_t _mi_path_max(void) {
|
||||
static size_t path_max = 0;
|
||||
if (path_max <= 0) {
|
||||
long m = pathconf("/",_PC_PATH_MAX);
|
||||
long m = pathconf("/", _PC_PATH_MAX);
|
||||
if (m <= 0) path_max = 4096; // guess
|
||||
else if (m < 256) path_max = 256; // at least 256
|
||||
else path_max = m;
|
||||
@ -670,20 +672,22 @@ static size_t mi_path_max() {
|
||||
MI_ALLOC_API2(mi_decl_restrict char*, realpath, mi_heap_t*, heap, const char*, fname, char*, resolved_name)
|
||||
{
|
||||
if (resolved_name != NULL) {
|
||||
return realpath(fname,resolved_name);
|
||||
return realpath(fname, resolved_name);
|
||||
}
|
||||
else {
|
||||
size_t n = mi_path_max();
|
||||
char* buf = (char*)mi_malloc(n+1);
|
||||
size_t n = _mi_path_max();
|
||||
char* buf = (char*)MI_SOURCE_ARG(mi_heap_malloc, heap, n+1);
|
||||
if (buf==NULL) return NULL;
|
||||
char* rname = realpath(fname,buf);
|
||||
char* result = mi_base_strndup(heap, rname, n MI_SOURCE_XARG); // ok if `rname==NULL`
|
||||
char* rname = realpath(fname, buf);
|
||||
char* result = MI_SOURCE_ARG(mi_heap_strndup, heap, rname, n); // ok if `rname==NULL`
|
||||
mi_free(buf);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#else // wasi
|
||||
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------
|
||||
|
@ -9,7 +9,7 @@
|
||||
#include <mimalloc.h>
|
||||
#include <mimalloc-new-delete.h>
|
||||
#include <mimalloc-override.h>
|
||||
|
||||
#include <crtdbg.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
|
Loading…
x
Reference in New Issue
Block a user