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

[oneTBB] Add task_scheduler_handle #358

Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 64 additions & 0 deletions source/elements/oneTBB/source/deprecated/task_arena_attach_tag.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
.. SPDX-FileCopyrightText: 2019-2021 Intel Corporation
..
.. SPDX-License-Identifier: CC-BY-4.0

==================
task_arena::attach
==================
**[deprecated.task_arena_attach_tag]**

.. caution::

Deprecated in oneTBB Specification 1.1.

A set of methods for constructing a ``task_arena`` with ``attach``.
kboyarinov marked this conversation as resolved.
Show resolved Hide resolved

.. code:: cpp

// Defined in header <tbb/task_arena.h>

namespace tbb {
kboyarinov marked this conversation as resolved.
Show resolved Hide resolved

class task_arena {
public:
// ...
struct attach {};

explicit task_arena(task_arena::attach);
void initialize(task_arena::attach);
// ...
};

} // namespace tbb


Member types and constants
--------------------------

.. cpp:struct:: attach

A tag for constructing a ``task_arena`` with ``attach``.

Member functions
----------------

.. cpp:function:: explicit task_arena(task_arena::attach)

Creates an instance of ``task_arena`` that is connected to the internal task arena representation currently used by the calling thread.
If no such arena exists yet, creates a ``task_arena`` with default parameters.

.. note::

Unlike other ``task_arena`` constructors, this one automatically initializes
the new ``task_arena`` when connecting to an already existing arena.


.. cpp:function:: void initialize(task_arena::attach)

If an internal task arena representation currently used by the calling thread, the method ignores arena
alexey-katranov marked this conversation as resolved.
Show resolved Hide resolved
parameters and connects ``task_arena`` to that internal task arena representation.
The method has no effect when called for an already initialized ``task_arena``.

See also:

* :doc:`attach <../task_scheduler/attach_tag_type>`
6 changes: 6 additions & 0 deletions source/elements/oneTBB/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,9 @@ oneAPI Threading Building Blocks Specification
mutual_exclusion.rst
timing.rst
info_namespace.rst

.. toctree::
:maxdepth: 2
:caption: oneTBB Deprecated Interfaces:

task_arena_attach_tag.rst
alexey-katranov marked this conversation as resolved.
Show resolved Hide resolved
10 changes: 10 additions & 0 deletions source/elements/oneTBB/source/task_scheduler.rst
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ Scheduling controls
task_scheduler/scheduling_controls/task_group_context_cls.rst
task_scheduler/scheduling_controls/global_control_cls.rst
task_scheduler/scheduling_controls/resumable_tasks.rst
task_scheduler/scheduling_controls/task_scheduler_handle_cls.rst

Task Group
----------
Expand All @@ -56,3 +57,12 @@ Task Arena
task_scheduler/task_arena/task_arena_cls.rst
task_scheduler/task_arena/this_task_arena_ns.rst
task_scheduler/task_arena/task_scheduler_observer_cls.rst

Helper types
------------

.. toctree::
:titlesonly:

task_scheduler/attach_tag_type.rst

24 changes: 24 additions & 0 deletions source/elements/oneTBB/source/task_scheduler/attach_tag_type.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
.. SPDX-FileCopyrightText: 2021 Intel Corporation
..
.. SPDX-License-Identifier: CC-BY-4.0

===============
attach tag type
===============
**[scheduler.attach]**

An ``attach`` tag type is specifically used with ``task_arena`` and
``task_scheduler_handle`` interfaces. It is guaranteed to be constructible by default.

.. code:: cpp

namespace oneapi {
namespace tbb {
using attach = /* unspecified */
alexey-katranov marked this conversation as resolved.
Show resolved Hide resolved
}
}

See also:

* :doc:`task_arena <task_arena/task_arena_cls>`
* :doc:`task_scheduler_handle <scheduling_controls/task_scheduler_handle_cls>`
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
.. SPDX-FileCopyrightText: 2021 Intel Corporation
..
.. SPDX-License-Identifier: CC-BY-4.0

=====================
task_scheduler_handle
=====================
**[scheduler.task_scheduler_handle]**

