vlib: add a dlmalloc module (#12974)

pull/13052/head
playX 2022-01-05 19:17:47 +03:00 committed by GitHub
parent a60b381d5e
commit 70a0aab72b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 1712 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@ -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)
}
}

View File

@ -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)
}
}

View File

@ -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)
}
}
}