Skip to content
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