Skip to content

Commit e641bc9

Browse files
committed
Start providing ways to specify priority
1 parent 30ca9dd commit e641bc9

File tree

3 files changed

+50
-101
lines changed

3 files changed

+50
-101
lines changed

crates/bevy_tasks/src/lib.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ pub trait ConditionalSendFuture: Future + ConditionalSend {}
6666

6767
impl<T: Future + ConditionalSend> ConditionalSendFuture for T {}
6868

69+
use core::marker::PhantomData;
70+
6971
use alloc::boxed::Box;
7072

7173
/// An owned and dynamically typed Future used when you can't statically type your result or need to add some indirection.
@@ -201,3 +203,30 @@ pub(crate) struct Metadata {
201203
pub priority: TaskPriority,
202204
pub is_send: bool,
203205
}
206+
207+
pub struct TaskBuilder<T> {
208+
priority: TaskPriority,
209+
marker_: PhantomData<*const T>
210+
}
211+
212+
impl<T> TaskBuilder<T> {
213+
pub fn with_priority(mut self, priority: TaskPriority) -> Self {
214+
self.priority = priority;
215+
self
216+
}
217+
218+
pub fn build_metadata(self) -> Metadata {
219+
Metadata {
220+
priority: self.priority,
221+
is_send: false,
222+
}
223+
}
224+
}
225+
226+
pub struct ScopeTaskBuilder<'a: 'scope, 'scope: 'env, 'env, T> {
227+
scope: &'a Scope<'scope, 'env, T>,
228+
}
229+
230+
impl<'a, 'scope, 'env> ScopeTaskBuilder<'a, 'scope, 'env, T> {
231+
232+
}

crates/bevy_tasks/src/task_pool.rs

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use alloc::{boxed::Box, format, string::String, vec::Vec};
22
use core::{future::Future, marker::PhantomData, mem, panic::AssertUnwindSafe};
3-
use std::thread::{self, JoinHandle};
3+
use std::{sync::OnceLock, thread::{self, JoinHandle}};
44

55
use crate::{bevy_executor::Executor, Metadata};
66
use async_task::FallibleTask;
@@ -12,6 +12,9 @@ use crate::{block_on, Task};
1212

1313
pub use crate::bevy_executor::ThreadSpawner;
1414

15+
static EXECUTOR: Executor = Executor::new();
16+
static TASK_POOL: OnceLock<TaskPool> = OnceLock::new();
17+
1518
struct CallOnDrop(Option<Arc<dyn Fn() + Send + Sync + 'static>>);
1619

1720
impl Drop for CallOnDrop {
@@ -148,9 +151,16 @@ impl TaskPool {
148151
self.executor.current_thread_spawner()
149152
}
150153

151-
/// Create a `TaskPool` with the default configuration.
152-
pub fn new() -> Self {
153-
TaskPoolBuilder::new().build()
154+
pub fn try_get() -> Option<&'static TaskPool> {
155+
TASK_POOL.get()
156+
}
157+
158+
pub fn get() -> &'static TaskPool {
159+
Self::get_or_init(Default::default)
160+
}
161+
162+
pub fn get_or_init(f: impl FnOnce() -> TaskPoolBuilder) -> &'static TaskPool {
163+
TASK_POOL.get_or_init(|| f().build_static(&EXECUTOR))
154164
}
155165

156166
fn new_internal(builder: TaskPoolBuilder, executor: &'static Executor) -> Self {
@@ -421,12 +431,6 @@ impl TaskPool {
421431
}
422432
}
423433

424-
impl Default for TaskPool {
425-
fn default() -> Self {
426-
Self::new()
427-
}
428-
}
429-
430434
impl Drop for TaskPool {
431435
fn drop(&mut self) {
432436
self.shutdown_tx.close();
@@ -553,7 +557,7 @@ mod tests {
553557

554558
#[test]
555559
fn test_spawn() {
556-
let pool = TaskPool::new();
560+
let pool = TaskPool::get();
557561

558562
let foo = Box::new(42);
559563
let foo = &*foo;
@@ -636,7 +640,7 @@ mod tests {
636640

637641
#[test]
638642
fn test_mixed_spawn_on_scope_and_spawn() {
639-
let pool = TaskPool::new();
643+
let pool = TaskPool::get();
640644

641645
let foo = Box::new(42);
642646
let foo = &*foo;
@@ -681,7 +685,7 @@ mod tests {
681685

682686
#[test]
683687
fn test_thread_locality() {
684-
let pool = Arc::new(TaskPool::new());
688+
let pool = TaskPool::get();
685689
let count = Arc::new(AtomicI32::new(0));
686690
let barrier = Arc::new(Barrier::new(101));
687691
let thread_check_failed = Arc::new(AtomicBool::new(false));
@@ -718,7 +722,7 @@ mod tests {
718722

719723
#[test]
720724
fn test_nested_spawn() {
721-
let pool = TaskPool::new();
725+
let pool = TaskPool::get();
722726

723727
let foo = Box::new(42);
724728
let foo = &*foo;
@@ -756,7 +760,7 @@ mod tests {
756760

757761
#[test]
758762
fn test_nested_locality() {
759-
let pool = Arc::new(TaskPool::new());
763+
let pool = TaskPool::get();
760764
let count = Arc::new(AtomicI32::new(0));
761765
let barrier = Arc::new(Barrier::new(101));
762766
let thread_check_failed = Arc::new(AtomicBool::new(false));
@@ -795,7 +799,7 @@ mod tests {
795799
// This test will often freeze on other executors.
796800
#[test]
797801
fn test_nested_scopes() {
798-
let pool = TaskPool::new();
802+
let pool = TaskPool::get();
799803
let count = Arc::new(AtomicI32::new(0));
800804

801805
pool.scope(|scope| {

crates/bevy_tasks/src/usages.rs

Lines changed: 1 addition & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -1,88 +1,4 @@
1-
use super::{TaskPool, TaskPoolBuilder};
2-
use bevy_platform::sync::OnceLock;
3-
use core::ops::Deref;
4-
5-
crate::cfg::bevy_executor! {
6-
if {
7-
use crate::bevy_executor::Executor;
8-
} else {
9-
use crate::edge_executor::Executor;
10-
}
11-
}
12-
13-
macro_rules! taskpool {
14-
($(#[$attr:meta])* ($static:ident, $executor:ident, $type:ident)) => {
15-
static $executor: Executor = Executor::new();
16-
static $static: OnceLock<$type> = OnceLock::new();
17-
18-
$(#[$attr])*
19-
#[derive(Debug)]
20-
pub struct $type(TaskPool);
21-
22-
impl $type {
23-
#[doc = concat!(" Gets the global [`", stringify!($type), "`] instance, or initializes it with `f`.")]
24-
pub fn get_or_init(f: impl FnOnce() -> TaskPoolBuilder) -> &'static Self {
25-
$static.get_or_init(|| Self(f().build_static(&$executor)))
26-
}
27-
28-
#[doc = concat!(" Attempts to get the global [`", stringify!($type), "`] instance, \
29-
or returns `None` if it is not initialized.")]
30-
pub fn try_get() -> Option<&'static Self> {
31-
$static.get()
32-
}
33-
34-
#[doc = concat!(" Gets the global [`", stringify!($type), "`] instance.")]
35-
#[doc = ""]
36-
#[doc = " # Panics"]
37-
#[doc = " Panics if the global instance has not been initialized yet."]
38-
pub fn get() -> &'static Self {
39-
$static.get().expect(
40-
concat!(
41-
"The ",
42-
stringify!($type),
43-
" has not been initialized yet. Please call ",
44-
stringify!($type),
45-
"::get_or_init beforehand."
46-
)
47-
)
48-
}
49-
}
50-
51-
impl Deref for $type {
52-
type Target = TaskPool;
53-
54-
fn deref(&self) -> &Self::Target {
55-
&self.0
56-
}
57-
}
58-
};
59-
}
60-
61-
taskpool! {
62-
/// A newtype for a task pool for CPU-intensive work that must be completed to
63-
/// deliver the next frame
64-
///
65-
/// See [`TaskPool`] documentation for details on Bevy tasks.
66-
/// [`AsyncComputeTaskPool`] should be preferred if the work does not have to be
67-
/// completed before the next frame.
68-
(COMPUTE_TASK_POOL, COMPUTE_EXECUTOR, ComputeTaskPool)
69-
}
70-
71-
taskpool! {
72-
/// A newtype for a task pool for CPU-intensive work that may span across multiple frames
73-
///
74-
/// See [`TaskPool`] documentation for details on Bevy tasks.
75-
/// Use [`ComputeTaskPool`] if the work must be complete before advancing to the next frame.
76-
(ASYNC_COMPUTE_TASK_POOL, ASYNC_COMPUTE_EXECUTOR, AsyncComputeTaskPool)
77-
}
78-
79-
taskpool! {
80-
/// A newtype for a task pool for IO-intensive work (i.e. tasks that spend very little time in a
81-
/// "woken" state)
82-
///
83-
/// See [`TaskPool`] documentation for details on Bevy tasks.
84-
(IO_TASK_POOL, IO_EXECUTOR, IoTaskPool)
85-
}
1+
use super::TaskPool;
862

873
crate::cfg::web! {
884
if {} else {

0 commit comments

Comments
 (0)