portable_atomic_util/arc.rs
1// SPDX-License-Identifier: Apache-2.0 OR MIT
2
3// This module is based on alloc::sync::Arc.
4//
5// The code has been adjusted to work with stable Rust (and optionally support some unstable features).
6//
7// Source: https://github.com/rust-lang/rust/blob/1.93.0/library/alloc/src/sync.rs
8//
9// Copyright & License of the original code:
10// - https://github.com/rust-lang/rust/blob/1.93.0/COPYRIGHT
11// - https://github.com/rust-lang/rust/blob/1.93.0/LICENSE-APACHE
12// - https://github.com/rust-lang/rust/blob/1.93.0/LICENSE-MIT
13
14#![allow(clippy::must_use_candidate)] // align to alloc::sync::Arc
15#![allow(clippy::undocumented_unsafe_blocks)] // TODO: most of the unsafe codes were inherited from alloc::sync::Arc
16
17use alloc::{
18 alloc::handle_alloc_error,
19 borrow::{Cow, ToOwned},
20 boxed::Box,
21 string::String,
22 vec::Vec,
23};
24#[cfg(not(portable_atomic_no_min_const_generics))]
25use core::convert::TryFrom;
26use core::{
27 alloc::Layout,
28 any::Any,
29 borrow,
30 cmp::Ordering,
31 fmt,
32 hash::{Hash, Hasher},
33 iter::FromIterator,
34 marker::PhantomData,
35 mem::{self, ManuallyDrop},
36 ops::Deref,
37 pin::Pin,
38 ptr::{self, NonNull},
39 slice,
40};
41#[allow(deprecated)]
42use core::{isize, usize};
43#[cfg(portable_atomic_unstable_coerce_unsized)]
44use core::{marker::Unsize, ops::CoerceUnsized};
45
46use portable_atomic::{
47 self as atomic,
48 Ordering::{Acquire, Relaxed, Release},
49 hint,
50};
51
52use crate::utils::ptr as strict;
53#[cfg(portable_atomic_no_strict_provenance)]
54use crate::utils::ptr::PtrExt as _;
55
56#[allow(deprecated)] // associated constant MAX requires Rust 1.43
57const ISIZE_MAX: isize = isize::MAX;
58#[allow(deprecated)] // associated constant MAX requires Rust 1.43
59const USIZE_MAX: usize = usize::MAX;
60
61/// A soft limit on the amount of references that may be made to an `Arc`.
62///
63/// Going above this limit will abort your program (although not
64/// necessarily) at _exactly_ `MAX_REFCOUNT + 1` references.
65/// Trying to go above it might call a `panic` (if not actually going above it).
66///
67/// This is a global invariant, and also applies when using a compare-exchange loop.
68///
69/// See comment in `Arc::clone`.
70const MAX_REFCOUNT: usize = ISIZE_MAX as usize;
71
72/// The error in case either counter reaches above `MAX_REFCOUNT`, and we can `panic` safely.
73const INTERNAL_OVERFLOW_ERROR: &str = "Arc counter overflow";
74
75#[cfg(not(portable_atomic_sanitize_thread))]
76macro_rules! acquire {
77 ($x:expr) => {
78 atomic::fence(Acquire)
79 };
80}
81
82// ThreadSanitizer does not support memory fences. To avoid false positive
83// reports in Arc / Weak implementation use atomic loads for synchronization
84// instead.
85#[cfg(portable_atomic_sanitize_thread)]
86macro_rules! acquire {
87 ($x:expr) => {
88 $x.load(Acquire)
89 };
90}
91
92/// A thread-safe reference-counting pointer. 'Arc' stands for 'Atomically
93/// Reference Counted'.
94///
95/// This is an equivalent to [`std::sync::Arc`], but using [portable-atomic] for synchronization.
96/// See the documentation for [`std::sync::Arc`] for more details.
97///
98/// **Note:** Unlike `std::sync::Arc`, coercing `Arc<T>` to `Arc<U>` is only possible if
99/// the optional cfg `portable_atomic_unstable_coerce_unsized` is enabled, as documented at the crate-level documentation,
100/// and this optional cfg item is only supported with Rust nightly version.
101/// This is because coercing the pointee requires the
102/// [unstable `CoerceUnsized` trait](https://doc.rust-lang.org/nightly/core/ops/trait.CoerceUnsized.html).
103/// See [this issue comment](https://github.com/taiki-e/portable-atomic/issues/143#issuecomment-1866488569)
104/// for a workaround that works without depending on unstable features.
105///
106/// [portable-atomic]: https://crates.io/crates/portable-atomic
107///
108/// # Examples
109///
110/// ```
111/// use portable_atomic_util::Arc;
112/// use std::thread;
113///
114/// let five = Arc::new(5);
115///
116/// for _ in 0..10 {
117/// let five = Arc::clone(&five);
118///
119/// thread::spawn(move || {
120/// assert_eq!(*five, 5);
121/// });
122/// }
123/// # if cfg!(miri) { std::thread::sleep(std::time::Duration::from_millis(500)); } // wait for background threads closed: https://github.com/rust-lang/miri/issues/1371
124/// ```
125pub struct Arc<T: ?Sized> {
126 ptr: NonNull<ArcInner<T>>,
127 phantom: PhantomData<ArcInner<T>>,
128}
129
130unsafe impl<T: ?Sized + Sync + Send> Send for Arc<T> {}
131unsafe impl<T: ?Sized + Sync + Send> Sync for Arc<T> {}
132
133#[cfg(not(portable_atomic_no_core_unwind_safe))]
134impl<T: ?Sized + core::panic::RefUnwindSafe> core::panic::UnwindSafe for Arc<T> {}
135#[cfg(all(portable_atomic_no_core_unwind_safe, feature = "std"))]
136impl<T: ?Sized + std::panic::RefUnwindSafe> std::panic::UnwindSafe for Arc<T> {}
137
138#[cfg(portable_atomic_unstable_coerce_unsized)]
139impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Arc<U>> for Arc<T> {}
140
141impl<T: ?Sized> Arc<T> {
142 #[inline]
143 fn into_inner_non_null(this: Self) -> NonNull<ArcInner<T>> {
144 let this = mem::ManuallyDrop::new(this);
145 this.ptr
146 }
147
148 #[inline]
149 unsafe fn from_inner(ptr: NonNull<ArcInner<T>>) -> Self {
150 Self { ptr, phantom: PhantomData }
151 }
152
153 #[inline]
154 unsafe fn from_ptr(ptr: *mut ArcInner<T>) -> Self {
155 // SAFETY: the caller must uphold the safety contract.
156 unsafe { Self::from_inner(NonNull::new_unchecked(ptr)) }
157 }
158}
159
160/// `Weak` is a version of [`Arc`] that holds a non-owning reference to the
161/// managed allocation.
162///
163/// The allocation is accessed by calling [`upgrade`] on the `Weak`
164/// pointer, which returns an <code>[Option]<[Arc]\<T>></code>.
165///
166/// This is an equivalent to [`std::sync::Weak`], but using [portable-atomic] for synchronization.
167/// See the documentation for [`std::sync::Weak`] for more details.
168///
169/// <!-- TODO: support coercing `Weak<T>` to `Weak<U>` with testing, if optional cfg `portable_atomic_unstable_coerce_unsized` is enabled -->
170/// **Note:** Unlike `std::sync::Weak`, coercing `Weak<T>` to `Weak<U>` is not possible, not even if
171/// the optional cfg `portable_atomic_unstable_coerce_unsized` is enabled.
172///
173/// [`upgrade`]: Weak::upgrade
174/// [portable-atomic]: https://crates.io/crates/portable-atomic
175///
176/// # Examples
177///
178/// ```
179/// use portable_atomic_util::Arc;
180/// use std::thread;
181///
182/// let five = Arc::new(5);
183/// let weak_five = Arc::downgrade(&five);
184///
185/// # let t =
186/// thread::spawn(move || {
187/// let five = weak_five.upgrade().unwrap();
188/// assert_eq!(*five, 5);
189/// });
190/// # t.join().unwrap(); // join thread to avoid https://github.com/rust-lang/miri/issues/1371
191/// ```
192pub struct Weak<T: ?Sized> {
193 // This is a `NonNull` to allow optimizing the size of this type in enums,
194 // but it is not necessarily a valid pointer.
195 // `Weak::new` sets this to `usize::MAX` so that it doesn't need
196 // to allocate space on the heap. That's not a value a real pointer
197 // will ever have because ArcInner has alignment at least 2.
198 ptr: NonNull<ArcInner<T>>,
199}
200
201unsafe impl<T: ?Sized + Sync + Send> Send for Weak<T> {}
202unsafe impl<T: ?Sized + Sync + Send> Sync for Weak<T> {}
203
204impl<T: ?Sized> fmt::Debug for Weak<T> {
205 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
206 f.write_str("(Weak)")
207 }
208}
209
210// This is repr(C) to future-proof against possible field-reordering, which
211// would interfere with otherwise safe [into|from]_raw() of transmutable
212// inner types.
213// Unlike RcInner, repr(align(2)) is not strictly required because atomic types
214// have the alignment same as its size, but we use it for consistency and clarity.
215#[repr(C, align(2))]
216struct ArcInner<T: ?Sized> {
217 strong: atomic::AtomicUsize,
218
219 // the value usize::MAX acts as a sentinel for temporarily "locking" the
220 // ability to upgrade weak pointers or downgrade strong ones; this is used
221 // to avoid races in `make_mut` and `get_mut`.
222 weak: atomic::AtomicUsize,
223
224 data: T,
225}
226
227/// Calculate layout for `ArcInner<T>` using the inner value's layout
228fn arc_inner_layout_for_value_layout(layout: Layout) -> Layout {
229 // Calculate layout using the given value layout.
230 // Previously, layout was calculated on the expression
231 // `&*(ptr as *const ArcInner<T>)`, but this created a misaligned
232 // reference (see #54908).
233 layout::pad_to_align(layout::extend(Layout::new::<ArcInner<()>>(), layout).unwrap().0)
234}
235
236unsafe impl<T: ?Sized + Sync + Send> Send for ArcInner<T> {}
237unsafe impl<T: ?Sized + Sync + Send> Sync for ArcInner<T> {}
238
239impl<T> Arc<T> {
240 /// Constructs a new `Arc<T>`.
241 ///
242 /// # Examples
243 ///
244 /// ```
245 /// use portable_atomic_util::Arc;
246 ///
247 /// let five = Arc::new(5);
248 /// ```
249 #[inline]
250 pub fn new(data: T) -> Self {
251 // Start the weak pointer count as 1 which is the weak pointer that's
252 // held by all the strong pointers (kinda), see std/rc.rs for more info
253 let x: Box<_> = Box::new(ArcInner {
254 strong: atomic::AtomicUsize::new(1),
255 weak: atomic::AtomicUsize::new(1),
256 data,
257 });
258 unsafe { Self::from_inner(Box::leak(x).into()) }
259 }
260
261 /// Constructs a new `Arc<T>` while giving you a `Weak<T>` to the allocation,
262 /// to allow you to construct a `T` which holds a weak pointer to itself.
263 ///
264 /// Generally, a structure circularly referencing itself, either directly or
265 /// indirectly, should not hold a strong reference to itself to prevent a memory leak.
266 /// Using this function, you get access to the weak pointer during the
267 /// initialization of `T`, before the `Arc<T>` is created, such that you can
268 /// clone and store it inside the `T`.
269 ///
270 /// `new_cyclic` first allocates the managed allocation for the `Arc<T>`,
271 /// then calls your closure, giving it a `Weak<T>` to this allocation,
272 /// and only afterwards completes the construction of the `Arc<T>` by placing
273 /// the `T` returned from your closure into the allocation.
274 ///
275 /// Since the new `Arc<T>` is not fully-constructed until `Arc<T>::new_cyclic`
276 /// returns, calling [`upgrade`] on the weak reference inside your closure will
277 /// fail and result in a `None` value.
278 ///
279 /// # Panics
280 ///
281 /// If `data_fn` panics, the panic is propagated to the caller, and the
282 /// temporary [`Weak<T>`] is dropped normally.
283 ///
284 /// # Example
285 ///
286 /// ```
287 /// use portable_atomic_util::{Arc, Weak};
288 ///
289 /// struct Gadget {
290 /// me: Weak<Gadget>,
291 /// }
292 ///
293 /// impl Gadget {
294 /// /// Constructs a reference counted Gadget.
295 /// fn new() -> Arc<Self> {
296 /// // `me` is a `Weak<Gadget>` pointing at the new allocation of the
297 /// // `Arc` we're constructing.
298 /// Arc::new_cyclic(|me| {
299 /// // Create the actual struct here.
300 /// Gadget { me: me.clone() }
301 /// })
302 /// }
303 ///
304 /// /// Returns a reference counted pointer to Self.
305 /// fn me(&self) -> Arc<Self> {
306 /// self.me.upgrade().unwrap()
307 /// }
308 /// }
309 /// ```
310 /// [`upgrade`]: Weak::upgrade
311 #[inline]
312 pub fn new_cyclic<F>(data_fn: F) -> Self
313 where
314 F: FnOnce(&Weak<T>) -> T,
315 {
316 // Construct the inner in the "uninitialized" state with a single
317 // weak reference.
318 let init_ptr = Weak::new_uninit_ptr();
319
320 let weak = Weak { ptr: init_ptr };
321
322 // It's important we don't give up ownership of the weak pointer, or
323 // else the memory might be freed by the time `data_fn` returns. If
324 // we really wanted to pass ownership, we could create an additional
325 // weak pointer for ourselves, but this would result in additional
326 // updates to the weak reference count which might not be necessary
327 // otherwise.
328 let data = data_fn(&weak);
329
330 // Now we can properly initialize the inner value and turn our weak
331 // reference into a strong reference.
332 unsafe {
333 let inner = init_ptr.as_ptr();
334 ptr::write(data_ptr::<T>(inner, &data), data);
335
336 // The above write to the data field must be visible to any threads which
337 // observe a non-zero strong count. Therefore we need at least "Release" ordering
338 // in order to synchronize with the `compare_exchange_weak` in `Weak::upgrade`.
339 //
340 // "Acquire" ordering is not required. When considering the possible behaviors
341 // of `data_fn` we only need to look at what it could do with a reference to a
342 // non-upgradeable `Weak`:
343 // - It can *clone* the `Weak`, increasing the weak reference count.
344 // - It can drop those clones, decreasing the weak reference count (but never to zero).
345 //
346 // These side effects do not impact us in any way, and no other side effects are
347 // possible with safe code alone.
348 let prev_value = (*inner).strong.fetch_add(1, Release);
349 debug_assert_eq!(prev_value, 0, "No prior strong references should exist");
350
351 // Strong references should collectively own a shared weak reference,
352 // so don't run the destructor for our old weak reference.
353 mem::forget(weak);
354
355 Self::from_inner(init_ptr)
356 }
357 }
358
359 /// Constructs a new `Arc` with uninitialized contents.
360 ///
361 /// # Examples
362 ///
363 /// ```
364 /// use portable_atomic_util::Arc;
365 ///
366 /// let mut five = Arc::<u32>::new_uninit();
367 ///
368 /// // Deferred initialization:
369 /// Arc::get_mut(&mut five).unwrap().write(5);
370 ///
371 /// let five = unsafe { five.assume_init() };
372 ///
373 /// assert_eq!(*five, 5)
374 /// ```
375 #[inline]
376 #[must_use]
377 pub fn new_uninit() -> Arc<mem::MaybeUninit<T>> {
378 unsafe {
379 Arc::from_ptr(Arc::allocate_for_layout(
380 Layout::new::<T>(),
381 |layout| Global.allocate(layout),
382 |ptr| ptr as *mut _,
383 ))
384 }
385 }
386
387 /// Constructs a new `Arc` with uninitialized contents, with the memory
388 /// being filled with `0` bytes.
389 ///
390 /// See [`MaybeUninit::zeroed`][zeroed] for examples of correct and incorrect usage
391 /// of this method.
392 ///
393 /// # Examples
394 ///
395 /// ```
396 /// use portable_atomic_util::Arc;
397 ///
398 /// let zero = Arc::<u32>::new_zeroed();
399 /// let zero = unsafe { zero.assume_init() };
400 ///
401 /// assert_eq!(*zero, 0)
402 /// ```
403 ///
404 /// [zeroed]: mem::MaybeUninit::zeroed
405 #[inline]
406 #[must_use]
407 pub fn new_zeroed() -> Arc<mem::MaybeUninit<T>> {
408 unsafe {
409 Arc::from_ptr(Arc::allocate_for_layout(
410 Layout::new::<T>(),
411 |layout| Global.allocate_zeroed(layout),
412 |ptr| ptr as *mut _,
413 ))
414 }
415 }
416
417 /// Constructs a new `Pin<Arc<T>>`. If `T` does not implement `Unpin`, then
418 /// `data` will be pinned in memory and unable to be moved.
419 #[must_use]
420 pub fn pin(data: T) -> Pin<Self> {
421 unsafe { Pin::new_unchecked(Self::new(data)) }
422 }
423
424 /// Returns the inner value, if the `Arc` has exactly one strong reference.
425 ///
426 /// Otherwise, an [`Err`] is returned with the same `Arc` that was
427 /// passed in.
428 ///
429 /// This will succeed even if there are outstanding weak references.
430 ///
431 /// It is strongly recommended to use [`Arc::into_inner`] instead if you don't
432 /// keep the `Arc` in the [`Err`] case.
433 /// Immediately dropping the [`Err`]-value, as the expression
434 /// `Arc::try_unwrap(this).ok()` does, can cause the strong count to
435 /// drop to zero and the inner value of the `Arc` to be dropped.
436 /// For instance, if two threads execute such an expression in parallel,
437 /// there is a race condition without the possibility of unsafety:
438 /// The threads could first both check whether they own the last instance
439 /// in `Arc::try_unwrap`, determine that they both do not, and then both
440 /// discard and drop their instance in the call to [`ok`][`Result::ok`].
441 /// In this scenario, the value inside the `Arc` is safely destroyed
442 /// by exactly one of the threads, but neither thread will ever be able
443 /// to use the value.
444 ///
445 /// # Examples
446 ///
447 /// ```
448 /// use portable_atomic_util::Arc;
449 ///
450 /// let x = Arc::new(3);
451 /// assert_eq!(Arc::try_unwrap(x), Ok(3));
452 ///
453 /// let x = Arc::new(4);
454 /// let _y = Arc::clone(&x);
455 /// assert_eq!(*Arc::try_unwrap(x).unwrap_err(), 4);
456 /// ```
457 #[inline]
458 pub fn try_unwrap(this: Self) -> Result<T, Self> {
459 if this.inner().strong.compare_exchange(1, 0, Relaxed, Relaxed).is_err() {
460 return Err(this);
461 }
462
463 acquire!(this.inner().strong);
464
465 let this = ManuallyDrop::new(this);
466 let elem: T = unsafe { ptr::read(&this.ptr.as_ref().data) };
467
468 // Make a weak pointer to clean up the implicit strong-weak reference
469 let _weak = Weak { ptr: this.ptr };
470
471 Ok(elem)
472 }
473
474 /// Returns the inner value, if the `Arc` has exactly one strong reference.
475 ///
476 /// Otherwise, [`None`] is returned and the `Arc` is dropped.
477 ///
478 /// This will succeed even if there are outstanding weak references.
479 ///
480 /// If `Arc::into_inner` is called on every clone of this `Arc`,
481 /// it is guaranteed that exactly one of the calls returns the inner value.
482 /// This means in particular that the inner value is not dropped.
483 ///
484 /// [`Arc::try_unwrap`] is conceptually similar to `Arc::into_inner`, but it
485 /// is meant for different use-cases. If used as a direct replacement
486 /// for `Arc::into_inner` anyway, such as with the expression
487 /// <code>[Arc::try_unwrap]\(this).[ok][Result::ok]()</code>, then it does
488 /// **not** give the same guarantee as described in the previous paragraph.
489 /// For more information, see the examples below and read the documentation
490 /// of [`Arc::try_unwrap`].
491 ///
492 /// # Examples
493 ///
494 /// Minimal example demonstrating the guarantee that `Arc::into_inner` gives.
495 ///
496 /// ```
497 /// use portable_atomic_util::Arc;
498 ///
499 /// let x = Arc::new(3);
500 /// let y = Arc::clone(&x);
501 ///
502 /// // Two threads calling `Arc::into_inner` on both clones of an `Arc`:
503 /// let x_thread = std::thread::spawn(|| Arc::into_inner(x));
504 /// let y_thread = std::thread::spawn(|| Arc::into_inner(y));
505 ///
506 /// let x_inner_value = x_thread.join().unwrap();
507 /// let y_inner_value = y_thread.join().unwrap();
508 ///
509 /// // One of the threads is guaranteed to receive the inner value:
510 /// assert!(matches!((x_inner_value, y_inner_value), (None, Some(3)) | (Some(3), None)));
511 /// // The result could also be `(None, None)` if the threads called
512 /// // `Arc::try_unwrap(x).ok()` and `Arc::try_unwrap(y).ok()` instead.
513 /// ```
514 ///
515 /// A more practical example demonstrating the need for `Arc::into_inner`:
516 /// ```
517 /// use portable_atomic_util::Arc;
518 ///
519 /// // Definition of a simple singly linked list using `Arc`:
520 /// #[derive(Clone)]
521 /// struct LinkedList<T>(Option<Arc<Node<T>>>);
522 /// struct Node<T>(T, Option<Arc<Node<T>>>);
523 ///
524 /// // Dropping a long `LinkedList<T>` relying on the destructor of `Arc`
525 /// // can cause a stack overflow. To prevent this, we can provide a
526 /// // manual `Drop` implementation that does the destruction in a loop:
527 /// impl<T> Drop for LinkedList<T> {
528 /// fn drop(&mut self) {
529 /// let mut link = self.0.take();
530 /// while let Some(arc_node) = link.take() {
531 /// if let Some(Node(_value, next)) = Arc::into_inner(arc_node) {
532 /// link = next;
533 /// }
534 /// }
535 /// }
536 /// }
537 ///
538 /// // Implementation of `new` and `push` omitted
539 /// impl<T> LinkedList<T> {
540 /// /* ... */
541 /// # fn new() -> Self {
542 /// # LinkedList(None)
543 /// # }
544 /// # fn push(&mut self, x: T) {
545 /// # self.0 = Some(Arc::new(Node(x, self.0.take())));
546 /// # }
547 /// }
548 ///
549 /// // The following code could have still caused a stack overflow
550 /// // despite the manual `Drop` impl if that `Drop` impl had used
551 /// // `Arc::try_unwrap(arc).ok()` instead of `Arc::into_inner(arc)`.
552 ///
553 /// // Create a long list and clone it
554 /// let mut x = LinkedList::new();
555 /// let size = 100_000;
556 /// # let size = if cfg!(miri) { 100 } else { size };
557 /// for i in 0..size {
558 /// x.push(i); // Adds i to the front of x
559 /// }
560 /// let y = x.clone();
561 ///
562 /// // Drop the clones in parallel
563 /// let x_thread = std::thread::spawn(|| drop(x));
564 /// let y_thread = std::thread::spawn(|| drop(y));
565 /// x_thread.join().unwrap();
566 /// y_thread.join().unwrap();
567 /// ```
568 #[inline]
569 pub fn into_inner(this: Self) -> Option<T> {
570 // Make sure that the ordinary `Drop` implementation isn't called as well
571 let mut this = mem::ManuallyDrop::new(this);
572
573 // Following the implementation of `drop` and `drop_slow`
574 if this.inner().strong.fetch_sub(1, Release) != 1 {
575 return None;
576 }
577
578 acquire!(this.inner().strong);
579
580 // SAFETY: This mirrors the line
581 //
582 // unsafe { ptr::drop_in_place(Self::get_mut_unchecked(self)) };
583 //
584 // in `drop_slow`. Instead of dropping the value behind the pointer,
585 // it is read and eventually returned; `ptr::read` has the same
586 // safety conditions as `ptr::drop_in_place`.
587 let inner = unsafe { ptr::read(Self::get_mut_unchecked(&mut this)) };
588
589 drop(Weak { ptr: this.ptr });
590
591 Some(inner)
592 }
593
594 /// Maps the value in an `Arc`, reusing the allocation if possible.
595 ///
596 /// `f` is called on a reference to the value in the `Arc`, and the result is returned, also in
597 /// an `Arc`.
598 ///
599 /// Note: this is an associated function, which means that you have
600 /// to call it as `Arc::map(a, f)` instead of `r.map(a)`. This
601 /// is so that there is no conflict with a method on the inner type.
602 ///
603 /// # Examples
604 ///
605 /// ```
606 /// use portable_atomic_util::Arc;
607 ///
608 /// let r = Arc::new(7);
609 /// let new = Arc::map(r, |i| i + 7);
610 /// assert_eq!(*new, 14);
611 /// ```
612 #[inline]
613 pub fn map<F, U>(this: Self, f: F) -> Arc<U>
614 where
615 F: FnOnce(&T) -> U,
616 {
617 if mem::size_of::<T>() == mem::size_of::<U>()
618 && mem::align_of::<T>() == mem::align_of::<U>()
619 && Arc::is_unique(&this)
620 {
621 unsafe {
622 let ptr = Arc::into_raw(this);
623 let value = ptr.read();
624 let mut allocation = Arc::from_raw(ptr as *const mem::MaybeUninit<U>);
625
626 *Arc::get_mut_unchecked(&mut allocation) = mem::MaybeUninit::new(f(&value));
627 allocation.assume_init()
628 }
629 } else {
630 Arc::new(f(&*this))
631 }
632 }
633}
634
635impl<T> Arc<[T]> {
636 /// Constructs a new atomically reference-counted slice with uninitialized contents.
637 ///
638 /// # Examples
639 ///
640 /// ```
641 /// use portable_atomic_util::Arc;
642 ///
643 /// let mut values = Arc::<[u32]>::new_uninit_slice(3);
644 ///
645 /// // Deferred initialization:
646 /// let data = Arc::get_mut(&mut values).unwrap();
647 /// data[0].write(1);
648 /// data[1].write(2);
649 /// data[2].write(3);
650 ///
651 /// let values = unsafe { values.assume_init() };
652 ///
653 /// assert_eq!(*values, [1, 2, 3])
654 /// ```
655 #[inline]
656 #[must_use]
657 pub fn new_uninit_slice(len: usize) -> Arc<[mem::MaybeUninit<T>]> {
658 unsafe { Arc::from_ptr(Arc::allocate_for_slice(len)) }
659 }
660
661 /// Constructs a new atomically reference-counted slice with uninitialized contents, with the memory being
662 /// filled with `0` bytes.
663 ///
664 /// See [`MaybeUninit::zeroed`][zeroed] for examples of correct and
665 /// incorrect usage of this method.
666 ///
667 /// # Examples
668 ///
669 /// ```
670 /// use portable_atomic_util::Arc;
671 ///
672 /// let values = Arc::<[u32]>::new_zeroed_slice(3);
673 /// let values = unsafe { values.assume_init() };
674 ///
675 /// assert_eq!(*values, [0, 0, 0])
676 /// ```
677 ///
678 /// [zeroed]: mem::MaybeUninit::zeroed
679 #[inline]
680 #[must_use]
681 #[allow(clippy::missing_panics_doc)]
682 pub fn new_zeroed_slice(len: usize) -> Arc<[mem::MaybeUninit<T>]> {
683 unsafe {
684 Arc::from_ptr(Arc::allocate_for_layout(
685 layout::array::<T>(len).unwrap(),
686 |layout| Global.allocate_zeroed(layout),
687 |mem| {
688 // We create a slice just for metadata (we must use `[mem::MaybeUninit<T>]`
689 // instead of `[T]` because values behind `mem` is not valid initialized `T`s.
690 // there is no size/alignment issue thanks to layout::array), and create a
691 // pointer from `mem` and slice's metadata.
692 //
693 // We cannot use other ways here:
694 // - ptr::slice_from_raw_parts_mut is best way here, but requires Rust 1.42.
695 // - We cannot use slice::from_raw_parts_mut then casting to its pointer to
696 // ArcInner due to provenance because the actual size of valid allocation
697 // behind `mem` is `layout.size()` bytes (counters + values + padding) but the
698 // allocation from the pointer from slice::from_raw_parts_mut only valid for
699 // `size_of::<T> * len` bytes (only values).
700 let meta: *const _ =
701 slice::from_raw_parts(mem as *const mem::MaybeUninit<T>, len);
702 strict::with_metadata_of(mem, meta) as *mut ArcInner<[mem::MaybeUninit<T>]>
703 },
704 ))
705 }
706 }
707}
708
709impl<T> Arc<mem::MaybeUninit<T>> {
710 /// Converts to `Arc<T>`.
711 ///
712 /// # Safety
713 ///
714 /// As with [`MaybeUninit::assume_init`],
715 /// it is up to the caller to guarantee that the inner value
716 /// really is in an initialized state.
717 /// Calling this when the content is not yet fully initialized
718 /// causes immediate undefined behavior.
719 ///
720 /// [`MaybeUninit::assume_init`]: mem::MaybeUninit::assume_init
721 ///
722 /// # Examples
723 ///
724 /// ```
725 /// use portable_atomic_util::Arc;
726 ///
727 /// let mut five = Arc::<u32>::new_uninit();
728 ///
729 /// // Deferred initialization:
730 /// Arc::get_mut(&mut five).unwrap().write(5);
731 ///
732 /// let five = unsafe { five.assume_init() };
733 ///
734 /// assert_eq!(*five, 5)
735 /// ```
736 #[inline]
737 #[must_use = "`self` will be dropped if the result is not used"]
738 pub unsafe fn assume_init(self) -> Arc<T> {
739 let ptr = Arc::into_inner_non_null(self);
740 // SAFETY: MaybeUninit<T> has the same layout as T, and
741 // the caller must guarantee that the data is initialized.
742 unsafe { Arc::from_inner(ptr.cast::<ArcInner<T>>()) }
743 }
744}
745
746impl<T: ?Sized + CloneToUninit> Arc<T> {
747 fn clone_from_ref(value: &T) -> Self {
748 // `in_progress` drops the allocation if we panic before finishing initializing it.
749 let mut in_progress: UniqueArcUninit<T> = UniqueArcUninit::new(value);
750
751 // Initialize with clone of value.
752 unsafe {
753 // Clone. If the clone panics, `in_progress` will be dropped and clean up.
754 value.clone_to_uninit(in_progress.data_ptr() as *mut u8);
755 // Cast type of pointer, now that it is initialized.
756 in_progress.into_arc()
757 }
758 }
759}
760
761impl<T> Arc<[mem::MaybeUninit<T>]> {
762 /// Converts to `Arc<[T]>`.
763 ///
764 /// # Safety
765 ///
766 /// As with [`MaybeUninit::assume_init`],
767 /// it is up to the caller to guarantee that the inner value
768 /// really is in an initialized state.
769 /// Calling this when the content is not yet fully initialized
770 /// causes immediate undefined behavior.
771 ///
772 /// [`MaybeUninit::assume_init`]: mem::MaybeUninit::assume_init
773 ///
774 /// # Examples
775 ///
776 /// ```
777 /// use portable_atomic_util::Arc;
778 ///
779 /// let mut values = Arc::<[u32]>::new_uninit_slice(3);
780 ///
781 /// // Deferred initialization:
782 /// let data = Arc::get_mut(&mut values).unwrap();
783 /// data[0].write(1);
784 /// data[1].write(2);
785 /// data[2].write(3);
786 ///
787 /// let values = unsafe { values.assume_init() };
788 ///
789 /// assert_eq!(*values, [1, 2, 3])
790 /// ```
791 #[inline]
792 #[must_use = "`self` will be dropped if the result is not used"]
793 pub unsafe fn assume_init(self) -> Arc<[T]> {
794 let ptr = Arc::into_inner_non_null(self);
795 // SAFETY: [MaybeUninit<T>] has the same layout as [T], and
796 // the caller must guarantee that the data is initialized.
797 unsafe { Arc::from_ptr(ptr.as_ptr() as *mut ArcInner<[T]>) }
798 }
799}
800
801impl<T: ?Sized> Arc<T> {
802 /// Constructs an `Arc<T>` from a raw pointer.
803 ///
804 /// # Safety
805 ///
806 /// The raw pointer must have been previously returned by a call to
807 /// [`Arc<U>::into_raw`][into_raw] with the following requirements:
808 ///
809 /// * If `U` is sized, it must have the same size and alignment as `T`. This
810 /// is trivially true if `U` is `T`.
811 /// * If `U` is unsized, its data pointer must have the same size and
812 /// alignment as `T`. This is trivially true if `Arc<U>` was constructed
813 /// through `Arc<T>` and then converted to `Arc<U>` through an [unsized
814 /// coercion].
815 ///
816 /// Note that if `U` or `U`'s data pointer is not `T` but has the same size
817 /// and alignment, this is basically like transmuting references of
818 /// different types. See [`mem::transmute`] for more information
819 /// on what restrictions apply in this case.
820 ///
821 /// The raw pointer must point to a block of memory allocated by the global allocator.
822 ///
823 /// The user of `from_raw` has to make sure a specific value of `T` is only
824 /// dropped once.
825 ///
826 /// This function is unsafe because improper use may lead to memory unsafety,
827 /// even if the returned `Arc<T>` is never accessed.
828 ///
829 /// [into_raw]: Arc::into_raw
830 /// [unsized coercion]: https://doc.rust-lang.org/reference/type-coercions.html#unsized-coercions
831 ///
832 /// # Examples
833 ///
834 /// ```
835 /// use portable_atomic_util::Arc;
836 ///
837 /// let x = Arc::new("hello".to_owned());
838 /// let x_ptr = Arc::into_raw(x);
839 ///
840 /// unsafe {
841 /// // Convert back to an `Arc` to prevent leak.
842 /// let x = Arc::from_raw(x_ptr);
843 /// assert_eq!(&*x, "hello");
844 ///
845 /// // Further calls to `Arc::from_raw(x_ptr)` would be memory-unsafe.
846 /// }
847 ///
848 /// // The memory was freed when `x` went out of scope above, so `x_ptr` is now dangling!
849 /// ```
850 ///
851 /// Convert a slice back into its original array:
852 ///
853 /// ```
854 /// use portable_atomic_util::Arc;
855 ///
856 /// let x: Arc<[u32]> = Arc::from([1, 2, 3]);
857 /// let x_ptr: *const [u32] = Arc::into_raw(x);
858 ///
859 /// unsafe {
860 /// let x: Arc<[u32; 3]> = Arc::from_raw(x_ptr.cast::<[u32; 3]>());
861 /// assert_eq!(&*x, &[1, 2, 3]);
862 /// }
863 /// ```
864 #[inline]
865 pub unsafe fn from_raw(ptr: *const T) -> Self {
866 unsafe {
867 let offset = data_offset::<T>(&*ptr);
868
869 // Reverse the offset to find the original ArcInner.
870 let arc_ptr = strict::byte_sub(ptr as *mut T, offset) as *mut ArcInner<T>;
871
872 Self::from_ptr(arc_ptr)
873 }
874 }
875
876 /// Consumes the `Arc`, returning the wrapped pointer.
877 ///
878 /// To avoid a memory leak the pointer must be converted back to an `Arc` using
879 /// [`Arc::from_raw`].
880 ///
881 /// # Examples
882 ///
883 /// ```
884 /// use portable_atomic_util::Arc;
885 ///
886 /// let x = Arc::new("hello".to_owned());
887 /// let x_ptr = Arc::into_raw(x);
888 /// assert_eq!(unsafe { &*x_ptr }, "hello");
889 /// # // Prevent leaks for Miri.
890 /// # drop(unsafe { Arc::from_raw(x_ptr) });
891 /// ```
892 #[must_use = "losing the pointer will leak memory"]
893 pub fn into_raw(this: Self) -> *const T {
894 let this = ManuallyDrop::new(this);
895 Self::as_ptr(&*this)
896 }
897
898 /// Increments the strong reference count on the `Arc<T>` associated with the
899 /// provided pointer by one.
900 ///
901 /// # Safety
902 ///
903 /// The pointer must have been obtained through `Arc::into_raw` and must satisfy the
904 /// same layout requirements specified in [`Arc::from_raw`].
905 /// The associated `Arc` instance must be valid (i.e. the strong count must be at
906 /// least 1) for the duration of this method, and `ptr` must point to a block of memory
907 /// allocated by the global allocator.
908 ///
909 /// # Examples
910 ///
911 /// ```
912 /// use portable_atomic_util::Arc;
913 ///
914 /// let five = Arc::new(5);
915 ///
916 /// unsafe {
917 /// let ptr = Arc::into_raw(five);
918 /// Arc::increment_strong_count(ptr);
919 ///
920 /// // This assertion is deterministic because we haven't shared
921 /// // the `Arc` between threads.
922 /// let five = Arc::from_raw(ptr);
923 /// assert_eq!(2, Arc::strong_count(&five));
924 /// # // Prevent leaks for Miri.
925 /// # Arc::decrement_strong_count(ptr);
926 /// }
927 /// ```
928 #[inline]
929 pub unsafe fn increment_strong_count(ptr: *const T) {
930 // Retain Arc, but don't touch refcount by wrapping in ManuallyDrop
931 let arc = unsafe { mem::ManuallyDrop::new(Self::from_raw(ptr)) };
932 // Now increase refcount, but don't drop new refcount either
933 let _arc_clone: mem::ManuallyDrop<_> = arc.clone();
934 }
935
936 /// Decrements the strong reference count on the `Arc<T>` associated with the
937 /// provided pointer by one.
938 ///
939 /// # Safety
940 ///
941 /// The pointer must have been obtained through `Arc::into_raw` and must satisfy the
942 /// same layout requirements specified in [`Arc::from_raw`].
943 /// The associated `Arc` instance must be valid (i.e. the strong count must be at
944 /// least 1) when invoking this method, and `ptr` must point to a block of memory
945 /// allocated by the global allocator. This method can be used to release the final
946 /// `Arc` and backing storage, but **should not** be called after the final `Arc` has been
947 /// released.
948 ///
949 /// # Examples
950 ///
951 /// ```
952 /// use portable_atomic_util::Arc;
953 ///
954 /// let five = Arc::new(5);
955 ///
956 /// unsafe {
957 /// let ptr = Arc::into_raw(five);
958 /// Arc::increment_strong_count(ptr);
959 ///
960 /// // Those assertions are deterministic because we haven't shared
961 /// // the `Arc` between threads.
962 /// let five = Arc::from_raw(ptr);
963 /// assert_eq!(2, Arc::strong_count(&five));
964 /// Arc::decrement_strong_count(ptr);
965 /// assert_eq!(1, Arc::strong_count(&five));
966 /// }
967 /// ```
968 #[inline]
969 pub unsafe fn decrement_strong_count(ptr: *const T) {
970 // SAFETY: the caller must uphold the safety contract.
971 unsafe { drop(Self::from_raw(ptr)) }
972 }
973
974 /// Provides a raw pointer to the data.
975 ///
976 /// The counts are not affected in any way and the `Arc` is not consumed. The pointer is valid for
977 /// as long as there are strong counts in the `Arc`.
978 ///
979 /// # Examples
980 ///
981 /// ```
982 /// use portable_atomic_util::Arc;
983 ///
984 /// let x = Arc::new("hello".to_owned());
985 /// let y = Arc::clone(&x);
986 /// let x_ptr = Arc::as_ptr(&x);
987 /// assert_eq!(x_ptr, Arc::as_ptr(&y));
988 /// assert_eq!(unsafe { &*x_ptr }, "hello");
989 /// ```
990 #[must_use]
991 pub fn as_ptr(this: &Self) -> *const T {
992 let ptr: *mut ArcInner<T> = NonNull::as_ptr(this.ptr);
993
994 // SAFETY: This cannot go through Deref::deref or ArcInnerPtr::inner because
995 // this is required to retain raw/mut provenance such that e.g. `get_mut` can
996 // write through the pointer after the Arc is recovered through `from_raw`.
997 unsafe { data_ptr::<T>(ptr, &**this) }
998 }
999
1000 /// Creates a new [`Weak`] pointer to this allocation.
1001 ///
1002 /// # Examples
1003 ///
1004 /// ```
1005 /// use portable_atomic_util::Arc;
1006 ///
1007 /// let five = Arc::new(5);
1008 ///
1009 /// let weak_five = Arc::downgrade(&five);
1010 /// ```
1011 #[must_use = "this returns a new `Weak` pointer, \
1012 without modifying the original `Arc`"]
1013 #[allow(clippy::missing_panics_doc)]
1014 pub fn downgrade(this: &Self) -> Weak<T> {
1015 // This Relaxed is OK because we're checking the value in the CAS
1016 // below.
1017 let mut cur = this.inner().weak.load(Relaxed);
1018
1019 loop {
1020 // check if the weak counter is currently "locked"; if so, spin.
1021 if cur == USIZE_MAX {
1022 hint::spin_loop();
1023 cur = this.inner().weak.load(Relaxed);
1024 continue;
1025 }
1026
1027 // We can't allow the refcount to increase much past `MAX_REFCOUNT`.
1028 assert!(cur <= MAX_REFCOUNT, "{}", INTERNAL_OVERFLOW_ERROR);
1029
1030 // NOTE: this code currently ignores the possibility of overflow
1031 // into usize::MAX; in general both Rc and Arc need to be adjusted
1032 // to deal with overflow.
1033
1034 // Unlike with Clone(), we need this to be an Acquire read to
1035 // synchronize with the write coming from `is_unique`, so that the
1036 // events prior to that write happen before this read.
1037 match this.inner().weak.compare_exchange_weak(cur, cur + 1, Acquire, Relaxed) {
1038 Ok(_) => {
1039 // Make sure we do not create a dangling Weak
1040 debug_assert!(!is_dangling(this.ptr.as_ptr()));
1041 return Weak { ptr: this.ptr };
1042 }
1043 Err(old) => cur = old,
1044 }
1045 }
1046 }
1047
1048 /// Gets the number of [`Weak`] pointers to this allocation.
1049 ///
1050 /// # Safety
1051 ///
1052 /// This method by itself is safe, but using it correctly requires extra care.
1053 /// Another thread can change the weak count at any time,
1054 /// including potentially between calling this method and acting on the result.
1055 ///
1056 /// # Examples
1057 ///
1058 /// ```
1059 /// use portable_atomic_util::Arc;
1060 ///
1061 /// let five = Arc::new(5);
1062 /// let _weak_five = Arc::downgrade(&five);
1063 ///
1064 /// // This assertion is deterministic because we haven't shared
1065 /// // the `Arc` or `Weak` between threads.
1066 /// assert_eq!(1, Arc::weak_count(&five));
1067 /// ```
1068 #[inline]
1069 #[must_use]
1070 pub fn weak_count(this: &Self) -> usize {
1071 let cnt = this.inner().weak.load(Relaxed);
1072 // If the weak count is currently locked, the value of the
1073 // count was 0 just before taking the lock.
1074 if cnt == USIZE_MAX { 0 } else { cnt - 1 }
1075 }
1076
1077 /// Gets the number of strong (`Arc`) pointers to this allocation.
1078 ///
1079 /// # Safety
1080 ///
1081 /// This method by itself is safe, but using it correctly requires extra care.
1082 /// Another thread can change the strong count at any time,
1083 /// including potentially between calling this method and acting on the result.
1084 ///
1085 /// # Examples
1086 ///
1087 /// ```
1088 /// use portable_atomic_util::Arc;
1089 ///
1090 /// let five = Arc::new(5);
1091 /// let _also_five = Arc::clone(&five);
1092 ///
1093 /// // This assertion is deterministic because we haven't shared
1094 /// // the `Arc` between threads.
1095 /// assert_eq!(2, Arc::strong_count(&five));
1096 /// ```
1097 #[inline]
1098 #[must_use]
1099 pub fn strong_count(this: &Self) -> usize {
1100 this.inner().strong.load(Relaxed)
1101 }
1102
1103 #[inline]
1104 fn inner(&self) -> &ArcInner<T> {
1105 // This unsafety is ok because while this arc is alive we're guaranteed
1106 // that the inner pointer is valid. Furthermore, we know that the
1107 // `ArcInner` structure itself is `Sync` because the inner data is
1108 // `Sync` as well, so we're ok loaning out an immutable pointer to these
1109 // contents.
1110 unsafe { self.ptr.as_ref() }
1111 }
1112
1113 // Non-inlined part of `drop`.
1114 #[inline(never)]
1115 unsafe fn drop_slow(&mut self) {
1116 // Drop the weak ref collectively held by all strong references when this
1117 // variable goes out of scope. This ensures that the memory is deallocated
1118 // even if the destructor of `T` panics.
1119 // Take a reference to `self.alloc` instead of cloning because 1. it'll last long
1120 // enough, and 2. you should be able to drop `Arc`s with unclonable allocators
1121 let _weak = Weak { ptr: self.ptr };
1122
1123 // Destroy the data at this time, even though we must not free the box
1124 // allocation itself (there might still be weak pointers lying around).
1125 // We cannot use `get_mut_unchecked` here, because `self.alloc` is borrowed.
1126 unsafe { ptr::drop_in_place(&mut (*self.ptr.as_ptr()).data) }
1127 }
1128
1129 /// Returns `true` if the two `Arc`s point to the same allocation in a vein similar to
1130 /// [`ptr::eq`]. This function ignores the metadata of `dyn Trait` pointers.
1131 ///
1132 /// # Examples
1133 ///
1134 /// ```
1135 /// use portable_atomic_util::Arc;
1136 ///
1137 /// let five = Arc::new(5);
1138 /// let same_five = Arc::clone(&five);
1139 /// let other_five = Arc::new(5);
1140 ///
1141 /// assert!(Arc::ptr_eq(&five, &same_five));
1142 /// assert!(!Arc::ptr_eq(&five, &other_five));
1143 /// ```
1144 ///
1145 /// [`ptr::eq`]: core::ptr::eq "ptr::eq"
1146 #[inline]
1147 #[must_use]
1148 pub fn ptr_eq(this: &Self, other: &Self) -> bool {
1149 ptr::eq(this.ptr.as_ptr() as *const (), other.ptr.as_ptr() as *const ())
1150 }
1151}
1152
1153impl<T: ?Sized> Arc<T> {
1154 /// Allocates an `ArcInner<T>` with sufficient space for
1155 /// a possibly-unsized inner value where the value has the layout provided.
1156 ///
1157 /// The function `mem_to_arc_inner` is called with the data pointer
1158 /// and must return back a (potentially fat)-pointer for the `ArcInner<T>`.
1159 unsafe fn allocate_for_layout(
1160 value_layout: Layout,
1161 allocate: impl FnOnce(Layout) -> Option<NonNull<u8>>,
1162 mem_to_arc_inner: impl FnOnce(*mut u8) -> *mut ArcInner<T>,
1163 ) -> *mut ArcInner<T> {
1164 let layout = arc_inner_layout_for_value_layout(value_layout);
1165
1166 let ptr = allocate(layout).unwrap_or_else(|| handle_alloc_error(layout));
1167
1168 unsafe { Self::initialize_arc_inner(ptr, layout, mem_to_arc_inner) }
1169 }
1170
1171 unsafe fn initialize_arc_inner(
1172 ptr: NonNull<u8>,
1173 _layout: Layout,
1174 mem_to_arc_inner: impl FnOnce(*mut u8) -> *mut ArcInner<T>,
1175 ) -> *mut ArcInner<T> {
1176 let inner: *mut ArcInner<T> = mem_to_arc_inner(ptr.as_ptr());
1177 // debug_assert_eq!(unsafe { Layout::for_value_raw(inner) }, layout); // for_value_raw is unstable
1178
1179 // SAFETY: mem_to_arc_inner return a valid pointer to uninitialized ArcInner<T>.
1180 // ArcInner<T> is repr(C), and strong and weak are the first and second fields and
1181 // are the same type, so `inner as *mut atomic::AtomicUsize` is strong and
1182 // `(inner as *mut atomic::AtomicUsize).add(1)` is weak.
1183 unsafe {
1184 let strong = inner as *mut atomic::AtomicUsize;
1185 strong.write(atomic::AtomicUsize::new(1));
1186 let weak = strong.add(1);
1187 weak.write(atomic::AtomicUsize::new(1));
1188 }
1189
1190 inner
1191 }
1192}
1193
1194impl<T: ?Sized> Arc<T> {
1195 /// Allocates an `ArcInner<T>` with sufficient space for an unsized inner value.
1196 #[inline]
1197 unsafe fn allocate_for_value(value: &T) -> *mut ArcInner<T> {
1198 let ptr: *const T = value;
1199 // Allocate for the `ArcInner<T>` using the given value.
1200 unsafe {
1201 Self::allocate_for_layout(
1202 Layout::for_value(value),
1203 |layout| Global.allocate(layout),
1204 |mem| strict::with_metadata_of(mem, ptr as *const ArcInner<T>),
1205 )
1206 }
1207 }
1208
1209 fn from_box(src: Box<T>) -> Arc<T> {
1210 unsafe {
1211 let value_size = mem::size_of_val(&*src);
1212 let ptr = Self::allocate_for_value(&*src);
1213
1214 // Copy value as bytes
1215 ptr::copy_nonoverlapping(
1216 &*src as *const T as *const u8,
1217 data_ptr::<T>(ptr, &*src) as *mut u8,
1218 value_size,
1219 );
1220
1221 // Free the allocation without dropping its contents
1222 let box_ptr = Box::into_raw(src);
1223 let src = Box::from_raw(box_ptr as *mut mem::ManuallyDrop<T>);
1224 drop(src);
1225
1226 Self::from_ptr(ptr)
1227 }
1228 }
1229}
1230
1231impl<T> Arc<[T]> {
1232 /// Allocates an `ArcInner<[mem::MaybeUninit<T>]>` with the given length.
1233 unsafe fn allocate_for_slice(len: usize) -> *mut ArcInner<[mem::MaybeUninit<T>]> {
1234 unsafe {
1235 Arc::allocate_for_layout(
1236 layout::array::<T>(len).unwrap(),
1237 |layout| Global.allocate(layout),
1238 |mem| {
1239 // We create a slice just for metadata (we must use `[mem::MaybeUninit<T>]`
1240 // instead of `[T]` because values behind `mem` is not valid initialized `T`s.
1241 // there is no size/alignment issue thanks to layout::array), and create a
1242 // pointer from `mem` and slice's metadata.
1243 //
1244 // We cannot use other ways here:
1245 // - ptr::slice_from_raw_parts_mut is best way here, but requires Rust 1.42.
1246 // - We cannot use slice::from_raw_parts_mut then casting to its pointer to
1247 // ArcInner due to provenance because the actual size of valid allocation
1248 // behind `mem` is `layout.size()` bytes (counters + values + padding) but the
1249 // allocation from the pointer from slice::from_raw_parts_mut only valid for
1250 // `size_of::<T> * len` bytes (only values).
1251 let meta: *const _ =
1252 slice::from_raw_parts(mem as *const mem::MaybeUninit<T>, len);
1253 strict::with_metadata_of(mem, meta) as *mut ArcInner<[mem::MaybeUninit<T>]>
1254 },
1255 )
1256 }
1257 }
1258
1259 /// Constructs an `Arc<[T]>` from an iterator known to be of a certain size.
1260 ///
1261 /// Behavior is undefined should the size be wrong.
1262 unsafe fn from_iter_exact(iter: impl Iterator<Item = T>, len: usize) -> Self {
1263 // Panic guard while cloning T elements.
1264 // In the event of a panic, elements that have been written
1265 // into the new ArcInner will be dropped, then the memory freed.
1266 struct Guard<T> {
1267 mem: NonNull<u8>,
1268 elems: *mut T,
1269 layout: Layout,
1270 n_elems: usize,
1271 }
1272
1273 impl<T> Drop for Guard<T> {
1274 fn drop(&mut self) {
1275 unsafe {
1276 let slice = slice::from_raw_parts_mut(self.elems, self.n_elems);
1277 ptr::drop_in_place(slice);
1278
1279 Global.deallocate(self.mem, self.layout);
1280 }
1281 }
1282 }
1283
1284 unsafe {
1285 let ptr: *mut ArcInner<[mem::MaybeUninit<T>]> = Arc::allocate_for_slice(len);
1286
1287 let mem = ptr as *mut _ as *mut u8;
1288 let layout = Layout::for_value(&*ptr);
1289
1290 // Pointer to first element
1291 let elems = (*ptr).data.as_mut_ptr() as *mut T;
1292
1293 let mut guard = Guard { mem: NonNull::new_unchecked(mem), elems, layout, n_elems: 0 };
1294
1295 for (i, item) in iter.enumerate() {
1296 ptr::write(elems.add(i), item);
1297 guard.n_elems += 1;
1298 }
1299
1300 // All clear. Forget the guard so it doesn't free the new ArcInner.
1301 mem::forget(guard);
1302
1303 Arc::from_ptr(ptr).assume_init()
1304 }
1305 }
1306}
1307
1308impl<T: ?Sized> Clone for Arc<T> {
1309 /// Makes a clone of the `Arc` pointer.
1310 ///
1311 /// This creates another pointer to the same allocation, increasing the
1312 /// strong reference count.
1313 ///
1314 /// # Examples
1315 ///
1316 /// ```
1317 /// use portable_atomic_util::Arc;
1318 ///
1319 /// let five = Arc::new(5);
1320 ///
1321 /// let _ = Arc::clone(&five);
1322 /// ```
1323 #[inline]
1324 fn clone(&self) -> Self {
1325 // Using a relaxed ordering is alright here, as knowledge of the
1326 // original reference prevents other threads from erroneously deleting
1327 // the object.
1328 //
1329 // As explained in the [Boost documentation][1], Increasing the
1330 // reference counter can always be done with memory_order_relaxed: New
1331 // references to an object can only be formed from an existing
1332 // reference, and passing an existing reference from one thread to
1333 // another must already provide any required synchronization.
1334 //
1335 // [1]: (www.boost.org/doc/libs/1_55_0/doc/html/atomic/usage_examples.html)
1336 let old_size = self.inner().strong.fetch_add(1, Relaxed);
1337
1338 // However we need to guard against massive refcounts in case someone is `mem::forget`ing
1339 // Arcs. If we don't do this the count can overflow and users will use-after free. This
1340 // branch will never be taken in any realistic program. We abort because such a program is
1341 // incredibly degenerate, and we don't care to support it.
1342 //
1343 // This check is not 100% water-proof: we error when the refcount grows beyond `isize::MAX`.
1344 // But we do that check *after* having done the increment, so there is a chance here that
1345 // the worst already happened and we actually do overflow the `usize` counter. However, that
1346 // requires the counter to grow from `isize::MAX` to `usize::MAX` between the increment
1347 // above and the `abort` below, which seems exceedingly unlikely.
1348 //
1349 // This is a global invariant, and also applies when using a compare-exchange loop to increment
1350 // counters in other methods.
1351 // Otherwise, the counter could be brought to an almost-overflow using a compare-exchange loop,
1352 // and then overflow using a few `fetch_add`s.
1353 if old_size > MAX_REFCOUNT {
1354 abort();
1355 }
1356
1357 unsafe { Self::from_inner(self.ptr) }
1358 }
1359}
1360
1361impl<T: ?Sized> Deref for Arc<T> {
1362 type Target = T;
1363
1364 #[inline]
1365 fn deref(&self) -> &Self::Target {
1366 &self.inner().data
1367 }
1368}
1369
1370impl<T: ?Sized + CloneToUninit> Arc<T> {
1371 /// Makes a mutable reference into the given `Arc`.
1372 ///
1373 /// If there are other `Arc` pointers to the same allocation, then `make_mut` will
1374 /// [`clone`] the inner value to a new allocation to ensure unique ownership. This is also
1375 /// referred to as clone-on-write.
1376 ///
1377 /// However, if there are no other `Arc` pointers to this allocation, but some [`Weak`]
1378 /// pointers, then the [`Weak`] pointers will be dissociated and the inner value will not
1379 /// be cloned.
1380 ///
1381 /// See also [`get_mut`], which will fail rather than cloning the inner value
1382 /// or dissociating [`Weak`] pointers.
1383 ///
1384 /// [`clone`]: Clone::clone
1385 /// [`get_mut`]: Arc::get_mut
1386 ///
1387 /// # Examples
1388 ///
1389 /// ```
1390 /// use portable_atomic_util::Arc;
1391 ///
1392 /// let mut data = Arc::new(5);
1393 ///
1394 /// *Arc::make_mut(&mut data) += 1; // Won't clone anything
1395 /// let mut other_data = Arc::clone(&data); // Won't clone inner data
1396 /// *Arc::make_mut(&mut data) += 1; // Clones inner data
1397 /// *Arc::make_mut(&mut data) += 1; // Won't clone anything
1398 /// *Arc::make_mut(&mut other_data) *= 2; // Won't clone anything
1399 ///
1400 /// // Now `data` and `other_data` point to different allocations.
1401 /// assert_eq!(*data, 8);
1402 /// assert_eq!(*other_data, 12);
1403 /// ```
1404 ///
1405 /// [`Weak`] pointers will be dissociated:
1406 ///
1407 /// ```
1408 /// use portable_atomic_util::Arc;
1409 ///
1410 /// let mut data = Arc::new(75);
1411 /// let weak = Arc::downgrade(&data);
1412 ///
1413 /// assert_eq!(75, *data);
1414 /// assert_eq!(75, *weak.upgrade().unwrap());
1415 ///
1416 /// *Arc::make_mut(&mut data) += 1;
1417 ///
1418 /// assert_eq!(76, *data);
1419 /// assert!(weak.upgrade().is_none());
1420 /// ```
1421 #[inline]
1422 pub fn make_mut(this: &mut Self) -> &mut T {
1423 let size_of_val = mem::size_of_val::<T>(&**this);
1424
1425 // Note that we hold both a strong reference and a weak reference.
1426 // Thus, releasing our strong reference only will not, by itself, cause
1427 // the memory to be deallocated.
1428 //
1429 // Use Acquire to ensure that we see any writes to `weak` that happen
1430 // before release writes (i.e., decrements) to `strong`. Since we hold a
1431 // weak count, there's no chance the ArcInner itself could be
1432 // deallocated.
1433 if this.inner().strong.compare_exchange(1, 0, Acquire, Relaxed).is_err() {
1434 // Another strong pointer exists, so we must clone.
1435 *this = Arc::clone_from_ref(&**this);
1436 } else if this.inner().weak.load(Relaxed) != 1 {
1437 // Relaxed suffices in the above because this is fundamentally an
1438 // optimization: we are always racing with weak pointers being
1439 // dropped. Worst case, we end up allocated a new Arc unnecessarily.
1440
1441 // We removed the last strong ref, but there are additional weak
1442 // refs remaining. We'll move the contents to a new Arc, and
1443 // invalidate the other weak refs.
1444
1445 // Note that it is not possible for the read of `weak` to yield
1446 // usize::MAX (i.e., locked), since the weak count can only be
1447 // locked by a thread with a strong reference.
1448
1449 // Materialize our own implicit weak pointer, so that it can clean
1450 // up the ArcInner as needed.
1451 let _weak = Weak { ptr: this.ptr };
1452
1453 // Can just steal the data, all that's left is `Weak`s
1454 //
1455 // We don't need panic-protection like the above branch does, but we might as well
1456 // use the same mechanism.
1457 let mut in_progress: UniqueArcUninit<T> = UniqueArcUninit::new(&**this);
1458 unsafe {
1459 // Initialize `in_progress` with move of **this.
1460 // We have to express this in terms of bytes because `T: ?Sized`; there is no
1461 // operation that just copies a value based on its `size_of_val()`.
1462 ptr::copy_nonoverlapping(
1463 &**this as *const T as *const u8,
1464 in_progress.data_ptr() as *mut u8,
1465 size_of_val,
1466 );
1467
1468 ptr::write(this, in_progress.into_arc());
1469 }
1470 } else {
1471 // We were the sole reference of either kind; bump back up the
1472 // strong ref count.
1473 this.inner().strong.store(1, Release);
1474 }
1475
1476 // As with `get_mut()`, the unsafety is ok because our reference was
1477 // either unique to begin with, or became one upon cloning the contents.
1478 unsafe { Self::get_mut_unchecked(this) }
1479 }
1480}
1481
1482impl<T: Clone> Arc<T> {
1483 /// If we have the only reference to `T` then unwrap it. Otherwise, clone `T` and return the
1484 /// clone.
1485 ///
1486 /// Assuming `arc_t` is of type `Arc<T>`, this function is functionally equivalent to
1487 /// `(*arc_t).clone()`, but will avoid cloning the inner value where possible.
1488 ///
1489 /// # Examples
1490 ///
1491 /// ```
1492 /// use std::ptr;
1493 ///
1494 /// use portable_atomic_util::Arc;
1495 ///
1496 /// let inner = String::from("test");
1497 /// let ptr = inner.as_ptr();
1498 ///
1499 /// let arc = Arc::new(inner);
1500 /// let inner = Arc::unwrap_or_clone(arc);
1501 /// // The inner value was not cloned
1502 /// assert!(ptr::eq(ptr, inner.as_ptr()));
1503 ///
1504 /// let arc = Arc::new(inner);
1505 /// let arc2 = arc.clone();
1506 /// let inner = Arc::unwrap_or_clone(arc);
1507 /// // Because there were 2 references, we had to clone the inner value.
1508 /// assert!(!ptr::eq(ptr, inner.as_ptr()));
1509 /// // `arc2` is the last reference, so when we unwrap it we get back
1510 /// // the original `String`.
1511 /// let inner = Arc::unwrap_or_clone(arc2);
1512 /// assert!(ptr::eq(ptr, inner.as_ptr()));
1513 /// ```
1514 #[inline]
1515 pub fn unwrap_or_clone(this: Self) -> T {
1516 Self::try_unwrap(this).unwrap_or_else(|arc| (*arc).clone())
1517 }
1518}
1519
1520impl<T: ?Sized> Arc<T> {
1521 /// Returns a mutable reference into the given `Arc`, if there are
1522 /// no other `Arc` or [`Weak`] pointers to the same allocation.
1523 ///
1524 /// Returns [`None`] otherwise, because it is not safe to
1525 /// mutate a shared value.
1526 ///
1527 /// See also [`make_mut`][make_mut], which will [`clone`][clone]
1528 /// the inner value when there are other `Arc` pointers.
1529 ///
1530 /// [make_mut]: Arc::make_mut
1531 /// [clone]: Clone::clone
1532 ///
1533 /// # Examples
1534 ///
1535 /// ```
1536 /// use portable_atomic_util::Arc;
1537 ///
1538 /// let mut x = Arc::new(3);
1539 /// *Arc::get_mut(&mut x).unwrap() = 4;
1540 /// assert_eq!(*x, 4);
1541 ///
1542 /// let _y = Arc::clone(&x);
1543 /// assert!(Arc::get_mut(&mut x).is_none());
1544 /// ```
1545 #[inline]
1546 pub fn get_mut(this: &mut Self) -> Option<&mut T> {
1547 if Self::is_unique(this) {
1548 // This unsafety is ok because we're guaranteed that the pointer
1549 // returned is the *only* pointer that will ever be returned to T. Our
1550 // reference count is guaranteed to be 1 at this point, and we required
1551 // the Arc itself to be `mut`, so we're returning the only possible
1552 // reference to the inner data.
1553 unsafe { Some(Self::get_mut_unchecked(this)) }
1554 } else {
1555 None
1556 }
1557 }
1558
1559 #[inline]
1560 unsafe fn get_mut_unchecked(this: &mut Self) -> &mut T {
1561 // We are careful to *not* create a reference covering the "count" fields, as
1562 // this would alias with concurrent access to the reference counts (e.g. by `Weak`).
1563 unsafe { &mut (*this.ptr.as_ptr()).data }
1564 }
1565
1566 #[inline]
1567 fn is_unique(this: &Self) -> bool {
1568 // lock the weak pointer count if we appear to be the sole weak pointer
1569 // holder.
1570 //
1571 // The acquire label here ensures a happens-before relationship with any
1572 // writes to `strong` (in particular in `Weak::upgrade`) prior to decrements
1573 // of the `weak` count (via `Weak::drop`, which uses release). If the upgraded
1574 // weak ref was never dropped, the CAS here will fail so we do not care to synchronize.
1575 if this.inner().weak.compare_exchange(1, USIZE_MAX, Acquire, Relaxed).is_ok() {
1576 // This needs to be an `Acquire` to synchronize with the decrement of the `strong`
1577 // counter in `drop` -- the only access that happens when any but the last reference
1578 // is being dropped.
1579 let unique = this.inner().strong.load(Acquire) == 1;
1580
1581 // The release write here synchronizes with a read in `downgrade`,
1582 // effectively preventing the above read of `strong` from happening
1583 // after the write.
1584 this.inner().weak.store(1, Release); // release the lock
1585 unique
1586 } else {
1587 false
1588 }
1589 }
1590}
1591
1592impl<T: ?Sized> Drop for Arc<T> {
1593 /// Drops the `Arc`.
1594 ///
1595 /// This will decrement the strong reference count. If the strong reference
1596 /// count reaches zero then the only other references (if any) are
1597 /// [`Weak`], so we `drop` the inner value.
1598 ///
1599 /// # Examples
1600 ///
1601 /// ```
1602 /// use portable_atomic_util::Arc;
1603 ///
1604 /// struct Foo;
1605 ///
1606 /// impl Drop for Foo {
1607 /// fn drop(&mut self) {
1608 /// println!("dropped!");
1609 /// }
1610 /// }
1611 ///
1612 /// let foo = Arc::new(Foo);
1613 /// let foo2 = Arc::clone(&foo);
1614 ///
1615 /// drop(foo); // Doesn't print anything
1616 /// drop(foo2); // Prints "dropped!"
1617 /// ```
1618 #[inline]
1619 fn drop(&mut self) {
1620 // Because `fetch_sub` is already atomic, we do not need to synchronize
1621 // with other threads unless we are going to delete the object. This
1622 // same logic applies to the below `fetch_sub` to the `weak` count.
1623 if self.inner().strong.fetch_sub(1, Release) != 1 {
1624 return;
1625 }
1626
1627 // This fence is needed to prevent reordering of use of the data and
1628 // deletion of the data. Because it is marked `Release`, the decreasing
1629 // of the reference count synchronizes with this `Acquire` fence. This
1630 // means that use of the data happens before decreasing the reference
1631 // count, which happens before this fence, which happens before the
1632 // deletion of the data.
1633 //
1634 // As explained in the [Boost documentation][1],
1635 //
1636 // > It is important to enforce any possible access to the object in one
1637 // > thread (through an existing reference) to *happen before* deleting
1638 // > the object in a different thread. This is achieved by a "release"
1639 // > operation after dropping a reference (any access to the object
1640 // > through this reference must obviously happened before), and an
1641 // > "acquire" operation before deleting the object.
1642 //
1643 // In particular, while the contents of an Arc are usually immutable, it's
1644 // possible to have interior writes to something like a Mutex<T>. Since a
1645 // Mutex is not acquired when it is deleted, we can't rely on its
1646 // synchronization logic to make writes in thread A visible to a destructor
1647 // running in thread B.
1648 //
1649 // Also note that the Acquire fence here could probably be replaced with an
1650 // Acquire load, which could improve performance in highly-contended
1651 // situations. See [2].
1652 //
1653 // [1]: (www.boost.org/doc/libs/1_55_0/doc/html/atomic/usage_examples.html)
1654 // [2]: (https://github.com/rust-lang/rust/pull/41714)
1655 acquire!(self.inner().strong);
1656
1657 unsafe {
1658 self.drop_slow();
1659 }
1660 }
1661}
1662
1663impl Arc<dyn Any + Send + Sync> {
1664 /// Attempts to downcast the `Arc<dyn Any + Send + Sync>` to a concrete type.
1665 ///
1666 /// # Examples
1667 ///
1668 /// ```
1669 /// use std::any::Any;
1670 ///
1671 /// use portable_atomic_util::Arc;
1672 ///
1673 /// fn print_if_string(value: Arc<dyn Any + Send + Sync>) {
1674 /// if let Ok(string) = value.downcast::<String>() {
1675 /// println!("String ({}): {}", string.len(), string);
1676 /// }
1677 /// }
1678 ///
1679 /// let my_string = "Hello World".to_string();
1680 /// print_if_string(Arc::from(Box::new(my_string) as Box<dyn Any + Send + Sync>));
1681 /// print_if_string(Arc::from(Box::new(0i8) as Box<dyn Any + Send + Sync>));
1682 /// // or with "--cfg portable_atomic_unstable_coerce_unsized" in RUSTFLAGS (requires Rust nightly):
1683 /// // print_if_string(Arc::new(my_string));
1684 /// // print_if_string(Arc::new(0i8));
1685 /// ```
1686 #[inline]
1687 pub fn downcast<T>(self) -> Result<Arc<T>, Self>
1688 where
1689 T: Any + Send + Sync,
1690 {
1691 if (*self).is::<T>() {
1692 unsafe {
1693 let ptr = Arc::into_inner_non_null(self);
1694 Ok(Arc::from_inner(ptr.cast::<ArcInner<T>>()))
1695 }
1696 } else {
1697 Err(self)
1698 }
1699 }
1700}
1701
1702impl<T> Weak<T> {
1703 /// Constructs a new `Weak<T>`, without allocating any memory.
1704 /// Calling [`upgrade`] on the return value always gives [`None`].
1705 ///
1706 /// [`upgrade`]: Weak::upgrade
1707 ///
1708 /// # Examples
1709 ///
1710 /// ```
1711 /// use portable_atomic_util::Weak;
1712 ///
1713 /// let empty: Weak<i64> = Weak::new();
1714 /// assert!(empty.upgrade().is_none());
1715 /// ```
1716 #[inline]
1717 #[must_use]
1718 pub const fn new() -> Self {
1719 Self {
1720 ptr: unsafe {
1721 NonNull::new_unchecked(strict::without_provenance_mut::<ArcInner<T>>(USIZE_MAX))
1722 },
1723 }
1724 }
1725
1726 #[inline]
1727 #[must_use]
1728 fn new_uninit_ptr() -> NonNull<ArcInner<T>> {
1729 unsafe {
1730 NonNull::new_unchecked(Self::allocate_for_layout(
1731 Layout::new::<T>(),
1732 |layout| Global.allocate(layout),
1733 |ptr| ptr as *mut _,
1734 ))
1735 }
1736 }
1737}
1738
1739/// Helper type to allow accessing the reference counts without
1740/// making any assertions about the data field.
1741struct WeakInner<'a> {
1742 weak: &'a atomic::AtomicUsize,
1743 strong: &'a atomic::AtomicUsize,
1744}
1745
1746// TODO: See todo comment in Weak::from_raw
1747impl<T /*: ?Sized */> Weak<T> {
1748 /// Converts a raw pointer previously created by [`into_raw`] back into `Weak<T>`.
1749 ///
1750 /// This can be used to safely get a strong reference (by calling [`upgrade`]
1751 /// later) or to deallocate the weak count by dropping the `Weak<T>`.
1752 ///
1753 /// It takes ownership of one weak reference (with the exception of pointers created by [`new`],
1754 /// as these don't own anything; the method still works on them).
1755 ///
1756 /// # Safety
1757 ///
1758 /// The pointer must have originated from the [`into_raw`] and must still own its potential
1759 /// weak reference, and must point to a block of memory allocated by global allocator.
1760 ///
1761 /// It is allowed for the strong count to be 0 at the time of calling this. Nevertheless, this
1762 /// takes ownership of one weak reference currently represented as a raw pointer (the weak
1763 /// count is not modified by this operation) and therefore it must be paired with a previous
1764 /// call to [`into_raw`].
1765 /// # Examples
1766 ///
1767 /// ```
1768 /// use portable_atomic_util::{Arc, Weak};
1769 ///
1770 /// let strong = Arc::new("hello".to_owned());
1771 ///
1772 /// let raw_1 = Arc::downgrade(&strong).into_raw();
1773 /// let raw_2 = Arc::downgrade(&strong).into_raw();
1774 ///
1775 /// assert_eq!(2, Arc::weak_count(&strong));
1776 ///
1777 /// assert_eq!("hello", &*unsafe { Weak::from_raw(raw_1) }.upgrade().unwrap());
1778 /// assert_eq!(1, Arc::weak_count(&strong));
1779 ///
1780 /// drop(strong);
1781 ///
1782 /// // Decrement the last weak count.
1783 /// assert!(unsafe { Weak::from_raw(raw_2) }.upgrade().is_none());
1784 /// ```
1785 ///
1786 /// [`new`]: Weak::new
1787 /// [`into_raw`]: Weak::into_raw
1788 /// [`upgrade`]: Weak::upgrade
1789 #[inline]
1790 pub unsafe fn from_raw(ptr: *const T) -> Self {
1791 // See Weak::as_ptr for context on how the input pointer is derived.
1792
1793 let ptr = if is_dangling(ptr) {
1794 // This is a dangling Weak.
1795 ptr as *mut ArcInner<T>
1796 } else {
1797 // Otherwise, we're guaranteed the pointer came from a non-dangling Weak.
1798 // TODO: data_offset calls align_of_val which needs to create a reference
1799 // to data but we cannot create a reference to data here since data in Weak
1800 // can be dropped concurrently from another thread. Therefore, we can
1801 // only support sized types that can avoid references to data
1802 // unless align_of_val_raw is stabilized.
1803 // // SAFETY: data_offset is safe to call, as ptr references a real (potentially dropped) T.
1804 // let offset = unsafe { data_offset(ptr) };
1805 let offset = data_offset_align(mem::align_of::<T>());
1806 // Thus, we reverse the offset to get the whole ArcInner.
1807 // SAFETY: the pointer originated from a Weak, so this offset is safe.
1808 unsafe { strict::byte_sub(ptr as *mut T, offset) as *mut ArcInner<T> }
1809 };
1810
1811 // SAFETY: we now have recovered the original Weak pointer, so can create the Weak.
1812 Self { ptr: unsafe { NonNull::new_unchecked(ptr) } }
1813 }
1814
1815 /// Consumes the `Weak<T>` and turns it into a raw pointer.
1816 ///
1817 /// This converts the weak pointer into a raw pointer, while still preserving the ownership of
1818 /// one weak reference (the weak count is not modified by this operation). It can be turned
1819 /// back into the `Weak<T>` with [`from_raw`].
1820 ///
1821 /// The same restrictions of accessing the target of the pointer as with
1822 /// [`as_ptr`] apply.
1823 ///
1824 /// # Examples
1825 ///
1826 /// ```
1827 /// use portable_atomic_util::{Arc, Weak};
1828 ///
1829 /// let strong = Arc::new("hello".to_owned());
1830 /// let weak = Arc::downgrade(&strong);
1831 /// let raw = weak.into_raw();
1832 ///
1833 /// assert_eq!(1, Arc::weak_count(&strong));
1834 /// assert_eq!("hello", unsafe { &*raw });
1835 ///
1836 /// drop(unsafe { Weak::from_raw(raw) });
1837 /// assert_eq!(0, Arc::weak_count(&strong));
1838 /// ```
1839 ///
1840 /// [`from_raw`]: Weak::from_raw
1841 /// [`as_ptr`]: Weak::as_ptr
1842 #[must_use = "losing the pointer will leak memory"]
1843 pub fn into_raw(self) -> *const T {
1844 ManuallyDrop::new(self).as_ptr()
1845 }
1846}
1847
1848// TODO: See todo comment in Weak::from_raw
1849impl<T /*: ?Sized */> Weak<T> {
1850 /// Returns a raw pointer to the object `T` pointed to by this `Weak<T>`.
1851 ///
1852 /// The pointer is valid only if there are some strong references. The pointer may be dangling,
1853 /// unaligned or even [`null`] otherwise.
1854 ///
1855 /// # Examples
1856 ///
1857 /// ```
1858 /// use std::ptr;
1859 ///
1860 /// use portable_atomic_util::Arc;
1861 ///
1862 /// let strong = Arc::new("hello".to_owned());
1863 /// let weak = Arc::downgrade(&strong);
1864 /// // Both point to the same object
1865 /// assert!(ptr::eq(&*strong, weak.as_ptr()));
1866 /// // The strong here keeps it alive, so we can still access the object.
1867 /// assert_eq!("hello", unsafe { &*weak.as_ptr() });
1868 ///
1869 /// drop(strong);
1870 /// // But not any more. We can do weak.as_ptr(), but accessing the pointer would lead to
1871 /// // undefined behavior.
1872 /// // assert_eq!("hello", unsafe { &*weak.as_ptr() });
1873 /// ```
1874 ///
1875 /// [`null`]: core::ptr::null "ptr::null"
1876 #[must_use]
1877 pub fn as_ptr(&self) -> *const T {
1878 let ptr: *mut ArcInner<T> = NonNull::as_ptr(self.ptr);
1879
1880 if is_dangling(ptr) {
1881 // If the pointer is dangling, we return the sentinel directly. This cannot be
1882 // a valid payload address, as the payload is at least as aligned as ArcInner (usize).
1883 ptr as *const T
1884 } else {
1885 // TODO: See todo comment in Weak::from_raw
1886 // // SAFETY: if is_dangling returns false, then the pointer is dereferenceable.
1887 // // The payload may be dropped at this point, and we have to maintain provenance,
1888 // // so use raw pointer manipulation.
1889 // unsafe { data_ptr::<T>(ptr, &(*ptr).data) }
1890 unsafe {
1891 let offset = data_offset_align(mem::align_of::<T>());
1892 strict::byte_add(ptr, offset) as *const T
1893 }
1894 }
1895 }
1896}
1897
1898impl<T: ?Sized> Weak<T> {
1899 /// Attempts to upgrade the `Weak` pointer to an [`Arc`], delaying
1900 /// dropping of the inner value if successful.
1901 ///
1902 /// Returns [`None`] if the inner value has since been dropped.
1903 ///
1904 /// # Examples
1905 ///
1906 /// ```
1907 /// use portable_atomic_util::Arc;
1908 ///
1909 /// let five = Arc::new(5);
1910 ///
1911 /// let weak_five = Arc::downgrade(&five);
1912 ///
1913 /// let strong_five: Option<Arc<_>> = weak_five.upgrade();
1914 /// assert!(strong_five.is_some());
1915 ///
1916 /// // Destroy all strong pointers.
1917 /// drop(strong_five);
1918 /// drop(five);
1919 ///
1920 /// assert!(weak_five.upgrade().is_none());
1921 /// ```
1922 #[must_use = "this returns a new `Arc`, \
1923 without modifying the original weak pointer"]
1924 pub fn upgrade(&self) -> Option<Arc<T>> {
1925 #[inline]
1926 fn checked_increment(n: usize) -> Option<usize> {
1927 // Any write of 0 we can observe leaves the field in permanently zero state.
1928 if n == 0 {
1929 return None;
1930 }
1931 // See comments in `Arc::clone` for why we do this (for `mem::forget`).
1932 assert!(n <= MAX_REFCOUNT, "{}", INTERNAL_OVERFLOW_ERROR);
1933 Some(n + 1)
1934 }
1935
1936 // We use a CAS loop to increment the strong count instead of a
1937 // fetch_add as this function should never take the reference count
1938 // from zero to one.
1939 //
1940 // Relaxed is fine for the failure case because we don't have any expectations about the new state.
1941 // Acquire is necessary for the success case to synchronize with `Arc::new_cyclic`, when the inner
1942 // value can be initialized after `Weak` references have already been created. In that case, we
1943 // expect to observe the fully initialized value.
1944 if self.inner()?.strong.fetch_update(Acquire, Relaxed, checked_increment).is_ok() {
1945 // SAFETY: pointer is not null, verified in checked_increment
1946 unsafe { Some(Arc::from_inner(self.ptr)) }
1947 } else {
1948 None
1949 }
1950 }
1951
1952 /// Gets the number of strong (`Arc`) pointers pointing to this allocation.
1953 ///
1954 /// If `self` was created using [`Weak::new`], this will return 0.
1955 #[must_use]
1956 pub fn strong_count(&self) -> usize {
1957 if let Some(inner) = self.inner() { inner.strong.load(Relaxed) } else { 0 }
1958 }
1959
1960 /// Gets an approximation of the number of `Weak` pointers pointing to this
1961 /// allocation.
1962 ///
1963 /// If `self` was created using [`Weak::new`], or if there are no remaining
1964 /// strong pointers, this will return 0.
1965 ///
1966 /// # Accuracy
1967 ///
1968 /// Due to implementation details, the returned value can be off by 1 in
1969 /// either direction when other threads are manipulating any `Arc`s or
1970 /// `Weak`s pointing to the same allocation.
1971 #[must_use]
1972 pub fn weak_count(&self) -> usize {
1973 if let Some(inner) = self.inner() {
1974 let weak = inner.weak.load(Acquire);
1975 let strong = inner.strong.load(Relaxed);
1976 if strong == 0 {
1977 0
1978 } else {
1979 // Since we observed that there was at least one strong pointer
1980 // after reading the weak count, we know that the implicit weak
1981 // reference (present whenever any strong references are alive)
1982 // was still around when we observed the weak count, and can
1983 // therefore safely subtract it.
1984 weak - 1
1985 }
1986 } else {
1987 0
1988 }
1989 }
1990
1991 /// Returns `None` when the pointer is dangling and there is no allocated `ArcInner`,
1992 /// (i.e., when this `Weak` was created by `Weak::new`).
1993 #[inline]
1994 fn inner(&self) -> Option<WeakInner<'_>> {
1995 let ptr = self.ptr.as_ptr();
1996 if is_dangling(ptr) {
1997 None
1998 } else {
1999 // SAFETY: non-dangling Weak has a valid pointer.
2000 // We are careful to *not* create a reference covering the "data" field, as
2001 // the field may be mutated concurrently (for example, if the last `Arc`
2002 // is dropped, the data field will be dropped in-place).
2003 Some(unsafe { WeakInner { strong: &(*ptr).strong, weak: &(*ptr).weak } })
2004 }
2005 }
2006
2007 /// Returns `true` if the two `Weak`s point to the same allocation similar to [`ptr::eq`], or if
2008 /// both don't point to any allocation (because they were created with `Weak::new()`). However,
2009 /// this function ignores the metadata of `dyn Trait` pointers.
2010 ///
2011 /// # Notes
2012 ///
2013 /// Since this compares pointers it means that `Weak::new()` will equal each
2014 /// other, even though they don't point to any allocation.
2015 ///
2016 /// # Examples
2017 ///
2018 /// ```
2019 /// use portable_atomic_util::Arc;
2020 ///
2021 /// let first_rc = Arc::new(5);
2022 /// let first = Arc::downgrade(&first_rc);
2023 /// let second = Arc::downgrade(&first_rc);
2024 ///
2025 /// assert!(first.ptr_eq(&second));
2026 ///
2027 /// let third_rc = Arc::new(5);
2028 /// let third = Arc::downgrade(&third_rc);
2029 ///
2030 /// assert!(!first.ptr_eq(&third));
2031 /// ```
2032 ///
2033 /// Comparing `Weak::new`.
2034 ///
2035 /// ```
2036 /// use portable_atomic_util::{Arc, Weak};
2037 ///
2038 /// let first = Weak::new();
2039 /// let second = Weak::new();
2040 /// assert!(first.ptr_eq(&second));
2041 ///
2042 /// let third_rc = Arc::new(());
2043 /// let third = Arc::downgrade(&third_rc);
2044 /// assert!(!first.ptr_eq(&third));
2045 /// ```
2046 ///
2047 /// [`ptr::eq`]: core::ptr::eq "ptr::eq"
2048 #[inline]
2049 #[must_use]
2050 pub fn ptr_eq(&self, other: &Self) -> bool {
2051 ptr::eq(self.ptr.as_ptr() as *const (), other.ptr.as_ptr() as *const ())
2052 }
2053}
2054
2055impl<T: ?Sized> Weak<T> {
2056 /// Allocates an `ArcInner<T>` with sufficient space for
2057 /// a possibly-unsized inner value where the value has the layout provided.
2058 ///
2059 /// The function `mem_to_arc_inner` is called with the data pointer
2060 /// and must return back a (potentially fat)-pointer for the `ArcInner<T>`.
2061 unsafe fn allocate_for_layout(
2062 value_layout: Layout,
2063 allocate: impl FnOnce(Layout) -> Option<NonNull<u8>>,
2064 mem_to_arc_inner: impl FnOnce(*mut u8) -> *mut ArcInner<T>,
2065 ) -> *mut ArcInner<T> {
2066 let layout = arc_inner_layout_for_value_layout(value_layout);
2067
2068 let ptr = allocate(layout).unwrap_or_else(|| handle_alloc_error(layout));
2069
2070 unsafe { Self::initialize_arc_inner(ptr, layout, mem_to_arc_inner) }
2071 }
2072
2073 unsafe fn initialize_arc_inner(
2074 ptr: NonNull<u8>,
2075 _layout: Layout,
2076 mem_to_arc_inner: impl FnOnce(*mut u8) -> *mut ArcInner<T>,
2077 ) -> *mut ArcInner<T> {
2078 let inner: *mut ArcInner<T> = mem_to_arc_inner(ptr.as_ptr());
2079 // debug_assert_eq!(unsafe { Layout::for_value_raw(inner) }, layout); // for_value_raw is unstable
2080
2081 // SAFETY: mem_to_arc_inner return a valid pointer to uninitialized ArcInner<T>.
2082 // ArcInner<T> is repr(C), and strong and weak are the first and second fields and
2083 // are the same type, so `inner as *mut atomic::AtomicUsize` is strong and
2084 // `(inner as *mut atomic::AtomicUsize).add(1)` is weak.
2085 unsafe {
2086 let strong = inner as *mut atomic::AtomicUsize;
2087 strong.write(atomic::AtomicUsize::new(0));
2088 let weak = strong.add(1);
2089 weak.write(atomic::AtomicUsize::new(1));
2090 }
2091
2092 inner
2093 }
2094}
2095
2096impl<T: ?Sized> Clone for Weak<T> {
2097 /// Makes a clone of the `Weak` pointer that points to the same allocation.
2098 ///
2099 /// # Examples
2100 ///
2101 /// ```
2102 /// use portable_atomic_util::{Arc, Weak};
2103 ///
2104 /// let weak_five = Arc::downgrade(&Arc::new(5));
2105 ///
2106 /// let _ = Weak::clone(&weak_five);
2107 /// ```
2108 #[inline]
2109 fn clone(&self) -> Self {
2110 if let Some(inner) = self.inner() {
2111 // See comments in Arc::clone() for why this is relaxed. This can use a
2112 // fetch_add (ignoring the lock) because the weak count is only locked
2113 // where are *no other* weak pointers in existence. (So we can't be
2114 // running this code in that case).
2115 let old_size = inner.weak.fetch_add(1, Relaxed);
2116
2117 // See comments in Arc::clone() for why we do this (for mem::forget).
2118 if old_size > MAX_REFCOUNT {
2119 abort();
2120 }
2121 }
2122
2123 Self { ptr: self.ptr }
2124 }
2125}
2126
2127impl<T> Default for Weak<T> {
2128 /// Constructs a new `Weak<T>`, without allocating memory.
2129 /// Calling [`upgrade`] on the return value always
2130 /// gives [`None`].
2131 ///
2132 /// [`upgrade`]: Weak::upgrade
2133 ///
2134 /// # Examples
2135 ///
2136 /// ```
2137 /// use portable_atomic_util::Weak;
2138 ///
2139 /// let empty: Weak<i64> = Weak::default();
2140 /// assert!(empty.upgrade().is_none());
2141 /// ```
2142 fn default() -> Self {
2143 Self::new()
2144 }
2145}
2146
2147impl<T: ?Sized> Drop for Weak<T> {
2148 /// Drops the `Weak` pointer.
2149 ///
2150 /// # Examples
2151 ///
2152 /// ```
2153 /// use portable_atomic_util::{Arc, Weak};
2154 ///
2155 /// struct Foo;
2156 ///
2157 /// impl Drop for Foo {
2158 /// fn drop(&mut self) {
2159 /// println!("dropped!");
2160 /// }
2161 /// }
2162 ///
2163 /// let foo = Arc::new(Foo);
2164 /// let weak_foo = Arc::downgrade(&foo);
2165 /// let other_weak_foo = Weak::clone(&weak_foo);
2166 ///
2167 /// drop(weak_foo); // Doesn't print anything
2168 /// drop(foo); // Prints "dropped!"
2169 ///
2170 /// assert!(other_weak_foo.upgrade().is_none());
2171 /// ```
2172 fn drop(&mut self) {
2173 // If we find out that we were the last weak pointer, then its time to
2174 // deallocate the data entirely. See the discussion in Arc::drop() about
2175 // the memory orderings
2176 //
2177 // It's not necessary to check for the locked state here, because the
2178 // weak count can only be locked if there was precisely one weak ref,
2179 // meaning that drop could only subsequently run ON that remaining weak
2180 // ref, which can only happen after the lock is released.
2181 let inner = if let Some(inner) = self.inner() { inner } else { return };
2182
2183 if inner.weak.fetch_sub(1, Release) == 1 {
2184 acquire!(inner.weak);
2185 // Free the allocation without dropping T
2186 let ptr = self.ptr.as_ptr() as *mut ArcInner<mem::ManuallyDrop<T>>;
2187 drop(unsafe { Box::from_raw(ptr) });
2188 }
2189 }
2190}
2191
2192impl<T: ?Sized + PartialEq> PartialEq for Arc<T> {
2193 /// Equality for two `Arc`s.
2194 ///
2195 /// Two `Arc`s are equal if their inner values are equal, even if they are
2196 /// stored in different allocation.
2197 ///
2198 /// If `T` also implements `Eq` (implying reflexivity of equality),
2199 /// two `Arc`s that point to the same allocation are always equal.
2200 ///
2201 /// # Examples
2202 ///
2203 /// ```
2204 /// use portable_atomic_util::Arc;
2205 ///
2206 /// let five = Arc::new(5);
2207 ///
2208 /// assert_eq!(five, Arc::new(5));
2209 /// ```
2210 #[inline]
2211 fn eq(&self, other: &Self) -> bool {
2212 **self == **other
2213 }
2214
2215 /// Inequality for two `Arc`s.
2216 ///
2217 /// Two `Arc`s are not equal if their inner values are not equal.
2218 ///
2219 /// If `T` also implements `Eq` (implying reflexivity of equality),
2220 /// two `Arc`s that point to the same value are always equal.
2221 ///
2222 /// # Examples
2223 ///
2224 /// ```
2225 /// use portable_atomic_util::Arc;
2226 ///
2227 /// let five = Arc::new(5);
2228 ///
2229 /// assert_ne!(five, Arc::new(6));
2230 /// ```
2231 #[allow(clippy::partialeq_ne_impl)]
2232 #[inline]
2233 fn ne(&self, other: &Self) -> bool {
2234 **self != **other
2235 }
2236}
2237
2238impl<T: ?Sized + PartialOrd> PartialOrd for Arc<T> {
2239 /// Partial comparison for two `Arc`s.
2240 ///
2241 /// The two are compared by calling `partial_cmp()` on their inner values.
2242 ///
2243 /// # Examples
2244 ///
2245 /// ```
2246 /// use std::cmp::Ordering;
2247 ///
2248 /// use portable_atomic_util::Arc;
2249 ///
2250 /// let five = Arc::new(5);
2251 ///
2252 /// assert_eq!(Some(Ordering::Less), five.partial_cmp(&Arc::new(6)));
2253 /// ```
2254 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
2255 (**self).partial_cmp(&**other)
2256 }
2257
2258 /// Less-than comparison for two `Arc`s.
2259 ///
2260 /// The two are compared by calling `<` on their inner values.
2261 ///
2262 /// # Examples
2263 ///
2264 /// ```
2265 /// use portable_atomic_util::Arc;
2266 ///
2267 /// let five = Arc::new(5);
2268 ///
2269 /// assert!(five < Arc::new(6));
2270 /// ```
2271 fn lt(&self, other: &Self) -> bool {
2272 *(*self) < *(*other)
2273 }
2274
2275 /// 'Less than or equal to' comparison for two `Arc`s.
2276 ///
2277 /// The two are compared by calling `<=` on their inner values.
2278 ///
2279 /// # Examples
2280 ///
2281 /// ```
2282 /// use portable_atomic_util::Arc;
2283 ///
2284 /// let five = Arc::new(5);
2285 ///
2286 /// assert!(five <= Arc::new(5));
2287 /// ```
2288 fn le(&self, other: &Self) -> bool {
2289 *(*self) <= *(*other)
2290 }
2291
2292 /// Greater-than comparison for two `Arc`s.
2293 ///
2294 /// The two are compared by calling `>` on their inner values.
2295 ///
2296 /// # Examples
2297 ///
2298 /// ```
2299 /// use portable_atomic_util::Arc;
2300 ///
2301 /// let five = Arc::new(5);
2302 ///
2303 /// assert!(five > Arc::new(4));
2304 /// ```
2305 fn gt(&self, other: &Self) -> bool {
2306 *(*self) > *(*other)
2307 }
2308
2309 /// 'Greater than or equal to' comparison for two `Arc`s.
2310 ///
2311 /// The two are compared by calling `>=` on their inner values.
2312 ///
2313 /// # Examples
2314 ///
2315 /// ```
2316 /// use portable_atomic_util::Arc;
2317 ///
2318 /// let five = Arc::new(5);
2319 ///
2320 /// assert!(five >= Arc::new(5));
2321 /// ```
2322 fn ge(&self, other: &Self) -> bool {
2323 *(*self) >= *(*other)
2324 }
2325}
2326impl<T: ?Sized + Ord> Ord for Arc<T> {
2327 /// Comparison for two `Arc`s.
2328 ///
2329 /// The two are compared by calling `cmp()` on their inner values.
2330 ///
2331 /// # Examples
2332 ///
2333 /// ```
2334 /// use std::cmp::Ordering;
2335 ///
2336 /// use portable_atomic_util::Arc;
2337 ///
2338 /// let five = Arc::new(5);
2339 ///
2340 /// assert_eq!(Ordering::Less, five.cmp(&Arc::new(6)));
2341 /// ```
2342 fn cmp(&self, other: &Self) -> Ordering {
2343 (**self).cmp(&**other)
2344 }
2345}
2346impl<T: ?Sized + Eq> Eq for Arc<T> {}
2347
2348impl<T: ?Sized + fmt::Display> fmt::Display for Arc<T> {
2349 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2350 fmt::Display::fmt(&**self, f)
2351 }
2352}
2353
2354impl<T: ?Sized + fmt::Debug> fmt::Debug for Arc<T> {
2355 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2356 fmt::Debug::fmt(&**self, f)
2357 }
2358}
2359
2360impl<T: ?Sized> fmt::Pointer for Arc<T> {
2361 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2362 fmt::Pointer::fmt(&(&**self as *const T), f)
2363 }
2364}
2365
2366impl<T: Default> Default for Arc<T> {
2367 /// Creates a new `Arc<T>`, with the `Default` value for `T`.
2368 ///
2369 /// # Examples
2370 ///
2371 /// ```
2372 /// use portable_atomic_util::Arc;
2373 ///
2374 /// let x: Arc<i32> = Arc::default();
2375 /// assert_eq!(*x, 0);
2376 /// ```
2377 fn default() -> Self {
2378 // TODO: https://github.com/rust-lang/rust/pull/131460 / https://github.com/rust-lang/rust/pull/132031
2379 Self::new(T::default())
2380 }
2381}
2382
2383#[cfg(not(portable_atomic_no_min_const_generics))]
2384impl Default for Arc<str> {
2385 /// Creates an empty str inside an Arc.
2386 ///
2387 /// This may or may not share an allocation with other Arcs.
2388 #[inline]
2389 fn default() -> Self {
2390 let arc: Arc<[u8]> = Arc::default();
2391 debug_assert!(core::str::from_utf8(&arc).is_ok());
2392 let ptr = Arc::into_inner_non_null(arc);
2393 unsafe { Arc::from_ptr(ptr.as_ptr() as *mut ArcInner<str>) }
2394 }
2395}
2396
2397#[cfg(not(portable_atomic_no_min_const_generics))]
2398impl<T> Default for Arc<[T]> {
2399 /// Creates an empty `[T]` inside an Arc.
2400 ///
2401 /// This may or may not share an allocation with other Arcs.
2402 #[inline]
2403 fn default() -> Self {
2404 // TODO: we cannot use non-allocation optimization (https://github.com/rust-lang/rust/blob/1.93.0/library/alloc/src/sync.rs#L3807)
2405 // for now since casting Arc<[T; N]> -> Arc<[T]> requires unstable CoerceUnsized.
2406 let arr: [T; 0] = [];
2407 Arc::from(arr)
2408 }
2409}
2410
2411impl<T> Default for Pin<Arc<T>>
2412where
2413 T: ?Sized,
2414 Arc<T>: Default,
2415{
2416 #[inline]
2417 fn default() -> Self {
2418 unsafe { Pin::new_unchecked(Arc::<T>::default()) }
2419 }
2420}
2421
2422impl<T: ?Sized + Hash> Hash for Arc<T> {
2423 fn hash<H: Hasher>(&self, state: &mut H) {
2424 (**self).hash(state);
2425 }
2426}
2427
2428impl<T> From<T> for Arc<T> {
2429 /// Converts a `T` into an `Arc<T>`
2430 ///
2431 /// The conversion moves the value into a
2432 /// newly allocated `Arc`. It is equivalent to
2433 /// calling `Arc::new(t)`.
2434 ///
2435 /// # Example
2436 ///
2437 /// ```
2438 /// use portable_atomic_util::Arc;
2439 /// let x = 5;
2440 /// let arc = Arc::new(5);
2441 ///
2442 /// assert_eq!(Arc::from(x), arc);
2443 /// ```
2444 fn from(t: T) -> Self {
2445 Self::new(t)
2446 }
2447}
2448
2449// This just outputs the input as is, but can be used like an item-level block by using it with cfg.
2450// Note: This macro is items!({ }), not items! { }.
2451// An extra brace is used in input to make contents rustfmt-able.
2452#[cfg(not(portable_atomic_no_min_const_generics))]
2453macro_rules! items {
2454 ({$($tt:tt)*}) => {
2455 $($tt)*
2456 };
2457}
2458
2459#[cfg(not(portable_atomic_no_min_const_generics))]
2460items!({
2461 impl<T, const N: usize> From<[T; N]> for Arc<[T]> {
2462 /// Converts a [`[T; N]`](prim@array) into an `Arc<[T]>`.
2463 ///
2464 /// The conversion moves the array into a newly allocated `Arc`.
2465 ///
2466 /// # Example
2467 ///
2468 /// ```
2469 /// use portable_atomic_util::Arc;
2470 /// let original: [i32; 3] = [1, 2, 3];
2471 /// let shared: Arc<[i32]> = Arc::from(original);
2472 /// assert_eq!(&[1, 2, 3], &shared[..]);
2473 /// ```
2474 #[inline]
2475 fn from(v: [T; N]) -> Self {
2476 // Casting Arc<[T; N]> -> Arc<[T]> requires unstable CoerceUnsized, so we convert via Box.
2477 // Since the compiler knows the actual size and metadata, the intermediate allocation is
2478 // optimized and generates the same code as when using CoerceUnsized and convert Arc<[T; N]> to Arc<[T]>.
2479 // https://github.com/taiki-e/portable-atomic/issues/143#issuecomment-1866488569
2480 let v: Box<[T]> = Box::<[T; N]>::from(v);
2481 v.into()
2482 }
2483 }
2484});
2485
2486impl<T: Clone> From<&[T]> for Arc<[T]> {
2487 /// Allocates a reference-counted slice and fills it by cloning `v`'s items.
2488 ///
2489 /// # Example
2490 ///
2491 /// ```
2492 /// use portable_atomic_util::Arc;
2493 /// let original: &[i32] = &[1, 2, 3];
2494 /// let shared: Arc<[i32]> = Arc::from(original);
2495 /// assert_eq!(&[1, 2, 3], &shared[..]);
2496 /// ```
2497 #[inline]
2498 fn from(v: &[T]) -> Self {
2499 unsafe { Self::from_iter_exact(v.iter().cloned(), v.len()) }
2500 }
2501}
2502
2503impl<T: Clone> From<&mut [T]> for Arc<[T]> {
2504 /// Allocates a reference-counted slice and fills it by cloning `v`'s items.
2505 ///
2506 /// # Example
2507 ///
2508 /// ```
2509 /// use portable_atomic_util::Arc;
2510 /// let mut original = [1, 2, 3];
2511 /// let original: &mut [i32] = &mut original;
2512 /// let shared: Arc<[i32]> = Arc::from(original);
2513 /// assert_eq!(&[1, 2, 3], &shared[..]);
2514 /// ```
2515 #[inline]
2516 fn from(v: &mut [T]) -> Self {
2517 Self::from(&*v)
2518 }
2519}
2520
2521impl From<&str> for Arc<str> {
2522 /// Allocates a reference-counted `str` and copies `v` into it.
2523 ///
2524 /// # Example
2525 ///
2526 /// ```
2527 /// use portable_atomic_util::Arc;
2528 /// let shared: Arc<str> = Arc::from("eggplant");
2529 /// assert_eq!("eggplant", &shared[..]);
2530 /// ```
2531 #[inline]
2532 fn from(v: &str) -> Self {
2533 let arc = Arc::<[u8]>::from(v.as_bytes());
2534 // SAFETY: `str` has the same layout as `[u8]`.
2535 // https://doc.rust-lang.org/nightly/reference/type-layout.html#str-layout
2536 unsafe { Self::from_raw(Arc::into_raw(arc) as *const str) }
2537 }
2538}
2539
2540impl From<&mut str> for Arc<str> {
2541 /// Allocates a reference-counted `str` and copies `v` into it.
2542 ///
2543 /// # Example
2544 ///
2545 /// ```
2546 /// use portable_atomic_util::Arc;
2547 /// let mut original = String::from("eggplant");
2548 /// let original: &mut str = &mut original;
2549 /// let shared: Arc<str> = Arc::from(original);
2550 /// assert_eq!("eggplant", &shared[..]);
2551 /// ```
2552 #[inline]
2553 fn from(v: &mut str) -> Self {
2554 Self::from(&*v)
2555 }
2556}
2557
2558impl From<String> for Arc<str> {
2559 /// Allocates a reference-counted `str` and copies `v` into it.
2560 ///
2561 /// # Example
2562 ///
2563 /// ```
2564 /// use portable_atomic_util::Arc;
2565 /// let unique: String = "eggplant".to_owned();
2566 /// let shared: Arc<str> = Arc::from(unique);
2567 /// assert_eq!("eggplant", &shared[..]);
2568 /// ```
2569 #[inline]
2570 fn from(v: String) -> Self {
2571 Self::from(&v[..])
2572 }
2573}
2574
2575impl<T: ?Sized> From<Box<T>> for Arc<T> {
2576 /// Move a boxed object to a new, reference-counted allocation.
2577 ///
2578 /// # Example
2579 ///
2580 /// ```
2581 /// use portable_atomic_util::Arc;
2582 /// let unique: Box<str> = Box::from("eggplant");
2583 /// let shared: Arc<str> = Arc::from(unique);
2584 /// assert_eq!("eggplant", &shared[..]);
2585 /// ```
2586 #[inline]
2587 fn from(v: Box<T>) -> Self {
2588 Self::from_box(v)
2589 }
2590}
2591
2592impl<T> From<Vec<T>> for Arc<[T]> {
2593 /// Allocates a reference-counted slice and moves `v`'s items into it.
2594 ///
2595 /// # Example
2596 ///
2597 /// ```
2598 /// use portable_atomic_util::Arc;
2599 /// let unique: Vec<i32> = vec![1, 2, 3];
2600 /// let shared: Arc<[i32]> = Arc::from(unique);
2601 /// assert_eq!(&[1, 2, 3], &shared[..]);
2602 /// ```
2603 #[inline]
2604 fn from(v: Vec<T>) -> Self {
2605 unsafe {
2606 let len = v.len();
2607 let cap = v.capacity();
2608 let vec_ptr = mem::ManuallyDrop::new(v).as_mut_ptr();
2609
2610 let mut arc = Self::new_uninit_slice(len);
2611 let data = Arc::get_mut_unchecked(&mut arc);
2612 ptr::copy_nonoverlapping(vec_ptr, data.as_mut_ptr() as *mut T, len);
2613
2614 // Create a `Vec<T>` with length 0, to deallocate the buffer
2615 // without dropping its contents or the allocator
2616 let _ = Vec::from_raw_parts(vec_ptr, 0, cap);
2617
2618 arc.assume_init()
2619 }
2620 }
2621}
2622
2623impl<'a, B> From<Cow<'a, B>> for Arc<B>
2624where
2625 B: ?Sized + ToOwned,
2626 Arc<B>: From<&'a B> + From<B::Owned>,
2627{
2628 /// Creates an atomically reference-counted pointer from a clone-on-write
2629 /// pointer by copying its content.
2630 ///
2631 /// # Example
2632 ///
2633 /// ```
2634 /// use std::borrow::Cow;
2635 ///
2636 /// use portable_atomic_util::Arc;
2637 ///
2638 /// let cow: Cow<'_, str> = Cow::Borrowed("eggplant");
2639 /// let shared: Arc<str> = Arc::from(cow);
2640 /// assert_eq!("eggplant", &shared[..]);
2641 /// ```
2642 #[inline]
2643 fn from(cow: Cow<'a, B>) -> Self {
2644 match cow {
2645 Cow::Borrowed(s) => Self::from(s),
2646 Cow::Owned(s) => Self::from(s),
2647 }
2648 }
2649}
2650
2651impl From<Arc<str>> for Arc<[u8]> {
2652 /// Converts an atomically reference-counted string slice into a byte slice.
2653 ///
2654 /// # Example
2655 ///
2656 /// ```
2657 /// use portable_atomic_util::Arc;
2658 /// let string: Arc<str> = Arc::from("eggplant");
2659 /// let bytes: Arc<[u8]> = Arc::from(string);
2660 /// assert_eq!("eggplant".as_bytes(), bytes.as_ref());
2661 /// ```
2662 #[inline]
2663 fn from(rc: Arc<str>) -> Self {
2664 // SAFETY: `str` has the same layout as `[u8]`.
2665 // https://doc.rust-lang.org/nightly/reference/type-layout.html#str-layout
2666 unsafe { Self::from_raw(Arc::into_raw(rc) as *const [u8]) }
2667 }
2668}
2669
2670#[cfg(not(portable_atomic_no_min_const_generics))]
2671items!({
2672 impl<T, const N: usize> TryFrom<Arc<[T]>> for Arc<[T; N]> {
2673 type Error = Arc<[T]>;
2674
2675 fn try_from(boxed_slice: Arc<[T]>) -> Result<Self, Self::Error> {
2676 if boxed_slice.len() == N {
2677 let ptr = Arc::into_inner_non_null(boxed_slice);
2678 Ok(unsafe { Self::from_inner(ptr.cast::<ArcInner<[T; N]>>()) })
2679 } else {
2680 Err(boxed_slice)
2681 }
2682 }
2683 }
2684});
2685
2686impl<T> FromIterator<T> for Arc<[T]> {
2687 /// Takes each element in the `Iterator` and collects it into an `Arc<[T]>`.
2688 ///
2689 /// # Performance characteristics
2690 ///
2691 /// ## The general case
2692 ///
2693 /// In the general case, collecting into `Arc<[T]>` is done by first
2694 /// collecting into a `Vec<T>`. That is, when writing the following:
2695 ///
2696 /// ```
2697 /// use portable_atomic_util::Arc;
2698 /// let evens: Arc<[u8]> = (0..10).filter(|&x| x % 2 == 0).collect();
2699 /// # assert_eq!(&*evens, &[0, 2, 4, 6, 8]);
2700 /// ```
2701 ///
2702 /// this behaves as if we wrote:
2703 ///
2704 /// ```
2705 /// use portable_atomic_util::Arc;
2706 /// let evens: Arc<[u8]> = (0..10).filter(|&x| x % 2 == 0)
2707 /// .collect::<Vec<_>>() // The first set of allocations happens here.
2708 /// .into(); // A second allocation for `Arc<[T]>` happens here.
2709 ///
2710 /// assert_eq!(&*evens, &[0, 2, 4, 6, 8]);
2711 /// ```
2712 ///
2713 /// This will allocate as many times as needed for constructing the `Vec<T>`
2714 /// and then it will allocate once for turning the `Vec<T>` into the `Arc<[T]>`.
2715 ///
2716 /// ## Iterators of known length
2717 ///
2718 /// When your `Iterator` implements `TrustedLen` and is of an exact size,
2719 /// a single allocation will be made for the `Arc<[T]>`. For example:
2720 ///
2721 /// ```
2722 /// use portable_atomic_util::Arc;
2723 /// let evens: Arc<[u8]> = (0..10).collect(); // Just a single allocation happens here.
2724 ///
2725 /// assert_eq!(&*evens, &*(0..10).collect::<Vec<_>>());
2726 /// ```
2727 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
2728 iter.into_iter().collect::<Vec<T>>().into()
2729 }
2730}
2731
2732impl<T: ?Sized> borrow::Borrow<T> for Arc<T> {
2733 fn borrow(&self) -> &T {
2734 self
2735 }
2736}
2737
2738impl<T: ?Sized> AsRef<T> for Arc<T> {
2739 fn as_ref(&self) -> &T {
2740 self
2741 }
2742}
2743
2744impl<T: ?Sized> Unpin for Arc<T> {}
2745
2746/// Gets the pointer to data within the given an `ArcInner`.
2747///
2748/// # Safety
2749///
2750/// `arc` must uphold the safety requirements for `.byte_add(data_offset)`.
2751/// This is automatically satisfied if it is a pointer to a valid `ArcInner`.
2752unsafe fn data_ptr<T: ?Sized>(arc: *mut ArcInner<T>, data: &T) -> *mut T {
2753 // SAFETY: the caller must uphold the safety contract.
2754 unsafe {
2755 let offset = data_offset::<T>(data);
2756 strict::byte_add(arc, offset) as *mut T
2757 }
2758}
2759
2760/// Gets the offset within an `ArcInner` for the payload behind a pointer.
2761fn data_offset<T: ?Sized>(ptr: &T) -> usize {
2762 // Align the unsized value to the end of the ArcInner.
2763 // Because ArcInner is repr(C), it will always be the last field in memory.
2764 data_offset_align(mem::align_of_val::<T>(ptr))
2765}
2766
2767#[inline]
2768fn data_offset_align(align: usize) -> usize {
2769 let layout = Layout::new::<ArcInner<()>>();
2770 layout.size() + layout::padding_needed_for(layout, align)
2771}
2772
2773/// A unique owning pointer to an [`ArcInner`] **that does not imply the contents are initialized,**
2774/// but will deallocate it (without dropping the value) when dropped.
2775///
2776/// This is a helper for [`Arc::make_mut()`] to ensure correct cleanup on panic.
2777struct UniqueArcUninit<T: ?Sized> {
2778 ptr: NonNull<ArcInner<T>>,
2779 layout_for_value: Layout,
2780}
2781
2782impl<T: ?Sized> UniqueArcUninit<T> {
2783 /// Allocates an ArcInner with layout suitable to contain `for_value` or a clone of it.
2784 fn new(for_value: &T) -> Self {
2785 let layout = Layout::for_value(for_value);
2786 let ptr = unsafe { Arc::allocate_for_value(for_value) };
2787 Self { ptr: NonNull::new(ptr).unwrap(), layout_for_value: layout }
2788 }
2789
2790 /// Returns the pointer to be written into to initialize the [`Arc`].
2791 fn data_ptr(&mut self) -> *mut T {
2792 let offset = data_offset_align(self.layout_for_value.align());
2793 unsafe { strict::byte_add(self.ptr.as_ptr(), offset) as *mut T }
2794 }
2795
2796 /// Upgrade this into a normal [`Arc`].
2797 ///
2798 /// # Safety
2799 ///
2800 /// The data must have been initialized (by writing to [`Self::data_ptr()`]).
2801 unsafe fn into_arc(self) -> Arc<T> {
2802 let this = ManuallyDrop::new(self);
2803 let ptr = this.ptr.as_ptr();
2804
2805 // SAFETY: The pointer is valid as per `UniqueArcUninit::new`, and the caller is responsible
2806 // for having initialized the data.
2807 unsafe { Arc::from_ptr(ptr) }
2808 }
2809}
2810
2811impl<T: ?Sized> Drop for UniqueArcUninit<T> {
2812 fn drop(&mut self) {
2813 // SAFETY:
2814 // * new() produced a pointer safe to deallocate.
2815 // * We own the pointer unless into_arc() was called, which forgets us.
2816 unsafe {
2817 Global.deallocate(
2818 self.ptr.cast::<u8>(),
2819 arc_inner_layout_for_value_layout(self.layout_for_value),
2820 );
2821 }
2822 }
2823}
2824
2825#[cfg(not(portable_atomic_no_error_in_core))]
2826use core::error;
2827#[cfg(all(portable_atomic_no_error_in_core, feature = "std"))]
2828use std::error;
2829#[cfg(any(not(portable_atomic_no_error_in_core), feature = "std"))]
2830impl<T: ?Sized + error::Error> error::Error for Arc<T> {
2831 #[allow(deprecated)]
2832 fn cause(&self) -> Option<&dyn error::Error> {
2833 error::Error::cause(&**self)
2834 }
2835 fn source(&self) -> Option<&(dyn error::Error + 'static)> {
2836 error::Error::source(&**self)
2837 }
2838}
2839
2840#[cfg(feature = "serde")]
2841#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
2842mod serde_impls {
2843 use serde::{
2844 de::{Deserialize, Deserializer},
2845 ser::{Serialize, Serializer},
2846 };
2847
2848 use super::{Arc, Box, Weak};
2849
2850 // Refs: https://github.com/serde-rs/serde/blob/v1.0.228/serde_core/src/ser/impls.rs#L472
2851 impl<T: ?Sized + Serialize> Serialize for Arc<T> {
2852 #[inline]
2853 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
2854 where
2855 S: Serializer,
2856 {
2857 (**self).serialize(serializer)
2858 }
2859 }
2860
2861 // Refs: https://github.com/serde-rs/serde/blob/v1.0.228/serde_core/src/ser/impls.rs#L564
2862 impl<T: ?Sized + Serialize> Serialize for Weak<T> {
2863 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
2864 where
2865 S: Serializer,
2866 {
2867 self.upgrade().serialize(serializer)
2868 }
2869 }
2870
2871 // Refs: https://github.com/serde-rs/serde/blob/v1.0.228/serde_core/src/de/impls.rs#L2057
2872 impl<'de, T> Deserialize<'de> for Arc<T>
2873 where
2874 T: ?Sized,
2875 Box<T>: Deserialize<'de>,
2876 {
2877 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
2878 where
2879 D: serde::Deserializer<'de>,
2880 {
2881 Box::deserialize(deserializer).map(Into::into)
2882 }
2883 }
2884
2885 // Refs: https://github.com/serde-rs/serde/blob/v1.0.228/serde_core/src/de/impls.rs#L2035
2886 impl<'de, T> Deserialize<'de> for Weak<T>
2887 where
2888 T: Deserialize<'de>,
2889 {
2890 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
2891 where
2892 D: Deserializer<'de>,
2893 {
2894 Option::<T>::deserialize(deserializer)?;
2895 Ok(Weak::new())
2896 }
2897 }
2898}
2899
2900#[cfg(feature = "std")]
2901mod std_impls {
2902 // TODO: Other trait implementations that are stable but we currently don't provide:
2903 // - alloc::ffi
2904 // - https://doc.rust-lang.org/nightly/alloc/sync/struct.Arc.html#impl-From%3C%26CStr%3E-for-Arc%3CCStr%3E
2905 // - https://doc.rust-lang.org/nightly/alloc/sync/struct.Arc.html#impl-From%3C%26mut+CStr%3E-for-Arc%3CCStr%3E
2906 // - https://doc.rust-lang.org/nightly/alloc/sync/struct.Arc.html#impl-From%3CCString%3E-for-Arc%3CCStr%3E
2907 // - https://doc.rust-lang.org/nightly/alloc/sync/struct.Arc.html#impl-Default-for-Arc%3CCStr%3E
2908 // - Currently, we cannot implement these since CStr layout is not stable.
2909 // - std::ffi
2910 // - https://doc.rust-lang.org/nightly/std/sync/struct.Arc.html#impl-From%3C%26OsStr%3E-for-Arc%3COsStr%3E
2911 // - https://doc.rust-lang.org/nightly/std/sync/struct.Arc.html#impl-From%3C%26mut+OsStr%3E-for-Arc%3COsStr%3E
2912 // - https://doc.rust-lang.org/nightly/std/sync/struct.Arc.html#impl-From%3COsString%3E-for-Arc%3COsStr%3E
2913 // - Currently, we cannot implement these since OsStr layout is not stable.
2914 // - std::path
2915 // - https://doc.rust-lang.org/nightly/std/sync/struct.Arc.html#impl-From%3C%26Path%3E-for-Arc%3CPath%3E
2916 // - https://doc.rust-lang.org/nightly/std/sync/struct.Arc.html#impl-From%3C%26mut+Path%3E-for-Arc%3CPath%3E
2917 // - https://doc.rust-lang.org/nightly/std/sync/struct.Arc.html#impl-From%3CPathBuf%3E-for-Arc%3CPath%3E
2918 // - Currently, we cannot implement these since Path layout is not stable.
2919
2920 use std::io;
2921 // https://doc.rust-lang.org/nightly/std/sync/struct.Arc.html#impl-AsFd-for-Arc%3CT%3E
2922 // https://doc.rust-lang.org/nightly/std/sync/struct.Arc.html#impl-AsHandle-for-Arc%3CT%3E
2923 // https://doc.rust-lang.org/nightly/std/sync/struct.Arc.html#impl-AsRawFd-for-Arc%3CT%3E
2924 // https://doc.rust-lang.org/nightly/std/sync/struct.Arc.html#impl-AsSocket-for-Arc%3CT%3E
2925 // Note:
2926 // - T: ?Sized is currently only allowed on AsFd/AsHandle: https://github.com/rust-lang/rust/pull/114655#issuecomment-1977994288
2927 // - std doesn't implement AsRawHandle/AsRawSocket for Arc as of Rust 1.90.
2928 // - std::os::unix::io::AsRawFd and std::os::windows::io::{AsRawHandle, AsRawSocket} are available in all versions
2929 // - std::os::wasi::prelude::AsRawFd requires 1.56 (https://github.com/rust-lang/rust/commit/e555003e6d6b6d71ce5509a6b6c7a15861208d6c)
2930 // - std::os::unix::io::AsFd, std::os::wasi::prelude::AsFd, and std::os::windows::io::{AsHandle, AsSocket} require Rust 1.63
2931 // - std::os::wasi::io::AsFd requires Rust 1.65 (https://github.com/rust-lang/rust/pull/103308)
2932 // - std::os::fd requires Rust 1.66 (https://github.com/rust-lang/rust/pull/98368)
2933 // - std::os::hermit::io::AsFd requires Rust 1.69 (https://github.com/rust-lang/rust/commit/b5fb4f3d9b1b308d59cab24ef2f9bf23dad948aa)
2934 // - std::os::fd for HermitOS requires Rust 1.81 (https://github.com/rust-lang/rust/pull/126346)
2935 // - std::os::fd for Trusty requires Rust 1.87 (no std support before it, https://github.com/rust-lang/rust/commit/7f6ee12526700e037ef34912b2b0c628028d382c)
2936 // - std::os::solid::io::AsFd is unstable (solid_ext, https://github.com/rust-lang/rust/pull/115159)
2937 // Note: we don't implement unstable ones.
2938 #[cfg(not(portable_atomic_no_io_safety))]
2939 #[cfg(target_os = "trusty")]
2940 use std::os::fd;
2941 #[cfg(not(portable_atomic_no_io_safety))]
2942 #[cfg(target_os = "hermit")]
2943 use std::os::hermit::io as fd;
2944 #[cfg(unix)]
2945 use std::os::unix::io as fd;
2946 #[cfg(not(portable_atomic_no_io_safety))]
2947 #[cfg(target_os = "wasi")]
2948 use std::os::wasi::prelude as fd;
2949
2950 use super::Arc;
2951
2952 /// This impl allows implementing traits that require `AsRawFd` on Arc.
2953 /// ```
2954 /// # #[cfg(target_os = "hermit")]
2955 /// # use std::os::hermit::io::AsRawFd;
2956 /// # #[cfg(target_os = "wasi")]
2957 /// # use std::os::wasi::prelude::AsRawFd;
2958 /// # #[cfg(unix)]
2959 /// # use std::os::unix::io::AsRawFd;
2960 /// use std::net::UdpSocket;
2961 ///
2962 /// use portable_atomic_util::Arc;
2963 ///
2964 /// trait MyTrait: AsRawFd {}
2965 /// impl MyTrait for Arc<UdpSocket> {}
2966 /// ```
2967 #[cfg(any(
2968 unix,
2969 all(
2970 not(portable_atomic_no_io_safety),
2971 any(target_os = "hermit", target_os = "trusty", target_os = "wasi"),
2972 ),
2973 ))]
2974 impl<T: fd::AsRawFd> fd::AsRawFd for Arc<T> {
2975 #[inline]
2976 fn as_raw_fd(&self) -> fd::RawFd {
2977 (**self).as_raw_fd()
2978 }
2979 }
2980 /// This impl allows implementing traits that require `AsFd` on Arc.
2981 /// ```
2982 /// # #[cfg(target_os = "hermit")]
2983 /// # use std::os::hermit::io::AsFd;
2984 /// # #[cfg(target_os = "wasi")]
2985 /// # use std::os::wasi::prelude::AsFd;
2986 /// # #[cfg(unix)]
2987 /// # use std::os::unix::io::AsFd;
2988 /// use std::net::UdpSocket;
2989 ///
2990 /// use portable_atomic_util::Arc;
2991 ///
2992 /// trait MyTrait: AsFd {}
2993 /// impl MyTrait for Arc<UdpSocket> {}
2994 /// ```
2995 #[cfg(not(portable_atomic_no_io_safety))]
2996 #[cfg(any(unix, target_os = "hermit", target_os = "trusty", target_os = "wasi"))]
2997 impl<T: ?Sized + fd::AsFd> fd::AsFd for Arc<T> {
2998 #[inline]
2999 fn as_fd(&self) -> fd::BorrowedFd<'_> {
3000 (**self).as_fd()
3001 }
3002 }
3003 /// This impl allows implementing traits that require `AsHandle` on Arc.
3004 /// ```
3005 /// # use std::os::windows::io::AsHandle;
3006 /// use std::fs::File;
3007 ///
3008 /// use portable_atomic_util::Arc;
3009 ///
3010 /// trait MyTrait: AsHandle {}
3011 /// impl MyTrait for Arc<File> {}
3012 /// ```
3013 #[cfg(not(portable_atomic_no_io_safety))]
3014 #[cfg(windows)]
3015 impl<T: ?Sized + std::os::windows::io::AsHandle> std::os::windows::io::AsHandle for Arc<T> {
3016 #[inline]
3017 fn as_handle(&self) -> std::os::windows::io::BorrowedHandle<'_> {
3018 (**self).as_handle()
3019 }
3020 }
3021 /// This impl allows implementing traits that require `AsSocket` on Arc.
3022 /// ```
3023 /// # use std::os::windows::io::AsSocket;
3024 /// use std::net::UdpSocket;
3025 ///
3026 /// use portable_atomic_util::Arc;
3027 ///
3028 /// trait MyTrait: AsSocket {}
3029 /// impl MyTrait for Arc<UdpSocket> {}
3030 /// ```
3031 #[cfg(not(portable_atomic_no_io_safety))]
3032 #[cfg(windows)]
3033 impl<T: std::os::windows::io::AsSocket> std::os::windows::io::AsSocket for Arc<T> {
3034 #[inline]
3035 fn as_socket(&self) -> std::os::windows::io::BorrowedSocket<'_> {
3036 (**self).as_socket()
3037 }
3038 }
3039
3040 // https://doc.rust-lang.org/nightly/std/sync/struct.Arc.html#impl-Read-for-Arc%3CFile%3E
3041 // https://doc.rust-lang.org/nightly/std/sync/struct.Arc.html#impl-Seek-for-Arc%3CFile%3E
3042 // https://doc.rust-lang.org/nightly/std/sync/struct.Arc.html#impl-Write-for-Arc%3CFile%3E
3043 impl io::Read for Arc<std::fs::File> {
3044 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
3045 (&**self).read(buf)
3046 }
3047 fn read_vectored(&mut self, bufs: &mut [io::IoSliceMut<'_>]) -> io::Result<usize> {
3048 (&**self).read_vectored(bufs)
3049 }
3050 // fn read_buf(&mut self, cursor: io::BorrowedCursor<'_>) -> io::Result<()> {
3051 // (&**self).read_buf(cursor)
3052 // }
3053 // #[inline]
3054 // fn is_read_vectored(&self) -> bool {
3055 // (&**self).is_read_vectored()
3056 // }
3057 fn read_to_end(&mut self, buf: &mut alloc::vec::Vec<u8>) -> io::Result<usize> {
3058 (&**self).read_to_end(buf)
3059 }
3060 fn read_to_string(&mut self, buf: &mut alloc::string::String) -> io::Result<usize> {
3061 (&**self).read_to_string(buf)
3062 }
3063 }
3064 impl io::Write for Arc<std::fs::File> {
3065 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
3066 (&**self).write(buf)
3067 }
3068 fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result<usize> {
3069 (&**self).write_vectored(bufs)
3070 }
3071 // #[inline]
3072 // fn is_write_vectored(&self) -> bool {
3073 // (&**self).is_write_vectored()
3074 // }
3075 #[inline]
3076 fn flush(&mut self) -> io::Result<()> {
3077 (&**self).flush()
3078 }
3079 }
3080 impl io::Seek for Arc<std::fs::File> {
3081 fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {
3082 (&**self).seek(pos)
3083 }
3084 }
3085 // TODO: TcpStream and UnixStream: https://github.com/rust-lang/rust/pull/134190
3086 // impl io::Read for Arc<std::net::TcpStream> {
3087 // fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
3088 // (&**self).read(buf)
3089 // }
3090 // // fn read_buf(&mut self, buf: io::BorrowedCursor<'_>) -> io::Result<()> {
3091 // // (&**self).read_buf(buf)
3092 // // }
3093 // fn read_vectored(&mut self, bufs: &mut [io::IoSliceMut<'_>]) -> io::Result<usize> {
3094 // (&**self).read_vectored(bufs)
3095 // }
3096 // // #[inline]
3097 // // fn is_read_vectored(&self) -> bool {
3098 // // (&**self).is_read_vectored()
3099 // // }
3100 // }
3101 // impl io::Write for Arc<std::net::TcpStream> {
3102 // fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
3103 // (&**self).write(buf)
3104 // }
3105 // fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result<usize> {
3106 // (&**self).write_vectored(bufs)
3107 // }
3108 // // #[inline]
3109 // // fn is_write_vectored(&self) -> bool {
3110 // // (&**self).is_write_vectored()
3111 // // }
3112 // #[inline]
3113 // fn flush(&mut self) -> io::Result<()> {
3114 // (&**self).flush()
3115 // }
3116 // }
3117 // #[cfg(unix)]
3118 // impl io::Read for Arc<std::os::unix::net::UnixStream> {
3119 // fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
3120 // (&**self).read(buf)
3121 // }
3122 // // fn read_buf(&mut self, buf: io::BorrowedCursor<'_>) -> io::Result<()> {
3123 // // (&**self).read_buf(buf)
3124 // // }
3125 // fn read_vectored(&mut self, bufs: &mut [io::IoSliceMut<'_>]) -> io::Result<usize> {
3126 // (&**self).read_vectored(bufs)
3127 // }
3128 // // #[inline]
3129 // // fn is_read_vectored(&self) -> bool {
3130 // // (&**self).is_read_vectored()
3131 // // }
3132 // }
3133 // #[cfg(unix)]
3134 // impl io::Write for Arc<std::os::unix::net::UnixStream> {
3135 // fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
3136 // (&**self).write(buf)
3137 // }
3138 // fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result<usize> {
3139 // (&**self).write_vectored(bufs)
3140 // }
3141 // // #[inline]
3142 // // fn is_write_vectored(&self) -> bool {
3143 // // (&**self).is_write_vectored()
3144 // // }
3145 // #[inline]
3146 // fn flush(&mut self) -> io::Result<()> {
3147 // (&**self).flush()
3148 // }
3149 // }
3150}
3151
3152use self::clone::CloneToUninit;
3153mod clone {
3154 use core::{
3155 mem::{self, MaybeUninit},
3156 ptr, slice,
3157 };
3158
3159 use super::strict;
3160
3161 // Based on unstable core::clone::CloneToUninit.
3162 // This trait is private and cannot be implemented for types outside of `portable-atomic-util`.
3163 #[doc(hidden)] // private API
3164 #[allow(unknown_lints, unnameable_types)] // Not public API. unnameable_types is available on Rust 1.79+
3165 pub unsafe trait CloneToUninit {
3166 unsafe fn clone_to_uninit(&self, dest: *mut u8);
3167 }
3168 unsafe impl<T: Clone> CloneToUninit for T {
3169 #[inline]
3170 unsafe fn clone_to_uninit(&self, dest: *mut u8) {
3171 // SAFETY: we're calling a specialization with the same contract
3172 unsafe { clone_one(self, dest as *mut T) }
3173 }
3174 }
3175 unsafe impl<T: Clone> CloneToUninit for [T] {
3176 #[inline]
3177 #[cfg_attr(all(debug_assertions, not(portable_atomic_no_track_caller)), track_caller)]
3178 unsafe fn clone_to_uninit(&self, dest: *mut u8) {
3179 let dest: *mut [T] = strict::with_metadata_of(dest, self);
3180 // SAFETY: we're calling a specialization with the same contract
3181 unsafe { clone_slice(self, dest) }
3182 }
3183 }
3184 unsafe impl CloneToUninit for str {
3185 #[inline]
3186 #[cfg_attr(all(debug_assertions, not(portable_atomic_no_track_caller)), track_caller)]
3187 unsafe fn clone_to_uninit(&self, dest: *mut u8) {
3188 // SAFETY: str is just a [u8] with UTF-8 invariant
3189 unsafe { self.as_bytes().clone_to_uninit(dest) }
3190 }
3191 }
3192 // Note: Currently, we cannot implement this for CStr/OsStr/Path since theirs layout is not stable.
3193
3194 #[inline]
3195 unsafe fn clone_one<T: Clone>(src: &T, dst: *mut T) {
3196 // SAFETY: The safety conditions of clone_to_uninit() are a superset of those of
3197 // ptr::write().
3198 unsafe {
3199 // We hope the optimizer will figure out to create the cloned value in-place,
3200 // skipping ever storing it on the stack and the copy to the destination.
3201 ptr::write(dst, src.clone());
3202 }
3203 }
3204 #[inline]
3205 #[cfg_attr(all(debug_assertions, not(portable_atomic_no_track_caller)), track_caller)]
3206 unsafe fn clone_slice<T: Clone>(src: &[T], dst: *mut [T]) {
3207 let len = src.len();
3208
3209 // SAFETY: The produced `&mut` is valid because:
3210 // * The caller is obligated to provide a pointer which is valid for writes.
3211 // * All bytes pointed to are in MaybeUninit, so we don't care about the memory's
3212 // initialization status.
3213 let uninit_ref = unsafe { &mut *(dst as *mut [MaybeUninit<T>]) };
3214
3215 // This is the most likely mistake to make, so check it as a debug assertion.
3216 debug_assert_eq!(
3217 len,
3218 uninit_ref.len(), // <*const [T]>::len is unstable
3219 "clone_to_uninit() source and destination must have equal lengths",
3220 );
3221
3222 // Copy the elements
3223 let mut initializing = InitializingSlice::from_fully_uninit(uninit_ref);
3224 for element_ref in src {
3225 // If the clone() panics, `initializing` will take care of the cleanup.
3226 initializing.push(element_ref.clone());
3227 }
3228 // If we reach here, then the entire slice is initialized, and we've satisfied our
3229 // responsibilities to the caller. Disarm the cleanup guard by forgetting it.
3230 mem::forget(initializing);
3231 }
3232
3233 /// Ownership of a collection of values stored in a non-owned `[MaybeUninit<T>]`, some of which
3234 /// are not yet initialized. This is sort of like a `Vec` that doesn't own its allocation.
3235 /// Its responsibility is to provide cleanup on unwind by dropping the values that *are*
3236 /// initialized, unless disarmed by forgetting.
3237 ///
3238 /// This is a helper for `impl<T: Clone> CloneToUninit for [T]`.
3239 struct InitializingSlice<'a, T> {
3240 data: &'a mut [MaybeUninit<T>],
3241 /// Number of elements of `*self.data` that are initialized.
3242 initialized_len: usize,
3243 }
3244 impl<'a, T> InitializingSlice<'a, T> {
3245 #[inline]
3246 fn from_fully_uninit(data: &'a mut [MaybeUninit<T>]) -> Self {
3247 Self { data, initialized_len: 0 }
3248 }
3249 /// Push a value onto the end of the initialized part of the slice.
3250 ///
3251 /// # Panics
3252 ///
3253 /// Panics if the slice is already fully initialized.
3254 #[inline]
3255 fn push(&mut self, value: T) {
3256 self.data[self.initialized_len] = MaybeUninit::new(value);
3257 self.initialized_len += 1;
3258 }
3259 }
3260 impl<T> Drop for InitializingSlice<'_, T> {
3261 #[cold] // will only be invoked on unwind
3262 fn drop(&mut self) {
3263 let initialized_slice = unsafe {
3264 slice::from_raw_parts_mut(self.data.as_mut_ptr() as *mut T, self.initialized_len)
3265 };
3266 // SAFETY:
3267 // * the pointer is valid because it was made from a mutable reference
3268 // * `initialized_len` counts the initialized elements as an invariant of this type,
3269 // so each of the pointed-to elements is initialized and may be dropped.
3270 unsafe {
3271 ptr::drop_in_place::<[T]>(initialized_slice);
3272 }
3273 }
3274 }
3275}
3276
3277mod layout {
3278 use core::{alloc::Layout, cmp};
3279
3280 use super::{ISIZE_MAX, USIZE_MAX};
3281
3282 // Based on unstable Layout::padding_needed_for.
3283 #[inline]
3284 #[must_use]
3285 pub(super) fn padding_needed_for(layout: Layout, align: usize) -> usize {
3286 // FIXME: Can we just change the type on this to `Alignment`?
3287 if !align.is_power_of_two() {
3288 return USIZE_MAX;
3289 }
3290 let len_rounded_up = size_rounded_up_to_custom_align(layout, align);
3291 // SAFETY: Cannot overflow because the rounded-up value is never less
3292 len_rounded_up.wrapping_sub(layout.size()) // can use unchecked_sub
3293 }
3294
3295 /// Returns the smallest multiple of `align` greater than or equal to `self.size()`.
3296 ///
3297 /// This can return at most `Alignment::MAX` (aka `isize::MAX + 1`)
3298 /// because the original size is at most `isize::MAX`.
3299 #[inline]
3300 fn size_rounded_up_to_custom_align(layout: Layout, align: usize) -> usize {
3301 // Rounded up value is:
3302 // size_rounded_up = (size + align - 1) & !(align - 1);
3303 //
3304 // The arithmetic we do here can never overflow:
3305 //
3306 // 1. align is guaranteed to be > 0, so align - 1 is always
3307 // valid.
3308 //
3309 // 2. size is at most `isize::MAX`, so adding `align - 1` (which is at
3310 // most `isize::MAX`) can never overflow a `usize`.
3311 //
3312 // 3. masking by the alignment can remove at most `align - 1`,
3313 // which is what we just added, thus the value we return is never
3314 // less than the original `size`.
3315 //
3316 // (Size 0 Align MAX is already aligned, so stays the same, but things like
3317 // Size 1 Align MAX or Size isize::MAX Align 2 round up to `isize::MAX + 1`.)
3318 let align_m1 = align.wrapping_sub(1);
3319 layout.size().wrapping_add(align_m1) & !align_m1
3320 }
3321
3322 // Based on Layout::pad_to_align stabilized in Rust 1.44.
3323 #[inline]
3324 #[must_use]
3325 pub(super) fn pad_to_align(layout: Layout) -> Layout {
3326 // This cannot overflow. Quoting from the invariant of Layout:
3327 // > `size`, when rounded up to the nearest multiple of `align`,
3328 // > must not overflow isize (i.e., the rounded value must be
3329 // > less than or equal to `isize::MAX`)
3330 let new_size = size_rounded_up_to_custom_align(layout, layout.align());
3331
3332 // SAFETY: padded size is guaranteed to not exceed `isize::MAX`.
3333 unsafe { Layout::from_size_align_unchecked(new_size, layout.align()) }
3334 }
3335
3336 // Based on Layout::extend stabilized in Rust 1.44.
3337 #[inline]
3338 pub(super) fn extend(layout: Layout, next: Layout) -> Option<(Layout, usize)> {
3339 let new_align = cmp::max(layout.align(), next.align());
3340 let offset = size_rounded_up_to_custom_align(layout, next.align());
3341
3342 // SAFETY: `offset` is at most `isize::MAX + 1` (such as from aligning
3343 // to `Alignment::MAX`) and `next.size` is at most `isize::MAX` (from the
3344 // `Layout` type invariant). Thus the largest possible `new_size` is
3345 // `isize::MAX + 1 + isize::MAX`, which is `usize::MAX`, and cannot overflow.
3346 let new_size = offset.wrapping_add(next.size()); // can use unchecked_add
3347
3348 let layout = Layout::from_size_align(new_size, new_align).ok()?;
3349 Some((layout, offset))
3350 }
3351
3352 // Based on Layout::array stabilized in Rust 1.44.
3353 #[inline]
3354 pub(super) fn array<T>(n: usize) -> Option<Layout> {
3355 #[inline(always)]
3356 const fn max_size_for_align(align: usize) -> usize {
3357 // (power-of-two implies align != 0.)
3358
3359 // Rounded up size is:
3360 // size_rounded_up = (size + align - 1) & !(align - 1);
3361 //
3362 // We know from above that align != 0. If adding (align - 1)
3363 // does not overflow, then rounding up will be fine.
3364 //
3365 // Conversely, &-masking with !(align - 1) will subtract off
3366 // only low-order-bits. Thus if overflow occurs with the sum,
3367 // the &-mask cannot subtract enough to undo that overflow.
3368 //
3369 // Above implies that checking for summation overflow is both
3370 // necessary and sufficient.
3371
3372 // SAFETY: the maximum possible alignment is `isize::MAX + 1`,
3373 // so the subtraction cannot overflow.
3374 (ISIZE_MAX as usize + 1).wrapping_sub(align)
3375 }
3376
3377 #[inline]
3378 fn inner(element_layout: Layout, n: usize) -> Option<Layout> {
3379 let element_size = element_layout.size();
3380 let align = element_layout.align();
3381
3382 // We need to check two things about the size:
3383 // - That the total size won't overflow a `usize`, and
3384 // - That the total size still fits in an `isize`.
3385 // By using division we can check them both with a single threshold.
3386 // That'd usually be a bad idea, but thankfully here the element size
3387 // and alignment are constants, so the compiler will fold all of it.
3388 if element_size != 0 && n > max_size_for_align(align) / element_size {
3389 return None;
3390 }
3391
3392 // SAFETY: We just checked that we won't overflow `usize` when we multiply.
3393 // This is a useless hint inside this function, but after inlining this helps
3394 // deduplicate checks for whether the overall capacity is zero (e.g., in `RawVec`'s
3395 // allocation path) before/after this multiplication.
3396 let array_size = element_size.wrapping_mul(n); // can use unchecked_mul
3397
3398 // SAFETY: We just checked above that the `array_size` will not
3399 // exceed `isize::MAX` even when rounded up to the alignment.
3400 // And `Alignment` guarantees it's a power of two.
3401 unsafe { Some(Layout::from_size_align_unchecked(array_size, align)) }
3402 }
3403
3404 // Reduce the amount of code we need to monomorphize per `T`.
3405 inner(Layout::new::<T>(), n)
3406 }
3407}
3408
3409#[cfg(feature = "std")]
3410use std::process::abort;
3411#[cfg(not(feature = "std"))]
3412#[cold]
3413fn abort() -> ! {
3414 struct Abort;
3415 impl Drop for Abort {
3416 fn drop(&mut self) {
3417 panic!();
3418 }
3419 }
3420
3421 let _abort = Abort;
3422 panic!("abort")
3423}
3424
3425fn is_dangling<T: ?Sized>(ptr: *const T) -> bool {
3426 (ptr as *const ()).addr() == USIZE_MAX
3427}
3428
3429// Based on unstable alloc::alloc::Global.
3430//
3431// Note: unlike alloc::alloc::Global that returns NonNull<[u8]>,
3432// this returns NonNull<u8>.
3433struct Global;
3434#[allow(clippy::unused_self)]
3435impl Global {
3436 #[inline]
3437 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3438 fn alloc_impl(&self, layout: Layout, zeroed: bool) -> Option<NonNull<u8>> {
3439 // Layout::dangling is unstable
3440 #[inline]
3441 #[must_use]
3442 fn dangling(layout: Layout) -> NonNull<u8> {
3443 // SAFETY: align is guaranteed to be non-zero
3444 unsafe { NonNull::new_unchecked(strict::without_provenance_mut::<u8>(layout.align())) }
3445 }
3446
3447 match layout.size() {
3448 0 => Some(dangling(layout)),
3449 // SAFETY: `layout` is non-zero in size,
3450 _size => unsafe {
3451 let raw_ptr = if zeroed {
3452 alloc::alloc::alloc_zeroed(layout)
3453 } else {
3454 alloc::alloc::alloc(layout)
3455 };
3456 NonNull::new(raw_ptr)
3457 },
3458 }
3459 }
3460 #[inline]
3461 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3462 fn allocate(self, layout: Layout) -> Option<NonNull<u8>> {
3463 self.alloc_impl(layout, false)
3464 }
3465 #[inline]
3466 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3467 fn allocate_zeroed(self, layout: Layout) -> Option<NonNull<u8>> {
3468 self.alloc_impl(layout, true)
3469 }
3470 #[inline]
3471 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
3472 unsafe fn deallocate(self, ptr: NonNull<u8>, layout: Layout) {
3473 if layout.size() != 0 {
3474 // SAFETY:
3475 // * We have checked that `layout` is non-zero in size.
3476 // * The caller is obligated to provide a layout that "fits", and in this case,
3477 // "fit" always means a layout that is equal to the original, because our
3478 // `allocate()`, `grow()`, and `shrink()` implementations never returns a larger
3479 // allocation than requested.
3480 // * Other conditions must be upheld by the caller, as per `Allocator::deallocate()`'s
3481 // safety documentation.
3482 unsafe { alloc::alloc::dealloc(ptr.as_ptr(), layout) }
3483 }
3484 }
3485}