Skip to content

Commit

Permalink
Merge #656
Browse files Browse the repository at this point in the history
656: Rust 1.26 and assorted cleanups r=nikomatsakis a=cuviper

In anticipation of [RFC 3](rayon-rs/rfcs#3), giving us a policy to soon raise our minimum to Rust 1.26, I started this branch to make the conversion. After the primary motivation of upgrading crossbeam, I also looked for ways to use newer language features.

Throughout all of this, the public API should be completely unaffected.

Closes #586 for newer crossbeam, even though we're not quite at the *newest*.

Co-authored-by: Josh Stone <cuviper@gmail.com>
  • Loading branch information
bors[bot] and cuviper committed May 8, 2019
2 parents 021d15f + bcfca1b commit 939d3ee
Show file tree
Hide file tree
Showing 105 changed files with 996 additions and 1,305 deletions.
10 changes: 2 additions & 8 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,13 @@ matrix:
fast_finish: true
include:
# NB: To help with CI delays, each `pull_request` is only tested on Linux,
# with 1.13 for compatibility and stable+rayon_unstable for broad test
# with 1.26 for compatibility and stable+rayon_unstable for broad test
# coverage. The bors bot counts as a `push` type, which will run it all.

- rust: 1.13.0
- rust: 1.26.0
os: linux
#if: everything!
script: cargo build
before_script:
# lazy_static 1.1 requires Rust 1.21+, so downgrade it.
# (and docopt 1.1 requires lazy_static 1.3)
- cargo generate-lockfile
- cargo update -p docopt --precise 1.0.2
- cargo update -p lazy_static --precise 1.0.2

- rust: stable
os: linux
Expand Down
7 changes: 3 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "rayon"
# Reminder to update html_rool_url in lib.rs when updating version
version = "1.0.3"
version = "1.1.0"
authors = ["Niko Matsakis <niko@alum.mit.edu>",
"Josh Stone <cuviper@gmail.com>"]
description = "Simple work-stealing parallelism for Rust"
Expand All @@ -11,16 +11,15 @@ documentation = "https://docs.rs/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"]
exclude = ["ci"]

[dependencies]
rayon-core = { version = "1.4.1", path = "rayon-core" }
crossbeam-deque = "0.2.0"
rayon-core = { version = "1.5.0", path = "rayon-core" }
crossbeam-deque = "0.6.3"

