Add pvalloc()

This commit is contained in:
Peter Limkilde Svendsen
2025-02-11 21:13:05 +01:00
parent 7edc231f31
commit b3f36faf87
7 changed files with 99 additions and 3 deletions
+2 -2
View File
@@ -1,5 +1,5 @@
#ifndef _MALLOC_H
#define _MALLOC_H
#ifndef _BITS_MALLOC_H
#define _BITS_MALLOC_H
#include <stddef.h>
+10
View File
@@ -0,0 +1,10 @@
sys_includes = ["features.h", "stddef.h"]
include_guard = "_RELIBC_MALLOC_H"
trailer = "#include <bits/malloc.h>"
language = "C"
style = "Type"
no_includes = true
cpp_compat = true
[enum]
prefix_with_name = true
+39
View File
@@ -0,0 +1,39 @@
//! `malloc.h` implementation.
//!
//! Non-POSIX, see <https://man7.org/linux/man-pages/man3/posix_memalign.3.html>.
use crate::{
header::errno::*,
platform::{self, types::*, Pal, Sys, ERRNO},
};
use core::ptr;
/// See <https://man7.org/linux/man-pages/man3/posix_memalign.3.html>.
#[deprecated]
#[no_mangle]
pub unsafe extern "C" fn pvalloc(size: size_t) -> *mut c_void {
let page_size = Sys::getpagesize();
// Find the smallest multiple of the page size in which the requested size
// will fit. The result of the division will always be less than or equal
// to size_t::MAX - 1, and the num_pages calculation will therefore never
// overflow.
let num_pages = if size != 0 {
(size - 1) / page_size + 1
} else {
0
};
match num_pages.checked_mul(page_size) {
Some(alloc_size) => {
let ptr = platform::alloc_align(alloc_size, page_size);
if ptr.is_null() {
platform::ERRNO.set(ENOMEM);
}
ptr
}
None => {
platform::ERRNO.set(ENOMEM);
ptr::null_mut()
}
}
}
+1
View File
@@ -35,6 +35,7 @@ pub mod langinfo;
pub mod libgen;
pub mod limits;
pub mod locale;
pub mod malloc;
// math.h implemented in C
pub mod monetary;
// TODO: mqueue.h
@@ -24,3 +24,7 @@ posix_memalign (alignment 0): pointer: (nil), error value: 22 = Invalid argument
posix_memalign (non-power-of-two multiple of sizeof(void *)): pointer: (nil), error value: 22 = Invalid argument
posix_memalign (size 0): (OK)
posix_memalign (SIZE_MAX): pointer: (nil), error value: 12 = Out of memory
pvalloc (size 0): (OK)
pvalloc: pointer: (alignment OK), error value: 0 = Success
pvalloc (2 pages): pointer: (alignment OK), error value: 0 = Success
pvalloc (SIZE_MAX): pointer: (nil), error value: 12 = Out of memory
@@ -24,3 +24,7 @@ posix_memalign (alignment 0): pointer: (nil), error value: 22 = Invalid argument
posix_memalign (non-power-of-two multiple of sizeof(void *)): pointer: (nil), error value: 22 = Invalid argument
posix_memalign (size 0): (OK)
posix_memalign (SIZE_MAX): pointer: (nil), error value: 12 = Out of memory
pvalloc (size 0): (OK)
pvalloc: pointer: (alignment OK), error value: 0 = Success
pvalloc (2 pages): pointer: (alignment OK), error value: 0 = Success
pvalloc (SIZE_MAX): pointer: (nil), error value: 12 = Out of memory
+39 -1
View File
@@ -1,4 +1,4 @@
#include <malloc.h>
#include <malloc.h> /* for pvalloc() */
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
@@ -299,5 +299,43 @@ int main(void) {
test_cannot_alloc(ptr_posix_memalign_maxsize, posix_memalign_maxsize_return);
free(ptr_posix_memalign_maxsize);
errno = 0;
char * ptr_pvalloc_size0 = (char *)pvalloc(zero_size);
int pvalloc_size0_errno = errno;
printf("pvalloc (size 0): ");
test_size_zero(ptr_pvalloc_size0, page_size, pvalloc_size0_errno);
free(ptr_pvalloc_size0);
errno = 0;
char * ptr_pvalloc = (char *)pvalloc(sample_alloc_size);
int pvalloc_errno = errno;
printf("pvalloc: ");
test_valid_aligned(ptr_pvalloc, page_size, pvalloc_errno);
/* Check that the alloc size is rounded up to nearest page-size
* multiple */
for(i = 0; i < page_size; i++) {
ptr_pvalloc[i] = (char)i;
}
free(ptr_pvalloc);
errno = 0;
char * ptr_pvalloc_multipage = (char *)pvalloc(page_size + 1);
int pvalloc_multipage_errno = errno;
printf("pvalloc (2 pages): ");
test_valid_aligned(ptr_pvalloc_multipage, page_size, pvalloc_multipage_errno);
/* Check that the alloc size is rounded up to nearest page-size
* multiple */
for(i = 0; i < 2*page_size; i++) {
ptr_pvalloc_multipage[i] = (char)i;
}
free(ptr_pvalloc_multipage);
errno = 0;
char * ptr_pvalloc_maxsize = (char *)pvalloc(max_size);
int pvalloc_maxsize_errno = errno;
printf("pvalloc (SIZE_MAX): ");
test_cannot_alloc(ptr_pvalloc_maxsize, pvalloc_maxsize_errno);
free(ptr_pvalloc_maxsize);
#pragma GCC diagnostic pop
}