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

Expand the documentation for the std::sync module #54078

Merged
merged 6 commits into from
Oct 6, 2018
Merged

Expand the documentation for the std::sync module #54078

merged 6 commits into from
Oct 6, 2018

Conversation

GabrielMajeri
Copy link
Contributor

I've tried to expand the documentation for Rust's synchronization primitives. The module level documentation explains why synchronization is required when working with a multiprocessor system,
and then links to the appropiate structure in this module.

Fixes #29377, since this should be the last item on the checklist (documentation for Atomic* was fixed in #44854, but not ticked off the checklist).

@rust-highfive
Copy link
Collaborator

r? @withoutboats

(rust_highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Sep 9, 2018
//! other types of concurrent primitives.
//! ## The need for synchronization
//!
//! On an ideal single-core CPU, the timeline of events happening in a program
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can have concurrency on a single core CPU.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do mention this possibility when talking about the need for compiler fences with signal handlers / interrupts in single-threaded programs.
I couldn't think of a better way to introduce the idea of sequential consistency / program order, in comparison to actual execution order (which is why I used "ideal", to indicate reality is a bit more complicated).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, I get where this paragraph is coming from, but agree it could be worded differently. I'm struggling a bit... I think the issues are:

  1. it's not clear that this is "ideal".
  2. This is phrased as being true, when the intention is to show that it's not true.

//! Considering the following code, operating on some global static variables:
//!
//! ```rust
//! # static mut A: u32 = 0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why hiding them? Also: they're not global since they're inside a function. If you don't declare the main function, then all code is put inside it (except extern crate declarations).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why hiding them?

I was trying to keep the example code clean and focus on the executed instructions. But I guess they won't hurt readability.

Also: they're not global since they're inside a function.

Thanks, should be fixed now.

@GuillaumeGomez
Copy link
Member

cc @rust-lang/docs

@XAMPPRocky
Copy link
Member

Tirage; @GuillaumeGomez What's the current status of the review of this PR?

@GuillaumeGomez
Copy link
Member

I'd like english native speakers to review.

//! other types of concurrent primitives.
//! ## The need for synchronization
//!
//! On an ideal single-core CPU, the timeline of events happening in a program
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, I get where this paragraph is coming from, but agree it could be worded differently. I'm struggling a bit... I think the issues are:

  1. it's not clear that this is "ideal".
  2. This is phrased as being true, when the intention is to show that it's not true.

//! updated.
//!
//! - the final result could be determined just by looking at the code at compile time,
//! so [constant folding] might turn the whole block into a simple `println!("7 4 4")`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These bullets should all be converted to sentences; capital letters and periods please!

Provides an overview on why synchronization is required,
as well a short summary of what sync primitives are available.
Because `fn main()` was added automatically, the variables
were actually local statics.
Reword the lead paragraph and turn the list items into
complete sentences.
@GabrielMajeri
Copy link
Contributor Author

r? @steveklabnik

I've rebased and then addressed the review comments. Thanks!

@rust-highfive
Copy link
Collaborator

The job x86_64-gnu-llvm-5.0 of your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.
[00:44:04] 
[00:44:04] warning: `[atomic::compiler_fence]` cannot be resolved, ignoring it...
[00:44:04]    --> libstd/sync/mod.rs:101:24
[00:44:04]     |
[00:44:04] 101 | //! [compiler fences]: atomic::compiler_fence
[00:44:04]     |
[00:44:04]     = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
[00:44:04] 
[00:44:04] warning: `[atomic::fence]` cannot be resolved, ignoring it...
[00:44:04] warning: `[atomic::fence]` cannot be resolved, ignoring it...
[00:44:04]    --> libstd/sync/mod.rs:104:22
[00:44:04]     |
[00:44:04] 104 | //! [memory fences]: atomic::fence
[00:44:04]     |
[00:44:04]     = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
[00:44:04] 
[00:44:04] 
[00:44:04] warning: `[mpsc]` cannot be resolved, ignoring it...
[00:44:04]    --> libstd/sync/mod.rs:133:17
[00:44:04]     |
[00:44:04] 133 | //! [channels]: mpsc
[00:44:04]     |
[00:44:04]     = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
[00:44:04] 
[00:44:04] warning: `[Mutex]` cannot be resolved, ignoring it...
[00:44:04] warning: `[Mutex]` cannot be resolved, ignoring it...
[00:44:04]    --> libstd/sync/mod.rs:122:6
[00:44:04]     |
[00:44:04] 122 | //! [`Mutex`] can involve blocking until another thread releases it.
[00:44:04]     |
[00:44:04]     = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
[00:44:04] 
[00:44:04] warning: `[RwLock]` cannot be resolved, ignoring it...
[00:44:04] warning: `[RwLock]` cannot be resolved, ignoring it...
[00:44:04]    --> libstd/sync/mod.rs:123:10
[00:44:04]     |
[00:44:04] 123 | //! For [`RwLock`], while! any number of readers may acquire it without
[00:44:04]     |
[00:44:04]     = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
[00:44:04] 
[00:44:04] warning: `[Weak::upgrade]` cannot be resolved, ignoring it...
---
[00:53:16] ....................................................................................................
[00:53:19] ...............................................................i....................................
[00:53:22] ....................................................................................................
[00:53:25] ....................................................................................................
[00:53:28] ............iiiiiiiii...............................................................................
[00:53:33] ....................................................................................................
[00:53:37] ................................................................................................i...
[00:53:39] ....................................................................................................
[00:53:42] ........................................................i.i..ii.....................................
---
[01:23:23] travis_fold:end:stage0-linkchecker

[01:23:23] travis_time:end:stage0-linkchecker:start=1538074295393550818,finish=1538074297751386313,duration=2357835495

[01:25:29] std/sync/index.html:65: broken link - std/sync/atomic::compiler_fence
[01:25:29] std/sync/index.html:79: broken link - std/sync/atomic::fence
[01:25:29] std/sync/index.html:100: directory link - std/sync/mpsc
[01:26:15] thread 'main' panicked at 'found some broken links', tools/linkchecker/main.rs:49:9
[01:26:15] 
[01:26:15] 
[01:26:15] command did not execute successfully: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-tools-bin/linkchecker" "/checkout/obj/build/x86_64-unknown-linux-gnu/doc"
[01:26:15] expected success, got: exit code: 101
[01:26:15] expected success, got: exit code: 101
[01:26:15] 
[01:26:15] 
[01:26:15] failed to run: /checkout/obj/build/bootstrap/debug/bootstrap test
[01:26:15] Build completed unsuccessfully in 0:41:25
[01:26:15] Makefile:58: recipe for target 'check' failed
[01:26:15] make: *** [check] Error 1

The command "stamp sh -x -c "$RUN_SCRIPT"" exited with 2.
travis_time:start:02446757
$ date && (curl -fs --head https://google.com | grep ^Date: | sed 's/Date: //g' || true)

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

src/libstd/sync/mod.rs Outdated Show resolved Hide resolved
@rust-highfive
Copy link
Collaborator

The job x86_64-gnu-llvm-5.0 of your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.
[00:54:48] ....................................................................................................
[00:54:51] ...............................................................i....................................
[00:54:53] ....................................................................................................
[00:54:57] ....................................................................................................
[00:54:59] ............iiiiiiiii...............................................................................
[00:55:05] ....................................................................................................
[00:55:08] ................................................................................................i...
[00:55:11] ....................................................................................................
[00:55:14] ........................................................i.i..ii.....................................
---
[01:26:06] travis_fold:end:stage0-linkchecker

[01:26:06] travis_time:end:stage0-linkchecker:start=1538080846403656929,finish=1538080848642144437,duration=2238487508

[01:28:13] std/sync/index.html:65: broken link - std/sync/std::sync::atomic::compiler_fence
[01:28:13] std/sync/index.html:79: broken link - std/sync/std::sync::atomic::fence
[01:28:13] std/sync/index.html:100: broken link - std/sync/std::sync::mpsc
[01:28:55] thread 'main' panicked at 'found some broken links', tools/linkchecker/main.rs:49:9
[01:28:55] 
[01:28:55] 
[01:28:55] command did not execute successfully: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-tools-bin/linkchecker" "/checkout/obj/build/x86_64-unknown-linux-gnu/doc"
[01:28:55] expected success, got: exit code: 101
[01:28:55] expected success, got: exit code: 101
[01:28:55] 
[01:28:55] 
[01:28:55] failed to run: /checkout/obj/build/bootstrap/debug/bootstrap test
[01:28:55] Build completed unsuccessfully in 0:42:57
[01:28:55] Makefile:58: recipe for target 'check' failed
[01:28:55] make: *** [check] Error 1
37756 ./src/tools/lldb/www
37080 ./obj/build/x86_64-unknown-linux-gnu/stage0-std/release
37064 ./obj/build/x86_64-unknown-linux-gnu/stage1-std/release
36376 ./.git/modules/src/libcompiler_builtins
---
travis_time:end:03b35bfc:start=1538081019791091137,finish=1538081019797722661,duration=6631524
travis_fold:end:after_failure.3
travis_fold:start:after_failure.4
travis_time:start:198b59ac
$ ln -s . checkout && for CORE in obj/cores/core.*; do EXE=$(echo $CORE | sed 's|obj/cores/core\.[0-9]*\.!checkout!\(.*\)|\1|;y|!|/|'); if [ -f "$EXE" ]; then printf travis_fold":start:crashlog\n\033[31;1m%s\033[0m\n" "$CORE"; gdb --batch -q -c "$CORE" "$EXE" -iex 'set auto-load off' -iex 'dir src/' -iex 'set sysroot .' -ex bt -ex q; echo travis_fold":"end:crashlog; fi; done || true
travis_fold:end:after_failure.4
travis_fold:start:after_failure.5
travis_time:start:00a6955a
travis_time:start:00a6955a
$ cat ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers || true
cat: ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers: No such file or directory
travis_fold:end:after_failure.5
travis_fold:start:after_failure.6
travis_time:start:14a625bf
$ dmesg | grep -i kill

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

Copy link
Member

@QuietMisdreavus QuietMisdreavus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall i think the docs here are fine for describing why you would need synchronization in the first place, but i don't think it does a good job describing the actual contents of the module. I feel like it spends a lot of time on low-level details like fences but doesn't spend much time on higher-level synchronization structures like Arc/Mutex/RwLock/channels/etc that a user is going to require more of the time. Most of the items in this module aren't meant to deal with single-threaded execution order, so outside of the documentation for compiler_fence it's no more than a curiosity. I'd appreciate it if the commonly-used items in this module (IMO, Arc, Mutex, channel, at least) were given more screen time, so to speak.

//! other types of concurrent primitives.
//! ## The need for synchronization
//!
//! Conceptually, a Rust program is simply a series of operations which will
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove the word "simply".

//! be executed on a computer. The timeline of events happening in the program
//! is consistent with the order of the operations in the code.
//!
//! Considering the following code, operating on some global static variables:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Consider the following code..." (please change tense of "Considering")

//! }
//! ```
//!
//! It appears _as if_ some variables stored in memory are changed, an addition
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This emphasis seems odd; i feel like it would flow better if the emphasis was moved to "appears" or removed entirely.

//!
//! - **Multiprocessor** system, where multiple hardware threads run at the same time.
//! In multi-threaded scenarios, you can use two kinds of primitives to deal
//! with synchronization:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The flow between these bullet points seems odd; they're using different structures. Compare the first phrase of each item:

  • Compiler reordering instructions:
  • Single processor executing instructions out-of-order:
  • Multiprocessor system, where multiple hardware threads run at the same time.

The first two items use colons to separate a title from the rest of the segment, but the last one just treats the first sentence as the summary and doesn't have a succinct title like the others.

I feel like this item would work better like this:

  • A multiprocessor system executing multiple hardware threads at the same time: In multi-threaded scenarios...

src/libstd/sync/mod.rs Show resolved Hide resolved
//! Use [compiler fences] to prevent this reordering.
//!
//! - **Single processor** executing instructions [out-of-order]: modern CPUs are
//! capable of [superscalar] execution, i.e. multiple instructions might be
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • A single processor executing instructions out-of-order: ...

@GabrielMajeri
Copy link
Contributor Author

I've addressed the review comments and expanded the section on higher-level synchronization primitives provided by the standard library.

@steveklabnik
Copy link
Member

@bors: r+ rollup

thanks!

@bors
Copy link
Contributor

bors commented Oct 5, 2018

📌 Commit 6ba5584 has been approved by steveklabnik

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Oct 5, 2018
pietroalbini added a commit to pietroalbini/rust that referenced this pull request Oct 5, 2018
…teveklabnik

Expand the documentation for the `std::sync` module

I've tried to expand the documentation for Rust's synchronization primitives. The module level documentation explains why synchronization is required when working with a multiprocessor system,
and then links to the appropiate structure in this module.

Fixes rust-lang#29377, since this should be the last item on the checklist (documentation for `Atomic*` was fixed in rust-lang#44854, but not ticked off the checklist).
bors added a commit that referenced this pull request Oct 6, 2018
Rollup of 11 pull requests

Successful merges:

 - #54078 (Expand the documentation for the `std::sync` module)
 - #54717 (Cleanup rustc/ty part 1)
 - #54781 (Add examples to `TyKind::FnDef` and `TyKind::FnPtr` docs)
 - #54787 (Only warn about unused `mut` in user-written code)
 - #54804 (add suggestion for inverted function parameters)
 - #54812 (Regression test for #32382.)
 - #54833 (make `Parser::parse_foreign_item()` return a foreign item or error)
 - #54834 (rustdoc: overflow:auto doesn't work nicely on small screens)
 - #54838 (Fix typo in src/libsyntax/parse/parser.rs)
 - #54851 (Fix a regression in 1.30 by reverting #53564)
 - #54853 (Remove unneccessary error from test, revealing NLL error.)

Failed merges:

r? @ghost
@bors bors merged commit 6ba5584 into rust-lang:master Oct 6, 2018
@GabrielMajeri GabrielMajeri deleted the expand-sync-docs branch October 6, 2018 05:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

API Docs: sync
9 participants