Merge branch 'allocator' into 'master'

Allocator

See merge request redox-os/relibc!295
This commit is contained in:
Jeremy Soller
2020-07-18 19:51:37 +00:00
8 changed files with 104 additions and 18 deletions
+18 -2
View File
@@ -523,7 +523,8 @@ MAX_RELEASE_CHECK_RATE default: 4095 unless not HAVE_MMAP
/* Customizations { */
#define HAVE_MMAP 0
#define HAVE_MMAP 1
#define ONLY_MSPACES 1
#define LACKS_ERRNO_H
#define LACKS_FCNTL_H
#define LACKS_SCHED_H
@@ -536,7 +537,7 @@ MAX_RELEASE_CHECK_RATE default: 4095 unless not HAVE_MMAP
#define USE_DL_PREFIX 1
#define USE_LOCKS 1
#define USE_SPIN_LOCKS 1
#define HAVE_MREMAP 0
#define malloc_getpagesize ((size_t)4096U)
#include <stddef.h>
@@ -545,7 +546,22 @@ MAX_RELEASE_CHECK_RATE default: 4095 unless not HAVE_MMAP
#define EINVAL 22
extern __thread int errno;
#if defined(__linux__)
#define O_RDWR 2
#define PROT_READ 1
#define PROT_WRITE 2
#elif defined(__redox__)
#define O_RDWR 196608
#define PROT_READ 4
#define PROT_WRITE 2
#endif /*defined(__redox__)*/
#define MAP_PRIVATE 2
typedef long off_t;
int open(const char *pathname, int flags);
void *mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off);
int munmap(void *addr, size_t len);
void abort(void);
void *memcpy(void *dest, const void *src, size_t n);
void *memset(void *s, int c, size_t n);
+5 -1
View File
@@ -694,7 +694,11 @@ impl Linker {
set_u64(tm as u64);
}
reloc::R_X86_64_DTPOFF64 => {
set_u64((s - b) as u64);
if s != 0 {
set_u64((s - b) as u64);
} else {
set_u64(s as u64);
}
}
reloc::R_X86_64_GLOB_DAT | reloc::R_X86_64_JUMP_SLOT => {
set_u64(s as u64);
+10 -2
View File
@@ -3,7 +3,12 @@
use alloc::{borrow::ToOwned, boxed::Box, collections::BTreeMap, string::String, vec::Vec};
use crate::{
c_str::CStr, header::unistd, platform::types::c_char, start::Stack, sync::mutex::Mutex,
c_str::CStr,
header::unistd,
platform::{new_mspace, types::c_char},
start::Stack,
sync::mutex::Mutex,
ALLOCATOR,
};
use super::{
@@ -116,7 +121,9 @@ unsafe fn adjust_stack(sp: &'static mut Stack) {
}
#[no_mangle]
pub extern "C" fn relibc_ld_so_start(sp: &'static mut Stack, ld_entry: usize) -> usize {
// first we get the arguments, the environment, and the auxilary vector
// First thing we initialize the mspace
ALLOCATOR.set_book_keeper(new_mspace());
// next we get the arguments, the environment, and the auxilary vector
let (argv, envs, auxv) = unsafe {
let argv_start = sp.argv() as *mut usize;
let (argv, argv_end) = get_argv(argv_start);
@@ -210,6 +217,7 @@ pub extern "C" fn relibc_ld_so_start(sp: &'static mut Stack, ld_entry: usize) ->
}
if let Some(tcb) = unsafe { Tcb::current() } {
tcb.linker_ptr = Box::into_raw(Box::new(Mutex::new(linker)));
tcb.mspace = ALLOCATOR.get_book_keeper();
}
if is_manual {
eprintln!("ld.so: entry '{}': {:#x}", path, entry);
+3
View File
@@ -45,6 +45,8 @@ pub struct Tcb {
pub masters_len: usize,
/// Pointer to dynamic linker
pub linker_ptr: *const Mutex<Linker>,
/// pointer to rust memory allocator structure
pub mspace: usize,
}
impl Tcb {
@@ -64,6 +66,7 @@ impl Tcb {
masters_ptr: ptr::null_mut(),
masters_len: 0,
linker_ptr: ptr::null(),
mspace: 0,
},
);
+2 -2
View File
@@ -59,10 +59,10 @@ pub mod platform;
pub mod start;
pub mod sync;
use crate::platform::{Allocator, Pal, Sys};
use crate::platform::{Allocator, Pal, Sys, NEWALLOCATOR};
#[global_allocator]
static ALLOCATOR: Allocator = Allocator;
static ALLOCATOR: Allocator = NEWALLOCATOR;
#[no_mangle]
pub extern "C" fn relibc_panic(pi: &::core::panic::PanicInfo) -> ! {
+37 -10
View File
@@ -1,16 +1,39 @@
use core::alloc::{GlobalAlloc, Layout};
use core::{
alloc::{GlobalAlloc, Layout},
sync::atomic::{AtomicUsize, Ordering},
};
use crate::ALLOCATOR;
use super::types::*;
extern "C" {
fn dlmalloc(bytes: size_t) -> *mut c_void;
fn dlmemalign(alignment: size_t, bytes: size_t) -> *mut c_void;
fn dlrealloc(oldmem: *mut c_void, bytes: size_t) -> *mut c_void;
fn dlfree(mem: *mut c_void);
fn create_mspace(capacity: size_t, locked: c_int) -> usize;
fn mspace_malloc(msp: usize, bytes: size_t) -> *mut c_void;
fn mspace_memalign(msp: usize, alignment: size_t, bytes: size_t) -> *mut c_void;
fn mspace_realloc(msp: usize, oldmem: *mut c_void, bytes: size_t) -> *mut c_void;
fn mspace_free(msp: usize, mem: *mut c_void);
//fn dlmalloc(bytes: size_t) -> *mut c_void;
//fn dlmemalign(alignment: size_t, bytes: size_t) -> *mut c_void;
//fn dlrealloc(oldmem: *mut c_void, bytes: size_t) -> *mut c_void;
//fn dlfree(mem: *mut c_void);
}
pub struct Allocator;
pub struct Allocator {
mstate: AtomicUsize,
}
pub const NEWALLOCATOR: Allocator = Allocator {
mstate: AtomicUsize::new(0),
};
impl Allocator {
pub fn set_book_keeper(&self, mstate: usize) {
self.mstate.store(mstate, Ordering::Relaxed);
}
pub fn get_book_keeper(&self) -> usize {
self.mstate.load(Ordering::Relaxed)
}
}
unsafe impl<'a> GlobalAlloc for Allocator {
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
alloc_align(layout.size(), layout.align()) as *mut u8
@@ -22,17 +45,21 @@ unsafe impl<'a> GlobalAlloc for Allocator {
}
pub unsafe fn alloc(size: usize) -> *mut c_void {
dlmalloc(size)
mspace_malloc(ALLOCATOR.get_book_keeper(), size)
}
pub unsafe fn alloc_align(size: usize, alignment: usize) -> *mut c_void {
dlmemalign(alignment, size)
mspace_memalign(ALLOCATOR.get_book_keeper(), alignment, size)
}
pub unsafe fn realloc(ptr: *mut c_void, size: size_t) -> *mut c_void {
dlrealloc(ptr, size)
mspace_realloc(ALLOCATOR.get_book_keeper(), ptr, size)
}
pub unsafe fn free(ptr: *mut c_void) {
dlfree(ptr)
mspace_free(ALLOCATOR.get_book_keeper(), ptr)
}
pub fn new_mspace() -> usize {
unsafe { create_mspace(0, 0) }
}
+5
View File
@@ -17,6 +17,7 @@ use crate::{
Pal, Sys,
},
sync::Mutex,
ALLOCATOR,
};
pub struct Semaphore {
@@ -76,6 +77,7 @@ unsafe extern "C" fn pte_osThreadShim(
tls_masters_ptr: *mut Master,
tls_masters_len: usize,
tls_linker_ptr: *const Mutex<Linker>,
tls_mspace: usize,
) {
// The kernel allocated TLS does not have masters set, so do not attempt to copy it.
// It will be copied by the kernel.
@@ -84,6 +86,7 @@ unsafe extern "C" fn pte_osThreadShim(
tcb.masters_ptr = tls_masters_ptr;
tcb.masters_len = tls_masters_len;
tcb.linker_ptr = tls_linker_ptr;
tcb.mspace = tls_mspace;
tcb.copy_masters().unwrap();
tcb.activate();
}
@@ -134,11 +137,13 @@ pub unsafe extern "C" fn pte_osThreadCreate(
push(0);
if let Some(tcb) = Tcb::current() {
push(tcb.mspace as usize);
push(tcb.linker_ptr as usize);
push(tcb.masters_len);
push(tcb.masters_ptr as usize);
push(tcb.tls_len);
} else {
push(ALLOCATOR.get_book_keeper());
push(0);
push(0);
push(0);
+24 -1
View File
@@ -4,7 +4,8 @@ use core::{intrinsics, ptr};
use crate::{
header::{stdio, stdlib},
ld_so,
platform::{self, types::*, Pal, Sys},
platform::{self, new_mspace, types::*, Pal, Sys},
ALLOCATOR,
};
#[repr(C)]
@@ -66,7 +67,26 @@ static INIT_ARRAY: [extern "C" fn(); 1] = [init_array];
static mut init_complete: bool = false;
fn alloc_init() {
unsafe{
if let Some(tcb) = ld_so::tcb::Tcb::current() {
if tcb.mspace != 0 {
ALLOCATOR.set_book_keeper(tcb.mspace);
} else if ALLOCATOR.get_book_keeper() == 0 {
ALLOCATOR.set_book_keeper(new_mspace());
}
} else if ALLOCATOR.get_book_keeper() == 0 {
ALLOCATOR.set_book_keeper(new_mspace());
}
}
}
extern "C" fn init_array() {
// The thing is that we cannot guarantee if
// init_array runs first or if relibc_start runs first
// Still whoever gets to run first must initialize rust
// memory allocator before doing anything else.
alloc_init();
io_init();
unsafe { init_complete = true };
}
@@ -92,6 +112,9 @@ pub unsafe extern "C" fn relibc_start(sp: &'static Stack) -> ! {
fn _init();
fn main(argc: isize, argv: *mut *mut c_char, envp: *mut *mut c_char) -> c_int;
}
// Step 1 setup the right allocator...
// if any memory rust based memory allocation happen before this step .. we are doomed.
alloc_init();
// Ensure correct host system before executing more system calls
relibc_verify_host();