Commit Graph

138 Commits

Author SHA1 Message Date
Matthias Krüger
7d8e329194
Rollup merge of #105243 - RalfJung:no-op-let, r=Mark-Simulacrum
remove no-op 'let _ = '

Also see the discussion at https://github.com/rust-lang/rust/pull/93563#discussion_r1034057555.

I don't know why these `Drop` implementations exist to begin with, given that their body does literally nothing, but did not want to change that. (It might affect dropck.)

Cc `````@ibraheemdev````` `````@Amanieu`````
2022-12-06 13:27:42 +01:00
Rageking8
58110572fb fix dupe word typos 2022-12-05 16:42:36 +08:00
Ralf Jung
c823dfa8b2 remove no-op 'let _ = ' 2022-12-04 10:32:00 +01:00
Dylan DPC
5caac92dc0
Rollup merge of #104528 - WaffleLapkin:lazy_lock_docfix, r=matklad
Properly link `{Once,Lazy}{Cell,Lock}` in docs

See https://github.com/rust-lang/rust/issues/74465#issuecomment-1317947443
2022-11-19 11:54:44 +05:30
Maybe Waffle
57e726108a Properly link {Once,Lazy}{Cell,Lock} in docs 2022-11-17 11:05:56 +00:00
Ralf Jung
5fd561dea2 avoid memory leak in mpsc test 2022-11-14 13:38:53 +01:00
bors
afd7977c85 Auto merge of #93563 - ibraheemdev:crossbeam-channel, r=Amanieu
Merge crossbeam-channel into `std::sync::mpsc`

