Skip to content

Commit eeba9b9

Browse files
authored
[oneTBB] Improve interoperability of task arenas and task groups (#624)
1 parent 1ea5088 commit eeba9b9

File tree

2 files changed

+55
-34
lines changed

2 files changed

+55
-34
lines changed

source/elements/oneTBB/source/task_scheduler/task_arena/task_arena_cls.rst

Lines changed: 40 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
.. SPDX-FileCopyrightText: 2019-2021 Intel Corporation
2+
.. SPDX-FileCopyrightText: 2025 UXL Foundation Contributors
23
..
34
.. SPDX-License-Identifier: CC-BY-4.0
45
@@ -62,9 +63,12 @@ A class that represents an explicit, user-managed task scheduler arena.
6263
int max_concurrency() const;
6364
6465
template<typename F> auto execute(F&& f) -> decltype(f());
65-
template<typename F> void enqueue(F&& f);
6666
67+
template<typename F> void enqueue(F&& f);
68+
template<typename F> void enqueue(F&& f, task_group& tg);
6769
void enqueue(task_handle&& h);
70+
71+
task_group_status task_arena::wait_for(task_group& tg);
6872
};
6973
7074
} // namespace tbb
@@ -263,7 +267,26 @@ Member functions
263267
Returns the concurrency level of the ``task_arena``.
264268
Does not require the ``task_arena`` to be initialized and does not perform initialization.
265269

266-
.. cpp:function:: template<F> void enqueue(F&& f)
270+
.. cpp:function:: template<typename F> auto execute(F&& f) -> decltype(f())
271+
272+
Executes the specified functor in the ``task_arena`` and returns the value returned by the functor.
273+
The ``F`` type must meet the `Function Objects` requirements described in the [function.objects] section of the ISO C++ standard.
274+
275+
The calling thread joins the ``task_arena`` if possible, and executes the functor.
276+
Upon return it restores the previous task scheduler state and floating-point settings.
277+
278+
If joining the ``task_arena`` is not possible, the call wraps the functor into a task,
279+
enqueues it into the arena, waits using an OS kernel synchronization object
280+
for another opportunity to join, and finishes after the task completion.
281+
282+
An exception thrown in the functor will be captured and re-thrown from ``execute``.
283+
284+
.. note::
285+
286+
Any number of threads outside of the arena can submit work to the arena and be blocked.
287+
However, only the maximal number of threads specified for the arena can participate in executing the work.
288+
289+
.. cpp:function:: template<typename F> void enqueue(F&& f)
267290

268291
Enqueues a task into the ``task_arena`` to process the specified functor and immediately returns.
269292
The ``F`` type must meet the `Function Objects` requirements described in the [function.objects] section of the ISO C++ standard.
@@ -284,34 +307,28 @@ Member functions
284307

285308
An exception thrown and not caught in the functor results in undefined behavior.
286309

287-
.. cpp:function:: template<F> auto execute(F&& f) -> decltype(f())
310+
.. cpp:function:: template<typename F> void enqueue(F&& f, task_group& tg)
288311

289-
Executes the specified functor in the ``task_arena`` and returns the value returned by the functor.
290-
The ``F`` type must meet the `Function Objects` requirements described in the [function.objects] section of the ISO C++ standard.
291-
292-
The calling thread joins the ``task_arena`` if possible, and executes the functor.
293-
Upon return it restores the previous task scheduler state and floating-point settings.
312+
Adds a task to process the specified functor into ``tg`` and enqueues it into the ``task_arena``.
294313

295-
If joining the ``task_arena`` is not possible, the call wraps the functor into a task,
296-
enqueues it into the arena, waits using an OS kernel synchronization object
297-
for another opportunity to join, and finishes after the task completion.
298-
299-
An exception thrown in the functor will be captured and re-thrown from ``execute``.
300-
301-
.. note::
302-
303-
Any number of threads outside of the arena can submit work to the arena and be blocked.
304-
However, only the maximal number of threads specified for the arena can participate in executing the work.
314+
The behavior of this function is equivalent to ``this->enqueue( tg.defer(std::forward<F>(f)) )``.
305315

306316
.. cpp:function:: void enqueue(task_handle&& h)
307317
308318
Enqueues a task owned by ``h`` into the ``task_arena`` for processing.
309319

310-
The behavior of this function is identical to the generic version (``template<typename F> void task_arena::enqueue(F&& f)``), except parameter type.
320+
The behavior of this function is equivalent to the generic version (``template<typename F> void task_arena::enqueue(F&& f)``), except parameter type.
311321

312322
.. note::
313323
``h`` should not be empty to avoid an undefined behavior.
314324

325+
.. cpp:function:: task_group_status task_arena::wait_for(task_group& tg)
326+
327+
Waits for all tasks in ``tg`` to complete or be cancelled, while possibly executing tasks in the ``task_arena``.
328+
Returns the status of ``tg`` once waiting is complete.
329+
330+
The behavior of this function is equivalent to ``this->execute([&tg]{ return tg.wait(); })``.
331+
315332
Example
316333
-------
317334

@@ -335,17 +352,13 @@ to the corresponding NUMA node.
335352
}
336353
337354
for (int i = 0; i < numa_nodes.size(); i++) {
338-
arenas[i].execute([&task_groups, i] {
339-
task_groups[i].run([] {
340-
/* executed by the thread pinned to specified NUMA node */
341-
});
342-
});
355+
arenas[i].enqueue([]{
356+
/* executed by a thread pinned to the specified NUMA node */
357+
}, task_groups[i]);
343358
}
344359
345360
for (int i = 0; i < numa_nodes.size(); i++) {
346-
arenas[i].execute([&task_groups, i] {
347-
task_groups[i].wait();
348-
});
361+
arenas[i].wait_for(task_groups[i]);
349362
}
350363
351364
return 0;

source/elements/oneTBB/source/task_scheduler/task_arena/this_task_arena_ns.rst

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
.. SPDX-FileCopyrightText: 2019-2021 Intel Corporation
2+
.. SPDX-FileCopyrightText: 2025 UXL Foundation Contributors
23
..
34
.. SPDX-License-Identifier: CC-BY-4.0
45
@@ -21,11 +22,12 @@ with the ``task_arena`` currently used by the calling thread.
2122
namespace this_task_arena {
2223
int current_thread_index();
2324
int max_concurrency();
25+
2426
template<typename F> auto isolate(F&& f) -> decltype(f());
2527
28+
template<typename F> void enqueue(F&& f);
29+
template<typename F> void enqueue(F&& f, task_group& tg);
2630
void enqueue(task_handle&& h);
27-
28-
template<typename F> void enqueue(F&& f) ;
2931
}
3032
} // namespace tbb
3133
} // namespace oneapi
@@ -63,7 +65,7 @@ with the ``task_arena`` currently used by the calling thread.
6365
If the thread has not yet initialized the task scheduler, returns the concurrency level
6466
determined automatically for the hardware configuration.
6567

66-
.. cpp:function:: template<F> auto isolate(F&& f) -> decltype(f())
68+
.. cpp:function:: template<typename F> auto isolate(F&& f) -> decltype(f())
6769

6870
Runs the specified functor in isolation by restricting the calling thread to process only tasks
6971
scheduled in the scope of the functor (also called the isolation region). The function returns the value returned by the functor.
@@ -77,15 +79,21 @@ with the ``task_arena`` currently used by the calling thread.
7779
7880
Enqueues a task into the ``task_arena`` currently used by the calling thread to process the specified functor, then returns immediately.
7981
The ``F`` type must meet the `Function Objects` requirements described in the [function.objects] section of the ISO C++ standard.
80-
81-
Behavior of this function is identical to ``template<typename F> void task_arena::enqueue(F&& f)`` applied to the ``task_arena``
82-
object constructed with ``attach`` parameter.
82+
83+
Behavior of this function is equivalent to ``template<typename F> void task_arena::enqueue(F&& f)`` applied to the ``task_arena``
84+
object constructed with ``attach`` parameter.
85+
86+
.. cpp:function:: template<typename F> void enqueue(F&& f, task_group& tg)
87+
88+
Adds a task to process the specified functor into ``tg`` and enqueues it into the ``task_arena`` currently used by the calling thread.
89+
90+
The behavior of this function is equivalent to ``this_task_arena::enqueue( tg.defer(std::forward<F>(f)) )``.
8391

8492
.. cpp:function:: void enqueue(task_handle&& h)
8593
8694
Enqueues a task owned by ``h`` into the ``task_arena`` that is currently used by the calling thread.
8795

88-
The behavior of this function is identical to the generic version (``template<typename F> void enqueue(F&& f)``), except the parameter type.
96+
The behavior of this function is equivalent to the generic version (``template<typename F> void enqueue(F&& f)``), except the parameter type.
8997

9098
.. note::
9199
``h`` should not be empty to avoid an undefined behavior.

0 commit comments

Comments
 (0)