Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a const-constructors for sync primitives #2790

Merged
merged 11 commits into from Sep 12, 2020
4 changes: 4 additions & 0 deletions tokio/src/lib.rs
Expand Up @@ -17,6 +17,10 @@
))]
#![cfg_attr(docsrs, feature(doc_cfg))]
#![cfg_attr(docsrs, feature(doc_alias))]
#![cfg_attr(
all(feature = "nightly", feature = "parking_lot", not(all(loom, test))),
feature(const_fn)
)]

//! A runtime for writing reliable, asynchronous, and slim applications.
//!
Expand Down
6 changes: 6 additions & 0 deletions tokio/src/loom/std/atomic_usize.rs
Expand Up @@ -16,6 +16,12 @@ impl AtomicUsize {
AtomicUsize { inner }
}

#[cfg(all(feature = "nightly", feature = "parking_lot", not(all(loom, test)),))]
pub(crate) const fn const_new(val: usize) -> AtomicUsize {
let inner = UnsafeCell::new(std::sync::atomic::AtomicUsize::new(val));
AtomicUsize { inner }
}

/// Performs an unsynchronized load.
///
/// # Safety
Expand Down
7 changes: 7 additions & 0 deletions tokio/src/loom/std/parking_lot.rs
Expand Up @@ -26,6 +26,13 @@ impl<T> Mutex<T> {
Mutex(parking_lot::Mutex::new(t))
}

#[inline]
#[cfg(all(feature = "nightly", feature = "parking_lot", not(all(loom, test)),))]
mental32 marked this conversation as resolved.
Show resolved Hide resolved
#[cfg_attr(docsrs, doc(cfg(all(feature = "parking_lot", feature = "nightly"))))]
pub(crate) const fn const_new(t: T) -> Mutex<T> {
Mutex(parking_lot::const_mutex(t))
}

#[inline]
pub(crate) fn lock(&self) -> LockResult<MutexGuard<'_, T>> {
Ok(self.0.lock())
Expand Down
15 changes: 15 additions & 0 deletions tokio/src/sync/batch_semaphore.rs
Expand Up @@ -123,6 +123,21 @@ impl Semaphore {
}
}

/// Creates a new semaphore with the initial number of permits
///
/// Maximum number of permits on 32-bit platforms is `1<<29`.
#[cfg(all(feature = "nightly", feature = "parking_lot", not(all(loom, test)),))]
pub(crate) const fn const_new(permits: usize) -> Self {
// FIXME: assertions and by extension panics are still being worked on: https://github.com/rust-lang/rust/issues/74925
mental32 marked this conversation as resolved.
Show resolved Hide resolved
Self {
permits: AtomicUsize::const_new(permits << Self::PERMIT_SHIFT),
waiters: Mutex::const_new(Waitlist {
queue: LinkedList::const_new(),
closed: false,
}),
}
}

/// Returns the current number of available permits
pub(crate) fn available_permits(&self) -> usize {
self.permits.load(Acquire) >> Self::PERMIT_SHIFT
Expand Down
21 changes: 21 additions & 0 deletions tokio/src/sync/mutex.rs
Expand Up @@ -219,6 +219,27 @@ impl<T: ?Sized> Mutex<T> {
}
}

/// Creates a new lock in an unlocked state ready for use.
///
/// # Examples
///
/// ```
/// use tokio::sync::Mutex;
///
/// static lock: Mutex<i32> = Mutex::const_new(5);
/// ```
#[cfg(all(feature = "nightly", feature = "parking_lot", not(all(loom, test)),))]
mental32 marked this conversation as resolved.
Show resolved Hide resolved
mental32 marked this conversation as resolved.
Show resolved Hide resolved
#[cfg_attr(docsrs, doc(cfg(all(feature = "parking_lot", feature = "nightly"))))]
pub const fn const_new(t: T) -> Self
where
T: Sized,
{
Self {
c: UnsafeCell::new(t),
s: semaphore::Semaphore::const_new(1),
}
}

/// Locks this mutex, causing the current task
/// to yield until the lock has been acquired.
/// When the lock has been acquired, function returns a [`MutexGuard`].
Expand Down
9 changes: 9 additions & 0 deletions tokio/src/util/linked_list.rs
Expand Up @@ -75,6 +75,15 @@ impl<T: Link> LinkedList<T> {
}
}

/// Creates an empty linked list
#[cfg(all(feature = "nightly", feature = "parking_lot", not(all(loom, test)),))]
mental32 marked this conversation as resolved.
Show resolved Hide resolved
pub(crate) const fn const_new() -> LinkedList<T> {
LinkedList {
head: None,
tail: None,
}
}

/// Adds an element first in the list.
pub(crate) fn push_front(&mut self, val: T::Handle) {
// The value should not be dropped, it is being inserted into the list
Expand Down