From e620fbde5717afd339385762d0cc3bb0f76bc05a Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Sat, 13 Apr 2019 20:22:56 +0000 Subject: [PATCH] Initialize src --- .gitignore | 1 + Cargo.lock | 16 +++++++++++ Cargo.toml | 9 ++++++ src/error.rs | 22 +++++++++++++++ src/lib.rs | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 127 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 src/error.rs create mode 100644 src/lib.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..eb5a316 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..c4e887e --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,16 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "gc" +version = "0.1.0" +dependencies = [ + "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "libc" +version = "0.2.51" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[metadata] +"checksum libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)" = "bedcc7a809076656486ffe045abeeac163da1b558e963a31e29fbfbeba916917" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..e77f856 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "gc" +version = "0.1.0" +authors = ["swgillespie ", "Yota Toyama "] +publish = false +edition = "2018" + +[dependencies] +libc = "0.2" diff --git a/src/error.rs b/src/error.rs new file mode 100644 index 0000000..ea6deb2 --- /dev/null +++ b/src/error.rs @@ -0,0 +1,22 @@ +#[derive(Debug)] +pub struct Error { + description: &'static str, +} + +impl Error { + pub fn new(description: &'static str) -> Error { + Error { description } + } +} + +impl std::fmt::Display for Error { + fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(formatter, "{}", self.description) + } +} + +impl std::error::Error for Error { + fn description(&self) -> &str { + self.description + } +} diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..1086f09 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,79 @@ +extern crate libc; + +mod error; + +use libc::{c_int, c_void, size_t}; +use std::alloc::{GlobalAlloc, Layout}; + +const GC_SUCCESS: c_int = 0; + +#[repr(C)] +struct GCStackBase { + mem_base: *const c_void, + reg_base: *const c_void, +} + +#[link(name = "gc")] +extern "C" { + fn GC_allow_register_threads() -> c_void; + fn GC_free(ptr: *mut c_void); + fn GC_get_stack_base(stack_base: *mut GCStackBase) -> c_int; + fn GC_init() -> c_void; + fn GC_malloc(size: size_t) -> *mut c_void; + fn GC_malloc_uncollectable(size: size_t) -> *mut c_void; + fn GC_register_my_thread(stack_base: *const GCStackBase) -> c_int; + fn GC_unregister_my_thread(); +} + +static mut GC_STARTED: bool = false; +pub struct Allocator; + +impl Allocator { + pub unsafe fn initialize() { + GC_init(); + GC_allow_register_threads(); + } + + pub unsafe fn start_gc() { + GC_STARTED = true + } + + pub fn register_current_thread() -> Result<(), error::Error> { + let mut base = GCStackBase { + mem_base: std::ptr::null(), + reg_base: std::ptr::null(), + }; + + if unsafe { GC_get_stack_base(&mut base) } != GC_SUCCESS { + return Err(error::Error::new("failed to get stack base")); + } + + if unsafe { GC_register_my_thread(&base) } != GC_SUCCESS { + return Err(error::Error::new("failed to register a thread for GC")); + } + + Ok(()) + } + + pub fn unregister_current_thread() { + unsafe { GC_unregister_my_thread() } + } + + pub fn alloc(size: usize) -> *mut u8 { + unsafe { Allocator.alloc(Layout::from_size_align_unchecked(size, 8)) } + } +} + +unsafe impl GlobalAlloc for Allocator { + unsafe fn alloc(&self, layout: Layout) -> *mut u8 { + return if GC_STARTED { + GC_malloc(layout.size()) + } else { + GC_malloc_uncollectable(layout.size()) + } as *mut u8; + } + + unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) { + GC_free(ptr as *mut c_void) + } +}