Skip to content

Rollup of 7 pull requests #25711

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 15 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 44 additions & 42 deletions src/doc/trpl/dining-philosophers.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,28 @@

For our second project, let’s look at a classic concurrency problem. It’s
called ‘the dining philosophers’. It was originally conceived by Dijkstra in
1965, but we’ll use the version from [this paper][paper] by Tony Hoare in 1985.
1965, but we’ll use a lightly adapted version from [this paper][paper] by Tony
Hoare in 1985.

[paper]: http://www.usingcsp.com/cspbook.pdf

> In ancient times, a wealthy philanthropist endowed a College to accommodate
> five eminent philosophers. Each philosopher had a room in which she could
> engage in her professional activity of thinking; there was also a common
> five eminent philosophers. Each philosopher had a room in which they could
> engage in their professional activity of thinking; there was also a common
> dining room, furnished with a circular table, surrounded by five chairs, each
> labelled by the name of the philosopher who was to sit in it. They sat
> anticlockwise around the table. To the left of each philosopher there was
> laid a golden fork, and in the centre stood a large bowl of spaghetti, which
> was constantly replenished. A philosopher was expected to spend most of her
> time thinking; but when she felt hungry, she went to the dining room, sat down
> in her own chair, picked up her own fork on her left, and plunged it into the
> spaghetti. But such is the tangled nature of spaghetti that a second fork is
> required to carry it to the mouth. The philosopher therefore had also to pick
> up the fork on her right. When she was finished she would put down both her
> forks, get up from her chair, and continue thinking. Of course, a fork can be
> used by only one philosopher at a time. If the other philosopher wants it, she
> just has to wait until the fork is available again.
> was constantly replenished. A philosopher was expected to spend most of
> their time thinking; but when they felt hungry, they went to the dining
> room, sat down in their own chair, picked up their own fork on their left,
> and plunged it into the spaghetti. But such is the tangled nature of
> spaghetti that a second fork is required to carry it to the mouth. The
> philosopher therefore had also to pick up the fork on their right. When
> they were finished they would put down both their forks, get up from their
> chair, and continue thinking. Of course, a fork can be used by only one
> philosopher at a time. If the other philosopher wants it, they just have
> to wait until the fork is available again.

This classic problem shows off a few different elements of concurrency. The
reason is that it's actually slightly tricky to implement: a simple
Expand Down Expand Up @@ -60,10 +62,10 @@ impl Philosopher {
}

