vlib: add a dlmalloc module (#12974)
parent
a60b381d5e
commit
70a0aab72b
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,116 @@
|
||||||
|
module dlmalloc
|
||||||
|
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
fn C.munmap(ptr voidptr, size usize) int
|
||||||
|
fn C.mremap(ptr voidptr, old usize, new usize, flags usize) voidptr
|
||||||
|
fn C.mmap(base voidptr, len usize, prot int, flags int, fd int, offset i64) voidptr
|
||||||
|
|
||||||
|
pub enum Mm_prot {
|
||||||
|
prot_read = 0x1
|
||||||
|
prot_write = 0x2
|
||||||
|
prot_exec = 0x4
|
||||||
|
prot_none = 0x0
|
||||||
|
prot_growsdown = 0x01000000
|
||||||
|
prot_growsup = 0x02000000
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum Map_flags {
|
||||||
|
map_shared = 0x01
|
||||||
|
map_private = 0x02
|
||||||
|
map_shared_validate = 0x03
|
||||||
|
map_type = 0x0f
|
||||||
|
map_fixed = 0x10
|
||||||
|
map_file = 0x00
|
||||||
|
map_anonymous = 0x20
|
||||||
|
map_huge_shift = 26
|
||||||
|
map_huge_mask = 0x3f
|
||||||
|
}
|
||||||
|
|
||||||
|
enum MemProt {
|
||||||
|
prot_read = 0x1
|
||||||
|
prot_write = 0x2
|
||||||
|
prot_exec = 0x4
|
||||||
|
prot_none = 0x0
|
||||||
|
prot_growsdown = 0x01000000
|
||||||
|
prot_growsup = 0x02000000
|
||||||
|
}
|
||||||
|
|
||||||
|
enum MapFlags {
|
||||||
|
map_shared = 0x01
|
||||||
|
map_private = 0x02
|
||||||
|
map_shared_validate = 0x03
|
||||||
|
map_type = 0x0f
|
||||||
|
map_fixed = 0x10
|
||||||
|
map_file = 0x00
|
||||||
|
map_anonymous = 0x20
|
||||||
|
map_huge_shift = 26
|
||||||
|
map_huge_mask = 0x3f
|
||||||
|
}
|
||||||
|
|
||||||
|
fn system_alloc(_ voidptr, size usize) (voidptr, usize, u32) {
|
||||||
|
unsafe {
|
||||||
|
mem_prot := MemProt(int(MemProt.prot_read) | int(MemProt.prot_write))
|
||||||
|
map_flags := MapFlags(int(MapFlags.map_private) | int(MapFlags.map_anonymous))
|
||||||
|
addr := C.mmap(voidptr(0), size, int(mem_prot), int(map_flags), -1, 0)
|
||||||
|
|
||||||
|
if addr == voidptr(-1) {
|
||||||
|
return voidptr(0), 0, 0
|
||||||
|
} else {
|
||||||
|
return addr, size, 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn system_remap(_ voidptr, ptr voidptr, oldsize usize, newsize usize, can_move bool) voidptr {
|
||||||
|
return voidptr(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn system_free_part(_ voidptr, ptr voidptr, oldsize usize, newsize usize) bool {
|
||||||
|
$if linux {
|
||||||
|
unsafe {
|
||||||
|
rc := C.mremap(ptr, oldsize, newsize, 0)
|
||||||
|
if rc != voidptr(-1) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return C.munmap(voidptr(usize(ptr) + newsize), oldsize - newsize) == 0
|
||||||
|
}
|
||||||
|
} $else $if macos {
|
||||||
|
unsafe {
|
||||||
|
return C.munmap(voidptr(usize(ptr) + newsize), oldsize - newsize) == 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
fn system_free(_ voidptr, ptr voidptr, size usize) bool {
|
||||||
|
unsafe {
|
||||||
|
return C.munmap(ptr, size) == 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn system_can_release_part(_ voidptr, _ u32) bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
fn system_allocates_zeros(_ voidptr) bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
fn system_page_size(_ voidptr) usize {
|
||||||
|
return 4096
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_system_allocator() Allocator {
|
||||||
|
return Allocator{
|
||||||
|
alloc: system_alloc
|
||||||
|
remap: system_remap
|
||||||
|
free_part: system_free_part
|
||||||
|
free_: system_free
|
||||||
|
can_release_part: system_can_release_part
|
||||||
|
allocates_zeros: system_allocates_zeros
|
||||||
|
page_size: system_page_size
|
||||||
|
data: voidptr(0)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
module dlmalloc
|
||||||
|
|
||||||
|
fn system_alloc(_ voidptr, size usize) (voidptr, usize, u32) {
|
||||||
|
return voidptr(0), 0, 0
|
||||||
|
}
|
||||||
|
|
||||||
|
fn system_remap(_ voidptr, ptr voidptr, oldsize usize, newsize usize, can_move bool) voidptr {
|
||||||
|
return voidptr(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn system_free_part(_ voidptr, ptr voidptr, oldsize usize, newsize usize) bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
fn system_free(_ voidptr, ptr voidptr, size usize) bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
fn system_can_release_part(_ voidptr, _ u32) bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
fn system_allocates_zeros(_ voidptr) bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
fn system_page_size(_ voidptr) usize {
|
||||||
|
return 4096
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_system_allocator() Allocator {
|
||||||
|
return Allocator{
|
||||||
|
alloc: system_alloc
|
||||||
|
remap: system_remap
|
||||||
|
free_part: system_free_part
|
||||||
|
free_: system_free
|
||||||
|
can_release_part: system_can_release_part
|
||||||
|
allocates_zeros: system_allocates_zeros
|
||||||
|
page_size: system_page_size
|
||||||
|
data: voidptr(0)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
[has_globals]
|
||||||
|
module dlmalloc
|
||||||
|
|
||||||
|
__global global = new(get_system_allocator())
|
||||||
|
|
||||||
|
/// malloc allocates `size` bytes.
|
||||||
|
///
|
||||||
|
/// Returns a null pointer if allocation fails. Returns a valid pointer
|
||||||
|
/// otherwise.
|
||||||
|
[unsafe]
|
||||||
|
pub fn malloc(size usize) voidptr {
|
||||||
|
unsafe {
|
||||||
|
return global.malloc(size)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// free deallocates a `ptr`.
|
||||||
|
[unsafe]
|
||||||
|
pub fn free(ptr voidptr) {
|
||||||
|
unsafe {
|
||||||
|
global.free_(ptr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Same as `malloc`, except if the allocation succeeds it's guaranteed to
|
||||||
|
// point to `size` bytes of zeros.
|
||||||
|
[unsafe]
|
||||||
|
pub fn calloc(size usize) voidptr {
|
||||||
|
unsafe {
|
||||||
|
return global.calloc(size)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// realloc reallocates `ptr`, a previous allocation with `old_size` and
|
||||||
|
// to have `new_size`.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Returns a null pointer if the memory couldn't be reallocated, but `ptr`
|
||||||
|
// is still valid. Returns a valid pointer and frees `ptr` if the request
|
||||||
|
// is satisfied.
|
||||||
|
[unsafe]
|
||||||
|
pub fn realloc(ptr voidptr, oldsize usize, newsize usize) voidptr {
|
||||||
|
unsafe {
|
||||||
|
_ := oldsize
|
||||||
|
|
||||||
|
return global.realloc(ptr, newsize)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// memalign allocates `size` bytes with `align` align.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Returns a null pointer if allocation fails. Returns a valid pointer otherwise.
|
||||||
|
[unsafe]
|
||||||
|
pub fn memalign(size usize, align usize) voidptr {
|
||||||
|
unsafe {
|
||||||
|
if align <= malloc_alignment {
|
||||||
|
return global.malloc(size)
|
||||||
|
} else {
|
||||||
|
return global.memalign(align, size)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue