Noting down improvement ideas for procs

This commit is contained in:
Nadja Reitzenstein 2022-06-23 16:00:21 +02:00
parent 2f5f7cb0d7
commit ff727b6d97
3 changed files with 20 additions and 8 deletions

View File

@ -46,8 +46,8 @@ pub struct LightProc {
// LightProc is both Sync and Send because it explicitly handles synchronization internally: // LightProc is both Sync and Send because it explicitly handles synchronization internally:
// The state of a `LightProc` is only modified atomically guaranteeing a consistent view from all // The state of a `LightProc` is only modified atomically guaranteeing a consistent view from all
// threads. Existing handles are atomically reference counted so the proc itself will not be dropped // threads. Existing wakers (and the proc_handle) are atomically reference counted so the proc
// until all pointers to it are themselves dropped. // itself will not be dropped until all pointers to it are themselves dropped.
// However, if the future or result inside the LightProc is !Send the executor must ensure that // However, if the future or result inside the LightProc is !Send the executor must ensure that
// the `schedule` function does not move the LightProc to a different thread. // the `schedule` function does not move the LightProc to a different thread.
unsafe impl Send for LightProc {} unsafe impl Send for LightProc {}

View File

@ -6,6 +6,7 @@ use crate::state::*;
use std::fmt::{self, Debug, Formatter}; use std::fmt::{self, Debug, Formatter};
use std::future::Future; use std::future::Future;
use std::marker::{PhantomData, Unpin}; use std::marker::{PhantomData, Unpin};
use std::mem::MaybeUninit;
use std::pin::Pin; use std::pin::Pin;
use std::ptr::NonNull; use std::ptr::NonNull;
use std::sync::atomic::Ordering; use std::sync::atomic::Ordering;
@ -24,7 +25,7 @@ pub struct ProcHandle<R> {
/// A marker capturing the generic type `R`. /// A marker capturing the generic type `R`.
// TODO: Instead of writing the future output to the RawProc on heap, put it in the handle // TODO: Instead of writing the future output to the RawProc on heap, put it in the handle
// (if still available). // (if still available).
pub(crate) result: PhantomData<R>, pub(crate) result: MaybeUninit<R>,
} }
unsafe impl<R: Send> Send for ProcHandle<R> {} unsafe impl<R: Send> Send for ProcHandle<R> {}
@ -36,7 +37,7 @@ impl<R> ProcHandle<R> {
pub(crate) fn new(raw_proc: NonNull<()>) -> Self { pub(crate) fn new(raw_proc: NonNull<()>) -> Self {
Self { Self {
raw_proc, raw_proc,
result: PhantomData, result: MaybeUninit::uninit(),
} }
} }
@ -50,6 +51,13 @@ impl<R> ProcHandle<R> {
let pdata = ptr as *const ProcData; let pdata = ptr as *const ProcData;
unsafe { unsafe {
let id = (&(*pdata).span).id().map(|id| id.into_u64()).unwrap_or(0);
tracing::trace!(
target: "executor::handle",
op = "handle.cancel",
task.id = id,
);
let mut state = (*pdata).state.load(Ordering::Acquire); let mut state = (*pdata).state.load(Ordering::Acquire);
loop { loop {

View File

@ -20,6 +20,7 @@ use tracing::Span;
/// Raw pointers to the fields of a proc. /// Raw pointers to the fields of a proc.
// TODO: Make generic over the Allocator used! // TODO: Make generic over the Allocator used!
// TODO: The actual layout stored could be expressed as a struct w/ union. Maybe do that?
pub(crate) struct RawProc<'a, F, R, S> { pub(crate) struct RawProc<'a, F, R, S> {
pub(crate) pdata: *const ProcData, pub(crate) pdata: *const ProcData,
pub(crate) schedule: *const S, pub(crate) schedule: *const S,
@ -30,10 +31,13 @@ pub(crate) struct RawProc<'a, F, R, S> {
// Make the lifetime 'a of the future invariant // Make the lifetime 'a of the future invariant
_marker: PhantomData<&'a ()>, _marker: PhantomData<&'a ()>,
// TODO: We should link a proc to a process bucket for scheduling and tracing // TODO: We should link a proc to a process group for scheduling and tracing
// => nope, do that via scheduling func // - sub-tasks should start in the same group by default
// TODO: A proc should be able to be assigned a name for tracing and reporting // - that data needs to be available when calling `spawn` and to decide which task to run.
// This could also be implemented via storing a Span similar to `Instrumented` // So there must be a thread-local reference to it that's managed by the executor, and
// updated when a new task is being polled.
// Additionally `schedule` must have a reference to it to be able to push to the right
// queue? The `schedule` fn could just come from the group instead.
} }
impl<'a, F, R, S> RawProc<'a, F, R, S> impl<'a, F, R, S> RawProc<'a, F, R, S>