fn main() {
let p1 = Philosopher::new("Baruch Spinoza");
let p1 = Philosopher::new("Judith Butler");
let p2 = Philosopher::new("Gilles Deleuze");
let p3 = Philosopher::new("Karl Marx");
let p4 = Philosopher::new("Friedrich Nietzsche");
let p4 = Philosopher::new("Emma Goldman");
let p5 = Philosopher::new("Michel Foucault");
}
```
Expand Down Expand Up @@ -159,10 +161,10 @@ look at `main()` again:
# }
#
fn main() {
let p1 = Philosopher::new("Baruch Spinoza");
let p1 = Philosopher::new("Judith Butler");
let p2 = Philosopher::new("Gilles Deleuze");
let p3 = Philosopher::new("Karl Marx");
let p4 = Philosopher::new("Friedrich Nietzsche");
let p4 = Philosopher::new("Emma Goldman");
let p5 = Philosopher::new("Michel Foucault");
}
```
Expand All @@ -176,10 +178,10 @@ that `new()` function, it would look like this:
# name: String,
# }
fn main() {
let p1 = Philosopher { name: "Baruch Spinoza".to_string() };
let p1 = Philosopher { name: "Judith Butler".to_string() };
let p2 = Philosopher { name: "Gilles Deleuze".to_string() };
let p3 = Philosopher { name: "Karl Marx".to_string() };
let p4 = Philosopher { name: "Friedrich Nietzche".to_string() };
let p4 = Philosopher { name: "Emma Goldman".to_string() };
let p5 = Philosopher { name: "Michel Foucault".to_string() };
}
```
Expand Down Expand Up @@ -211,10 +213,10 @@ impl Philosopher {

fn main() {
let philosophers = vec![
Philosopher::new("Baruch Spinoza"),
Philosopher::new("Judith Butler"),
Philosopher::new("Gilles Deleuze"),
Philosopher::new("Karl Marx"),
Philosopher::new("Friedrich Nietzsche"),
Philosopher::new("Emma Goldman"),
Philosopher::new("Michel Foucault"),
];

Expand Down Expand Up @@ -247,10 +249,10 @@ mention they’re done eating. Running this program should give you the followin
output:

```text
Baruch Spinoza is done eating.
Judith Butler is done eating.
Gilles Deleuze is done eating.
Karl Marx is done eating.
Friedrich Nietzsche is done eating.
Emma Goldman is done eating.
Michel Foucault is done eating.
```

Expand Down Expand Up @@ -285,10 +287,10 @@ impl Philosopher {

fn main() {
let philosophers = vec![
Philosopher::new("Baruch Spinoza"),
Philosopher::new("Judith Butler"),
Philosopher::new("Gilles Deleuze"),
Philosopher::new("Karl Marx"),
Philosopher::new("Friedrich Nietzsche"),
Philosopher::new("Emma Goldman"),
Philosopher::new("Michel Foucault"),
];

Expand Down Expand Up @@ -323,14 +325,14 @@ simulate the time it takes a philosopher to eat.
If you run this program, you should see each philosopher eat in turn:

```text
Baruch Spinoza is eating.
Baruch Spinoza is done eating.
Judith Butler is eating.
Judith Butler is done eating.
Gilles Deleuze is eating.
Gilles Deleuze is done eating.
Karl Marx is eating.
Karl Marx is done eating.
Friedrich Nietzsche is eating.
Friedrich Nietzsche is done eating.
Emma Goldman is eating.
Emma Goldman is done eating.
Michel Foucault is eating.
Michel Foucault is done eating.
```
Expand Down Expand Up @@ -366,10 +368,10 @@ impl Philosopher {

fn main() {
let philosophers = vec![
Philosopher::new("Baruch Spinoza"),
Philosopher::new("Judith Butler"),
Philosopher::new("Gilles Deleuze"),
Philosopher::new("Karl Marx"),
Philosopher::new("Friedrich Nietzsche"),
Philosopher::new("Emma Goldman"),
Philosopher::new("Michel Foucault"),
];

Expand Down Expand Up @@ -458,11 +460,11 @@ We have multi-threading!
```text
Gilles Deleuze is eating.
Gilles Deleuze is done eating.
Friedrich Nietzsche is eating.
Friedrich Nietzsche is done eating.
Emma Goldman is eating.
Emma Goldman is done eating.
Michel Foucault is eating.
Baruch Spinoza is eating.
Baruch Spinoza is done eating.
Judith Butler is eating.
Judith Butler is done eating.
Karl Marx is eating.
Karl Marx is done eating.
Michel Foucault is done eating.
Expand Down Expand Up @@ -532,10 +534,10 @@ fn main() {
]});

let philosophers = vec![
Philosopher::new("Baruch Spinoza", 0, 1),
Philosopher::new("Judith Butler", 0, 1),
Philosopher::new("Gilles Deleuze", 1, 2),
Philosopher::new("Karl Marx", 2, 3),
Philosopher::new("Friedrich Nietzsche", 3, 4),
Philosopher::new("Emma Goldman", 3, 4),
Philosopher::new("Michel Foucault", 0, 4),
];

Expand Down Expand Up @@ -643,10 +645,10 @@ count will go up, and when each thread ends, it will go back down.

```rust,ignore
let philosophers = vec![
Philosopher::new("Baruch Spinoza", 0, 1),
Philosopher::new("Judith Butler", 0, 1),
Philosopher::new("Gilles Deleuze", 1, 2),
Philosopher::new("Karl Marx", 2, 3),
Philosopher::new("Friedrich Nietzsche", 3, 4),
Philosopher::new("Emma Goldman", 3, 4),
Philosopher::new("Michel Foucault", 0, 4),
];
```
Expand Down Expand Up @@ -679,12 +681,12 @@ and so you’ll get some output like this:

```text
Gilles Deleuze is eating.
Friedrich Nietzsche is eating.
Friedrich Nietzsche is done eating.
Emma Goldman is eating.
Emma Goldman is done eating.
Gilles Deleuze is done eating.
Baruch Spinoza is eating.
Judith Butler is eating.
Karl Marx is eating.
Baruch Spinoza is done eating.
Judith Butler is done eating.
Michel Foucault is eating.
Karl Marx is done eating.
Michel Foucault is done eating.
Expand Down
2 changes: 1 addition & 1 deletion src/liballoc/rc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@
//! // At the end of the method, gadget_owner, gadget1 and gadget2 get
//! // destroyed. There are now no strong (`Rc<T>`) references to the gadgets.
//! // Once they get destroyed, the Gadgets get destroyed. This zeroes the
//! // reference count on Gadget Man, so he gets destroyed as well.
//! // reference count on Gadget Man, they get destroyed as well.
//! }
//! ```