This PR imports the [`crossbeam-channel`](https://github.com/crossbeam-rs/crossbeam/tree/master/crossbeam-channel#crossbeam-channel) crate into the standard library as a private module, `sync::mpmc`. `sync::mpsc` is now implemented as a thin wrapper around `sync::mpmc`. The primary purpose of this PR is to resolve https://github.com/rust-lang/rust/issues/39364. The public API intentionally remains the same.

The reason https://github.com/rust-lang/rust/issues/39364 has not been fixed in over 5 years is that the current channel is *incredibly* complex. It was written many years ago and has sat mostly untouched since. `crossbeam-channel` has become the most popular alternative on crates.io, amassing over 30 million downloads. While crossbeam's channel is also complex, like all fast concurrent data structures, it avoids some of the major issues with the current implementation around dynamic flavor upgrades. The new implementation decides on the datastructure to be used when the channel is created, and the channel retains that structure until it is dropped.

Replacing `sync::mpsc` with a simpler, less performant implementation has been discussed as an alternative. However, Rust touts itself as enabling *fearless concurrency*, and having the standard library feature a subpar implementation of a core concurrency primitive doesn't feel right. The argument is that slower is better than broken, but this PR shows that we can do better.

As mentioned before, the primary purpose of this PR is to fix https://github.com/rust-lang/rust/issues/39364, and so the public API intentionally remains the same. *After* that problem is fixed, the fact that `sync::mpmc` now exists makes it easier to fix the primary limitation of `mpsc`, the fact that it only supports a single consumer. spmc and mpmc are two other common concurrency patterns, and this change enables a path to deprecating `mpsc` and exposing a general `sync::channel` module that supports multiple consumers. It also implements other useful methods such as `send_timeout`. That said, exposing MPMC and other new functionality is mostly out of scope for this PR, and it would be helpful if discussion stays on topic :)

For what it's worth, the new implementation has also been shown to be more performant in [some basic benchmarks](https://github.com/crossbeam-rs/crossbeam/tree/master/crossbeam-channel/benchmarks#results).

cc `@taiki-e`

r? rust-lang/libs
2022-11-13 12:08:42 +00:00
Ibraheem Ahmed
a22426916d avoid calling thread::current in channel destructor 2022-11-12 23:13:58 -05:00
bors
b0c6527912 Auto merge of #103150 - joboet:remove_lock_wrappers, r=m-ou-se
Remove lock wrappers in `sys_common`

This moves the lazy allocation to `sys` (SGX and UNIX). While this leads to a bit more verbosity, it will simplify future improvements by making room in `sys_common` for platform-independent implementations.

This also removes the condvar check on SGX as it is not necessary for soundness and will be removed anyway once mutex has been made movable.

For simplicity's sake, `libunwind` also uses lazy allocation now on SGX. This will require an update to the C definitions before merging this (CC `@raoulstrackx).`

r? `@m-ou-se`
2022-11-12 01:31:39 +00:00
Ibraheem Ahmed
209168655a tidy 2022-11-09 23:20:02 -05:00
Ibraheem Ahmed
f2b5e27a60 spin less in mpsc::SyncSender::send 2022-11-09 23:20:02 -05:00
Ibraheem Ahmed
f2966d1d0c remove extra spinning from mpsc parker 2022-11-09 23:20:02 -05:00
Ibraheem Ahmed
8dddb22943 sync::mpsc: quadratic backoff 2022-11-09 23:20:02 -05:00
Ibraheem Ahmed
7b721ed0cd sync::mpsc: reload state after spinning on CAS failure 2022-11-09 23:20:02 -05:00
Ibraheem Ahmed
8c17a3e7cb remove extra spinning from mpsc::Receiver::recv 2022-11-09 23:20:02 -05:00
Ibraheem Ahmed
cb394c026a remove mention of rust-lang#39364 from mpsc docs 2022-11-09 23:20:02 -05:00
Ibraheem Ahmed
8a68b40432 add test case for rust-lang#39364 2022-11-09 23:20:02 -05:00
Ibraheem Ahmed
31dc5bba89 implement sync::mpsc as a wrapper around sync::mpmc 2022-11-09 23:20:00 -05:00
Ibraheem Ahmed
a43da5a097 initial port of crossbeam-channel 2022-11-09 23:18:06 -05:00
Pietro Albini
807a7bfcee
clarify licensing situation of mpsc and spsc queue 2022-11-08 09:36:08 +01:00
joboet
98815742cf
std: remove lock wrappers in sys_common 2022-11-06 15:32:59 +01:00
Rageking8
c246a3ddd4 more dupe typos again 2022-10-25 22:51:47 +08:00
Yuki Okushi
387df55f26
Rollup merge of #102277 - mgeisler:rwlock, r=m-ou-se
Consistently write `RwLock`

Before the documentation sometimes referred to an "rwlock" and sometimes to "`RwLock`".
2022-10-11 18:37:52 +09:00
bors
a688a0305f Auto merge of #99505 - joboet:futex_once, r=thomcc
std: use futex in `Once`

Now that we have efficient locks, let's optimize the rest of `sync` as well. This PR adds a futex-based implementation for `Once`, which drastically simplifies the implementation compared to the generic version, which is provided as fallback for platforms without futex (Windows only supports them on newer versions, so it uses the fallback for now).

Instead of storing a linked list of waiters, the new implementation adds another state (`QUEUED`), which is set when there are waiting threads. These now use `futex_wait` on that state and are woken by the running thread when it finishes and notices the `QUEUED` state, thereby avoiding unnecessary calls to `futex_wake_all`.
2022-10-08 03:50:07 +00:00
joboet
5d0211dc03
std: use futex in Once 2022-10-07 12:12:36 +02:00
mejrs
f3ac328d58 Address feedback 2022-09-27 21:42:09 +02:00
Martin Geisler
f67184fdcb Consistently write RwLock
Before the documentation sometimes referred to an "rwlock" and sometimes to "`RwLock`".
2022-09-25 21:09:38 +02:00
bors
e7cdd4c090 Auto merge of #100576 - joboet:movable_const_remutex, r=Mark-Simulacrum
Make `ReentrantMutex` movable and `const`

As `MovableMutex` is now `const`, it can be used to simplify the implementation and interface of the internal reentrant mutex type. Consequently, the standard error stream does not need to be wrapped in `OnceLock` and `OnceLock::get_or_init_pin()` can be removed.
2022-09-04 22:53:58 +00:00
joboet
8c37fdf2d7
std: make ReentrantMutex movable and const; simplify Stdout initialization 2022-09-03 14:05:28 +02:00
Guillaume Gomez
07f43a1ca1
Rollup merge of #97739 - a2aaron:let_underscore, r=estebank
Uplift the `let_underscore` lints from clippy into rustc.

This PR resolves #97241.

This PR adds three lints from clippy--`let_underscore_drop`, `let_underscore_lock`, and `let_underscore_must_use`, which are meant to capture likely-incorrect uses of `let _ = ...` bindings (in particular, doing this on a type with a non-trivial `Drop` causes the `Drop` to occur immediately, instead of at the end of the scope. For a type like `MutexGuard`, this effectively releases the lock immediately, which is almost certainly the wrong behavior)

In porting the lints from clippy I had to copy over a bunch of utility functions from `clippy_util` that these lints also relied upon. Is that the right approach?

Note that I've set the `must_use` and `drop` lints to Allow by default and set `lock` to Deny by default (this matches the same settings that clippy has). In talking with `@estebank` he informed me to do a Crater run (I am not sure what type of Crater run to request here--I think it's just "check only"?)

