From 698f8c2f01ea549d77d7dc3338a12e04c11057b9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:02:58 +0200 Subject: Adding upstream version 1.64.0+dfsg1. Signed-off-by: Daniel Baumann --- vendor/tokio/src/runtime/task/stack.rs | 83 ++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 vendor/tokio/src/runtime/task/stack.rs (limited to 'vendor/tokio/src/runtime/task/stack.rs') diff --git a/vendor/tokio/src/runtime/task/stack.rs b/vendor/tokio/src/runtime/task/stack.rs new file mode 100644 index 000000000..9dd8d3f43 --- /dev/null +++ b/vendor/tokio/src/runtime/task/stack.rs @@ -0,0 +1,83 @@ +use crate::loom::sync::atomic::AtomicPtr; +use crate::runtime::task::{Header, Task}; + +use std::marker::PhantomData; +use std::ptr::{self, NonNull}; +use std::sync::atomic::Ordering::{Acquire, Relaxed, Release}; + +/// Concurrent stack of tasks, used to pass ownership of a task from one worker +/// to another. +pub(crate) struct TransferStack { + head: AtomicPtr
, + _p: PhantomData, +} + +impl TransferStack { + pub(crate) fn new() -> TransferStack { + TransferStack { + head: AtomicPtr::new(ptr::null_mut()), + _p: PhantomData, + } + } + + pub(crate) fn push(&self, task: Task) { + let task = task.into_raw(); + + // We don't care about any memory associated w/ setting the `head` + // field, just the current value. + // + // The compare-exchange creates a release sequence. + let mut curr = self.head.load(Relaxed); + + loop { + unsafe { + task.as_ref() + .stack_next + .with_mut(|ptr| *ptr = NonNull::new(curr)) + }; + + let res = self + .head + .compare_exchange(curr, task.as_ptr() as *mut _, Release, Relaxed); + + match res { + Ok(_) => return, + Err(actual) => { + curr = actual; + } + } + } + } + + pub(crate) fn drain(&self) -> impl Iterator> { + struct Iter(Option>, PhantomData); + + impl Iterator for Iter { + type Item = Task; + + fn next(&mut self) -> Option> { + let task = self.0?; + + // Move the cursor forward + self.0 = unsafe { task.as_ref().stack_next.with(|ptr| *ptr) }; + + // Return the task + unsafe { Some(Task::from_raw(task)) } + } + } + + impl Drop for Iter { + fn drop(&mut self) { + use std::process; + + if self.0.is_some() { + // we have bugs + process::abort(); + } + } + } + + let ptr = self.head.swap(ptr::null_mut(), Acquire); + Iter(NonNull::new(ptr), PhantomData) + } +} -- cgit v1.2.3