Merge branch 'allocator' into 'master'
Allocator See merge request redox-os/relibc!295
This commit is contained in:
+18
-2
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
@@ -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
@@ -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) -> ! {
|
||||
|
||||
@@ -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) }
|
||||
}
|
||||
|
||||
@@ -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
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user