The ``oneapi::tbb::task_scheduler_handle`` class and the ``oneapi::tbb::finalize`` function allow user to wait for completion of worker threads.

When the ``oneapi::tbb::finalize`` function is called with an ``oneapi::tbb::task_scheduler_handle`` instance, it blocks the calling
thread until the completion of all worker threads that were implicitly created by the library.


.. code:: cpp

// Defined in header <oneapi/tbb/global_control.h>

namespace oneapi {
namespace tbb {

class task_scheduler_handle {
public:
task_scheduler_handle() = default;
task_scheduler_handle(oneapi::tbb::attach);
~task_scheduler_handle();

task_scheduler_handle(const task_scheduler_handle& other) = delete;
task_scheduler_handle(task_scheduler_handle&& other) noexcept;
task_scheduler_handle& operator=(const task_scheduler_handle& other) = delete;
task_scheduler_handle& operator=(task_scheduler_handle&& other) noexcept;

explicit operator bool() const noexcept;

void release();
};

void finalize(task_scheduler_handle& handle);
bool finalize(task_scheduler_handle& handle, const std::nothrow_t&) noexcept;

} // namespace tbb
} // namespace oneapi

Member Functions
----------------

.. cpp:function:: task_scheduler_handle()

**Effects**: Creates an empty instance of the ``task_scheduler_handle`` class that does not contain any references to the task scheduler.

-------------------------------------------------------

.. cpp:function:: task_scheduler_handle(oneapi::tbb::attach)

**Effects**: Creates an instance of the ``task_scheduler_handle`` class that holds a reference to the task scheduler preventing
its premature destruction.

-------------------------------------------------------

.. cpp:function:: ~task_scheduler_handle()

**Effects**: Destroys an instance of the ``task_scheduler_handle`` class.
If not empty, releases a reference to the task scheduler and deactivates an instance of the ``task_scheduler_handle`` class.

-------------------------------------------------------

.. cpp:function:: task_scheduler_handle(task_scheduler_handle&& other) noexcept

**Effects**: Creates an instance of the ``task_scheduler_handle`` class that references the task scheduler referenced by ``other``. In turn, ``other`` releases its reference to the task scheduler.

-------------------------------------------------------

.. cpp:function:: task_scheduler_handle& operator=(task_scheduler_handle&& other) noexcept

**Effects**: If not empty, releases a reference to the task scheduler referenced by ``this``. Adds a reference to the task scheduler referenced by ``other``.
In turn, ``other`` releases its reference to the task scheduler.
**Returns**: A reference to ``*this``.

alexey-katranov marked this conversation as resolved.
Show resolved Hide resolved
-------------------------------------------------------

.. cpp:function:: explicit operator bool() const noexcept

**Returns**: ``true`` if ``this`` is not empty and refers to some task scheduler; ``false`` otherwise.

-------------------------------------------------------

.. cpp:function:: void release()

**Effects**: If not empty, releases a reference to the task scheduler and deactivates an instance of the ``task_scheduler_handle``
class; no effect otherwise. Non-blocking method.
alexey-katranov marked this conversation as resolved.
Show resolved Hide resolved
alexey-katranov marked this conversation as resolved.
Show resolved Hide resolved

Non-member Functions
--------------------

.. cpp:function:: void finalize(task_scheduler_handle& handle)
alexey-katranov marked this conversation as resolved.
Show resolved Hide resolved

**Effects**: If ``handle`` is not empty, blocks the program execution until all worker threads have been completed; no effect otherwise.
alexey-katranov marked this conversation as resolved.
Show resolved Hide resolved
alexey-katranov marked this conversation as resolved.
Show resolved Hide resolved
Throws the ``oneapi::tbb::unsafe_wait`` exception if it is not safe to wait for the completion of the worker threads.

The following conditions should be met for finalization to succeed:

- No active, not yet terminated, instances of ``task_arena`` class exist in the whole program.
- ``task_scheduler_handle::release`` is called for each other active instance of ``task_scheduler_handle`` class, possibly by different application threads.

Under these conditions, it is guaranteed that at least one ``finalize`` call succeeds,
at which point all worker threads have been completed.
If calls are performed simultaneously, more than one call might succeed.

.. note::

