Updating the tbb version in Windows build.

This commit is contained in:
Tadas Baltrusaitis 2018-02-07 08:28:39 +00:00
parent 6e8a8e6d42
commit 3dc07457a6
136 changed files with 6179 additions and 4389 deletions

View file

@ -2,6 +2,280 @@
The list of most significant changes made over time in The list of most significant changes made over time in
Intel(R) Threading Building Blocks (Intel(R) TBB). Intel(R) Threading Building Blocks (Intel(R) TBB).
Intel TBB 2017 Update 7
TBB_INTERFACE_VERSION == 9107
Changes (w.r.t. Intel TBB 2017 Update 6):
- In the huge pages mode, the memory allocator now is also able to use
transparent huge pages.
Preview Features:
- Added support for Intel TBB integration into CMake-aware
projects, with valuable guidance and feedback provided by Brad King
(Kitware).
Bugs fixed:
- Fixed scalable_allocation_command(TBBMALLOC_CLEAN_ALL_BUFFERS, 0)
to process memory left after exited threads.
------------------------------------------------------------------------
Intel TBB 2017 Update 6
TBB_INTERFACE_VERSION == 9106
Changes (w.r.t. Intel TBB 2017 Update 5):
- Added support for Android* NDK r14.
Preview Features:
- Added a blocking terminate extension to the task_scheduler_init class
that allows an object to wait for termination of worker threads.
Bugs fixed:
- Fixed compilation and testing issues with MinGW (GCC 6).
- Fixed compilation with /std:c++latest option of VS 2017
(https://github.com/01org/tbb/issues/13).
------------------------------------------------------------------------
Intel TBB 2017 Update 5
TBB_INTERFACE_VERSION == 9105
Changes (w.r.t. Intel TBB 2017 Update 4):
- Added support for Microsoft* Visual Studio* 2017.
- Added graph/matmult example to demonstrate support for compute offload
to Intel(R) Graphics Technology in the flow graph API.
- The "compiler" build option now allows to specify a full path to the
compiler.
Changes affecting backward compatibility:
- Constructors for many classes, including graph nodes, concurrent
containers, thread-local containers, etc., are declared explicit and
cannot be used for implicit conversions anymore.
Bugs fixed:
- Added a workaround for bug 16657 in the GNU C Library (glibc)
affecting the debug version of tbb::mutex.
- Fixed a crash in pool_identify() called for an object allocated in
another thread.
------------------------------------------------------------------------
Intel TBB 2017 Update 4
TBB_INTERFACE_VERSION == 9104
Changes (w.r.t. Intel TBB 2017 Update 3):
- Added support for C++11 move semantics in parallel_do.
- Added support for FreeBSD* 11.
Changes affecting backward compatibility:
- Minimal compiler versions required for support of C++11 move semantics
raised to GCC 4.5, VS 2012, and Intel(R) C++ Compiler 14.0.
Bugs fixed:
- The workaround for crashes in the library compiled with GCC 6
(-flifetime-dse=1) was extended to Windows*.
------------------------------------------------------------------------
Intel TBB 2017 Update 3
TBB_INTERFACE_VERSION == 9103
Changes (w.r.t. Intel TBB 2017 Update 2):
- Added support for Android* 7.0 and Android* NDK r13, r13b.
Preview Features:
- Added template class gfx_factory to the flow graph API. It implements
the Factory concept for streaming_node to offload computations to
Intel(R) processor graphics.
Bugs fixed:
- Fixed a possible deadlock caused by missed wakeup signals in
task_arena::execute().
Open-source contributions integrated:
- A build fix for Linux* s390x platform by Jerry J.
------------------------------------------------------------------------
Intel TBB 2017 Update 2
TBB_INTERFACE_VERSION == 9102
Changes (w.r.t. Intel TBB 2017 Update 1):
- Removed the long-outdated support for Xbox* consoles.
Bugs fixed:
- Fixed the issue with task_arena::execute() not being processed when
the calling thread cannot join the arena.
- Fixed dynamic memory allocation replacement failure on macOS* 10.12.
------------------------------------------------------------------------
Intel TBB 2017 Update 1
TBB_INTERFACE_VERSION == 9101
Changes (w.r.t. Intel TBB 2017):
Bugs fixed:
- Fixed dynamic memory allocation replacement failures on Windows* 10
Anniversary Update.
- Fixed emplace() method of concurrent unordered containers to not
require a copy constructor.
------------------------------------------------------------------------
Intel TBB 2017
TBB_INTERFACE_VERSION == 9100
Changes (w.r.t. Intel TBB 4.4 Update 5):
- static_partitioner class is now a fully supported feature.
- async_node class is now a fully supported feature.
- Improved dynamic memory allocation replacement on Windows* OS to skip
DLLs for which replacement cannot be done, instead of aborting.
- Intel TBB no longer performs dynamic memory allocation replacement
for Microsoft* Visual Studio* 2008.
- For 64-bit platforms, quadrupled the worst-case limit on the amount
of memory the Intel TBB allocator can handle.
- Added TBB_USE_GLIBCXX_VERSION macro to specify the version of GNU
libstdc++ when it cannot be properly recognized, e.g. when used
with Clang on Linux* OS. Inspired by a contribution from David A.
- Added graph/stereo example to demostrate tbb::flow::async_msg.
- Removed a few cases of excessive user data copying in the flow graph.
- Reworked split_node to eliminate unnecessary overheads.
- Added support for C++11 move semantics to the argument of
tbb::parallel_do_feeder::add() method.
- Added C++11 move constructor and assignment operator to
tbb::combinable template class.
- Added tbb::this_task_arena::max_concurrency() function and
max_concurrency() method of class task_arena returning the maximal
number of threads that can work inside an arena.
- Deprecated tbb::task_arena::current_thread_index() static method;
use tbb::this_task_arena::current_thread_index() function instead.
- All examples for commercial version of library moved online:
https://software.intel.com/en-us/product-code-samples. Examples are
available as a standalone package or as a part of Intel(R) Parallel
Studio XE or Intel(R) System Studio Online Samples packages.
Changes affecting backward compatibility:
- Renamed following methods and types in async_node class:
Old New
async_gateway_type => gateway_type
async_gateway() => gateway()
async_try_put() => try_put()
async_reserve() => reserve_wait()
async_commit() => release_wait()
- Internal layout of some flow graph nodes has changed; recompilation
is recommended for all binaries that use the flow graph.
Preview Features:
- Added template class streaming_node to the flow graph API. It allows
a flow graph to offload computations to other devices through
streaming or offloading APIs.
- Template class opencl_node reimplemented as a specialization of
streaming_node that works with OpenCL*.
- Added tbb::this_task_arena::isolate() function to isolate execution
of a group of tasks or an algorithm from other tasks submitted
to the scheduler.
Bugs fixed:
- Added a workaround for GCC bug #62258 in std::rethrow_exception()
to prevent possible problems in case of exception propagation.
- Fixed parallel_scan to provide correct result if the initial value
of an accumulator is not the operation identity value.
- Fixed a memory corruption in the memory allocator when it meets
internal limits.
- Fixed the memory allocator on 64-bit platforms to align memory
to 16 bytes by default for all allocations bigger than 8 bytes.
- As a workaround for crashes in the Intel TBB library compiled with
GCC 6, added -flifetime-dse=1 to compilation options on Linux* OS.
- Fixed a race in the flow graph implementation.
Open-source contributions integrated:
- Enabling use of C++11 'override' keyword by Raf Schietekat.
------------------------------------------------------------------------
Intel TBB 4.4 Update 6
TBB_INTERFACE_VERSION == 9006
Changes (w.r.t. Intel TBB 4.4 Update 5):
- For 64-bit platforms, quadrupled the worst-case limit on the amount
of memory the Intel TBB allocator can handle.
Bugs fixed:
- Fixed a memory corruption in the memory allocator when it meets
internal limits.
- Fixed the memory allocator on 64-bit platforms to align memory
to 16 bytes by default for all allocations bigger than 8 bytes.
- Fixed parallel_scan to provide correct result if the initial value
of an accumulator is not the operation identity value.
- As a workaround for crashes in the Intel TBB library compiled with
GCC 6, added -flifetime-dse=1 to compilation options on Linux* OS.
------------------------------------------------------------------------
Intel TBB 4.4 Update 5
TBB_INTERFACE_VERSION == 9005
Changes (w.r.t. Intel TBB 4.4 Update 4):
- Modified graph/fgbzip2 example to remove unnecessary data queuing.
Preview Features:
- Added a Python* module which is able to replace Python's thread pool
class with the implementation based on Intel TBB task scheduler.
Bugs fixed:
- Fixed the implementation of 64-bit tbb::atomic for IA-32 architecture
to work correctly with GCC 5.2 in C++11/14 mode.
- Fixed a possible crash when tasks with affinity (e.g. specified via
affinity_partitioner) are used simultaneously with task priority
changes.
------------------------------------------------------------------------
Intel TBB 4.4 Update 4
TBB_INTERFACE_VERSION == 9004
Changes (w.r.t. Intel TBB 4.4 Update 3):
- Removed a few cases of excessive user data copying in the flow graph.
- Improved robustness of concurrent_bounded_queue::abort() in case of
simultaneous push and pop operations.
Preview Features:
- Added tbb::flow::async_msg, a special message type to support
communications between the flow graph and external asynchronous
activities.
- async_node modified to support use with C++03 compilers.
Bugs fixed:
- Fixed a bug in dynamic memory allocation replacement for Windows* OS.
- Fixed excessive memory consumption on Linux* OS caused by enabling
zero-copy realloc.
- Fixed performance regression on Intel(R) Xeon Phi(tm) coprocessor with
auto_partitioner.
------------------------------------------------------------------------
Intel TBB 4.4 Update 3 Intel TBB 4.4 Update 3
TBB_INTERFACE_VERSION == 9003 TBB_INTERFACE_VERSION == 9003
@ -474,7 +748,7 @@ Bugs fixed:
- Fixed data races in preview extensions of task_scheduler_observer. - Fixed data races in preview extensions of task_scheduler_observer.
- Added noexcept(false) for destructor of task_group_base to avoid - Added noexcept(false) for destructor of task_group_base to avoid
crash on cancelation of structured task group in C++11. crash on cancellation of structured task group in C++11.
Open-source contributions integrated: Open-source contributions integrated:
@ -1157,7 +1431,7 @@ Bugs fixed:
was a temporary object. was a temporary object.
- Incorrect usage of memory fences on PowerPC and XBOX360 platforms. - Incorrect usage of memory fences on PowerPC and XBOX360 platforms.
- A subtle issue in task group context binding that could result - A subtle issue in task group context binding that could result
in cancelation signal being missed by nested task groups. in cancellation signal being missed by nested task groups.
- Incorrect construction of concurrent_unordered_map if specified - Incorrect construction of concurrent_unordered_map if specified
number of buckets is not power of two. number of buckets is not power of two.
- Broken count() and equal_range() of concurrent_unordered_map. - Broken count() and equal_range() of concurrent_unordered_map.
@ -2078,7 +2352,8 @@ Packaging:
are provided separately on Intel(R) Premier. are provided separately on Intel(R) Premier.
------------------------------------------------------------------------ ------------------------------------------------------------------------
Intel and Cilk are registered trademarks or trademarks of Intel Corporation or its Intel, the Intel logo, Xeon, Intel Xeon Phi, and Cilk are registered
subsidiaries in the United States and other countries. trademarks or trademarks of Intel Corporation or its subsidiaries in
the United States and other countries.
* Other names and brands may be claimed as the property of others. * Other names and brands may be claimed as the property of others.

201
lib/3rdParty/tbb/LICENSE vendored Normal file
View file

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -8,12 +8,14 @@ Include files for Intel® Threading Building Blocks (Intel® TBB).
<DL> <DL>
<DT><A HREF="tbb/index.html">tbb</A> <DT><A HREF="tbb/index.html">tbb</A>
<DD>Include files for Intel TBB classes and functions. <DD>Include files for Intel TBB classes and functions.
<DT><A HREF="serial/tbb/">serial/tbb</A>
<DD>Include files for a sequential implementation of the parallel_for algorithm.
</DL> </DL>
<HR> <HR>
<A HREF="../index.html">Up to parent directory</A> <A HREF="../index.html">Up to parent directory</A>
<p></p> <p></p>
Copyright &copy; 2005-2016 Intel Corporation. All Rights Reserved. Copyright &copy; 2005-2017 Intel Corporation. All Rights Reserved.
<P></P> <P></P>
Intel is a registered trademark or trademark of Intel Corporation Intel is a registered trademark or trademark of Intel Corporation
or its subsidiaries in the United States and other countries. or its subsidiaries in the United States and other countries.

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#ifndef __TBB_SERIAL_parallel_for_H #ifndef __TBB_SERIAL_parallel_for_H
@ -121,14 +121,12 @@ void parallel_for( const Range& range, const Body& body, const auto_partitioner&
serial::interface9::start_for<Range,Body,const auto_partitioner>::run(range,body,partitioner); serial::interface9::start_for<Range,Body,const auto_partitioner>::run(range,body,partitioner);
} }
#if TBB_PREVIEW_STATIC_PARTITIONER
//! Parallel iteration over range with static_partitioner. //! Parallel iteration over range with static_partitioner.
/** @ingroup algorithms **/ /** @ingroup algorithms **/
template<typename Range, typename Body> template<typename Range, typename Body>
void parallel_for( const Range& range, const Body& body, const static_partitioner& partitioner ) { void parallel_for( const Range& range, const Body& body, const static_partitioner& partitioner ) {
serial::interface9::start_for<Range,Body,const static_partitioner>::run(range,body,partitioner); serial::interface9::start_for<Range,Body,const static_partitioner>::run(range,body,partitioner);
} }
#endif
//! Parallel iteration over range with affinity_partitioner. //! Parallel iteration over range with affinity_partitioner.
/** @ingroup algorithms **/ /** @ingroup algorithms **/
@ -169,13 +167,11 @@ template <typename Index, typename Function>
void parallel_for(Index first, Index last, Index step, const Function& f, const auto_partitioner& p) { void parallel_for(Index first, Index last, Index step, const Function& f, const auto_partitioner& p) {
parallel_for_impl<Index,Function,const auto_partitioner>(first, last, step, f, p); parallel_for_impl<Index,Function,const auto_partitioner>(first, last, step, f, p);
} }
#if TBB_PREVIEW_STATIC_PARTITIONER
//! Parallel iteration over a range of integers with explicit step and static partitioner //! Parallel iteration over a range of integers with explicit step and static partitioner
template <typename Index, typename Function> template <typename Index, typename Function>
void parallel_for(Index first, Index last, Index step, const Function& f, const static_partitioner& p) { void parallel_for(Index first, Index last, Index step, const Function& f, const static_partitioner& p) {
parallel_for_impl<Index,Function,const static_partitioner>(first, last, step, f, p); parallel_for_impl<Index,Function,const static_partitioner>(first, last, step, f, p);
} }
#endif
//! Parallel iteration over a range of integers with explicit step and affinity partitioner //! Parallel iteration over a range of integers with explicit step and affinity partitioner
template <typename Index, typename Function> template <typename Index, typename Function>
void parallel_for(Index first, Index last, Index step, const Function& f, affinity_partitioner& p) { void parallel_for(Index first, Index last, Index step, const Function& f, affinity_partitioner& p) {
@ -197,13 +193,11 @@ template <typename Index, typename Function>
void parallel_for(Index first, Index last, const Function& f, const auto_partitioner& p) { void parallel_for(Index first, Index last, const Function& f, const auto_partitioner& p) {
parallel_for_impl<Index,Function,const auto_partitioner>(first, last, static_cast<Index>(1), f, p); parallel_for_impl<Index,Function,const auto_partitioner>(first, last, static_cast<Index>(1), f, p);
} }
#if TBB_PREVIEW_STATIC_PARTITIONER
//! Parallel iteration over a range of integers with default step and static partitioner //! Parallel iteration over a range of integers with default step and static partitioner
template <typename Index, typename Function> template <typename Index, typename Function>
void parallel_for(Index first, Index last, const Function& f, const static_partitioner& p) { void parallel_for(Index first, Index last, const Function& f, const static_partitioner& p) {
parallel_for_impl<Index,Function,const static_partitioner>(first, last, static_cast<Index>(1), f, p); parallel_for_impl<Index,Function,const static_partitioner>(first, last, static_cast<Index>(1), f, p);
} }
#endif
//! Parallel iteration over a range of integers with default step and affinity_partitioner //! Parallel iteration over a range of integers with default step and affinity_partitioner
template <typename Index, typename Function> template <typename Index, typename Function>
void parallel_for(Index first, Index last, const Function& f, affinity_partitioner& p) { void parallel_for(Index first, Index last, const Function& f, affinity_partitioner& p) {

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#ifndef __TBB_annotate_H #ifndef __TBB_annotate_H

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#ifndef __TBB__aggregator_H #ifndef __TBB__aggregator_H
@ -62,7 +62,7 @@ public:
template<typename Body> template<typename Body>
class basic_operation : public basic_operation_base, no_assign { class basic_operation : public basic_operation_base, no_assign {
const Body& my_body; const Body& my_body;
/*override*/ void apply_body() { my_body(); } void apply_body() __TBB_override { my_body(); }
public: public:
basic_operation(const Body& b) : basic_operation_base(), my_body(b) {} basic_operation(const Body& b) : basic_operation_base(), my_body(b) {}
}; };
@ -102,7 +102,7 @@ public:
/** Details of user-made operations must be handled by user-provided handler */ /** Details of user-made operations must be handled by user-provided handler */
void process(aggregator_operation *op) { execute_impl(*op); } void process(aggregator_operation *op) { execute_impl(*op); }
protected: protected:
/** Place operation in mailbox, then either handle mailbox or wait for the operation /** Place operation in mailbox, then either handle mailbox or wait for the operation
to be completed by a different thread. */ to be completed by a different thread. */
void execute_impl(aggregator_operation& op) { void execute_impl(aggregator_operation& op) {
@ -114,7 +114,7 @@ public:
// thus this tag will be acquired just before the operation is handled in the // thus this tag will be acquired just before the operation is handled in the
// handle_operations functor. // handle_operations functor.
call_itt_notify(releasing, &(op.status)); call_itt_notify(releasing, &(op.status));
// insert the operation in the queue // insert the operation into the list
do { do {
// ITT may flag the following line as a race; it is a false positive: // ITT may flag the following line as a race; it is a false positive:
// This is an atomic read; we don't provide itt_hide_load_word for atomics // This is an atomic read; we don't provide itt_hide_load_word for atomics
@ -135,7 +135,7 @@ public:
} }
private: private:
//! An atomically updated list (aka mailbox) of aggregator_operations //! An atomically updated list (aka mailbox) of aggregator_operations
atomic<aggregator_operation *> mailbox; atomic<aggregator_operation *> mailbox;

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#ifndef __TBB_aligned_space_H #ifndef __TBB_aligned_space_H

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#ifndef __TBB_atomic_H #ifndef __TBB_atomic_H
@ -31,8 +31,8 @@
#include "tbb_machine.h" #include "tbb_machine.h"
#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) #if _MSC_VER && !__INTEL_COMPILER
// Workaround for overzealous compiler warnings // Suppress overzealous compiler warnings till the end of the file
#pragma warning (push) #pragma warning (push)
#pragma warning (disable: 4244 4267 4512) #pragma warning (disable: 4244 4267 4512)
#endif #endif
@ -54,7 +54,9 @@ enum memory_semantics {
//! @cond INTERNAL //! @cond INTERNAL
namespace internal { namespace internal {
#if __TBB_ATTRIBUTE_ALIGNED_PRESENT #if __TBB_ALIGNAS_PRESENT
#define __TBB_DECL_ATOMIC_FIELD(t,f,a) alignas(a) t f;
#elif __TBB_ATTRIBUTE_ALIGNED_PRESENT
#define __TBB_DECL_ATOMIC_FIELD(t,f,a) t f __attribute__ ((aligned(a))); #define __TBB_DECL_ATOMIC_FIELD(t,f,a) t f __attribute__ ((aligned(a)));
#elif __TBB_DECLSPEC_ALIGN_PRESENT #elif __TBB_DECLSPEC_ALIGN_PRESENT
#define __TBB_DECL_ATOMIC_FIELD(t,f,a) __declspec(align(a)) t f; #define __TBB_DECL_ATOMIC_FIELD(t,f,a) __declspec(align(a)) t f;
@ -551,6 +553,6 @@ inline atomic<T>& as_atomic( T& t ) {
#if _MSC_VER && !__INTEL_COMPILER #if _MSC_VER && !__INTEL_COMPILER
#pragma warning (pop) #pragma warning (pop)
#endif // warnings 4244, 4267 are back #endif // warnings are restored
#endif /* __TBB_atomic_H */ #endif /* __TBB_atomic_H */

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#ifndef __TBB_blocked_range_H #ifndef __TBB_blocked_range_H

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#ifndef __TBB_blocked_range2d_H #ifndef __TBB_blocked_range2d_H

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#ifndef __TBB_blocked_range3d_H #ifndef __TBB_blocked_range3d_H

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#ifndef __TBB_cache_aligned_allocator_H #ifndef __TBB_cache_aligned_allocator_H

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#ifndef __TBB_combinable_H #ifndef __TBB_combinable_H
@ -32,9 +32,9 @@ namespace tbb {
/** @ingroup containers */ /** @ingroup containers */
template <typename T> template <typename T>
class combinable { class combinable {
private: private:
typedef typename tbb::cache_aligned_allocator<T> my_alloc; typedef typename tbb::cache_aligned_allocator<T> my_alloc;
typedef typename tbb::enumerable_thread_specific<T, my_alloc, ets_no_key> my_ets_type; typedef typename tbb::enumerable_thread_specific<T, my_alloc, ets_no_key> my_ets_type;
my_ets_type my_ets; my_ets_type my_ets;
@ -43,15 +43,28 @@ namespace tbb {
combinable() { } combinable() { }
template <typename finit> template <typename finit>
combinable( finit _finit) : my_ets(_finit) { } explicit combinable( finit _finit) : my_ets(_finit) { }
//! destructor //! destructor
~combinable() { ~combinable() { }
combinable( const combinable& other) : my_ets(other.my_ets) { }
#if __TBB_ETS_USE_CPP11
combinable( combinable&& other) : my_ets( std::move(other.my_ets)) { }
#endif
combinable & operator=( const combinable & other) {
my_ets = other.my_ets;
return *this;
} }
combinable(const combinable& other) : my_ets(other.my_ets) { } #if __TBB_ETS_USE_CPP11
combinable & operator=( combinable && other) {
combinable & operator=( const combinable & other) { my_ets = other.my_ets; return *this; } my_ets=std::move(other.my_ets);
return *this;
}
#endif
void clear() { my_ets.clear(); } void clear() { my_ets.clear(); }

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#ifndef __TBB_condition_variable_H #ifndef __TBB_condition_variable_H

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#ifndef __TBB_compat_ppl_H #ifndef __TBB_compat_ppl_H

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#ifndef __TBB_thread_H #ifndef __TBB_thread_H

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#ifndef __TBB_tuple_H #ifndef __TBB_tuple_H

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#ifndef __TBB_concurrent_hash_map_H #ifndef __TBB_concurrent_hash_map_H
@ -32,7 +32,7 @@
#include <iterator> #include <iterator>
#include <utility> // Need std::pair #include <utility> // Need std::pair
#include <cstring> // Need std::memset #include <cstring> // Need std::memset
#include <algorithm> // Need std::swap #include __TBB_STD_SWAP_HEADER
#if !TBB_USE_EXCEPTIONS && _MSC_VER #if !TBB_USE_EXCEPTIONS && _MSC_VER
#pragma warning (pop) #pragma warning (pop)
@ -333,9 +333,10 @@ namespace interface5 {
void advance_to_next_bucket() { // TODO?: refactor to iterator_base class void advance_to_next_bucket() { // TODO?: refactor to iterator_base class
size_t k = my_index+1; size_t k = my_index+1;
while( my_bucket && k <= my_map->my_mask ) { __TBB_ASSERT( my_bucket, "advancing an invalid iterator?");
while( k <= my_map->my_mask ) {
// Following test uses 2's-complement wizardry // Following test uses 2's-complement wizardry
if( k& (k-2) ) // not the beginning of a segment if( k&(k-2) ) // not the beginning of a segment
++my_bucket; ++my_bucket;
else my_bucket = my_map->get_bucket( k ); else my_bucket = my_map->get_bucket( k );
my_node = static_cast<node*>( my_bucket->node_list ); my_node = static_cast<node*>( my_bucket->node_list );
@ -368,7 +369,7 @@ namespace interface5 {
public: public:
//! Construct undefined iterator //! Construct undefined iterator
hash_map_iterator() {} hash_map_iterator(): my_map(), my_index(), my_bucket(), my_node() {}
hash_map_iterator( const hash_map_iterator<Container,typename Container::value_type> &other ) : hash_map_iterator( const hash_map_iterator<Container,typename Container::value_type> &other ) :
my_map(other.my_map), my_map(other.my_map),
my_index(other.my_index), my_index(other.my_index),
@ -765,7 +766,7 @@ public:
}; };
//! Construct empty table. //! Construct empty table.
concurrent_hash_map( const allocator_type &a = allocator_type() ) explicit concurrent_hash_map( const allocator_type &a = allocator_type() )
: internal::hash_map_base(), my_allocator(a) : internal::hash_map_base(), my_allocator(a)
{} {}

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#ifndef __TBB_concurrent_lru_cache_H #ifndef __TBB_concurrent_lru_cache_H
@ -126,8 +126,8 @@ private:
} }
static handle_move_t move(handle_object& h){ static handle_move_t move(handle_object& h){
__TBB_ASSERT(h.my_cache_pointer,"move from the same object twice ?"); __TBB_ASSERT(h.my_cache_pointer,"move from the same object twice ?");
concurrent_lru_cache * cache_pointer = NULL; concurrent_lru_cache * cache_pointer = h.my_cache_pointer;
std::swap(cache_pointer,h.my_cache_pointer); h.my_cache_pointer = NULL;
return handle_move_t(*cache_pointer,h.my_map_record_ref); return handle_move_t(*cache_pointer,h.my_map_record_ref);
} }
private: private:

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#ifndef __TBB_concurrent_priority_queue_H #ifndef __TBB_concurrent_priority_queue_H
@ -30,6 +30,7 @@
#include <vector> #include <vector>
#include <iterator> #include <iterator>
#include <functional> #include <functional>
#include __TBB_STD_SWAP_HEADER
#if __TBB_INITIALIZER_LISTS_PRESENT #if __TBB_INITIALIZER_LISTS_PRESENT
#include <initializer_list> #include <initializer_list>
@ -373,7 +374,7 @@ class concurrent_priority_queue {
compare(data[0], data[data.size()-1])) { compare(data[0], data[data.size()-1])) {
// there are newly pushed elems and the last one // there are newly pushed elems and the last one
// is higher than top // is higher than top
*(tmp->elem) = move(data[data.size()-1]); *(tmp->elem) = tbb::internal::move(data[data.size()-1]);
__TBB_store_with_release(my_size, my_size-1); __TBB_store_with_release(my_size, my_size-1);
itt_store_word_with_release(tmp->status, uintptr_t(SUCCEEDED)); itt_store_word_with_release(tmp->status, uintptr_t(SUCCEEDED));
data.pop_back(); data.pop_back();
@ -389,7 +390,7 @@ class concurrent_priority_queue {
if (tmp->type == PUSH_OP) { if (tmp->type == PUSH_OP) {
push_back_helper(*(tmp->elem), typename internal::use_element_copy_constructor<value_type>::type()); push_back_helper(*(tmp->elem), typename internal::use_element_copy_constructor<value_type>::type());
} else { } else {
data.push_back(move(*(tmp->elem))); data.push_back(tbb::internal::move(*(tmp->elem)));
} }
__TBB_store_with_release(my_size, my_size + 1); __TBB_store_with_release(my_size, my_size + 1);
itt_store_word_with_release(tmp->status, uintptr_t(SUCCEEDED)); itt_store_word_with_release(tmp->status, uintptr_t(SUCCEEDED));
@ -413,13 +414,13 @@ class concurrent_priority_queue {
compare(data[0], data[data.size()-1])) { compare(data[0], data[data.size()-1])) {
// there are newly pushed elems and the last one is // there are newly pushed elems and the last one is
// higher than top // higher than top
*(tmp->elem) = move(data[data.size()-1]); *(tmp->elem) = tbb::internal::move(data[data.size()-1]);
__TBB_store_with_release(my_size, my_size-1); __TBB_store_with_release(my_size, my_size-1);
itt_store_word_with_release(tmp->status, uintptr_t(SUCCEEDED)); itt_store_word_with_release(tmp->status, uintptr_t(SUCCEEDED));
data.pop_back(); data.pop_back();
} }
else { // extract top and push last element down heap else { // extract top and push last element down heap
*(tmp->elem) = move(data[0]); *(tmp->elem) = tbb::internal::move(data[0]);
__TBB_store_with_release(my_size, my_size-1); __TBB_store_with_release(my_size, my_size-1);
itt_store_word_with_release(tmp->status, uintptr_t(SUCCEEDED)); itt_store_word_with_release(tmp->status, uintptr_t(SUCCEEDED));
reheap(); reheap();
@ -439,14 +440,14 @@ class concurrent_priority_queue {
for (; mark<data.size(); ++mark) { for (; mark<data.size(); ++mark) {
// for each unheapified element under size // for each unheapified element under size
size_type cur_pos = mark; size_type cur_pos = mark;
value_type to_place = move(data[mark]); value_type to_place = tbb::internal::move(data[mark]);
do { // push to_place up the heap do { // push to_place up the heap
size_type parent = (cur_pos-1)>>1; size_type parent = (cur_pos-1)>>1;
if (!compare(data[parent], to_place)) break; if (!compare(data[parent], to_place)) break;
data[cur_pos] = move(data[parent]); data[cur_pos] = tbb::internal::move(data[parent]);
cur_pos = parent; cur_pos = parent;
} while( cur_pos ); } while( cur_pos );
data[cur_pos] = move(to_place); data[cur_pos] = tbb::internal::move(to_place);
} }
} }
@ -461,12 +462,12 @@ class concurrent_priority_queue {
++target; ++target;
// target now has the higher priority child // target now has the higher priority child
if (compare(data[target], data[data.size()-1])) break; if (compare(data[target], data[data.size()-1])) break;
data[cur_pos] = move(data[target]); data[cur_pos] = tbb::internal::move(data[target]);
cur_pos = target; cur_pos = target;
child = (cur_pos<<1)+1; child = (cur_pos<<1)+1;
} }
if (cur_pos != data.size()-1) if (cur_pos != data.size()-1)
data[cur_pos] = move(data[data.size()-1]); data[cur_pos] = tbb::internal::move(data[data.size()-1]);
data.pop_back(); data.pop_back();
if (mark > data.size()) mark = data.size(); if (mark > data.size()) mark = data.size();
} }

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#ifndef __TBB_concurrent_queue_H #ifndef __TBB_concurrent_queue_H
@ -40,7 +40,7 @@ class concurrent_queue: public internal::concurrent_queue_base_v3<T> {
page_allocator_type my_allocator; page_allocator_type my_allocator;
//! Allocates a block of size n (bytes) //! Allocates a block of size n (bytes)
/*override*/ virtual void *allocate_block( size_t n ) { virtual void *allocate_block( size_t n ) __TBB_override {
void *b = reinterpret_cast<void*>(my_allocator.allocate( n )); void *b = reinterpret_cast<void*>(my_allocator.allocate( n ));
if( !b ) if( !b )
internal::throw_exception(internal::eid_bad_alloc); internal::throw_exception(internal::eid_bad_alloc);
@ -48,7 +48,7 @@ class concurrent_queue: public internal::concurrent_queue_base_v3<T> {
} }
//! Deallocates block created by allocate_block. //! Deallocates block created by allocate_block.
/*override*/ virtual void deallocate_block( void *b, size_t n ) { virtual void deallocate_block( void *b, size_t n ) __TBB_override {
my_allocator.deallocate( reinterpret_cast<char*>(b), n ); my_allocator.deallocate( reinterpret_cast<char*>(b), n );
} }
@ -185,10 +185,8 @@ concurrent_queue<T,A>::~concurrent_queue() {
template<typename T, class A> template<typename T, class A>
void concurrent_queue<T,A>::clear() { void concurrent_queue<T,A>::clear() {
while( !empty() ) {
T value; T value;
this->internal_try_pop(&value); while( !empty() ) try_pop(value);
}
} }
} // namespace strict_ppl } // namespace strict_ppl
@ -223,41 +221,41 @@ class concurrent_bounded_queue: public internal::concurrent_queue_base_v8 {
return (&static_cast<padded_page*>(static_cast<void*>(&p))->last)[index]; return (&static_cast<padded_page*>(static_cast<void*>(&p))->last)[index];
} }
/*override*/ virtual void copy_item( page& dst, size_t index, const void* src ) { virtual void copy_item( page& dst, size_t index, const void* src ) __TBB_override {
new( &get_ref(dst,index) ) T(*static_cast<const T*>(src)); new( &get_ref(dst,index) ) T(*static_cast<const T*>(src));
} }
#if __TBB_CPP11_RVALUE_REF_PRESENT #if __TBB_CPP11_RVALUE_REF_PRESENT
/*override*/ virtual void move_item( page& dst, size_t index, const void* src ) { virtual void move_item( page& dst, size_t index, const void* src ) __TBB_override {
new( &get_ref(dst,index) ) T( std::move(*static_cast<T*>(const_cast<void*>(src))) ); new( &get_ref(dst,index) ) T( std::move(*static_cast<T*>(const_cast<void*>(src))) );
} }
#else #else
/*override*/ virtual void move_item( page&, size_t, const void* ) { virtual void move_item( page&, size_t, const void* ) __TBB_override {
__TBB_ASSERT( false, "Unreachable code" ); __TBB_ASSERT( false, "Unreachable code" );
} }
#endif #endif
/*override*/ virtual void copy_page_item( page& dst, size_t dindex, const page& src, size_t sindex ) { virtual void copy_page_item( page& dst, size_t dindex, const page& src, size_t sindex ) __TBB_override {
new( &get_ref(dst,dindex) ) T( get_ref( const_cast<page&>(src), sindex ) ); new( &get_ref(dst,dindex) ) T( get_ref( const_cast<page&>(src), sindex ) );
} }
#if __TBB_CPP11_RVALUE_REF_PRESENT #if __TBB_CPP11_RVALUE_REF_PRESENT
/*override*/ virtual void move_page_item( page& dst, size_t dindex, const page& src, size_t sindex ) { virtual void move_page_item( page& dst, size_t dindex, const page& src, size_t sindex ) __TBB_override {
new( &get_ref(dst,dindex) ) T( std::move(get_ref( const_cast<page&>(src), sindex )) ); new( &get_ref(dst,dindex) ) T( std::move(get_ref( const_cast<page&>(src), sindex )) );
} }
#else #else
/*override*/ virtual void move_page_item( page&, size_t, const page&, size_t ) { virtual void move_page_item( page&, size_t, const page&, size_t ) __TBB_override {
__TBB_ASSERT( false, "Unreachable code" ); __TBB_ASSERT( false, "Unreachable code" );
} }
#endif #endif
/*override*/ virtual void assign_and_destroy_item( void* dst, page& src, size_t index ) { virtual void assign_and_destroy_item( void* dst, page& src, size_t index ) __TBB_override {
T& from = get_ref(src,index); T& from = get_ref(src,index);
destroyer d(from); destroyer d(from);
*static_cast<T*>(dst) = tbb::internal::move( from ); *static_cast<T*>(dst) = tbb::internal::move( from );
} }
/*override*/ virtual page *allocate_page() { virtual page *allocate_page() __TBB_override {
size_t n = sizeof(padded_page) + (items_per_page-1)*sizeof(T); size_t n = sizeof(padded_page) + (items_per_page-1)*sizeof(T);
page *p = reinterpret_cast<page*>(my_allocator.allocate( n )); page *p = reinterpret_cast<page*>(my_allocator.allocate( n ));
if( !p ) if( !p )
@ -265,7 +263,7 @@ class concurrent_bounded_queue: public internal::concurrent_queue_base_v8 {
return p; return p;
} }
/*override*/ virtual void deallocate_page( page *p ) { virtual void deallocate_page( page *p ) __TBB_override {
size_t n = sizeof(padded_page) + (items_per_page-1)*sizeof(T); size_t n = sizeof(padded_page) + (items_per_page-1)*sizeof(T);
my_allocator.deallocate( reinterpret_cast<char*>(p), n ); my_allocator.deallocate( reinterpret_cast<char*>(p), n );
} }
@ -449,10 +447,8 @@ concurrent_bounded_queue<T,A>::~concurrent_bounded_queue() {
template<typename T, class A> template<typename T, class A>
void concurrent_bounded_queue<T,A>::clear() { void concurrent_bounded_queue<T,A>::clear() {
while( !empty() ) {
T value; T value;
internal_pop_if_present(&value); while( try_pop(value) ) /*noop*/;
}
} }
using strict_ppl::concurrent_queue; using strict_ppl::concurrent_queue;

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
/* Container implementations in this header are based on PPL implementations /* Container implementations in this header are based on PPL implementations
@ -45,22 +45,6 @@ protected:
concurrent_unordered_map_traits() : my_hash_compare() {} concurrent_unordered_map_traits() : my_hash_compare() {}
concurrent_unordered_map_traits(const hash_compare& hc) : my_hash_compare(hc) {} concurrent_unordered_map_traits(const hash_compare& hc) : my_hash_compare(hc) {}
class value_compare : public std::binary_function<value_type, value_type, bool>
{
friend class concurrent_unordered_map_traits<Key, T, Hash_compare, Allocator, Allow_multimapping>;
public:
bool operator()(const value_type& left, const value_type& right) const
{
return (my_hash_compare(left.first, right.first));
}
value_compare(const hash_compare& comparator) : my_hash_compare(comparator) {}
protected:
hash_compare my_hash_compare; // the comparator predicate for keys
};
template<class Type1, class Type2> template<class Type1, class Type2>
static const Key& get_key(const std::pair<Type1, Type2>& value) { static const Key& get_key(const std::pair<Type1, Type2>& value) {
return (value.first); return (value.first);
@ -115,12 +99,10 @@ public:
const hasher& _Hasher = hasher(), const key_equal& _Key_equality = key_equal(), const hasher& _Hasher = hasher(), const key_equal& _Key_equality = key_equal(),
const allocator_type& a = allocator_type()) const allocator_type& a = allocator_type())
: base_type(n_of_buckets, key_compare(_Hasher, _Key_equality), a) : base_type(n_of_buckets, key_compare(_Hasher, _Key_equality), a)
{ {}
}
concurrent_unordered_map(const Allocator& a) : base_type(base_type::initial_bucket_number, key_compare(), a) explicit concurrent_unordered_map(const Allocator& a) : base_type(base_type::initial_bucket_number, key_compare(), a)
{ {}
}
template <typename Iterator> template <typename Iterator>
concurrent_unordered_map(Iterator first, Iterator last, size_type n_of_buckets = base_type::initial_bucket_number, concurrent_unordered_map(Iterator first, Iterator last, size_type n_of_buckets = base_type::initial_bucket_number,
@ -142,11 +124,11 @@ public:
} }
#endif //# __TBB_INITIALIZER_LISTS_PRESENT #endif //# __TBB_INITIALIZER_LISTS_PRESENT
#if __TBB_CPP11_RVALUE_REF_PRESENT && __TBB_CPP11_IMPLICIT_MOVE_MEMBERS_GENERATION_FOR_DERIVED_BROKEN #if __TBB_CPP11_RVALUE_REF_PRESENT
#if !__TBB_IMPLICIT_MOVE_PRESENT
concurrent_unordered_map(const concurrent_unordered_map& table) concurrent_unordered_map(const concurrent_unordered_map& table)
: base_type(table) : base_type(table)
{ {}
}
concurrent_unordered_map& operator=(const concurrent_unordered_map& table) concurrent_unordered_map& operator=(const concurrent_unordered_map& table)
{ {
@ -155,25 +137,22 @@ public:
concurrent_unordered_map(concurrent_unordered_map&& table) concurrent_unordered_map(concurrent_unordered_map&& table)
: base_type(std::move(table)) : base_type(std::move(table))
{ {}
}
concurrent_unordered_map& operator=(concurrent_unordered_map&& table) concurrent_unordered_map& operator=(concurrent_unordered_map&& table)
{ {
return static_cast<concurrent_unordered_map&>(base_type::operator=(std::move(table))); return static_cast<concurrent_unordered_map&>(base_type::operator=(std::move(table)));
} }
#endif //__TBB_CPP11_IMPLICIT_MOVE_MEMBERS_GENERATION_FOR_DERIVED_BROKEN #endif //!__TBB_IMPLICIT_MOVE_PRESENT
concurrent_unordered_map(concurrent_unordered_map&& table, const Allocator& a) : base_type(std::move(table), a)
{}
#endif //__TBB_CPP11_RVALUE_REF_PRESENT
concurrent_unordered_map(const concurrent_unordered_map& table, const Allocator& a) concurrent_unordered_map(const concurrent_unordered_map& table, const Allocator& a)
: base_type(table, a) : base_type(table, a)
{ {}
}
#if __TBB_CPP11_RVALUE_REF_PRESENT
concurrent_unordered_map(concurrent_unordered_map&& table, const Allocator& a) : base_type(std::move(table), a)
{
}
#endif
// Observers // Observers
mapped_type& operator[](const key_type& key) mapped_type& operator[](const key_type& key)
{ {
@ -256,12 +235,10 @@ public:
const hasher& _Hasher = hasher(), const key_equal& _Key_equality = key_equal(), const hasher& _Hasher = hasher(), const key_equal& _Key_equality = key_equal(),
const allocator_type& a = allocator_type()) const allocator_type& a = allocator_type())
: base_type(n_of_buckets, key_compare(_Hasher, _Key_equality), a) : base_type(n_of_buckets, key_compare(_Hasher, _Key_equality), a)
{ {}
}
concurrent_unordered_multimap(const Allocator& a) : base_type(base_type::initial_bucket_number, key_compare(), a) explicit concurrent_unordered_multimap(const Allocator& a) : base_type(base_type::initial_bucket_number, key_compare(), a)
{ {}
}
template <typename Iterator> template <typename Iterator>
concurrent_unordered_multimap(Iterator first, Iterator last, size_type n_of_buckets = base_type::initial_bucket_number, concurrent_unordered_multimap(Iterator first, Iterator last, size_type n_of_buckets = base_type::initial_bucket_number,
@ -283,11 +260,11 @@ public:
} }
#endif //# __TBB_INITIALIZER_LISTS_PRESENT #endif //# __TBB_INITIALIZER_LISTS_PRESENT
#if __TBB_CPP11_RVALUE_REF_PRESENT && __TBB_CPP11_IMPLICIT_MOVE_MEMBERS_GENERATION_FOR_DERIVED_BROKEN #if __TBB_CPP11_RVALUE_REF_PRESENT
#if !__TBB_IMPLICIT_MOVE_PRESENT
concurrent_unordered_multimap(const concurrent_unordered_multimap& table) concurrent_unordered_multimap(const concurrent_unordered_multimap& table)
: base_type(table) : base_type(table)
{ {}
}
concurrent_unordered_multimap& operator=(const concurrent_unordered_multimap& table) concurrent_unordered_multimap& operator=(const concurrent_unordered_multimap& table)
{ {
@ -296,25 +273,21 @@ public:
concurrent_unordered_multimap(concurrent_unordered_multimap&& table) concurrent_unordered_multimap(concurrent_unordered_multimap&& table)
: base_type(std::move(table)) : base_type(std::move(table))
{ {}
}
concurrent_unordered_multimap& operator=(concurrent_unordered_multimap&& table) concurrent_unordered_multimap& operator=(concurrent_unordered_multimap&& table)
{ {
return static_cast<concurrent_unordered_multimap&>(base_type::operator=(std::move(table))); return static_cast<concurrent_unordered_multimap&>(base_type::operator=(std::move(table)));
} }
#endif //__TBB_CPP11_IMPLICIT_MOVE_MEMBERS_GENERATION_FOR_DERIVED_BROKEN #endif //!__TBB_IMPLICIT_MOVE_PRESENT
concurrent_unordered_multimap(concurrent_unordered_multimap&& table, const Allocator& a) : base_type(std::move(table), a)
{}
#endif //__TBB_CPP11_RVALUE_REF_PRESENT
concurrent_unordered_multimap(const concurrent_unordered_multimap& table, const Allocator& a) concurrent_unordered_multimap(const concurrent_unordered_multimap& table, const Allocator& a)
: base_type(table, a) : base_type(table, a)
{ {}
}
#if __TBB_CPP11_RVALUE_REF_PRESENT
concurrent_unordered_multimap(concurrent_unordered_multimap&& table, const Allocator& a) : base_type(std::move(table), a)
{
}
#endif
}; };
} // namespace interface5 } // namespace interface5

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
/* Container implementations in this header are based on PPL implementations /* Container implementations in this header are based on PPL implementations
@ -45,8 +45,6 @@ protected:
concurrent_unordered_set_traits() : my_hash_compare() {} concurrent_unordered_set_traits() : my_hash_compare() {}
concurrent_unordered_set_traits(const hash_compare& hc) : my_hash_compare(hc) {} concurrent_unordered_set_traits(const hash_compare& hc) : my_hash_compare(hc) {}
typedef hash_compare value_compare;
static const Key& get_key(const value_type& value) { static const Key& get_key(const value_type& value) {
return value; return value;
} }
@ -59,8 +57,8 @@ class concurrent_unordered_set : public internal::concurrent_unordered_base< con
{ {
// Base type definitions // Base type definitions
typedef internal::hash_compare<Key, Hasher, Key_equality> hash_compare; typedef internal::hash_compare<Key, Hasher, Key_equality> hash_compare;
typedef internal::concurrent_unordered_base< concurrent_unordered_set_traits<Key, hash_compare, Allocator, false> > base_type; typedef concurrent_unordered_set_traits<Key, hash_compare, Allocator, false> traits_type;
typedef concurrent_unordered_set_traits<Key, internal::hash_compare<Key, Hasher, Key_equality>, Allocator, false> traits_type; typedef internal::concurrent_unordered_base< traits_type > base_type;
#if __TBB_EXTRA_DEBUG #if __TBB_EXTRA_DEBUG
public: public:
#endif #endif
@ -94,12 +92,10 @@ public:
explicit concurrent_unordered_set(size_type n_of_buckets = base_type::initial_bucket_number, const hasher& a_hasher = hasher(), explicit concurrent_unordered_set(size_type n_of_buckets = base_type::initial_bucket_number, const hasher& a_hasher = hasher(),
const key_equal& a_keyeq = key_equal(), const allocator_type& a = allocator_type()) const key_equal& a_keyeq = key_equal(), const allocator_type& a = allocator_type())
: base_type(n_of_buckets, key_compare(a_hasher, a_keyeq), a) : base_type(n_of_buckets, key_compare(a_hasher, a_keyeq), a)
{ {}
}
concurrent_unordered_set(const Allocator& a) : base_type(base_type::initial_bucket_number, key_compare(), a) explicit concurrent_unordered_set(const Allocator& a) : base_type(base_type::initial_bucket_number, key_compare(), a)
{ {}
}
template <typename Iterator> template <typename Iterator>
concurrent_unordered_set(Iterator first, Iterator last, size_type n_of_buckets = base_type::initial_bucket_number, const hasher& a_hasher = hasher(), concurrent_unordered_set(Iterator first, Iterator last, size_type n_of_buckets = base_type::initial_bucket_number, const hasher& a_hasher = hasher(),
@ -119,11 +115,11 @@ public:
} }
#endif //# __TBB_INITIALIZER_LISTS_PRESENT #endif //# __TBB_INITIALIZER_LISTS_PRESENT
#if __TBB_CPP11_RVALUE_REF_PRESENT && __TBB_CPP11_IMPLICIT_MOVE_MEMBERS_GENERATION_FOR_DERIVED_BROKEN #if __TBB_CPP11_RVALUE_REF_PRESENT
#if !__TBB_IMPLICIT_MOVE_PRESENT
concurrent_unordered_set(const concurrent_unordered_set& table) concurrent_unordered_set(const concurrent_unordered_set& table)
: base_type(table) : base_type(table)
{ {}
}
concurrent_unordered_set& operator=(const concurrent_unordered_set& table) concurrent_unordered_set& operator=(const concurrent_unordered_set& table)
{ {
@ -132,26 +128,22 @@ public:
concurrent_unordered_set(concurrent_unordered_set&& table) concurrent_unordered_set(concurrent_unordered_set&& table)
: base_type(std::move(table)) : base_type(std::move(table))
{ {}
}
concurrent_unordered_set& operator=(concurrent_unordered_set&& table) concurrent_unordered_set& operator=(concurrent_unordered_set&& table)
{ {
return static_cast<concurrent_unordered_set&>(base_type::operator=(std::move(table))); return static_cast<concurrent_unordered_set&>(base_type::operator=(std::move(table)));
} }
#endif //__TBB_CPP11_IMPLICIT_MOVE_MEMBERS_GENERATION_FOR_DERIVED_BROKEN #endif //!__TBB_IMPLICIT_MOVE_PRESENT
concurrent_unordered_set(concurrent_unordered_set&& table, const Allocator& a)
: base_type(std::move(table), a)
{}
#endif //__TBB_CPP11_RVALUE_REF_PRESENT
concurrent_unordered_set(const concurrent_unordered_set& table, const Allocator& a) concurrent_unordered_set(const concurrent_unordered_set& table, const Allocator& a)
: base_type(table, a) : base_type(table, a)
{ {}
}
#if __TBB_CPP11_RVALUE_REF_PRESENT
concurrent_unordered_set(concurrent_unordered_set&& table, const Allocator& a)
: base_type(std::move(table), a)
{
}
#endif //__TBB_CPP11_RVALUE_REF_PRESENT
}; };
@ -199,12 +191,10 @@ public:
const hasher& _Hasher = hasher(), const key_equal& _Key_equality = key_equal(), const hasher& _Hasher = hasher(), const key_equal& _Key_equality = key_equal(),
const allocator_type& a = allocator_type()) const allocator_type& a = allocator_type())
: base_type(n_of_buckets, key_compare(_Hasher, _Key_equality), a) : base_type(n_of_buckets, key_compare(_Hasher, _Key_equality), a)
{ {}
}
concurrent_unordered_multiset(const Allocator& a) : base_type(base_type::initial_bucket_number, key_compare(), a) explicit concurrent_unordered_multiset(const Allocator& a) : base_type(base_type::initial_bucket_number, key_compare(), a)
{ {}
}
template <typename Iterator> template <typename Iterator>
concurrent_unordered_multiset(Iterator first, Iterator last, size_type n_of_buckets = base_type::initial_bucket_number, concurrent_unordered_multiset(Iterator first, Iterator last, size_type n_of_buckets = base_type::initial_bucket_number,
@ -225,11 +215,11 @@ public:
} }
#endif //# __TBB_INITIALIZER_LISTS_PRESENT #endif //# __TBB_INITIALIZER_LISTS_PRESENT
#if __TBB_CPP11_RVALUE_REF_PRESENT && __TBB_CPP11_IMPLICIT_MOVE_MEMBERS_GENERATION_FOR_DERIVED_BROKEN #if __TBB_CPP11_RVALUE_REF_PRESENT
#if !__TBB_IMPLICIT_MOVE_PRESENT
concurrent_unordered_multiset(const concurrent_unordered_multiset& table) concurrent_unordered_multiset(const concurrent_unordered_multiset& table)
: base_type(table) : base_type(table)
{ {}
}
concurrent_unordered_multiset& operator=(const concurrent_unordered_multiset& table) concurrent_unordered_multiset& operator=(const concurrent_unordered_multiset& table)
{ {
@ -238,26 +228,23 @@ public:
concurrent_unordered_multiset(concurrent_unordered_multiset&& table) concurrent_unordered_multiset(concurrent_unordered_multiset&& table)
: base_type(std::move(table)) : base_type(std::move(table))
{ {}
}
concurrent_unordered_multiset& operator=(concurrent_unordered_multiset&& table) concurrent_unordered_multiset& operator=(concurrent_unordered_multiset&& table)
{ {
return static_cast<concurrent_unordered_multiset&>(base_type::operator=(std::move(table))); return static_cast<concurrent_unordered_multiset&>(base_type::operator=(std::move(table)));
} }
#endif //__TBB_CPP11_IMPLICIT_MOVE_MEMBERS_GENERATION_FOR_DERIVED_BROKEN #endif //!__TBB_IMPLICIT_MOVE_PRESENT
concurrent_unordered_multiset(const concurrent_unordered_multiset& table, const Allocator& a)
: base_type(table, a)
{
}
#if __TBB_CPP11_RVALUE_REF_PRESENT
concurrent_unordered_multiset(concurrent_unordered_multiset&& table, const Allocator& a) concurrent_unordered_multiset(concurrent_unordered_multiset&& table, const Allocator& a)
: base_type(std::move(table), a) : base_type(std::move(table), a)
{ {
} }
#endif //__TBB_CPP11_RVALUE_REF_PRESENT #endif //__TBB_CPP11_RVALUE_REF_PRESENT
concurrent_unordered_multiset(const concurrent_unordered_multiset& table, const Allocator& a)
: base_type(table, a)
{}
}; };
} // namespace interface5 } // namespace interface5

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#ifndef __TBB_concurrent_vector_H #ifndef __TBB_concurrent_vector_H
@ -30,6 +30,7 @@
#include "tbb_profiling.h" #include "tbb_profiling.h"
#include <new> #include <new>
#include <cstring> // for memset() #include <cstring> // for memset()
#include __TBB_STD_SWAP_HEADER
#if !TBB_USE_EXCEPTIONS && _MSC_VER #if !TBB_USE_EXCEPTIONS && _MSC_VER
// Suppress "C++ exception handler used, but unwind semantics are not enabled" warning in STL headers // Suppress "C++ exception handler used, but unwind semantics are not enabled" warning in STL headers
@ -72,12 +73,12 @@ namespace tbb {
template<typename T, class A = cache_aligned_allocator<T> > template<typename T, class A = cache_aligned_allocator<T> >
class concurrent_vector; class concurrent_vector;
template<typename Container, typename Value>
class vector_iterator;
//! @cond INTERNAL //! @cond INTERNAL
namespace internal { namespace internal {
template<typename Container, typename Value>
class vector_iterator;
//! Bad allocation marker //! Bad allocation marker
static void *const vector_allocation_error_flag = reinterpret_cast<void*>(size_t(63)); static void *const vector_allocation_error_flag = reinterpret_cast<void*>(size_t(63));

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#ifndef _TBB_CRITICAL_SECTION_H_ #ifndef _TBB_CRITICAL_SECTION_H_

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#ifndef __TBB_enumerable_thread_specific_H #ifndef __TBB_enumerable_thread_specific_H
@ -73,7 +73,7 @@ namespace interface6 {
slot& at( size_t k ) { slot& at( size_t k ) {
return ((slot*)(void*)(this+1))[k]; return ((slot*)(void*)(this+1))[k];
} }
size_t size() const {return (size_t)1<<lg_size;} size_t size() const {return size_t(1)<<lg_size;}
size_t mask() const {return size()-1;} size_t mask() const {return size()-1;}
size_t start( size_t h ) const { size_t start( size_t h ) const {
return h>>(8*sizeof(size_t)-lg_size); return h>>(8*sizeof(size_t)-lg_size);
@ -102,14 +102,14 @@ namespace interface6 {
virtual void* create_array(size_t _size) = 0; // _size in bytes virtual void* create_array(size_t _size) = 0; // _size in bytes
virtual void free_array(void* ptr, size_t _size) = 0; // _size in bytes virtual void free_array(void* ptr, size_t _size) = 0; // _size in bytes
array* allocate( size_t lg_size ) { array* allocate( size_t lg_size ) {
size_t n = 1<<lg_size; size_t n = size_t(1)<<lg_size;
array* a = static_cast<array*>(create_array( sizeof(array)+n*sizeof(slot) )); array* a = static_cast<array*>(create_array( sizeof(array)+n*sizeof(slot) ));
a->lg_size = lg_size; a->lg_size = lg_size;
std::memset( a+1, 0, n*sizeof(slot) ); std::memset( a+1, 0, n*sizeof(slot) );
return a; return a;
} }
void free(array* a) { void free(array* a) {
size_t n = 1<<(a->lg_size); size_t n = size_t(1)<<(a->lg_size);
free_array( (void *)a, size_t(sizeof(array)+n*sizeof(slot)) ); free_array( (void *)a, size_t(sizeof(array)+n*sizeof(slot)) );
} }
@ -266,9 +266,9 @@ namespace interface6 {
void* get_tls() const { return pthread_getspecific(my_key); } void* get_tls() const { return pthread_getspecific(my_key); }
#endif #endif
tls_key_t my_key; tls_key_t my_key;
virtual void* create_local() = 0; virtual void* create_local() __TBB_override = 0;
virtual void* create_array(size_t _size) = 0; // _size in bytes virtual void* create_array(size_t _size) __TBB_override = 0; // _size in bytes
virtual void free_array(void* ptr, size_t _size) = 0; // size in bytes virtual void free_array(void* ptr, size_t _size) __TBB_override = 0; // size in bytes
protected: protected:
ets_base() {create_key();} ets_base() {create_key();}
~ets_base() {destroy_key();} ~ets_base() {destroy_key();}
@ -663,16 +663,16 @@ namespace interface6 {
// TODO: make the construction/destruction consistent (use allocator.construct/destroy) // TODO: make the construction/destruction consistent (use allocator.construct/destroy)
typedef typename tbb::tbb_allocator<callback_leaf> my_allocator_type; typedef typename tbb::tbb_allocator<callback_leaf> my_allocator_type;
/*override*/ callback_base<T>* clone() const { callback_base<T>* clone() const __TBB_override {
return make(*this); return make(*this);
} }
/*override*/ void destroy() { void destroy() __TBB_override {
my_allocator_type().destroy(this); my_allocator_type().destroy(this);
my_allocator_type().deallocate(this,1); my_allocator_type().deallocate(this,1);
} }
/*override*/ void construct(void* where) { void construct(void* where) __TBB_override {
Constructor::construct(where); Constructor::construct(where);
} }
public: public:
@ -700,7 +700,6 @@ namespace interface6 {
successfully-constructed, set the flag to true or call value_committed(). successfully-constructed, set the flag to true or call value_committed().
If the constructor throws, the flag will be false. If the constructor throws, the flag will be false.
*/ */
// TODO: make a constructor for ets_element that takes a callback_base. make is_built private
template<typename U> template<typename U>
struct ets_element { struct ets_element {
tbb::aligned_space<U> my_space; tbb::aligned_space<U> my_space;
@ -794,7 +793,7 @@ namespace interface6 {
// TODO: consider unifying the callback mechanism for all create_local* methods below // TODO: consider unifying the callback mechanism for all create_local* methods below
// (likely non-compatible and requires interface version increase) // (likely non-compatible and requires interface version increase)
/*override*/ void* create_local() { void* create_local() __TBB_override {
padded_element& lref = *my_locals.grow_by(1); padded_element& lref = *my_locals.grow_by(1);
my_construct_callback->construct(lref.value()); my_construct_callback->construct(lref.value());
return lref.value_committed(); return lref.value_committed();
@ -819,12 +818,12 @@ namespace interface6 {
typedef typename Allocator::template rebind< uintptr_t >::other array_allocator_type; typedef typename Allocator::template rebind< uintptr_t >::other array_allocator_type;
// _size is in bytes // _size is in bytes
/*override*/ void* create_array(size_t _size) { void* create_array(size_t _size) __TBB_override {
size_t nelements = (_size + sizeof(uintptr_t) -1) / sizeof(uintptr_t); size_t nelements = (_size + sizeof(uintptr_t) -1) / sizeof(uintptr_t);
return array_allocator_type().allocate(nelements); return array_allocator_type().allocate(nelements);
} }
/*override*/ void free_array( void* _ptr, size_t _size) { void free_array( void* _ptr, size_t _size) __TBB_override {
size_t nelements = (_size + sizeof(uintptr_t) -1) / sizeof(uintptr_t); size_t nelements = (_size + sizeof(uintptr_t) -1) / sizeof(uintptr_t);
array_allocator_type().deallocate( reinterpret_cast<uintptr_t *>(_ptr),nelements); array_allocator_type().deallocate( reinterpret_cast<uintptr_t *>(_ptr),nelements);
} }
@ -860,17 +859,17 @@ namespace interface6 {
, typename = typename internal::enable_if<internal::is_callable_no_args<typename internal::strip<Finit>::type>::value>::type , typename = typename internal::enable_if<internal::is_callable_no_args<typename internal::strip<Finit>::type>::value>::type
#endif #endif
> >
enumerable_thread_specific( Finit finit ) : my_construct_callback( explicit enumerable_thread_specific( Finit finit ) : my_construct_callback(
internal::callback_leaf<T,internal::construct_by_finit<T,Finit> >::make( tbb::internal::move(finit) ) internal::callback_leaf<T,internal::construct_by_finit<T,Finit> >::make( tbb::internal::move(finit) )
){} ){}
//! Constructor with exemplar. Each local instance of T is copy-constructed from the exemplar. //! Constructor with exemplar. Each local instance of T is copy-constructed from the exemplar.
enumerable_thread_specific( const T& exemplar ) : my_construct_callback( explicit enumerable_thread_specific( const T& exemplar ) : my_construct_callback(
internal::callback_leaf<T,internal::construct_by_exemplar<T> >::make( exemplar ) internal::callback_leaf<T,internal::construct_by_exemplar<T> >::make( exemplar )
){} ){}
#if __TBB_ETS_USE_CPP11 #if __TBB_ETS_USE_CPP11
enumerable_thread_specific( T&& exemplar ) : my_construct_callback( explicit enumerable_thread_specific( T&& exemplar ) : my_construct_callback(
internal::callback_leaf<T,internal::construct_by_exemplar<T> >::make( std::move(exemplar) ) internal::callback_leaf<T,internal::construct_by_exemplar<T> >::make( std::move(exemplar) )
){} ){}
@ -1089,7 +1088,7 @@ namespace interface6 {
flattened2d( const Container &c, typename Container::const_iterator b, typename Container::const_iterator e ) : flattened2d( const Container &c, typename Container::const_iterator b, typename Container::const_iterator e ) :
my_container(const_cast<Container*>(&c)), my_begin(b), my_end(e) { } my_container(const_cast<Container*>(&c)), my_begin(b), my_end(e) { }
flattened2d( const Container &c ) : explicit flattened2d( const Container &c ) :
my_container(const_cast<Container*>(&c)), my_begin(c.begin()), my_end(c.end()) { } my_container(const_cast<Container*>(&c)), my_begin(c.begin()), my_end(c.end()) { }
iterator begin() { return iterator(*my_container) = my_begin; } iterator begin() { return iterator(*my_container) = my_begin; }

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,57 @@
/*
Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#ifndef __TBB_flow_graph_abstractions_H
#define __TBB_flow_graph_abstractions_H
namespace tbb {
namespace flow {
namespace interface9 {
//! Pure virtual template classes that define interfaces for async communication
class graph_proxy {
public:
//! Inform a graph that messages may come from outside, to prevent premature graph completion
virtual void reserve_wait() = 0;
//! Inform a graph that a previous call to reserve_wait is no longer in effect
virtual void release_wait() = 0;
virtual ~graph_proxy() {}
};
template <typename Input>
class receiver_gateway : public graph_proxy {
public:
//! Type of inputing data into FG.
typedef Input input_type;
//! Submit signal from an asynchronous activity to FG.
virtual bool try_put(const input_type&) = 0;
};
} //interface9
using interface9::graph_proxy;
using interface9::receiver_gateway;
} //flow
} //tbb
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,359 @@
/*
Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#ifndef __TBB_flow_graph_gfx_factory_H
#define __TBB_flow_graph_gfx_factory_H
#include "tbb/tbb_config.h"
#if __TBB_PREVIEW_GFX_FACTORY
#include <vector>
#include <future>
#include <mutex>
#include <iostream>
#include <gfx/gfx_rt.h>
#include <gfx/gfx_intrin.h>
#include <gfx/gfx_types.h>
namespace tbb {
namespace flow {
namespace interface9 {
template <typename T>
class gfx_buffer;
namespace gfx_offload {
typedef GfxTaskId task_id_type;
//-----------------------------------------------------------------------
// GFX errors checkers.
// For more debug output, set GFX_LOG_OFFLOAD=2 macro
//-----------------------------------------------------------------------
// TODO: reconsider error handling approach. If exception is the right way
// then need to define and document a specific exception type.
inline void throw_gfx_exception() {
std::string msg = "GFX error occurred: " + std::to_string(_GFX_get_last_error());
std::cerr << msg << std::endl;
throw msg;
}
inline void check_enqueue_retcode(task_id_type err) {
if (err == 0) {
throw_gfx_exception();
}
}
inline void check_gfx_retcode(task_id_type err) {
if (err != GFX_SUCCESS) {
throw_gfx_exception();
}
}
//---------------------------------------------------------------------
// GFX asynchronous offload and share API
//---------------------------------------------------------------------
// Sharing and unsharing data API
template<typename DataType, typename SizeType>
void share(DataType* p, SizeType n) { check_gfx_retcode(_GFX_share(p, sizeof(*p)*n)); }
template<typename DataType>
void unshare(DataType* p) { check_gfx_retcode(_GFX_unshare(p)); }
// Retrieving array pointer from shared gfx_buffer
// Other types remain the same
template <typename T>
T* raw_data(gfx_buffer<T>& buffer) { return buffer.data(); }
template <typename T>
const T* raw_data(const gfx_buffer<T>& buffer) { return buffer.data(); }
template <typename T>
T& raw_data(T& data) { return data; }
template <typename T>
const T& raw_data(const T& data) { return data; }
// Kernel enqueuing on device with arguments
template <typename F, typename ...ArgType>
task_id_type run_kernel(F ptr, ArgType&... args) {
task_id_type id = _GFX_offload(ptr, raw_data(args)...);
// Check if something during offload went wrong (ex: driver initialization failure)
gfx_offload::check_enqueue_retcode(id);
return id;
}
// Waiting for tasks completion
void wait_for_task(task_id_type id) { check_gfx_retcode(_GFX_wait(id)); }
} // namespace gfx_offload
template <typename T>
class gfx_buffer {
public:
typedef typename std::vector<T>::iterator iterator;
typedef typename std::vector<T>::const_iterator const_iterator;
typedef std::size_t size_type;
gfx_buffer() : my_vector_ptr(std::make_shared< std::vector<T> >()) {}
gfx_buffer(size_type size) : my_vector_ptr(std::make_shared< std::vector<T> >(size)) {}
T* data() { return &(my_vector_ptr->front()); }
const T* data() const { return &(my_vector_ptr->front()); }
size_type size() const { return my_vector_ptr->size(); }
const_iterator cbegin() const { return my_vector_ptr->cbegin(); }
const_iterator cend() const { return my_vector_ptr->cend(); }
iterator begin() { return my_vector_ptr->begin(); }
iterator end() { return my_vector_ptr->end(); }
T& operator[](size_type pos) { return (*my_vector_ptr)[pos]; }
const T& operator[](size_type pos) const { return (*my_vector_ptr)[pos]; }
private:
std::shared_ptr< std::vector<T> > my_vector_ptr;
};
template<typename T>
class gfx_async_msg : public tbb::flow::async_msg<T> {
public:
typedef gfx_offload::task_id_type kernel_id_type;
gfx_async_msg() : my_task_id(0) {}
gfx_async_msg(const T& input_data) : my_data(input_data), my_task_id(0) {}
T& data() { return my_data; }
const T& data() const { return my_data; }
void set_task_id(kernel_id_type id) { my_task_id = id; }
kernel_id_type task_id() const { return my_task_id; }
private:
T my_data;
kernel_id_type my_task_id;
};
class gfx_factory {
private:
// Wrapper for GFX kernel which is just a function
class func_wrapper {
public:
template <typename F>
func_wrapper(F ptr) { my_ptr = reinterpret_cast<void*>(ptr); }
template<typename ...Args>
void operator()(Args&&... args) {}
operator void*() { return my_ptr; }
private:
void* my_ptr;
};
public:
// Device specific types
template<typename T> using async_msg_type = gfx_async_msg<T>;
typedef func_wrapper kernel_type;
// Empty device type that is needed for Factory Concept
// but is not used in gfx_factory
typedef struct {} device_type;
typedef gfx_offload::task_id_type kernel_id_type;
gfx_factory(tbb::flow::graph& g) : m_graph(g), current_task_id(0) {}
// Upload data to the device
template <typename ...Args>
void send_data(device_type /*device*/, Args&... args) {
send_data_impl(args...);
}
// Run kernel on the device
template <typename ...Args>
void send_kernel(device_type /*device*/, const kernel_type& kernel, Args&... args) {
// Get packed T data from async_msg<T> and pass it to kernel
kernel_id_type id = gfx_offload::run_kernel(kernel, args.data()...);
// Set id to async_msg
set_kernel_id(id, args...);
// Extend the graph lifetime until the callback completion.
m_graph.reserve_wait();
// Mutex for future assignment
std::lock_guard<std::mutex> lock(future_assignment_mutex);
// Set callback that waits for kernel execution
callback_future = std::async(std::launch::async, &gfx_factory::callback<Args...>, this, id, args...);
}
// Finalization action after the kernel run
template <typename FinalizeFn, typename ...Args>
void finalize(device_type /*device*/, FinalizeFn fn, Args&... /*args*/) {
fn();
}
// Empty device selector.
// No way to choose a device with GFX API.
class dummy_device_selector {
public:
device_type operator()(gfx_factory& /*factory*/) {
return device_type();
}
};
private:
//---------------------------------------------------------------------
// Callback for kernel result
//---------------------------------------------------------------------
template <typename ...Args>
void callback(kernel_id_type id, Args... args) {
// Waiting for specific tasks id to complete
{
std::lock_guard<std::mutex> lock(task_wait_mutex);
if (current_task_id < id) {
gfx_offload::wait_for_task(id);
current_task_id = id;
}
}
// Get result from device and set to async_msg (args)
receive_data(args...);
// Data was sent to the graph, release the reference
m_graph.release_wait();
}
//---------------------------------------------------------------------
// send_data() arguments processing
//---------------------------------------------------------------------
// GFX buffer shared data with device that will be executed on
template <typename T>
void share_data(T) {}
template <typename T>
void share_data(gfx_buffer<T>& buffer) {
gfx_offload::share(buffer.data(), buffer.size());
}
template <typename T>
void send_arg(T) {}
template <typename T>
void send_arg(async_msg_type<T>& msg) {
share_data(msg.data());
}
void send_data_impl() {}
template <typename T, typename ...Rest>
void send_data_impl(T& arg, Rest&... args) {
send_arg(arg);
send_data_impl(args...);
}
//----------------------------------------------------------------------
// send_kernel() arguments processing
//----------------------------------------------------------------------
template <typename T>
void set_kernel_id_arg(kernel_id_type, T) {}
template <typename T>
void set_kernel_id_arg(kernel_id_type id, async_msg_type<T>& msg) {
msg.set_task_id(id);
}
void set_kernel_id(kernel_id_type) {}
template <typename T, typename ...Rest>
void set_kernel_id(kernel_id_type id, T& arg, Rest&... args) {
set_kernel_id_arg(id, arg);
set_kernel_id(id, args...);
}
//-----------------------------------------------------------------------
// Arguments processing after kernel execution.
// Unsharing buffers and forwarding results to the graph
//-----------------------------------------------------------------------
// After kernel execution the data should be unshared
template <typename T>
void unshare_data(T) {}
template <typename T>
void unshare_data(gfx_buffer<T>& buffer) {
gfx_offload::unshare(buffer.data());
}
template <typename T>
void receive_arg(T) {}
template <typename T>
void receive_arg(async_msg_type<T>& msg) {
unshare_data(msg.data());
msg.set(msg.data());
}
void receive_data() {}
template <typename T, typename ...Rest>
void receive_data(T& arg, Rest&... args) {
receive_arg(arg);
receive_data(args...);
}
//-----------------------------------------------------------------------
int current_task_id;
std::future<void> callback_future;
tbb::flow::graph& m_graph;
std::mutex future_assignment_mutex;
std::mutex task_wait_mutex;
};
} // namespace interface9
using interface9::gfx_factory;
using interface9::gfx_buffer;
} // namespace flow
} // namespace tbb
#endif // __TBB_PREVIEW_GFX_FACTORY
#endif // __TBB_flow_graph_gfx_factory_H

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#ifndef __TBB_global_control_H #ifndef __TBB_global_control_H

View file

@ -19,7 +19,7 @@ Include files for Intel&reg; Threading Building Blocks classes and functions.
<HR> <HR>
<A HREF="../index.html">Up to parent directory</A> <A HREF="../index.html">Up to parent directory</A>
<p></p> <p></p>
Copyright &copy; 2005-2016 Intel Corporation. All Rights Reserved. Copyright &copy; 2005-2017 Intel Corporation. All Rights Reserved.
<P></P> <P></P>
Intel is a registered trademark or trademark of Intel Corporation Intel is a registered trademark or trademark of Intel Corporation
or its subsidiaries in the United States and other countries. or its subsidiaries in the United States and other countries.

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#ifndef __TBB__aggregator_impl_H #ifndef __TBB__aggregator_impl_H
@ -36,7 +36,9 @@ using namespace tbb::internal;
template <typename Derived> template <typename Derived>
class aggregated_operation { class aggregated_operation {
public: public:
//! Zero value means "wait" status, all other values are "user" specified values and are defined into the scope of a class which uses "status".
uintptr_t status; uintptr_t status;
Derived *next; Derived *next;
aggregated_operation() : status(0), next(NULL) {} aggregated_operation() : status(0), next(NULL) {}
}; };
@ -52,19 +54,21 @@ class aggregator_generic {
public: public:
aggregator_generic() : handler_busy(false) { pending_operations = NULL; } aggregator_generic() : handler_busy(false) { pending_operations = NULL; }
//! Place operation in list //! Execute an operation
/** Place operation in list and either handle list or wait for operation to /** Places an operation into the waitlist (pending_operations), and either handles the list,
complete. or waits for the operation to complete, or returns.
long_life_time specifies life time of an operation inserting in an aggregator. The long_life_time parameter specifies the life time of the given operation object.
"Long" (long_life_time == true) life time operation can be accessed Operations with long_life_time == true may be accessed after execution.
even after executing it. A "short" life time operation (long_life_time == false) can be destroyed
"Short" (long_life_time == false) life time operations can be destroyed during execution, and so any access to it after it was put into the waitlist,
during executing so any access to it after executing is invalid.*/ including status check, is invalid. As a consequence, waiting for completion
of such operation causes undefined behavior.
*/
template < typename handler_type > template < typename handler_type >
void execute(operation_type *op, handler_type &handle_operations, bool long_life_time = true) { void execute(operation_type *op, handler_type &handle_operations, bool long_life_time = true) {
operation_type *res; operation_type *res;
// op->status should be read before inserting the operation in the // op->status should be read before inserting the operation into the
// aggregator queue since it can become invalid after executing a // aggregator waitlist since it can become invalid after executing a
// handler (if the operation has 'short' life time.) // handler (if the operation has 'short' life time.)
const uintptr_t status = op->status; const uintptr_t status = op->status;
@ -76,7 +80,7 @@ public:
call_itt_notify(releasing, &(op->status)); call_itt_notify(releasing, &(op->status));
// insert the operation in the queue. // insert the operation in the queue.
do { do {
// ITT may flag the following line as a race; it is a false positive: // Tools may flag the following line as a race; it is a false positive:
// This is an atomic read; we don't provide itt_hide_load_word for atomics // This is an atomic read; we don't provide itt_hide_load_word for atomics
op->next = res = pending_operations; // NOT A RACE op->next = res = pending_operations; // NOT A RACE
} while (pending_operations.compare_and_swap(op, res) != res); } while (pending_operations.compare_and_swap(op, res) != res);
@ -92,7 +96,7 @@ public:
} }
// not first; wait for op to be ready. // not first; wait for op to be ready.
else if (!status) { // operation is blocking here. else if (!status) { // operation is blocking here.
__TBB_ASSERT(long_life_time, "The blocking operation cannot have 'short' life time. Since it can already be destroyed."); __TBB_ASSERT(long_life_time, "Waiting for an operation object that might be destroyed during processing.");
call_itt_notify(prepare, &(op->status)); call_itt_notify(prepare, &(op->status));
spin_wait_while_eq(op->status, uintptr_t(0)); spin_wait_while_eq(op->status, uintptr_t(0));
itt_load_word_with_acquire(op->status); itt_load_word_with_acquire(op->status);

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#ifndef __TBB__concurrent_queue_impl_H #ifndef __TBB__concurrent_queue_impl_H
@ -33,7 +33,7 @@
#include "../tbb_exception.h" #include "../tbb_exception.h"
#include "../tbb_profiling.h" #include "../tbb_profiling.h"
#include <new> #include <new>
#include <utility> #include __TBB_STD_SWAP_HEADER
#if !TBB_USE_EXCEPTIONS && _MSC_VER #if !TBB_USE_EXCEPTIONS && _MSC_VER
// Suppress "C++ exception handler used, but unwind semantics are not enabled" warning in STL headers // Suppress "C++ exception handler used, but unwind semantics are not enabled" warning in STL headers
@ -281,15 +281,15 @@ bool micro_queue<T>::pop( void* dst, ticket k, concurrent_queue_base_v3<T>& base
call_itt_notify(acquired, &head_counter); call_itt_notify(acquired, &head_counter);
if( tail_counter==k ) spin_wait_while_eq( tail_counter, k ); if( tail_counter==k ) spin_wait_while_eq( tail_counter, k );
call_itt_notify(acquired, &tail_counter); call_itt_notify(acquired, &tail_counter);
page& p = *head_page; page *p = head_page;
__TBB_ASSERT( &p, NULL ); __TBB_ASSERT( p, NULL );
size_t index = modulo_power_of_two( k/concurrent_queue_rep_base::n_queue, base.my_rep->items_per_page ); size_t index = modulo_power_of_two( k/concurrent_queue_rep_base::n_queue, base.my_rep->items_per_page );
bool success = false; bool success = false;
{ {
micro_queue_pop_finalizer<T> finalizer( *this, base, k+concurrent_queue_rep_base::n_queue, index==base.my_rep->items_per_page-1 ? &p : NULL ); micro_queue_pop_finalizer<T> finalizer( *this, base, k+concurrent_queue_rep_base::n_queue, index==base.my_rep->items_per_page-1 ? p : NULL );
if( p.mask & uintptr_t(1)<<index ) { if( p->mask & uintptr_t(1)<<index ) {
success = true; success = true;
assign_and_destroy_item( dst, p, index ); assign_and_destroy_item( dst, *p, index );
} else { } else {
--base.my_rep->n_invalid_entries; --base.my_rep->n_invalid_entries;
} }
@ -450,13 +450,13 @@ private:
typedef typename micro_queue<T>::padded_page padded_page; typedef typename micro_queue<T>::padded_page padded_page;
typedef typename micro_queue<T>::item_constructor_t item_constructor_t; typedef typename micro_queue<T>::item_constructor_t item_constructor_t;
/* override */ virtual page *allocate_page() { virtual page *allocate_page() __TBB_override {
concurrent_queue_rep<T>& r = *my_rep; concurrent_queue_rep<T>& r = *my_rep;
size_t n = sizeof(padded_page) + (r.items_per_page-1)*sizeof(T); size_t n = sizeof(padded_page) + (r.items_per_page-1)*sizeof(T);
return reinterpret_cast<page*>(allocate_block ( n )); return reinterpret_cast<page*>(allocate_block ( n ));
} }
/* override */ virtual void deallocate_page( concurrent_queue_rep_base::page *p ) { virtual void deallocate_page( concurrent_queue_rep_base::page *p ) __TBB_override {
concurrent_queue_rep<T>& r = *my_rep; concurrent_queue_rep<T>& r = *my_rep;
size_t n = sizeof(padded_page) + (r.items_per_page-1)*sizeof(T); size_t n = sizeof(padded_page) + (r.items_per_page-1)*sizeof(T);
deallocate_block( reinterpret_cast<void*>(p), n ); deallocate_block( reinterpret_cast<void*>(p), n );
@ -471,7 +471,7 @@ private:
protected: protected:
concurrent_queue_base_v3(); concurrent_queue_base_v3();
/* override */ virtual ~concurrent_queue_base_v3() { virtual ~concurrent_queue_base_v3() {
#if TBB_USE_ASSERT #if TBB_USE_ASSERT
size_t nq = my_rep->n_queue; size_t nq = my_rep->n_queue;
for( size_t i=0; i<nq; i++ ) for( size_t i=0; i<nq; i++ )
@ -764,7 +764,7 @@ class concurrent_queue_iterator: public concurrent_queue_iterator_base_v3<typena
public: public:
#endif #endif
//! Construct iterator pointing to head of queue. //! Construct iterator pointing to head of queue.
concurrent_queue_iterator( const concurrent_queue_base_v3<Value>& queue ) : explicit concurrent_queue_iterator( const concurrent_queue_base_v3<typename tbb_remove_cv<Value>::type>& queue ) :
concurrent_queue_iterator_base_v3<typename tbb_remove_cv<Value>::type>(queue) concurrent_queue_iterator_base_v3<typename tbb_remove_cv<Value>::type>(queue)
{ {
} }
@ -772,6 +772,8 @@ public:
public: public:
concurrent_queue_iterator() {} concurrent_queue_iterator() {}
/** If Value==Container::value_type, then this routine is the copy constructor.
If Value==const Container::value_type, then this routine is a conversion constructor. */
concurrent_queue_iterator( const concurrent_queue_iterator<Container,typename Container::value_type>& other ) : concurrent_queue_iterator( const concurrent_queue_iterator<Container,typename Container::value_type>& other ) :
concurrent_queue_iterator_base_v3<typename tbb_remove_cv<Value>::type>(other) concurrent_queue_iterator_base_v3<typename tbb_remove_cv<Value>::type>(other)
{} {}
@ -1023,7 +1025,7 @@ public:
#endif #endif
//! Construct iterator pointing to head of queue. //! Construct iterator pointing to head of queue.
concurrent_queue_iterator( const concurrent_queue_base_v3& queue ) : explicit concurrent_queue_iterator( const concurrent_queue_base_v3& queue ) :
concurrent_queue_iterator_base_v3(queue,__TBB_offsetof(concurrent_queue_base_v3::padded_page<Value>,last)) concurrent_queue_iterator_base_v3(queue,__TBB_offsetof(concurrent_queue_base_v3::padded_page<Value>,last))
{ {
} }

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
/* Container implementations in this header are based on PPL implementations /* Container implementations in this header are based on PPL implementations
@ -40,7 +40,7 @@
#include <functional> // Need std::equal_to (in ../concurrent_unordered_*.h) #include <functional> // Need std::equal_to (in ../concurrent_unordered_*.h)
#include <string> // For tbb_hasher #include <string> // For tbb_hasher
#include <cstring> // Need std::memset #include <cstring> // Need std::memset
#include <algorithm> // Need std::swap #include __TBB_STD_SWAP_HEADER
#if !TBB_USE_EXCEPTIONS && _MSC_VER #if !TBB_USE_EXCEPTIONS && _MSC_VER
#pragma warning (pop) #pragma warning (pop)
@ -269,7 +269,8 @@ public:
// Allocate a new node with the given order key and value // Allocate a new node with the given order key and value
template<typename Arg> template<typename Arg>
nodeptr_t create_node(sokey_t order_key, __TBB_FORWARDING_REF(Arg) t){ nodeptr_t create_node(sokey_t order_key, __TBB_FORWARDING_REF(Arg) t,
/*AllowCreate=*/tbb::internal::true_type=tbb::internal::true_type()){
nodeptr_t pnode = my_node_allocator.allocate(1); nodeptr_t pnode = my_node_allocator.allocate(1);
//TODO: use RAII scoped guard instead of explicit catch //TODO: use RAII scoped guard instead of explicit catch
@ -284,6 +285,14 @@ public:
return (pnode); return (pnode);
} }
// A helper to avoid excessive requiremens in internal_insert
template<typename Arg>
nodeptr_t create_node(sokey_t, __TBB_FORWARDING_REF(Arg),
/*AllowCreate=*/tbb::internal::false_type){
__TBB_ASSERT(false, "This compile-time helper should never get called");
return nodeptr_t();
}
// Allocate a new node with the given parameters for constructing value // Allocate a new node with the given parameters for constructing value
template<typename __TBB_PARAMETER_PACK Args> template<typename __TBB_PARAMETER_PACK Args>
nodeptr_t create_node_v( __TBB_FORWARDING_REF(Args) __TBB_PARAMETER_PACK args){ nodeptr_t create_node_v( __TBB_FORWARDING_REF(Args) __TBB_PARAMETER_PACK args){
@ -659,7 +668,6 @@ protected:
typedef typename Traits::value_type value_type; typedef typename Traits::value_type value_type;
typedef typename Traits::key_type key_type; typedef typename Traits::key_type key_type;
typedef typename Traits::hash_compare hash_compare; typedef typename Traits::hash_compare hash_compare;
typedef typename Traits::value_compare value_compare;
typedef typename Traits::allocator_type allocator_type; typedef typename Traits::allocator_type allocator_type;
typedef typename hash_compare::hasher hasher; typedef typename hash_compare::hasher hasher;
typedef typename hash_compare::key_equal key_equal; typedef typename hash_compare::key_equal key_equal;
@ -708,7 +716,7 @@ protected:
my_allocator(a), my_maximum_bucket_size((float) initial_bucket_load) my_allocator(a), my_maximum_bucket_size((float) initial_bucket_load)
{ {
if( n_of_buckets == 0) ++n_of_buckets; if( n_of_buckets == 0) ++n_of_buckets;
my_number_of_buckets = 1<<__TBB_Log2((uintptr_t)n_of_buckets*2-1); // round up to power of 2 my_number_of_buckets = size_type(1)<<__TBB_Log2((uintptr_t)n_of_buckets*2-1); // round up to power of 2
internal_init(); internal_init();
} }
@ -958,7 +966,7 @@ public:
// Modifiers // Modifiers
std::pair<iterator, bool> insert(const value_type& value) { std::pair<iterator, bool> insert(const value_type& value) {
return internal_insert(value); return internal_insert</*AllowCreate=*/tbb::internal::true_type>(value);
} }
iterator insert(const_iterator, const value_type& value) { iterator insert(const_iterator, const value_type& value) {
@ -968,7 +976,7 @@ public:
#if __TBB_CPP11_RVALUE_REF_PRESENT #if __TBB_CPP11_RVALUE_REF_PRESENT
std::pair<iterator, bool> insert(value_type&& value) { std::pair<iterator, bool> insert(value_type&& value) {
return internal_insert(std::move(value)); return internal_insert</*AllowCreate=*/tbb::internal::true_type>(std::move(value));
} }
iterator insert(const_iterator, value_type&& value) { iterator insert(const_iterator, value_type&& value) {
@ -984,7 +992,7 @@ public:
const sokey_t order_key = split_order_key_regular(hashed_element_key); const sokey_t order_key = split_order_key_regular(hashed_element_key);
pnode->init(order_key); pnode->init(order_key);
return internal_insert(pnode->my_element, pnode); return internal_insert</*AllowCreate=*/tbb::internal::false_type>(pnode->my_element, pnode);
} }
template<typename... Args> template<typename... Args>
@ -1194,7 +1202,7 @@ public:
size_type current_buckets = my_number_of_buckets; size_type current_buckets = my_number_of_buckets;
if (current_buckets >= buckets) if (current_buckets >= buckets)
return; return;
my_number_of_buckets = 1<<__TBB_Log2((uintptr_t)buckets*2-1); // round up to power of 2 my_number_of_buckets = size_type(1)<<__TBB_Log2((uintptr_t)buckets*2-1); // round up to power of 2
} }
private: private:
@ -1260,40 +1268,34 @@ private:
} }
// Insert an element in the hash given its value // Insert an element in the hash given its value
template< typename ValueType> template<typename AllowCreate, typename ValueType>
std::pair<iterator, bool> internal_insert( __TBB_FORWARDING_REF(ValueType) value, nodeptr_t pnode = NULL) std::pair<iterator, bool> internal_insert(__TBB_FORWARDING_REF(ValueType) value, nodeptr_t pnode = NULL)
{ {
sokey_t order_key = (sokey_t) my_hash_compare(get_key(value)); const key_type *pkey = &get_key(value);
size_type bucket = order_key % my_number_of_buckets; sokey_t hash_key = (sokey_t) my_hash_compare(*pkey);
//TODO:refactor the get_bucket related stuff into separate function something like acquire_bucket(key_type)
// If bucket is empty, initialize it first
if (!is_initialized(bucket))
init_bucket(bucket);
size_type new_count = 0; size_type new_count = 0;
order_key = split_order_key_regular(order_key); sokey_t order_key = split_order_key_regular(hash_key);
raw_iterator it = get_bucket(bucket); raw_iterator previous = prepare_bucket(hash_key);
raw_iterator last = my_solist.raw_end(); raw_iterator last = my_solist.raw_end();
raw_iterator where = it; __TBB_ASSERT(previous != last, "Invalid head node");
__TBB_ASSERT(where != last, "Invalid head node");
// First node is a dummy node // First node is a dummy node
++where; for (raw_iterator where = previous;;)
for (;;)
{ {
++where;
if (where == last || solist_t::get_order_key(where) > order_key || if (where == last || solist_t::get_order_key(where) > order_key ||
// if multimapped, stop at the first item equal to us. // if multimapped, stop at the first item equal to us.
(allow_multimapping && solist_t::get_order_key(where) == order_key && (allow_multimapping && solist_t::get_order_key(where) == order_key &&
!my_hash_compare(get_key(*where), get_key(value)))) !my_hash_compare(get_key(*where), *pkey))) // TODO: fix negation
{ {
if (!pnode) if (!pnode) {
pnode = my_solist.create_node(order_key, tbb::internal::forward<ValueType>(value)); pnode = my_solist.create_node(order_key, tbb::internal::forward<ValueType>(value), AllowCreate());
// If the value was moved, the known reference to key might be invalid
pkey = &get_key(pnode->my_element);
}
// Try to insert 'pnode' between 'it' and 'where' // Try to insert 'pnode' between 'previous' and 'where'
std::pair<iterator, bool> result = my_solist.try_insert(it, where, pnode, &new_count); std::pair<iterator, bool> result = my_solist.try_insert(previous, where, pnode, &new_count);
if (result.second) if (result.second)
{ {
@ -1308,38 +1310,30 @@ private:
// Proceed with the search from the previous location where order key was // Proceed with the search from the previous location where order key was
// known to be larger (note: this is legal only because there is no safe // known to be larger (note: this is legal only because there is no safe
// concurrent erase operation supported). // concurrent erase operation supported).
where = it; where = previous;
++where;
continue; continue;
} }
} }
else if (!allow_multimapping && solist_t::get_order_key(where) == order_key && else if (!allow_multimapping && solist_t::get_order_key(where) == order_key &&
my_hash_compare(get_key(*where), get_key(value)) == 0) !my_hash_compare(get_key(*where), *pkey)) // TODO: fix negation
{ // Element already in the list, return it { // Element already in the list, return it
if (pnode) if (pnode)
my_solist.destroy_node(pnode); my_solist.destroy_node(pnode);
return std::pair<iterator, bool>(my_solist.get_iterator(where), false); return std::pair<iterator, bool>(my_solist.get_iterator(where), false);
} }
// Move the iterator forward // Move the iterator forward
it = where; previous = where;
++where;
} }
} }
// Find the element in the split-ordered list // Find the element in the split-ordered list
iterator internal_find(const key_type& key) iterator internal_find(const key_type& key)
{ {
sokey_t order_key = (sokey_t) my_hash_compare(key); sokey_t hash_key = (sokey_t) my_hash_compare(key);
size_type bucket = order_key % my_number_of_buckets; sokey_t order_key = split_order_key_regular(hash_key);
// If bucket is empty, initialize it first
if (!is_initialized(bucket))
init_bucket(bucket);
order_key = split_order_key_regular(order_key);
raw_iterator last = my_solist.raw_end(); raw_iterator last = my_solist.raw_end();
for (raw_iterator it = get_bucket(bucket); it != last; ++it) for (raw_iterator it = prepare_bucket(hash_key); it != last; ++it)
{ {
if (solist_t::get_order_key(it) > order_key) if (solist_t::get_order_key(it) > order_key)
{ {
@ -1352,7 +1346,7 @@ private:
// The fact that order keys match does not mean that the element is found. // The fact that order keys match does not mean that the element is found.
// Key function comparison has to be performed to check whether this is the // Key function comparison has to be performed to check whether this is the
// right element. If not, keep searching while order key is the same. // right element. If not, keep searching while order key is the same.
if (!my_hash_compare(get_key(*it), key)) if (!my_hash_compare(get_key(*it), key)) // TODO: fix negation
return my_solist.get_iterator(it); return my_solist.get_iterator(it);
} }
} }
@ -1363,35 +1357,18 @@ private:
// Erase an element from the list. This is not a concurrency safe function. // Erase an element from the list. This is not a concurrency safe function.
iterator internal_erase(const_iterator it) iterator internal_erase(const_iterator it)
{ {
//const reference extends lifetime of possible temporary coming from get_key sokey_t hash_key = (sokey_t) my_hash_compare(get_key(*it));
const key_type& key = get_key(*it); raw_iterator previous = prepare_bucket(hash_key);
sokey_t order_key = (sokey_t) my_hash_compare(key);
size_type bucket = order_key % my_number_of_buckets;
// If bucket is empty, initialize it first
if (!is_initialized(bucket))
init_bucket(bucket);
order_key = split_order_key_regular(order_key);
raw_iterator previous = get_bucket(bucket);
raw_iterator last = my_solist.raw_end(); raw_iterator last = my_solist.raw_end();
raw_iterator where = previous; __TBB_ASSERT(previous != last, "Invalid head node");
__TBB_ASSERT(where != last, "Invalid head node");
// First node is a dummy node // First node is a dummy node
for (raw_iterator where = previous; ; previous = where) {
++where; ++where;
for (;;) {
if (where == last) if (where == last)
return end(); return end();
else if (my_solist.get_iterator(where) == it) else if (my_solist.get_iterator(where) == it)
return my_solist.erase_node(previous, it); return my_solist.erase_node(previous, it);
// Move the iterator forward
previous = where;
++where;
} }
} }
@ -1399,24 +1376,19 @@ private:
// This operation makes sense only if mapping is many-to-one. // This operation makes sense only if mapping is many-to-one.
pairii_t internal_equal_range(const key_type& key) pairii_t internal_equal_range(const key_type& key)
{ {
sokey_t order_key = (sokey_t) my_hash_compare(key); sokey_t hash_key = (sokey_t) my_hash_compare(key);
size_type bucket = order_key % my_number_of_buckets; sokey_t order_key = split_order_key_regular(hash_key);
// If bucket is empty, initialize it first
if (!is_initialized(bucket))
init_bucket(bucket);
order_key = split_order_key_regular(order_key);
raw_iterator end_it = my_solist.raw_end(); raw_iterator end_it = my_solist.raw_end();
for (raw_iterator it = get_bucket(bucket); it != end_it; ++it) for (raw_iterator it = prepare_bucket(hash_key); it != end_it; ++it)
{ {
if (solist_t::get_order_key(it) > order_key) if (solist_t::get_order_key(it) > order_key)
{ {
// There is no element with the given key // There is no element with the given key
return pairii_t(end(), end()); return pairii_t(end(), end());
} }
else if (solist_t::get_order_key(it) == order_key && !my_hash_compare(get_key(*it), key)) else if (solist_t::get_order_key(it) == order_key &&
!my_hash_compare(get_key(*it), key)) // TODO: fix negation; also below
{ {
iterator first = my_solist.get_iterator(it); iterator first = my_solist.get_iterator(it);
iterator last = first; iterator last = first;
@ -1490,6 +1462,15 @@ private:
return my_buckets[segment][bucket]; return my_buckets[segment][bucket];
} }
raw_iterator prepare_bucket(sokey_t hash_key) {
size_type bucket = hash_key % my_number_of_buckets;
size_type segment = segment_index_of(bucket);
size_type index = bucket - segment_base(segment);
if (my_buckets[segment] == NULL || my_buckets[segment][index].get_node_ptr() == NULL)
init_bucket(bucket);
return my_buckets[segment][index];
}
void set_bucket(size_type bucket, raw_iterator dummy_head) { void set_bucket(size_type bucket, raw_iterator dummy_head) {
size_type segment = segment_index_of(bucket); size_type segment = segment_index_of(bucket);
bucket -= segment_base(segment); bucket -= segment_base(segment);

View file

@ -0,0 +1,221 @@
/*
Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#ifndef __TBB__flow_graph_async_msg_impl_H
#define __TBB__flow_graph_async_msg_impl_H
#ifndef __TBB_flow_graph_H
#error Do not #include this internal file directly; use public TBB headers instead.
#endif
// included in namespace tbb::flow::interfaceX (in flow_graph.h)
template< typename T > class async_msg;
namespace internal {
template< typename T, typename = void >
struct async_helpers {
typedef async_msg<T> async_type;
typedef T filtered_type;
static const bool is_async_type = false;
static const void* to_void_ptr(const T& t) {
return static_cast<const void*>(&t);
}
static void* to_void_ptr(T& t) {
return static_cast<void*>(&t);
}
static const T& from_void_ptr(const void* p) {
return *static_cast<const T*>(p);
}
static T& from_void_ptr(void* p) {
return *static_cast<T*>(p);
}
static task* try_put_task_wrapper_impl( receiver<T>* const this_recv, const void *p, bool is_async ) {
if ( is_async ) {
// This (T) is NOT async and incoming 'A<X> t' IS async
// Get data from async_msg
const async_msg<filtered_type>& msg = async_helpers< async_msg<filtered_type> >::from_void_ptr(p);
task* const new_task = msg.my_storage->subscribe(*this_recv);
// finalize() must be called after subscribe() because set() can be called in finalize()
// and 'this_recv' client must be subscribed by this moment
msg.finalize();
return new_task;
} else {
// Incoming 't' is NOT async
return this_recv->try_put_task( from_void_ptr(p) );
}
}
};
template< typename T >
struct async_helpers< T, typename std::enable_if< std::is_base_of<async_msg<typename T::async_msg_data_type>, T>::value >::type > {
typedef T async_type;
typedef typename T::async_msg_data_type filtered_type;
static const bool is_async_type = true;
// Receiver-classes use const interfaces
static const void* to_void_ptr(const T& t) {
return static_cast<const void*>( &static_cast<const async_msg<filtered_type>&>(t) );
}
static void* to_void_ptr(T& t) {
return static_cast<void*>( &static_cast<async_msg<filtered_type>&>(t) );
}
// Sender-classes use non-const interfaces
static const T& from_void_ptr(const void* p) {
return *static_cast<const T*>( static_cast<const async_msg<filtered_type>*>(p) );
}
static T& from_void_ptr(void* p) {
return *static_cast<T*>( static_cast<async_msg<filtered_type>*>(p) );
}
// Used in receiver<T> class
static task* try_put_task_wrapper_impl(receiver<T>* const this_recv, const void *p, bool is_async) {
if ( is_async ) {
// Both are async
return this_recv->try_put_task( from_void_ptr(p) );
} else {
// This (T) is async and incoming 'X t' is NOT async
// Create async_msg for X
const filtered_type& t = async_helpers<filtered_type>::from_void_ptr(p);
const T msg(t);
return this_recv->try_put_task(msg);
}
}
};
template <typename T>
class async_storage {
public:
typedef receiver<T> async_storage_client;
async_storage() { my_data_ready.store<tbb::relaxed>(false); }
template<typename C>
async_storage(C&& data) : my_data( std::forward<C>(data) ) {
using namespace tbb::internal;
__TBB_STATIC_ASSERT( (is_same_type<typename strip<C>::type, typename strip<T>::type>::value), "incoming type must be T" );
my_data_ready.store<tbb::relaxed>(true);
}
template<typename C>
bool set(C&& data) {
using namespace tbb::internal;
__TBB_STATIC_ASSERT( (is_same_type<typename strip<C>::type, typename strip<T>::type>::value), "incoming type must be T" );
{
tbb::spin_mutex::scoped_lock locker(my_mutex);
if (my_data_ready.load<tbb::relaxed>()) {
__TBB_ASSERT(false, "double set() call");
return false;
}
my_data = std::forward<C>(data);
my_data_ready.store<tbb::release>(true);
}
// Thread sync is on my_data_ready flag
for (typename subscriber_list_type::iterator it = my_clients.begin(); it != my_clients.end(); ++it) {
(*it)->try_put(my_data);
}
return true;
}
task* subscribe(async_storage_client& client) {
if (! my_data_ready.load<tbb::acquire>())
{
tbb::spin_mutex::scoped_lock locker(my_mutex);
if (! my_data_ready.load<tbb::relaxed>()) {
#if TBB_USE_ASSERT
for (typename subscriber_list_type::iterator it = my_clients.begin(); it != my_clients.end(); ++it) {
__TBB_ASSERT(*it != &client, "unexpected double subscription");
}
#endif // TBB_USE_ASSERT
// Subscribe
my_clients.push_back(&client);
return SUCCESSFULLY_ENQUEUED;
}
}
__TBB_ASSERT(my_data_ready.load<tbb::relaxed>(), "data is NOT ready");
return client.try_put_task(my_data);
}
private:
tbb::spin_mutex my_mutex;
tbb::atomic<bool> my_data_ready;
T my_data;
typedef std::vector<async_storage_client*> subscriber_list_type;
subscriber_list_type my_clients;
};
} // namespace internal
template <typename T>
class async_msg {
template< typename > friend class receiver;
template< typename, typename > friend struct internal::async_helpers;
public:
typedef T async_msg_data_type;
async_msg() : my_storage(std::make_shared< internal::async_storage<T> >()) {}
async_msg(const T& t) : my_storage(std::make_shared< internal::async_storage<T> >(t)) {}
async_msg(T&& t) : my_storage(std::make_shared< internal::async_storage<T> >( std::move(t) )) {}
virtual ~async_msg() {}
void set(const T& t) {
my_storage->set(t);
}
void set(T&& t) {
my_storage->set( std::move(t) );
}
protected:
// Can be overridden in derived class to inform that
// async calculation chain is over
virtual void finalize() const {}
private:
typedef std::shared_ptr< internal::async_storage<T> > async_storage_ptr;
async_storage_ptr my_storage;
};
#endif // __TBB__flow_graph_async_msg_impl_H

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#ifndef __TBB__flow_graph_impl_H #ifndef __TBB__flow_graph_impl_H
@ -69,8 +69,8 @@ namespace internal {
class source_body_leaf : public source_body<Output> { class source_body_leaf : public source_body<Output> {
public: public:
source_body_leaf( const Body &_body ) : body(_body) { } source_body_leaf( const Body &_body ) : body(_body) { }
/*override*/ bool operator()(Output &output) { return body( output ); } bool operator()(Output &output) __TBB_override { return body( output ); }
/*override*/ source_body_leaf* clone() { source_body_leaf* clone() __TBB_override {
return new source_body_leaf< Output, Body >(body); return new source_body_leaf< Output, Body >(body);
} }
Body get_body() { return body; } Body get_body() { return body; }
@ -92,9 +92,9 @@ namespace internal {
class function_body_leaf : public function_body< Input, Output > { class function_body_leaf : public function_body< Input, Output > {
public: public:
function_body_leaf( const B &_body ) : body(_body) { } function_body_leaf( const B &_body ) : body(_body) { }
Output operator()(const Input &i) { return body(i); } Output operator()(const Input &i) __TBB_override { return body(i); }
B get_body() { return body; } B get_body() { return body; }
/*override*/ function_body_leaf* clone() { function_body_leaf* clone() __TBB_override {
return new function_body_leaf< Input, Output, B >(body); return new function_body_leaf< Input, Output, B >(body);
} }
private: private:
@ -106,12 +106,12 @@ namespace internal {
class function_body_leaf< continue_msg, continue_msg, B> : public function_body< continue_msg, continue_msg > { class function_body_leaf< continue_msg, continue_msg, B> : public function_body< continue_msg, continue_msg > {
public: public:
function_body_leaf( const B &_body ) : body(_body) { } function_body_leaf( const B &_body ) : body(_body) { }
continue_msg operator()( const continue_msg &i ) { continue_msg operator()( const continue_msg &i ) __TBB_override {
body(i); body(i);
return i; return i;
} }
B get_body() { return body; } B get_body() { return body; }
/*override*/ function_body_leaf* clone() { function_body_leaf* clone() __TBB_override {
return new function_body_leaf< continue_msg, continue_msg, B >(body); return new function_body_leaf< continue_msg, continue_msg, B >(body);
} }
private: private:
@ -123,12 +123,12 @@ namespace internal {
class function_body_leaf< Input, continue_msg, B> : public function_body< Input, continue_msg > { class function_body_leaf< Input, continue_msg, B> : public function_body< Input, continue_msg > {
public: public:
function_body_leaf( const B &_body ) : body(_body) { } function_body_leaf( const B &_body ) : body(_body) { }
continue_msg operator()(const Input &i) { continue_msg operator()(const Input &i) __TBB_override {
body(i); body(i);
return continue_msg(); return continue_msg();
} }
B get_body() { return body; } B get_body() { return body; }
/*override*/ function_body_leaf* clone() { function_body_leaf* clone() __TBB_override {
return new function_body_leaf< Input, continue_msg, B >(body); return new function_body_leaf< Input, continue_msg, B >(body);
} }
private: private:
@ -140,26 +140,17 @@ namespace internal {
class function_body_leaf< continue_msg, Output, B > : public function_body< continue_msg, Output > { class function_body_leaf< continue_msg, Output, B > : public function_body< continue_msg, Output > {
public: public:
function_body_leaf( const B &_body ) : body(_body) { } function_body_leaf( const B &_body ) : body(_body) { }
Output operator()(const continue_msg &i) { Output operator()(const continue_msg &i) __TBB_override {
return body(i); return body(i);
} }
B get_body() { return body; } B get_body() { return body; }
/*override*/ function_body_leaf* clone() { function_body_leaf* clone() __TBB_override {
return new function_body_leaf< continue_msg, Output, B >(body); return new function_body_leaf< continue_msg, Output, B >(body);
} }
private: private:
B body; B body;
}; };
#if __TBB_PREVIEW_ASYNC_NODE
template< typename T, typename = typename T::async_gateway_type >
void set_async_gateway(T *body, void *g) {
body->set_async_gateway(static_cast<typename T::async_gateway_type *>(g));
}
inline void set_async_gateway(...) { }
#endif
//! function_body that takes an Input and a set of output ports //! function_body that takes an Input and a set of output ports
template<typename Input, typename OutputSet> template<typename Input, typename OutputSet>
class multifunction_body : tbb::internal::no_assign { class multifunction_body : tbb::internal::no_assign {
@ -167,9 +158,7 @@ inline void set_async_gateway(...) { }
virtual ~multifunction_body () {} virtual ~multifunction_body () {}
virtual void operator()(const Input &/* input*/, OutputSet &/*oset*/) = 0; virtual void operator()(const Input &/* input*/, OutputSet &/*oset*/) = 0;
virtual multifunction_body* clone() = 0; virtual multifunction_body* clone() = 0;
#if __TBB_PREVIEW_ASYNC_NODE virtual void* get_body_ptr() = 0;
virtual void set_gateway(void *gateway) = 0;
#endif
}; };
//! leaf for multifunction. OutputSet can be a std::tuple or a vector. //! leaf for multifunction. OutputSet can be a std::tuple or a vector.
@ -177,17 +166,11 @@ inline void set_async_gateway(...) { }
class multifunction_body_leaf : public multifunction_body<Input, OutputSet> { class multifunction_body_leaf : public multifunction_body<Input, OutputSet> {
public: public:
multifunction_body_leaf(const B &_body) : body(_body) { } multifunction_body_leaf(const B &_body) : body(_body) { }
void operator()(const Input &input, OutputSet &oset) { void operator()(const Input &input, OutputSet &oset) __TBB_override {
body(input, oset); // body may explicitly put() to one or more of oset. body(input, oset); // body may explicitly put() to one or more of oset.
} }
B get_body() { return body; } void* get_body_ptr() __TBB_override { return &body; }
multifunction_body_leaf* clone() __TBB_override {
#if __TBB_PREVIEW_ASYNC_NODE
/*override*/ void set_gateway(void *gateway) {
set_async_gateway(&body, gateway);
}
#endif
/*override*/ multifunction_body_leaf* clone() {
return new multifunction_body_leaf<Input, OutputSet,B>(body); return new multifunction_body_leaf<Input, OutputSet,B>(body);
} }
@ -218,9 +201,9 @@ template <typename Input, typename Output, typename B>
class type_to_key_function_body_leaf : public type_to_key_function_body<Input, Output> { class type_to_key_function_body_leaf : public type_to_key_function_body<Input, Output> {
public: public:
type_to_key_function_body_leaf( const B &_body ) : body(_body) { } type_to_key_function_body_leaf( const B &_body ) : body(_body) { }
/*override*/Output operator()(const Input &i) { return body(i); } Output operator()(const Input &i) __TBB_override { return body(i); }
B get_body() { return body; } B get_body() { return body; }
/*override*/ type_to_key_function_body_leaf* clone() { type_to_key_function_body_leaf* clone() __TBB_override {
return new type_to_key_function_body_leaf< Input, Output, B>(body); return new type_to_key_function_body_leaf< Input, Output, B>(body);
} }
private: private:
@ -231,17 +214,13 @@ template <typename Input, typename Output, typename B>
class type_to_key_function_body_leaf<Input,Output&,B> : public type_to_key_function_body< Input, Output&> { class type_to_key_function_body_leaf<Input,Output&,B> : public type_to_key_function_body< Input, Output&> {
public: public:
type_to_key_function_body_leaf( const B &_body ) : body(_body) { } type_to_key_function_body_leaf( const B &_body ) : body(_body) { }
const Output& operator()(const Input &i) __TBB_override {
/*override*/const Output& operator()(const Input &i) {
return body(i); return body(i);
} }
B get_body() { return body; } B get_body() { return body; }
type_to_key_function_body_leaf* clone() __TBB_override {
/*override*/ type_to_key_function_body_leaf* clone() {
return new type_to_key_function_body_leaf< Input, Output&, B>(body); return new type_to_key_function_body_leaf< Input, Output&, B>(body);
} }
private: private:
B body; B body;
}; };
@ -260,7 +239,7 @@ private:
forward_task_bypass( NodeType &n ) : my_node(n) {} forward_task_bypass( NodeType &n ) : my_node(n) {}
task *execute() { task *execute() __TBB_override {
task * new_task = my_node.forward_task(); task * new_task = my_node.forward_task();
if (new_task == SUCCESSFULLY_ENQUEUED) new_task = NULL; if (new_task == SUCCESSFULLY_ENQUEUED) new_task = NULL;
return new_task; return new_task;
@ -279,7 +258,7 @@ private:
apply_body_task_bypass( NodeType &n, const Input &i ) : my_node(n), my_input(i) {} apply_body_task_bypass( NodeType &n, const Input &i ) : my_node(n), my_input(i) {}
task *execute() { task *execute() __TBB_override {
task * next_task = my_node.apply_body_bypass( my_input ); task * next_task = my_node.apply_body_bypass( my_input );
if(next_task == SUCCESSFULLY_ENQUEUED) next_task = NULL; if(next_task == SUCCESSFULLY_ENQUEUED) next_task = NULL;
return next_task; return next_task;
@ -296,7 +275,7 @@ private:
source_task_bypass( NodeType &n ) : my_node(n) {} source_task_bypass( NodeType &n ) : my_node(n) {}
task *execute() { task *execute() __TBB_override {
task *new_task = my_node.apply_body_bypass( ); task *new_task = my_node.apply_body_bypass( );
if(new_task == SUCCESSFULLY_ENQUEUED) return NULL; if(new_task == SUCCESSFULLY_ENQUEUED) return NULL;
return new_task; return new_task;
@ -405,12 +384,22 @@ private:
//! A cache of predecessors that only supports try_get //! A cache of predecessors that only supports try_get
template< typename T, typename M=spin_mutex > template< typename T, typename M=spin_mutex >
#if __TBB_PREVIEW_ASYNC_MSG
// TODO: make predecessor_cache type T-independent when async_msg becomes regular feature
class predecessor_cache : public node_cache< untyped_sender, M > {
#else
class predecessor_cache : public node_cache< sender<T>, M > { class predecessor_cache : public node_cache< sender<T>, M > {
#endif // __TBB_PREVIEW_ASYNC_MSG
public: public:
typedef M mutex_type; typedef M mutex_type;
typedef T output_type; typedef T output_type;
#if __TBB_PREVIEW_ASYNC_MSG
typedef untyped_sender predecessor_type;
typedef untyped_receiver successor_type;
#else
typedef sender<output_type> predecessor_type; typedef sender<output_type> predecessor_type;
typedef receiver<output_type> successor_type; typedef receiver<output_type> successor_type;
#endif // __TBB_PREVIEW_ASYNC_MSG
predecessor_cache( ) : my_owner( NULL ) { } predecessor_cache( ) : my_owner( NULL ) { }
@ -462,19 +451,25 @@ private:
protected: protected:
#if TBB_PREVIEW_FLOW_GRAPH_FEATURES #if TBB_PREVIEW_FLOW_GRAPH_FEATURES
using node_cache< sender<T>, M >::my_built_predecessors; using node_cache< predecessor_type, M >::my_built_predecessors;
#endif #endif
successor_type *my_owner; successor_type *my_owner;
}; };
//! An cache of predecessors that supports requests and reservations //! An cache of predecessors that supports requests and reservations
// TODO: make reservable_predecessor_cache type T-independent when async_msg becomes regular feature
template< typename T, typename M=spin_mutex > template< typename T, typename M=spin_mutex >
class reservable_predecessor_cache : public predecessor_cache< T, M > { class reservable_predecessor_cache : public predecessor_cache< T, M > {
public: public:
typedef M mutex_type; typedef M mutex_type;
typedef T output_type; typedef T output_type;
#if __TBB_PREVIEW_ASYNC_MSG
typedef untyped_sender predecessor_type;
typedef untyped_receiver successor_type;
#else
typedef sender<T> predecessor_type; typedef sender<T> predecessor_type;
typedef receiver<T> successor_type; typedef receiver<T> successor_type;
#endif // __TBB_PREVIEW_ASYNC_MSG
reservable_predecessor_cache( ) : reserved_src(NULL) { } reservable_predecessor_cache( ) : reserved_src(NULL) { }
@ -538,6 +533,7 @@ private:
//! An abstract cache of successors //! An abstract cache of successors
// TODO: make successor_cache type T-independent when async_msg becomes regular feature
template<typename T, typename M=spin_rw_mutex > template<typename T, typename M=spin_rw_mutex >
class successor_cache : tbb::internal::no_copy { class successor_cache : tbb::internal::no_copy {
protected: protected:
@ -545,15 +541,22 @@ private:
typedef M mutex_type; typedef M mutex_type;
mutex_type my_mutex; mutex_type my_mutex;
#if __TBB_PREVIEW_ASYNC_MSG
typedef untyped_receiver successor_type;
typedef untyped_receiver *pointer_type;
typedef untyped_sender owner_type;
#else
typedef receiver<T> successor_type; typedef receiver<T> successor_type;
typedef receiver<T> *pointer_type; typedef receiver<T> *pointer_type;
typedef sender<T> owner_type;
#endif // __TBB_PREVIEW_ASYNC_MSG
typedef std::list< pointer_type > successors_type; typedef std::list< pointer_type > successors_type;
#if TBB_PREVIEW_FLOW_GRAPH_FEATURES #if TBB_PREVIEW_FLOW_GRAPH_FEATURES
edge_container<successor_type> my_built_successors; edge_container<successor_type> my_built_successors;
#endif #endif
successors_type my_successors; successors_type my_successors;
sender<T> *my_owner; owner_type *my_owner;
public: public:
#if TBB_PREVIEW_FLOW_GRAPH_FEATURES #if TBB_PREVIEW_FLOW_GRAPH_FEATURES
@ -585,7 +588,7 @@ private:
successor_cache( ) : my_owner(NULL) {} successor_cache( ) : my_owner(NULL) {}
void set_owner( sender<T> *owner ) { my_owner = owner; } void set_owner( owner_type *owner ) { my_owner = owner; }
virtual ~successor_cache() {} virtual ~successor_cache() {}
@ -617,7 +620,9 @@ private:
#endif #endif
} }
#if !__TBB_PREVIEW_ASYNC_MSG
virtual task * try_put_task( const T &t ) = 0; virtual task * try_put_task( const T &t ) = 0;
#endif // __TBB_PREVIEW_ASYNC_MSG
}; // successor_cache<T> }; // successor_cache<T>
//! An abstract cache of successors, specialized to continue_msg //! An abstract cache of successors, specialized to continue_msg
@ -628,8 +633,13 @@ private:
typedef spin_rw_mutex mutex_type; typedef spin_rw_mutex mutex_type;
mutex_type my_mutex; mutex_type my_mutex;
#if __TBB_PREVIEW_ASYNC_MSG
typedef untyped_receiver successor_type;
typedef untyped_receiver *pointer_type;
#else
typedef receiver<continue_msg> successor_type; typedef receiver<continue_msg> successor_type;
typedef receiver<continue_msg> *pointer_type; typedef receiver<continue_msg> *pointer_type;
#endif // __TBB_PREVIEW_ASYNC_MSG
typedef std::list< pointer_type > successors_type; typedef std::list< pointer_type > successors_type;
successors_type my_successors; successors_type my_successors;
#if TBB_PREVIEW_FLOW_GRAPH_FEATURES #if TBB_PREVIEW_FLOW_GRAPH_FEATURES
@ -708,11 +718,14 @@ private:
#endif #endif
} }
#if !__TBB_PREVIEW_ASYNC_MSG
virtual task * try_put_task( const continue_msg &t ) = 0; virtual task * try_put_task( const continue_msg &t ) = 0;
#endif // __TBB_PREVIEW_ASYNC_MSG
}; // successor_cache< continue_msg > }; // successor_cache< continue_msg >
//! A cache of successors that are broadcast to //! A cache of successors that are broadcast to
// TODO: make broadcast_cache type T-independent when async_msg becomes regular feature
template<typename T, typename M=spin_rw_mutex> template<typename T, typename M=spin_rw_mutex>
class broadcast_cache : public successor_cache<T, M> { class broadcast_cache : public successor_cache<T, M> {
typedef M mutex_type; typedef M mutex_type;
@ -723,7 +736,12 @@ private:
broadcast_cache( ) {} broadcast_cache( ) {}
// as above, but call try_put_task instead, and return the last task we received (if any) // as above, but call try_put_task instead, and return the last task we received (if any)
/*override*/ task * try_put_task( const T &t ) { #if __TBB_PREVIEW_ASYNC_MSG
template<typename X>
task * try_put_task( const X &t ) {
#else
task * try_put_task( const T &t ) __TBB_override {
#endif // __TBB_PREVIEW_ASYNC_MSG
task * last_task = NULL; task * last_task = NULL;
bool upgraded = true; bool upgraded = true;
typename mutex_type::scoped_lock l(this->my_mutex, upgraded); typename mutex_type::scoped_lock l(this->my_mutex, upgraded);
@ -752,6 +770,7 @@ private:
}; };
//! A cache of successors that are put in a round-robin fashion //! A cache of successors that are put in a round-robin fashion
// TODO: make round_robin_cache type T-independent when async_msg becomes regular feature
template<typename T, typename M=spin_rw_mutex > template<typename T, typename M=spin_rw_mutex >
class round_robin_cache : public successor_cache<T, M> { class round_robin_cache : public successor_cache<T, M> {
typedef size_t size_type; typedef size_t size_type;
@ -767,7 +786,12 @@ private:
return this->my_successors.size(); return this->my_successors.size();
} }
/*override*/task *try_put_task( const T &t ) { #if __TBB_PREVIEW_ASYNC_MSG
template<typename X>
task * try_put_task( const X &t ) {
#else
task *try_put_task( const T &t ) __TBB_override {
#endif // __TBB_PREVIEW_ASYNC_MSG
bool upgraded = true; bool upgraded = true;
typename mutex_type::scoped_lock l(this->my_mutex, upgraded); typename mutex_type::scoped_lock l(this->my_mutex, upgraded);
typename successors_type::iterator i = this->my_successors.begin(); typename successors_type::iterator i = this->my_successors.begin();
@ -797,7 +821,7 @@ private:
T *my_node; T *my_node;
task *execute() { task *execute() __TBB_override {
return my_node->decrement_counter(); return my_node->decrement_counter();
} }

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#ifndef __TBB__flow_graph_indexer_impl_H #ifndef __TBB__flow_graph_indexer_impl_H
@ -25,7 +25,7 @@
#error Do not #include this internal file directly; use public TBB headers instead. #error Do not #include this internal file directly; use public TBB headers instead.
#endif #endif
#include "tbb/internal/_flow_graph_types_impl.h" #include "_flow_graph_types_impl.h"
namespace internal { namespace internal {
@ -106,43 +106,40 @@ namespace internal {
} }
#if TBB_PREVIEW_FLOW_GRAPH_FEATURES #if TBB_PREVIEW_FLOW_GRAPH_FEATURES
typedef typename receiver<T>::predecessor_list_type predecessor_list_type; typedef typename receiver<T>::predecessor_list_type predecessor_list_type;
typedef typename receiver<T>::predecessor_type predecessor_type;
/*override*/ built_predecessors_type &built_predecessors() { return my_built_predecessors; } built_predecessors_type &built_predecessors() __TBB_override { return my_built_predecessors; }
/*override*/size_t predecessor_count() { size_t predecessor_count() __TBB_override {
spin_mutex::scoped_lock l(my_pred_mutex); spin_mutex::scoped_lock l(my_pred_mutex);
return my_built_predecessors.edge_count(); return my_built_predecessors.edge_count();
} }
/*override*/void internal_add_built_predecessor(sender<T> &p) { void internal_add_built_predecessor(predecessor_type &p) __TBB_override {
spin_mutex::scoped_lock l(my_pred_mutex); spin_mutex::scoped_lock l(my_pred_mutex);
my_built_predecessors.add_edge(p); my_built_predecessors.add_edge(p);
} }
/*override*/void internal_delete_built_predecessor(sender<T> &p) { void internal_delete_built_predecessor(predecessor_type &p) __TBB_override {
spin_mutex::scoped_lock l(my_pred_mutex); spin_mutex::scoped_lock l(my_pred_mutex);
my_built_predecessors.delete_edge(p); my_built_predecessors.delete_edge(p);
} }
/*override*/void copy_predecessors( predecessor_list_type &v) { void copy_predecessors( predecessor_list_type &v) __TBB_override {
spin_mutex::scoped_lock l(my_pred_mutex); spin_mutex::scoped_lock l(my_pred_mutex);
return my_built_predecessors.copy_edges(v); my_built_predecessors.copy_edges(v);
}
/*override*/void clear_predecessors() {
spin_mutex::scoped_lock l(my_pred_mutex);
my_built_predecessors.clear();
} }
#endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */ #endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */
protected: protected:
template< typename R, typename B > friend class run_and_put_task; template< typename R, typename B > friend class run_and_put_task;
template<typename X, typename Y> friend class internal::broadcast_cache; template<typename X, typename Y> friend class internal::broadcast_cache;
template<typename X, typename Y> friend class internal::round_robin_cache; template<typename X, typename Y> friend class internal::round_robin_cache;
task *try_put_task(const T &v) { task *try_put_task(const T &v) __TBB_override {
return my_try_put_task(v, my_indexer_ptr); return my_try_put_task(v, my_indexer_ptr);
} }
public: public:
#if TBB_PREVIEW_FLOW_GRAPH_FEATURES #if TBB_PREVIEW_FLOW_GRAPH_FEATURES
/*override*/void reset_receiver(reset_flags f) { if(f&rf_clear_edges) my_built_predecessors.clear(); } void reset_receiver(reset_flags f) __TBB_override { if(f&rf_clear_edges) my_built_predecessors.clear(); }
#else #else
/*override*/void reset_receiver(reset_flags /*f*/) { } void reset_receiver(reset_flags /*f*/) __TBB_override { }
#endif #endif
#if TBB_PREVIEW_FLOW_GRAPH_FEATURES #if TBB_PREVIEW_FLOW_GRAPH_FEATURES
@ -175,7 +172,7 @@ namespace internal {
static const size_t N = tbb::flow::tuple_size<InputTuple>::value; static const size_t N = tbb::flow::tuple_size<InputTuple>::value;
typedef OutputType output_type; typedef OutputType output_type;
typedef StructTypes tuple_types; typedef StructTypes tuple_types;
typedef receiver<output_type> successor_type; typedef typename sender<output_type>::successor_type successor_type;
typedef indexer_node_FE<InputTuple, output_type,StructTypes> input_ports_type; typedef indexer_node_FE<InputTuple, output_type,StructTypes> input_ports_type;
#if TBB_PREVIEW_FLOW_GRAPH_FEATURES #if TBB_PREVIEW_FLOW_GRAPH_FEATURES
typedef typename sender<output_type>::built_successors_type built_successors_type; typedef typename sender<output_type>::built_successors_type built_successors_type;
@ -190,7 +187,6 @@ namespace internal {
blt_succ_cnt, blt_succ_cpy blt_succ_cnt, blt_succ_cpy
#endif #endif
}; };
enum op_stat {WAIT=0, SUCCEEDED, FAILED};
typedef indexer_node_base<InputTuple,output_type,StructTypes> class_type; typedef indexer_node_base<InputTuple,output_type,StructTypes> class_type;
class indexer_node_base_operation : public aggregated_operation<indexer_node_base_operation> { class indexer_node_base_operation : public aggregated_operation<indexer_node_base_operation> {
@ -272,19 +268,19 @@ namespace internal {
my_aggregator.initialize_handler(handler_type(this)); my_aggregator.initialize_handler(handler_type(this));
} }
bool register_successor(successor_type &r) { bool register_successor(successor_type &r) __TBB_override {
indexer_node_base_operation op_data(r, reg_succ); indexer_node_base_operation op_data(r, reg_succ);
my_aggregator.execute(&op_data); my_aggregator.execute(&op_data);
return op_data.status == SUCCEEDED; return op_data.status == SUCCEEDED;
} }
bool remove_successor( successor_type &r) { bool remove_successor( successor_type &r) __TBB_override {
indexer_node_base_operation op_data(r, rem_succ); indexer_node_base_operation op_data(r, rem_succ);
my_aggregator.execute(&op_data); my_aggregator.execute(&op_data);
return op_data.status == SUCCEEDED; return op_data.status == SUCCEEDED;
} }
task * try_put_task(output_type const *v) { task * try_put_task(output_type const *v) { // not a virtual method in this class
indexer_node_base_operation op_data(v, try__put_task); indexer_node_base_operation op_data(v, try__put_task);
my_aggregator.execute(&op_data); my_aggregator.execute(&op_data);
return op_data.bypass_t; return op_data.bypass_t;
@ -292,36 +288,36 @@ namespace internal {
#if TBB_PREVIEW_FLOW_GRAPH_FEATURES #if TBB_PREVIEW_FLOW_GRAPH_FEATURES
built_successors_type &built_successors() { return my_successors.built_successors(); } built_successors_type &built_successors() __TBB_override { return my_successors.built_successors(); }
void internal_add_built_successor( successor_type &r) { void internal_add_built_successor( successor_type &r) __TBB_override {
indexer_node_base_operation op_data(r, add_blt_succ); indexer_node_base_operation op_data(r, add_blt_succ);
my_aggregator.execute(&op_data); my_aggregator.execute(&op_data);
} }
void internal_delete_built_successor( successor_type &r) { void internal_delete_built_successor( successor_type &r) __TBB_override {
indexer_node_base_operation op_data(r, del_blt_succ); indexer_node_base_operation op_data(r, del_blt_succ);
my_aggregator.execute(&op_data); my_aggregator.execute(&op_data);
} }
size_t successor_count() { size_t successor_count() __TBB_override {
indexer_node_base_operation op_data(blt_succ_cnt); indexer_node_base_operation op_data(blt_succ_cnt);
my_aggregator.execute(&op_data); my_aggregator.execute(&op_data);
return op_data.cnt_val; return op_data.cnt_val;
} }
void copy_successors( successor_list_type &v) { void copy_successors( successor_list_type &v) __TBB_override {
indexer_node_base_operation op_data(blt_succ_cpy); indexer_node_base_operation op_data(blt_succ_cpy);
op_data.succv = &v; op_data.succv = &v;
my_aggregator.execute(&op_data); my_aggregator.execute(&op_data);
} }
void extract() { void extract() __TBB_override {
my_successors.built_successors().sender_extract(*this); my_successors.built_successors().sender_extract(*this);
indexer_helper<StructTypes,N>::extract(this->my_inputs); indexer_helper<StructTypes,N>::extract(this->my_inputs);
} }
#endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */ #endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */
protected: protected:
/*override*/void reset_node(reset_flags f) { void reset_node(reset_flags f) __TBB_override {
if(f & rf_clear_edges) { if(f & rf_clear_edges) {
my_successors.clear(); my_successors.clear();
indexer_helper<StructTypes,N>::reset_inputs(this->my_inputs,f); indexer_helper<StructTypes,N>::reset_inputs(this->my_inputs,f);

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#ifndef __TBB__flow_graph_item_buffer_impl_H #ifndef __TBB__flow_graph_item_buffer_impl_H
@ -56,7 +56,7 @@ namespace internal {
size_type my_head; size_type my_head;
size_type my_tail; size_type my_tail;
bool buffer_empty() { return my_head == my_tail; } bool buffer_empty() const { return my_head == my_tail; }
buffer_item_type &item(size_type i) { buffer_item_type &item(size_type i) {
__TBB_ASSERT(!(size_type(&(my_array[i&(my_array_size-1)].second))%alignment_of<buffer_item_state>::value),NULL); __TBB_ASSERT(!(size_type(&(my_array[i&(my_array_size-1)].second))%alignment_of<buffer_item_state>::value),NULL);
@ -64,11 +64,17 @@ namespace internal {
return my_array[i & (my_array_size - 1) ]; return my_array[i & (my_array_size - 1) ];
} }
bool my_item_valid(size_type i) { return (i < my_tail) && (i >= my_head) && (item(i).second != no_item); } const buffer_item_type &item(size_type i) const {
bool my_item_reserved(size_type i) { return item(i).second == reserved_item; } __TBB_ASSERT(!(size_type(&(my_array[i&(my_array_size-1)].second))%alignment_of<buffer_item_state>::value), NULL);
__TBB_ASSERT(!(size_type(&(my_array[i&(my_array_size-1)].first))%alignment_of<item_type>::value), NULL);
return my_array[i & (my_array_size-1)];
}
bool my_item_valid(size_type i) const { return (i < my_tail) && (i >= my_head) && (item(i).second != no_item); }
bool my_item_reserved(size_type i) const { return item(i).second == reserved_item; }
// object management in buffer // object management in buffer
const item_type &get_my_item(size_t i) { const item_type &get_my_item(size_t i) const {
__TBB_ASSERT(my_item_valid(i),"attempt to get invalid item"); __TBB_ASSERT(my_item_valid(i),"attempt to get invalid item");
item_type *itm = (tbb::internal::punned_cast<item_type *>(&(item(i).first))); item_type *itm = (tbb::internal::punned_cast<item_type *>(&(item(i).first)));
return *(const item_type *)itm; return *(const item_type *)itm;
@ -124,15 +130,18 @@ namespace internal {
item(i).second = no_item; item(i).second = no_item;
} }
// returns a copy of the front // returns the front element
void copy_front(item_type &v) { const item_type& front() const
{
__TBB_ASSERT(my_item_valid(my_head), "attempt to fetch head non-item"); __TBB_ASSERT(my_item_valid(my_head), "attempt to fetch head non-item");
v = get_my_item(my_head); return get_my_item(my_head);
} }
// returns a copy of the back
void copy_back(item_type &v) { // returns the back element
__TBB_ASSERT(my_item_valid(my_tail-1), "attempt to fetch head non-item"); const item_type& back() const
v = get_my_item(my_tail-1); {
__TBB_ASSERT(my_item_valid(my_tail - 1), "attempt to fetch head non-item");
return get_my_item(my_tail - 1);
} }
// following methods are for reservation of the front of a bufffer. // following methods are for reservation of the front of a bufffer.
@ -191,7 +200,7 @@ namespace internal {
if (!my_item_valid(my_tail-1)) { if (!my_item_valid(my_tail-1)) {
return false; return false;
} }
copy_back(v); v = this->back();
destroy_back(); destroy_back();
return true; return true;
} }
@ -200,7 +209,7 @@ namespace internal {
if(!my_item_valid(my_head)) { if(!my_item_valid(my_head)) {
return false; return false;
} }
copy_front(v); v = this->front();
destroy_front(); destroy_front();
return true; return true;
} }
@ -251,10 +260,10 @@ namespace internal {
protected: protected:
bool reserve_front(T &v) { bool reserve_front(T &v) {
if(my_reserved || !my_item_valid(my_head)) return false; if(my_reserved || !my_item_valid(this->my_head)) return false;
my_reserved = true; my_reserved = true;
// reserving the head // reserving the head
this->copy_front(v); v = this->front();
this->reserve_item(this->my_head); this->reserve_item(this->my_head);
return true; return true;
} }

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#ifndef __TBB__flow_graph_join_impl_H #ifndef __TBB__flow_graph_join_impl_H
@ -213,7 +213,7 @@ namespace internal {
class reserving_port : public receiver<T> { class reserving_port : public receiver<T> {
public: public:
typedef T input_type; typedef T input_type;
typedef sender<T> predecessor_type; typedef typename receiver<input_type>::predecessor_type predecessor_type;
#if TBB_PREVIEW_FLOW_GRAPH_FEATURES #if TBB_PREVIEW_FLOW_GRAPH_FEATURES
typedef typename receiver<input_type>::predecessor_list_type predecessor_list_type; typedef typename receiver<input_type>::predecessor_list_type predecessor_list_type;
typedef typename receiver<input_type>::built_predecessors_type built_predecessors_type; typedef typename receiver<input_type>::built_predecessors_type built_predecessors_type;
@ -320,7 +320,7 @@ namespace internal {
template< typename R, typename B > friend class run_and_put_task; template< typename R, typename B > friend class run_and_put_task;
template<typename X, typename Y> friend class internal::broadcast_cache; template<typename X, typename Y> friend class internal::broadcast_cache;
template<typename X, typename Y> friend class internal::round_robin_cache; template<typename X, typename Y> friend class internal::round_robin_cache;
task *try_put_task( const T & ) { task *try_put_task( const T & ) __TBB_override {
return NULL; return NULL;
} }
@ -346,14 +346,14 @@ namespace internal {
} }
//! Add a predecessor //! Add a predecessor
bool register_predecessor( sender<T> &src ) { bool register_predecessor( predecessor_type &src ) __TBB_override {
reserving_port_operation op_data(src, reg_pred); reserving_port_operation op_data(src, reg_pred);
my_aggregator.execute(&op_data); my_aggregator.execute(&op_data);
return op_data.status == SUCCEEDED; return op_data.status == SUCCEEDED;
} }
//! Remove a predecessor //! Remove a predecessor
bool remove_predecessor( sender<T> &src ) { bool remove_predecessor( predecessor_type &src ) __TBB_override {
reserving_port_operation op_data(src, rem_pred); reserving_port_operation op_data(src, rem_pred);
my_aggregator.execute(&op_data); my_aggregator.execute(&op_data);
return op_data.status == SUCCEEDED; return op_data.status == SUCCEEDED;
@ -379,24 +379,24 @@ namespace internal {
} }
#if TBB_PREVIEW_FLOW_GRAPH_FEATURES #if TBB_PREVIEW_FLOW_GRAPH_FEATURES
/*override*/ built_predecessors_type &built_predecessors() { return my_predecessors.built_predecessors(); } built_predecessors_type &built_predecessors() __TBB_override { return my_predecessors.built_predecessors(); }
/*override*/void internal_add_built_predecessor(predecessor_type &src) { void internal_add_built_predecessor(predecessor_type &src) __TBB_override {
reserving_port_operation op_data(src, add_blt_pred); reserving_port_operation op_data(src, add_blt_pred);
my_aggregator.execute(&op_data); my_aggregator.execute(&op_data);
} }
/*override*/void internal_delete_built_predecessor(predecessor_type &src) { void internal_delete_built_predecessor(predecessor_type &src) __TBB_override {
reserving_port_operation op_data(src, del_blt_pred); reserving_port_operation op_data(src, del_blt_pred);
my_aggregator.execute(&op_data); my_aggregator.execute(&op_data);
} }
/*override*/size_t predecessor_count() { size_t predecessor_count() __TBB_override {
reserving_port_operation op_data(blt_pred_cnt); reserving_port_operation op_data(blt_pred_cnt);
my_aggregator.execute(&op_data); my_aggregator.execute(&op_data);
return op_data.cnt_val; return op_data.cnt_val;
} }
/*override*/void copy_predecessors(predecessor_list_type &l) { void copy_predecessors(predecessor_list_type &l) __TBB_override {
reserving_port_operation op_data(blt_pred_cpy); reserving_port_operation op_data(blt_pred_cpy);
op_data.plist = &l; op_data.plist = &l;
my_aggregator.execute(&op_data); my_aggregator.execute(&op_data);
@ -408,7 +408,7 @@ namespace internal {
#endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */ #endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */
/*override*/void reset_receiver( reset_flags f) { void reset_receiver( reset_flags f) __TBB_override {
if(f & rf_clear_edges) my_predecessors.clear(); if(f & rf_clear_edges) my_predecessors.clear();
else else
my_predecessors.reset(); my_predecessors.reset();
@ -427,7 +427,7 @@ namespace internal {
class queueing_port : public receiver<T>, public item_buffer<T> { class queueing_port : public receiver<T>, public item_buffer<T> {
public: public:
typedef T input_type; typedef T input_type;
typedef sender<T> predecessor_type; typedef typename receiver<input_type>::predecessor_type predecessor_type;
typedef queueing_port<T> class_type; typedef queueing_port<T> class_type;
#if TBB_PREVIEW_FLOW_GRAPH_FEATURES #if TBB_PREVIEW_FLOW_GRAPH_FEATURES
typedef typename receiver<input_type>::built_predecessors_type built_predecessors_type; typedef typename receiver<input_type>::built_predecessors_type built_predecessors_type;
@ -449,7 +449,7 @@ namespace internal {
T my_val; T my_val;
T *my_arg; T *my_arg;
#if TBB_PREVIEW_FLOW_GRAPH_FEATURES #if TBB_PREVIEW_FLOW_GRAPH_FEATURES
sender<T> *pred; predecessor_type *pred;
size_t cnt_val; size_t cnt_val;
predecessor_list_type *plist; predecessor_list_type *plist;
#endif #endif
@ -494,7 +494,7 @@ namespace internal {
break; break;
case get__item: case get__item:
if(!this->buffer_empty()) { if(!this->buffer_empty()) {
this->copy_front(*(current->my_arg)); *(current->my_arg) = this->front();
__TBB_store_with_release(current->status, SUCCEEDED); __TBB_store_with_release(current->status, SUCCEEDED);
} }
else { else {
@ -536,7 +536,7 @@ namespace internal {
template< typename R, typename B > friend class run_and_put_task; template< typename R, typename B > friend class run_and_put_task;
template<typename X, typename Y> friend class internal::broadcast_cache; template<typename X, typename Y> friend class internal::broadcast_cache;
template<typename X, typename Y> friend class internal::round_robin_cache; template<typename X, typename Y> friend class internal::round_robin_cache;
/*override*/task *try_put_task(const T &v) { task *try_put_task(const T &v) __TBB_override {
queueing_port_operation op_data(v, try__put_task); queueing_port_operation op_data(v, try__put_task);
my_aggregator.execute(&op_data); my_aggregator.execute(&op_data);
__TBB_ASSERT(op_data.status == SUCCEEDED || !op_data.bypass_t, "inconsistent return from aggregator"); __TBB_ASSERT(op_data.status == SUCCEEDED || !op_data.bypass_t, "inconsistent return from aggregator");
@ -578,27 +578,27 @@ namespace internal {
} }
#if TBB_PREVIEW_FLOW_GRAPH_FEATURES #if TBB_PREVIEW_FLOW_GRAPH_FEATURES
/*override*/ built_predecessors_type &built_predecessors() { return my_built_predecessors; } built_predecessors_type &built_predecessors() __TBB_override { return my_built_predecessors; }
/*override*/void internal_add_built_predecessor(sender<T> &p) { void internal_add_built_predecessor(predecessor_type &p) __TBB_override {
queueing_port_operation op_data(add_blt_pred); queueing_port_operation op_data(add_blt_pred);
op_data.pred = &p; op_data.pred = &p;
my_aggregator.execute(&op_data); my_aggregator.execute(&op_data);
} }
/*override*/void internal_delete_built_predecessor(sender<T> &p) { void internal_delete_built_predecessor(predecessor_type &p) __TBB_override {
queueing_port_operation op_data(del_blt_pred); queueing_port_operation op_data(del_blt_pred);
op_data.pred = &p; op_data.pred = &p;
my_aggregator.execute(&op_data); my_aggregator.execute(&op_data);
} }
/*override*/size_t predecessor_count() { size_t predecessor_count() __TBB_override {
queueing_port_operation op_data(blt_pred_cnt); queueing_port_operation op_data(blt_pred_cnt);
my_aggregator.execute(&op_data); my_aggregator.execute(&op_data);
return op_data.cnt_val; return op_data.cnt_val;
} }
/*override*/void copy_predecessors(predecessor_list_type &l) { void copy_predecessors(predecessor_list_type &l) __TBB_override {
queueing_port_operation op_data(blt_pred_cpy); queueing_port_operation op_data(blt_pred_cpy);
op_data.plist = &l; op_data.plist = &l;
my_aggregator.execute(&op_data); my_aggregator.execute(&op_data);
@ -610,7 +610,7 @@ namespace internal {
} }
#endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */ #endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */
/*override*/void reset_receiver(reset_flags f) { void reset_receiver(reset_flags f) __TBB_override {
tbb::internal::suppress_unused_warning(f); tbb::internal::suppress_unused_warning(f);
item_buffer<T>::reset(); item_buffer<T>::reset();
#if TBB_PREVIEW_FLOW_GRAPH_FEATURES #if TBB_PREVIEW_FLOW_GRAPH_FEATURES
@ -622,7 +622,7 @@ namespace internal {
private: private:
forwarding_base *my_join; forwarding_base *my_join;
#if TBB_PREVIEW_FLOW_GRAPH_FEATURES #if TBB_PREVIEW_FLOW_GRAPH_FEATURES
edge_container<sender<T> > my_built_predecessors; edge_container<predecessor_type> my_built_predecessors;
#endif #endif
}; // queueing_port }; // queueing_port
@ -655,7 +655,7 @@ namespace internal {
typedef typename TraitsType::T input_type; typedef typename TraitsType::T input_type;
typedef typename TraitsType::K key_type; typedef typename TraitsType::K key_type;
typedef typename tbb::internal::strip<key_type>::type noref_key_type; typedef typename tbb::internal::strip<key_type>::type noref_key_type;
typedef sender<input_type> predecessor_type; typedef typename receiver<input_type>::predecessor_type predecessor_type;
typedef typename TraitsType::TtoK type_to_key_func_type; typedef typename TraitsType::TtoK type_to_key_func_type;
typedef typename TraitsType::KHash hash_compare_type; typedef typename TraitsType::KHash hash_compare_type;
typedef hash_buffer< key_type, input_type, type_to_key_func_type, hash_compare_type > buffer_type; typedef hash_buffer< key_type, input_type, type_to_key_func_type, hash_compare_type > buffer_type;
@ -747,7 +747,7 @@ namespace internal {
template< typename R, typename B > friend class run_and_put_task; template< typename R, typename B > friend class run_and_put_task;
template<typename X, typename Y> friend class internal::broadcast_cache; template<typename X, typename Y> friend class internal::broadcast_cache;
template<typename X, typename Y> friend class internal::round_robin_cache; template<typename X, typename Y> friend class internal::round_robin_cache;
/*override*/task *try_put_task(const input_type& v) { task *try_put_task(const input_type& v) __TBB_override {
key_matching_port_operation op_data(v, try__put); key_matching_port_operation op_data(v, try__put);
task *rtask = NULL; task *rtask = NULL;
my_aggregator.execute(&op_data); my_aggregator.execute(&op_data);
@ -790,27 +790,27 @@ namespace internal {
} }
#if TBB_PREVIEW_FLOW_GRAPH_FEATURES #if TBB_PREVIEW_FLOW_GRAPH_FEATURES
/*override*/built_predecessors_type &built_predecessors() { return my_built_predecessors; } built_predecessors_type &built_predecessors() __TBB_override { return my_built_predecessors; }
/*override*/void internal_add_built_predecessor(sender<input_type> &p) { void internal_add_built_predecessor(predecessor_type &p) __TBB_override {
key_matching_port_operation op_data(add_blt_pred); key_matching_port_operation op_data(add_blt_pred);
op_data.pred = &p; op_data.pred = &p;
my_aggregator.execute(&op_data); my_aggregator.execute(&op_data);
} }
/*override*/void internal_delete_built_predecessor(sender<input_type> &p) { void internal_delete_built_predecessor(predecessor_type &p) __TBB_override {
key_matching_port_operation op_data(del_blt_pred); key_matching_port_operation op_data(del_blt_pred);
op_data.pred = &p; op_data.pred = &p;
my_aggregator.execute(&op_data); my_aggregator.execute(&op_data);
} }
/*override*/size_t predecessor_count() { size_t predecessor_count() __TBB_override {
key_matching_port_operation op_data(blt_pred_cnt); key_matching_port_operation op_data(blt_pred_cnt);
my_aggregator.execute(&op_data); my_aggregator.execute(&op_data);
return op_data.cnt_val; return op_data.cnt_val;
} }
/*override*/void copy_predecessors(predecessor_list_type &l) { void copy_predecessors(predecessor_list_type &l) __TBB_override {
key_matching_port_operation op_data(blt_pred_cpy); key_matching_port_operation op_data(blt_pred_cpy);
op_data.plist = &l; op_data.plist = &l;
my_aggregator.execute(&op_data); my_aggregator.execute(&op_data);
@ -831,7 +831,7 @@ namespace internal {
my_built_predecessors.receiver_extract(*this); my_built_predecessors.receiver_extract(*this);
} }
#endif #endif
/*override*/void reset_receiver(reset_flags f ) { void reset_receiver(reset_flags f ) __TBB_override {
tbb::internal::suppress_unused_warning(f); tbb::internal::suppress_unused_warning(f);
buffer_type::reset(); buffer_type::reset();
#if TBB_PREVIEW_FLOW_GRAPH_FEATURES #if TBB_PREVIEW_FLOW_GRAPH_FEATURES
@ -878,12 +878,12 @@ namespace internal {
void set_my_node(base_node_type *new_my_node) { my_node = new_my_node; } void set_my_node(base_node_type *new_my_node) { my_node = new_my_node; }
void increment_port_count() { void increment_port_count() __TBB_override {
++ports_with_no_inputs; ++ports_with_no_inputs;
} }
// if all input_ports have predecessors, spawn forward to try and consume tuples // if all input_ports have predecessors, spawn forward to try and consume tuples
task * decrement_port_count(bool handle_task) { task * decrement_port_count(bool handle_task) __TBB_override {
if(ports_with_no_inputs.fetch_and_decrement() == 1) { if(ports_with_no_inputs.fetch_and_decrement() == 1) {
if(this->graph_pointer->is_active()) { if(this->graph_pointer->is_active()) {
task *rtask = new ( task::allocate_additional_child_of( *(this->graph_pointer->root_task()) ) ) task *rtask = new ( task::allocate_additional_child_of( *(this->graph_pointer->root_task()) ) )
@ -962,7 +962,7 @@ namespace internal {
} }
// if all input_ports have items, spawn forward to try and consume tuples // if all input_ports have items, spawn forward to try and consume tuples
task * decrement_port_count(bool handle_task) task * decrement_port_count(bool handle_task) __TBB_override
{ {
if(ports_with_no_items.fetch_and_decrement() == 1) { if(ports_with_no_items.fetch_and_decrement() == 1) {
if(this->graph_pointer->is_active()) { if(this->graph_pointer->is_active()) {
@ -975,7 +975,7 @@ namespace internal {
return NULL; return NULL;
} }
void increment_port_count() { __TBB_ASSERT(false, NULL); } // should never be called void increment_port_count() __TBB_override { __TBB_ASSERT(false, NULL); } // should never be called
input_type &input_ports() { return my_inputs; } input_type &input_ports() { return my_inputs; }
@ -1148,7 +1148,7 @@ namespace internal {
__TBB_store_with_release(current->status, FAILED); __TBB_store_with_release(current->status, FAILED);
} }
else { else {
this->copy_front(*(current->my_output)); *(current->my_output) = this->front();
__TBB_store_with_release(current->status, SUCCEEDED); __TBB_store_with_release(current->status, SUCCEEDED);
} }
break; break;
@ -1188,15 +1188,15 @@ namespace internal {
// if all input_ports have items, spawn forward to try and consume tuples // if all input_ports have items, spawn forward to try and consume tuples
// return a task if we are asked and did create one. // return a task if we are asked and did create one.
/*override*/ task *increment_key_count(unref_key_type const & t, bool handle_task) { // called from input_ports task *increment_key_count(unref_key_type const & t, bool handle_task) __TBB_override { // called from input_ports
key_matching_FE_operation op_data(t, handle_task, inc_count); key_matching_FE_operation op_data(t, handle_task, inc_count);
my_aggregator.execute(&op_data); my_aggregator.execute(&op_data);
return op_data.bypass_t; return op_data.bypass_t;
} }
/*override*/ task *decrement_port_count(bool /*handle_task*/) { __TBB_ASSERT(false, NULL); return NULL; } task *decrement_port_count(bool /*handle_task*/) __TBB_override { __TBB_ASSERT(false, NULL); return NULL; }
void increment_port_count() { __TBB_ASSERT(false, NULL); } // should never be called void increment_port_count() __TBB_override { __TBB_ASSERT(false, NULL); } // should never be called
input_type &input_ports() { return my_inputs; } input_type &input_ports() { return my_inputs; }
@ -1256,7 +1256,7 @@ namespace internal {
public: public:
typedef OutputTuple output_type; typedef OutputTuple output_type;
typedef receiver<output_type> successor_type; typedef typename sender<output_type>::successor_type successor_type;
typedef join_node_FE<JP, InputTuple, OutputTuple> input_ports_type; typedef join_node_FE<JP, InputTuple, OutputTuple> input_ports_type;
using input_ports_type::tuple_build_may_succeed; using input_ports_type::tuple_build_may_succeed;
using input_ports_type::try_to_make_tuple; using input_ports_type::try_to_make_tuple;
@ -1402,44 +1402,44 @@ namespace internal {
my_aggregator.initialize_handler(handler_type(this)); my_aggregator.initialize_handler(handler_type(this));
} }
bool register_successor(successor_type &r) { bool register_successor(successor_type &r) __TBB_override {
join_node_base_operation op_data(r, reg_succ); join_node_base_operation op_data(r, reg_succ);
my_aggregator.execute(&op_data); my_aggregator.execute(&op_data);
return op_data.status == SUCCEEDED; return op_data.status == SUCCEEDED;
} }
bool remove_successor( successor_type &r) { bool remove_successor( successor_type &r) __TBB_override {
join_node_base_operation op_data(r, rem_succ); join_node_base_operation op_data(r, rem_succ);
my_aggregator.execute(&op_data); my_aggregator.execute(&op_data);
return op_data.status == SUCCEEDED; return op_data.status == SUCCEEDED;
} }
bool try_get( output_type &v) { bool try_get( output_type &v) __TBB_override {
join_node_base_operation op_data(v, try__get); join_node_base_operation op_data(v, try__get);
my_aggregator.execute(&op_data); my_aggregator.execute(&op_data);
return op_data.status == SUCCEEDED; return op_data.status == SUCCEEDED;
} }
#if TBB_PREVIEW_FLOW_GRAPH_FEATURES #if TBB_PREVIEW_FLOW_GRAPH_FEATURES
/*override*/built_successors_type &built_successors() { return my_successors.built_successors(); } built_successors_type &built_successors() __TBB_override { return my_successors.built_successors(); }
/*override*/void internal_add_built_successor( successor_type &r) { void internal_add_built_successor( successor_type &r) __TBB_override {
join_node_base_operation op_data(r, add_blt_succ); join_node_base_operation op_data(r, add_blt_succ);
my_aggregator.execute(&op_data); my_aggregator.execute(&op_data);
} }
/*override*/void internal_delete_built_successor( successor_type &r) { void internal_delete_built_successor( successor_type &r) __TBB_override {
join_node_base_operation op_data(r, del_blt_succ); join_node_base_operation op_data(r, del_blt_succ);
my_aggregator.execute(&op_data); my_aggregator.execute(&op_data);
} }
/*override*/size_t successor_count() { size_t successor_count() __TBB_override {
join_node_base_operation op_data(blt_succ_cnt); join_node_base_operation op_data(blt_succ_cnt);
my_aggregator.execute(&op_data); my_aggregator.execute(&op_data);
return op_data.cnt_val; return op_data.cnt_val;
} }
/*override*/ void copy_successors(successor_list_type &l) { void copy_successors(successor_list_type &l) __TBB_override {
join_node_base_operation op_data(blt_succ_cpy); join_node_base_operation op_data(blt_succ_cpy);
op_data.slist = &l; op_data.slist = &l;
my_aggregator.execute(&op_data); my_aggregator.execute(&op_data);
@ -1447,7 +1447,7 @@ namespace internal {
#endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */ #endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */
#if TBB_PREVIEW_FLOW_GRAPH_FEATURES #if TBB_PREVIEW_FLOW_GRAPH_FEATURES
/*override*/void extract() { void extract() __TBB_override {
input_ports_type::extract(); input_ports_type::extract();
my_successors.built_successors().sender_extract(*this); my_successors.built_successors().sender_extract(*this);
} }
@ -1455,7 +1455,7 @@ namespace internal {
protected: protected:
/*override*/void reset_node(reset_flags f) { void reset_node(reset_flags f) __TBB_override {
input_ports_type::reset(f); input_ports_type::reset(f);
if(f & rf_clear_edges) my_successors.clear(); if(f & rf_clear_edges) my_successors.clear();
} }

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#ifndef __TBB__flow_graph_node_impl_H #ifndef __TBB__flow_graph_node_impl_H
@ -37,10 +37,22 @@ namespace internal {
template< typename T, typename A > template< typename T, typename A >
class function_input_queue : public item_buffer<T,A> { class function_input_queue : public item_buffer<T,A> {
public: public:
bool empty() const {
return this->buffer_empty();
}
const T& front() const {
return this->item_buffer<T, A>::front();
}
bool pop( T& t ) { bool pop( T& t ) {
return this->pop_front( t ); return this->pop_front( t );
} }
void pop() {
this->destroy_front();
}
bool push( T& t ) { bool push( T& t ) {
return this->push_back( t ); return this->push_back( t );
} }
@ -51,7 +63,6 @@ namespace internal {
// call and any handling of the result. // call and any handling of the result.
template< typename Input, typename A, typename ImplType > template< typename Input, typename A, typename ImplType >
class function_input_base : public receiver<Input>, tbb::internal::no_assign { class function_input_base : public receiver<Input>, tbb::internal::no_assign {
enum op_stat {WAIT=0, SUCCEEDED, FAILED};
enum op_type {reg_pred, rem_pred, app_body, try_fwd, tryput_bypass, app_body_bypass enum op_type {reg_pred, rem_pred, app_body, try_fwd, tryput_bypass, app_body_bypass
#if TBB_PREVIEW_FLOW_GRAPH_FEATURES #if TBB_PREVIEW_FLOW_GRAPH_FEATURES
, add_blt_pred, del_blt_pred, , add_blt_pred, del_blt_pred,
@ -64,7 +75,7 @@ namespace internal {
//! The input type of this receiver //! The input type of this receiver
typedef Input input_type; typedef Input input_type;
typedef sender<Input> predecessor_type; typedef typename receiver<input_type>::predecessor_type predecessor_type;
typedef predecessor_cache<input_type, null_mutex > predecessor_cache_type; typedef predecessor_cache<input_type, null_mutex > predecessor_cache_type;
typedef function_input_queue<input_type, A> input_queue_type; typedef function_input_queue<input_type, A> input_queue_type;
typedef typename A::template rebind< input_queue_type >::other queue_allocator_type; typedef typename A::template rebind< input_queue_type >::other queue_allocator_type;
@ -76,7 +87,7 @@ namespace internal {
//! Constructor for function_input_base //! Constructor for function_input_base
function_input_base( graph &g, size_t max_concurrency, input_queue_type *q = NULL) function_input_base( graph &g, size_t max_concurrency, input_queue_type *q = NULL)
: my_graph(g), my_max_concurrency(max_concurrency), my_concurrency(0), : my_graph_ptr(&g), my_max_concurrency(max_concurrency), my_concurrency(0),
my_queue(q), forwarder_busy(false) { my_queue(q), forwarder_busy(false) {
my_predecessors.set_owner(this); my_predecessors.set_owner(this);
my_aggregator.initialize_handler(handler_type(this)); my_aggregator.initialize_handler(handler_type(this));
@ -85,7 +96,7 @@ namespace internal {
//! Copy constructor //! Copy constructor
function_input_base( const function_input_base& src, input_queue_type *q = NULL) : function_input_base( const function_input_base& src, input_queue_type *q = NULL) :
receiver<Input>(), tbb::internal::no_assign(), receiver<Input>(), tbb::internal::no_assign(),
my_graph(src.my_graph), my_max_concurrency(src.my_max_concurrency), my_graph_ptr(src.my_graph_ptr), my_max_concurrency(src.my_max_concurrency),
my_concurrency(0), my_queue(q), forwarder_busy(false) my_concurrency(0), my_queue(q), forwarder_busy(false)
{ {
my_predecessors.set_owner(this); my_predecessors.set_owner(this);
@ -101,13 +112,13 @@ namespace internal {
} }
//! Put to the node, returning a task if available //! Put to the node, returning a task if available
virtual task * try_put_task( const input_type &t ) { task * try_put_task( const input_type &t ) __TBB_override {
if ( my_max_concurrency == 0 ) { if ( my_max_concurrency == 0 ) {
return create_body_task( t ); return create_body_task( t );
} else { } else {
operation_type op_data(t, tryput_bypass); operation_type op_data(t, tryput_bypass);
my_aggregator.execute(&op_data); my_aggregator.execute(&op_data);
if(op_data.status == SUCCEEDED ) { if(op_data.status == internal::SUCCEEDED) {
return op_data.bypass_t; return op_data.bypass_t;
} }
return NULL; return NULL;
@ -115,7 +126,7 @@ namespace internal {
} }
//! Adds src to the list of cached predecessors. //! Adds src to the list of cached predecessors.
/* override */ bool register_predecessor( predecessor_type &src ) { bool register_predecessor( predecessor_type &src ) __TBB_override {
operation_type op_data(reg_pred); operation_type op_data(reg_pred);
op_data.r = &src; op_data.r = &src;
my_aggregator.execute(&op_data); my_aggregator.execute(&op_data);
@ -123,7 +134,7 @@ namespace internal {
} }
//! Removes src from the list of cached predecessors. //! Removes src from the list of cached predecessors.
/* override */ bool remove_predecessor( predecessor_type &src ) { bool remove_predecessor( predecessor_type &src ) __TBB_override {
operation_type op_data(rem_pred); operation_type op_data(rem_pred);
op_data.r = &src; op_data.r = &src;
my_aggregator.execute(&op_data); my_aggregator.execute(&op_data);
@ -132,32 +143,32 @@ namespace internal {
#if TBB_PREVIEW_FLOW_GRAPH_FEATURES #if TBB_PREVIEW_FLOW_GRAPH_FEATURES
//! Adds to list of predecessors added by make_edge //! Adds to list of predecessors added by make_edge
/*override*/ void internal_add_built_predecessor( predecessor_type &src) { void internal_add_built_predecessor( predecessor_type &src) __TBB_override {
operation_type op_data(add_blt_pred); operation_type op_data(add_blt_pred);
op_data.r = &src; op_data.r = &src;
my_aggregator.execute(&op_data); my_aggregator.execute(&op_data);
} }
//! removes from to list of predecessors (used by remove_edge) //! removes from to list of predecessors (used by remove_edge)
/*override*/ void internal_delete_built_predecessor( predecessor_type &src) { void internal_delete_built_predecessor( predecessor_type &src) __TBB_override {
operation_type op_data(del_blt_pred); operation_type op_data(del_blt_pred);
op_data.r = &src; op_data.r = &src;
my_aggregator.execute(&op_data); my_aggregator.execute(&op_data);
} }
/*override*/ size_t predecessor_count() { size_t predecessor_count() __TBB_override {
operation_type op_data(blt_pred_cnt); operation_type op_data(blt_pred_cnt);
my_aggregator.execute(&op_data); my_aggregator.execute(&op_data);
return op_data.cnt_val; return op_data.cnt_val;
} }
/*override*/ void copy_predecessors(predecessor_list_type &v) { void copy_predecessors(predecessor_list_type &v) __TBB_override {
operation_type op_data(blt_pred_cpy); operation_type op_data(blt_pred_cpy);
op_data.predv = &v; op_data.predv = &v;
my_aggregator.execute(&op_data); my_aggregator.execute(&op_data);
} }
/*override*/built_predecessors_type &built_predecessors() { built_predecessors_type &built_predecessors() __TBB_override {
return my_predecessors.built_predecessors(); return my_predecessors.built_predecessors();
} }
#endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */ #endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */
@ -173,13 +184,13 @@ namespace internal {
forwarder_busy = false; forwarder_busy = false;
} }
graph& my_graph; graph* my_graph_ptr;
const size_t my_max_concurrency; const size_t my_max_concurrency;
size_t my_concurrency; size_t my_concurrency;
input_queue_type *my_queue; input_queue_type *my_queue;
predecessor_cache<input_type, null_mutex > my_predecessors; predecessor_cache<input_type, null_mutex > my_predecessors;
/*override*/void reset_receiver( reset_flags f) { void reset_receiver( reset_flags f) __TBB_override {
if( f & rf_clear_edges) my_predecessors.clear(); if( f & rf_clear_edges) my_predecessors.clear();
else else
my_predecessors.reset(); my_predecessors.reset();
@ -213,6 +224,32 @@ namespace internal {
friend class internal::aggregating_functor<class_type, operation_type>; friend class internal::aggregating_functor<class_type, operation_type>;
aggregator< handler_type, operation_type > my_aggregator; aggregator< handler_type, operation_type > my_aggregator;
task* create_and_spawn_task(bool spawn) {
task* new_task = NULL;
if(my_queue) {
if(!my_queue->empty()) {
++my_concurrency;
new_task = create_body_task(my_queue->front());
my_queue->pop();
}
}
else {
input_type i;
if(my_predecessors.get_item(i)) {
++my_concurrency;
new_task = create_body_task(i);
}
}
//! Spawns a task that applies a body
// task == NULL => g.reset(), which shouldn't occur in concurrent context
if(spawn && new_task) {
FLOW_SPAWN(*new_task);
new_task = SUCCESSFULLY_ENQUEUED;
}
return new_task;
}
void handle_operations(operation_type *op_list) { void handle_operations(operation_type *op_list) {
operation_type *tmp; operation_type *tmp;
while (op_list) { while (op_list) {
@ -236,35 +273,16 @@ namespace internal {
--my_concurrency; --my_concurrency;
__TBB_store_with_release(tmp->status, SUCCEEDED); __TBB_store_with_release(tmp->status, SUCCEEDED);
if (my_concurrency<my_max_concurrency) { if (my_concurrency<my_max_concurrency) {
input_type i; create_and_spawn_task(/*spawn=*/true);
bool item_was_retrieved = false;
if ( my_queue )
item_was_retrieved = my_queue->pop(i);
else
item_was_retrieved = my_predecessors.get_item(i);
if (item_was_retrieved) {
++my_concurrency;
spawn_body_task(i);
}
} }
break; break;
case app_body_bypass: { case app_body_bypass: {
task * new_task = NULL; tmp->bypass_t = NULL;
__TBB_ASSERT(my_max_concurrency != 0, NULL); __TBB_ASSERT(my_max_concurrency != 0, NULL);
--my_concurrency; --my_concurrency;
if (my_concurrency<my_max_concurrency) { if(my_concurrency<my_max_concurrency)
input_type i; tmp->bypass_t = create_and_spawn_task(/*spawn=*/false);
bool item_was_retrieved = false;
if ( my_queue )
item_was_retrieved = my_queue->pop(i);
else
item_was_retrieved = my_predecessors.get_item(i);
if (item_was_retrieved) {
++my_concurrency;
new_task = create_body_task(i);
}
}
tmp->bypass_t = new_task;
__TBB_store_with_release(tmp->status, SUCCEEDED); __TBB_store_with_release(tmp->status, SUCCEEDED);
} }
break; break;
@ -313,22 +331,14 @@ namespace internal {
//! Tries to spawn bodies if available and if concurrency allows //! Tries to spawn bodies if available and if concurrency allows
void internal_forward(operation_type *op) { void internal_forward(operation_type *op) {
op->bypass_t = NULL; op->bypass_t = NULL;
if (my_concurrency<my_max_concurrency || !my_max_concurrency) { if (my_concurrency < my_max_concurrency || !my_max_concurrency)
input_type i; op->bypass_t = create_and_spawn_task(/*spawn=*/false);
bool item_was_retrieved = false; if(op->bypass_t)
if ( my_queue )
item_was_retrieved = my_queue->pop(i);
else
item_was_retrieved = my_predecessors.get_item(i);
if (item_was_retrieved) {
++my_concurrency;
op->bypass_t = create_body_task(i);
__TBB_store_with_release(op->status, SUCCEEDED); __TBB_store_with_release(op->status, SUCCEEDED);
return; else {
}
}
__TBB_store_with_release(op->status, FAILED);
forwarder_busy = false; forwarder_busy = false;
__TBB_store_with_release(op->status, FAILED);
}
} }
//! Applies the body to the provided input //! Applies the body to the provided input
@ -347,21 +357,12 @@ namespace internal {
//! allocates a task to apply a body //! allocates a task to apply a body
inline task * create_body_task( const input_type &input ) { inline task * create_body_task( const input_type &input ) {
return (my_graph.is_active()) ? return (my_graph_ptr->is_active()) ?
new(task::allocate_additional_child_of(*(my_graph.root_task()))) new(task::allocate_additional_child_of(*(my_graph_ptr->root_task())))
apply_body_task_bypass < class_type, input_type >(*this, input) : apply_body_task_bypass < class_type, input_type >(*this, input) :
NULL; NULL;
} }
//! Spawns a task that applies a body
inline void spawn_body_task( const input_type &input ) {
task* tp = create_body_task(input);
// tp == NULL => g.reset(), which shouldn't occur in concurrent context
if(tp) {
FLOW_SPAWN(*tp);
}
}
//! This is executed by an enqueued task, the "forwarder" //! This is executed by an enqueued task, the "forwarder"
task *forward_task() { task *forward_task() {
operation_type op_data(try_fwd); operation_type op_data(try_fwd);
@ -378,8 +379,8 @@ namespace internal {
} }
inline task *create_forward_task() { inline task *create_forward_task() {
return (my_graph.is_active()) ? return (my_graph_ptr->is_active()) ?
new(task::allocate_additional_child_of(*(my_graph.root_task()))) forward_task_bypass< class_type >(*this) : new(task::allocate_additional_child_of(*(my_graph_ptr->root_task()))) forward_task_bypass< class_type >(*this) :
NULL; NULL;
} }
@ -540,7 +541,7 @@ namespace internal {
template< typename Body > template< typename Body >
Body copy_function_object() { Body copy_function_object() {
multifunction_body_type &body_ref = *this->my_body; multifunction_body_type &body_ref = *this->my_body;
return dynamic_cast< internal::multifunction_body_leaf<input_type, output_ports_type, Body> & >(body_ref).get_body(); return *static_cast<Body*>(dynamic_cast< internal::multifunction_body_leaf<input_type, output_ports_type, Body> & >(body_ref).get_body_ptr());
} }
// for multifunction nodes we do not have a single successor as such. So we just tell // for multifunction nodes we do not have a single successor as such. So we just tell
@ -557,12 +558,12 @@ namespace internal {
protected: protected:
#if TBB_PREVIEW_FLOW_GRAPH_FEATURES #if TBB_PREVIEW_FLOW_GRAPH_FEATURES
/*override*/void extract() { void extract() {
extract_element<N>::extract_this(my_output_ports); extract_element<N>::extract_this(my_output_ports);
} }
#endif #endif
/*override*/void reset(reset_flags f) { void reset(reset_flags f) {
base_type::reset_function_input_base(f); base_type::reset_function_input_base(f);
if(f & rf_clear_edges)clear_element<N>::clear_this(my_output_ports); if(f & rf_clear_edges)clear_element<N>::clear_this(my_output_ports);
if(f & rf_reset_bodies) { if(f & rf_reset_bodies) {
@ -644,7 +645,7 @@ namespace internal {
return dynamic_cast< internal::function_body_leaf<input_type, output_type, Body> & >(body_ref).get_body(); return dynamic_cast< internal::function_body_leaf<input_type, output_type, Body> & >(body_ref).get_body();
} }
/*override*/void reset_receiver( reset_flags f) { void reset_receiver( reset_flags f) __TBB_override {
continue_receiver::reset_receiver(f); continue_receiver::reset_receiver(f);
if(f & rf_reset_bodies) { if(f & rf_reset_bodies) {
function_body_type *tmp = my_init_body->clone(); function_body_type *tmp = my_init_body->clone();
@ -678,7 +679,7 @@ namespace internal {
} }
//! Spawns a task that applies the body //! Spawns a task that applies the body
/* override */ task *execute( ) { task *execute( ) __TBB_override {
return (my_graph_ptr->is_active()) ? return (my_graph_ptr->is_active()) ?
new ( task::allocate_additional_child_of( *(my_graph_ptr->root_task()) ) ) new ( task::allocate_additional_child_of( *(my_graph_ptr->root_task()) ) )
apply_body_task_bypass< continue_input< Output >, continue_msg >( *this, continue_msg() ) : apply_body_task_bypass< continue_input< Output >, continue_msg >( *this, continue_msg() ) :
@ -694,7 +695,7 @@ namespace internal {
template<int N> friend struct clear_element; template<int N> friend struct clear_element;
typedef Output output_type; typedef Output output_type;
typedef receiver<output_type> successor_type; typedef typename sender<output_type>::successor_type successor_type;
typedef broadcast_cache<output_type> broadcast_cache_type; typedef broadcast_cache<output_type> broadcast_cache_type;
#if TBB_PREVIEW_FLOW_GRAPH_FEATURES #if TBB_PREVIEW_FLOW_GRAPH_FEATURES
typedef typename sender<output_type>::built_successors_type built_successors_type; typedef typename sender<output_type>::built_successors_type built_successors_type;
@ -707,34 +708,34 @@ namespace internal {
} }
//! Adds a new successor to this node //! Adds a new successor to this node
/* override */ bool register_successor( receiver<output_type> &r ) { bool register_successor( successor_type &r ) __TBB_override {
successors().register_successor( r ); successors().register_successor( r );
return true; return true;
} }
//! Removes a successor from this node //! Removes a successor from this node
/* override */ bool remove_successor( receiver<output_type> &r ) { bool remove_successor( successor_type &r ) __TBB_override {
successors().remove_successor( r ); successors().remove_successor( r );
return true; return true;
} }
#if TBB_PREVIEW_FLOW_GRAPH_FEATURES #if TBB_PREVIEW_FLOW_GRAPH_FEATURES
built_successors_type &built_successors() { return successors().built_successors(); } built_successors_type &built_successors() __TBB_override { return successors().built_successors(); }
/*override*/ void internal_add_built_successor( receiver<output_type> &r) { void internal_add_built_successor( successor_type &r) __TBB_override {
successors().internal_add_built_successor( r ); successors().internal_add_built_successor( r );
} }
/*override*/ void internal_delete_built_successor( receiver<output_type> &r) { void internal_delete_built_successor( successor_type &r) __TBB_override {
successors().internal_delete_built_successor( r ); successors().internal_delete_built_successor( r );
} }
/*override*/ size_t successor_count() { size_t successor_count() __TBB_override {
return successors().successor_count(); return successors().successor_count();
} }
/*override*/ void copy_successors( successor_list_type &v) { void copy_successors( successor_list_type &v) __TBB_override {
successors().copy_successors(v); successors().copy_successors(v);
} }
#endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */ #endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */
@ -747,7 +748,9 @@ namespace internal {
// //
// if task pointer is returned will always spawn and return true, else // if task pointer is returned will always spawn and return true, else
// return value will be bool returned from successors.try_put. // return value will be bool returned from successors.try_put.
task *try_put_task(const output_type &i) { return my_successors.try_put_task(i); } task *try_put_task(const output_type &i) { // not a virtual method in this class
return my_successors.try_put_task(i);
}
broadcast_cache_type &successors() { return my_successors; } broadcast_cache_type &successors() { return my_successors; }
protected: protected:

View file

@ -0,0 +1,745 @@
/*
Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#ifndef __TBB_flow_graph_streaming_H
#define __TBB_flow_graph_streaming_H
#ifndef __TBB_flow_graph_H
#error Do not #include this internal file directly; use public TBB headers instead.
#endif
#if __TBB_PREVIEW_STREAMING_NODE
// Included in namespace tbb::flow::interfaceX (in flow_graph.h)
namespace internal {
template <int N1, int N2>
struct port_ref_impl {
// "+1" since the port_ref range is a closed interval (includes its endpoints).
static const int size = N2 - N1 + 1;
};
} // internal
// The purpose of the port_ref_impl is the pretty syntax: the deduction of a compile-time constant is processed from the return type.
// So it is possible to use this helper without parentheses, e.g. "port_ref<0>".
template <int N1, int N2 = N1>
internal::port_ref_impl<N1,N2> port_ref() {
return internal::port_ref_impl<N1,N2>();
};
namespace internal {
template <typename T>
struct num_arguments {
static const int value = 1;
};
template <int N1, int N2>
struct num_arguments<port_ref_impl<N1,N2>(*)()> {
static const int value = port_ref_impl<N1,N2>::size;
};
template <int N1, int N2>
struct num_arguments<port_ref_impl<N1,N2>> {
static const int value = port_ref_impl<N1,N2>::size;
};
template <typename... Args>
void ignore_return_values( Args&&... ) {}
template <typename T>
T or_return_values( T&& t ) { return t; }
template <typename T, typename... Rest>
T or_return_values( T&& t, Rest&&... rest ) {
return t | or_return_values( std::forward<Rest>(rest)... );
}
template<typename JP>
struct key_from_policy {
typedef size_t type;
typedef std::false_type is_key_matching;
};
template<typename Key>
struct key_from_policy< key_matching<Key> > {
typedef Key type;
typedef std::true_type is_key_matching;
};
template<typename Key>
struct key_from_policy< key_matching<Key&> > {
typedef const Key &type;
typedef std::true_type is_key_matching;
};
template<typename Device, typename Key>
class streaming_device_with_key {
Device my_device;
typename std::decay<Key>::type my_key;
public:
// TODO: investigate why default constructor is required
streaming_device_with_key() {}
streaming_device_with_key( const Device& d, Key k ) : my_device( d ), my_key( k ) {}
Key key() const { return my_key; }
const Device& device() const { return my_device; }
};
// --------- Kernel argument helpers --------- //
template <typename T>
struct is_port_ref_impl {
typedef std::false_type type;
};
template <int N1, int N2>
struct is_port_ref_impl< port_ref_impl<N1, N2> > {
typedef std::true_type type;
};
template <int N1, int N2>
struct is_port_ref_impl< port_ref_impl<N1, N2>( * )() > {
typedef std::true_type type;
};
template <typename T>
struct is_port_ref {
typedef typename is_port_ref_impl< typename tbb::internal::strip<T>::type >::type type;
};
template <typename ...Args1>
struct convert_and_call_impl;
template <typename A1, typename ...Args1>
struct convert_and_call_impl<A1, Args1...> {
static const size_t my_delta = 1; // Index 0 contains device
template <typename F, typename Tuple, typename ...Args2>
static void doit(F& f, Tuple& t, A1& a1, Args1&... args1, Args2&... args2) {
convert_and_call_impl<A1, Args1...>::doit_impl(typename is_port_ref<A1>::type(), f, t, a1, args1..., args2...);
}
template <typename F, typename Tuple, typename ...Args2>
static void doit_impl(std::false_type, F& f, Tuple& t, A1& a1, Args1&... args1, Args2&... args2) {
convert_and_call_impl<Args1...>::doit(f, t, args1..., args2..., a1);
}
template <typename F, typename Tuple, int N1, int N2, typename ...Args2>
static void doit_impl(std::true_type x, F& f, Tuple& t, port_ref_impl<N1, N2>, Args1&... args1, Args2&... args2) {
convert_and_call_impl<port_ref_impl<N1 + 1,N2>, Args1...>::doit_impl(x, f, t, port_ref<N1 + 1, N2>(), args1...,
args2..., std::get<N1 + my_delta>(t));
}
template <typename F, typename Tuple, int N, typename ...Args2>
static void doit_impl(std::true_type, F& f, Tuple& t, port_ref_impl<N, N>, Args1&... args1, Args2&... args2) {
convert_and_call_impl<Args1...>::doit(f, t, args1..., args2..., std::get<N + my_delta>(t));
}
template <typename F, typename Tuple, int N1, int N2, typename ...Args2>
static void doit_impl(std::true_type x, F& f, Tuple& t, port_ref_impl<N1, N2>(* fn)(), Args1&... args1, Args2&... args2) {
doit_impl(x, f, t, fn(), args1..., args2...);
}
template <typename F, typename Tuple, int N, typename ...Args2>
static void doit_impl(std::true_type x, F& f, Tuple& t, port_ref_impl<N, N>(* fn)(), Args1&... args1, Args2&... args2) {
doit_impl(x, f, t, fn(), args1..., args2...);
}
};
template <>
struct convert_and_call_impl<> {
template <typename F, typename Tuple, typename ...Args2>
static void doit(F& f, Tuple&, Args2&... args2) {
f(args2...);
}
};
// ------------------------------------------- //
template<typename JP, typename StreamFactory, typename... Ports>
struct streaming_node_traits {
// Do not use 'using' instead of 'struct' because Microsoft Visual C++ 12.0 fails to compile.
template <typename T>
struct async_msg_type {
typedef typename StreamFactory::template async_msg_type<T> type;
};
typedef tuple< typename async_msg_type<Ports>::type... > input_tuple;
typedef input_tuple output_tuple;
typedef tuple< streaming_device_with_key< typename StreamFactory::device_type, typename key_from_policy<JP>::type >,
typename async_msg_type<Ports>::type... > kernel_input_tuple;
// indexer_node parameters pack expansion workaround for VS2013 for streaming_node
typedef indexer_node< typename async_msg_type<Ports>::type... > indexer_node_type;
};
// Default empty implementation
template<typename StreamFactory, typename KernelInputTuple, typename = void>
class kernel_executor_helper {
typedef typename StreamFactory::device_type device_type;
typedef typename StreamFactory::kernel_type kernel_type;
typedef KernelInputTuple kernel_input_tuple;
protected:
template <typename ...Args>
void enqueue_kernel_impl( kernel_input_tuple&, StreamFactory& factory, device_type device, const kernel_type& kernel, Args&... args ) const {
factory.send_kernel( device, kernel, args... );
}
};
// Implementation for StreamFactory supporting range
template<typename StreamFactory, typename KernelInputTuple>
class kernel_executor_helper<StreamFactory, KernelInputTuple, typename tbb::internal::void_t< typename StreamFactory::range_type >::type > {
typedef typename StreamFactory::device_type device_type;
typedef typename StreamFactory::kernel_type kernel_type;
typedef KernelInputTuple kernel_input_tuple;
typedef typename StreamFactory::range_type range_type;
// Container for randge. It can contain either port references or real range.
struct range_wrapper {
virtual range_type get_range( const kernel_input_tuple &ip ) const = 0;
virtual range_wrapper *clone() const = 0;
virtual ~range_wrapper() {}
};
struct range_value : public range_wrapper {
range_value( const range_type& value ) : my_value(value) {}
range_value( range_type&& value ) : my_value(std::move(value)) {}
range_type get_range( const kernel_input_tuple & ) const __TBB_override {
return my_value;
}
range_wrapper *clone() const __TBB_override {
return new range_value(my_value);
}
private:
range_type my_value;
};
template <int N>
struct range_mapper : public range_wrapper {
range_mapper() {}
range_type get_range( const kernel_input_tuple &ip ) const __TBB_override {
// "+1" since get<0>(ip) is StreamFactory::device.
return get<N + 1>(ip).data(false);
}
range_wrapper *clone() const __TBB_override {
return new range_mapper<N>;
}
};
protected:
template <typename ...Args>
void enqueue_kernel_impl( kernel_input_tuple& ip, StreamFactory& factory, device_type device, const kernel_type& kernel, Args&... args ) const {
__TBB_ASSERT(my_range_wrapper, "Range is not set. Call set_range() before running streaming_node.");
factory.send_kernel( device, kernel, my_range_wrapper->get_range(ip), args... );
}
public:
kernel_executor_helper() : my_range_wrapper(NULL) {}
kernel_executor_helper(const kernel_executor_helper& executor) : my_range_wrapper(executor.my_range_wrapper ? executor.my_range_wrapper->clone() : NULL) {}
kernel_executor_helper(kernel_executor_helper&& executor) : my_range_wrapper(executor.my_range_wrapper) {
// Set moving holder mappers to NULL to prevent double deallocation
executor.my_range_wrapper = NULL;
}
~kernel_executor_helper() {
if (my_range_wrapper) delete my_range_wrapper;
}
void set_range(const range_type& work_size) {
my_range_wrapper = new range_value(work_size);
}
void set_range(range_type&& work_size) {
my_range_wrapper = new range_value(std::move(work_size));
}
template <int N>
void set_range(port_ref_impl<N, N>) {
my_range_wrapper = new range_mapper<N>;
}
template <int N>
void set_range(port_ref_impl<N, N>(*)()) {
my_range_wrapper = new range_mapper<N>;
}
private:
range_wrapper* my_range_wrapper;
};
} // internal
/*
/---------------------------------------- streaming_node ------------------------------------\
| |
| /--------------\ /----------------------\ /-----------\ /----------------------\ |
| | | | (device_with_key) O---O | | | |
| | | | | | | | | |
O---O indexer_node O---O device_selector_node O---O join_node O---O kernel_node O---O
| | | | (multifunction_node) | | | | (multifunction_node) | |
O---O | | O---O | | O---O
| \--------------/ \----------------------/ \-----------/ \----------------------/ |
| |
\--------------------------------------------------------------------------------------------/
*/
template<typename... Args>
class streaming_node;
template<typename... Ports, typename JP, typename StreamFactory>
class streaming_node< tuple<Ports...>, JP, StreamFactory >
: public composite_node < typename internal::streaming_node_traits<JP, StreamFactory, Ports...>::input_tuple,
typename internal::streaming_node_traits<JP, StreamFactory, Ports...>::output_tuple >
, public internal::kernel_executor_helper< StreamFactory, typename internal::streaming_node_traits<JP, StreamFactory, Ports...>::kernel_input_tuple >
{
typedef typename internal::streaming_node_traits<JP, StreamFactory, Ports...>::input_tuple input_tuple;
typedef typename internal::streaming_node_traits<JP, StreamFactory, Ports...>::output_tuple output_tuple;
typedef typename internal::key_from_policy<JP>::type key_type;
protected:
typedef typename StreamFactory::device_type device_type;
typedef typename StreamFactory::kernel_type kernel_type;
private:
typedef internal::streaming_device_with_key<device_type, key_type> device_with_key_type;
typedef composite_node<input_tuple, output_tuple> base_type;
static const size_t NUM_INPUTS = tuple_size<input_tuple>::value;
static const size_t NUM_OUTPUTS = tuple_size<output_tuple>::value;
typedef typename internal::make_sequence<NUM_INPUTS>::type input_sequence;
typedef typename internal::make_sequence<NUM_OUTPUTS>::type output_sequence;
typedef typename internal::streaming_node_traits<JP, StreamFactory, Ports...>::indexer_node_type indexer_node_type;
typedef typename indexer_node_type::output_type indexer_node_output_type;
typedef typename internal::streaming_node_traits<JP, StreamFactory, Ports...>::kernel_input_tuple kernel_input_tuple;
typedef multifunction_node<indexer_node_output_type, kernel_input_tuple> device_selector_node;
typedef multifunction_node<kernel_input_tuple, output_tuple> kernel_multifunction_node;
template <int... S>
typename base_type::input_ports_type get_input_ports( internal::sequence<S...> ) {
return std::tie( internal::input_port<S>( my_indexer_node )... );
}
template <int... S>
typename base_type::output_ports_type get_output_ports( internal::sequence<S...> ) {
return std::tie( internal::output_port<S>( my_kernel_node )... );
}
typename base_type::input_ports_type get_input_ports() {
return get_input_ports( input_sequence() );
}
typename base_type::output_ports_type get_output_ports() {
return get_output_ports( output_sequence() );
}
template <int N>
int make_Nth_edge() {
make_edge( internal::output_port<N>( my_device_selector_node ), internal::input_port<N>( my_join_node ) );
return 0;
}
template <int... S>
void make_edges( internal::sequence<S...> ) {
make_edge( my_indexer_node, my_device_selector_node );
make_edge( my_device_selector_node, my_join_node );
internal::ignore_return_values( make_Nth_edge<S + 1>()... );
make_edge( my_join_node, my_kernel_node );
}
void make_edges() {
make_edges( input_sequence() );
}
class device_selector_base {
public:
virtual void operator()( const indexer_node_output_type &v, typename device_selector_node::output_ports_type &op ) = 0;
virtual device_selector_base *clone( streaming_node &n ) const = 0;
virtual ~device_selector_base() {}
};
template <typename UserFunctor>
class device_selector : public device_selector_base, tbb::internal::no_assign {
public:
device_selector( UserFunctor uf, streaming_node &n, StreamFactory &f )
: my_dispatch_funcs( create_dispatch_funcs( input_sequence() ) )
, my_user_functor( uf ), my_node(n), my_factory( f )
{
my_port_epoches.fill( 0 );
}
void operator()( const indexer_node_output_type &v, typename device_selector_node::output_ports_type &op ) __TBB_override {
(this->*my_dispatch_funcs[ v.tag() ])( my_port_epoches[ v.tag() ], v, op );
__TBB_ASSERT( (tbb::internal::is_same_type<typename internal::key_from_policy<JP>::is_key_matching, std::false_type>::value)
|| my_port_epoches[v.tag()] == 0, "Epoch is changed when key matching is requested" );
}
device_selector_base *clone( streaming_node &n ) const __TBB_override {
return new device_selector( my_user_functor, n, my_factory );
}
private:
typedef void(device_selector<UserFunctor>::*send_and_put_fn_type)(size_t &, const indexer_node_output_type &, typename device_selector_node::output_ports_type &);
typedef std::array < send_and_put_fn_type, NUM_INPUTS > dispatch_funcs_type;
template <int... S>
static dispatch_funcs_type create_dispatch_funcs( internal::sequence<S...> ) {
dispatch_funcs_type dispatch = { { &device_selector<UserFunctor>::send_and_put_impl<S>... } };
return dispatch;
}
template <typename T>
key_type get_key( std::false_type, const T &, size_t &epoch ) {
__TBB_STATIC_ASSERT( (tbb::internal::is_same_type<key_type, size_t>::value), "" );
return epoch++;
}
template <typename T>
key_type get_key( std::true_type, const T &t, size_t &/*epoch*/ ) {
using tbb::flow::key_from_message;
return key_from_message<key_type>( t );
}
template <int N>
void send_and_put_impl( size_t &epoch, const indexer_node_output_type &v, typename device_selector_node::output_ports_type &op ) {
typedef typename tuple_element<N + 1, typename device_selector_node::output_ports_type>::type::output_type elem_type;
elem_type e = internal::cast_to<elem_type>( v );
device_type device = get_device( get_key( typename internal::key_from_policy<JP>::is_key_matching(), e, epoch ), get<0>( op ) );
my_factory.send_data( device, e );
get<N + 1>( op ).try_put( e );
}
template< typename DevicePort >
device_type get_device( key_type key, DevicePort& dp ) {
typename std::unordered_map<typename std::decay<key_type>::type, epoch_desc>::iterator it = my_devices.find( key );
if ( it == my_devices.end() ) {
device_type d = my_user_functor( my_factory );
std::tie( it, std::ignore ) = my_devices.insert( std::make_pair( key, d ) );
bool res = dp.try_put( device_with_key_type( d, key ) );
__TBB_ASSERT_EX( res, NULL );
my_node.notify_new_device( d );
}
epoch_desc &e = it->second;
device_type d = e.my_device;
if ( ++e.my_request_number == NUM_INPUTS ) my_devices.erase( it );
return d;
}
struct epoch_desc {
epoch_desc(device_type d ) : my_device( d ), my_request_number( 0 ) {}
device_type my_device;
size_t my_request_number;
};
std::unordered_map<typename std::decay<key_type>::type, epoch_desc> my_devices;
std::array<size_t, NUM_INPUTS> my_port_epoches;
dispatch_funcs_type my_dispatch_funcs;
UserFunctor my_user_functor;
streaming_node &my_node;
StreamFactory &my_factory;
};
class device_selector_body {
public:
device_selector_body( device_selector_base *d ) : my_device_selector( d ) {}
void operator()( const indexer_node_output_type &v, typename device_selector_node::output_ports_type &op ) {
(*my_device_selector)(v, op);
}
private:
device_selector_base *my_device_selector;
};
class args_storage_base : tbb::internal::no_copy {
public:
typedef typename kernel_multifunction_node::output_ports_type output_ports_type;
virtual void enqueue( kernel_input_tuple &ip, output_ports_type &op, const streaming_node &n ) = 0;
virtual void send( device_type d ) = 0;
virtual args_storage_base *clone() const = 0;
virtual ~args_storage_base () {}
protected:
args_storage_base( const kernel_type& kernel, StreamFactory &f )
: my_kernel( kernel ), my_factory( f )
{}
args_storage_base( const args_storage_base &k )
: my_kernel( k.my_kernel ), my_factory( k.my_factory )
{}
const kernel_type my_kernel;
StreamFactory &my_factory;
};
template <typename... Args>
class args_storage : public args_storage_base {
typedef typename args_storage_base::output_ports_type output_ports_type;
// ---------- Update events helpers ---------- //
template <int N>
bool do_try_put( const kernel_input_tuple& ip, output_ports_type &op ) const {
const auto& t = get<N + 1>( ip );
auto &port = get<N>( op );
return port.try_put( t );
}
template <int... S>
bool do_try_put( const kernel_input_tuple& ip, output_ports_type &op, internal::sequence<S...> ) const {
return internal::or_return_values( do_try_put<S>( ip, op )... );
}
// ------------------------------------------- //
class run_kernel_func : tbb::internal::no_assign {
public:
run_kernel_func( kernel_input_tuple &ip, const streaming_node &node, const args_storage& storage )
: my_kernel_func( ip, node, storage, get<0>(ip).device() ) {}
// It is immpossible to use Args... because a function pointer cannot be casted to a function reference implicitly.
// Allow the compiler to deduce types for function pointers automatically.
template <typename... FnArgs>
void operator()( FnArgs&... args ) {
internal::convert_and_call_impl<FnArgs...>::doit( my_kernel_func, my_kernel_func.my_ip, args... );
}
private:
struct kernel_func : tbb::internal::no_copy {
kernel_input_tuple &my_ip;
const streaming_node &my_node;
const args_storage& my_storage;
device_type my_device;
kernel_func( kernel_input_tuple &ip, const streaming_node &node, const args_storage& storage, device_type device )
: my_ip( ip ), my_node( node ), my_storage( storage ), my_device( device )
{}
template <typename... FnArgs>
void operator()( FnArgs&... args ) {
my_node.enqueue_kernel( my_ip, my_storage.my_factory, my_device, my_storage.my_kernel, args... );
}
} my_kernel_func;
};
template<typename FinalizeFn>
class run_finalize_func : tbb::internal::no_assign {
public:
run_finalize_func( kernel_input_tuple &ip, StreamFactory &factory, FinalizeFn fn )
: my_ip( ip ), my_finalize_func( factory, get<0>(ip).device(), fn ) {}
// It is immpossible to use Args... because a function pointer cannot be casted to a function reference implicitly.
// Allow the compiler to deduce types for function pointers automatically.
template <typename... FnArgs>
void operator()( FnArgs&... args ) {
internal::convert_and_call_impl<FnArgs...>::doit( my_finalize_func, my_ip, args... );
}
private:
kernel_input_tuple &my_ip;
struct finalize_func : tbb::internal::no_assign {
StreamFactory &my_factory;
device_type my_device;
FinalizeFn my_fn;
finalize_func( StreamFactory &factory, device_type device, FinalizeFn fn )
: my_factory(factory), my_device(device), my_fn(fn) {}
template <typename... FnArgs>
void operator()( FnArgs&... args ) {
my_factory.finalize( my_device, my_fn, args... );
}
} my_finalize_func;
};
template<typename FinalizeFn>
static run_finalize_func<FinalizeFn> make_run_finalize_func( kernel_input_tuple &ip, StreamFactory &factory, FinalizeFn fn ) {
return run_finalize_func<FinalizeFn>( ip, factory, fn );
}
class send_func : tbb::internal::no_assign {
public:
send_func( StreamFactory &factory, device_type d )
: my_factory(factory), my_device( d ) {}
template <typename... FnArgs>
void operator()( FnArgs&... args ) {
my_factory.send_data( my_device, args... );
}
private:
StreamFactory &my_factory;
device_type my_device;
};
public:
args_storage( const kernel_type& kernel, StreamFactory &f, Args&&... args )
: args_storage_base( kernel, f )
, my_args_pack( std::forward<Args>(args)... )
{}
args_storage( const args_storage &k ) : args_storage_base( k ), my_args_pack( k.my_args_pack ) {}
args_storage( const args_storage_base &k, Args&&... args ) : args_storage_base( k ), my_args_pack( std::forward<Args>(args)... ) {}
void enqueue( kernel_input_tuple &ip, output_ports_type &op, const streaming_node &n ) __TBB_override {
// Make const qualified args_pack (from non-const)
const args_pack_type& const_args_pack = my_args_pack;
// factory.enqure_kernel() gets
// - 'ip' tuple elements by reference and updates it (and 'ip') with dependencies
// - arguments (from my_args_pack) by const-reference via const_args_pack
tbb::internal::call( run_kernel_func( ip, n, *this ), const_args_pack );
if (! do_try_put( ip, op, input_sequence() ) ) {
graph& g = n.my_graph;
// No one message was passed to successors so set a callback to extend the graph lifetime until the kernel completion.
g.increment_wait_count();
// factory.finalize() gets
// - 'ip' tuple elements by reference, so 'ip' might be changed
// - arguments (from my_args_pack) by const-reference via const_args_pack
tbb::internal::call( make_run_finalize_func(ip, this->my_factory, [&g] {
g.decrement_wait_count();
}), const_args_pack );
}
}
void send( device_type d ) __TBB_override {
// factory.send() gets arguments by reference and updates these arguments with dependencies
// (it gets but usually ignores port_ref-s)
tbb::internal::call( send_func( this->my_factory, d ), my_args_pack );
}
args_storage_base *clone() const __TBB_override {
// Create new args_storage with copying constructor.
return new args_storage<Args...>( *this );
}
private:
typedef tbb::internal::stored_pack<Args...> args_pack_type;
args_pack_type my_args_pack;
};
// Body for kernel_multifunction_node.
class kernel_body : tbb::internal::no_assign {
public:
kernel_body( const streaming_node &node ) : my_node( node ) {}
void operator()( kernel_input_tuple ip, typename args_storage_base::output_ports_type &op ) {
__TBB_ASSERT( (my_node.my_args_storage != NULL), "No arguments storage" );
// 'ip' is passed by value to create local copy for updating inside enqueue_kernel()
my_node.my_args_storage->enqueue( ip, op, my_node );
}
private:
const streaming_node &my_node;
};
template <typename T, typename U = typename internal::is_port_ref<T>::type >
struct wrap_to_async {
typedef T type; // Keep port_ref as it is
};
template <typename T>
struct wrap_to_async<T, std::false_type> {
typedef typename StreamFactory::template async_msg_type< typename tbb::internal::strip<T>::type > type;
};
template <typename... Args>
args_storage_base *make_args_storage(const args_storage_base& storage, Args&&... args) const {
// In this variadic template convert all simple types 'T' into 'async_msg_type<T>'
return new args_storage<Args...>(storage, std::forward<Args>(args)...);
}
void notify_new_device( device_type d ) {
my_args_storage->send( d );
}
template <typename ...Args>
void enqueue_kernel( kernel_input_tuple& ip, StreamFactory& factory, device_type device, const kernel_type& kernel, Args&... args ) const {
this->enqueue_kernel_impl( ip, factory, device, kernel, args... );
}
public:
template <typename DeviceSelector>
streaming_node( graph &g, const kernel_type& kernel, DeviceSelector d, StreamFactory &f )
: base_type( g )
, my_indexer_node( g )
, my_device_selector( new device_selector<DeviceSelector>( d, *this, f ) )
, my_device_selector_node( g, serial, device_selector_body( my_device_selector ) )
, my_join_node( g )
, my_kernel_node( g, serial, kernel_body( *this ) )
// By default, streaming_node maps all its ports to the kernel arguments on a one-to-one basis.
, my_args_storage( make_args_storage( args_storage<>(kernel, f), port_ref<0, NUM_INPUTS - 1>() ) )
{
base_type::set_external_ports( get_input_ports(), get_output_ports() );
make_edges();
}
streaming_node( const streaming_node &node )
: base_type( node.my_graph )
, my_indexer_node( node.my_indexer_node )
, my_device_selector( node.my_device_selector->clone( *this ) )
, my_device_selector_node( node.my_graph, serial, device_selector_body( my_device_selector ) )
, my_join_node( node.my_join_node )
, my_kernel_node( node.my_graph, serial, kernel_body( *this ) )
, my_args_storage( node.my_args_storage->clone() )
{
base_type::set_external_ports( get_input_ports(), get_output_ports() );
make_edges();
}
streaming_node( streaming_node &&node )
: base_type( node.my_graph )
, my_indexer_node( std::move( node.my_indexer_node ) )
, my_device_selector( node.my_device_selector->clone(*this) )
, my_device_selector_node( node.my_graph, serial, device_selector_body( my_device_selector ) )
, my_join_node( std::move( node.my_join_node ) )
, my_kernel_node( node.my_graph, serial, kernel_body( *this ) )
, my_args_storage( node.my_args_storage )
{
base_type::set_external_ports( get_input_ports(), get_output_ports() );
make_edges();
// Set moving node mappers to NULL to prevent double deallocation.
node.my_args_storage = NULL;
}
~streaming_node() {
if ( my_args_storage ) delete my_args_storage;
if ( my_device_selector ) delete my_device_selector;
}
template <typename... Args>
void set_args( Args&&... args ) {
// Copy the base class of args_storage and create new storage for "Args...".
args_storage_base * const new_args_storage = make_args_storage( *my_args_storage, typename wrap_to_async<Args>::type(std::forward<Args>(args))...);
delete my_args_storage;
my_args_storage = new_args_storage;
}
protected:
void reset_node( reset_flags = rf_reset_protocol ) __TBB_override { __TBB_ASSERT( false, "Not implemented yet" ); }
private:
indexer_node_type my_indexer_node;
device_selector_base *my_device_selector;
device_selector_node my_device_selector_node;
join_node<kernel_input_tuple, JP> my_join_node;
kernel_multifunction_node my_kernel_node;
args_storage_base *my_args_storage;
};
#endif // __TBB_PREVIEW_STREAMING_NODE
#endif // __TBB_flow_graph_streaming_H

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
// a hash table buffer that can expand, and can support as many deletions as // a hash table buffer that can expand, and can support as many deletions as

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#ifndef _FGT_GRAPH_TRACE_IMPL_H #ifndef _FGT_GRAPH_TRACE_IMPL_H

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#ifndef __TBB__flow_graph_types_impl_H #ifndef __TBB__flow_graph_types_impl_H
@ -451,12 +451,12 @@ public:
explicit Wrapper( const T& other ) : value_space(other) { } explicit Wrapper( const T& other ) : value_space(other) { }
explicit Wrapper(const Wrapper& other) : value_space(other.value_space) { } explicit Wrapper(const Wrapper& other) : value_space(other.value_space) { }
/*override*/void CopyTo(void* newSpace) const { void CopyTo(void* newSpace) const __TBB_override {
_unwind_space guard((pointer_type)newSpace); _unwind_space guard((pointer_type)newSpace);
(void) new(newSpace) Wrapper(value_space); (void) new(newSpace) Wrapper(value_space);
guard.space = NULL; guard.space = NULL;
} }
/*override*/~Wrapper() { } ~Wrapper() { }
}; };
// specialization for array objects // specialization for array objects
@ -519,11 +519,11 @@ public:
guard.space = NULL; guard.space = NULL;
} }
/*override*/void CopyTo(void* newSpace) const { void CopyTo(void* newSpace) const __TBB_override {
(void) new(newSpace) Wrapper(*this); // exceptions handled in copy constructor (void) new(newSpace) Wrapper(*this); // exceptions handled in copy constructor
} }
/*override*/~Wrapper() { ~Wrapper() {
// have to destroy explicitly in reverse order // have to destroy explicitly in reverse order
pointer_type vp = reinterpret_cast<pointer_type>(&value_space); pointer_type vp = reinterpret_cast<pointer_type>(&value_space);
for(size_t i = N; i > 0 ; --i ) vp[i-1].~value_type(); for(size_t i = N; i > 0 ; --i ) vp[i-1].~value_type();
@ -706,6 +706,8 @@ const V& cast_to(T const &t) { return t.template cast_to<V>(); }
template<typename V, typename T> template<typename V, typename T>
bool is_a(T const &t) { return t.template is_a<V>(); } bool is_a(T const &t) { return t.template is_a<V>(); }
enum op_stat { WAIT = 0, SUCCEEDED, FAILED };
} // namespace internal } // namespace internal
#endif /* __TBB__flow_graph_types_impl_H */ #endif /* __TBB__flow_graph_types_impl_H */

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#ifndef __TBB_mutex_padding_H #ifndef __TBB_mutex_padding_H

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#ifndef __TBB_range_iterator_H #ifndef __TBB_range_iterator_H

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
// must be included outside namespaces. // must be included outside namespaces.
@ -47,6 +47,7 @@ public:
} }
bool operator()(const Key& key1, const Key& key2) const { bool operator()(const Key& key1, const Key& key2) const {
// TODO: get rid of the result invertion
return (!my_key_compare_object(key1, key2)); return (!my_key_compare_object(key1, key2));
} }

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
TBB_STRING_RESOURCE(FLOW_BROADCAST_NODE, "broadcast_node") TBB_STRING_RESOURCE(FLOW_BROADCAST_NODE, "broadcast_node")

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#ifndef __TBB_tbb_windef_H #ifndef __TBB_tbb_windef_H

View file

@ -1,27 +1,28 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#ifndef __TBB_template_helpers_H #ifndef __TBB_template_helpers_H
#define __TBB_template_helpers_H #define __TBB_template_helpers_H
#include <utility> #include <utility>
#include <cstddef>
namespace tbb { namespace internal { namespace tbb { namespace internal {
@ -47,10 +48,10 @@ template<typename T> struct strip<volatile T&&> { typedef T type; };
template<typename T> struct strip<const volatile T&&> { typedef T type; }; template<typename T> struct strip<const volatile T&&> { typedef T type; };
#endif #endif
//! Specialization for arrays converts to a corresponding pointer //! Specialization for arrays converts to a corresponding pointer
template<typename T, size_t N> struct strip<T(&)[N]> { typedef T* type; }; template<typename T, std::size_t N> struct strip<T(&)[N]> { typedef T* type; };
template<typename T, size_t N> struct strip<const T(&)[N]> { typedef const T* type; }; template<typename T, std::size_t N> struct strip<const T(&)[N]> { typedef const T* type; };
template<typename T, size_t N> struct strip<volatile T(&)[N]> { typedef volatile T* type; }; template<typename T, std::size_t N> struct strip<volatile T(&)[N]> { typedef volatile T* type; };
template<typename T, size_t N> struct strip<const volatile T(&)[N]> { typedef const volatile T* type; }; template<typename T, std::size_t N> struct strip<const volatile T(&)[N]> { typedef const volatile T* type; };
//! Detects whether two given types are the same //! Detects whether two given types are the same
template<class U, class V> struct is_same_type { static const bool value = false; }; template<class U, class V> struct is_same_type { static const bool value = false; };
@ -59,6 +60,11 @@ template<class W> struct is_same_type<W,W> { static const bool value =
template<typename T> struct is_ref { static const bool value = false; }; template<typename T> struct is_ref { static const bool value = false; };
template<typename U> struct is_ref<U&> { static const bool value = true; }; template<typename U> struct is_ref<U&> { static const bool value = true; };
#if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT
//! std::void_t internal implementation (to avoid GCC < 4.7 "template aliases" absence)
template<typename...> struct void_t { typedef void type; };
#endif
#if __TBB_CPP11_RVALUE_REF_PRESENT && __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT #if __TBB_CPP11_RVALUE_REF_PRESENT && __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT
//! Allows to store a function parameter pack as a variable and later pass it to another function //! Allows to store a function parameter pack as a variable and later pass it to another function
@ -107,6 +113,13 @@ struct stored_pack<T, Types...> : stored_pack<Types...>
template< typename Ret, typename F, typename Pack > friend Ret call_and_return( F&& f, Pack&& p ); template< typename Ret, typename F, typename Pack > friend Ret call_and_return( F&& f, Pack&& p );
protected: protected:
template< typename Ret, typename F, typename... Preceding >
static Ret call( F&& f, pack_type& pack, Preceding&&... params ) {
return pack_remainder::template call<Ret>(
std::forward<F>(f), static_cast<pack_remainder&>(pack),
std::forward<Preceding>(params)... , pack.leftmost_value
);
}
template< typename Ret, typename F, typename... Preceding > template< typename Ret, typename F, typename... Preceding >
static Ret call( F&& f, const pack_type& pack, Preceding&&... params ) { static Ret call( F&& f, const pack_type& pack, Preceding&&... params ) {
return pack_remainder::template call<Ret>( return pack_remainder::template call<Ret>(

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#ifndef __TBB__x86_eliding_mutex_impl_H #ifndef __TBB__x86_eliding_mutex_impl_H

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#ifndef __TBB__x86_rtm_rw_mutex_impl_H #ifndef __TBB__x86_rtm_rw_mutex_impl_H

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
/* /*
@ -83,7 +83,7 @@ static inline int32_t __TBB_machine_cmpswp4(volatile void *ptr, int32_t value, i
"it eq\n" "it eq\n"
"strexeq %0, %5, [%3]\n" "strexeq %0, %5, [%3]\n"
: "=&r" (res), "=&r" (oldval), "+Qo" (*(volatile int32_t*)ptr) : "=&r" (res), "=&r" (oldval), "+Qo" (*(volatile int32_t*)ptr)
: "r" ((int32_t *)ptr), "Ir" (comparand), "r" (value) : "r" ((volatile int32_t *)ptr), "Ir" (comparand), "r" (value)
: "cc"); : "cc");
} while (res); } while (res);
@ -116,7 +116,7 @@ static inline int64_t __TBB_machine_cmpswp8(volatile void *ptr, int64_t value, i
"it eq\n" "it eq\n"
"strexdeq %0, %5, %H5, [%3]" "strexdeq %0, %5, %H5, [%3]"
: "=&r" (res), "=&r" (oldval), "+Qo" (*(volatile int64_t*)ptr) : "=&r" (res), "=&r" (oldval), "+Qo" (*(volatile int64_t*)ptr)
: "r" ((int64_t *)ptr), "r" (comparand), "r" (value) : "r" ((volatile int64_t *)ptr), "r" (comparand), "r" (value)
: "cc"); : "cc");
} while (res); } while (res);
@ -139,7 +139,7 @@ static inline int32_t __TBB_machine_fetchadd4(volatile void* ptr, int32_t addend
" cmp %1, #0\n" " cmp %1, #0\n"
" bne 1b\n" " bne 1b\n"
: "=&r" (result), "=&r" (tmp), "+Qo" (*(volatile int32_t*)ptr), "=&r"(tmp2) : "=&r" (result), "=&r" (tmp), "+Qo" (*(volatile int32_t*)ptr), "=&r"(tmp2)
: "r" ((int32_t *)ptr), "Ir" (addend) : "r" ((volatile int32_t *)ptr), "Ir" (addend)
: "cc"); : "cc");
__TBB_full_memory_fence(); __TBB_full_memory_fence();
@ -162,7 +162,7 @@ static inline int64_t __TBB_machine_fetchadd8(volatile void *ptr, int64_t addend
" cmp %1, #0\n" " cmp %1, #0\n"
" bne 1b" " bne 1b"
: "=&r" (result), "=&r" (tmp), "+Qo" (*(volatile int64_t*)ptr), "=&r"(tmp2) : "=&r" (result), "=&r" (tmp), "+Qo" (*(volatile int64_t*)ptr), "=&r"(tmp2)
: "r" ((int64_t *)ptr), "r" (addend) : "r" ((volatile int64_t *)ptr), "r" (addend)
: "cc"); : "cc");

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#if !defined(__TBB_machine_H) || defined(__TBB_machine_gcc_generic_H) #if !defined(__TBB_machine_H) || defined(__TBB_machine_gcc_generic_H)

View file

@ -1,27 +1,27 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#ifndef __TBB_machine_gcc_ia32_common_H #ifndef __TBB_machine_gcc_ia32_common_H
#define __TBB_machine_gcc_ia32_common_H #define __TBB_machine_gcc_ia32_common_H
//TODO: Add a higher-level function, e.g. tbb::interal::log2(), into tbb_stddef.h, which //TODO: Add a higher-level function, e.g. tbb::internal::log2(), into tbb_stddef.h, which
//uses __TBB_Log2 and contains the assert and remove the assert from here and all other //uses __TBB_Log2 and contains the assert and remove the assert from here and all other
//platform-specific headers. //platform-specific headers.
//TODO: Check if use of gcc intrinsic gives a better chance for cross call optimizations //TODO: Check if use of gcc intrinsic gives a better chance for cross call optimizations

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#if !defined(__TBB_machine_H) || defined(__TBB_machine_gcc_itsx_H) #if !defined(__TBB_machine_H) || defined(__TBB_machine_gcc_itsx_H)

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
// TODO: revise by comparing with mac_ppc.h // TODO: revise by comparing with mac_ppc.h

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#if !defined(__TBB_machine_H) || defined(__TBB_machine_icc_generic_H) #if !defined(__TBB_machine_H) || defined(__TBB_machine_icc_generic_H)

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#ifndef __TBB_machine_H #ifndef __TBB_machine_H

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#if !defined(__TBB_machine_H) || defined(__TBB_machine_linux_ia32_H) #if !defined(__TBB_machine_H) || defined(__TBB_machine_linux_ia32_H)

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#if !defined(__TBB_machine_H) || defined(__TBB_machine_linux_ia64_H) #if !defined(__TBB_machine_H) || defined(__TBB_machine_linux_ia64_H)

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#if !defined(__TBB_machine_H) || defined(__TBB_machine_linux_intel64_H) #if !defined(__TBB_machine_H) || defined(__TBB_machine_linux_intel64_H)

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#if !defined(__TBB_machine_H) || defined(__TBB_machine_gcc_power_H) #if !defined(__TBB_machine_H) || defined(__TBB_machine_gcc_power_H)

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#if !defined(__TBB_machine_H) || defined(__TBB_machine_macos_common_H) #if !defined(__TBB_machine_H) || defined(__TBB_machine_macos_common_H)
@ -54,7 +54,7 @@ static inline int __TBB_macos_available_cpu() {
static inline int64_t __TBB_machine_cmpswp8_OsX(volatile void *ptr, int64_t value, int64_t comparand) static inline int64_t __TBB_machine_cmpswp8_OsX(volatile void *ptr, int64_t value, int64_t comparand)
{ {
__TBB_ASSERT( tbb::internal::is_aligned(ptr,8), "address not properly aligned for OS X* atomics"); __TBB_ASSERT( tbb::internal::is_aligned(ptr,8), "address not properly aligned for macOS* atomics");
int64_t* address = (int64_t*)ptr; int64_t* address = (int64_t*)ptr;
while( !OSAtomicCompareAndSwap64Barrier(comparand, value, address) ){ while( !OSAtomicCompareAndSwap64Barrier(comparand, value, address) ){
#if __TBB_WORDSIZE==8 #if __TBB_WORDSIZE==8
@ -99,7 +99,7 @@ static inline int64_t __TBB_machine_cmpswp8_OsX(volatile void *ptr, int64_t valu
static inline int32_t __TBB_machine_cmpswp4(volatile void *ptr, int32_t value, int32_t comparand) static inline int32_t __TBB_machine_cmpswp4(volatile void *ptr, int32_t value, int32_t comparand)
{ {
__TBB_ASSERT( tbb::internal::is_aligned(ptr,4), "address not properly aligned for OS X* atomics"); __TBB_ASSERT( tbb::internal::is_aligned(ptr,4), "address not properly aligned for macOS atomics");
int32_t* address = (int32_t*)ptr; int32_t* address = (int32_t*)ptr;
while( !OSAtomicCompareAndSwap32Barrier(comparand, value, address) ){ while( !OSAtomicCompareAndSwap32Barrier(comparand, value, address) ){
int32_t snapshot = *address; int32_t snapshot = *address;
@ -110,13 +110,13 @@ static inline int32_t __TBB_machine_cmpswp4(volatile void *ptr, int32_t value, i
static inline int32_t __TBB_machine_fetchadd4(volatile void *ptr, int32_t addend) static inline int32_t __TBB_machine_fetchadd4(volatile void *ptr, int32_t addend)
{ {
__TBB_ASSERT( tbb::internal::is_aligned(ptr,4), "address not properly aligned for OS X* atomics"); __TBB_ASSERT( tbb::internal::is_aligned(ptr,4), "address not properly aligned for macOS atomics");
return OSAtomicAdd32Barrier(addend, (int32_t*)ptr) - addend; return OSAtomicAdd32Barrier(addend, (int32_t*)ptr) - addend;
} }
static inline int64_t __TBB_machine_fetchadd8(volatile void *ptr, int64_t addend) static inline int64_t __TBB_machine_fetchadd8(volatile void *ptr, int64_t addend)
{ {
__TBB_ASSERT( tbb::internal::is_aligned(ptr,8), "address not properly aligned for OS X* atomics"); __TBB_ASSERT( tbb::internal::is_aligned(ptr,8), "address not properly aligned for macOS atomics");
return OSAtomicAdd64Barrier(addend, (int64_t*)ptr) - addend; return OSAtomicAdd64Barrier(addend, (int64_t*)ptr) - addend;
} }

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#ifndef __TBB_mic_common_H #ifndef __TBB_mic_common_H

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#if !defined(__TBB_machine_H) || defined(__TBB_msvc_armv7_H) #if !defined(__TBB_machine_H) || defined(__TBB_msvc_armv7_H)

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#if !defined(__TBB_machine_H) || defined(__TBB_machine_msvc_ia32_common_H) #if !defined(__TBB_machine_H) || defined(__TBB_machine_msvc_ia32_common_H)

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#ifndef __TBB_machine_windows_api_H #ifndef __TBB_machine_windows_api_H
@ -23,18 +23,8 @@
#if _WIN32 || _WIN64 #if _WIN32 || _WIN64
#if _XBOX
#define NONET
#define NOD3D
#include <xtl.h>
#else // Assume "usual" Windows
#include <windows.h> #include <windows.h>
#endif // _XBOX
#if _WIN32_WINNT < 0x0600 #if _WIN32_WINNT < 0x0600
// The following Windows API function is declared explicitly; // The following Windows API function is declared explicitly;
// otherwise it fails to compile by VS2005. // otherwise it fails to compile by VS2005.

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#if !defined(__TBB_machine_H) || defined(__TBB_machine_windows_ia32_H) #if !defined(__TBB_machine_H) || defined(__TBB_machine_windows_ia32_H)

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#if !defined(__TBB_machine_H) || defined(__TBB_machine_windows_intel64_H) #if !defined(__TBB_machine_H) || defined(__TBB_machine_windows_intel64_H)

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#ifndef __TBB_memory_pool_H #ifndef __TBB_memory_pool_H
@ -107,7 +107,7 @@ public:
typedef memory_pool_allocator<U, P> other; typedef memory_pool_allocator<U, P> other;
}; };
memory_pool_allocator(pool_type &pool) throw() : my_pool(&pool) {} explicit memory_pool_allocator(pool_type &pool) throw() : my_pool(&pool) {}
memory_pool_allocator(const memory_pool_allocator& src) throw() : my_pool(src.my_pool) {} memory_pool_allocator(const memory_pool_allocator& src) throw() : my_pool(src.my_pool) {}
template<typename U> template<typename U>
memory_pool_allocator(const memory_pool_allocator<U,P>& src) throw() : my_pool(src.my_pool) {} memory_pool_allocator(const memory_pool_allocator<U,P>& src) throw() : my_pool(src.my_pool) {}
@ -165,7 +165,7 @@ public:
typedef memory_pool_allocator<U, P> other; typedef memory_pool_allocator<U, P> other;
}; };
memory_pool_allocator( pool_type &pool) throw() : my_pool(&pool) {} explicit memory_pool_allocator( pool_type &pool) throw() : my_pool(&pool) {}
memory_pool_allocator( const memory_pool_allocator& src) throw() : my_pool(src.my_pool) {} memory_pool_allocator( const memory_pool_allocator& src) throw() : my_pool(src.my_pool) {}
template<typename U> template<typename U>
memory_pool_allocator(const memory_pool_allocator<U,P>& src) throw() : my_pool(src.my_pool) {} memory_pool_allocator(const memory_pool_allocator<U,P>& src) throw() : my_pool(src.my_pool) {}
@ -196,7 +196,7 @@ class memory_pool : public internal::pool_base {
public: public:
//! construct pool with underlying allocator //! construct pool with underlying allocator
memory_pool(const Alloc &src = Alloc()); explicit memory_pool(const Alloc &src = Alloc());
//! destroy pool //! destroy pool
~memory_pool() { destroy(); } // call the callbacks first and destroy my_alloc latter ~memory_pool() { destroy(); } // call the callbacks first and destroy my_alloc latter

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#ifndef __TBB_mutex_H #ifndef __TBB_mutex_H
@ -34,9 +34,8 @@
namespace tbb { namespace tbb {
//! Wrapper around the platform's native reader-writer lock. //! Wrapper around the platform's native lock.
/** For testing purposes only. /** @ingroup synchronization */
@ingroup synchronization */
class mutex : internal::mutex_copy_deprecated_and_disabled { class mutex : internal::mutex_copy_deprecated_and_disabled {
public: public:
//! Construct unacquired mutex. //! Construct unacquired mutex.

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#ifndef __TBB_null_mutex_H #ifndef __TBB_null_mutex_H

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#ifndef __TBB_null_rw_mutex_H #ifndef __TBB_null_rw_mutex_H

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#ifndef __TBB_parallel_do_H #ifndef __TBB_parallel_do_H
@ -28,31 +28,37 @@
#include <iterator> #include <iterator>
namespace tbb { namespace tbb {
namespace interface9 {
//! @cond INTERNAL //! @cond INTERNAL
namespace internal { namespace internal {
template<typename Body, typename Item> class parallel_do_feeder_impl; template<typename Body, typename Item> class parallel_do_feeder_impl;
template<typename Body> class do_group_task;
} // namespace internal } // namespace internal
//! @endcond //! @endcond
//! Class the user supplied algorithm body uses to add new tasks //! Class the user supplied algorithm body uses to add new tasks
/** \param Item Work item type **/ /** \param Item Work item type **/
template<typename Item> template<typename Item>
class parallel_do_feeder: internal::no_copy class parallel_do_feeder: ::tbb::internal::no_copy
{ {
parallel_do_feeder() {} parallel_do_feeder() {}
virtual ~parallel_do_feeder () {} virtual ~parallel_do_feeder () {}
virtual void internal_add( const Item& item ) = 0; virtual void internal_add_copy( const Item& item ) = 0;
#if __TBB_CPP11_RVALUE_REF_PRESENT
virtual void internal_add_move( Item&& item ) = 0;
#endif
template<typename Body_, typename Item_> friend class internal::parallel_do_feeder_impl; template<typename Body_, typename Item_> friend class internal::parallel_do_feeder_impl;
public: public:
//! Add a work item to a running parallel_do. //! Add a work item to a running parallel_do.
// TODO: add an overload for r-value reference void add( const Item& item ) {internal_add_copy(item);}
void add( const Item& item ) {internal_add(item);} #if __TBB_CPP11_RVALUE_REF_PRESENT
}; void add( Item&& item ) {internal_add_move(std::move(item));}
#endif
};
//! @cond INTERNAL //! @cond INTERNAL
namespace internal { namespace internal {
template<typename Body> class do_group_task;
//! For internal use only. //! For internal use only.
/** Selects one of the two possible forms of function call member operator. /** Selects one of the two possible forms of function call member operator.
@ingroup algorithms **/ @ingroup algorithms **/
@ -61,19 +67,26 @@ namespace internal {
{ {
typedef parallel_do_feeder<Item> Feeder; typedef parallel_do_feeder<Item> Feeder;
template<typename A1, typename A2, typename CvItem > template<typename A1, typename A2, typename CvItem >
static void internal_call( const Body& obj, A1& arg1, A2&, void (Body::*)(CvItem) const ) { static void internal_call( const Body& obj, __TBB_FORWARDING_REF(A1) arg1, A2&, void (Body::*)(CvItem) const ) {
obj(tbb::internal::forward<A1>(arg1));
}
template<typename A1, typename A2, typename CvItem >
static void internal_call( const Body& obj, __TBB_FORWARDING_REF(A1) arg1, A2& arg2, void (Body::*)(CvItem, parallel_do_feeder<Item>&) const ) {
obj(tbb::internal::forward<A1>(arg1), arg2);
}
template<typename A1, typename A2, typename CvItem >
static void internal_call( const Body& obj, __TBB_FORWARDING_REF(A1) arg1, A2&, void (Body::*)(CvItem&) const ) {
obj(arg1); obj(arg1);
} }
template<typename A1, typename A2, typename CvItem > template<typename A1, typename A2, typename CvItem >
static void internal_call( const Body& obj, A1& arg1, A2& arg2, void (Body::*)(CvItem, parallel_do_feeder<Item>&) const ) { static void internal_call( const Body& obj, __TBB_FORWARDING_REF(A1) arg1, A2& arg2, void (Body::*)(CvItem&, parallel_do_feeder<Item>&) const ) {
obj(arg1, arg2); obj(arg1, arg2);
} }
public: public:
template<typename A1, typename A2 > template<typename A1, typename A2>
static void call( const Body& obj, A1& arg1, A2& arg2 ) static void call( const Body& obj, __TBB_FORWARDING_REF(A1) arg1, A2& arg2 )
{ {
internal_call( obj, arg1, arg2, &Body::operator() ); internal_call( obj, tbb::internal::forward<A1>(arg1), arg2, &Body::operator() );
} }
}; };
@ -92,11 +105,15 @@ namespace internal {
my_value(value), my_feeder(feeder) my_value(value), my_feeder(feeder)
{} {}
/*override*/ #if __TBB_CPP11_RVALUE_REF_PRESENT
task* execute() do_iteration_task( Item&& value, feeder_type& feeder ) :
my_value(std::move(value)), my_feeder(feeder)
{}
#endif
task* execute() __TBB_override
{ {
// TODO: use move semantics for my_value parallel_do_operator_selector<Body, Item>::call(*my_feeder.my_body, tbb::internal::move(my_value), my_feeder);
parallel_do_operator_selector<Body, Item>::call(*my_feeder.my_body, my_value, my_feeder);
return NULL; return NULL;
} }
@ -115,8 +132,7 @@ namespace internal {
my_iter(iter), my_feeder(feeder) my_iter(iter), my_feeder(feeder)
{} {}
/*override*/ task* execute() __TBB_override
task* execute()
{ {
parallel_do_operator_selector<Body, Item>::call(*my_feeder.my_body, *my_iter, my_feeder); parallel_do_operator_selector<Body, Item>::call(*my_feeder.my_body, *my_iter, my_feeder);
return NULL; return NULL;
@ -133,15 +149,37 @@ namespace internal {
template<class Body, typename Item> template<class Body, typename Item>
class parallel_do_feeder_impl : public parallel_do_feeder<Item> class parallel_do_feeder_impl : public parallel_do_feeder<Item>
{ {
/*override*/ #if __TBB_CPP11_RVALUE_REF_PRESENT
void internal_add( const Item& item ) //Avoiding use of copy constructor in a virtual method if the type does not support it
void internal_add_copy_impl(std::true_type, const Item& item) {
typedef do_iteration_task<Body, Item> iteration_type;
iteration_type& t = *new (task::allocate_additional_child_of(*my_barrier)) iteration_type(item, *this);
task::spawn(t);
}
void internal_add_copy_impl(std::false_type, const Item&) {
__TBB_ASSERT(false, "Overloading for r-value reference doesn't work or it's not movable and not copyable object");
}
void internal_add_copy( const Item& item ) __TBB_override
{
#if __TBB_CPP11_IS_COPY_CONSTRUCTIBLE_PRESENT
internal_add_copy_impl(typename std::is_copy_constructible<Item>::type(), item);
#else
internal_add_copy_impl(std::true_type(), item);
#endif
}
void internal_add_move( Item&& item ) __TBB_override
{ {
typedef do_iteration_task<Body, Item> iteration_type; typedef do_iteration_task<Body, Item> iteration_type;
iteration_type& t = *new (task::allocate_additional_child_of(*my_barrier)) iteration_type(std::move(item), *this);
iteration_type& t = *new (task::allocate_additional_child_of(*my_barrier)) iteration_type(item, *this); task::spawn(t);
t.spawn( t );
} }
#else /* ! __TBB_CPP11_RVALUE_REF_PRESENT */
void internal_add_copy(const Item& item) __TBB_override {
typedef do_iteration_task<Body, Item> iteration_type;
iteration_type& t = *new (task::allocate_additional_child_of(*my_barrier)) iteration_type(item, *this);
task::spawn(t);
}
#endif /* __TBB_CPP11_RVALUE_REF_PRESENT */
public: public:
const Body* my_body; const Body* my_body;
empty_task* my_barrier; empty_task* my_barrier;
@ -186,7 +224,7 @@ namespace internal {
: my_feeder(feeder), my_first(first), my_size(size) : my_feeder(feeder), my_first(first), my_size(size)
{} {}
/*override*/ task* execute() task* execute() __TBB_override
{ {
typedef do_iteration_task_iter<Iterator, Body, Item> iteration_type; typedef do_iteration_task_iter<Iterator, Body, Item> iteration_type;
__TBB_ASSERT( my_size>0, NULL ); __TBB_ASSERT( my_size>0, NULL );
@ -223,15 +261,20 @@ namespace internal {
: my_feeder(feeder), my_size(0) : my_feeder(feeder), my_size(0)
{} {}
/*override*/ task* execute() task* execute() __TBB_override
{ {
typedef do_iteration_task_iter<Item*, Body, Item> iteration_type; #if __TBB_CPP11_RVALUE_REF_PRESENT
typedef std::move_iterator<Item*> Item_iterator;
#else
typedef Item* Item_iterator;
#endif
typedef do_iteration_task_iter<Item_iterator, Body, Item> iteration_type;
__TBB_ASSERT( my_size>0, NULL ); __TBB_ASSERT( my_size>0, NULL );
task_list list; task_list list;
task* t; task* t;
size_t k=0; size_t k=0;
for(;;) { for(;;) {
t = new( allocate_child() ) iteration_type( my_arg.begin() + k, my_feeder ); t = new( allocate_child() ) iteration_type( Item_iterator(my_arg.begin() + k), my_feeder );
if( ++k==my_size ) break; if( ++k==my_size ) break;
list.push_back(*t); list.push_back(*t);
} }
@ -277,7 +320,7 @@ namespace internal {
templates. Besides template functions would always fall back to the least templates. Besides template functions would always fall back to the least
efficient variant (the one for input iterators) in case of iterators having efficient variant (the one for input iterators) in case of iterators having
custom tags derived from basic ones. */ custom tags derived from basic ones. */
/*override*/ task* execute() task* execute() __TBB_override
{ {
typedef typename std::iterator_traits<Iterator>::iterator_category iterator_tag; typedef typename std::iterator_traits<Iterator>::iterator_category iterator_tag;
return run( (iterator_tag*)NULL ); return run( (iterator_tag*)NULL );
@ -293,7 +336,7 @@ namespace internal {
block_type& t = *new( allocate_additional_child_of(*my_feeder.my_barrier) ) block_type(my_feeder); block_type& t = *new( allocate_additional_child_of(*my_feeder.my_barrier) ) block_type(my_feeder);
size_t k=0; size_t k=0;
while( !(my_first == my_last) ) { while( !(my_first == my_last) ) {
// TODO: move *my_first // Move semantics are automatically used when supported by the iterator
new (t.my_arg.begin() + k) Item(*my_first); new (t.my_arg.begin() + k) Item(*my_first);
++my_first; ++my_first;
if( ++k==block_type::max_arg_size ) { if( ++k==block_type::max_arg_size ) {
@ -396,13 +439,13 @@ namespace internal {
void select_parallel_do( Iterator first, Iterator last, const Body& body, void (Body::*)(Item) const void select_parallel_do( Iterator first, Iterator last, const Body& body, void (Body::*)(Item) const
#if __TBB_TASK_GROUP_CONTEXT #if __TBB_TASK_GROUP_CONTEXT
, task_group_context& context , task_group_context& context
#endif // __TBB_TASK_GROUP_CONTEXT #endif
) )
{ {
run_parallel_do<Iterator, Body, typename strip<Item>::type>( first, last, body run_parallel_do<Iterator, Body, typename ::tbb::internal::strip<Item>::type>( first, last, body
#if __TBB_TASK_GROUP_CONTEXT #if __TBB_TASK_GROUP_CONTEXT
, context , context
#endif // __TBB_TASK_GROUP_CONTEXT #endif
); );
} }
@ -413,20 +456,20 @@ namespace internal {
void select_parallel_do( Iterator first, Iterator last, const Body& body, void (Body::*)(Item, parallel_do_feeder<_Item>&) const void select_parallel_do( Iterator first, Iterator last, const Body& body, void (Body::*)(Item, parallel_do_feeder<_Item>&) const
#if __TBB_TASK_GROUP_CONTEXT #if __TBB_TASK_GROUP_CONTEXT
, task_group_context& context , task_group_context& context
#endif // __TBB_TASK_GROUP_CONTEXT #endif
) )
{ {
run_parallel_do<Iterator, Body, typename strip<Item>::type>( first, last, body run_parallel_do<Iterator, Body, typename ::tbb::internal::strip<Item>::type>( first, last, body
#if __TBB_TASK_GROUP_CONTEXT #if __TBB_TASK_GROUP_CONTEXT
, context , context
#endif // __TBB_TASK_GROUP_CONTEXT #endif
); );
} }
} // namespace internal } // namespace internal
} // namespace interface9
//! @endcond //! @endcond
/** \page parallel_do_body_req Requirements on parallel_do body /** \page parallel_do_body_req Requirements on parallel_do body
Class \c Body implementing the concept of parallel_do body must define: Class \c Body implementing the concept of parallel_do body must define:
- \code - \code
@ -458,11 +501,11 @@ void parallel_do( Iterator first, Iterator last, const Body& body )
return; return;
#if __TBB_TASK_GROUP_CONTEXT #if __TBB_TASK_GROUP_CONTEXT
task_group_context context; task_group_context context;
#endif // __TBB_TASK_GROUP_CONTEXT #endif
internal::select_parallel_do( first, last, body, &Body::operator() interface9::internal::select_parallel_do( first, last, body, &Body::operator()
#if __TBB_TASK_GROUP_CONTEXT #if __TBB_TASK_GROUP_CONTEXT
, context , context
#endif // __TBB_TASK_GROUP_CONTEXT #endif
); );
} }
@ -484,7 +527,7 @@ void parallel_do( Iterator first, Iterator last, const Body& body, task_group_co
{ {
if ( first == last ) if ( first == last )
return; return;
internal::select_parallel_do( first, last, body, &Body::operator(), context ); interface9::internal::select_parallel_do( first, last, body, &Body::operator(), context );
} }
template<typename Range, typename Body> template<typename Range, typename Body>
@ -501,6 +544,8 @@ void parallel_do(const Range& rng, const Body& body, task_group_context& context
//@} //@}
using interface9::parallel_do_feeder;
} // namespace } // namespace
#endif /* __TBB_parallel_do_H */ #endif /* __TBB_parallel_do_H */

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#ifndef __TBB_parallel_for_H #ifndef __TBB_parallel_for_H
@ -43,10 +43,10 @@ namespace internal {
Range my_range; Range my_range;
const Body my_body; const Body my_body;
typename Partitioner::task_partition_type my_partition; typename Partitioner::task_partition_type my_partition;
/*override*/ task* execute(); task* execute() __TBB_override;
//! Update affinity info, if any. //! Update affinity info, if any.
/*override*/ void note_affinity( affinity_id id ) { void note_affinity( affinity_id id ) __TBB_override {
my_partition.note_affinity( id ); my_partition.note_affinity( id );
} }
@ -200,14 +200,12 @@ void parallel_for( const Range& range, const Body& body, const auto_partitioner&
internal::start_for<Range,Body,const auto_partitioner>::run(range,body,partitioner); internal::start_for<Range,Body,const auto_partitioner>::run(range,body,partitioner);
} }
#if TBB_PREVIEW_STATIC_PARTITIONER
//! Parallel iteration over range with static_partitioner. //! Parallel iteration over range with static_partitioner.
/** @ingroup algorithms **/ /** @ingroup algorithms **/
template<typename Range, typename Body> template<typename Range, typename Body>
void parallel_for( const Range& range, const Body& body, const static_partitioner& partitioner ) { void parallel_for( const Range& range, const Body& body, const static_partitioner& partitioner ) {
internal::start_for<Range,Body,const static_partitioner>::run(range,body,partitioner); internal::start_for<Range,Body,const static_partitioner>::run(range,body,partitioner);
} }
#endif
//! Parallel iteration over range with affinity_partitioner. //! Parallel iteration over range with affinity_partitioner.
/** @ingroup algorithms **/ /** @ingroup algorithms **/
@ -238,14 +236,12 @@ void parallel_for( const Range& range, const Body& body, const auto_partitioner&
internal::start_for<Range,Body,const auto_partitioner>::run(range, body, partitioner, context); internal::start_for<Range,Body,const auto_partitioner>::run(range, body, partitioner, context);
} }
#if TBB_PREVIEW_STATIC_PARTITIONER
//! Parallel iteration over range with static_partitioner and user-supplied context. //! Parallel iteration over range with static_partitioner and user-supplied context.
/** @ingroup algorithms **/ /** @ingroup algorithms **/
template<typename Range, typename Body> template<typename Range, typename Body>
void parallel_for( const Range& range, const Body& body, const static_partitioner& partitioner, task_group_context& context ) { void parallel_for( const Range& range, const Body& body, const static_partitioner& partitioner, task_group_context& context ) {
internal::start_for<Range,Body,const static_partitioner>::run(range, body, partitioner, context); internal::start_for<Range,Body,const static_partitioner>::run(range, body, partitioner, context);
} }
#endif
//! Parallel iteration over range with affinity_partitioner and user-supplied context. //! Parallel iteration over range with affinity_partitioner and user-supplied context.
/** @ingroup algorithms **/ /** @ingroup algorithms **/
@ -288,13 +284,11 @@ template <typename Index, typename Function>
void parallel_for(Index first, Index last, Index step, const Function& f, const auto_partitioner& partitioner) { void parallel_for(Index first, Index last, Index step, const Function& f, const auto_partitioner& partitioner) {
parallel_for_impl<Index,Function,const auto_partitioner>(first, last, step, f, partitioner); parallel_for_impl<Index,Function,const auto_partitioner>(first, last, step, f, partitioner);
} }
#if TBB_PREVIEW_STATIC_PARTITIONER
//! Parallel iteration over a range of integers with a step provided and static partitioner //! Parallel iteration over a range of integers with a step provided and static partitioner
template <typename Index, typename Function> template <typename Index, typename Function>
void parallel_for(Index first, Index last, Index step, const Function& f, const static_partitioner& partitioner) { void parallel_for(Index first, Index last, Index step, const Function& f, const static_partitioner& partitioner) {
parallel_for_impl<Index,Function,const static_partitioner>(first, last, step, f, partitioner); parallel_for_impl<Index,Function,const static_partitioner>(first, last, step, f, partitioner);
} }
#endif
//! Parallel iteration over a range of integers with a step provided and affinity partitioner //! Parallel iteration over a range of integers with a step provided and affinity partitioner
template <typename Index, typename Function> template <typename Index, typename Function>
void parallel_for(Index first, Index last, Index step, const Function& f, affinity_partitioner& partitioner) { void parallel_for(Index first, Index last, Index step, const Function& f, affinity_partitioner& partitioner) {
@ -316,13 +310,11 @@ template <typename Index, typename Function>
void parallel_for(Index first, Index last, const Function& f, const auto_partitioner& partitioner) { void parallel_for(Index first, Index last, const Function& f, const auto_partitioner& partitioner) {
parallel_for_impl<Index,Function,const auto_partitioner>(first, last, static_cast<Index>(1), f, partitioner); parallel_for_impl<Index,Function,const auto_partitioner>(first, last, static_cast<Index>(1), f, partitioner);
} }
#if TBB_PREVIEW_STATIC_PARTITIONER
//! Parallel iteration over a range of integers with a default step value and static partitioner //! Parallel iteration over a range of integers with a default step value and static partitioner
template <typename Index, typename Function> template <typename Index, typename Function>
void parallel_for(Index first, Index last, const Function& f, const static_partitioner& partitioner) { void parallel_for(Index first, Index last, const Function& f, const static_partitioner& partitioner) {
parallel_for_impl<Index,Function,const static_partitioner>(first, last, static_cast<Index>(1), f, partitioner); parallel_for_impl<Index,Function,const static_partitioner>(first, last, static_cast<Index>(1), f, partitioner);
} }
#endif
//! Parallel iteration over a range of integers with a default step value and affinity partitioner //! Parallel iteration over a range of integers with a default step value and affinity partitioner
template <typename Index, typename Function> template <typename Index, typename Function>
void parallel_for(Index first, Index last, const Function& f, affinity_partitioner& partitioner) { void parallel_for(Index first, Index last, const Function& f, affinity_partitioner& partitioner) {
@ -359,13 +351,11 @@ void parallel_for(Index first, Index last, Index step, const Function& f, const
void parallel_for(Index first, Index last, Index step, const Function& f, const auto_partitioner& partitioner, tbb::task_group_context &context) { void parallel_for(Index first, Index last, Index step, const Function& f, const auto_partitioner& partitioner, tbb::task_group_context &context) {
parallel_for_impl<Index,Function,const auto_partitioner>(first, last, step, f, partitioner, context); parallel_for_impl<Index,Function,const auto_partitioner>(first, last, step, f, partitioner, context);
} }
#if TBB_PREVIEW_STATIC_PARTITIONER
//! Parallel iteration over a range of integers with explicit step, task group context, and static partitioner //! Parallel iteration over a range of integers with explicit step, task group context, and static partitioner
template <typename Index, typename Function> template <typename Index, typename Function>
void parallel_for(Index first, Index last, Index step, const Function& f, const static_partitioner& partitioner, tbb::task_group_context &context) { void parallel_for(Index first, Index last, Index step, const Function& f, const static_partitioner& partitioner, tbb::task_group_context &context) {
parallel_for_impl<Index,Function,const static_partitioner>(first, last, step, f, partitioner, context); parallel_for_impl<Index,Function,const static_partitioner>(first, last, step, f, partitioner, context);
} }
#endif
//! Parallel iteration over a range of integers with explicit step, task group context, and affinity partitioner //! Parallel iteration over a range of integers with explicit step, task group context, and affinity partitioner
template <typename Index, typename Function> template <typename Index, typename Function>
void parallel_for(Index first, Index last, Index step, const Function& f, affinity_partitioner& partitioner, tbb::task_group_context &context) { void parallel_for(Index first, Index last, Index step, const Function& f, affinity_partitioner& partitioner, tbb::task_group_context &context) {
@ -388,13 +378,11 @@ void parallel_for(Index first, Index last, const Function& f, const simple_parti
void parallel_for(Index first, Index last, const Function& f, const auto_partitioner& partitioner, tbb::task_group_context &context) { void parallel_for(Index first, Index last, const Function& f, const auto_partitioner& partitioner, tbb::task_group_context &context) {
parallel_for_impl<Index,Function,const auto_partitioner>(first, last, static_cast<Index>(1), f, partitioner, context); parallel_for_impl<Index,Function,const auto_partitioner>(first, last, static_cast<Index>(1), f, partitioner, context);
} }
#if TBB_PREVIEW_STATIC_PARTITIONER
//! Parallel iteration over a range of integers with a default step value, explicit task group context, and static partitioner //! Parallel iteration over a range of integers with a default step value, explicit task group context, and static partitioner
template <typename Index, typename Function> template <typename Index, typename Function>
void parallel_for(Index first, Index last, const Function& f, const static_partitioner& partitioner, tbb::task_group_context &context) { void parallel_for(Index first, Index last, const Function& f, const static_partitioner& partitioner, tbb::task_group_context &context) {
parallel_for_impl<Index,Function,const static_partitioner>(first, last, static_cast<Index>(1), f, partitioner, context); parallel_for_impl<Index,Function,const static_partitioner>(first, last, static_cast<Index>(1), f, partitioner, context);
} }
#endif
//! Parallel iteration over a range of integers with a default step value, explicit task group context, and affinity_partitioner //! Parallel iteration over a range of integers with a default step value, explicit task group context, and affinity_partitioner
template <typename Index, typename Function> template <typename Index, typename Function>
void parallel_for(Index first, Index last, const Function& f, affinity_partitioner& partitioner, tbb::task_group_context &context) { void parallel_for(Index first, Index last, const Function& f, affinity_partitioner& partitioner, tbb::task_group_context &context) {

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#ifndef __TBB_parallel_for_each_H #ifndef __TBB_parallel_for_each_H

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#ifndef __TBB_parallel_invoke_H #ifndef __TBB_parallel_invoke_H
@ -24,7 +24,7 @@
#include "task.h" #include "task.h"
#if __TBB_VARIADIC_PARALLEL_INVOKE #if __TBB_VARIADIC_PARALLEL_INVOKE
#include <utility> #include <utility> // std::forward
#endif #endif
namespace tbb { namespace tbb {
@ -43,8 +43,7 @@ namespace internal {
function_invoker(const function& _function) : my_function(_function) {} function_invoker(const function& _function) : my_function(_function) {}
private: private:
const function &my_function; const function &my_function;
/*override*/ task* execute() __TBB_override
task* execute()
{ {
my_function(); my_function();
return NULL; return NULL;
@ -60,7 +59,7 @@ namespace internal {
const function3& my_func3; const function3& my_func3;
bool is_recycled; bool is_recycled;
task* execute (){ task* execute () __TBB_override {
if(is_recycled){ if(is_recycled){
return NULL; return NULL;
}else{ }else{

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#ifndef __TBB_parallel_reduce_H #ifndef __TBB_parallel_reduce_H
@ -62,7 +62,7 @@ namespace internal {
if( has_right_zombie ) if( has_right_zombie )
zombie_space.begin()->~Body(); zombie_space.begin()->~Body();
} }
task* execute() { task* execute() __TBB_override {
if( has_right_zombie ) { if( has_right_zombie ) {
// Right child was stolen. // Right child was stolen.
Body* s = zombie_space.begin(); Body* s = zombie_space.begin();
@ -89,9 +89,9 @@ namespace internal {
Range my_range; Range my_range;
typename Partitioner::task_partition_type my_partition; typename Partitioner::task_partition_type my_partition;
reduction_context my_context; reduction_context my_context;
/*override*/ task* execute(); task* execute() __TBB_override;
//! Update affinity info, if any //! Update affinity info, if any
/*override*/ void note_affinity( affinity_id id ) { void note_affinity( affinity_id id ) __TBB_override {
my_partition.note_affinity( id ); my_partition.note_affinity( id );
} }
template<typename Body_> template<typename Body_>
@ -209,7 +209,7 @@ public:
my_right_body( body, split() ) my_right_body( body, split() )
{ {
} }
task* execute() { task* execute() __TBB_override {
my_left_body.join( my_right_body ); my_left_body.join( my_right_body );
return NULL; return NULL;
} }
@ -224,7 +224,7 @@ public:
typedef finish_deterministic_reduce<Body> finish_type; typedef finish_deterministic_reduce<Body> finish_type;
Body &my_body; Body &my_body;
Range my_range; Range my_range;
/*override*/ task* execute(); task* execute() __TBB_override;
//! Constructor used for root task //! Constructor used for root task
start_deterministic_reduce( const Range& range, Body& body ) : start_deterministic_reduce( const Range& range, Body& body ) :
@ -374,14 +374,12 @@ void parallel_reduce( const Range& range, Body& body, const auto_partitioner& pa
internal::start_reduce<Range,Body,const auto_partitioner>::run( range, body, partitioner ); internal::start_reduce<Range,Body,const auto_partitioner>::run( range, body, partitioner );
} }
#if TBB_PREVIEW_STATIC_PARTITIONER
//! Parallel iteration with reduction and static_partitioner //! Parallel iteration with reduction and static_partitioner
/** @ingroup algorithms **/ /** @ingroup algorithms **/
template<typename Range, typename Body> template<typename Range, typename Body>
void parallel_reduce( const Range& range, Body& body, const static_partitioner& partitioner ) { void parallel_reduce( const Range& range, Body& body, const static_partitioner& partitioner ) {
internal::start_reduce<Range,Body,const static_partitioner>::run( range, body, partitioner ); internal::start_reduce<Range,Body,const static_partitioner>::run( range, body, partitioner );
} }
#endif
//! Parallel iteration with reduction and affinity_partitioner //! Parallel iteration with reduction and affinity_partitioner
/** @ingroup algorithms **/ /** @ingroup algorithms **/
@ -405,14 +403,12 @@ void parallel_reduce( const Range& range, Body& body, const auto_partitioner& pa
internal::start_reduce<Range,Body,const auto_partitioner>::run( range, body, partitioner, context ); internal::start_reduce<Range,Body,const auto_partitioner>::run( range, body, partitioner, context );
} }
#if TBB_PREVIEW_STATIC_PARTITIONER
//! Parallel iteration with reduction, static_partitioner and user-supplied context //! Parallel iteration with reduction, static_partitioner and user-supplied context
/** @ingroup algorithms **/ /** @ingroup algorithms **/
template<typename Range, typename Body> template<typename Range, typename Body>
void parallel_reduce( const Range& range, Body& body, const static_partitioner& partitioner, task_group_context& context ) { void parallel_reduce( const Range& range, Body& body, const static_partitioner& partitioner, task_group_context& context ) {
internal::start_reduce<Range,Body,const static_partitioner>::run( range, body, partitioner, context ); internal::start_reduce<Range,Body,const static_partitioner>::run( range, body, partitioner, context );
} }
#endif
//! Parallel iteration with reduction, affinity_partitioner and user-supplied context //! Parallel iteration with reduction, affinity_partitioner and user-supplied context
/** @ingroup algorithms **/ /** @ingroup algorithms **/
@ -457,7 +453,6 @@ Value parallel_reduce( const Range& range, const Value& identity, const RealBody
return body.result(); return body.result();
} }
#if TBB_PREVIEW_STATIC_PARTITIONER
//! Parallel iteration with reduction and static_partitioner //! Parallel iteration with reduction and static_partitioner
/** @ingroup algorithms **/ /** @ingroup algorithms **/
template<typename Range, typename Value, typename RealBody, typename Reduction> template<typename Range, typename Value, typename RealBody, typename Reduction>
@ -468,7 +463,6 @@ Value parallel_reduce( const Range& range, const Value& identity, const RealBody
::run( range, body, partitioner ); ::run( range, body, partitioner );
return body.result(); return body.result();
} }
#endif
//! Parallel iteration with reduction and affinity_partitioner //! Parallel iteration with reduction and affinity_partitioner
/** @ingroup algorithms **/ /** @ingroup algorithms **/
@ -504,7 +498,6 @@ Value parallel_reduce( const Range& range, const Value& identity, const RealBody
return body.result(); return body.result();
} }
#if TBB_PREVIEW_STATIC_PARTITIONER
//! Parallel iteration with reduction, static_partitioner and user-supplied context //! Parallel iteration with reduction, static_partitioner and user-supplied context
/** @ingroup algorithms **/ /** @ingroup algorithms **/
template<typename Range, typename Value, typename RealBody, typename Reduction> template<typename Range, typename Value, typename RealBody, typename Reduction>
@ -515,7 +508,6 @@ Value parallel_reduce( const Range& range, const Value& identity, const RealBody
::run( range, body, partitioner, context ); ::run( range, body, partitioner, context );
return body.result(); return body.result();
} }
#endif
//! Parallel iteration with reduction, affinity_partitioner and user-supplied context //! Parallel iteration with reduction, affinity_partitioner and user-supplied context
/** @ingroup algorithms **/ /** @ingroup algorithms **/

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#ifndef __TBB_parallel_scan_H #ifndef __TBB_parallel_scan_H
@ -67,7 +67,7 @@ namespace internal {
my_stuff_last = stuff_last_; my_stuff_last = stuff_last_;
} }
private: private:
/*override*/ task* execute() { task* execute() __TBB_override {
my_body( *my_range.begin(), final_scan_tag() ); my_body( *my_range.begin(), final_scan_tag() );
if( my_stuff_last ) if( my_stuff_last )
my_stuff_last->assign(my_body); my_stuff_last->assign(my_body);
@ -91,6 +91,7 @@ namespace internal {
bool my_left_is_final; bool my_left_is_final;
Range my_range; Range my_range;
sum_node( const Range range_, bool left_is_final_ ) : sum_node( const Range range_, bool left_is_final_ ) :
my_stuff_last(NULL),
my_left_sum(NULL), my_left_sum(NULL),
my_left(NULL), my_left(NULL),
my_right(NULL), my_right(NULL),
@ -113,7 +114,7 @@ namespace internal {
return n; return n;
} }
} }
/*override*/ task* execute() { task* execute() __TBB_override {
if( my_body ) { if( my_body ) {
if( my_incoming ) if( my_incoming )
my_left_sum->my_body.reverse_join( my_incoming->my_body ); my_left_sum->my_body.reverse_join( my_incoming->my_body );
@ -149,7 +150,7 @@ namespace internal {
final_sum_type* my_right_zombie; final_sum_type* my_right_zombie;
sum_node_type& my_result; sum_node_type& my_result;
/*override*/ task* execute() { task* execute() __TBB_override {
__TBB_ASSERT( my_result.ref_count()==(my_result.my_left!=NULL)+(my_result.my_right!=NULL), NULL ); __TBB_ASSERT( my_result.ref_count()==(my_result.my_left!=NULL)+(my_result.my_right!=NULL), NULL );
if( my_result.my_left ) if( my_result.my_left )
my_result.my_left_is_final = false; my_result.my_left_is_final = false;
@ -194,7 +195,7 @@ namespace internal {
bool my_is_right_child; bool my_is_right_child;
Range my_range; Range my_range;
typename Partitioner::partition_type my_partition; typename Partitioner::partition_type my_partition;
/*override*/ task* execute(); task* execute() __TBB_override ;
public: public:
start_scan( sum_node_type*& return_slot_, start_scan& parent_, sum_node_type* parent_sum_ ) : start_scan( sum_node_type*& return_slot_, start_scan& parent_, sum_node_type* parent_sum_ ) :
my_body(parent_.my_body), my_body(parent_.my_body),
@ -233,6 +234,7 @@ namespace internal {
range_, range_,
*temp_body, *temp_body,
partitioner_ ); partitioner_ );
temp_body->my_body.reverse_join(body_);
task::spawn_root_and_wait( pass1 ); task::spawn_root_and_wait( pass1 );
if( root ) { if( root ) {
root->my_body = temp_body; root->my_body = temp_body;

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#ifndef __TBB_parallel_sort_H #ifndef __TBB_parallel_sort_H

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#ifndef __TBB_parallel_while #ifndef __TBB_parallel_while
@ -41,7 +41,7 @@ namespace internal {
class while_iteration_task: public task { class while_iteration_task: public task {
const Body& my_body; const Body& my_body;
typename Body::argument_type my_value; typename Body::argument_type my_value;
/*override*/ task* execute() { task* execute() __TBB_override {
my_body(my_value); my_body(my_value);
return NULL; return NULL;
} }
@ -62,7 +62,7 @@ namespace internal {
size_t size; size_t size;
typename Body::argument_type my_arg[max_arg_size]; typename Body::argument_type my_arg[max_arg_size];
while_group_task( const Body& body ) : my_body(body), size(0) {} while_group_task( const Body& body ) : my_body(body), size(0) {}
/*override*/ task* execute() { task* execute() __TBB_override {
typedef while_iteration_task<Body> iteration_type; typedef while_iteration_task<Body> iteration_type;
__TBB_ASSERT( size>0, NULL ); __TBB_ASSERT( size>0, NULL );
task_list list; task_list list;
@ -89,7 +89,7 @@ namespace internal {
Stream& my_stream; Stream& my_stream;
const Body& my_body; const Body& my_body;
empty_task& my_barrier; empty_task& my_barrier;
/*override*/ task* execute() { task* execute() __TBB_override {
typedef while_group_task<Body> block_type; typedef while_group_task<Body> block_type;
block_type& t = *new( allocate_additional_child_of(my_barrier) ) block_type(my_body); block_type& t = *new( allocate_additional_child_of(my_barrier) ) block_type(my_body);
size_t k=0; size_t k=0;

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#ifndef __TBB_partitioner_H #ifndef __TBB_partitioner_H
@ -35,7 +35,7 @@
#endif #endif
#ifndef __TBB_DEMAND_DEPTH_ADD #ifndef __TBB_DEMAND_DEPTH_ADD
// when imbalance is found range splits this value times more // when imbalance is found range splits this value times more
#define __TBB_DEMAND_DEPTH_ADD 2 #define __TBB_DEMAND_DEPTH_ADD 1
#endif #endif
#ifndef __TBB_STATIC_THRESHOLD #ifndef __TBB_STATIC_THRESHOLD
// necessary number of clocks for the work to be distributed among all tasks // necessary number of clocks for the work to be distributed among all tasks
@ -64,9 +64,7 @@ namespace tbb {
class auto_partitioner; class auto_partitioner;
class simple_partitioner; class simple_partitioner;
#if TBB_PREVIEW_STATIC_PARTITIONER
class static_partitioner; class static_partitioner;
#endif
class affinity_partitioner; class affinity_partitioner;
namespace interface9 { namespace interface9 {
@ -130,7 +128,7 @@ class flag_task: public task {
public: public:
tbb::atomic<bool> my_child_stolen; tbb::atomic<bool> my_child_stolen;
flag_task() { my_child_stolen = false; } flag_task() { my_child_stolen = false; }
task* execute() { return NULL; } task* execute() __TBB_override { return NULL; }
static void mark_task_stolen(task &t) { static void mark_task_stolen(task &t) {
tbb::atomic<bool> &flag = static_cast<flag_task*>(t.parent())->my_child_stolen; tbb::atomic<bool> &flag = static_cast<flag_task*>(t.parent())->my_child_stolen;
#if TBB_USE_THREADING_TOOLS #if TBB_USE_THREADING_TOOLS
@ -519,22 +517,16 @@ public:
} }
}; };
#if TBB_PREVIEW_STATIC_PARTITIONER class static_partition_type : public unbalancing_partition_type<linear_affinity_mode<static_partition_type> > {
#ifndef __TBB_STATIC_PARTITIONER_BASE_TYPE
#define __TBB_STATIC_PARTITIONER_BASE_TYPE unbalancing_partition_type
#endif
class static_partition_type : public __TBB_STATIC_PARTITIONER_BASE_TYPE<linear_affinity_mode<static_partition_type> > {
public: public:
typedef proportional_split split_type; typedef proportional_split split_type;
static_partition_type( const static_partitioner& ) static_partition_type( const static_partitioner& )
: __TBB_STATIC_PARTITIONER_BASE_TYPE<linear_affinity_mode<static_partition_type> >() {} : unbalancing_partition_type<linear_affinity_mode<static_partition_type> >() {}
static_partition_type( static_partition_type& p, split ) static_partition_type( static_partition_type& p, split )
: __TBB_STATIC_PARTITIONER_BASE_TYPE<linear_affinity_mode<static_partition_type> >(p, split()) {} : unbalancing_partition_type<linear_affinity_mode<static_partition_type> >(p, split()) {}
static_partition_type( static_partition_type& p, const proportional_split& split_obj ) static_partition_type( static_partition_type& p, const proportional_split& split_obj )
: __TBB_STATIC_PARTITIONER_BASE_TYPE<linear_affinity_mode<static_partition_type> >(p, split_obj) {} : unbalancing_partition_type<linear_affinity_mode<static_partition_type> >(p, split_obj) {}
}; };
#undef __TBB_STATIC_PARTITIONER_BASE_TYPE
#endif
class affinity_partition_type : public balancing_partition_type<linear_affinity_mode<affinity_partition_type> > { class affinity_partition_type : public balancing_partition_type<linear_affinity_mode<affinity_partition_type> > {
static const unsigned factor_power = 4; // TODO: get a unified formula based on number of computing units static const unsigned factor_power = 4; // TODO: get a unified formula based on number of computing units
@ -641,7 +633,6 @@ private:
typedef interface9::internal::auto_partition_type::split_type split_type; typedef interface9::internal::auto_partition_type::split_type split_type;
}; };
#if TBB_PREVIEW_STATIC_PARTITIONER
//! A static partitioner //! A static partitioner
class static_partitioner { class static_partitioner {
public: public:
@ -659,7 +650,6 @@ private:
// TODO: consider to make split_type public // TODO: consider to make split_type public
typedef interface9::internal::static_partition_type::split_type split_type; typedef interface9::internal::static_partition_type::split_type split_type;
}; };
#endif
//! An affinity partitioner //! An affinity partitioner
class affinity_partitioner: internal::affinity_partitioner_base_v3 { class affinity_partitioner: internal::affinity_partitioner_base_v3 {

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#ifndef __TBB_pipeline_H #ifndef __TBB_pipeline_H
@ -103,7 +103,7 @@ public:
serial = serial_in_order serial = serial_in_order
}; };
protected: protected:
filter( bool is_serial_ ) : explicit filter( bool is_serial_ ) :
next_filter_in_pipeline(not_in_pipeline()), next_filter_in_pipeline(not_in_pipeline()),
my_input_buffer(NULL), my_input_buffer(NULL),
my_filter_mode(static_cast<unsigned char>((is_serial_ ? serial : parallel) | exact_exception_propagation)), my_filter_mode(static_cast<unsigned char>((is_serial_ ? serial : parallel) | exact_exception_propagation)),
@ -112,7 +112,7 @@ protected:
next_segment(NULL) next_segment(NULL)
{} {}
filter( mode filter_mode ) : explicit filter( mode filter_mode ) :
next_filter_in_pipeline(not_in_pipeline()), next_filter_in_pipeline(not_in_pipeline()),
my_input_buffer(NULL), my_input_buffer(NULL),
my_filter_mode(static_cast<unsigned char>(filter_mode | exact_exception_propagation)), my_filter_mode(static_cast<unsigned char>(filter_mode | exact_exception_propagation)),
@ -205,7 +205,7 @@ public:
end_of_stream end_of_stream
}; };
protected: protected:
thread_bound_filter(mode filter_mode): explicit thread_bound_filter(mode filter_mode):
filter(static_cast<mode>(filter_mode | filter::filter_is_bound)) filter(static_cast<mode>(filter_mode | filter::filter_is_bound))
{ {
__TBB_ASSERT(filter_mode & filter::filter_is_serial, "thread-bound filters must be serial"); __TBB_ASSERT(filter_mode & filter::filter_is_serial, "thread-bound filters must be serial");
@ -412,14 +412,14 @@ class concrete_filter: public tbb::filter {
typedef token_helper<U,is_large_object<U>::value > u_helper; typedef token_helper<U,is_large_object<U>::value > u_helper;
typedef typename u_helper::pointer u_pointer; typedef typename u_helper::pointer u_pointer;
/*override*/ void* operator()(void* input) { void* operator()(void* input) __TBB_override {
t_pointer temp_input = t_helper::cast_from_void_ptr(input); t_pointer temp_input = t_helper::cast_from_void_ptr(input);
u_pointer output_u = u_helper::create_token(my_body(t_helper::token(temp_input))); u_pointer output_u = u_helper::create_token(my_body(t_helper::token(temp_input)));
t_helper::destroy_token(temp_input); t_helper::destroy_token(temp_input);
return u_helper::cast_to_void_ptr(output_u); return u_helper::cast_to_void_ptr(output_u);
} }
/*override*/ void finalize(void * input) { void finalize(void * input) __TBB_override {
t_pointer temp_input = t_helper::cast_from_void_ptr(input); t_pointer temp_input = t_helper::cast_from_void_ptr(input);
t_helper::destroy_token(temp_input); t_helper::destroy_token(temp_input);
} }
@ -435,7 +435,7 @@ class concrete_filter<void,U,Body>: public filter {
typedef token_helper<U, is_large_object<U>::value > u_helper; typedef token_helper<U, is_large_object<U>::value > u_helper;
typedef typename u_helper::pointer u_pointer; typedef typename u_helper::pointer u_pointer;
/*override*/void* operator()(void*) { void* operator()(void*) __TBB_override {
flow_control control; flow_control control;
u_pointer output_u = u_helper::create_token(my_body(control)); u_pointer output_u = u_helper::create_token(my_body(control));
if(control.is_pipeline_stopped) { if(control.is_pipeline_stopped) {
@ -459,13 +459,13 @@ class concrete_filter<T,void,Body>: public filter {
typedef token_helper<T, is_large_object<T>::value > t_helper; typedef token_helper<T, is_large_object<T>::value > t_helper;
typedef typename t_helper::pointer t_pointer; typedef typename t_helper::pointer t_pointer;
/*override*/ void* operator()(void* input) { void* operator()(void* input) __TBB_override {
t_pointer temp_input = t_helper::cast_from_void_ptr(input); t_pointer temp_input = t_helper::cast_from_void_ptr(input);
my_body(t_helper::token(temp_input)); my_body(t_helper::token(temp_input));
t_helper::destroy_token(temp_input); t_helper::destroy_token(temp_input);
return NULL; return NULL;
} }
/*override*/ void finalize(void* input) { void finalize(void* input) __TBB_override {
t_pointer temp_input = t_helper::cast_from_void_ptr(input); t_pointer temp_input = t_helper::cast_from_void_ptr(input);
t_helper::destroy_token(temp_input); t_helper::destroy_token(temp_input);
} }
@ -479,7 +479,7 @@ class concrete_filter<void,void,Body>: public filter {
const Body& my_body; const Body& my_body;
/** Override privately because it is always called virtually */ /** Override privately because it is always called virtually */
/*override*/ void* operator()(void*) { void* operator()(void*) __TBB_override {
flow_control control; flow_control control;
my_body(control); my_body(control);
void* output = control.is_pipeline_stopped ? NULL : (void*)(intptr_t)-1; void* output = control.is_pipeline_stopped ? NULL : (void*)(intptr_t)-1;
@ -537,7 +537,7 @@ template<typename T, typename U, typename Body>
class filter_node_leaf: public filter_node { class filter_node_leaf: public filter_node {
const tbb::filter::mode mode; const tbb::filter::mode mode;
const Body body; const Body body;
/*override*/void add_to( pipeline& p ) { void add_to( pipeline& p ) __TBB_override {
concrete_filter<T,U,Body>* f = new concrete_filter<T,U,Body>(mode,body); concrete_filter<T,U,Body>* f = new concrete_filter<T,U,Body>(mode,body);
p.add_filter( *f ); p.add_filter( *f );
} }
@ -550,11 +550,11 @@ class filter_node_join: public filter_node {
friend class filter_node; // to suppress GCC 3.2 warnings friend class filter_node; // to suppress GCC 3.2 warnings
filter_node& left; filter_node& left;
filter_node& right; filter_node& right;
/*override*/~filter_node_join() { ~filter_node_join() {
left.remove_ref(); left.remove_ref();
right.remove_ref(); right.remove_ref();
} }
/*override*/void add_to( pipeline& p ) { void add_to( pipeline& p ) __TBB_override {
left.add_to(p); left.add_to(p);
right.add_to(p); right.add_to(p);
} }

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#ifndef __TBB_queuing_mutex_H #ifndef __TBB_queuing_mutex_H

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#ifndef __TBB_queuing_rw_mutex_H #ifndef __TBB_queuing_rw_mutex_H

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#ifndef __TBB_reader_writer_lock_H #ifndef __TBB_reader_writer_lock_H

View file

@ -1,21 +1,21 @@
/* /*
Copyright 2005-2016 Intel Corporation. All Rights Reserved. Copyright (c) 2005-2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
you can redistribute it and/or modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation. Threading Building Blocks is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of
the GNU General Public License along with Threading Building Blocks; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
As a special exception, you may use this file as part of a free software library without
restriction. Specifically, if other files instantiate templates or use macros or inline
functions from this file, or you compile this file and link it with other files to produce
an executable, this file does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however invalidate any other
reasons why the executable file might be covered by the GNU General Public License.
*/ */
#ifndef __TBB_recursive_mutex_H #ifndef __TBB_recursive_mutex_H

Some files were not shown because too many files have changed in this diff Show more