Skip to content

Correctly set and restore the TLV and remove the Cargo feature for it #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 9 commits into from
14 changes: 7 additions & 7 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
[package]
name = "rayon"
name = "rustc-rayon"
# Reminder to update html_rool_url in lib.rs when updating version
version = "1.0.3"
version = "0.1.3"
authors = ["Niko Matsakis <[email protected]>",
"Josh Stone <[email protected]>"]
description = "Simple work-stealing parallelism for Rust"
description = "Simple work-stealing parallelism for Rust - fork for rustc"
license = "Apache-2.0/MIT"
repository = "https://github.com/rayon-rs/rayon"
documentation = "https://docs.rs/rayon/"
repository = "https://github.com/rust-lang/rustc-rayon"
documentation = "https://docs.rs/rustc-rayon/"
readme = "README.md"
keywords = ["parallel", "thread", "concurrency", "join", "performance"]
categories = ["concurrency"]
build = "build.rs"
exclude = ["/ci/*", "/scripts/*", "/.travis.yml", "/appveyor.yml", "/bors.toml"]

[workspace]
members = ["rayon-demo", "rayon-core", "rayon-futures"]
members = ["rayon-core"]
exclude = ["ci"]

[dependencies]
rayon-core = { version = "1.4", path = "rayon-core" }
rustc-rayon-core = { version = "0.1", path = "rayon-core" }
crossbeam-deque = "0.2.0"

# This is a public dependency!
Expand Down
126 changes: 3 additions & 123 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,130 +1,10 @@
# Rayon
# rustc-rayon