On the linked issue, there's some discussion about using `must_use` and `Drop` together as a heuristic for when to warn--I did not implement this yet.

r? `@estebank`
2022-09-02 11:34:45 +02:00
Ralf Jung
8c8dc125b1 make many std tests work in Miri 2022-08-18 18:07:39 -04:00
Matthias Krüger
0e71d1f237
Rollup merge of #97629 - guswynn:exclusive_struct, r=m-ou-se
[core] add `Exclusive` to sync

(discussed here: https://rust-lang.zulipchat.com/#narrow/stream/219381-t-libs/topic/Adding.20.60SyncWrapper.60.20to.20std)

`Exclusive` is a wrapper that exclusively allows mutable access to the inner value if you have exclusive access to the wrapper. It acts like a compile time mutex, and hold an unconditional `Sync` implementation.

## Justification for inclusion into std
- This wrapper unblocks actual problems:
  - The example that I hit was a vector of `futures::future::BoxFuture`'s causing a central struct in a script to be non-`Sync`. To work around it, you either write really difficult code, or wrap the futures in a needless mutex.
- Easy to maintain: this struct is as simple as a wrapper can get, and its `Sync` implementation has very clear reasoning
- Fills a gap: `&/&mut` are to `RwLock` as `Exclusive` is to `Mutex`

## Public Api
```rust
// core::sync
#[derive(Default)]
struct Exclusive<T: ?Sized> { ... }

impl<T: ?Sized> Sync for Exclusive {}

impl<T> Exclusive<T> {
    pub const fn new(t: T) -> Self;
    pub const fn into_inner(self) -> T;
}

impl<T: ?Sized> Exclusive<T> {
    pub const fn get_mut(&mut self) -> &mut T;
    pub const fn get_pin_mut(Pin<&mut self>) -> Pin<&mut T>;
    pub const fn from_mut(&mut T) -> &mut Exclusive<T>;
    pub const fn from_pin_mut(Pin<&mut T>) -> Pin<&mut Exclusive<T>>;
}

impl<T: Future> Future for Exclusive { ... }

impl<T> From<T> for Exclusive<T> { ... }
impl<T: ?Sized> Debug for Exclusive { ... }
```

## Naming
This is a big bikeshed, but I felt that `Exclusive` captured its general purpose quite well.

## Stability and location
As this is so simple, it can be in `core`. I feel that it can be stabilized quite soon after it is merged, if the libs teams feels its reasonable to add. Also, I don't really know how unstable feature work in std/core's codebases, so I might need help fixing them

## Tips for review
The docs probably are the thing that needs to be reviewed! I tried my best, but I'm sure people have more experience than me writing docs for `Core`

### Implementation:
The API is mostly pulled from https://docs.rs/sync_wrapper/latest/sync_wrapper/struct.SyncWrapper.html (which is apache 2.0 licenesed), and the implementation is trivial:
- its an unsafe justification for pinning
- its an unsafe justification for the `Sync` impl (mostly reasoned about by ````@danielhenrymantilla```` here: https://github.com/Actyx/sync_wrapper/pull/2)
- and forwarding impls, starting with derivable ones and `Future`
2022-06-30 19:55:50 +02:00
bors
00ce47209d Auto merge of #96820 - r-raymond:master, r=cuviper
Make RwLockReadGuard covariant

Hi, first time contributor here, if anything is not as expected, please let me know.

`RwLockReadGoard`'s type constructor is invariant. Since it behaves like a smart pointer to an immutable reference, there is no reason that it should not be covariant. Take e.g.

```
fn test_read_guard_covariance() {
    fn do_stuff<'a>(_: RwLockReadGuard<'_, &'a i32>, _: &'a i32) {}
    let j: i32 = 5;
    let lock = RwLock::new(&j);
    {
        let i = 6;
        do_stuff(lock.read().unwrap(), &i);
    }
    drop(lock);
}
```
where the compiler complains that &i doesn't live long enough. If `RwLockReadGuard` is covariant, then the above code is accepted because the lifetime can be shorter than `'a`.

In order for `RwLockReadGuard` to be covariant, it can't contain a full reference to the `RwLock`, which can never be covariant (because it exposes a mutable reference to the underlying data structure). By reducing the data structure to the required pieces of `RwLock`, the rest falls in place.

If there is a better way to do a test that tests successful compilation, please let me know.

Fixes #80392
2022-06-25 13:03:53 +00:00
Gus Wynn
029f9aa3bf add tracking issue for exclusive 2022-06-23 08:52:13 -07:00
bors
15fc228d0d Auto merge of #97791 - m-ou-se:const-locks, r=m-ou-se
Make {Mutex, Condvar, RwLock}::new() const.

This makes it possible to have `static M: Mutex<_> = Mutex::new(..);` 🎉

Our implementations [on Linux](https://github.com/rust-lang/rust/pull/95035), [on Windows](https://github.com/rust-lang/rust/pull/77380), and various BSDs and some tier 3 platforms have already been using a non-allocating const-constructible implementation. As of https://github.com/rust-lang/rust/pull/97647, the remaining platforms (most notably macOS) now have a const-constructible implementation as well. This means we can finally make these functions publicly const.

Tracking issue: https://github.com/rust-lang/rust/issues/93740
2022-06-19 08:20:36 +00:00
Robin Raymond
09d937ed5f Add comment explaining why we use NonNull 2022-06-19 09:23:35 +02:00
Robin Raymond
fa1656e8ae Add safety comments 2022-06-19 09:23:35 +02:00
Robin Raymond
0157593c74 Documentation typo 2022-06-19 09:23:35 +02:00
Robin Raymond
08650fbb50 *const to NonNull plus documentation 2022-06-19 09:23:32 +02:00
Robin Raymond
cf1238e799 Address comments 2022-06-19 09:22:40 +02:00
Robin Raymond
391f800705 More formatting 2022-06-19 09:22:40 +02:00
Robin Raymond
0b6e6e3d63 Formatting 2022-06-19 09:22:32 +02:00
Robin Raymond
7cefa8f995 Make RwLockReadGuard covariant 2022-06-19 09:21:28 +02:00
Matthias Krüger
f351f347b8
Rollup merge of #98165 - WaffleLapkin:once_things_renamings, r=m-ou-se
once cell renamings

This PR does the renamings proposed in https://github.com/rust-lang/rust/issues/74465#issuecomment-1153703128

- Move/rename `lazy::{OnceCell, Lazy}` to `cell::{OnceCell, LazyCell}`
- Move/rename `lazy::{SyncOnceCell, SyncLazy}` to `sync::{OnceLock, LazyLock}`

(I used `Lazy...` instead of `...Lazy` as it seems to be more consistent, easier to pronounce, etc)

```@rustbot``` label +T-libs-api -T-libs
2022-06-19 00:17:13 +02:00
Maybe Waffle
c1a2db3372 Move/rename lazy::Sync{OnceCell,Lazy} to sync::{Once,Lazy}Lock 2022-06-16 19:54:42 +04:00
Josh Stone
34895ded2c Avoid thread::panicking() in non-poisoning methods of Mutex and RwLock
`Mutex::lock()` and `RwLock::write()` are poison-guarded against panics,
in that they set the poison flag if a panic occurs while they're locked.
But if we're already in a panic (`thread::panicking()`), they leave the
poison flag alone.

That check is a bit of a waste for methods that never set the poison
flag though, namely `get_mut()`, `into_inner()`, and `RwLock::read()`.
These use-cases are now split to avoid that unnecessary call.
2022-06-09 11:51:39 -07:00
Gus Wynn
63d1c86230 [core] add Exclusive to sync 2022-06-07 13:10:50 -07:00
Dylan DPC
e224185409
Update library/std/src/sync/mutex.rs
Co-authored-by: Weiyi Wang <wwylele@gmail.com>
2022-06-07 15:15:19 +02:00
Nilstrieb
83af085c77 Remove confusing sentence from Mutex docs
The docs were saying something about "statically initializing" the
mutex, and it's not clear what this means. Remove that part to avoid
confusion.
2022-06-07 09:53:44 +02:00
Mara Bos
edae495855 Make {Mutex, Condvar, RwLock}::new() const. 2022-06-06 13:55:43 +02:00