diff --git a/Cargo.toml b/Cargo.toml index 28a522f..0c218bc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,11 +1,17 @@ [package] -name = "mimalloc-rs" -version = "0.1.0" +name = "mimalloc-rust" +version = "0.1.1" edition = "2018" +repository = "https://github.com/lemonhx/mimalloc-rust" +description = "the best binding for mimalloc in rust" +license = "MIT" + +[workspace] +members = ["mimalloc-rust-sys"] -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dev-dependencies] lazy_static = "1.4.0" + [dependencies] -mimalloc-sys = { path = "./mimalloc-sys" } +mimalloc-rust-sys = "1.7.2" cty = "0.2" diff --git a/License.md b/License.md new file mode 100644 index 0000000..750c5ba --- /dev/null +++ b/License.md @@ -0,0 +1,23 @@ +# MIT License + +> Copyright (c) 2021 LemonHX + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + + +**THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE.** \ No newline at end of file diff --git a/README.md b/README.md index 568d5e0..b3399e6 100644 --- a/README.md +++ b/README.md @@ -1 +1,23 @@ -mimalloc 1.7.2 \ No newline at end of file +# The Best and Highest-Leveled and Newest bingding for MiMalloc Ever Existed in Rust +> mimalloc 1.7.2 stable + +![ci](https://github.com/LemonHX/mimalloc-rust/actions/workflows/rust.yml/badge.svg) + +## Why create this + +in repo `https://github.com/purpleprotocol/mimalloc_rust` i didn't see any data types and it neither has all the functionalities which mimalloc has provided, in other words it's garbage. + +## Usage + +first add to dependencies +```toml +[dependencies] +mimalloc-rust = "0.1" +``` +then set the global allocator +```rust +use mimalloc_rust::*; + +#[global_allocator] +static GLOBAL_MIMALLOC: GlobalMiMalloc = GlobalMiMalloc; +``` \ No newline at end of file diff --git a/mimalloc-sys/.gitignore b/mimalloc-rust-sys/.gitignore similarity index 100% rename from mimalloc-sys/.gitignore rename to mimalloc-rust-sys/.gitignore diff --git a/mimalloc-sys/Cargo.toml b/mimalloc-rust-sys/Cargo.toml similarity index 56% rename from mimalloc-sys/Cargo.toml rename to mimalloc-rust-sys/Cargo.toml index fda816a..1eab607 100644 --- a/mimalloc-sys/Cargo.toml +++ b/mimalloc-rust-sys/Cargo.toml @@ -1,5 +1,7 @@ [package] -name = "mimalloc-sys" +name = "mimalloc-rust-sys" +description = "mimalloc_rust hand writted sys binding" +license = "MIT" # mimalloc version version = "1.7.2" edition = "2018" diff --git a/mimalloc-sys/build.rs b/mimalloc-rust-sys/build.rs similarity index 96% rename from mimalloc-sys/build.rs rename to mimalloc-rust-sys/build.rs index 9941014..a2d03eb 100644 --- a/mimalloc-sys/build.rs +++ b/mimalloc-rust-sys/build.rs @@ -1,6 +1,4 @@ use std::env; -extern crate bindgen; -use std::path::PathBuf; fn main() { let mut build = cc::Build::new(); diff --git a/mimalloc-sys/c_src/mimalloc/LICENSE b/mimalloc-rust-sys/c_src/mimalloc/LICENSE similarity index 100% rename from mimalloc-sys/c_src/mimalloc/LICENSE rename to mimalloc-rust-sys/c_src/mimalloc/LICENSE diff --git a/mimalloc-sys/c_src/mimalloc/include/mimalloc-atomic.h b/mimalloc-rust-sys/c_src/mimalloc/include/mimalloc-atomic.h similarity index 100% rename from mimalloc-sys/c_src/mimalloc/include/mimalloc-atomic.h rename to mimalloc-rust-sys/c_src/mimalloc/include/mimalloc-atomic.h diff --git a/mimalloc-sys/c_src/mimalloc/include/mimalloc-internal.h b/mimalloc-rust-sys/c_src/mimalloc/include/mimalloc-internal.h similarity index 100% rename from mimalloc-sys/c_src/mimalloc/include/mimalloc-internal.h rename to mimalloc-rust-sys/c_src/mimalloc/include/mimalloc-internal.h diff --git a/mimalloc-sys/c_src/mimalloc/include/mimalloc-new-delete.h b/mimalloc-rust-sys/c_src/mimalloc/include/mimalloc-new-delete.h similarity index 100% rename from mimalloc-sys/c_src/mimalloc/include/mimalloc-new-delete.h rename to mimalloc-rust-sys/c_src/mimalloc/include/mimalloc-new-delete.h diff --git a/mimalloc-sys/c_src/mimalloc/include/mimalloc-override.h b/mimalloc-rust-sys/c_src/mimalloc/include/mimalloc-override.h similarity index 100% rename from mimalloc-sys/c_src/mimalloc/include/mimalloc-override.h rename to mimalloc-rust-sys/c_src/mimalloc/include/mimalloc-override.h diff --git a/mimalloc-sys/c_src/mimalloc/include/mimalloc-types.h b/mimalloc-rust-sys/c_src/mimalloc/include/mimalloc-types.h similarity index 100% rename from mimalloc-sys/c_src/mimalloc/include/mimalloc-types.h rename to mimalloc-rust-sys/c_src/mimalloc/include/mimalloc-types.h diff --git a/mimalloc-sys/c_src/mimalloc/include/mimalloc.h b/mimalloc-rust-sys/c_src/mimalloc/include/mimalloc.h similarity index 100% rename from mimalloc-sys/c_src/mimalloc/include/mimalloc.h rename to mimalloc-rust-sys/c_src/mimalloc/include/mimalloc.h diff --git a/mimalloc-sys/c_src/mimalloc/src/alloc-aligned.c b/mimalloc-rust-sys/c_src/mimalloc/src/alloc-aligned.c similarity index 100% rename from mimalloc-sys/c_src/mimalloc/src/alloc-aligned.c rename to mimalloc-rust-sys/c_src/mimalloc/src/alloc-aligned.c diff --git a/mimalloc-sys/c_src/mimalloc/src/alloc-override-osx.c b/mimalloc-rust-sys/c_src/mimalloc/src/alloc-override-osx.c similarity index 100% rename from mimalloc-sys/c_src/mimalloc/src/alloc-override-osx.c rename to mimalloc-rust-sys/c_src/mimalloc/src/alloc-override-osx.c diff --git a/mimalloc-sys/c_src/mimalloc/src/alloc-override.c b/mimalloc-rust-sys/c_src/mimalloc/src/alloc-override.c similarity index 100% rename from mimalloc-sys/c_src/mimalloc/src/alloc-override.c rename to mimalloc-rust-sys/c_src/mimalloc/src/alloc-override.c diff --git a/mimalloc-sys/c_src/mimalloc/src/alloc-posix.c b/mimalloc-rust-sys/c_src/mimalloc/src/alloc-posix.c similarity index 100% rename from mimalloc-sys/c_src/mimalloc/src/alloc-posix.c rename to mimalloc-rust-sys/c_src/mimalloc/src/alloc-posix.c diff --git a/mimalloc-sys/c_src/mimalloc/src/alloc.c b/mimalloc-rust-sys/c_src/mimalloc/src/alloc.c similarity index 100% rename from mimalloc-sys/c_src/mimalloc/src/alloc.c rename to mimalloc-rust-sys/c_src/mimalloc/src/alloc.c diff --git a/mimalloc-sys/c_src/mimalloc/src/arena.c b/mimalloc-rust-sys/c_src/mimalloc/src/arena.c similarity index 100% rename from mimalloc-sys/c_src/mimalloc/src/arena.c rename to mimalloc-rust-sys/c_src/mimalloc/src/arena.c diff --git a/mimalloc-sys/c_src/mimalloc/src/bitmap.c b/mimalloc-rust-sys/c_src/mimalloc/src/bitmap.c similarity index 100% rename from mimalloc-sys/c_src/mimalloc/src/bitmap.c rename to mimalloc-rust-sys/c_src/mimalloc/src/bitmap.c diff --git a/mimalloc-sys/c_src/mimalloc/src/bitmap.h b/mimalloc-rust-sys/c_src/mimalloc/src/bitmap.h similarity index 100% rename from mimalloc-sys/c_src/mimalloc/src/bitmap.h rename to mimalloc-rust-sys/c_src/mimalloc/src/bitmap.h diff --git a/mimalloc-sys/c_src/mimalloc/src/heap.c b/mimalloc-rust-sys/c_src/mimalloc/src/heap.c similarity index 100% rename from mimalloc-sys/c_src/mimalloc/src/heap.c rename to mimalloc-rust-sys/c_src/mimalloc/src/heap.c diff --git a/mimalloc-sys/c_src/mimalloc/src/init.c b/mimalloc-rust-sys/c_src/mimalloc/src/init.c similarity index 100% rename from mimalloc-sys/c_src/mimalloc/src/init.c rename to mimalloc-rust-sys/c_src/mimalloc/src/init.c diff --git a/mimalloc-sys/c_src/mimalloc/src/options.c b/mimalloc-rust-sys/c_src/mimalloc/src/options.c similarity index 100% rename from mimalloc-sys/c_src/mimalloc/src/options.c rename to mimalloc-rust-sys/c_src/mimalloc/src/options.c diff --git a/mimalloc-sys/c_src/mimalloc/src/os.c b/mimalloc-rust-sys/c_src/mimalloc/src/os.c similarity index 100% rename from mimalloc-sys/c_src/mimalloc/src/os.c rename to mimalloc-rust-sys/c_src/mimalloc/src/os.c diff --git a/mimalloc-sys/c_src/mimalloc/src/page-queue.c b/mimalloc-rust-sys/c_src/mimalloc/src/page-queue.c similarity index 100% rename from mimalloc-sys/c_src/mimalloc/src/page-queue.c rename to mimalloc-rust-sys/c_src/mimalloc/src/page-queue.c diff --git a/mimalloc-sys/c_src/mimalloc/src/page.c b/mimalloc-rust-sys/c_src/mimalloc/src/page.c similarity index 100% rename from mimalloc-sys/c_src/mimalloc/src/page.c rename to mimalloc-rust-sys/c_src/mimalloc/src/page.c diff --git a/mimalloc-sys/c_src/mimalloc/src/random.c b/mimalloc-rust-sys/c_src/mimalloc/src/random.c similarity index 100% rename from mimalloc-sys/c_src/mimalloc/src/random.c rename to mimalloc-rust-sys/c_src/mimalloc/src/random.c diff --git a/mimalloc-sys/c_src/mimalloc/src/region.c b/mimalloc-rust-sys/c_src/mimalloc/src/region.c similarity index 100% rename from mimalloc-sys/c_src/mimalloc/src/region.c rename to mimalloc-rust-sys/c_src/mimalloc/src/region.c diff --git a/mimalloc-sys/c_src/mimalloc/src/segment.c b/mimalloc-rust-sys/c_src/mimalloc/src/segment.c similarity index 100% rename from mimalloc-sys/c_src/mimalloc/src/segment.c rename to mimalloc-rust-sys/c_src/mimalloc/src/segment.c diff --git a/mimalloc-sys/c_src/mimalloc/src/static.c b/mimalloc-rust-sys/c_src/mimalloc/src/static.c similarity index 100% rename from mimalloc-sys/c_src/mimalloc/src/static.c rename to mimalloc-rust-sys/c_src/mimalloc/src/static.c diff --git a/mimalloc-sys/c_src/mimalloc/src/stats.c b/mimalloc-rust-sys/c_src/mimalloc/src/stats.c similarity index 100% rename from mimalloc-sys/c_src/mimalloc/src/stats.c rename to mimalloc-rust-sys/c_src/mimalloc/src/stats.c diff --git a/mimalloc-sys/src/aligned_allocation.rs b/mimalloc-rust-sys/src/aligned_allocation.rs similarity index 97% rename from mimalloc-sys/src/aligned_allocation.rs rename to mimalloc-rust-sys/src/aligned_allocation.rs index e4949eb..73b8eff 100644 --- a/mimalloc-sys/src/aligned_allocation.rs +++ b/mimalloc-rust-sys/src/aligned_allocation.rs @@ -1,24 +1,24 @@ -use cty::c_void; - -//Doc: https://microsoft.github.io/mimalloc/group__aligned.html - -extern "C" { - pub fn mi_malloc_aligned(size: usize, alignment: usize) -> *mut c_void; - pub fn mi_malloc_aligned_at(size: usize, alignment: usize, offset: usize) -> *mut c_void; - pub fn mi_zalloc_aligned(size: usize, alignment: usize) -> *mut c_void; - pub fn mi_zalloc_aligned_at(size: usize, alignment: usize, offset: usize) -> *mut c_void; - pub fn mi_calloc_aligned(count: usize, size: usize, alignment: usize) -> *mut c_void; - pub fn mi_calloc_aligned_at( - count: usize, - size: usize, - alignment: usize, - offset: usize, - ) -> *mut c_void; - pub fn mi_realloc_aligned(p: *mut c_void, newsize: usize, alignment: usize) -> *mut c_void; - pub fn mi_realloc_aligned_at( - p: *mut c_void, - newsize: usize, - alignment: usize, - offset: usize, - ) -> *mut c_void; -} +use cty::c_void; + +//Doc: https://microsoft.github.io/mimalloc/group__aligned.html + +extern "C" { + pub fn mi_malloc_aligned(size: usize, alignment: usize) -> *mut c_void; + pub fn mi_malloc_aligned_at(size: usize, alignment: usize, offset: usize) -> *mut c_void; + pub fn mi_zalloc_aligned(size: usize, alignment: usize) -> *mut c_void; + pub fn mi_zalloc_aligned_at(size: usize, alignment: usize, offset: usize) -> *mut c_void; + pub fn mi_calloc_aligned(count: usize, size: usize, alignment: usize) -> *mut c_void; + pub fn mi_calloc_aligned_at( + count: usize, + size: usize, + alignment: usize, + offset: usize, + ) -> *mut c_void; + pub fn mi_realloc_aligned(p: *mut c_void, newsize: usize, alignment: usize) -> *mut c_void; + pub fn mi_realloc_aligned_at( + p: *mut c_void, + newsize: usize, + alignment: usize, + offset: usize, + ) -> *mut c_void; +} diff --git a/mimalloc-sys/src/basic_allocation.rs b/mimalloc-rust-sys/src/basic_allocation.rs similarity index 98% rename from mimalloc-sys/src/basic_allocation.rs rename to mimalloc-rust-sys/src/basic_allocation.rs index c95d262..3739faf 100644 --- a/mimalloc-sys/src/basic_allocation.rs +++ b/mimalloc-rust-sys/src/basic_allocation.rs @@ -1,17 +1,17 @@ -use cty::{c_char, c_void}; -// Doc: https://microsoft.github.io/mimalloc/group__malloc.html -extern "C" { - pub fn mi_calloc(count: usize, size: usize) -> *mut c_void; - pub fn mi_expand(p: *mut c_void, size: usize) -> *mut c_void; - pub fn mi_free(p: *mut c_void); - pub fn mi_malloc(size: usize) -> *mut c_void; - pub fn mi_mallocn(count: usize, size: usize) -> *mut c_void; - pub fn mi_realloc(p: *mut c_void, newsize: usize) -> *mut c_void; - pub fn mi_reallocf(p: *mut c_void, newsize: usize) -> *mut c_void; - pub fn mi_reallocn(p: *mut c_void, count: usize, size: usize) -> *mut c_void; - pub fn mi_realpath(fname: *const c_char, resolved_name: *mut c_char) -> *mut c_char; - pub fn mi_recalloc(p: *mut c_void, newcount: usize, size: usize) -> *mut c_void; - pub fn mi_strdup(s: *const c_char) -> *mut c_char; - pub fn mi_strndup(s: *const c_char, n: usize) -> *mut c_char; - pub fn mi_zalloc(size: usize) -> *mut c_void; -} +use cty::{c_char, c_void}; +// Doc: https://microsoft.github.io/mimalloc/group__malloc.html +extern "C" { + pub fn mi_calloc(count: usize, size: usize) -> *mut c_void; + pub fn mi_expand(p: *mut c_void, size: usize) -> *mut c_void; + pub fn mi_free(p: *mut c_void); + pub fn mi_malloc(size: usize) -> *mut c_void; + pub fn mi_mallocn(count: usize, size: usize) -> *mut c_void; + pub fn mi_realloc(p: *mut c_void, newsize: usize) -> *mut c_void; + pub fn mi_reallocf(p: *mut c_void, newsize: usize) -> *mut c_void; + pub fn mi_reallocn(p: *mut c_void, count: usize, size: usize) -> *mut c_void; + pub fn mi_realpath(fname: *const c_char, resolved_name: *mut c_char) -> *mut c_char; + pub fn mi_recalloc(p: *mut c_void, newcount: usize, size: usize) -> *mut c_void; + pub fn mi_strdup(s: *const c_char) -> *mut c_char; + pub fn mi_strndup(s: *const c_char, n: usize) -> *mut c_char; + pub fn mi_zalloc(size: usize) -> *mut c_void; +} diff --git a/mimalloc-sys/src/extended_functions.rs b/mimalloc-rust-sys/src/extended_functions.rs similarity index 97% rename from mimalloc-sys/src/extended_functions.rs rename to mimalloc-rust-sys/src/extended_functions.rs index 145769f..eec7fc8 100644 --- a/mimalloc-sys/src/extended_functions.rs +++ b/mimalloc-rust-sys/src/extended_functions.rs @@ -1,45 +1,45 @@ -use cty::{c_char, c_int, c_ulonglong, c_void}; -// Doc: https://microsoft.github.io/mimalloc/group__malloc.html -pub const MI_SMALL_SIZE_MAX: usize = 128 * core::mem::size_of::<*mut c_void>(); -pub type mi_deferred_free_fun = - Option; -pub type mi_output_fun = Option; -pub type mi_error_fun = Option; -extern "C" { - pub fn mi_collect(force: bool); - pub fn mi_good_size(size: usize) -> usize; - pub fn mi_is_in_heap_region(p: *const c_void) -> bool; - pub fn mi_malloc_small(size: usize) -> *mut c_void; - pub fn mi_process_info( - elapsed_msecs: *mut usize, - user_msecs: *mut usize, - system_msecs: *mut usize, - current_rss: *mut usize, - peak_rss: *mut usize, - current_commit: *mut usize, - peak_commit: *mut usize, - page_faults: *mut usize, - ); - pub fn mi_register_deferred_free(out: mi_deferred_free_fun, arg: *mut c_void); - pub fn mi_register_error(out: mi_error_fun, arg: *mut c_void); - pub fn mi_register_output(out: mi_output_fun, arg: *mut c_void); - pub fn mi_reserve_huge_os_pages_at( - pages: usize, - numa_node: c_int, - timeout_msecs: usize, - ) -> c_int; - pub fn mi_reserve_huge_os_pages_interleave( - pages: usize, - numa_node: c_int, - timeout_msecs: usize, - ) -> c_int; - pub fn mi_stats_print(_: *mut c_void); - pub fn mi_stats_print_out(out: mi_output_fun, arg: *mut c_void); - pub fn mi_stats_reset(); - pub fn mi_stats_merge(); - pub fn mi_thread_init(); - pub fn mi_thread_done(); - pub fn mi_thread_stats_print_out(out: mi_output_fun, arg: *mut c_void); - pub fn mi_usable_size(p: *const c_void) -> usize; - pub fn mi_zalloc_small(size: usize) -> *mut c_void; -} +use cty::{c_char, c_int, c_ulonglong, c_void}; +// Doc: https://microsoft.github.io/mimalloc/group__malloc.html +pub const MI_SMALL_SIZE_MAX: usize = 128 * core::mem::size_of::<*mut c_void>(); +pub type mi_deferred_free_fun = + Option; +pub type mi_output_fun = Option; +pub type mi_error_fun = Option; +extern "C" { + pub fn mi_collect(force: bool); + pub fn mi_good_size(size: usize) -> usize; + pub fn mi_is_in_heap_region(p: *const c_void) -> bool; + pub fn mi_malloc_small(size: usize) -> *mut c_void; + pub fn mi_process_info( + elapsed_msecs: *mut usize, + user_msecs: *mut usize, + system_msecs: *mut usize, + current_rss: *mut usize, + peak_rss: *mut usize, + current_commit: *mut usize, + peak_commit: *mut usize, + page_faults: *mut usize, + ); + pub fn mi_register_deferred_free(out: mi_deferred_free_fun, arg: *mut c_void); + pub fn mi_register_error(out: mi_error_fun, arg: *mut c_void); + pub fn mi_register_output(out: mi_output_fun, arg: *mut c_void); + pub fn mi_reserve_huge_os_pages_at( + pages: usize, + numa_node: c_int, + timeout_msecs: usize, + ) -> c_int; + pub fn mi_reserve_huge_os_pages_interleave( + pages: usize, + numa_node: c_int, + timeout_msecs: usize, + ) -> c_int; + pub fn mi_stats_print(_: *mut c_void); + pub fn mi_stats_print_out(out: mi_output_fun, arg: *mut c_void); + pub fn mi_stats_reset(); + pub fn mi_stats_merge(); + pub fn mi_thread_init(); + pub fn mi_thread_done(); + pub fn mi_thread_stats_print_out(out: mi_output_fun, arg: *mut c_void); + pub fn mi_usable_size(p: *const c_void) -> usize; + pub fn mi_zalloc_small(size: usize) -> *mut c_void; +} diff --git a/mimalloc-sys/src/heap.rs b/mimalloc-rust-sys/src/heap.rs similarity index 96% rename from mimalloc-sys/src/heap.rs rename to mimalloc-rust-sys/src/heap.rs index cfa054c..25e827e 100644 --- a/mimalloc-sys/src/heap.rs +++ b/mimalloc-rust-sys/src/heap.rs @@ -1,155 +1,155 @@ -use cty::{c_char, c_void}; - -use crate::types::mi_heap_t; - -// Doc: https://microsoft.github.io/mimalloc/group__heap.html - -#[repr(C)] -#[derive(Debug, Clone, Copy)] -pub struct mi_heap_area_t { - pub blocks: *mut c_void, - pub reserved: usize, - pub committed: usize, - pub used: usize, - pub block_size: usize, -} - -pub type mi_block_visit_fun = Option< - unsafe extern "C" fn( - heap: *const mi_heap_t, - area: *const mi_heap_area_t, - block: *mut c_void, - block_size: usize, - arg: *mut c_void, - ) -> bool, ->; - -extern "C" { - pub fn mi_heap_new() -> *mut mi_heap_t; - pub fn mi_heap_delete(heap: *mut mi_heap_t); - pub fn mi_heap_destroy(heap: *mut mi_heap_t); - pub fn mi_heap_set_default(heap: *mut mi_heap_t) -> *mut mi_heap_t; - pub fn mi_heap_get_default() -> *mut mi_heap_t; - pub fn mi_heap_get_backing() -> *mut mi_heap_t; - pub fn mi_heap_collect(heap: *mut mi_heap_t, force: bool); - pub fn mi_heap_malloc(heap: *mut mi_heap_t, size: usize) -> *mut c_void; - pub fn mi_heap_malloc_small(heap: *mut mi_heap_t, size: usize) -> *mut c_void; - pub fn mi_heap_zalloc(heap: *mut mi_heap_t, size: usize) -> *mut c_void; - pub fn mi_heap_calloc(heap: *mut mi_heap_t, count: usize, size: usize) -> *mut c_void; - pub fn mi_heap_mallocn(heap: *mut mi_heap_t, count: usize, size: usize) -> *mut c_void; - pub fn mi_heap_strdup(heap: *mut mi_heap_t, s: *const c_char) -> *mut c_char; - pub fn mi_heap_strndup(heap: *mut mi_heap_t, s: *const c_char, n: usize) -> *mut c_char; - pub fn mi_heap_realpath( - heap: *mut mi_heap_t, - fname: *const c_char, - resolved_name: *mut c_char, - ) -> *mut c_char; - pub fn mi_heap_realloc(heap: *mut mi_heap_t, p: *mut c_void, newsize: usize) -> *mut c_void; - pub fn mi_heap_reallocn( - heap: *mut mi_heap_t, - p: *mut c_void, - count: usize, - size: usize, - ) -> *mut c_void; - pub fn mi_heap_reallocf(heap: *mut mi_heap_t, p: *mut c_void, newsize: usize) -> *mut c_void; - pub fn mi_heap_malloc_aligned( - heap: *mut mi_heap_t, - size: usize, - alignment: usize, - ) -> *mut c_void; - pub fn mi_heap_malloc_aligned_at( - heap: *mut mi_heap_t, - size: usize, - alignment: usize, - offset: usize, - ) -> *mut c_void; - pub fn mi_heap_zalloc_aligned( - heap: *mut mi_heap_t, - size: usize, - alignment: usize, - ) -> *mut c_void; - pub fn mi_heap_zalloc_aligned_at( - heap: *mut mi_heap_t, - size: usize, - alignment: usize, - offset: usize, - ) -> *mut c_void; - pub fn mi_heap_calloc_aligned( - heap: *mut mi_heap_t, - count: usize, - size: usize, - alignment: usize, - ) -> *mut c_void; - pub fn mi_heap_calloc_aligned_at( - heap: *mut mi_heap_t, - count: usize, - size: usize, - alignment: usize, - offset: usize, - ) -> *mut c_void; - pub fn mi_heap_realloc_aligned( - heap: *mut mi_heap_t, - p: *mut c_void, - newsize: usize, - alignment: usize, - ) -> *mut c_void; - pub fn mi_heap_realloc_aligned_at( - heap: *mut mi_heap_t, - p: *mut c_void, - newsize: usize, - alignment: usize, - offset: usize, - ) -> *mut c_void; - - // Zero initialized re-allocation - // Doc: https://microsoft.github.io/mimalloc/group__zeroinit.html - - pub fn mi_heap_rezalloc(heap: *mut mi_heap_t, p: *mut c_void, newsize: usize) -> *mut c_void; - pub fn mi_heap_recalloc( - heap: *mut mi_heap_t, - p: *mut c_void, - newcount: usize, - size: usize, - ) -> *mut c_void; - pub fn mi_heap_rezalloc_aligned( - heap: *mut mi_heap_t, - p: *mut c_void, - newsize: usize, - alignment: usize, - ) -> *mut c_void; - pub fn mi_heap_rezalloc_aligned_at( - heap: *mut mi_heap_t, - p: *mut c_void, - newsize: usize, - alignment: usize, - offset: usize, - ) -> *mut c_void; - pub fn mi_heap_recalloc_aligned( - heap: *mut mi_heap_t, - p: *mut c_void, - newcount: usize, - size: usize, - alignment: usize, - ) -> *mut c_void; - pub fn mi_heap_recalloc_aligned_at( - heap: *mut mi_heap_t, - p: *mut c_void, - newcount: usize, - size: usize, - alignment: usize, - offset: usize, - ) -> *mut c_void; - - // Heap Introspection - // Doc: https://microsoft.github.io/mimalloc/group__analysis.html - - pub fn mi_heap_contains_block(heap: *mut mi_heap_t, p: *const c_void) -> bool; - pub fn mi_heap_check_owned(heap: *mut mi_heap_t, p: *const c_void) -> bool; - pub fn mi_check_owned(p: *const c_void) -> bool; - pub fn mi_heap_visit_blocks( - heap: *const mi_heap_t, - visit_all_blocks: bool, - visitor: mi_block_visit_fun, - arg: *mut c_void, - ) -> bool; -} +use cty::{c_char, c_void}; + +use crate::types::mi_heap_t; + +// Doc: https://microsoft.github.io/mimalloc/group__heap.html + +#[repr(C)] +#[derive(Debug, Clone, Copy)] +pub struct mi_heap_area_t { + pub blocks: *mut c_void, + pub reserved: usize, + pub committed: usize, + pub used: usize, + pub block_size: usize, +} + +pub type mi_block_visit_fun = Option< + unsafe extern "C" fn( + heap: *const mi_heap_t, + area: *const mi_heap_area_t, + block: *mut c_void, + block_size: usize, + arg: *mut c_void, + ) -> bool, +>; + +extern "C" { + pub fn mi_heap_new() -> *mut mi_heap_t; + pub fn mi_heap_delete(heap: *mut mi_heap_t); + pub fn mi_heap_destroy(heap: *mut mi_heap_t); + pub fn mi_heap_set_default(heap: *mut mi_heap_t) -> *mut mi_heap_t; + pub fn mi_heap_get_default() -> *mut mi_heap_t; + pub fn mi_heap_get_backing() -> *mut mi_heap_t; + pub fn mi_heap_collect(heap: *mut mi_heap_t, force: bool); + pub fn mi_heap_malloc(heap: *mut mi_heap_t, size: usize) -> *mut c_void; + pub fn mi_heap_malloc_small(heap: *mut mi_heap_t, size: usize) -> *mut c_void; + pub fn mi_heap_zalloc(heap: *mut mi_heap_t, size: usize) -> *mut c_void; + pub fn mi_heap_calloc(heap: *mut mi_heap_t, count: usize, size: usize) -> *mut c_void; + pub fn mi_heap_mallocn(heap: *mut mi_heap_t, count: usize, size: usize) -> *mut c_void; + pub fn mi_heap_strdup(heap: *mut mi_heap_t, s: *const c_char) -> *mut c_char; + pub fn mi_heap_strndup(heap: *mut mi_heap_t, s: *const c_char, n: usize) -> *mut c_char; + pub fn mi_heap_realpath( + heap: *mut mi_heap_t, + fname: *const c_char, + resolved_name: *mut c_char, + ) -> *mut c_char; + pub fn mi_heap_realloc(heap: *mut mi_heap_t, p: *mut c_void, newsize: usize) -> *mut c_void; + pub fn mi_heap_reallocn( + heap: *mut mi_heap_t, + p: *mut c_void, + count: usize, + size: usize, + ) -> *mut c_void; + pub fn mi_heap_reallocf(heap: *mut mi_heap_t, p: *mut c_void, newsize: usize) -> *mut c_void; + pub fn mi_heap_malloc_aligned( + heap: *mut mi_heap_t, + size: usize, + alignment: usize, + ) -> *mut c_void; + pub fn mi_heap_malloc_aligned_at( + heap: *mut mi_heap_t, + size: usize, + alignment: usize, + offset: usize, + ) -> *mut c_void; + pub fn mi_heap_zalloc_aligned( + heap: *mut mi_heap_t, + size: usize, + alignment: usize, + ) -> *mut c_void; + pub fn mi_heap_zalloc_aligned_at( + heap: *mut mi_heap_t, + size: usize, + alignment: usize, + offset: usize, + ) -> *mut c_void; + pub fn mi_heap_calloc_aligned( + heap: *mut mi_heap_t, + count: usize, + size: usize, + alignment: usize, + ) -> *mut c_void; + pub fn mi_heap_calloc_aligned_at( + heap: *mut mi_heap_t, + count: usize, + size: usize, + alignment: usize, + offset: usize, + ) -> *mut c_void; + pub fn mi_heap_realloc_aligned( + heap: *mut mi_heap_t, + p: *mut c_void, + newsize: usize, + alignment: usize, + ) -> *mut c_void; + pub fn mi_heap_realloc_aligned_at( + heap: *mut mi_heap_t, + p: *mut c_void, + newsize: usize, + alignment: usize, + offset: usize, + ) -> *mut c_void; + + // Zero initialized re-allocation + // Doc: https://microsoft.github.io/mimalloc/group__zeroinit.html + + pub fn mi_heap_rezalloc(heap: *mut mi_heap_t, p: *mut c_void, newsize: usize) -> *mut c_void; + pub fn mi_heap_recalloc( + heap: *mut mi_heap_t, + p: *mut c_void, + newcount: usize, + size: usize, + ) -> *mut c_void; + pub fn mi_heap_rezalloc_aligned( + heap: *mut mi_heap_t, + p: *mut c_void, + newsize: usize, + alignment: usize, + ) -> *mut c_void; + pub fn mi_heap_rezalloc_aligned_at( + heap: *mut mi_heap_t, + p: *mut c_void, + newsize: usize, + alignment: usize, + offset: usize, + ) -> *mut c_void; + pub fn mi_heap_recalloc_aligned( + heap: *mut mi_heap_t, + p: *mut c_void, + newcount: usize, + size: usize, + alignment: usize, + ) -> *mut c_void; + pub fn mi_heap_recalloc_aligned_at( + heap: *mut mi_heap_t, + p: *mut c_void, + newcount: usize, + size: usize, + alignment: usize, + offset: usize, + ) -> *mut c_void; + + // Heap Introspection + // Doc: https://microsoft.github.io/mimalloc/group__analysis.html + + pub fn mi_heap_contains_block(heap: *mut mi_heap_t, p: *const c_void) -> bool; + pub fn mi_heap_check_owned(heap: *mut mi_heap_t, p: *const c_void) -> bool; + pub fn mi_check_owned(p: *const c_void) -> bool; + pub fn mi_heap_visit_blocks( + heap: *const mi_heap_t, + visit_all_blocks: bool, + visitor: mi_block_visit_fun, + arg: *mut c_void, + ) -> bool; +} diff --git a/mimalloc-rust-sys/src/lib.rs b/mimalloc-rust-sys/src/lib.rs new file mode 100644 index 0000000..65c07fb --- /dev/null +++ b/mimalloc-rust-sys/src/lib.rs @@ -0,0 +1,21 @@ +//! # mi-malloc +//! [documentation](https**://microsoft.github.io/mimalloc/index.html) +//! - **small and consistent**: the library is about 8k LOC using simple and consistent data structures. This makes it very suitable to integrate and adapt in other projects. For runtime systems it provides hooks for a monotonic heartbeat and deferred freeing (for bounded worst-case times with reference counting). +//! - **free list sharding**: instead of one big free list (per size class) we have many smaller lists per "mimalloc page" which reduces fragmentation and increases locality – things that are allocated close in time get allocated close in memory. (A mimalloc page contains blocks of one size class and is usually 64KiB on a 64-bit system). +//! - **free list multi-sharding**: the big idea! Not only do we shard the free list per mimalloc page, but for each page we have multiple free lists. In particular, there is one list for thread-local free operations, and another one for concurrent free operations. Free-ing from another thread can now be a single CAS without needing sophisticated coordination between threads. Since there will be thousands of separate free lists, contention is naturally distributed over the heap, and the chance of contending on a single location will be low – this is quite similar to randomized algorithms like skip lists where adding a random oracle removes the need for a more complex algorithm. +//! - **eager page reset**: when a "page" becomes empty (with increased chance due to free list sharding) the memory is marked to the OS as unused ("reset" or "purged") reducing (real) memory pressure and fragmentation, especially in long running programs. +//! - **secure**: mimalloc can be build in secure mode, adding guard pages, randomized allocation, encrypted free lists, etc. to protect against various heap vulnerabilities. The performance penalty is only around 3% on average over our benchmarks. +//! - **first-class heaps**: efficiently create and use multiple heaps to allocate across different regions. A heap can be destroyed at once instead of deallocating each object separately. +//! - **bounded**: it does not suffer from blowup, has bounded worst-case allocation times (wcat), bounded space overhead (~0.2% meta-data, with at most 12.5% waste in allocation sizes), and has no internal points of contention using only atomic operations. +//! - **fast**: In our benchmarks (see below), mimalloc outperforms all other leading allocators (jemalloc, tcmalloc, Hoard, etc), and usually uses less memory (up to 25% more in the worst case). A nice property is that it does consistently well over a wide range of benchmarks. + +#![no_std] +#![allow(nonstandard_style)] + +pub mod aligned_allocation; +pub mod basic_allocation; +pub mod extended_functions; +pub mod heap; +pub mod runtime_options; +pub mod types; +pub mod utils; diff --git a/mimalloc-sys/src/posix.rs b/mimalloc-rust-sys/src/posix.rs similarity index 50% rename from mimalloc-sys/src/posix.rs rename to mimalloc-rust-sys/src/posix.rs index d3f5a12..8b13789 100644 --- a/mimalloc-sys/src/posix.rs +++ b/mimalloc-rust-sys/src/posix.rs @@ -1 +1 @@ - + diff --git a/mimalloc-sys/src/runtime_options.rs b/mimalloc-rust-sys/src/runtime_options.rs similarity index 97% rename from mimalloc-sys/src/runtime_options.rs rename to mimalloc-rust-sys/src/runtime_options.rs index e82b4bb..5d66cff 100644 --- a/mimalloc-sys/src/runtime_options.rs +++ b/mimalloc-rust-sys/src/runtime_options.rs @@ -1,37 +1,37 @@ -use cty::{c_int, c_long}; - -pub type mi_option_t = c_int; - -pub const mi_option_show_errors: mi_option_t = 0; -pub const mi_option_show_stats: mi_option_t = 1; -pub const mi_option_verbose: mi_option_t = 2; -// the following options are experimental -pub const mi_option_eager_commit: mi_option_t = 3; -pub const mi_option_eager_region_commit: mi_option_t = 4; -pub const mi_option_reset_decommits: mi_option_t = 5; -// implies eager commit -pub const mi_option_large_os_pages: mi_option_t = 6; -pub const mi_option_reserve_huge_os_pages: mi_option_t = 7; -pub const mi_option_reserve_os_memory: mi_option_t = 8; -pub const mi_option_segment_cache: mi_option_t = 9; -pub const mi_option_page_reset: mi_option_t = 10; -pub const mi_option_abandoned_page_reset: mi_option_t = 11; -pub const mi_option_segment_reset: mi_option_t = 12; -pub const mi_option_eager_commit_delay: mi_option_t = 13; -pub const mi_option_reset_delay: mi_option_t = 14; -pub const mi_option_use_numa_nodes: mi_option_t = 15; -pub const mi_option_limit_os_alloc: mi_option_t = 16; -pub const mi_option_os_tag: mi_option_t = 17; -pub const mi_option_max_errors: mi_option_t = 18; -pub const mi_option_max_warnings: mi_option_t = 19; - -extern "C" { - pub fn mi_option_disable(option: mi_option_t); - pub fn mi_option_enable(option: mi_option_t); - pub fn mi_option_get(option: mi_option_t) -> c_long; - pub fn mi_option_is_enabled(option: mi_option_t) -> bool; - pub fn mi_option_set(option: mi_option_t, value: c_long); - pub fn mi_option_set_default(option: mi_option_t, value: c_long); - pub fn mi_option_set_enabled(option: mi_option_t); - pub fn mi_option_set_enabled_default(option: mi_option_t); -} +use cty::{c_int, c_long}; + +pub type mi_option_t = c_int; + +pub const mi_option_show_errors: mi_option_t = 0; +pub const mi_option_show_stats: mi_option_t = 1; +pub const mi_option_verbose: mi_option_t = 2; +// the following options are experimental +pub const mi_option_eager_commit: mi_option_t = 3; +pub const mi_option_eager_region_commit: mi_option_t = 4; +pub const mi_option_reset_decommits: mi_option_t = 5; +// implies eager commit +pub const mi_option_large_os_pages: mi_option_t = 6; +pub const mi_option_reserve_huge_os_pages: mi_option_t = 7; +pub const mi_option_reserve_os_memory: mi_option_t = 8; +pub const mi_option_segment_cache: mi_option_t = 9; +pub const mi_option_page_reset: mi_option_t = 10; +pub const mi_option_abandoned_page_reset: mi_option_t = 11; +pub const mi_option_segment_reset: mi_option_t = 12; +pub const mi_option_eager_commit_delay: mi_option_t = 13; +pub const mi_option_reset_delay: mi_option_t = 14; +pub const mi_option_use_numa_nodes: mi_option_t = 15; +pub const mi_option_limit_os_alloc: mi_option_t = 16; +pub const mi_option_os_tag: mi_option_t = 17; +pub const mi_option_max_errors: mi_option_t = 18; +pub const mi_option_max_warnings: mi_option_t = 19; + +extern "C" { + pub fn mi_option_disable(option: mi_option_t); + pub fn mi_option_enable(option: mi_option_t); + pub fn mi_option_get(option: mi_option_t) -> c_long; + pub fn mi_option_is_enabled(option: mi_option_t) -> bool; + pub fn mi_option_set(option: mi_option_t, value: c_long); + pub fn mi_option_set_default(option: mi_option_t, value: c_long); + pub fn mi_option_set_enabled(option: mi_option_t); + pub fn mi_option_set_enabled_default(option: mi_option_t); +} diff --git a/mimalloc-sys/src/types.rs b/mimalloc-rust-sys/src/types.rs similarity index 100% rename from mimalloc-sys/src/types.rs rename to mimalloc-rust-sys/src/types.rs diff --git a/mimalloc-sys/src/utils.rs b/mimalloc-rust-sys/src/utils.rs similarity index 100% rename from mimalloc-sys/src/utils.rs rename to mimalloc-rust-sys/src/utils.rs diff --git a/mimalloc-sys/src/lib.rs b/mimalloc-sys/src/lib.rs deleted file mode 100644 index 13d4683..0000000 --- a/mimalloc-sys/src/lib.rs +++ /dev/null @@ -1,10 +0,0 @@ -#![no_std] -#![allow(nonstandard_style)] - -pub mod aligned_allocation; -pub mod basic_allocation; -pub mod extended_functions; -pub mod heap; -pub mod runtime_options; -pub mod types; -pub mod utils; diff --git a/src/heap.rs b/src/heap.rs index 1c0b7a1..a41ced3 100644 --- a/src/heap.rs +++ b/src/heap.rs @@ -1,15 +1,35 @@ +//! First-class heaps that can be destroyed in one go. +//! +//! [furthur documentation](https://microsoft.github.io/mimalloc/group__heap.html#details) +use crate::raw::{basic_allocation::mi_free, heap::*, types::mi_heap_t}; use core::{ alloc::*, ffi::c_void, + fmt::Debug, ops::Deref, ptr::{slice_from_raw_parts_mut, NonNull}, }; -use mimalloc_sys::{basic_allocation::mi_free, heap::*, types::mi_heap_t}; +/// Heap type used for allocator API pub struct MiMallocHeap> { pub heap: T, } +impl> MiMallocHeap { + pub fn new(heap: T) -> Self { + Self { heap } + } +} + +impl Debug for MiMallocHeap +where + T: Deref + Debug, +{ + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.write_fmt(format_args!("{:?}", self.heap)) + } +} + impl> From for MiMallocHeap { fn from(heap: T) -> Self { Self { heap } @@ -136,6 +156,7 @@ unsafe impl> Allocator for MiMallocHeap { } } +/// A custom function which visits the Heap pub trait HeapVisitor> where Self: Sized, @@ -159,6 +180,8 @@ where } } } + +/// the default Global Heap Type #[derive(Debug, PartialEq, Eq)] pub struct GlobalHeap { pub heap: *mut mi_heap_t, @@ -171,7 +194,7 @@ impl Deref for GlobalHeap { &self.heap } } - +/// the default Global Heap Type Alias pub type MiMallocHeapGlobal = MiMallocHeap; unsafe extern "C" fn visit_handler< @@ -189,6 +212,7 @@ unsafe extern "C" fn visit_handler< Visitor::visitor(visitor, &*heap, &*area, block, size) } +/// a macro which could only be used in single thread condition #[macro_export] macro_rules! with_heap { ($heap: ty, $do: expr) => {{ diff --git a/src/lib.rs b/src/lib.rs index 3b1bc73..468ab58 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,16 +1,82 @@ #![feature(allocator_api)] #![cfg_attr(not(test), no_std)] +//! this crate provides the best binding for [mimalloc](https://github.com/microsoft/mimalloc) +//! # Example Usage +//! first add to dependencies +//! ```toml +//! [dependencies] +//! mimalloc-rust = "0.1" +//! ``` +//! then set the global allocator +//! ```rust +//! use mimalloc_rust::*; +//! +//! #[global_allocator] +//! static GLOBAL_MIMALLOC: GlobalMiMalloc = GlobalMiMalloc; +//! ``` +//! # Allocator API! +//! ``` +//! #![feature(allocator_api)] +//! use std::{ffi::c_void, mem::ManuallyDrop}; +//! +//! use crate::{ +//! heap::{HeapVisitor, MiMallocHeap}, +//! raw::{ +//! heap::{mi_heap_area_t, mi_heap_delete, mi_heap_new}, +//! types::mi_heap_t, +//! }, +//! with_heap, GlobalMiMalloc, +//! }; +//! +//! #[derive(Debug, Clone)] +//! struct TestHeap { +//! heap: *mut mi_heap_t, +//! } +//! use std::ops::Deref; +//! impl Deref for TestHeap { +//! type Target = *mut mi_heap_t; +//! +//! fn deref(&self) -> &Self::Target { +//! &self.heap +//! } +//! } +//! +//! impl TestHeap { +//! fn new() -> Self { +//! Self { +//! heap: unsafe { mi_heap_new() }, +//! } +//! } +//! } +//! +//! impl Drop for TestHeap { +//! fn drop(&mut self) { +//! unsafe { mi_heap_delete(self.heap) } +//! } +//! } +//! +//! #[test] +//! fn test_allocator_api() { +//! let allocator = MiMallocHeap::new(TestHeap::new()); +//! let mut b: Vec> = Vec::new_in(&allocator); +//! b.push(1); +//! b.push(2); +//! assert_eq!(b[0], 1); +//! assert_eq!(b[1], 2); +//! } +//! +//! ``` + #[cfg(test)] -mod test; +mod tests; pub mod heap; use cty::c_long; -use heap::GlobalHeap; -use heap::MiMallocHeap; -use heap::MiMallocHeapGlobal; -pub use mimalloc_sys as sys; -use sys::types::mi_heap_t; +use heap::*; +// the hand writed native binding +pub use mimalloc_rust_sys as raw; +use raw::types::mi_heap_t; use core::{ alloc::{GlobalAlloc, Layout}, @@ -19,8 +85,8 @@ use core::{ ops::Deref, }; -use mimalloc_sys::{aligned_allocation::*, basic_allocation::*, heap::*, runtime_options::*}; - +use crate::raw::{aligned_allocation::*, basic_allocation::*, heap::*, runtime_options::*}; +/// The global allocator pub struct GlobalMiMalloc; impl Debug for GlobalMiMalloc { @@ -31,6 +97,7 @@ impl Debug for GlobalMiMalloc { } } impl GlobalMiMalloc { + /// replace the global allocator by a heap pub fn replace_by>( heap: &MiMallocHeap, ) -> MiMallocHeapGlobal { @@ -40,8 +107,7 @@ impl GlobalMiMalloc { }, } } -} -impl GlobalMiMalloc { + /// get the default heap type of the global allocator holds pub fn get() -> MiMallocHeapGlobal { MiMallocHeap { heap: GlobalHeap { diff --git a/src/test.rs b/src/tests/heap.rs similarity index 75% rename from src/test.rs rename to src/tests/heap.rs index 11c1b63..d2938cf 100644 --- a/src/test.rs +++ b/src/tests/heap.rs @@ -1,91 +1,89 @@ -use std::{ffi::c_void, mem::ManuallyDrop, println}; - -use mimalloc_sys::{ - heap::{mi_heap_area_t, mi_heap_delete}, - runtime_options::mi_option_show_stats, - types::mi_heap_t, -}; - -use crate::{ - heap::{HeapVisitor, MiMallocHeap}, - sys::heap::mi_heap_new, - with_heap, GlobalMiMalloc, -}; - -#[global_allocator] -static GLOBAL_MIMALLOC: GlobalMiMalloc = GlobalMiMalloc; - -#[test] -fn test_malloc() { - GlobalMiMalloc::option_enable(mi_option_show_stats); - let _vec: Vec = vec![0; 114514]; - println!("mimalloc: \n{:?}", GLOBAL_MIMALLOC); -} - -struct TestHeap { - heap: *mut mi_heap_t, -} -use std::ops::Deref; -impl Deref for TestHeap { - type Target = *mut mi_heap_t; - - fn deref(&self) -> &Self::Target { - &self.heap - } -} - -impl TestHeap { - fn new() -> Self { - Self { - heap: unsafe { mi_heap_new() }, - } - } -} - -impl Drop for TestHeap { - fn drop(&mut self) { - unsafe { mi_heap_delete(self.heap) } - } -} - -#[derive(Default, Debug)] -struct LeakDetector { - in_used: usize, - in_used_size: usize, -} - -impl Drop for LeakDetector { - fn drop(&mut self) { - if self.in_used != 0 && self.in_used_size != 0 { - panic!("Memory Leaks with information {:?}", self); - } - } -} -enum General {} -impl HeapVisitor for LeakDetector { - fn visitor( - &mut self, - _heap: &mi_heap_t, - area: &mi_heap_area_t, - _block: *mut c_void, - _size: usize, - ) -> bool { - // println!("{:?}", area); - // println!("{:?}", size); - self.in_used += area.used; - self.in_used_size += area.committed - area.used; - true - } -} - -#[test] -#[should_panic] -fn test_leak_detector() { - let (_res, heap) = with_heap!(TestHeap, unsafe { - let mut b: ManuallyDrop> = ManuallyDrop::new(vec![0; 114514]); - let mut _leak1: ManuallyDrop> = ManuallyDrop::new(vec![0; 114514]); - let mut _leak2: ManuallyDrop> = ManuallyDrop::new(vec![0; 1]); - ManuallyDrop::drop(&mut b); - }); - LeakDetector::default().visit(&heap); -} +use std::{ffi::c_void, mem::ManuallyDrop}; + +use crate::{ + heap::{HeapVisitor, MiMallocHeap}, + raw::{ + heap::{mi_heap_area_t, mi_heap_delete, mi_heap_new}, + types::mi_heap_t, + }, + with_heap, GlobalMiMalloc, +}; + +#[derive(Debug, Clone)] +struct TestHeap { + heap: *mut mi_heap_t, +} +use std::ops::Deref; +impl Deref for TestHeap { + type Target = *mut mi_heap_t; + + fn deref(&self) -> &Self::Target { + &self.heap + } +} + +impl TestHeap { + fn new() -> Self { + Self { + heap: unsafe { mi_heap_new() }, + } + } +} + +impl Drop for TestHeap { + fn drop(&mut self) { + unsafe { mi_heap_delete(self.heap) } + } +} + +#[derive(Default, Debug)] +struct LeakDetector { + in_used: usize, + in_used_size: usize, +} + +impl Drop for LeakDetector { + fn drop(&mut self) { + if self.in_used != 0 && self.in_used_size != 0 { + panic!("Memory Leaks with information {:?}", self); + } + } +} +enum General {} +impl HeapVisitor for LeakDetector { + fn visitor( + &mut self, + _heap: &mi_heap_t, + area: &mi_heap_area_t, + _block: *mut c_void, + _size: usize, + ) -> bool { + // println!("{:?}", area); + // println!("{:?}", size); + self.in_used += area.used; + self.in_used_size += area.committed - area.used; + true + } +} + +#[test] +fn test_allocator_api() { + let allocator = MiMallocHeap::new(TestHeap::new()); + let mut b: Vec> = Vec::new_in(&allocator); + b.push(1); + b.push(2); + assert_eq!(b[0], 1); + assert_eq!(b[1], 2); +} + +#[test] +#[should_panic] +fn test_leak_detector() { + let (_res, heap) = with_heap!(TestHeap, unsafe { + let mut b: ManuallyDrop> = ManuallyDrop::new(vec![0; 114514]); + let mut _leak1: ManuallyDrop> = ManuallyDrop::new(vec![0; 114514]); + let mut _leak2: ManuallyDrop> = ManuallyDrop::new(vec![0; 1]); + ManuallyDrop::drop(&mut b); + }); + LeakDetector::default().visit(&heap); +} diff --git a/src/tests/mod.rs b/src/tests/mod.rs new file mode 100644 index 0000000..4df0dad --- /dev/null +++ b/src/tests/mod.rs @@ -0,0 +1,24 @@ +mod heap; +use std::{ffi::c_void, mem::ManuallyDrop, println}; + +use crate::raw::{ + heap::{mi_heap_area_t, mi_heap_delete}, + runtime_options::mi_option_show_stats, + types::mi_heap_t, +}; + +use crate::{ + heap::{HeapVisitor, MiMallocHeap}, + raw::heap::mi_heap_new, + with_heap, GlobalMiMalloc, +}; + +#[global_allocator] +static GLOBAL_MIMALLOC: GlobalMiMalloc = GlobalMiMalloc; + +#[test] +fn test_malloc() { + GlobalMiMalloc::option_enable(mi_option_show_stats); + let _vec: Vec = vec![0; 114514]; + println!("mimalloc: \n{:?}", GLOBAL_MIMALLOC); +}