[![Rayon crate](https://img.shields.io/crates/v/rayon.svg)](https://crates.io/crates/rayon)
[![Rayon documentation](https://docs.rs/rayon/badge.svg)](https://docs.rs/rayon)
[![Travis Status](https://travis-ci.org/rayon-rs/rayon.svg?branch=master)](https://travis-ci.org/rayon-rs/rayon)
[![Appveyor status](https://ci.appveyor.com/api/projects/status/wre5dkx08gayy8hc/branch/master?svg=true)](https://ci.appveyor.com/project/cuviper/rayon/branch/master)
[![Join the chat at https://gitter.im/rayon-rs/Lobby](https://badges.gitter.im/rayon-rs/Lobby.svg)](https://gitter.im/rayon-rs/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)

Rayon is a data-parallelism library for Rust. It is extremely
lightweight and makes it easy to convert a sequential computation into
a parallel one. It also guarantees data-race freedom. (You may also
enjoy [this blog post][blog] about Rayon, which gives more background
and details about how it works, or [this video][video], from the Rust
Belt Rust conference.) Rayon is
[available on crates.io](https://crates.io/crates/rayon), and
[API Documentation is available on docs.rs](https://docs.rs/rayon/).

[blog]: http://smallcultfollowing.com/babysteps/blog/2015/12/18/rayon-data-parallelism-in-rust/
[video]: https://www.youtube.com/watch?v=gof_OEv71Aw

## Parallel iterators and more

Rayon makes it drop-dead simple to convert sequential iterators into
parallel ones: usually, you just change your `foo.iter()` call into
`foo.par_iter()`, and Rayon does the rest:

```rust
use rayon::prelude::*;
fn sum_of_squares(input: &[i32]) -> i32 {
input.par_iter() // <-- just change that!
.map(|&i| i * i)
.sum()
}
```

[Parallel iterators] take care of deciding how to divide your data
into tasks; it will dynamically adapt for maximum performance. If you
need more flexibility than that, Rayon also offers the [join] and
[scope] functions, which let you create parallel tasks on your own.
For even more control, you can create [custom threadpools] rather than
using Rayon's default, global threadpool.

[Parallel iterators]: https://docs.rs/rayon/*/rayon/iter/index.html
[join]: https://docs.rs/rayon/*/rayon/fn.join.html
[scope]: https://docs.rs/rayon/*/rayon/fn.scope.html
[custom threadpools]: https://docs.rs/rayon/*/rayon/struct.ThreadPool.html

## No data races

You may have heard that parallel execution can produce all kinds of
crazy bugs. Well, rest easy. Rayon's APIs all guarantee **data-race
freedom**, which generally rules out most parallel bugs (though not
all). In other words, **if your code compiles**, it typically does the
same thing it did before.

For the most, parallel iterators in particular are guaranteed to
produce the same results as their sequential counterparts. One caveat:
If your iterator has side effects (for example, sending methods to
other threads through a [Rust channel] or writing to disk), those side
effects may occur in a different order. Note also that, in some cases,
parallel iterators offer alternative versions of the sequential
iterator methods that can have higher performance.

[Rust channel]: https://doc.rust-lang.org/std/sync/mpsc/fn.channel.html

## Using Rayon

[Rayon is available on crates.io](https://crates.io/crates/rayon). The
recommended way to use it is to add a line into your Cargo.toml such
as:

```toml
[dependencies]
rayon = "1.0"
```

and then add the following to to your `lib.rs`:

```rust
extern crate rayon;
```

To use the Parallel Iterator APIs, a number of traits have to be in
scope. The easiest way to bring those things into scope is to use the
[Rayon prelude](https://docs.rs/rayon/*/rayon/prelude/index.html). In
each module where you would like to use the parallel iterator APIs,
just add:

```rust
use rayon::prelude::*;
```

Rayon currently requires `rustc 1.13.0` or greater.

## Contribution

Rayon is an open source project! If you'd like to contribute to Rayon, check out [the list of "help wanted" issues](https://github.com/rayon-rs/rayon/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22). These are all (or should be) issues that are suitable for getting started, and they generally include a detailed set of instructions for what to do. Please ask questions if anything is unclear! Also, check out the [Guide to Development](https://github.com/rayon-rs/rayon/wiki/Guide-to-Development) page on the wiki. Note that all code submitted in PRs to Rayon is assumed to [be licensed under Rayon's dual MIT/Apache2 licensing](https://github.com/rayon-rs/rayon/blob/master/README.md#license).

## Quick demo

To see Rayon in action, check out the `rayon-demo` directory, which
includes a number of demos of code using Rayon. For example, run this
command to get a visualization of an nbody simulation. To see the
effect of using Rayon, press `s` to run sequentially and `p` to run in
parallel.

```
> cd rayon-demo
> cargo run --release -- nbody visualize
```

For more information on demos, try:

```
> cd rayon-demo
> cargo run --release -- --help
```

## Other questions?

See [the Rayon FAQ][faq].

[faq]: https://github.com/rayon-rs/rayon/blob/master/FAQ.md
rustc-rayon is a fork of [the Rayon crate](https://github.com/rayon-rs/rayon/). It adds a few "in progress" features that rustc is using, mostly around deadlock detection. These features are not stable and should not be used by others -- though they may find their way into rayon proper at some point. In general, if you are not rustc, you should be using the real rayon crate, not rustc-rayon. =)

## License

Rayon is distributed under the terms of both the MIT license and the
rustc-rayon is a fork of rayon. rayon is distributed under the terms of both the MIT license and the
Apache License (Version 2.0). See [LICENSE-APACHE](LICENSE-APACHE) and
[LICENSE-MIT](LICENSE-MIT) for details. Opening a pull requests is
assumed to signal agreement with these licensing terms.
11 changes: 5 additions & 6 deletions rayon-core/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
[package]
name = "rayon-core"
version = "1.4.1" # reminder to update html_root_url attribute
name = "rustc-rayon-core"
version = "0.1.3" # reminder to update html_root_url attribute
authors = ["Niko Matsakis <[email protected]>",
"Josh Stone <[email protected]>"]
description = "Core APIs for Rayon"
description = "Core APIs for Rayon - fork for rustc"
license = "Apache-2.0/MIT"
repository = "https://github.com/rayon-rs/rayon"
documentation = "https://docs.rs/rayon/"
links = "rayon-core"
repository = "https://github.com/rust-lang/rustc-rayon"
documentation = "https://docs.rs/rustc-rayon-core/"
build = "build.rs"
readme = "README.md"
keywords = ["parallel", "thread", "concurrency", "join", "performance"]
Expand Down
2 changes: 2 additions & 0 deletions rayon-core/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
Note: This is an unstable fork made for use in rustc

Rayon-core represents the "core, stable" APIs of Rayon: join, scope, and so forth, as well as the ability to create custom thread-pools with ThreadPool.

Maybe worth mentioning: users are not necessarily intended to directly access rayon-core; all its APIs are mirror in the rayon crate. To that end, the examples in the docs use rayon::join and so forth rather than rayon_core::join.
Expand Down
11 changes: 9 additions & 2 deletions rayon-core/src/job.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::any::Any;
use std::cell::UnsafeCell;
use std::mem;
use unwind;
use tlv;

pub enum JobResult<T> {
None,
Expand Down Expand Up @@ -75,6 +76,7 @@ where
pub latch: L,
func: UnsafeCell<Option<F>>,
result: UnsafeCell<JobResult<R>>,
tlv: usize,
}

impl<L, F, R> StackJob<L, F, R>
Expand All @@ -83,11 +85,12 @@ where
F: FnOnce(bool) -> R + Send,
R: Send,
{
pub fn new(func: F, latch: L) -> StackJob<L, F, R> {
pub fn new(tlv: usize, func: F, latch: L) -> StackJob<L, F, R> {
StackJob {
latch: latch,
func: UnsafeCell::new(Some(func)),
result: UnsafeCell::new(JobResult::None),
tlv,
}
}

Expand All @@ -112,6 +115,7 @@ where
{
unsafe fn execute(this: *const Self) {
let this = &*this;
tlv::set(this.tlv);
let abort = unwind::AbortIfPanic;
let func = (*this.func.get()).take().unwrap();
(*this.result.get()) = match unwind::halt_unwinding(|| func(true)) {
Expand All @@ -134,15 +138,17 @@ where
BODY: FnOnce() + Send,
{
job: UnsafeCell<Option<BODY>>,
tlv: usize,
}

impl<BODY> HeapJob<BODY>
where
BODY: FnOnce() + Send,
{
pub fn new(func: BODY) -> Self {
pub fn new(tlv: usize, func: BODY) -> Self {
HeapJob {
job: UnsafeCell::new(Some(func)),
tlv,
}
}

Expand All @@ -161,6 +167,7 @@ where
{
unsafe fn execute(this: *const Self) {
let this: Box<Self> = mem::transmute(this);
tlv::set(this.tlv);
let job = (*this.job.get()).take().unwrap();
job();
}
Expand Down
17 changes: 16 additions & 1 deletion rayon-core/src/join/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use log::Event::*;
use registry::{self, WorkerThread};
use std::any::Any;
use unwind;
use tlv;

use FnContext;

Expand Down Expand Up @@ -120,10 +121,12 @@ where
worker: worker_thread.index()
});

let tlv = tlv::get();
// Create virtual wrapper for task b; this all has to be
// done here so that the stack frame can keep it all live
// long enough.
let job_b = StackJob::new(
tlv,
|migrated| oper_b(FnContext::new(migrated)),
SpinLatch::new(),
);
Expand All @@ -134,7 +137,7 @@ where
let status_a = unwind::halt_unwinding(move || oper_a(FnContext::new(injected)));
let result_a = match status_a {
Ok(v) => v,
Err(err) => join_recover_from_panic(worker_thread, &job_b.latch, err),
Err(err) => join_recover_from_panic(worker_thread, &job_b.latch, err, tlv),
};

// Now that task A has finished, try to pop job B from the
Expand All @@ -151,7 +154,11 @@ where
log!(PoppedRhs {
worker: worker_thread.index()
});
// Restore the TLV since we might have run some jobs overwriting it when waiting for job b.
tlv::set(tlv);

let result_b = job_b.run_inline(injected);

return (result_a, result_b);
} else {
log!(PoppedJob {
Expand All @@ -171,6 +178,9 @@ where
}
}

// Restore the TLV since we might have run some jobs overwriting it when waiting for job b.
tlv::set(tlv);

return (result_a, job_b.into_result());
})
}
Expand All @@ -183,7 +193,12 @@ unsafe fn join_recover_from_panic(
worker_thread: &WorkerThread,
job_b_latch: &SpinLatch,
err: Box<Any + Send>,
tlv: usize,
) -> ! {
worker_thread.wait_until(job_b_latch);

// Restore the TLV since we might have run some jobs overwriting it when waiting for job b.
tlv::set(tlv);

unwind::resume_unwinding(err)
}
Loading