# This is a public dependency!
[dependencies.either]
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ just add:
use rayon::prelude::*;
```

Rayon currently requires `rustc 1.13.0` or greater.
Rayon currently requires `rustc 1.26.0` or greater.

## Contribution

Expand Down
33 changes: 0 additions & 33 deletions build.rs

This file was deleted.

4 changes: 2 additions & 2 deletions examples/cpu_monitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use docopt::Docopt;
use std::io;
use std::process;

const USAGE: &'static str = "
const USAGE: &str = "
Usage: cpu_monitor [options] <scenario>
cpu_monitor --help
Expand Down Expand Up @@ -76,7 +76,7 @@ fn tasks_ended(args: &Args) {
}

fn task_stall_root(args: &Args) {
rayon::join(|| task(args), || wait_for_user());
rayon::join(|| task(args), wait_for_user);
}

fn task_stall_scope(args: &Args) {
Expand Down
18 changes: 7 additions & 11 deletions rayon-core/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "rayon-core"
version = "1.4.1" # reminder to update html_root_url attribute
version = "1.5.0" # reminder to update html_root_url attribute
authors = ["Niko Matsakis <niko@alum.mit.edu>",
"Josh Stone <cuviper@gmail.com>"]
description = "Core APIs for Rayon"
Expand All @@ -13,24 +13,20 @@ readme = "README.md"
keywords = ["parallel", "thread", "concurrency", "join", "performance"]
categories = ["concurrency"]

# Some dependencies may not be their latest version, in order to support older rustc.
[dependencies]
num_cpus = "1.2"
libc = "0.2.16"
lazy_static = "1"

# This is deliberately not the latest version, because we want
# to support older rustc than crossbeam-deque 0.3+ does.
[dependencies.crossbeam-deque]
version = "0.2.0"

# Also held back for rustc compatibility
[dependencies.crossbeam]
version = "0.3.0"
crossbeam-deque = "0.6.3"
crossbeam-queue = "0.1.2"

[dev-dependencies]
rand = "0.6"
rand_xorshift = "0.1"

[target.'cfg(unix)'.dev-dependencies]
libc = "0.2"

[[test]]
name = "stack_overflow_crash"
path = "tests/stack_overflow_crash.rs"
Expand Down
2 changes: 1 addition & 1 deletion rayon-core/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ Please see [Rayon Docs] for details about using Rayon.

[Rayon Docs]: https://docs.rs/rayon/

Rayon-core currently requires `rustc 1.13.0` or greater.
Rayon-core currently requires `rustc 1.26.0` or greater.
13 changes: 3 additions & 10 deletions rayon-core/src/internal/worker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,8 @@ pub fn if_in_worker_thread<F, R>(if_true: F) -> Option<R>
where
F: FnOnce(&WorkerThread) -> R,
{
let worker_thread = registry::WorkerThread::current();
if worker_thread.is_null() {
None
} else {
unsafe {
let wt = WorkerThread {
thread: &*worker_thread,
};
Some(if_true(&wt))
}
unsafe {
let thread = registry::WorkerThread::current().as_ref()?;
Some(if_true(&WorkerThread { thread }))
}
}
53 changes: 23 additions & 30 deletions rayon-core/src/job.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use crossbeam::sync::SegQueue;
use crossbeam_queue::SegQueue;
use latch::Latch;
use std::any::Any;
use std::cell::UnsafeCell;
use std::mem;
use unwind;

pub enum JobResult<T> {
pub(super) enum JobResult<T> {
None,
Ok(T),
Panic(Box<Any + Send>),
Expand All @@ -16,7 +16,7 @@ pub enum JobResult<T> {
/// arranged in a deque, so that thieves can take from the top of the
/// deque while the main worker manages the bottom of the deque. This
/// deque is managed by the `thread_pool` module.
pub trait Job {
pub(super) trait Job {
/// Unsafe: this may be called from a different thread than the one
/// which scheduled the job, so the implementer must ensure the
/// appropriate traits are met, whether `Send`, `Sync`, or both.
Expand All @@ -30,7 +30,7 @@ pub trait Job {
/// true type is something like `*const StackJob<...>`, but we hide
/// it. We also carry the "execute fn" from the `Job` trait.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct JobRef {
pub(super) struct JobRef {
pointer: *const (),
execute_fn: unsafe fn(*const ()),
}
Expand All @@ -41,24 +41,21 @@ unsafe impl Sync for JobRef {}
impl JobRef {
/// Unsafe: caller asserts that `data` will remain valid until the
/// job is executed.
pub unsafe fn new<T>(data: *const T) -> JobRef
pub(super) unsafe fn new<T>(data: *const T) -> JobRef
where
T: Job,
{
let fn_ptr: unsafe fn(*const T) = <T as Job>::execute;

// erase types:
let fn_ptr: unsafe fn(*const ()) = mem::transmute(fn_ptr);
let pointer = data as *const ();

JobRef {
pointer: pointer,
execute_fn: fn_ptr,
pointer: data as *const (),
execute_fn: mem::transmute(fn_ptr),
}
}

#[inline]
pub unsafe fn execute(&self) {
pub(super) unsafe fn execute(&self) {
(self.execute_fn)(self.pointer)
}
}
Expand All @@ -67,13 +64,13 @@ impl JobRef {
/// executes it need not free any heap data, the cleanup occurs when
/// the stack frame is later popped. The function parameter indicates
/// `true` if the job was stolen -- executed on a different thread.
pub struct StackJob<L, F, R>
pub(super) struct StackJob<L, F, R>
where
L: Latch + Sync,
F: FnOnce(bool) -> R + Send,
R: Send,
{
pub latch: L,
pub(super) latch: L,
func: UnsafeCell<Option<F>>,
result: UnsafeCell<JobResult<R>>,
}
Expand All @@ -84,23 +81,23 @@ where
F: FnOnce(bool) -> R + Send,
R: Send,
{
pub fn new(func: F, latch: L) -> StackJob<L, F, R> {
pub(super) fn new(func: F, latch: L) -> StackJob<L, F, R> {
StackJob {
latch: latch,
latch,
func: UnsafeCell::new(Some(func)),
result: UnsafeCell::new(JobResult::None),
}
}

pub unsafe fn as_job_ref(&self) -> JobRef {
pub(super) unsafe fn as_job_ref(&self) -> JobRef {
JobRef::new(self)
}

pub unsafe fn run_inline(self, stolen: bool) -> R {
pub(super) unsafe fn run_inline(self, stolen: bool) -> R {
self.func.into_inner().unwrap()(stolen)
}

pub unsafe fn into_result(self) -> R {
pub(super) unsafe fn into_result(self) -> R {
self.result.into_inner().into_return_value()
}
}
Expand Down Expand Up @@ -130,7 +127,7 @@ where
/// signal that the job executed.
///
/// (Probably `StackJob` should be refactored in a similar fashion.)
pub struct HeapJob<BODY>
pub(super) struct HeapJob<BODY>
where
BODY: FnOnce() + Send,
{
Expand All @@ -141,7 +138,7 @@ impl<BODY> HeapJob<BODY>
where
BODY: FnOnce() + Send,
{
pub fn new(func: BODY) -> Self {
pub(super) fn new(func: BODY) -> Self {
HeapJob {
job: UnsafeCell::new(Some(func)),
}
Expand All @@ -150,7 +147,7 @@ where
/// Creates a `JobRef` from this job -- note that this hides all
/// lifetimes, so it is up to you to ensure that this JobRef
/// doesn't outlive any data that it closes over.
pub unsafe fn as_job_ref(self: Box<Self>) -> JobRef {
pub(super) unsafe fn as_job_ref(self: Box<Self>) -> JobRef {
let this: *const Self = mem::transmute(self);
JobRef::new(this)
}
Expand All @@ -172,7 +169,7 @@ impl<T> JobResult<T> {
/// its JobResult is populated) into its return value.
///
/// NB. This will panic if the job panicked.
pub fn into_return_value(self) -> T {
pub(super) fn into_return_value(self) -> T {
match self {
JobResult::None => unreachable!(),
JobResult::Ok(x) => x,
Expand All @@ -182,18 +179,18 @@ impl<T> JobResult<T> {
}

/// Indirect queue to provide FIFO job priority.
pub struct JobFifo {
pub(super) struct JobFifo {
inner: SegQueue<JobRef>,
}

impl JobFifo {
pub fn new() -> Self {
pub(super) fn new() -> Self {
JobFifo {
inner: SegQueue::new(),
}
}

pub unsafe fn push(&self, job_ref: JobRef) -> JobRef {
pub(super) unsafe fn push(&self, job_ref: JobRef) -> JobRef {
// A little indirection ensures that spawns are always prioritized in FIFO order. The
// jobs in a thread's deque may be popped from the back (LIFO) or stolen from the front
// (FIFO), but either way they will end up popping from the front of this queue.
Expand All @@ -205,10 +202,6 @@ impl JobFifo {
impl Job for JobFifo {
unsafe fn execute(this: *const Self) {
// We "execute" a queue by executing its first job, FIFO.
(*this)
.inner
.try_pop()
.expect("job in fifo queue")
.execute()
(*this).inner.pop().expect("job in fifo queue").execute()
}
}
2 changes: 1 addition & 1 deletion rayon-core/src/join/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ where
}
}

return (result_a, job_b.into_result());
(result_a, job_b.into_result())
})
}

Expand Down
Loading

0 comments on commit 939d3ee

Please sign in to comment.