If user knows how many active ``task_scheduler_handle`` instances exist in the program,
it is necessary to ``release`` all but the last one, then call ``finalize`` for
the last instance.

.. caution::

The method always fails if called within a task, a parallel algorithm, or a flow graph node.

-------------------------------------------------------

.. cpp:function:: bool finalize(task_scheduler_handle& handle, const std::nothrow_t&) noexcept

**Effects**: If ``handle`` is not empty, blocks the program execution until all worker threads have been completed; no effect otherwise.
alexey-katranov marked this conversation as resolved.
Show resolved Hide resolved
alexey-katranov marked this conversation as resolved.
Show resolved Hide resolved
The behavior is the same as finalize(handle); however, ``false`` is returned instead of exception or ``true`` if no exception.

Examples
--------

.. code:: cpp

#include <oneapi/tbb/global_control.h>
#include <oneapi/tbb/parallel_for.h>

#include <iostream>

int main() {
oneapi::tbb::task_scheduler_handle handle;

handle = oneapi::tbb::task_scheduler_handle{oneapi::tbb::attach{}};
alexey-katranov marked this conversation as resolved.
Show resolved Hide resolved

// Do some parallel work here, e.g.
oneapi::tbb::parallel_for(0, 10000, [](int){});
try {
oneapi::tbb::finalize(handle);
// oneTBB worker threads are terminated at this point.
} catch (const oneapi::tbb::unsafe_wait&) {
std::cerr << "Failed to terminate the worker threads." << std::endl;
}
return 0;
}

See also:

* :doc:`attach <../attach_tag_type>`
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ A class that represents an explicit, user-managed task scheduler arena.
normal = /* unspecified */,
high = /* unspecified */
};
struct attach {};

struct constraints {
numa_node_id numa_node;
int max_concurrency;
Expand All @@ -38,15 +38,16 @@ A class that represents an explicit, user-managed task scheduler arena.
task_arena(constraints a_constraints, unsigned reserved_for_masters = 1,
priority a_priority = priority::normal);
task_arena(const task_arena &s);
explicit task_arena(task_arena::attach);
explicit task_arena(oneapi::tbb::attach);
~task_arena();

void initialize();
void initialize(int max_concurrency, unsigned reserved_for_masters = 1,
priority a_priority = priority::normal);
void initialize(constraints a_constraints, unsigned reserved_for_masters = 1,
priority a_priority = priority::normal);
void initialize(task_arena::attach);
void initialize(oneapi::tbb::attach);

void terminate();

bool is_active() const;
Expand Down Expand Up @@ -104,10 +105,6 @@ Member types and constants
When passed to a constructor or the ``initialize`` method, the initialized ``task_arena``
has a raised priority.

.. cpp:struct:: attach

A tag for constructing a ``task_arena`` with attach.

.. cpp:struct:: constraints

Represents limitations applied to threads within ``task_arena``.
Expand Down Expand Up @@ -158,7 +155,7 @@ Member functions

Copies settings from another ``task_arena`` instance.

.. cpp:function:: explicit task_arena(task_arena::attach)
.. cpp:function:: explicit task_arena(oneapi::tbb::attach)

Creates an instance of ``task_arena`` that is connected to the internal task arena representation currently used by the calling thread.
If no such arena exists yet, creates a ``task_arena`` with default parameters.
Expand Down Expand Up @@ -190,10 +187,9 @@ Member functions

Same as above.

.. cpp:function:: void initialize(task_arena::attach)
.. cpp:function:: void initialize(oneapi::tbb::attach)

If an instance of class ``task_arena::attach`` is specified as the argument, and there is
an internal task arena representation currently used by the calling thread, the method ignores arena
If an internal task arena representation currently used by the calling thread, the method ignores arena
parameters and connects ``task_arena`` to that internal task arena representation.
The method has no effect when called for an already initialized ``task_arena``.

Expand Down Expand Up @@ -293,5 +289,6 @@ to the corresponding NUMA node.

See also:

* :doc:`attach <../attach_tag_type>`
* :doc:`task_group <../task_group/task_group_cls>`
* :doc:`task_scheduler_observer <task_scheduler_observer_cls>`