mirror of
https://github.com/microsoft/mimalloc.git
synced 2025-05-04 22:49:32 +03:00
commit
ad45dbf0e5
5 changed files with 51 additions and 1 deletions
|
@ -196,6 +196,11 @@ static inline void mi_atomic_write(volatile uintptr_t* p, uintptr_t x) {
|
||||||
asm volatile("yield");
|
asm volatile("yield");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#elif defined(__wasi__)
|
||||||
|
#include <sched.h>
|
||||||
|
static inline void mi_atomic_yield() {
|
||||||
|
sched_yield();
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
static inline void mi_atomic_yield(void) {
|
static inline void mi_atomic_yield(void) {
|
||||||
|
|
|
@ -441,6 +441,7 @@ char* mi_strndup(const char* s, size_t n) mi_attr_noexcept {
|
||||||
return mi_heap_strndup(mi_get_default_heap(),s,n);
|
return mi_heap_strndup(mi_get_default_heap(),s,n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef __wasi__
|
||||||
// `realpath` using mi_malloc
|
// `realpath` using mi_malloc
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#ifndef PATH_MAX
|
#ifndef PATH_MAX
|
||||||
|
@ -497,6 +498,7 @@ char* mi_heap_realpath(mi_heap_t* heap, const char* fname, char* resolved_name)
|
||||||
char* mi_realpath(const char* fname, char* resolved_name) mi_attr_noexcept {
|
char* mi_realpath(const char* fname, char* resolved_name) mi_attr_noexcept {
|
||||||
return mi_heap_realpath(mi_get_default_heap(),fname,resolved_name);
|
return mi_heap_realpath(mi_get_default_heap(),fname,resolved_name);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*-------------------------------------------------------
|
/*-------------------------------------------------------
|
||||||
C++ new and new_aligned
|
C++ new and new_aligned
|
||||||
|
|
11
src/init.c
11
src/init.c
|
@ -148,6 +148,10 @@ uintptr_t _mi_random_shuffle(uintptr_t x) {
|
||||||
}
|
}
|
||||||
|
|
||||||
uintptr_t _mi_random_init(uintptr_t seed /* can be zero */) {
|
uintptr_t _mi_random_init(uintptr_t seed /* can be zero */) {
|
||||||
|
#ifdef __wasi__ // no ASLR when using WebAssembly, and time granularity may be coarse
|
||||||
|
uintptr_t x;
|
||||||
|
arc4random_buf(&x, sizeof x);
|
||||||
|
#else
|
||||||
// Hopefully, ASLR makes our function address random
|
// Hopefully, ASLR makes our function address random
|
||||||
uintptr_t x = (uintptr_t)((void*)&_mi_random_init);
|
uintptr_t x = (uintptr_t)((void*)&_mi_random_init);
|
||||||
x ^= seed;
|
x ^= seed;
|
||||||
|
@ -169,6 +173,7 @@ uintptr_t _mi_random_init(uintptr_t seed /* can be zero */) {
|
||||||
for (uintptr_t i = 0; i < max; i++) {
|
for (uintptr_t i = 0; i < max; i++) {
|
||||||
x = _mi_random_shuffle(x);
|
x = _mi_random_shuffle(x);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -269,7 +274,9 @@ static bool _mi_heap_done(void) {
|
||||||
// to set up the thread local keys.
|
// to set up the thread local keys.
|
||||||
// --------------------------------------------------------
|
// --------------------------------------------------------
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifdef __wasi__
|
||||||
|
// no pthreads in the WebAssembly Standard Interface
|
||||||
|
#elif !defined(_WIN32)
|
||||||
#define MI_USE_PTHREADS
|
#define MI_USE_PTHREADS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -290,6 +297,8 @@ static bool _mi_heap_done(void) {
|
||||||
static void mi_pthread_done(void* value) {
|
static void mi_pthread_done(void* value) {
|
||||||
if (value!=NULL) mi_thread_done();
|
if (value!=NULL) mi_thread_done();
|
||||||
}
|
}
|
||||||
|
#elif defined(__wasi__)
|
||||||
|
// no pthreads in the WebAssembly Standard Interface
|
||||||
#else
|
#else
|
||||||
#pragma message("define a way to call mi_thread_done when a thread is done")
|
#pragma message("define a way to call mi_thread_done when a thread is done")
|
||||||
#endif
|
#endif
|
||||||
|
|
30
src/os.c
30
src/os.c
|
@ -16,6 +16,8 @@ terms of the MIT license. A copy of the license can be found in the file
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#elif defined(__wasi__)
|
||||||
|
// stdlib.h is all we need, and has already been included in mimalloc.h
|
||||||
#else
|
#else
|
||||||
#include <sys/mman.h> // mmap
|
#include <sys/mman.h> // mmap
|
||||||
#include <unistd.h> // sysconf
|
#include <unistd.h> // sysconf
|
||||||
|
@ -136,6 +138,11 @@ void _mi_os_init(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#elif defined(__wasi__)
|
||||||
|
void _mi_os_init() {
|
||||||
|
os_page_size = 0x10000; // WebAssembly has a fixed page size: 64KB
|
||||||
|
os_alloc_granularity = 16;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
void _mi_os_init() {
|
void _mi_os_init() {
|
||||||
// get the page size
|
// get the page size
|
||||||
|
@ -161,6 +168,8 @@ static bool mi_os_mem_free(void* addr, size_t size, mi_stats_t* stats)
|
||||||
bool err = false;
|
bool err = false;
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
err = (VirtualFree(addr, 0, MEM_RELEASE) == 0);
|
err = (VirtualFree(addr, 0, MEM_RELEASE) == 0);
|
||||||
|
#elif defined(__wasi__)
|
||||||
|
err = 0; // WebAssembly's heap cannot be shrunk
|
||||||
#else
|
#else
|
||||||
err = (munmap(addr, size) == -1);
|
err = (munmap(addr, size) == -1);
|
||||||
#endif
|
#endif
|
||||||
|
@ -216,6 +225,19 @@ static void* mi_win_virtual_alloc(void* addr, size_t size, size_t try_alignment,
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#elif defined(__wasi__)
|
||||||
|
static void* mi_wasm_heap_grow(size_t size, size_t try_alignment) {
|
||||||
|
uintptr_t base = __builtin_wasm_memory_size(0) * os_page_size;
|
||||||
|
uintptr_t aligned_base = _mi_align_up(base, (uintptr_t) try_alignment);
|
||||||
|
size_t alloc_size = aligned_base - base + size;
|
||||||
|
mi_assert(alloc_size >= size);
|
||||||
|
if (alloc_size < size) return NULL;
|
||||||
|
if (__builtin_wasm_memory_grow(0, alloc_size / os_page_size) == SIZE_MAX) {
|
||||||
|
errno = ENOMEM;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return (void*) aligned_base;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
static void* mi_unix_mmap(size_t size, size_t try_alignment, int protect_flags) {
|
static void* mi_unix_mmap(size_t size, size_t try_alignment, int protect_flags) {
|
||||||
void* p = NULL;
|
void* p = NULL;
|
||||||
|
@ -272,6 +294,8 @@ static void* mi_os_mem_alloc(size_t size, size_t try_alignment, bool commit, mi_
|
||||||
int flags = MEM_RESERVE;
|
int flags = MEM_RESERVE;
|
||||||
if (commit) flags |= MEM_COMMIT;
|
if (commit) flags |= MEM_COMMIT;
|
||||||
p = mi_win_virtual_alloc(NULL, size, try_alignment, flags);
|
p = mi_win_virtual_alloc(NULL, size, try_alignment, flags);
|
||||||
|
#elif defined(__wasi__)
|
||||||
|
p = mi_wasm_heap_grow(size, try_alignment);
|
||||||
#else
|
#else
|
||||||
int protect_flags = (commit ? (PROT_WRITE | PROT_READ) : PROT_NONE);
|
int protect_flags = (commit ? (PROT_WRITE | PROT_READ) : PROT_NONE);
|
||||||
p = mi_unix_mmap(size, try_alignment, protect_flags);
|
p = mi_unix_mmap(size, try_alignment, protect_flags);
|
||||||
|
@ -434,6 +458,8 @@ static bool mi_os_commitx(void* addr, size_t size, bool commit, bool conservativ
|
||||||
BOOL ok = VirtualFree(start, csize, MEM_DECOMMIT);
|
BOOL ok = VirtualFree(start, csize, MEM_DECOMMIT);
|
||||||
err = (ok ? 0 : GetLastError());
|
err = (ok ? 0 : GetLastError());
|
||||||
}
|
}
|
||||||
|
#elif defined(__wasi__)
|
||||||
|
// WebAssembly guests can't control memory protection
|
||||||
#else
|
#else
|
||||||
err = mprotect(start, csize, (commit ? (PROT_READ | PROT_WRITE) : PROT_NONE));
|
err = mprotect(start, csize, (commit ? (PROT_READ | PROT_WRITE) : PROT_NONE));
|
||||||
#endif
|
#endif
|
||||||
|
@ -496,6 +522,8 @@ static bool mi_os_resetx(void* addr, size_t size, bool reset, mi_stats_t* stats)
|
||||||
advice = MADV_DONTNEED;
|
advice = MADV_DONTNEED;
|
||||||
err = madvise(start, csize, advice);
|
err = madvise(start, csize, advice);
|
||||||
}
|
}
|
||||||
|
#elif defined(__wasi__)
|
||||||
|
int err = 0;
|
||||||
#else
|
#else
|
||||||
int err = madvise(start, csize, MADV_DONTNEED);
|
int err = madvise(start, csize, MADV_DONTNEED);
|
||||||
#endif
|
#endif
|
||||||
|
@ -543,6 +571,8 @@ static bool mi_os_protectx(void* addr, size_t size, bool protect) {
|
||||||
DWORD oldprotect = 0;
|
DWORD oldprotect = 0;
|
||||||
BOOL ok = VirtualProtect(start, csize, protect ? PAGE_NOACCESS : PAGE_READWRITE, &oldprotect);
|
BOOL ok = VirtualProtect(start, csize, protect ? PAGE_NOACCESS : PAGE_READWRITE, &oldprotect);
|
||||||
err = (ok ? 0 : GetLastError());
|
err = (ok ? 0 : GetLastError());
|
||||||
|
#elif defined(__wasi__)
|
||||||
|
err = 0;
|
||||||
#else
|
#else
|
||||||
err = mprotect(start, csize, protect ? PROT_NONE : (PROT_READ | PROT_WRITE));
|
err = mprotect(start, csize, protect ? PROT_NONE : (PROT_READ | PROT_WRITE));
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -407,7 +407,11 @@ static void mi_process_info(double* utime, double* stime, size_t* peak_rss, size
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
#ifndef __wasi__
|
||||||
|
// WebAssembly instances are not processes
|
||||||
#pragma message("define a way to get process info")
|
#pragma message("define a way to get process info")
|
||||||
|
#endif
|
||||||
|
|
||||||
static void mi_process_info(double* utime, double* stime, size_t* peak_rss, size_t* page_faults, size_t* page_reclaim, size_t* peak_commit) {
|
static void mi_process_info(double* utime, double* stime, size_t* peak_rss, size_t* page_faults, size_t* page_reclaim, size_t* peak_commit) {
|
||||||
*peak_rss = 0;
|
*peak_rss = 0;
|
||||||
*page_faults = 0;
|
*page_faults = 0;
|
||||||
|
|
Loading…
Add table
Reference in a new issue