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
2 changes: 1 addition & 1 deletion tokio/src/loom/std/atomic_usize.rs
Expand Up @@ -11,7 +11,7 @@ unsafe impl Send for AtomicUsize {}
unsafe impl Sync for AtomicUsize {}

impl AtomicUsize {
pub(crate) fn new(val: usize) -> AtomicUsize {
pub(crate) const fn new(val: usize) -> AtomicUsize {
let inner = UnsafeCell::new(std::sync::atomic::AtomicUsize::new(val));
AtomicUsize { inner }
}
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 = "parking_lot", not(all(loom, test)),))]
#[cfg_attr(docsrs, doc(cfg(all(feature = "parking_lot",))))]
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
21 changes: 21 additions & 0 deletions tokio/src/sync/batch_semaphore.rs
Expand Up @@ -123,6 +123,27 @@ impl Semaphore {
}
}

/// Creates a new semaphore with the initial number of permits
///
/// Maximum number of permits on 32-bit platforms is `1<<29`.
///
/// If the specified number of permits exceeds the maximum permit amount
/// Then the value will get clamped to the maximum number of permits.
#[cfg(all(feature = "parking_lot", not(all(loom, test))))]
pub(crate) const fn const_new(mut permits: usize) -> Self {
// NOTE: assertions and by extension panics are still being worked on: https://github.com/rust-lang/rust/issues/74925
// currently we just clamp the permit count when it exceeds the max
permits = permits & Self::MAX_PERMITS;

Self {
permits: AtomicUsize::new(permits << Self::PERMIT_SHIFT),
waiters: Mutex::const_new(Waitlist {
queue: LinkedList::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 = "parking_lot", not(all(loom, test)),))]
#[cfg_attr(docsrs, doc(cfg(feature = "parking_lot")))]
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
1 change: 0 additions & 1 deletion tokio/src/util/linked_list.rs
Expand Up @@ -72,7 +72,6 @@ unsafe impl<T: Sync> Sync for Pointers<T> {}

impl<L, T> LinkedList<L, T> {
/// Creates an empty linked list.
#[allow(dead_code)] // NOTE: This will get removed with: https://github.com/tokio-rs/tokio/pull/2790
pub(crate) const fn new() -> LinkedList<L, T> {
LinkedList {
head: None,
Expand Down