From a63a24d4d2c8629c33bd121d286fed8c92bc4ac2 Mon Sep 17 00:00:00 2001 From: Yota Toyama Date: Mon, 29 Apr 2019 15:46:01 +0000 Subject: [PATCH] Add coroutine support --- .gitmodules | 1 + Cargo.lock | 32 +++++++ Cargo.toml | 1 + examples/coroutines/Cargo.lock | 142 ++++++++++++++++++++++++++++++++ examples/coroutines/Cargo.toml | 10 +++ examples/coroutines/src/main.rs | 28 +++++++ src/lib.rs | 20 ++++- vendor/bdwgc | 2 +- 8 files changed, 234 insertions(+), 2 deletions(-) create mode 100644 examples/coroutines/Cargo.lock create mode 100644 examples/coroutines/Cargo.toml create mode 100644 examples/coroutines/src/main.rs diff --git a/.gitmodules b/.gitmodules index 284c541..b2e9ce0 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,7 @@ [submodule "vendor/bdwgc"] path = vendor/bdwgc url = https://github.com/raviqqe/bdwgc + branch = coroutines [submodule "vendor/libatomic_ops"] path = vendor/libatomic_ops url = https://github.com/ivmai/libatomic_ops diff --git a/Cargo.lock b/Cargo.lock index 149f201..b9fcb1f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14,19 +14,51 @@ version = "0.3.0" dependencies = [ "autotools 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", + "nix 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "bitflags" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "cc" version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "cfg-if" +version = "0.1.7" +source = "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" +[[package]] +name = "nix" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", + "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [metadata] "checksum autotools 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "774fd1b2d459a939302a0bad631a3de176b8bd5f87cbfc28ceb1f6c18d731094" +"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" "checksum cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)" = "5e5f3fee5eeb60324c2781f1e41286bdee933850fff9b3c672587fed5ec58c83" +"checksum cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11d43355396e872eefb45ce6342e4374ed7bc2b3a502d1b28e36d6e23c05d1f4" "checksum libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)" = "bedcc7a809076656486ffe045abeeac163da1b558e963a31e29fbfbeba916917" +"checksum nix 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "46f0f3210768d796e8fa79ec70ee6af172dacbe7147f5e69be5240a47778302b" +"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" diff --git a/Cargo.toml b/Cargo.toml index 15d1795..8d0522c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,7 @@ build = "build.rs" [dependencies] libc = "0.2" +nix = "0.13" [build-dependencies] autotools = "0.2" diff --git a/examples/coroutines/Cargo.lock b/examples/coroutines/Cargo.lock new file mode 100644 index 0000000..7160a17 --- /dev/null +++ b/examples/coroutines/Cargo.lock @@ -0,0 +1,142 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "autotools" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "bdwgc-alloc" +version = "0.3.0" +dependencies = [ + "autotools 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", + "nix 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "bitflags" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "cc" +version = "1.0.35" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "cfg-if" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "context" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)", + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "coroutine" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "context 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "coroutines" +version = "0.1.0" +dependencies = [ + "bdwgc-alloc 0.3.0", + "coroutine 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "gcc" +version = "0.3.55" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "kernel32-sys" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-build 0.1.1 (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" + +[[package]] +name = "log" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "log" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "nix" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", + "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi-build" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[metadata] +"checksum autotools 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "774fd1b2d459a939302a0bad631a3de176b8bd5f87cbfc28ceb1f6c18d731094" +"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" +"checksum cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)" = "5e5f3fee5eeb60324c2781f1e41286bdee933850fff9b3c672587fed5ec58c83" +"checksum cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11d43355396e872eefb45ce6342e4374ed7bc2b3a502d1b28e36d6e23c05d1f4" +"checksum context 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7092f4d8395e0d78008911f93ee73f499d6eb1f0c41342718d8271d2d7c2ad8e" +"checksum coroutine 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d858f2484e2be5e56f7e5b810459035325abc915cc0c229e3b2226a93409f37b" +"checksum gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)" = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2" +"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" +"checksum libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)" = "bedcc7a809076656486ffe045abeeac163da1b558e963a31e29fbfbeba916917" +"checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" +"checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6" +"checksum nix 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "46f0f3210768d796e8fa79ec70ee6af172dacbe7147f5e69be5240a47778302b" +"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" +"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" +"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" diff --git a/examples/coroutines/Cargo.toml b/examples/coroutines/Cargo.toml new file mode 100644 index 0000000..b1e9856 --- /dev/null +++ b/examples/coroutines/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "coroutines" +version = "0.1.0" +authors = ["Yota Toyama "] +edition = "2018" +publish = false + +[dependencies] +bdwgc-alloc = { path = "../.." } +coroutine = "0.8" diff --git a/examples/coroutines/src/main.rs b/examples/coroutines/src/main.rs new file mode 100644 index 0000000..121441d --- /dev/null +++ b/examples/coroutines/src/main.rs @@ -0,0 +1,28 @@ +extern crate bdwgc_alloc; +extern crate coroutine; + +use bdwgc_alloc::Allocator; +use coroutine::asymmetric::Coroutine; +use std::alloc::{GlobalAlloc, Layout}; + +#[global_allocator] +static GLOBAL_ALLOCATOR: Allocator = Allocator; + +fn main() { + unsafe { + Allocator::initialize(); + Allocator::disable_gc(); + } + + let handle = Coroutine::spawn(move |_, _| { + let bottom: u8 = 0; + unsafe { Allocator::set_stack_bottom(&bottom) } + Allocator::enable_gc(); + + loop { + unsafe { GLOBAL_ALLOCATOR.alloc(Layout::from_size_align(2 ^ 8, 8).unwrap()) }; + } + }); + + for _ in handle {} +} diff --git a/src/lib.rs b/src/lib.rs index b2482d7..430ddca 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,7 +2,7 @@ extern crate libc; mod error; -use libc::{c_int, c_void, size_t}; +use libc::{c_char, c_int, c_void, size_t}; use std::alloc::{GlobalAlloc, Layout}; const GC_SUCCESS: c_int = 0; @@ -16,17 +16,28 @@ struct GcStackBase { #[link(name = "gc", kind = "static")] extern "C" { fn GC_allow_register_threads() -> c_void; + fn GC_disable() -> c_void; + fn GC_enable() -> 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_register_my_thread(stack_base: *const GcStackBase) -> c_int; + fn GC_set_stack_bottom(thread: *const c_void, stack_bottom: *const c_char); fn GC_unregister_my_thread(); } pub struct Allocator; impl Allocator { + pub fn disable_gc() { + unsafe { GC_disable() }; + } + + pub fn enable_gc() { + unsafe { GC_enable() }; + } + pub unsafe fn initialize() { GC_init(); GC_allow_register_threads(); @@ -47,6 +58,13 @@ impl Allocator { Ok(()) } + pub unsafe fn set_stack_bottom(bottom: *const u8) { + GC_set_stack_bottom( + std::mem::transmute(nix::sys::pthread::pthread_self()), + std::mem::transmute(bottom), + ); + } + pub unsafe fn unregister_current_thread() { GC_unregister_my_thread() } diff --git a/vendor/bdwgc b/vendor/bdwgc index 51a44b9..5579207 160000 --- a/vendor/bdwgc +++ b/vendor/bdwgc @@ -1 +1 @@ -Subproject commit 51a44b9cdb0f28e60509a6d930e7787163d110c4 +Subproject commit 557920793bae0bce85b70d29d51860ca259a322d