Expand Down
1 change: 0 additions & 1 deletion src/libcollections/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
#![feature(str_char)]
#![feature(str_words)]
#![feature(slice_patterns)]
#![feature(debug_builders)]
#![feature(utf8_error)]
#![cfg_attr(test, feature(rand, rustc_private, test, hash, collections,
collections_drain, collections_range))]
Expand Down
31 changes: 18 additions & 13 deletions src/libcore/fmt/builders.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ impl<'a, 'b: 'a> fmt::Write for PadAdapter<'a, 'b> {
///
/// Constructed by the `Formatter::debug_struct` method.
#[must_use]
#[stable(feature = "debug_builders", since = "1.2.0")]
pub struct DebugStruct<'a, 'b: 'a> {
fmt: &'a mut fmt::Formatter<'b>,
result: fmt::Result,
Expand All @@ -72,7 +73,7 @@ pub fn debug_struct_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>, name: &str)

impl<'a, 'b: 'a> DebugStruct<'a, 'b> {
/// Adds a new field to the generated struct output.
#[unstable(feature = "debug_builders", reason = "method was just created")]
#[stable(feature = "debug_builders", since = "1.2.0")]
pub fn field(&mut self, name: &str, value: &fmt::Debug) -> &mut DebugStruct<'a, 'b> {
self.result = self.result.and_then(|_| {
let prefix = if self.has_fields {
Expand All @@ -94,7 +95,7 @@ impl<'a, 'b: 'a> DebugStruct<'a, 'b> {
}

/// Finishes output and returns any error encountered.
#[unstable(feature = "debug_builders", reason = "method was just created")]
#[stable(feature = "debug_builders", since = "1.2.0")]
pub fn finish(&mut self) -> fmt::Result {
if self.has_fields {
self.result = self.result.and_then(|_| {
Expand All @@ -117,6 +118,7 @@ impl<'a, 'b: 'a> DebugStruct<'a, 'b> {
///
/// Constructed by the `Formatter::debug_tuple` method.
#[must_use]
#[stable(feature = "debug_builders", since = "1.2.0")]
pub struct DebugTuple<'a, 'b: 'a> {
fmt: &'a mut fmt::Formatter<'b>,
result: fmt::Result,
Expand All @@ -134,7 +136,7 @@ pub fn debug_tuple_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>, name: &str) -> D

impl<'a, 'b: 'a> DebugTuple<'a, 'b> {
/// Adds a new field to the generated tuple struct output.
#[unstable(feature = "debug_builders", reason = "method was just created")]
#[stable(feature = "debug_builders", since = "1.2.0")]
pub fn field(&mut self, value: &fmt::Debug) -> &mut DebugTuple<'a, 'b> {
self.result = self.result.and_then(|_| {
let (prefix, space) = if self.has_fields {
Expand All @@ -156,7 +158,7 @@ impl<'a, 'b: 'a> DebugTuple<'a, 'b> {
}

/// Finishes output and returns any error encountered.
#[unstable(feature = "debug_builders", reason = "method was just created")]
#[stable(feature = "debug_builders", since = "1.2.0")]
pub fn finish(&mut self) -> fmt::Result {
if self.has_fields {
self.result = self.result.and_then(|_| {
Expand Down Expand Up @@ -211,6 +213,7 @@ impl<'a, 'b: 'a> DebugInner<'a, 'b> {
///
/// Constructed by the `Formatter::debug_set` method.
#[must_use]
#[stable(feature = "debug_builders", since = "1.2.0")]
pub struct DebugSet<'a, 'b: 'a> {
inner: DebugInner<'a, 'b>,
}
Expand All @@ -228,14 +231,14 @@ pub fn debug_set_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugSet<'a, 'b

impl<'a, 'b: 'a> DebugSet<'a, 'b> {
/// Adds a new entry to the set output.
#[unstable(feature = "debug_builders", reason = "method was just created")]
#[stable(feature = "debug_builders", since = "1.2.0")]
pub fn entry(&mut self, entry: &fmt::Debug) -> &mut DebugSet<'a, 'b> {
self.inner.entry(entry);
self
}

/// Adds the contents of an iterator of entries to the set output.
#[unstable(feature = "debug_builders", reason = "method was just created")]
#[stable(feature = "debug_builders", since = "1.2.0")]
pub fn entries<D, I>(&mut self, entries: I) -> &mut DebugSet<'a, 'b>
where D: fmt::Debug, I: IntoIterator<Item=D> {
for entry in entries {
Expand All @@ -245,7 +248,7 @@ impl<'a, 'b: 'a> DebugSet<'a, 'b> {
}

/// Finishes output and returns any error encountered.
#[unstable(feature = "debug_builders", reason = "method was just created")]
#[stable(feature = "debug_builders", since = "1.2.0")]
pub fn finish(&mut self) -> fmt::Result {
self.inner.finish();
self.inner.result.and_then(|_| self.inner.fmt.write_str("}"))
Expand All @@ -256,6 +259,7 @@ impl<'a, 'b: 'a> DebugSet<'a, 'b> {
///
/// Constructed by the `Formatter::debug_list` method.
#[must_use]
#[stable(feature = "debug_builders", since = "1.2.0")]
pub struct DebugList<'a, 'b: 'a> {
inner: DebugInner<'a, 'b>,
}
Expand All @@ -273,14 +277,14 @@ pub fn debug_list_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugList<'a,

impl<'a, 'b: 'a> DebugList<'a, 'b> {
/// Adds a new entry to the list output.
#[unstable(feature = "debug_builders", reason = "method was just created")]
#[stable(feature = "debug_builders", since = "1.2.0")]
pub fn entry(&mut self, entry: &fmt::Debug) -> &mut DebugList<'a, 'b> {
self.inner.entry(entry);
self
}

/// Adds the contents of an iterator of entries to the list output.
#[unstable(feature = "debug_builders", reason = "method was just created")]
#[stable(feature = "debug_builders", since = "1.2.0")]
pub fn entries<D, I>(&mut self, entries: I) -> &mut DebugList<'a, 'b>
where D: fmt::Debug, I: IntoIterator<Item=D> {
for entry in entries {
Expand All @@ -290,7 +294,7 @@ impl<'a, 'b: 'a> DebugList<'a, 'b> {
}

/// Finishes output and returns any error encountered.
#[unstable(feature = "debug_builders", reason = "method was just created")]
#[stable(feature = "debug_builders", since = "1.2.0")]
pub fn finish(&mut self) -> fmt::Result {
self.inner.finish();
self.inner.result.and_then(|_| self.inner.fmt.write_str("]"))
Expand All @@ -301,6 +305,7 @@ impl<'a, 'b: 'a> DebugList<'a, 'b> {
///
/// Constructed by the `Formatter::debug_map` method.
#[must_use]
#[stable(feature = "debug_builders", since = "1.2.0")]
pub struct DebugMap<'a, 'b: 'a> {
fmt: &'a mut fmt::Formatter<'b>,
result: fmt::Result,
Expand All @@ -318,7 +323,7 @@ pub fn debug_map_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugMap<'a, 'b

impl<'a, 'b: 'a> DebugMap<'a, 'b> {
/// Adds a new entry to the map output.
#[unstable(feature = "debug_builders", reason = "method was just created")]
#[stable(feature = "debug_builders", since = "1.2.0")]
pub fn entry(&mut self, key: &fmt::Debug, value: &fmt::Debug) -> &mut DebugMap<'a, 'b> {
self.result = self.result.and_then(|_| {
if self.is_pretty() {
Expand All @@ -336,7 +341,7 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> {
}

/// Adds the contents of an iterator of entries to the map output.
#[unstable(feature = "debug_builders", reason = "method was just created")]
#[stable(feature = "debug_builders", since = "1.2.0")]
pub fn entries<K, V, I>(&mut self, entries: I) -> &mut DebugMap<'a, 'b>
where K: fmt::Debug, V: fmt::Debug, I: IntoIterator<Item=(K, V)> {
for (k, v) in entries {
Expand All @@ -346,7 +351,7 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> {
}

/// Finishes output and returns any error encountered.
#[unstable(feature = "debug_builders", reason = "method was just created")]
#[stable(feature = "debug_builders", since = "1.2.0")]
pub fn finish(&mut self) -> fmt::Result {
let prefix = if self.is_pretty() && self.has_fields { "\n" } else { "" };
self.result.and_then(|_| write!(self.fmt, "{}}}", prefix))
Expand Down
Loading