Skip to content

Commit 8fc20f7

Browse files
committed
Make threads work
1 parent 0a371b5 commit 8fc20f7

File tree

4 files changed

+207
-61
lines changed

4 files changed

+207
-61
lines changed

Cargo.lock

+24-19
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

example/std_example.rs

+4
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ fn main() {
1111
let stderr = ::std::io::stderr();
1212
let mut stderr = stderr.lock();
1313

14+
std::thread::spawn(move || {
15+
println!("Hello from another thread!");
16+
});
17+
1418
writeln!(stderr, "some {} text", "<unknown>").unwrap();
1519

1620
let _ = std::process::Command::new("true").env("c", "d").spawn();

patches/0015-Remove-usage-of-unsized-locals.patch

+5-42
Original file line numberDiff line numberDiff line change
@@ -44,53 +44,16 @@ index f6dee7c..0c6a8c0 100644
4444
#[unstable(feature = "coerce_unsized", issue = "27732")]
4545
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Box<U>> for Box<T> {}
4646

47-
diff --git a/src/libstd/sys_common/at_exit_imp.rs b/src/libstd/sys_common/at_exit_imp.rs
48-
index 1181b86..20f9251 100644
49-
--- a/src/libstd/sys_common/at_exit_imp.rs
50-
+++ b/src/libstd/sys_common/at_exit_imp.rs
51-
@@ -38,6 +38,7 @@ unsafe fn init() -> bool {
52-
true
53-
}
54-
55-
+/*
56-
pub fn cleanup() {
57-
for i in 1..=ITERS {
58-
unsafe {
59-
@@ -60,6 +61,7 @@ pub fn cleanup() {
60-
}
61-
}
62-
}
63-
+*/
64-
65-
pub fn push(f: Box<dyn FnOnce()>) -> bool {
66-
unsafe {
67-
diff --git a/src/libstd/sys_common/mod.rs b/src/libstd/sys_common/mod.rs
68-
index 6260c3b..611ed7e 100644
69-
--- a/src/libstd/sys_common/mod.rs
70-
+++ b/src/libstd/sys_common/mod.rs
71-
@@ -127,7 +127,6 @@ pub fn cleanup() {
72-
CLEANUP.call_once(|| unsafe {
73-
sys::args::cleanup();
74-
sys::stack_overflow::cleanup();
75-
- at_exit_imp::cleanup();
76-
});
77-
}
78-
7947
diff --git a/src/libstd/sys_common/thread.rs b/src/libstd/sys_common/thread.rs
8048
index b2142e7..718bb1c 100644
8149
--- a/src/libstd/sys_common/thread.rs
8250
+++ b/src/libstd/sys_common/thread.rs
83-
@@ -6,12 +6,7 @@ use crate::sys::thread as imp;
51+
@@ -6,7 +6,7 @@ pub unsafe fn start_thread(main: *mut u8) {
52+
let _handler = stack_overflow::Handler::new();
8453

85-
#[allow(dead_code)]
86-
pub unsafe fn start_thread(main: *mut u8) {
87-
- // Next, set up our stack overflow handler which may get triggered if we run
88-
- // out of stack.
89-
- let _handler = stack_overflow::Handler::new();
90-
-
91-
- // Finally, let's run some code.
54+
// Finally, let's run some code.
9255
- Box::from_raw(main as *mut Box<dyn FnOnce()>)()
93-
+ panic!("Threads are not yet supported, because cranelift doesn't support atomics.");
56+
+ Box::from_raw(main as *mut Box<dyn FnBox()>)()
9457
}
9558

9659
pub fn min_stack() -> usize {
@@ -102,7 +65,7 @@ index f4a1783..362b537 100644
10265
// unsafe: see thread::Builder::spawn_unchecked for safety requirements
10366
pub unsafe fn new(stack: usize, p: Box<dyn FnOnce()>)
10467
-> io::Result<Thread> {
105-
+ panic!("Threads are not yet supported, because cranelift doesn't support atomics.");
68+
+ panic!("Warning: Threads are not yet fully supported, because cranelift doesn't support atomics.");
10669
+
10770
let p = box p;
10871
let mut native: libc::pthread_t = mem::zeroed();

patches/0018-Add-FnBox-back.patch

+174
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
From 8617310c3c9e192080df6a0c7b4835d3f02e27b9 Mon Sep 17 00:00:00 2001
2+
From: bjorn3 <[email protected]>
3+
Date: Fri, 1 Nov 2019 20:58:30 +0100
4+
Subject: [PATCH] Add FnBox back
5+
6+
---
7+
src/liballoc/boxed.rs | 13 +++++++++++++
8+
src/libstd/prelude/v1.rs | 2 +-
9+
src/libstd/sys/cloudabi/thread.rs | 2 +-
10+
src/libstd/sys/hermit/thread.rs | 4 ++--
11+
src/libstd/sys/unix/thread.rs | 4 ++--
12+
src/libstd/sys_common/at_exit_imp.rs | 6 +++---
13+
src/libstd/sys_common/mod.rs | 2 +-
14+
src/libstd/sys_common/thread.rs | 2 +-
15+
src/libstd/thread/mod.rs | 2 +-
16+
9 files changed, 25 insertions(+), 12 deletions(-)
17+
18+
diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs
19+
index ef9b648..e32b870 100644
20+
--- a/src/liballoc/boxed.rs
21+
+++ b/src/liballoc/boxed.rs
22+
@@ -1079,3 +1079,16 @@ impl<F: ?Sized + Future + Unpin> Future for Box<F> {
23+
F::poll(Pin::new(&mut *self), cx)
24+
}
25+
}
26+
+
27+
+#[stable(feature = "rust1", since = "1.0.0")]
28+
+pub trait FnBox<A>: FnOnce<A> {
29+
+ #[stable(feature = "rust1", since = "1.0.0")]
30+
+ extern "rust-call" fn call_box(self: Box<Self>, args: A) -> Self::Output;
31+
+}
32+
+
33+
+#[stable(feature = "rust1", since = "1.0.0")]
34+
+impl<A, F: FnOnce<A>> FnBox<A> for F {
35+
+ extern "rust-call" fn call_box(self: Box<Self>, args: A) -> Self::Output {
36+
+ <F as FnOnce<A>>::call_once(*self, args)
37+
+ }
38+
+}
39+
diff --git a/src/libstd/prelude/v1.rs b/src/libstd/prelude/v1.rs
40+
index 3e4cf91..1f50eb3 100644
41+
--- a/src/libstd/prelude/v1.rs
42+
+++ b/src/libstd/prelude/v1.rs
43+
@@ -94,7 +94,7 @@ pub use core::prelude::v1::{
44+
45+
#[stable(feature = "rust1", since = "1.0.0")]
46+
#[doc(no_inline)]
47+
-pub use crate::boxed::Box;
48+
+pub use crate::boxed::{Box, FnBox};
49+
#[stable(feature = "rust1", since = "1.0.0")]
50+
#[doc(no_inline)]
51+
pub use crate::borrow::ToOwned;
52+
diff --git a/src/libstd/sys/cloudabi/thread.rs b/src/libstd/sys/cloudabi/thread.rs
53+
index 240b6ea..6f71c6b 100644
54+
--- a/src/libstd/sys/cloudabi/thread.rs
55+
+++ b/src/libstd/sys/cloudabi/thread.rs
56+
@@ -21,7 +21,7 @@ unsafe impl Sync for Thread {}
57+
58+
impl Thread {
59+
// unsafe: see thread::Builder::spawn_unchecked for safety requirements
60+
- pub unsafe fn new(stack: usize, p: Box<dyn FnOnce()>) -> io::Result<Thread> {
61+
+ pub unsafe fn new(stack: usize, p: Box<dyn FnBox()>) -> io::Result<Thread> {
62+
let p = box p;
63+
let mut native: libc::pthread_t = mem::zeroed();
64+
let mut attr: libc::pthread_attr_t = mem::zeroed();
65+
diff --git a/src/libstd/sys/hermit/thread.rs b/src/libstd/sys/hermit/thread.rs
66+
index 99a9c83..b8bc392 100644
67+
--- a/src/libstd/sys/hermit/thread.rs
68+
+++ b/src/libstd/sys/hermit/thread.rs
69+
@@ -44,7 +44,7 @@ unsafe impl Sync for Thread {}
70+
pub const DEFAULT_MIN_STACK_SIZE: usize = 262144;
71+
72+
impl Thread {
73+
- pub unsafe fn new_with_coreid(_stack: usize, p: Box<dyn FnOnce()>, core_id: isize)
74+
+ pub unsafe fn new_with_coreid(_stack: usize, p: Box<dyn FnBox()>, core_id: isize)
75+
-> io::Result<Thread>
76+
{
77+
let p = box p;
78+
@@ -67,7 +67,7 @@ impl Thread {
79+
}
80+
}
81+
82+
- pub unsafe fn new(stack: usize, p: Box<dyn FnOnce()>)
83+
+ pub unsafe fn new(stack: usize, p: Box<dyn FnBox()>)
84+
-> io::Result<Thread>
85+
{
86+
Thread::new_with_coreid(stack, p, -1 /* = no specific core */)
87+
diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs
88+
index 143cf2f..a6e8faf 100644
89+
--- a/src/libstd/sys/unix/thread.rs
90+
+++ b/src/libstd/sys/unix/thread.rs
91+
@@ -38,9 +38,9 @@ unsafe fn pthread_attr_setstacksize(_attr: *mut libc::pthread_attr_t,
92+
93+
impl Thread {
94+
// unsafe: see thread::Builder::spawn_unchecked for safety requirements
95+
- pub unsafe fn new(stack: usize, p: Box<dyn FnOnce()>)
96+
+ pub unsafe fn new(stack: usize, p: Box<dyn FnBox()>)
97+
-> io::Result<Thread> {
98+
- panic!("Warning: Threads are not yet fully supported, because cranelift doesn't support atomics.");
99+
+ println!("Warning: Threads are not yet fully supported, because cranelift doesn't support atomics.");
100+
101+
let p = box p;
102+
let mut native: libc::pthread_t = mem::zeroed();
103+
diff --git a/src/libstd/sys_common/at_exit_imp.rs b/src/libstd/sys_common/at_exit_imp.rs
104+
index cdb72ee..e523333 100644
105+
--- a/src/libstd/sys_common/at_exit_imp.rs
106+
+++ b/src/libstd/sys_common/at_exit_imp.rs
107+
@@ -6,7 +6,7 @@ use crate::ptr;
108+
use crate::mem;
109+
use crate::sys_common::mutex::Mutex;
110+
111+
-type Queue = Vec<Box<dyn FnOnce()>>;
112+
+type Queue = Vec<Box<dyn FnBox()>>;
113+
114+
// NB these are specifically not types from `std::sync` as they currently rely
115+
// on poisoning and this module needs to operate at a lower level than requiring
116+
@@ -53,14 +53,14 @@ pub fn cleanup() {
117+
let queue: Box<Queue> = Box::from_raw(queue);
118+
for to_run in *queue {
119+
// We are not holding any lock, so reentrancy is fine.
120+
- to_run();
121+
+ to_run.call_box(());
122+
}
123+
}
124+
}
125+
}
126+
}
127+
128+
-pub fn push(f: Box<dyn FnOnce()>) -> bool {
129+
+pub fn push(f: Box<dyn FnBox()>) -> bool {
130+
unsafe {
131+
let _guard = LOCK.lock();
132+
if init() {
133+
diff --git a/src/libstd/sys_common/mod.rs b/src/libstd/sys_common/mod.rs
134+
index 7a0bcd0..668bef2 100644
135+
--- a/src/libstd/sys_common/mod.rs
136+
+++ b/src/libstd/sys_common/mod.rs
137+
@@ -113,7 +113,7 @@ pub trait FromInner<Inner> {
138+
/// closure will be run once the main thread exits. Returns `Err` to indicate
139+
/// that the closure could not be registered, meaning that it is not scheduled
140+
/// to be run.
141+
-pub fn at_exit<F: FnOnce() + Send + 'static>(f: F) -> Result<(), ()> {
142+
+pub fn at_exit<F: FnBox() + Send + 'static>(f: F) -> Result<(), ()> {
143+
if at_exit_imp::push(Box::new(f)) {Ok(())} else {Err(())}
144+
}
145+
146+
diff --git a/src/libstd/sys_common/thread.rs b/src/libstd/sys_common/thread.rs
147+
index c638be9..5c18a18 100644
148+
--- a/src/libstd/sys_common/thread.rs
149+
+++ b/src/libstd/sys_common/thread.rs
150+
@@ -10,7 +10,7 @@ pub unsafe fn start_thread(main: *mut u8) {
151+
let _handler = stack_overflow::Handler::new();
152+
153+
// Finally, let's run some code.
154+
- Box::from_raw(main as *mut Box<dyn FnBox()>)()
155+
+ Box::from_raw(main as *mut Box<dyn FnBox()>).call_box(())
156+
}
157+
158+
pub fn min_stack() -> usize {
159+
diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs
160+
index 0ffa6ac..4a3e3d6 100644
161+
--- a/src/libstd/thread/mod.rs
162+
+++ b/src/libstd/thread/mod.rs
163+
@@ -485,7 +485,7 @@ impl Builder {
164+
// returning.
165+
native: Some(imp::Thread::new(
166+
stack_size,
167+
- mem::transmute::<Box<dyn FnOnce() + 'a>, Box<dyn FnOnce() + 'static>>(Box::new(
168+
+ mem::transmute::<Box<dyn FnBox() + 'a>, Box<dyn FnBox() + 'static>>(Box::new(
169+
main,
170+
)),
171+
)?),
172+
--
173+
2.20.1
174+

0 commit comments

Comments
 (0)