Move implementation for threads to Rust
This binds to the appropriate pthreads_* and Windows specific functions and calls them from Rust. This allows for removal of the C++ support code for threads. Fixes #10162
This commit is contained in:
parent
92065ceb63
commit
47e0bd403a
1
mk/rt.mk
1
mk/rt.mk
@ -84,7 +84,6 @@ endif
|
|||||||
|
|
||||||
RUNTIME_CXXS_$(1)_$(2) := \
|
RUNTIME_CXXS_$(1)_$(2) := \
|
||||||
rt/sync/lock_and_signal.cpp \
|
rt/sync/lock_and_signal.cpp \
|
||||||
rt/sync/rust_thread.cpp \
|
|
||||||
rt/rust_builtin.cpp \
|
rt/rust_builtin.cpp \
|
||||||
rt/rust_upcall.cpp \
|
rt/rust_upcall.cpp \
|
||||||
rt/miniz.cpp \
|
rt/miniz.cpp \
|
||||||
|
@ -224,7 +224,10 @@ pub mod types {
|
|||||||
pub mod common {
|
pub mod common {
|
||||||
pub mod posix01 {
|
pub mod posix01 {
|
||||||
use libc::types::common::c95::{c_void};
|
use libc::types::common::c95::{c_void};
|
||||||
use libc::types::os::arch::c95::{c_char, size_t};
|
use libc::types::os::arch::c95::{c_char, c_ulong, size_t};
|
||||||
|
|
||||||
|
pub type pthread_t = c_ulong;
|
||||||
|
|
||||||
pub struct glob_t {
|
pub struct glob_t {
|
||||||
gl_pathc: size_t,
|
gl_pathc: size_t,
|
||||||
gl_pathv: **c_char,
|
gl_pathv: **c_char,
|
||||||
@ -294,7 +297,7 @@ pub mod types {
|
|||||||
}
|
}
|
||||||
#[cfg(target_arch = "x86")]
|
#[cfg(target_arch = "x86")]
|
||||||
pub mod posix01 {
|
pub mod posix01 {
|
||||||
use libc::types::os::arch::c95::{c_short, c_long, time_t};
|
use libc::types::os::arch::c95::{c_char, c_short, c_long, time_t};
|
||||||
use libc::types::os::arch::posix88::{dev_t, gid_t, ino_t};
|
use libc::types::os::arch::posix88::{dev_t, gid_t, ino_t};
|
||||||
use libc::types::os::arch::posix88::{mode_t, off_t};
|
use libc::types::os::arch::posix88::{mode_t, off_t};
|
||||||
use libc::types::os::arch::posix88::{uid_t};
|
use libc::types::os::arch::posix88::{uid_t};
|
||||||
@ -325,10 +328,14 @@ pub mod types {
|
|||||||
__unused4: c_long,
|
__unused4: c_long,
|
||||||
__unused5: c_long,
|
__unused5: c_long,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct pthread_attr_t {
|
||||||
|
__size: [c_char, ..36]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#[cfg(target_arch = "arm")]
|
#[cfg(target_arch = "arm")]
|
||||||
pub mod posix01 {
|
pub mod posix01 {
|
||||||
use libc::types::os::arch::c95::{c_uchar, c_uint, c_ulong, time_t};
|
use libc::types::os::arch::c95::{c_char, c_uchar, c_uint, c_ulong, time_t};
|
||||||
use libc::types::os::arch::c99::{c_longlong, c_ulonglong};
|
use libc::types::os::arch::c99::{c_longlong, c_ulonglong};
|
||||||
use libc::types::os::arch::posix88::{uid_t, gid_t, ino_t};
|
use libc::types::os::arch::posix88::{uid_t, gid_t, ino_t};
|
||||||
|
|
||||||
@ -357,10 +364,14 @@ pub mod types {
|
|||||||
st_ctime_nsec: c_ulong,
|
st_ctime_nsec: c_ulong,
|
||||||
st_ino: c_ulonglong
|
st_ino: c_ulonglong
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct pthread_attr_t {
|
||||||
|
__size: [c_char, ..36]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#[cfg(target_arch = "mips")]
|
#[cfg(target_arch = "mips")]
|
||||||
pub mod posix01 {
|
pub mod posix01 {
|
||||||
use libc::types::os::arch::c95::{c_long, c_ulong, time_t};
|
use libc::types::os::arch::c95::{c_char, c_long, c_ulong, time_t};
|
||||||
use libc::types::os::arch::posix88::{gid_t, ino_t};
|
use libc::types::os::arch::posix88::{gid_t, ino_t};
|
||||||
use libc::types::os::arch::posix88::{mode_t, off_t};
|
use libc::types::os::arch::posix88::{mode_t, off_t};
|
||||||
use libc::types::os::arch::posix88::{uid_t};
|
use libc::types::os::arch::posix88::{uid_t};
|
||||||
@ -391,6 +402,10 @@ pub mod types {
|
|||||||
st_blocks: blkcnt_t,
|
st_blocks: blkcnt_t,
|
||||||
st_pad5: [c_long, ..14],
|
st_pad5: [c_long, ..14],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct pthread_attr_t {
|
||||||
|
__size: [c_char, ..36]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
pub mod posix08 {}
|
pub mod posix08 {}
|
||||||
pub mod bsd44 {}
|
pub mod bsd44 {}
|
||||||
@ -435,7 +450,7 @@ pub mod types {
|
|||||||
pub type ssize_t = i64;
|
pub type ssize_t = i64;
|
||||||
}
|
}
|
||||||
pub mod posix01 {
|
pub mod posix01 {
|
||||||
use libc::types::os::arch::c95::{c_int, c_long, time_t};
|
use libc::types::os::arch::c95::{c_char, c_int, c_long, time_t};
|
||||||
use libc::types::os::arch::posix88::{dev_t, gid_t, ino_t};
|
use libc::types::os::arch::posix88::{dev_t, gid_t, ino_t};
|
||||||
use libc::types::os::arch::posix88::{mode_t, off_t};
|
use libc::types::os::arch::posix88::{mode_t, off_t};
|
||||||
use libc::types::os::arch::posix88::{uid_t};
|
use libc::types::os::arch::posix88::{uid_t};
|
||||||
@ -463,6 +478,10 @@ pub mod types {
|
|||||||
st_ctime_nsec: c_long,
|
st_ctime_nsec: c_long,
|
||||||
__unused: [c_long, ..3],
|
__unused: [c_long, ..3],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct pthread_attr_t {
|
||||||
|
__size: [c_char, ..56]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
pub mod posix08 {
|
pub mod posix08 {
|
||||||
}
|
}
|
||||||
@ -479,6 +498,10 @@ pub mod types {
|
|||||||
pub mod posix01 {
|
pub mod posix01 {
|
||||||
use libc::types::common::c95::{c_void};
|
use libc::types::common::c95::{c_void};
|
||||||
use libc::types::os::arch::c95::{c_char, c_int, size_t};
|
use libc::types::os::arch::c95::{c_char, c_int, size_t};
|
||||||
|
use libc::types::os::arch::c99::{uintptr_t};
|
||||||
|
|
||||||
|
pub type pthread_t = uintptr_t;
|
||||||
|
|
||||||
pub struct glob_t {
|
pub struct glob_t {
|
||||||
gl_pathc: size_t,
|
gl_pathc: size_t,
|
||||||
__unused1: size_t,
|
__unused1: size_t,
|
||||||
@ -535,6 +558,7 @@ pub mod types {
|
|||||||
pub type ssize_t = i64;
|
pub type ssize_t = i64;
|
||||||
}
|
}
|
||||||
pub mod posix01 {
|
pub mod posix01 {
|
||||||
|
use libc::types::common::c95::{c_void};
|
||||||
use libc::types::common::c99::{uint8_t, uint32_t, int32_t};
|
use libc::types::common::c99::{uint8_t, uint32_t, int32_t};
|
||||||
use libc::types::os::arch::c95::{c_long, time_t};
|
use libc::types::os::arch::c95::{c_long, time_t};
|
||||||
use libc::types::os::arch::posix88::{dev_t, gid_t, ino_t};
|
use libc::types::os::arch::posix88::{dev_t, gid_t, ino_t};
|
||||||
@ -569,6 +593,8 @@ pub mod types {
|
|||||||
st_birthtime_nsec: c_long,
|
st_birthtime_nsec: c_long,
|
||||||
__unused: [uint8_t, ..2],
|
__unused: [uint8_t, ..2],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub type pthread_attr_t = *c_void;
|
||||||
}
|
}
|
||||||
pub mod posix08 {
|
pub mod posix08 {
|
||||||
}
|
}
|
||||||
@ -945,6 +971,10 @@ pub mod types {
|
|||||||
pub mod posix01 {
|
pub mod posix01 {
|
||||||
use libc::types::common::c95::{c_void};
|
use libc::types::common::c95::{c_void};
|
||||||
use libc::types::os::arch::c95::{c_char, c_int, size_t};
|
use libc::types::os::arch::c95::{c_char, c_int, size_t};
|
||||||
|
use libc::types::os::arch::c99::{uintptr_t};
|
||||||
|
|
||||||
|
pub type pthread_t = uintptr_t;
|
||||||
|
|
||||||
pub struct glob_t {
|
pub struct glob_t {
|
||||||
gl_pathc: size_t,
|
gl_pathc: size_t,
|
||||||
__unused1: c_int,
|
__unused1: c_int,
|
||||||
@ -1002,7 +1032,7 @@ pub mod types {
|
|||||||
}
|
}
|
||||||
pub mod posix01 {
|
pub mod posix01 {
|
||||||
use libc::types::common::c99::{int32_t, int64_t, uint32_t};
|
use libc::types::common::c99::{int32_t, int64_t, uint32_t};
|
||||||
use libc::types::os::arch::c95::{c_long, time_t};
|
use libc::types::os::arch::c95::{c_char, c_long, time_t};
|
||||||
use libc::types::os::arch::posix88::{dev_t, gid_t, ino_t,
|
use libc::types::os::arch::posix88::{dev_t, gid_t, ino_t,
|
||||||
mode_t, off_t, uid_t};
|
mode_t, off_t, uid_t};
|
||||||
|
|
||||||
@ -1034,6 +1064,11 @@ pub mod types {
|
|||||||
st_lspare: int32_t,
|
st_lspare: int32_t,
|
||||||
st_qspare: [int64_t, ..2],
|
st_qspare: [int64_t, ..2],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct pthread_attr_t {
|
||||||
|
__sig: c_long,
|
||||||
|
__opaque: [c_char, ..36]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
pub mod posix08 {
|
pub mod posix08 {
|
||||||
}
|
}
|
||||||
@ -1083,7 +1118,7 @@ pub mod types {
|
|||||||
pub mod posix01 {
|
pub mod posix01 {
|
||||||
use libc::types::common::c99::{int32_t, int64_t};
|
use libc::types::common::c99::{int32_t, int64_t};
|
||||||
use libc::types::common::c99::{uint32_t};
|
use libc::types::common::c99::{uint32_t};
|
||||||
use libc::types::os::arch::c95::{c_long, time_t};
|
use libc::types::os::arch::c95::{c_char, c_long, time_t};
|
||||||
use libc::types::os::arch::posix88::{dev_t, gid_t, ino_t};
|
use libc::types::os::arch::posix88::{dev_t, gid_t, ino_t};
|
||||||
use libc::types::os::arch::posix88::{mode_t, off_t, uid_t};
|
use libc::types::os::arch::posix88::{mode_t, off_t, uid_t};
|
||||||
|
|
||||||
@ -1115,6 +1150,11 @@ pub mod types {
|
|||||||
st_lspare: int32_t,
|
st_lspare: int32_t,
|
||||||
st_qspare: [int64_t, ..2],
|
st_qspare: [int64_t, ..2],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct pthread_attr_t {
|
||||||
|
__sig: c_long,
|
||||||
|
__opaque: [c_char, ..56]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
pub mod posix08 {
|
pub mod posix08 {
|
||||||
}
|
}
|
||||||
@ -1800,6 +1840,9 @@ pub mod consts {
|
|||||||
pub static _SC_XOPEN_LEGACY : c_int = 129;
|
pub static _SC_XOPEN_LEGACY : c_int = 129;
|
||||||
pub static _SC_XOPEN_REALTIME : c_int = 130;
|
pub static _SC_XOPEN_REALTIME : c_int = 130;
|
||||||
pub static _SC_XOPEN_REALTIME_THREADS : c_int = 131;
|
pub static _SC_XOPEN_REALTIME_THREADS : c_int = 131;
|
||||||
|
|
||||||
|
pub static PTHREAD_CREATE_JOINABLE: c_int = 0;
|
||||||
|
pub static PTHREAD_CREATE_DETACHED: c_int = 1;
|
||||||
}
|
}
|
||||||
pub mod posix08 {
|
pub mod posix08 {
|
||||||
}
|
}
|
||||||
@ -2207,6 +2250,9 @@ pub mod consts {
|
|||||||
pub static _SC_XOPEN_UNIX : c_int = 115;
|
pub static _SC_XOPEN_UNIX : c_int = 115;
|
||||||
pub static _SC_XOPEN_VERSION : c_int = 116;
|
pub static _SC_XOPEN_VERSION : c_int = 116;
|
||||||
pub static _SC_XOPEN_XCU_VERSION : c_int = 117;
|
pub static _SC_XOPEN_XCU_VERSION : c_int = 117;
|
||||||
|
|
||||||
|
pub static PTHREAD_CREATE_JOINABLE: c_int = 0;
|
||||||
|
pub static PTHREAD_CREATE_DETACHED: c_int = 1;
|
||||||
}
|
}
|
||||||
pub mod posix08 {
|
pub mod posix08 {
|
||||||
}
|
}
|
||||||
@ -2560,6 +2606,9 @@ pub mod consts {
|
|||||||
pub static _SC_XOPEN_UNIX : c_int = 115;
|
pub static _SC_XOPEN_UNIX : c_int = 115;
|
||||||
pub static _SC_XOPEN_VERSION : c_int = 116;
|
pub static _SC_XOPEN_VERSION : c_int = 116;
|
||||||
pub static _SC_XOPEN_XCU_VERSION : c_int = 121;
|
pub static _SC_XOPEN_XCU_VERSION : c_int = 121;
|
||||||
|
|
||||||
|
pub static PTHREAD_CREATE_JOINABLE: c_int = 1;
|
||||||
|
pub static PTHREAD_CREATE_DETACHED: c_int = 2;
|
||||||
}
|
}
|
||||||
pub mod posix08 {
|
pub mod posix08 {
|
||||||
}
|
}
|
||||||
|
@ -8,74 +8,141 @@
|
|||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
|
#[allow(non_camel_case_types)];
|
||||||
|
|
||||||
use cast;
|
use cast;
|
||||||
use libc;
|
use libc;
|
||||||
use ops::Drop;
|
use ops::Drop;
|
||||||
use unstable::raw;
|
|
||||||
use uint;
|
use uint;
|
||||||
|
use ptr;
|
||||||
|
|
||||||
#[allow(non_camel_case_types)] // runtime type
|
#[cfg(windows)]
|
||||||
type raw_thread = libc::c_void;
|
use libc::types::os::arch::extra::{LPSECURITY_ATTRIBUTES, SIZE_T,
|
||||||
|
LPVOID, DWORD, LPDWORD, HANDLE};
|
||||||
|
|
||||||
|
#[cfg(windows)] type rust_thread = HANDLE;
|
||||||
|
#[cfg(unix)] type rust_thread = libc::pthread_t;
|
||||||
|
|
||||||
pub struct Thread {
|
pub struct Thread {
|
||||||
priv main: ~fn(),
|
priv native: rust_thread,
|
||||||
priv raw_thread: *raw_thread,
|
|
||||||
priv joined: bool
|
priv joined: bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static DEFAULT_STACK_SIZE: libc::size_t = 1024*1024;
|
||||||
|
|
||||||
|
#[cfg(windows)] type rust_thread_return = DWORD;
|
||||||
|
#[cfg(unix)] type rust_thread_return = *libc::c_void;
|
||||||
|
|
||||||
impl Thread {
|
impl Thread {
|
||||||
#[fixed_stack_segment] #[inline(never)]
|
|
||||||
pub fn start(main: ~fn()) -> Thread {
|
pub fn start(main: ~fn()) -> Thread {
|
||||||
// This is the starting point of rust os threads. The first thing we do
|
// This is the starting point of rust os threads. The first thing we do
|
||||||
// is make sure that we don't trigger __morestack (also why this has a
|
// is make sure that we don't trigger __morestack (also why this has a
|
||||||
// no_split_stack annotation), and then we re-build the main function
|
// no_split_stack annotation), and then we extract the main function
|
||||||
// and invoke it from there.
|
// and invoke it.
|
||||||
#[no_split_stack]
|
#[no_split_stack]
|
||||||
extern "C" fn thread_start(code: *(), env: *()) {
|
extern "C" fn thread_start(trampoline: *libc::c_void) -> rust_thread_return {
|
||||||
use rt::context;
|
use rt::context;
|
||||||
unsafe {
|
unsafe {
|
||||||
context::record_stack_bounds(0, uint::max_value);
|
context::record_stack_bounds(0, uint::max_value);
|
||||||
let f: &fn() = cast::transmute(raw::Closure {
|
let f: ~~fn() = cast::transmute(trampoline);
|
||||||
code: code,
|
(*f)();
|
||||||
env: env,
|
|
||||||
});
|
|
||||||
f();
|
|
||||||
}
|
}
|
||||||
|
unsafe { cast::transmute(0) }
|
||||||
}
|
}
|
||||||
|
|
||||||
let raw_thread = unsafe {
|
let native = native_thread_create(thread_start, ~main);
|
||||||
let c: raw::Closure = cast::transmute_copy(&main);
|
|
||||||
let raw::Closure { code, env } = c;
|
|
||||||
rust_raw_thread_start(thread_start, code, env)
|
|
||||||
};
|
|
||||||
Thread {
|
Thread {
|
||||||
main: main,
|
native: native,
|
||||||
raw_thread: raw_thread,
|
|
||||||
joined: false,
|
joined: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn join(mut self) {
|
pub fn join(mut self) {
|
||||||
#[fixed_stack_segment]; #[inline(never)];
|
|
||||||
|
|
||||||
assert!(!self.joined);
|
assert!(!self.joined);
|
||||||
unsafe { rust_raw_thread_join(self.raw_thread); }
|
native_thread_join(self.native);
|
||||||
self.joined = true;
|
self.joined = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(windows)]
|
||||||
|
fn native_thread_create(thread_start: extern "C" fn(*libc::c_void) -> rust_thread_return,
|
||||||
|
tramp: ~~fn()) -> rust_thread {
|
||||||
|
#[fixed_stack_segment];
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
let ptr: *mut libc::c_void = cast::transmute(tramp);
|
||||||
|
CreateThread(ptr::mut_null(), DEFAULT_STACK_SIZE, thread_start, ptr, 0, ptr::mut_null())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(windows)]
|
||||||
|
fn native_thread_join(native: rust_thread) {
|
||||||
|
#[fixed_stack_segment];
|
||||||
|
use libc::consts::os::extra::INFINITE;
|
||||||
|
unsafe { WaitForSingleObject(native, INFINITE); }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
fn native_thread_create(thread_start: extern "C" fn(*libc::c_void) -> rust_thread_return,
|
||||||
|
tramp: ~~fn()) -> rust_thread {
|
||||||
|
#[fixed_stack_segment];
|
||||||
|
|
||||||
|
use unstable::intrinsics;
|
||||||
|
let mut native: libc::pthread_t = unsafe { intrinsics::uninit() };
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
use libc::consts::os::posix01::PTHREAD_CREATE_JOINABLE;
|
||||||
|
|
||||||
|
let mut attr: libc::pthread_attr_t = intrinsics::uninit();
|
||||||
|
assert!(pthread_attr_init(&mut attr) == 0);
|
||||||
|
assert!(pthread_attr_setstacksize(&mut attr, DEFAULT_STACK_SIZE) == 0);
|
||||||
|
assert!(pthread_attr_setdetachstate(&mut attr, PTHREAD_CREATE_JOINABLE) == 0);
|
||||||
|
|
||||||
|
let ptr: *libc::c_void = cast::transmute(tramp);
|
||||||
|
assert!(pthread_create(&mut native, &attr, thread_start, ptr) == 0);
|
||||||
|
}
|
||||||
|
native
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
fn native_thread_join(native: rust_thread) {
|
||||||
|
#[fixed_stack_segment];
|
||||||
|
unsafe { assert!(pthread_join(native, ptr::null()) == 0) }
|
||||||
|
}
|
||||||
|
|
||||||
impl Drop for Thread {
|
impl Drop for Thread {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
#[fixed_stack_segment]; #[inline(never)];
|
#[fixed_stack_segment]; #[inline(never)];
|
||||||
|
|
||||||
assert!(self.joined);
|
assert!(self.joined);
|
||||||
unsafe { rust_raw_thread_delete(self.raw_thread) }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern {
|
#[cfg(windows, target_arch = "x86")]
|
||||||
fn rust_raw_thread_start(f: extern "C" fn(*(), *()),
|
extern "stdcall" {
|
||||||
code: *(), env: *()) -> *raw_thread;
|
fn CreateThread(lpThreadAttributes: LPSECURITY_ATTRIBUTES, dwStackSize: SIZE_T,
|
||||||
fn rust_raw_thread_join(thread: *raw_thread);
|
lpStartAddress: extern "C" fn(*libc::c_void) -> rust_thread_return,
|
||||||
fn rust_raw_thread_delete(thread: *raw_thread);
|
lpParameter: LPVOID, dwCreationFlags: DWORD, lpThreadId: LPDWORD) -> HANDLE;
|
||||||
|
fn WaitForSingleObject(hHandle: HANDLE, dwMilliseconds: DWORD) -> DWORD;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(windows, target_arch = "x86_64")]
|
||||||
|
extern {
|
||||||
|
fn CreateThread(lpThreadAttributes: LPSECURITY_ATTRIBUTES, dwStackSize: SIZE_T,
|
||||||
|
lpStartAddress: extern "C" fn(*libc::c_void) -> rust_thread_return,
|
||||||
|
lpParameter: LPVOID, dwCreationFlags: DWORD, lpThreadId: LPDWORD) -> HANDLE;
|
||||||
|
fn WaitForSingleObject(hHandle: HANDLE, dwMilliseconds: DWORD) -> DWORD;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
extern {
|
||||||
|
fn pthread_create(native: *mut libc::pthread_t, attr: *libc::pthread_attr_t,
|
||||||
|
f: extern "C" fn(*libc::c_void) -> rust_thread_return,
|
||||||
|
value: *libc::c_void) -> libc::c_int;
|
||||||
|
fn pthread_join(native: libc::pthread_t, value: **libc::c_void) -> libc::c_int;
|
||||||
|
fn pthread_attr_init(attr: *mut libc::pthread_attr_t) -> libc::c_int;
|
||||||
|
fn pthread_attr_setstacksize(attr: *mut libc::pthread_attr_t,
|
||||||
|
stack_size: libc::size_t) -> libc::c_int;
|
||||||
|
fn pthread_attr_setdetachstate(attr: *mut libc::pthread_attr_t,
|
||||||
|
state: libc::c_int) -> libc::c_int;
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,6 @@
|
|||||||
/* Foreign builtins. */
|
/* Foreign builtins. */
|
||||||
|
|
||||||
#include "rust_util.h"
|
#include "rust_util.h"
|
||||||
#include "sync/rust_thread.h"
|
|
||||||
#include "sync/lock_and_signal.h"
|
#include "sync/lock_and_signal.h"
|
||||||
#include "vg/valgrind.h"
|
#include "vg/valgrind.h"
|
||||||
|
|
||||||
@ -385,42 +384,6 @@ rust_signal_little_lock(lock_and_signal *lock) {
|
|||||||
lock->signal();
|
lock->signal();
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef void(startfn)(void*, void*);
|
|
||||||
|
|
||||||
class raw_thread: public rust_thread {
|
|
||||||
public:
|
|
||||||
startfn *raw_start;
|
|
||||||
void *rust_fn;
|
|
||||||
void *rust_env;
|
|
||||||
|
|
||||||
raw_thread(startfn *raw_start, void *rust_fn, void *rust_env)
|
|
||||||
: raw_start(raw_start), rust_fn(rust_fn), rust_env(rust_env) { }
|
|
||||||
|
|
||||||
virtual void run() {
|
|
||||||
raw_start(rust_fn, rust_env);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
extern "C" raw_thread*
|
|
||||||
rust_raw_thread_start(startfn *raw_start, void *rust_start, void *rust_env) {
|
|
||||||
assert(raw_start && rust_start);
|
|
||||||
raw_thread *thread = new raw_thread(raw_start, rust_start, rust_env);
|
|
||||||
thread->start();
|
|
||||||
return thread;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" void
|
|
||||||
rust_raw_thread_join(raw_thread *thread) {
|
|
||||||
assert(thread);
|
|
||||||
thread->join();
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" void
|
|
||||||
rust_raw_thread_delete(raw_thread *thread) {
|
|
||||||
assert(thread);
|
|
||||||
delete thread;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
|
@ -42,9 +42,6 @@ rust_signal_little_lock
|
|||||||
rust_wait_little_lock
|
rust_wait_little_lock
|
||||||
tdefl_compress_mem_to_heap
|
tdefl_compress_mem_to_heap
|
||||||
tinfl_decompress_mem_to_heap
|
tinfl_decompress_mem_to_heap
|
||||||
rust_raw_thread_start
|
|
||||||
rust_raw_thread_join
|
|
||||||
rust_raw_thread_delete
|
|
||||||
swap_registers
|
swap_registers
|
||||||
rust_readdir
|
rust_readdir
|
||||||
rust_opendir
|
rust_opendir
|
||||||
|
@ -1,65 +0,0 @@
|
|||||||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
|
|
||||||
#include "rust_thread.h"
|
|
||||||
#include <limits.h>
|
|
||||||
|
|
||||||
const size_t default_stack_sz = 1024*1024;
|
|
||||||
|
|
||||||
rust_thread::rust_thread() : thread(0) {
|
|
||||||
}
|
|
||||||
|
|
||||||
rust_thread::~rust_thread() {
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(__WIN32__)
|
|
||||||
static DWORD WINAPI
|
|
||||||
#elif defined(__GNUC__)
|
|
||||||
static void *
|
|
||||||
#else
|
|
||||||
#error "Platform not supported"
|
|
||||||
#endif
|
|
||||||
rust_thread_start(void *ptr) {
|
|
||||||
rust_thread *thread = (rust_thread *) ptr;
|
|
||||||
thread->run();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
rust_thread::start() {
|
|
||||||
#if defined(__WIN32__)
|
|
||||||
thread = CreateThread(NULL, default_stack_sz, rust_thread_start, this, 0, NULL);
|
|
||||||
#else
|
|
||||||
// PTHREAD_STACK_MIN of some system is larger than default size
|
|
||||||
// so we check stack_sz to prevent assertion failure.
|
|
||||||
size_t stack_sz = default_stack_sz;
|
|
||||||
if (stack_sz < PTHREAD_STACK_MIN) {
|
|
||||||
stack_sz = PTHREAD_STACK_MIN;
|
|
||||||
}
|
|
||||||
pthread_attr_t attr;
|
|
||||||
CHECKED(pthread_attr_init(&attr));
|
|
||||||
CHECKED(pthread_attr_setstacksize(&attr, stack_sz));
|
|
||||||
CHECKED(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE));
|
|
||||||
CHECKED(pthread_create(&thread, &attr, rust_thread_start, (void *) this));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
rust_thread::join() {
|
|
||||||
#if defined(__WIN32__)
|
|
||||||
if (thread)
|
|
||||||
WaitForSingleObject(thread, INFINITE);
|
|
||||||
#else
|
|
||||||
if (thread)
|
|
||||||
CHECKED(pthread_join(thread, NULL));
|
|
||||||
#endif
|
|
||||||
thread = 0;
|
|
||||||
}
|
|
@ -1,38 +0,0 @@
|
|||||||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
#ifndef RUST_THREAD_H
|
|
||||||
#define RUST_THREAD_H
|
|
||||||
|
|
||||||
#include "rust_globals.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Thread utility class. Derive and implement your own run() method.
|
|
||||||
*/
|
|
||||||
class rust_thread {
|
|
||||||
private:
|
|
||||||
#if defined(__WIN32__)
|
|
||||||
HANDLE thread;
|
|
||||||
#else
|
|
||||||
pthread_t thread;
|
|
||||||
#endif
|
|
||||||
public:
|
|
||||||
|
|
||||||
rust_thread();
|
|
||||||
virtual ~rust_thread();
|
|
||||||
|
|
||||||
void start();
|
|
||||||
|
|
||||||
virtual void run() = 0;
|
|
||||||
|
|
||||||
void join();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* RUST_THREAD_H */
|
|
Loading…
Reference in New Issue
Block a user