diff --git a/lib/3rdParty/tbb/CHANGES b/lib/3rdParty/tbb/CHANGES index f2fc2d3..ab1d1a1 100644 --- a/lib/3rdParty/tbb/CHANGES +++ b/lib/3rdParty/tbb/CHANGES @@ -2,6 +2,280 @@ The list of most significant changes made over time in 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 TBB_INTERFACE_VERSION == 9003 @@ -474,7 +748,7 @@ Bugs fixed: - Fixed data races in preview extensions of task_scheduler_observer. - 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: @@ -490,7 +764,7 @@ TBB_INTERFACE_VERSION == 7003 Changes (w.r.t. Intel TBB 4.2 Update 2): - Added support for Microsoft* Visual Studio* 2013. -- Improved Microsoft* PPL-compatible form of parallel_for for better +- Improved Microsoft* PPL-compatible form of parallel_for for better support of auto-vectorization. - Added a new example for cancellation and reset in the flow graph: Kohonen self-organizing map (examples/graph/som). @@ -556,7 +830,7 @@ Preview Features: - Class task_arena no longer requires linking with a preview library, though still remains a community preview feature. - The method task_arena::wait_until_empty() is removed. -- The method task_arena::current_slot() now returns -1 if +- The method task_arena::current_slot() now returns -1 if the task scheduler is not initialized in the thread. Changes affecting backward compatibility: @@ -737,7 +1011,7 @@ Changes (w.r.t. Intel TBB 4.1): any platform supported by compiler version 12.1 and newer. - Using GetNativeSystemInfo() instead of GetSystemInfo() to support more than 32 processors for 32-bit applications under WOW64. -- The following form of parallel_for: +- The following form of parallel_for: parallel_for(first, last, [step,] f[, context]) now accepts an optional partitioner parameter after the function f. @@ -808,7 +1082,7 @@ Changes (w.r.t. Intel TBB 4.0 Update 4): Bugs fixed: -- Fixed a tv_nsec overflow bug in condition_variable::wait_for. +- Fixed a tv_nsec overflow bug in condition_variable::wait_for. - Fixed execution order of enqueued tasks with different priorities. - Fixed a bug with task priority changes causing lack of progress for fire-and-forget tasks when TBB was initialized to use 1 thread. @@ -877,7 +1151,7 @@ Changes (w.r.t. Intel TBB 4.0 Update 2): Backward-incompatible API changes: - a graph reference parameter is now required to be passed to the - constructors of the following flow graph nodes: overwrite_node, + constructors of the following flow graph nodes: overwrite_node, write_once_node, broadcast_node, and the CPF or_node. - the following tbb::flow node methods and typedefs have been renamed: Old New @@ -898,10 +1172,10 @@ TBB_INTERFACE_VERSION == 6002 Changes (w.r.t. Intel TBB 4.0 Update 1 commercial-aligned release): -- concurrent_bounded_queue now has an abort() operation that releases - threads involved in pending push or pop operations. The released +- concurrent_bounded_queue now has an abort() operation that releases + threads involved in pending push or pop operations. The released threads will receive a tbb::user_abort exception. -- Added Community Preview Feature: concurrent_lru_cache container, +- Added Community Preview Feature: concurrent_lru_cache container, a concurrent implementation of LRU (least-recently-used) cache. Bugs fixed: @@ -992,8 +1266,8 @@ TBB_INTERFACE_VERSION == 5006 (forgotten to increment) Changes (w.r.t. Intel TBB 3.0 Update 6 commercial-aligned release): -- Added implementation of the platform isolation layer based on - GCC atomic built-ins; it is supposed to work on any platform +- Added implementation of the platform isolation layer based on + GCC atomic built-ins; it is supposed to work on any platform where GCC has these built-ins. Community Preview Features: @@ -1070,9 +1344,9 @@ Changes (w.r.t. Intel TBB 3.0 Update 3 commercial-aligned release): - Fixed library loading to avoid possibility for remote code execution, see http://www.microsoft.com/technet/security/advisory/2269637.mspx. - Added support of more than 64 cores for appropriate Microsoft* - Windows* versions. For more details, see + Windows* versions. For more details, see http://msdn.microsoft.com/en-us/library/dd405503.aspx. -- Default number of worker threads is adjusted in accordance with +- Default number of worker threads is adjusted in accordance with process affinity mask. Bugs fixed: @@ -1157,7 +1431,7 @@ Bugs fixed: was a temporary object. - Incorrect usage of memory fences on PowerPC and XBOX360 platforms. - 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 number of buckets is not power of two. - Broken count() and equal_range() of concurrent_unordered_map. @@ -2078,7 +2352,8 @@ Packaging: are provided separately on Intel(R) Premier. ------------------------------------------------------------------------ -Intel and Cilk are registered trademarks or trademarks of Intel Corporation or its -subsidiaries in the United States and other countries. +Intel, the Intel logo, Xeon, Intel Xeon Phi, and Cilk are registered +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. diff --git a/lib/3rdParty/tbb/LICENSE b/lib/3rdParty/tbb/LICENSE new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/lib/3rdParty/tbb/LICENSE @@ -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. diff --git a/lib/3rdParty/tbb/bin/x64/v140/tbb.dll b/lib/3rdParty/tbb/bin/x64/v140/tbb.dll index b0dcda7..655e651 100644 Binary files a/lib/3rdParty/tbb/bin/x64/v140/tbb.dll and b/lib/3rdParty/tbb/bin/x64/v140/tbb.dll differ diff --git a/lib/3rdParty/tbb/bin/x64/v140/tbb_debug.dll b/lib/3rdParty/tbb/bin/x64/v140/tbb_debug.dll index 62e4369..bad9f08 100644 Binary files a/lib/3rdParty/tbb/bin/x64/v140/tbb_debug.dll and b/lib/3rdParty/tbb/bin/x64/v140/tbb_debug.dll differ diff --git a/lib/3rdParty/tbb/bin/x64/v140/tbb_preview.dll b/lib/3rdParty/tbb/bin/x64/v140/tbb_preview.dll index 1d9fc5f..7351808 100644 Binary files a/lib/3rdParty/tbb/bin/x64/v140/tbb_preview.dll and b/lib/3rdParty/tbb/bin/x64/v140/tbb_preview.dll differ diff --git a/lib/3rdParty/tbb/bin/x64/v140/tbbmalloc.dll b/lib/3rdParty/tbb/bin/x64/v140/tbbmalloc.dll index d6f7ee0..cee4336 100644 Binary files a/lib/3rdParty/tbb/bin/x64/v140/tbbmalloc.dll and b/lib/3rdParty/tbb/bin/x64/v140/tbbmalloc.dll differ diff --git a/lib/3rdParty/tbb/bin/x64/v140/tbbmalloc_proxy.dll b/lib/3rdParty/tbb/bin/x64/v140/tbbmalloc_proxy.dll index 01b0bb9..7e53309 100644 Binary files a/lib/3rdParty/tbb/bin/x64/v140/tbbmalloc_proxy.dll and b/lib/3rdParty/tbb/bin/x64/v140/tbbmalloc_proxy.dll differ diff --git a/lib/3rdParty/tbb/bin/x86/v140/tbb.dll b/lib/3rdParty/tbb/bin/x86/v140/tbb.dll index 9a99bb5..20ca289 100644 Binary files a/lib/3rdParty/tbb/bin/x86/v140/tbb.dll and b/lib/3rdParty/tbb/bin/x86/v140/tbb.dll differ diff --git a/lib/3rdParty/tbb/bin/x86/v140/tbb_debug.dll b/lib/3rdParty/tbb/bin/x86/v140/tbb_debug.dll index 7a29cba..96c5011 100644 Binary files a/lib/3rdParty/tbb/bin/x86/v140/tbb_debug.dll and b/lib/3rdParty/tbb/bin/x86/v140/tbb_debug.dll differ diff --git a/lib/3rdParty/tbb/bin/x86/v140/tbb_preview.dll b/lib/3rdParty/tbb/bin/x86/v140/tbb_preview.dll index f76c8d6..2090302 100644 Binary files a/lib/3rdParty/tbb/bin/x86/v140/tbb_preview.dll and b/lib/3rdParty/tbb/bin/x86/v140/tbb_preview.dll differ diff --git a/lib/3rdParty/tbb/bin/x86/v140/tbbmalloc.dll b/lib/3rdParty/tbb/bin/x86/v140/tbbmalloc.dll index 7e53e1f..99c6495 100644 Binary files a/lib/3rdParty/tbb/bin/x86/v140/tbbmalloc.dll and b/lib/3rdParty/tbb/bin/x86/v140/tbbmalloc.dll differ diff --git a/lib/3rdParty/tbb/bin/x86/v140/tbbmalloc_proxy.dll b/lib/3rdParty/tbb/bin/x86/v140/tbbmalloc_proxy.dll index e4cfbdc..cae643f 100644 Binary files a/lib/3rdParty/tbb/bin/x86/v140/tbbmalloc_proxy.dll and b/lib/3rdParty/tbb/bin/x86/v140/tbbmalloc_proxy.dll differ diff --git a/lib/3rdParty/tbb/include/index.html b/lib/3rdParty/tbb/include/index.html index c992bb6..b0962e0 100644 --- a/lib/3rdParty/tbb/include/index.html +++ b/lib/3rdParty/tbb/include/index.html @@ -8,12 +8,14 @@ Include files for Intel® Threading Building Blocks (Intel® TBB).
tbb
Include files for Intel TBB classes and functions. +
serial/tbb +
Include files for a sequential implementation of the parallel_for algorithm.

Up to parent directory

-Copyright © 2005-2016 Intel Corporation. All Rights Reserved. +Copyright © 2005-2017 Intel Corporation. All Rights Reserved.

Intel is a registered trademark or trademark of Intel Corporation or its subsidiaries in the United States and other countries. diff --git a/lib/3rdParty/tbb/include/serial/tbb/parallel_for.h b/lib/3rdParty/tbb/include/serial/tbb/parallel_for.h index 3ef776d..c8f9a79 100644 --- a/lib/3rdParty/tbb/include/serial/tbb/parallel_for.h +++ b/lib/3rdParty/tbb/include/serial/tbb/parallel_for.h @@ -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 @@ -121,14 +121,12 @@ void parallel_for( const Range& range, const Body& body, const auto_partitioner& serial::interface9::start_for::run(range,body,partitioner); } -#if TBB_PREVIEW_STATIC_PARTITIONER //! Parallel iteration over range with static_partitioner. /** @ingroup algorithms **/ template void parallel_for( const Range& range, const Body& body, const static_partitioner& partitioner ) { serial::interface9::start_for::run(range,body,partitioner); } -#endif //! Parallel iteration over range with affinity_partitioner. /** @ingroup algorithms **/ @@ -169,13 +167,11 @@ template void parallel_for(Index first, Index last, Index step, const Function& f, const auto_partitioner& p) { parallel_for_impl(first, last, step, f, p); } -#if TBB_PREVIEW_STATIC_PARTITIONER //! Parallel iteration over a range of integers with explicit step and static partitioner template void parallel_for(Index first, Index last, Index step, const Function& f, const static_partitioner& p) { parallel_for_impl(first, last, step, f, p); } -#endif //! Parallel iteration over a range of integers with explicit step and affinity partitioner template void parallel_for(Index first, Index last, Index step, const Function& f, affinity_partitioner& p) { @@ -197,13 +193,11 @@ template void parallel_for(Index first, Index last, const Function& f, const auto_partitioner& p) { parallel_for_impl(first, last, static_cast(1), f, p); } -#if TBB_PREVIEW_STATIC_PARTITIONER //! Parallel iteration over a range of integers with default step and static partitioner template void parallel_for(Index first, Index last, const Function& f, const static_partitioner& p) { parallel_for_impl(first, last, static_cast(1), f, p); } -#endif //! Parallel iteration over a range of integers with default step and affinity_partitioner template void parallel_for(Index first, Index last, const Function& f, affinity_partitioner& p) { diff --git a/lib/3rdParty/tbb/include/serial/tbb/tbb_annotate.h b/lib/3rdParty/tbb/include/serial/tbb/tbb_annotate.h index f7de75c..81c8d3a 100644 --- a/lib/3rdParty/tbb/include/serial/tbb/tbb_annotate.h +++ b/lib/3rdParty/tbb/include/serial/tbb/tbb_annotate.h @@ -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 diff --git a/lib/3rdParty/tbb/include/tbb/aggregator.h b/lib/3rdParty/tbb/include/tbb/aggregator.h index fc2ad21..6aecbb7 100644 --- a/lib/3rdParty/tbb/include/tbb/aggregator.h +++ b/lib/3rdParty/tbb/include/tbb/aggregator.h @@ -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 @@ -62,7 +62,7 @@ public: template class basic_operation : public basic_operation_base, no_assign { const Body& my_body; - /*override*/ void apply_body() { my_body(); } + void apply_body() __TBB_override { my_body(); } public: 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 */ void process(aggregator_operation *op) { execute_impl(*op); } - protected: +protected: /** Place operation in mailbox, then either handle mailbox or wait for the operation to be completed by a different thread. */ 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 // handle_operations functor. call_itt_notify(releasing, &(op.status)); - // insert the operation in the queue + // insert the operation into the list do { // 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 @@ -135,7 +135,7 @@ public: } - private: +private: //! An atomically updated list (aka mailbox) of aggregator_operations atomic mailbox; diff --git a/lib/3rdParty/tbb/include/tbb/aligned_space.h b/lib/3rdParty/tbb/include/tbb/aligned_space.h index 07d49ab..56fd85f 100644 --- a/lib/3rdParty/tbb/include/tbb/aligned_space.h +++ b/lib/3rdParty/tbb/include/tbb/aligned_space.h @@ -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 diff --git a/lib/3rdParty/tbb/include/tbb/atomic.h b/lib/3rdParty/tbb/include/tbb/atomic.h index b269ff2..72ec534 100644 --- a/lib/3rdParty/tbb/include/tbb/atomic.h +++ b/lib/3rdParty/tbb/include/tbb/atomic.h @@ -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 @@ -31,8 +31,8 @@ #include "tbb_machine.h" -#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) - // Workaround for overzealous compiler warnings +#if _MSC_VER && !__INTEL_COMPILER + // Suppress overzealous compiler warnings till the end of the file #pragma warning (push) #pragma warning (disable: 4244 4267 4512) #endif @@ -54,7 +54,9 @@ enum memory_semantics { //! @cond 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))); #elif __TBB_DECLSPEC_ALIGN_PRESENT #define __TBB_DECL_ATOMIC_FIELD(t,f,a) __declspec(align(a)) t f; @@ -551,6 +553,6 @@ inline atomic& as_atomic( T& t ) { #if _MSC_VER && !__INTEL_COMPILER #pragma warning (pop) -#endif // warnings 4244, 4267 are back +#endif // warnings are restored #endif /* __TBB_atomic_H */ diff --git a/lib/3rdParty/tbb/include/tbb/blocked_range.h b/lib/3rdParty/tbb/include/tbb/blocked_range.h index 5262669..9f24cd2 100644 --- a/lib/3rdParty/tbb/include/tbb/blocked_range.h +++ b/lib/3rdParty/tbb/include/tbb/blocked_range.h @@ -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 diff --git a/lib/3rdParty/tbb/include/tbb/blocked_range2d.h b/lib/3rdParty/tbb/include/tbb/blocked_range2d.h index 00b809c..f1b9f35 100644 --- a/lib/3rdParty/tbb/include/tbb/blocked_range2d.h +++ b/lib/3rdParty/tbb/include/tbb/blocked_range2d.h @@ -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 diff --git a/lib/3rdParty/tbb/include/tbb/blocked_range3d.h b/lib/3rdParty/tbb/include/tbb/blocked_range3d.h index 9db8b49..c62565e 100644 --- a/lib/3rdParty/tbb/include/tbb/blocked_range3d.h +++ b/lib/3rdParty/tbb/include/tbb/blocked_range3d.h @@ -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 diff --git a/lib/3rdParty/tbb/include/tbb/cache_aligned_allocator.h b/lib/3rdParty/tbb/include/tbb/cache_aligned_allocator.h index 14640ff..d435e78 100644 --- a/lib/3rdParty/tbb/include/tbb/cache_aligned_allocator.h +++ b/lib/3rdParty/tbb/include/tbb/cache_aligned_allocator.h @@ -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 diff --git a/lib/3rdParty/tbb/include/tbb/combinable.h b/lib/3rdParty/tbb/include/tbb/combinable.h index 3a95397..0063dbb 100644 --- a/lib/3rdParty/tbb/include/tbb/combinable.h +++ b/lib/3rdParty/tbb/include/tbb/combinable.h @@ -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 @@ -31,10 +31,10 @@ namespace tbb { //! Thread-local storage with optional reduction /** @ingroup containers */ template - class combinable { + class combinable { + private: typedef typename tbb::cache_aligned_allocator my_alloc; - typedef typename tbb::enumerable_thread_specific my_ets_type; my_ets_type my_ets; @@ -43,15 +43,28 @@ namespace tbb { combinable() { } template - combinable( finit _finit) : my_ets(_finit) { } + explicit combinable( finit _finit) : my_ets(_finit) { } //! 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) { } - - combinable & operator=( const combinable & other) { my_ets = other.my_ets; return *this; } +#if __TBB_ETS_USE_CPP11 + combinable & operator=( combinable && other) { + my_ets=std::move(other.my_ets); + return *this; + } +#endif void clear() { my_ets.clear(); } diff --git a/lib/3rdParty/tbb/include/tbb/compat/condition_variable b/lib/3rdParty/tbb/include/tbb/compat/condition_variable index 7a79225..43edfc0 100644 --- a/lib/3rdParty/tbb/include/tbb/compat/condition_variable +++ b/lib/3rdParty/tbb/include/tbb/compat/condition_variable @@ -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 diff --git a/lib/3rdParty/tbb/include/tbb/compat/ppl.h b/lib/3rdParty/tbb/include/tbb/compat/ppl.h index 2cfc537..840dfb2 100644 --- a/lib/3rdParty/tbb/include/tbb/compat/ppl.h +++ b/lib/3rdParty/tbb/include/tbb/compat/ppl.h @@ -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 diff --git a/lib/3rdParty/tbb/include/tbb/compat/thread b/lib/3rdParty/tbb/include/tbb/compat/thread index bc22ed5..0edd928 100644 --- a/lib/3rdParty/tbb/include/tbb/compat/thread +++ b/lib/3rdParty/tbb/include/tbb/compat/thread @@ -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 diff --git a/lib/3rdParty/tbb/include/tbb/compat/tuple b/lib/3rdParty/tbb/include/tbb/compat/tuple index 1eafb7b..5767c49 100644 --- a/lib/3rdParty/tbb/include/tbb/compat/tuple +++ b/lib/3rdParty/tbb/include/tbb/compat/tuple @@ -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 diff --git a/lib/3rdParty/tbb/include/tbb/concurrent_hash_map.h b/lib/3rdParty/tbb/include/tbb/concurrent_hash_map.h index fb41de7..09b2765 100644 --- a/lib/3rdParty/tbb/include/tbb/concurrent_hash_map.h +++ b/lib/3rdParty/tbb/include/tbb/concurrent_hash_map.h @@ -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 @@ -32,7 +32,7 @@ #include #include // Need std::pair #include // Need std::memset -#include // Need std::swap +#include __TBB_STD_SWAP_HEADER #if !TBB_USE_EXCEPTIONS && _MSC_VER #pragma warning (pop) @@ -333,9 +333,10 @@ namespace interface5 { void advance_to_next_bucket() { // TODO?: refactor to iterator_base class 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 - if( k& (k-2) ) // not the beginning of a segment + if( k&(k-2) ) // not the beginning of a segment ++my_bucket; else my_bucket = my_map->get_bucket( k ); my_node = static_cast( my_bucket->node_list ); @@ -368,7 +369,7 @@ namespace interface5 { public: //! Construct undefined iterator - hash_map_iterator() {} + hash_map_iterator(): my_map(), my_index(), my_bucket(), my_node() {} hash_map_iterator( const hash_map_iterator &other ) : my_map(other.my_map), my_index(other.my_index), @@ -765,7 +766,7 @@ public: }; //! 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) {} diff --git a/lib/3rdParty/tbb/include/tbb/concurrent_lru_cache.h b/lib/3rdParty/tbb/include/tbb/concurrent_lru_cache.h index 20fbb7b..8aacf24 100644 --- a/lib/3rdParty/tbb/include/tbb/concurrent_lru_cache.h +++ b/lib/3rdParty/tbb/include/tbb/concurrent_lru_cache.h @@ -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 @@ -126,8 +126,8 @@ private: } static handle_move_t move(handle_object& h){ __TBB_ASSERT(h.my_cache_pointer,"move from the same object twice ?"); - concurrent_lru_cache * cache_pointer = NULL; - std::swap(cache_pointer,h.my_cache_pointer); + concurrent_lru_cache * cache_pointer = h.my_cache_pointer; + h.my_cache_pointer = NULL; return handle_move_t(*cache_pointer,h.my_map_record_ref); } private: diff --git a/lib/3rdParty/tbb/include/tbb/concurrent_priority_queue.h b/lib/3rdParty/tbb/include/tbb/concurrent_priority_queue.h index d5871e5..89297d8 100644 --- a/lib/3rdParty/tbb/include/tbb/concurrent_priority_queue.h +++ b/lib/3rdParty/tbb/include/tbb/concurrent_priority_queue.h @@ -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 @@ -30,6 +30,7 @@ #include #include #include +#include __TBB_STD_SWAP_HEADER #if __TBB_INITIALIZER_LISTS_PRESENT #include @@ -373,7 +374,7 @@ class concurrent_priority_queue { compare(data[0], data[data.size()-1])) { // there are newly pushed elems and the last one // 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); itt_store_word_with_release(tmp->status, uintptr_t(SUCCEEDED)); data.pop_back(); @@ -389,7 +390,7 @@ class concurrent_priority_queue { if (tmp->type == PUSH_OP) { push_back_helper(*(tmp->elem), typename internal::use_element_copy_constructor::type()); } else { - data.push_back(move(*(tmp->elem))); + data.push_back(tbb::internal::move(*(tmp->elem))); } __TBB_store_with_release(my_size, my_size + 1); 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])) { // there are newly pushed elems and the last one 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); itt_store_word_with_release(tmp->status, uintptr_t(SUCCEEDED)); data.pop_back(); } 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); itt_store_word_with_release(tmp->status, uintptr_t(SUCCEEDED)); reheap(); @@ -439,14 +440,14 @@ class concurrent_priority_queue { for (; mark>1; if (!compare(data[parent], to_place)) break; - data[cur_pos] = move(data[parent]); + data[cur_pos] = tbb::internal::move(data[parent]); cur_pos = parent; } 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 now has the higher priority child 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; child = (cur_pos<<1)+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(); if (mark > data.size()) mark = data.size(); } diff --git a/lib/3rdParty/tbb/include/tbb/concurrent_queue.h b/lib/3rdParty/tbb/include/tbb/concurrent_queue.h index ee1187c..81db58a 100644 --- a/lib/3rdParty/tbb/include/tbb/concurrent_queue.h +++ b/lib/3rdParty/tbb/include/tbb/concurrent_queue.h @@ -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 @@ -40,7 +40,7 @@ class concurrent_queue: public internal::concurrent_queue_base_v3 { page_allocator_type my_allocator; //! 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(my_allocator.allocate( n )); if( !b ) internal::throw_exception(internal::eid_bad_alloc); @@ -48,7 +48,7 @@ class concurrent_queue: public internal::concurrent_queue_base_v3 { } //! 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(b), n ); } @@ -185,10 +185,8 @@ concurrent_queue::~concurrent_queue() { template void concurrent_queue::clear() { - while( !empty() ) { - T value; - this->internal_try_pop(&value); - } + T value; + while( !empty() ) try_pop(value); } } // namespace strict_ppl @@ -223,41 +221,41 @@ class concurrent_bounded_queue: public internal::concurrent_queue_base_v8 { return (&static_cast(static_cast(&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(src)); } #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(const_cast(src))) ); } #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" ); } #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(src), sindex ) ); } #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(src), sindex )) ); } #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" ); } #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); destroyer d(from); *static_cast(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); page *p = reinterpret_cast(my_allocator.allocate( n )); if( !p ) @@ -265,7 +263,7 @@ class concurrent_bounded_queue: public internal::concurrent_queue_base_v8 { 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); my_allocator.deallocate( reinterpret_cast(p), n ); } @@ -449,10 +447,8 @@ concurrent_bounded_queue::~concurrent_bounded_queue() { template void concurrent_bounded_queue::clear() { - while( !empty() ) { - T value; - internal_pop_if_present(&value); - } + T value; + while( try_pop(value) ) /*noop*/; } using strict_ppl::concurrent_queue; diff --git a/lib/3rdParty/tbb/include/tbb/concurrent_unordered_map.h b/lib/3rdParty/tbb/include/tbb/concurrent_unordered_map.h index 09a2a28..c959a7e 100644 --- a/lib/3rdParty/tbb/include/tbb/concurrent_unordered_map.h +++ b/lib/3rdParty/tbb/include/tbb/concurrent_unordered_map.h @@ -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 @@ -45,22 +45,6 @@ protected: concurrent_unordered_map_traits() : my_hash_compare() {} concurrent_unordered_map_traits(const hash_compare& hc) : my_hash_compare(hc) {} - class value_compare : public std::binary_function - { - friend class concurrent_unordered_map_traits; - - 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 static const Key& get_key(const std::pair& value) { return (value.first); @@ -115,12 +99,10 @@ public: const hasher& _Hasher = hasher(), const key_equal& _Key_equality = key_equal(), const allocator_type& a = allocator_type()) : 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 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 -#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) : base_type(table) - { - } + {} concurrent_unordered_map& operator=(const concurrent_unordered_map& table) { @@ -155,25 +137,22 @@ public: concurrent_unordered_map(concurrent_unordered_map&& table) : base_type(std::move(table)) - { - } + {} concurrent_unordered_map& operator=(concurrent_unordered_map&& table) { return static_cast(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) : 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 mapped_type& operator[](const key_type& key) { @@ -256,12 +235,10 @@ public: const hasher& _Hasher = hasher(), const key_equal& _Key_equality = key_equal(), const allocator_type& a = allocator_type()) : 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 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 -#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) : base_type(table) - { - } + {} concurrent_unordered_multimap& operator=(const concurrent_unordered_multimap& table) { @@ -296,25 +273,21 @@ public: concurrent_unordered_multimap(concurrent_unordered_multimap&& table) : base_type(std::move(table)) - { - } + {} concurrent_unordered_multimap& operator=(concurrent_unordered_multimap&& table) { return static_cast(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) : 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 diff --git a/lib/3rdParty/tbb/include/tbb/concurrent_unordered_set.h b/lib/3rdParty/tbb/include/tbb/concurrent_unordered_set.h index 62d992b..a26fee1 100644 --- a/lib/3rdParty/tbb/include/tbb/concurrent_unordered_set.h +++ b/lib/3rdParty/tbb/include/tbb/concurrent_unordered_set.h @@ -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 @@ -45,8 +45,6 @@ protected: concurrent_unordered_set_traits() : my_hash_compare() {} 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) { return value; } @@ -59,8 +57,8 @@ class concurrent_unordered_set : public internal::concurrent_unordered_base< con { // Base type definitions typedef internal::hash_compare hash_compare; - typedef internal::concurrent_unordered_base< concurrent_unordered_set_traits > base_type; - typedef concurrent_unordered_set_traits, Allocator, false> traits_type; + typedef concurrent_unordered_set_traits traits_type; + typedef internal::concurrent_unordered_base< traits_type > base_type; #if __TBB_EXTRA_DEBUG public: #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(), 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) - { - } + {} - 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 concurrent_unordered_set(Iterator first, Iterator last, size_type n_of_buckets = base_type::initial_bucket_number, const hasher& a_hasher = hasher(), @@ -111,7 +107,7 @@ public: #if __TBB_INITIALIZER_LISTS_PRESENT //! Constructor from initializer_list - concurrent_unordered_set(std::initializer_list il, size_type n_of_buckets = base_type::initial_bucket_number, const hasher& a_hasher = hasher(), + concurrent_unordered_set(std::initializer_list il, 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()) : base_type(n_of_buckets, key_compare(a_hasher, a_keyeq), a) { @@ -119,11 +115,11 @@ public: } #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) : base_type(table) - { - } + {} concurrent_unordered_set& operator=(const concurrent_unordered_set& table) { @@ -132,26 +128,22 @@ public: concurrent_unordered_set(concurrent_unordered_set&& table) : base_type(std::move(table)) - { - } + {} concurrent_unordered_set& operator=(concurrent_unordered_set&& table) { return static_cast(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) : 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 allocator_type& a = allocator_type()) : 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 concurrent_unordered_multiset(Iterator first, Iterator last, size_type n_of_buckets = base_type::initial_bucket_number, @@ -217,7 +207,7 @@ public: #if __TBB_INITIALIZER_LISTS_PRESENT //! Constructor from initializer_list - concurrent_unordered_multiset(std::initializer_list il, size_type n_of_buckets = base_type::initial_bucket_number, const hasher& a_hasher = hasher(), + concurrent_unordered_multiset(std::initializer_list il, 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()) : base_type(n_of_buckets, key_compare(a_hasher, a_keyeq), a) { @@ -225,39 +215,36 @@ public: } #endif //# __TBB_INITIALIZER_LISTS_PRESENT -#if __TBB_CPP11_RVALUE_REF_PRESENT && __TBB_CPP11_IMPLICIT_MOVE_MEMBERS_GENERATION_FOR_DERIVED_BROKEN - concurrent_unordered_multiset(const concurrent_unordered_multiset& table) +#if __TBB_CPP11_RVALUE_REF_PRESENT +#if !__TBB_IMPLICIT_MOVE_PRESENT + concurrent_unordered_multiset(const concurrent_unordered_multiset& table) : base_type(table) - { - } + {} - concurrent_unordered_multiset& operator=(const concurrent_unordered_multiset& table) + concurrent_unordered_multiset& operator=(const concurrent_unordered_multiset& table) { return static_cast(base_type::operator=(table)); } - concurrent_unordered_multiset(concurrent_unordered_multiset&& table) + concurrent_unordered_multiset(concurrent_unordered_multiset&& 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(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) : base_type(std::move(table), a) { } #endif //__TBB_CPP11_RVALUE_REF_PRESENT + + concurrent_unordered_multiset(const concurrent_unordered_multiset& table, const Allocator& a) + : base_type(table, a) + {} }; } // namespace interface5 diff --git a/lib/3rdParty/tbb/include/tbb/concurrent_vector.h b/lib/3rdParty/tbb/include/tbb/concurrent_vector.h index aeca317..370129e 100644 --- a/lib/3rdParty/tbb/include/tbb/concurrent_vector.h +++ b/lib/3rdParty/tbb/include/tbb/concurrent_vector.h @@ -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 @@ -30,6 +30,7 @@ #include "tbb_profiling.h" #include #include // for memset() +#include __TBB_STD_SWAP_HEADER #if !TBB_USE_EXCEPTIONS && _MSC_VER // Suppress "C++ exception handler used, but unwind semantics are not enabled" warning in STL headers @@ -72,12 +73,12 @@ namespace tbb { template > class concurrent_vector; -template -class vector_iterator; - //! @cond INTERNAL namespace internal { + template + class vector_iterator; + //! Bad allocation marker static void *const vector_allocation_error_flag = reinterpret_cast(size_t(63)); diff --git a/lib/3rdParty/tbb/include/tbb/critical_section.h b/lib/3rdParty/tbb/include/tbb/critical_section.h index 596f7fe..324b3e1 100644 --- a/lib/3rdParty/tbb/include/tbb/critical_section.h +++ b/lib/3rdParty/tbb/include/tbb/critical_section.h @@ -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_ diff --git a/lib/3rdParty/tbb/include/tbb/enumerable_thread_specific.h b/lib/3rdParty/tbb/include/tbb/enumerable_thread_specific.h index c457c03..f31f533 100644 --- a/lib/3rdParty/tbb/include/tbb/enumerable_thread_specific.h +++ b/lib/3rdParty/tbb/include/tbb/enumerable_thread_specific.h @@ -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 @@ -73,7 +73,7 @@ namespace interface6 { slot& at( size_t k ) { return ((slot*)(void*)(this+1))[k]; } - size_t size() const {return (size_t)1<>(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 free_array(void* ptr, size_t _size) = 0; // _size in bytes array* allocate( size_t lg_size ) { - size_t n = 1<(create_array( sizeof(array)+n*sizeof(slot) )); a->lg_size = lg_size; std::memset( a+1, 0, n*sizeof(slot) ); return 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)) ); } @@ -266,9 +266,9 @@ namespace interface6 { void* get_tls() const { return pthread_getspecific(my_key); } #endif tls_key_t my_key; - virtual void* create_local() = 0; - 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* create_local() __TBB_override = 0; + virtual void* create_array(size_t _size) __TBB_override = 0; // _size in bytes + virtual void free_array(void* ptr, size_t _size) __TBB_override = 0; // size in bytes protected: ets_base() {create_key();} ~ets_base() {destroy_key();} @@ -663,16 +663,16 @@ namespace interface6 { // TODO: make the construction/destruction consistent (use allocator.construct/destroy) typedef typename tbb::tbb_allocator my_allocator_type; - /*override*/ callback_base* clone() const { + callback_base* clone() const __TBB_override { return make(*this); } - /*override*/ void destroy() { + void destroy() __TBB_override { my_allocator_type().destroy(this); my_allocator_type().deallocate(this,1); } - /*override*/ void construct(void* where) { + void construct(void* where) __TBB_override { Constructor::construct(where); } public: @@ -700,7 +700,6 @@ namespace interface6 { successfully-constructed, set the flag to true or call value_committed(). 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 struct ets_element { tbb::aligned_space my_space; @@ -794,7 +793,7 @@ namespace interface6 { // TODO: consider unifying the callback mechanism for all create_local* methods below // (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); my_construct_callback->construct(lref.value()); return lref.value_committed(); @@ -819,12 +818,12 @@ namespace interface6 { typedef typename Allocator::template rebind< uintptr_t >::other array_allocator_type; // _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); 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); array_allocator_type().deallocate( reinterpret_cast(_ptr),nelements); } @@ -860,17 +859,17 @@ namespace interface6 { , typename = typename internal::enable_if::type>::value>::type #endif > - enumerable_thread_specific( Finit finit ) : my_construct_callback( + explicit enumerable_thread_specific( Finit finit ) : my_construct_callback( internal::callback_leaf >::make( tbb::internal::move(finit) ) ){} //! 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 >::make( exemplar ) ){} #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 >::make( std::move(exemplar) ) ){} @@ -1089,7 +1088,7 @@ namespace interface6 { flattened2d( const Container &c, typename Container::const_iterator b, typename Container::const_iterator e ) : my_container(const_cast(&c)), my_begin(b), my_end(e) { } - flattened2d( const Container &c ) : + explicit flattened2d( const Container &c ) : my_container(const_cast(&c)), my_begin(c.begin()), my_end(c.end()) { } iterator begin() { return iterator(*my_container) = my_begin; } diff --git a/lib/3rdParty/tbb/include/tbb/flow_graph.h b/lib/3rdParty/tbb/include/tbb/flow_graph.h index 3c5f305..7b03c0e 100644 --- a/lib/3rdParty/tbb/include/tbb/flow_graph.h +++ b/lib/3rdParty/tbb/include/tbb/flow_graph.h @@ -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_H @@ -33,11 +33,21 @@ #include "internal/_template_helpers.h" #include "internal/_aggregator_impl.h" #include "tbb_profiling.h" - -#if __TBB_PREVIEW_ASYNC_NODE #include "task_arena.h" +#include "flow_graph_abstractions.h" + +#if __TBB_PREVIEW_ASYNC_MSG +#include // std::vector in internal::async_storage +#include // std::shared_ptr in async_msg #endif +#if __TBB_PREVIEW_STREAMING_NODE +// For streaming_node +#include // std::array +#include // std::unordered_map +#include // std::decay, std::true_type, std::false_type +#endif // __TBB_PREVIEW_STREAMING_NODE + #if TBB_DEPRECATED_FLOW_ENQUEUE #define FLOW_SPAWN(a) tbb::task::enqueue((a)) #else @@ -78,16 +88,20 @@ namespace flow { //! An enumeration the provides the two most common concurrency levels: unlimited and serial enum concurrency { unlimited = 0, serial = 1 }; -namespace interface8 { +namespace internal { +static tbb::task * const SUCCESSFULLY_ENQUEUED = (task *)-1; +} + +namespace interface9 { + +using tbb::flow::internal::SUCCESSFULLY_ENQUEUED; namespace internal { template class successor_cache; template class broadcast_cache; template class round_robin_cache; - -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - template< typename C> class edge_container; -#endif + template class predecessor_cache; + template class reservable_predecessor_cache; } //A generic null type @@ -100,53 +114,9 @@ template< typename T > class sender; template< typename T > class receiver; class continue_receiver; -//! Pure virtual template class that defines a sender of messages of type T -template< typename T > -class sender { -public: - //! The output type of this sender - typedef T output_type; - - //! The successor type for this node - typedef receiver successor_type; - - virtual ~sender() {} - - //! Add a new successor to this node - virtual bool register_successor( successor_type &r ) = 0; - - //! Removes a successor from this node - virtual bool remove_successor( successor_type &r ) = 0; - - //! Request an item from the sender - virtual bool try_get( T & ) { return false; } - - //! Reserves an item in the sender - virtual bool try_reserve( T & ) { return false; } - - //! Releases the reserved item - virtual bool try_release( ) { return false; } - - //! Consumes the reserved item - virtual bool try_consume( ) { return false; } - -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - //! interface to record edges for traversal & deletion - typedef typename internal::edge_container built_successors_type; - typedef typename built_successors_type::edge_list_type successor_list_type; - virtual built_successors_type &built_successors() = 0; - virtual void internal_add_built_successor( successor_type & ) = 0; - virtual void internal_delete_built_successor( successor_type & ) = 0; - virtual void copy_successors( successor_list_type &) = 0; - virtual size_t successor_count() = 0; -#endif -}; // class sender - template< typename T > class limiter_node; // needed for resetting decrementer template< typename R, typename B > class run_and_put_task; -static tbb::task * const SUCCESSFULLY_ENQUEUED = (task *)-1; - // flags to modify the behavior of the graph reset(). Can be combined. enum reset_flags { rf_reset_protocol = 0, @@ -154,80 +124,6 @@ enum reset_flags { rf_clear_edges = 1<<1 // delete edges }; -// enqueue left task if necessary. Returns the non-enqueued task if there is one. -static inline tbb::task *combine_tasks( tbb::task * left, tbb::task * right) { - // if no RHS task, don't change left. - if(right == NULL) return left; - // right != NULL - if(left == NULL) return right; - if(left == SUCCESSFULLY_ENQUEUED) return right; - // left contains a task - if(right != SUCCESSFULLY_ENQUEUED) { - // both are valid tasks - FLOW_SPAWN(*left); - return right; - } - return left; -} - -//! Pure virtual template class that defines a receiver of messages of type T -template< typename T > -class receiver { -public: - //! The input type of this receiver - typedef T input_type; - - //! The predecessor type for this node - typedef sender predecessor_type; - - //! Destructor - virtual ~receiver() {} - - //! Put an item to the receiver - bool try_put( const T& t ) { - task *res = try_put_task(t); - if (!res) return false; - if (res != SUCCESSFULLY_ENQUEUED) FLOW_SPAWN(*res); - return true; - } - - //! put item to successor; return task to run the successor if possible. -protected: - template< typename R, typename B > friend class run_and_put_task; - template friend class internal::broadcast_cache; - template friend class internal::round_robin_cache; - virtual task *try_put_task(const T& t) = 0; -public: - - //! Add a predecessor to the node - virtual bool register_predecessor( predecessor_type & ) { return false; } - - //! Remove a predecessor from the node - virtual bool remove_predecessor( predecessor_type & ) { return false; } - -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - typedef typename internal::edge_container built_predecessors_type; - typedef typename built_predecessors_type::edge_list_type predecessor_list_type; - virtual built_predecessors_type &built_predecessors() = 0; - virtual void internal_add_built_predecessor( predecessor_type & ) = 0; - virtual void internal_delete_built_predecessor( predecessor_type & ) = 0; - virtual void copy_predecessors( predecessor_list_type & ) = 0; - virtual size_t predecessor_count() = 0; -#endif - -protected: - //! put receiver back in initial state - template friend class limiter_node; - virtual void reset_receiver(reset_flags f = rf_reset_protocol) = 0; - - template friend class internal::successor_cache; - virtual bool is_continue_receiver() { return false; } - -#if __TBB_PREVIEW_OPENCL_NODE - template< typename, typename > friend class proxy_dependency_receiver; -#endif /* __TBB_PREVIEW_OPENCL_NODE */ -}; // class receiver - #if TBB_PREVIEW_FLOW_GRAPH_FEATURES //* holder of edges both for caches and for those nodes which do not have predecessor caches. // C == receiver< ... > or sender< ... >, depending. @@ -265,15 +161,329 @@ public: // methods remove the statement from all predecessors/successors liste in the edge // container. - template< typename S > void sender_extract( S &s ); - template< typename R > void receiver_extract( R &r ); + template< typename S > void sender_extract( S &s ); + template< typename R > void receiver_extract( R &r ); -private: +private: edge_list_type built_edges; }; // class edge_container } // namespace internal #endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */ +#if __TBB_PREVIEW_ASYNC_MSG + +#include "internal/_flow_graph_async_msg_impl.h" + +namespace internal { + +class untyped_receiver; + +class untyped_sender { + template< typename, typename > friend class internal::predecessor_cache; + template< typename, typename > friend class internal::reservable_predecessor_cache; +public: + //! The successor type for this node + typedef untyped_receiver successor_type; + + virtual ~untyped_sender() {} + + // NOTE: Following part of PUBLIC section is copy-paste from original sender class + + // TODO: Prevent untyped successor registration + + //! Add a new successor to this node + virtual bool register_successor( successor_type &r ) = 0; + + //! Removes a successor from this node + virtual bool remove_successor( successor_type &r ) = 0; + + //! Releases the reserved item + virtual bool try_release( ) { return false; } + + //! Consumes the reserved item + virtual bool try_consume( ) { return false; } + +#if TBB_PREVIEW_FLOW_GRAPH_FEATURES + //! interface to record edges for traversal & deletion + typedef internal::edge_container built_successors_type; + typedef built_successors_type::edge_list_type successor_list_type; + virtual built_successors_type &built_successors() = 0; + virtual void internal_add_built_successor( successor_type & ) = 0; + virtual void internal_delete_built_successor( successor_type & ) = 0; + virtual void copy_successors( successor_list_type &) = 0; + virtual size_t successor_count() = 0; +#endif +protected: + //! Request an item from the sender + template< typename X > + bool try_get( X &t ) { + return try_get_wrapper( internal::async_helpers::to_void_ptr(t), internal::async_helpers::is_async_type ); + } + + //! Reserves an item in the sender + template< typename X > + bool try_reserve( X &t ) { + return try_reserve_wrapper( internal::async_helpers::to_void_ptr(t), internal::async_helpers::is_async_type ); + } + + virtual bool try_get_wrapper( void* p, bool is_async ) = 0; + virtual bool try_reserve_wrapper( void* p, bool is_async ) = 0; +}; + +class untyped_receiver { + template< typename, typename > friend class run_and_put_task; + template< typename > friend class limiter_node; + + template< typename, typename > friend class internal::broadcast_cache; + template< typename, typename > friend class internal::round_robin_cache; + template< typename, typename > friend class internal::successor_cache; + +#if __TBB_PREVIEW_OPENCL_NODE + template< typename, typename > friend class proxy_dependency_receiver; +#endif /* __TBB_PREVIEW_OPENCL_NODE */ +public: + //! The predecessor type for this node + typedef untyped_sender predecessor_type; + + //! Destructor + virtual ~untyped_receiver() {} + + //! Put an item to the receiver + template + bool try_put(const X& t) { + task *res = try_put_task(t); + if (!res) return false; + if (res != SUCCESSFULLY_ENQUEUED) FLOW_SPAWN(*res); + return true; + } + + // NOTE: Following part of PUBLIC section is copy-paste from original receiver class + + // TODO: Prevent untyped predecessor registration + + //! Add a predecessor to the node + virtual bool register_predecessor( predecessor_type & ) { return false; } + + //! Remove a predecessor from the node + virtual bool remove_predecessor( predecessor_type & ) { return false; } + +#if TBB_PREVIEW_FLOW_GRAPH_FEATURES + typedef internal::edge_container built_predecessors_type; + typedef built_predecessors_type::edge_list_type predecessor_list_type; + virtual built_predecessors_type &built_predecessors() = 0; + virtual void internal_add_built_predecessor( predecessor_type & ) = 0; + virtual void internal_delete_built_predecessor( predecessor_type & ) = 0; + virtual void copy_predecessors( predecessor_list_type & ) = 0; + virtual size_t predecessor_count() = 0; +#endif +protected: + template + task *try_put_task(const X& t) { + return try_put_task_wrapper( internal::async_helpers::to_void_ptr(t), internal::async_helpers::is_async_type ); + } + + virtual task* try_put_task_wrapper( const void* p, bool is_async ) = 0; + + // NOTE: Following part of PROTECTED and PRIVATE sections is copy-paste from original receiver class + + //! put receiver back in initial state + virtual void reset_receiver(reset_flags f = rf_reset_protocol) = 0; + + virtual bool is_continue_receiver() { return false; } +}; + +} // namespace internal + +//! Pure virtual template class that defines a sender of messages of type T +template< typename T > +class sender : public internal::untyped_sender { +public: + //! The output type of this sender + typedef T output_type; + + typedef typename internal::async_helpers::filtered_type filtered_type; + + //! Request an item from the sender + virtual bool try_get( T & ) { return false; } + + //! Reserves an item in the sender + virtual bool try_reserve( T & ) { return false; } + +protected: + virtual bool try_get_wrapper( void* p, bool is_async ) __TBB_override { + // Both async OR both are NOT async + if ( internal::async_helpers::is_async_type == is_async ) { + return try_get( internal::async_helpers::from_void_ptr(p) ); + } + // Else: this (T) is async OR incoming 't' is async + __TBB_ASSERT(false, "async_msg interface does not support 'pull' protocol in try_get()"); + return false; + } + + virtual bool try_reserve_wrapper( void* p, bool is_async ) __TBB_override { + // Both async OR both are NOT async + if ( internal::async_helpers::is_async_type == is_async ) { + return try_reserve( internal::async_helpers::from_void_ptr(p) ); + } + // Else: this (T) is async OR incoming 't' is async + __TBB_ASSERT(false, "async_msg interface does not support 'pull' protocol in try_reserve()"); + return false; + } +}; // class sender + +//! Pure virtual template class that defines a receiver of messages of type T +template< typename T > +class receiver : public internal::untyped_receiver { + template< typename > friend class internal::async_storage; + template< typename, typename > friend struct internal::async_helpers; +public: + //! The input type of this receiver + typedef T input_type; + + typedef typename internal::async_helpers::filtered_type filtered_type; + + //! Put an item to the receiver + bool try_put( const typename internal::async_helpers::filtered_type& t ) { + return internal::untyped_receiver::try_put(t); + } + + bool try_put( const typename internal::async_helpers::async_type& t ) { + return internal::untyped_receiver::try_put(t); + } + +protected: + virtual task* try_put_task_wrapper( const void *p, bool is_async ) __TBB_override { + return internal::async_helpers::try_put_task_wrapper_impl(this, p, is_async); + } + + //! Put item to successor; return task to run the successor if possible. + virtual task *try_put_task(const T& t) = 0; + +}; // class receiver + +#else // __TBB_PREVIEW_ASYNC_MSG + +//! Pure virtual template class that defines a sender of messages of type T +template< typename T > +class sender { +public: + //! The output type of this sender + typedef T output_type; + + //! The successor type for this node + typedef receiver successor_type; + + virtual ~sender() {} + + // NOTE: Following part of PUBLIC section is partly copy-pasted in sender under #if __TBB_PREVIEW_ASYNC_MSG + + //! Add a new successor to this node + virtual bool register_successor( successor_type &r ) = 0; + + //! Removes a successor from this node + virtual bool remove_successor( successor_type &r ) = 0; + + //! Request an item from the sender + virtual bool try_get( T & ) { return false; } + + //! Reserves an item in the sender + virtual bool try_reserve( T & ) { return false; } + + //! Releases the reserved item + virtual bool try_release( ) { return false; } + + //! Consumes the reserved item + virtual bool try_consume( ) { return false; } + +#if TBB_PREVIEW_FLOW_GRAPH_FEATURES + //! interface to record edges for traversal & deletion + typedef typename internal::edge_container built_successors_type; + typedef typename built_successors_type::edge_list_type successor_list_type; + virtual built_successors_type &built_successors() = 0; + virtual void internal_add_built_successor( successor_type & ) = 0; + virtual void internal_delete_built_successor( successor_type & ) = 0; + virtual void copy_successors( successor_list_type &) = 0; + virtual size_t successor_count() = 0; +#endif +}; // class sender + +//! Pure virtual template class that defines a receiver of messages of type T +template< typename T > +class receiver { +public: + //! The input type of this receiver + typedef T input_type; + + //! The predecessor type for this node + typedef sender predecessor_type; + + //! Destructor + virtual ~receiver() {} + + //! Put an item to the receiver + bool try_put( const T& t ) { + task *res = try_put_task(t); + if (!res) return false; + if (res != SUCCESSFULLY_ENQUEUED) FLOW_SPAWN(*res); + return true; + } + + //! put item to successor; return task to run the successor if possible. +protected: + 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::round_robin_cache; + virtual task *try_put_task(const T& t) = 0; +public: + // NOTE: Following part of PUBLIC and PROTECTED sections is copy-pasted in receiver under #if __TBB_PREVIEW_ASYNC_MSG + + //! Add a predecessor to the node + virtual bool register_predecessor( predecessor_type & ) { return false; } + + //! Remove a predecessor from the node + virtual bool remove_predecessor( predecessor_type & ) { return false; } + +#if TBB_PREVIEW_FLOW_GRAPH_FEATURES + typedef typename internal::edge_container built_predecessors_type; + typedef typename built_predecessors_type::edge_list_type predecessor_list_type; + virtual built_predecessors_type &built_predecessors() = 0; + virtual void internal_add_built_predecessor( predecessor_type & ) = 0; + virtual void internal_delete_built_predecessor( predecessor_type & ) = 0; + virtual void copy_predecessors( predecessor_list_type & ) = 0; + virtual size_t predecessor_count() = 0; +#endif + +protected: + //! put receiver back in initial state + template friend class limiter_node; + virtual void reset_receiver(reset_flags f = rf_reset_protocol) = 0; + + template friend class internal::successor_cache; + virtual bool is_continue_receiver() { return false; } + +#if __TBB_PREVIEW_OPENCL_NODE + template< typename, typename > friend class proxy_dependency_receiver; +#endif /* __TBB_PREVIEW_OPENCL_NODE */ +}; // class receiver + +#endif // __TBB_PREVIEW_ASYNC_MSG + +// enqueue left task if necessary. Returns the non-enqueued task if there is one. +static inline tbb::task *combine_tasks( tbb::task * left, tbb::task * right) { + // if no RHS task, don't change left. + if(right == NULL) return left; + // right != NULL + if(left == NULL) return right; + if(left == SUCCESSFULLY_ENQUEUED) return right; + // left contains a task + if(right != SUCCESSFULLY_ENQUEUED) { + // both are valid tasks + FLOW_SPAWN(*left); + return right; + } + return left; +} + //! Base class for receivers of completion messages /** These receivers automatically reset, but cannot be explicitly waited on */ class continue_receiver : public receiver< continue_msg > { @@ -283,10 +493,10 @@ public: typedef continue_msg input_type; //! The predecessor type for this node - typedef sender< continue_msg > predecessor_type; + typedef receiver::predecessor_type predecessor_type; //! Constructor - continue_receiver( int number_of_predecessors = 0 ) { + explicit continue_receiver( int number_of_predecessors = 0 ) { my_predecessor_count = my_initial_predecessor_count = number_of_predecessors; my_current_count = 0; } @@ -297,11 +507,8 @@ public: my_current_count = 0; } - //! Destructor - virtual ~continue_receiver() { } - //! Increments the trigger threshold - /* override */ bool register_predecessor( predecessor_type & ) { + bool register_predecessor( predecessor_type & ) __TBB_override { spin_mutex::scoped_lock l(my_mutex); ++my_predecessor_count; return true; @@ -311,7 +518,7 @@ public: /** Does not check to see if the removal of the predecessor now makes the current count exceed the new threshold. So removing a predecessor while the graph is active can cause unexpected results. */ - /* override */ bool remove_predecessor( predecessor_type & ) { + bool remove_predecessor( predecessor_type & ) __TBB_override { spin_mutex::scoped_lock l(my_mutex); --my_predecessor_count; return true; @@ -320,24 +527,24 @@ public: #if TBB_PREVIEW_FLOW_GRAPH_FEATURES typedef internal::edge_container built_predecessors_type; typedef built_predecessors_type::edge_list_type predecessor_list_type; - /*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( predecessor_type &s) { + void internal_add_built_predecessor( predecessor_type &s) __TBB_override { spin_mutex::scoped_lock l(my_mutex); my_built_predecessors.add_edge( s ); } - /*override*/ void internal_delete_built_predecessor( predecessor_type &s) { + void internal_delete_built_predecessor( predecessor_type &s) __TBB_override { spin_mutex::scoped_lock l(my_mutex); my_built_predecessors.delete_edge(s); } - /*override*/ void copy_predecessors( predecessor_list_type &v) { + void copy_predecessors( predecessor_list_type &v) __TBB_override { spin_mutex::scoped_lock l(my_mutex); my_built_predecessors.copy_edges(v); } - /*override*/ size_t predecessor_count() { + size_t predecessor_count() __TBB_override { spin_mutex::scoped_lock l(my_mutex); return my_built_predecessors.edge_count(); } @@ -349,7 +556,7 @@ protected: template friend class internal::broadcast_cache; template friend class internal::round_robin_cache; // execute body is supposed to be too small to create a task for. - /* override */ task *try_put_task( const input_type & ) { + task *try_put_task( const input_type & ) __TBB_override { { spin_mutex::scoped_lock l(my_mutex); if ( ++my_current_count < my_predecessor_count ) @@ -374,7 +581,7 @@ protected: // error in gcc 4.1.2 template friend class limiter_node; - /*override*/void reset_receiver( reset_flags f ) { + void reset_receiver( reset_flags f ) __TBB_override { my_current_count = 0; if (f & rf_clear_edges) { #if TBB_PREVIEW_FLOW_GRAPH_FEATURES @@ -389,10 +596,10 @@ protected: called while the sender is blocked in the try_put(). */ virtual task * execute() = 0; template friend class internal::successor_cache; - /*override*/ bool is_continue_receiver() { return true; } + bool is_continue_receiver() __TBB_override { return true; } }; // class continue_receiver -} // interface8 +} // interface9 #if __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING template @@ -401,9 +608,9 @@ protected: } #endif /* __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING */ - using interface8::sender; - using interface8::receiver; - using interface8::continue_receiver; + using interface9::sender; + using interface9::receiver; + using interface9::continue_receiver; } // flow } // tbb @@ -412,7 +619,7 @@ protected: namespace tbb { namespace flow { -namespace interface8 { +namespace interface9 { #include "internal/_flow_graph_impl.h" #include "internal/_flow_graph_types_impl.h" @@ -490,14 +697,14 @@ private: //! The graph class /** This class serves as a handle to the graph */ -class graph : tbb::internal::no_copy { +class graph : tbb::internal::no_copy, public graph_proxy { friend class graph_node; template< typename Body > class run_task : public task { public: run_task( Body& body ) : my_body(body) {} - task *execute() { + task *execute() __TBB_override { my_body(); return NULL; } @@ -509,7 +716,7 @@ class graph : tbb::internal::no_copy { class run_and_put_task : public task { public: run_and_put_task( Receiver &r, Body& body ) : my_receiver(r), my_body(body) {} - task *execute() { + task *execute() __TBB_override { task *res = my_receiver.try_put_task( my_body() ); if (res == SUCCESSFULLY_ENQUEUED) res = NULL; return res; @@ -520,7 +727,6 @@ class graph : tbb::internal::no_copy { }; typedef std::list task_list_type; -#if __TBB_PREVIEW_ASYNC_NODE class wait_functor { task* graph_root_task; public: @@ -530,24 +736,22 @@ class graph : tbb::internal::no_copy { void prepare_task_arena( bool reinit = false ) { if (reinit) { - __TBB_ASSERT( my_task_arena, NULL ); + __TBB_ASSERT( my_task_arena, "task arena is NULL"); my_task_arena->terminate(); my_task_arena->initialize(tbb::task_arena::attach()); } else { + __TBB_ASSERT(my_task_arena == NULL, "task arena is not NULL"); my_task_arena = new tbb::task_arena(tbb::task_arena::attach()); } if (!my_task_arena->is_active()) // failed to attach my_task_arena->initialize(); // create a new, default-initialized arena - __TBB_ASSERT(my_task_arena->is_active(), NULL); + __TBB_ASSERT(my_task_arena->is_active(), "task arena is not active"); } -#endif public: //! Constructs a graph with isolated task_group_context - graph() : my_nodes(NULL), my_nodes_last(NULL) { -#if __TBB_PREVIEW_ASYNC_NODE + graph() : my_nodes(NULL), my_nodes_last(NULL), my_task_arena(NULL) { prepare_task_arena(); -#endif own_context = true; cancelled = false; caught_exception = false; @@ -560,10 +764,8 @@ public: //! Constructs a graph with use_this_context as context explicit graph(task_group_context& use_this_context) : - my_context(&use_this_context), my_nodes(NULL), my_nodes_last(NULL) { -#if __TBB_PREVIEW_ASYNC_NODE + my_context(&use_this_context), my_nodes(NULL), my_nodes_last(NULL), my_task_arena(NULL) { prepare_task_arena(); -#endif own_context = false; my_root_task = ( new ( task::allocate_root(*my_context) ) empty_task ); my_root_task->set_ref_count(1); @@ -578,9 +780,7 @@ public: my_root_task->set_ref_count(0); task::destroy( *my_root_task ); if (own_context) delete my_context; -#if __TBB_PREVIEW_ASYNC_NODE delete my_task_arena; -#endif } #if TBB_PREVIEW_FLOW_GRAPH_TRACE @@ -605,6 +805,14 @@ public: my_root_task->decrement_ref_count(); } + void reserve_wait() __TBB_override { + increment_wait_count(); + } + + void release_wait() __TBB_override { + decrement_wait_count(); + } + //! Spawns a task that runs a body and puts its output to a specific receiver /** The task is spawned as a child of the graph. This is useful for running tasks that need to block a wait_for_all() on the graph. For example a one-off source. */ @@ -635,11 +843,7 @@ public: #if TBB_USE_EXCEPTIONS try { #endif -#if __TBB_PREVIEW_ASYNC_NODE my_task_arena->execute(wait_functor(my_root_task)); -#else - my_root_task->wait_for_all(); -#endif cancelled = my_context->is_group_execution_cancelled(); #if TBB_USE_EXCEPTIONS } @@ -652,7 +856,7 @@ public: } #endif // TODO: the "if" condition below is just a work-around to support the concurrent wait - // mode. The cancelation and exception mechanisms are still broken in this mode. + // mode. The cancellation and exception mechanisms are still broken in this mode. // Consider using task group not to re-implement the same functionality. if ( !(my_context->traits() & task_group_context::concurrent_wait) ) { my_context->reset(); // consistent with behavior in catch() @@ -722,11 +926,9 @@ private: void register_node(graph_node *n); void remove_node(graph_node *n); -#if __TBB_PREVIEW_ASYNC_NODE template < typename Input, typename Output, typename Policy, typename Allocator > friend class async_node; task_arena* my_task_arena; -#endif }; // class graph template @@ -747,14 +949,13 @@ typename graph_iterator::pointer graph_iterator::operator->() const { return current_node; } - template void graph_iterator::internal_forward() { if (current_node) current_node = current_node->next; } //! The base of all graph nodes. -class graph_node : tbb::internal::no_assign { +class graph_node : tbb::internal::no_copy { friend class graph; template friend class graph_iterator; @@ -762,7 +963,7 @@ protected: graph& my_graph; graph_node *next, *prev; public: - graph_node(graph& g) : my_graph(g) { + explicit graph_node(graph& g) : my_graph(g) { my_graph.register_node(this); } virtual ~graph_node() { @@ -805,7 +1006,7 @@ inline void graph::remove_node(graph_node *n) { n->prev = n->next = NULL; } -inline void graph::reset( reset_flags f ) { +inline void graph::reset( reset_flags f ) { // reset context set_active(false); if(my_context) my_context->reset(); @@ -816,11 +1017,9 @@ inline void graph::reset( reset_flags f ) { graph_node *my_p = &(*ii); my_p->reset_node(f); } -#if __TBB_PREVIEW_ASYNC_NODE // Reattach the arena. Might be useful to run the graph in a particular task_arena // while not limiting graph lifetime to a single task_arena::execute() call. prepare_task_arena( /*reinit=*/true ); -#endif set_active(true); // now spawn the tasks necessary to start the graph for(task_list_type::iterator rti = my_reset_task_list.begin(); rti != my_reset_task_list.end(); ++rti) { @@ -829,20 +1028,17 @@ inline void graph::reset( reset_flags f ) { my_reset_task_list.clear(); } - #include "internal/_flow_graph_node_impl.h" //! An executable node that acts as a source, i.e. it has no predecessors template < typename Output > class source_node : public graph_node, public sender< Output > { -protected: - using graph_node::my_graph; public: //! The type of the output message, which is complete typedef Output output_type; //! The type of successors of this node - typedef receiver< Output > successor_type; + typedef typename sender::successor_type successor_type; //Source node has no input type typedef null_type input_type; @@ -881,13 +1077,13 @@ public: ~source_node() { delete my_body; delete my_init_body; } #if TBB_PREVIEW_FLOW_GRAPH_TRACE - /* override */ void set_name( const char *name ) { + void set_name( const char *name ) __TBB_override { tbb::internal::fgt_node_desc( this, name ); } #endif //! Add a new successor to this node - /* override */ bool register_successor( successor_type &r ) { + bool register_successor( successor_type &r ) __TBB_override { spin_mutex::scoped_lock lock(my_mutex); my_successors.register_successor(r); if ( my_active ) @@ -896,7 +1092,7 @@ public: } //! Removes a successor from this node - /* override */ bool remove_successor( successor_type &r ) { + bool remove_successor( successor_type &r ) __TBB_override { spin_mutex::scoped_lock lock(my_mutex); my_successors.remove_successor(r); return true; @@ -904,31 +1100,31 @@ public: #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 { spin_mutex::scoped_lock lock(my_mutex); my_successors.internal_add_built_successor(r); } - /*override*/void internal_delete_built_successor( successor_type &r) { + void internal_delete_built_successor( successor_type &r) __TBB_override { spin_mutex::scoped_lock lock(my_mutex); my_successors.internal_delete_built_successor(r); } - /*override*/size_t successor_count() { + size_t successor_count() __TBB_override { spin_mutex::scoped_lock lock(my_mutex); return my_successors.successor_count(); } - /*override*/void copy_successors(successor_list_type &v) { + void copy_successors(successor_list_type &v) __TBB_override { spin_mutex::scoped_lock l(my_mutex); my_successors.copy_successors(v); } #endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */ //! Request an item from the node - /*override */ bool try_get( output_type &v ) { + bool try_get( output_type &v ) __TBB_override { spin_mutex::scoped_lock lock(my_mutex); if ( my_reserved ) return false; @@ -945,7 +1141,7 @@ public: } //! Reserves an item. - /* override */ bool try_reserve( output_type &v ) { + bool try_reserve( output_type &v ) __TBB_override { spin_mutex::scoped_lock lock(my_mutex); if ( my_reserved ) { return false; @@ -962,7 +1158,7 @@ public: //! Release a reserved item. /** true = item has been released and so remains in sender, dest must request or reserve future items */ - /* override */ bool try_release( ) { + bool try_release( ) __TBB_override { spin_mutex::scoped_lock lock(my_mutex); __TBB_ASSERT( my_reserved && my_has_cached_item, "releasing non-existent reservation" ); my_reserved = false; @@ -972,7 +1168,7 @@ public: } //! Consumes a reserved item - /* override */ bool try_consume( ) { + bool try_consume( ) __TBB_override { spin_mutex::scoped_lock lock(my_mutex); __TBB_ASSERT( my_reserved && my_has_cached_item, "consuming non-existent reservation" ); my_reserved = false; @@ -998,7 +1194,7 @@ public: } #if TBB_PREVIEW_FLOW_GRAPH_FEATURES - /*override*/void extract( ) { + void extract( ) __TBB_override { my_successors.built_successors().sender_extract(*this); // removes "my_owner" == this from each successor my_active = init_my_active; my_reserved = false; @@ -1009,7 +1205,7 @@ public: protected: //! resets the source_node to its initial state - /*override*/void reset_node( reset_flags f) { + void reset_node( reset_flags f) __TBB_override { my_active = init_my_active; my_reserved =false; if(my_has_cached_item) { @@ -1069,7 +1265,7 @@ private: } //! Spawns a task that applies the body - /* override */ void spawn_put( ) { + void spawn_put( ) { if(this->my_graph.is_active()) { FLOW_SPAWN( *create_put_task()); } @@ -1077,7 +1273,7 @@ private: friend class internal::source_task_bypass< source_node< output_type > >; //! Applies the body. Returning SUCCESSFULLY_ENQUEUED okay; forward_task_bypass will handle it. - /* override */ task * apply_body_bypass( ) { + task * apply_body_bypass( ) { output_type v; if ( !try_reserve_apply_body(v) ) return NULL; @@ -1107,11 +1303,11 @@ class function_node : public graph_node, public internal::function_input predecessor_type; - typedef receiver< output_type > successor_type; typedef internal::function_input fInput_type; typedef internal::function_input_queue input_queue_type; typedef internal::function_output fOutput_type; + typedef typename fInput_type::predecessor_type predecessor_type; + typedef typename fOutput_type::successor_type successor_type; #if TBB_PREVIEW_FLOW_GRAPH_FEATURES typedef typename fInput_type::predecessor_list_type predecessor_list_type; typedef typename fOutput_type::successor_list_type successor_list_type; @@ -1126,27 +1322,27 @@ public: function_node( graph &g, size_t concurrency, Body body ) : graph_node(g), fInput_type(g, concurrency, body, allocate_buffer::value ? new input_queue_type( ) : NULL ) { - tbb::internal::fgt_node_with_body( tbb::internal::FLOW_FUNCTION_NODE, &this->graph_node::my_graph, + tbb::internal::fgt_node_with_body( tbb::internal::FLOW_FUNCTION_NODE, &this->my_graph, static_cast *>(this), static_cast *>(this), this->my_body ); } //! Copy constructor function_node( const function_node& src ) : - graph_node(src.graph_node::my_graph), + graph_node(src.my_graph), fInput_type(src, allocate_buffer::value ? new input_queue_type : NULL), fOutput_type() { - tbb::internal::fgt_node_with_body( tbb::internal::FLOW_FUNCTION_NODE, &this->graph_node::my_graph, + tbb::internal::fgt_node_with_body( tbb::internal::FLOW_FUNCTION_NODE, &this->my_graph, static_cast *>(this), static_cast *>(this), this->my_body ); } #if TBB_PREVIEW_FLOW_GRAPH_TRACE - /* override */ void set_name( const char *name ) { + void set_name( const char *name ) __TBB_override { tbb::internal::fgt_node_desc( this, name ); } #endif #if TBB_PREVIEW_FLOW_GRAPH_FEATURES - /*override*/void extract( ) { + void extract( ) __TBB_override { my_predecessors.built_predecessors().receiver_extract(*this); successors().built_successors().sender_extract(*this); } @@ -1158,10 +1354,9 @@ protected: template friend class internal::round_robin_cache; using fInput_type::try_put_task; - /* override */ internal::broadcast_cache &successors () { return fOutput_type::my_successors; } + internal::broadcast_cache &successors () __TBB_override { return fOutput_type::my_successors; } - // override of graph_node's reset. - /*override*/void reset_node(reset_flags f) { + void reset_node(reset_flags f) __TBB_override { fInput_type::reset_function_input(f); // TODO: use clear() instead. if(f & rf_clear_edges) { @@ -1174,7 +1369,6 @@ protected: }; // class function_node - //! implements a function node that supports Input -> (set of outputs) // Output is a tuple of output types. template < typename Input, typename Output, typename Policy = queueing, typename Allocator=cache_aligned_allocator > @@ -1191,7 +1385,6 @@ class multifunction_node : Allocator > { protected: - using graph_node::my_graph; static const int N = tbb::flow::tuple_size::value; public: typedef Input input_type; @@ -1207,83 +1400,125 @@ public: multifunction_node( graph &g, size_t concurrency, Body body ) : graph_node(g), base_type(g,concurrency, body, allocate_buffer::value ? new input_queue_type : NULL) { tbb::internal::fgt_multioutput_node_with_body( tbb::internal::FLOW_MULTIFUNCTION_NODE, - &this->graph_node::my_graph, static_cast *>(this), + &this->my_graph, static_cast *>(this), this->output_ports(), this->my_body ); } multifunction_node( const multifunction_node &other) : - graph_node(other.graph_node::my_graph), base_type(other, allocate_buffer::value ? new input_queue_type : NULL) { + graph_node(other.my_graph), base_type(other, allocate_buffer::value ? new input_queue_type : NULL) { tbb::internal::fgt_multioutput_node_with_body( tbb::internal::FLOW_MULTIFUNCTION_NODE, - &this->graph_node::my_graph, static_cast *>(this), + &this->my_graph, static_cast *>(this), this->output_ports(), this->my_body ); } #if TBB_PREVIEW_FLOW_GRAPH_TRACE - /* override */ void set_name( const char *name ) { + void set_name( const char *name ) __TBB_override { tbb::internal::fgt_multioutput_node_desc( this, name ); } #endif #if TBB_PREVIEW_FLOW_GRAPH_FEATURES - void extract( ) { + void extract( ) __TBB_override { my_predecessors.built_predecessors().receiver_extract(*this); base_type::extract(); } #endif // all the guts are in multifunction_input... protected: - /*override*/void reset_node(reset_flags f) { base_type::reset(f); } + void reset_node(reset_flags f) __TBB_override { base_type::reset(f); } }; // multifunction_node //! split_node: accepts a tuple as input, forwards each element of the tuple to its -// successors. The node has unlimited concurrency, so though it is marked as -// "rejecting" it does not reject inputs. +// successors. The node has unlimited concurrency, so it does not reject inputs. template > -class split_node : public multifunction_node { +class split_node : public graph_node, public receiver { static const int N = tbb::flow::tuple_size::value; - typedef multifunction_node base_type; -public: - typedef typename base_type::output_ports_type output_ports_type; - typedef typename base_type::output_type output_type; -private: - struct splitting_body { - void operator()(const TupleType& t, output_ports_type &p) { - internal::emit_element::emit_this(t, p); - } - }; + typedef receiver base_type; public: typedef TupleType input_type; typedef Allocator allocator_type; - split_node(graph &g) : base_type(g, unlimited, splitting_body()) { - tbb::internal::fgt_multioutput_node( tbb::internal::FLOW_SPLIT_NODE, &this->graph_node::my_graph, - static_cast *>(this), this->output_ports() ); - } +#if TBB_PREVIEW_FLOW_GRAPH_FEATURES + typedef typename base_type::predecessor_type predecessor_type; + typedef typename base_type::predecessor_list_type predecessor_list_type; + typedef internal::predecessor_cache predecessor_cache_type; + typedef typename predecessor_cache_type::built_predecessors_type built_predecessors_type; +#endif - split_node( const split_node & other) : base_type(other) { - tbb::internal::fgt_multioutput_node( tbb::internal::FLOW_SPLIT_NODE, &this->graph_node::my_graph, - static_cast *>(this), this->output_ports() ); + typedef typename internal::wrap_tuple_elements< + N, // #elements in tuple + internal::multifunction_output, // wrap this around each element + TupleType // the tuple providing the types + >::type output_ports_type; + + explicit split_node(graph &g) : graph_node(g) + { + tbb::internal::fgt_multioutput_node(tbb::internal::FLOW_SPLIT_NODE, &this->my_graph, + static_cast *>(this), this->output_ports()); + } + split_node( const split_node & other) : graph_node(other.my_graph), base_type(other) + { + tbb::internal::fgt_multioutput_node(tbb::internal::FLOW_SPLIT_NODE, &this->my_graph, + static_cast *>(this), this->output_ports()); } #if TBB_PREVIEW_FLOW_GRAPH_TRACE - /* override */ void set_name( const char *name ) { + void set_name( const char *name ) __TBB_override { tbb::internal::fgt_multioutput_node_desc( this, name ); } #endif + output_ports_type &output_ports() { return my_output_ports; } + +protected: + task *try_put_task(const TupleType& t) __TBB_override { + // Sending split messages in parallel is not justified, as overheads would prevail + internal::emit_element::emit_this(t, output_ports()); + + //we do not have successors here.So we just tell the task is successful. + return SUCCESSFULLY_ENQUEUED; + } + void reset_node(reset_flags f) __TBB_override { + if (f & rf_clear_edges) + internal::clear_element::clear_this(my_output_ports); + + __TBB_ASSERT(!(f & rf_clear_edges) || internal::clear_element::this_empty(my_output_ports), "split_node reset failed"); + } + void reset_receiver(reset_flags /*f*/) __TBB_override {} + +#if TBB_PREVIEW_FLOW_GRAPH_FEATURES +private: //! split_node doesn't use this "predecessors" functionality; so, we have "dummies" here; + void extract() __TBB_override {} + + //! Adds to list of predecessors added by make_edge + void internal_add_built_predecessor(predecessor_type&) __TBB_override {} + + //! removes from to list of predecessors (used by remove_edge) + void internal_delete_built_predecessor(predecessor_type&) __TBB_override {} + + size_t predecessor_count() __TBB_override { return 0; } + + void copy_predecessors(predecessor_list_type&) __TBB_override {} + + built_predecessors_type &built_predecessors() __TBB_override { return my_predessors; } + + //! dummy member + built_predecessors_type my_predessors; +#endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */ + +private: + output_ports_type my_output_ports; }; //! Implements an executable node that supports continue_msg -> Output template class continue_node : public graph_node, public internal::continue_input, public internal::function_output { -protected: - using graph_node::my_graph; public: typedef continue_msg input_type; typedef Output output_type; - typedef sender< input_type > predecessor_type; - typedef receiver< output_type > successor_type; typedef internal::continue_input fInput_type; typedef internal::function_output fOutput_type; + typedef typename fInput_type::predecessor_type predecessor_type; + typedef typename fOutput_type::successor_type successor_type; //! Constructor for executable node with continue_msg -> Output template @@ -1306,7 +1541,7 @@ public: //! Copy constructor continue_node( const continue_node& src ) : - graph_node(src.graph_node::my_graph), internal::continue_input(src), + graph_node(src.my_graph), internal::continue_input(src), internal::function_output() { tbb::internal::fgt_node_with_body( tbb::internal::FLOW_CONTINUE_NODE, &this->my_graph, static_cast *>(this), @@ -1314,13 +1549,13 @@ public: } #if TBB_PREVIEW_FLOW_GRAPH_TRACE - /* override */ void set_name( const char *name ) { + void set_name( const char *name ) __TBB_override { tbb::internal::fgt_node_desc( this, name ); } #endif #if TBB_PREVIEW_FLOW_GRAPH_FEATURES - /*override graph_node*/ void extract() { + void extract() __TBB_override { fInput_type::my_built_predecessors.receiver_extract(*this); successors().built_successors().sender_extract(*this); } @@ -1331,25 +1566,22 @@ protected: template friend class internal::broadcast_cache; template friend class internal::round_robin_cache; using fInput_type::try_put_task; - /* override */ internal::broadcast_cache &successors () { return fOutput_type::my_successors; } + internal::broadcast_cache &successors () __TBB_override { return fOutput_type::my_successors; } - /*override*/void reset_node(reset_flags f) { + void reset_node(reset_flags f) __TBB_override { fInput_type::reset_receiver(f); if(f & rf_clear_edges)successors().clear(); __TBB_ASSERT(!(f & rf_clear_edges) || successors().empty(), "continue_node not reset"); } - }; // continue_node template< typename T > class overwrite_node : public graph_node, public receiver, public sender { -protected: - using graph_node::my_graph; public: typedef T input_type; typedef T output_type; - typedef sender< input_type > predecessor_type; - typedef receiver< output_type > successor_type; + typedef typename receiver::predecessor_type predecessor_type; + typedef typename sender::successor_type successor_type; #if TBB_PREVIEW_FLOW_GRAPH_FEATURES typedef typename receiver::built_predecessors_type built_predecessors_type; typedef typename sender::built_successors_type built_successors_type; @@ -1357,7 +1589,7 @@ public: typedef typename sender::successor_list_type successor_list_type; #endif - overwrite_node(graph &g) : graph_node(g), my_buffer_is_valid(false) { + explicit overwrite_node(graph &g) : graph_node(g), my_buffer_is_valid(false) { my_successors.set_owner( this ); tbb::internal::fgt_node( tbb::internal::FLOW_OVERWRITE_NODE, &this->my_graph, static_cast *>(this), static_cast *>(this) ); @@ -1375,12 +1607,12 @@ public: ~overwrite_node() {} #if TBB_PREVIEW_FLOW_GRAPH_TRACE - /* override */ void set_name( const char *name ) { + void set_name( const char *name ) __TBB_override { tbb::internal::fgt_node_desc( this, name ); } #endif - /* override */ bool register_successor( successor_type &s ) { + bool register_successor( successor_type &s ) __TBB_override { spin_mutex::scoped_lock l( my_mutex ); if (my_buffer_is_valid && this->my_graph.is_active()) { // We have a valid value that must be forwarded immediately. @@ -1398,57 +1630,57 @@ public: return true; } - /* override */ bool remove_successor( successor_type &s ) { + bool remove_successor( successor_type &s ) __TBB_override { spin_mutex::scoped_lock l( my_mutex ); my_successors.remove_successor(s); return true; } #if TBB_PREVIEW_FLOW_GRAPH_FEATURES - /*override*/built_predecessors_type &built_predecessors() { return my_built_predecessors; } - /*override*/built_successors_type &built_successors() { return my_successors.built_successors(); } + built_predecessors_type &built_predecessors() __TBB_override { return my_built_predecessors; } + built_successors_type &built_successors() __TBB_override { return my_successors.built_successors(); } - /*override*/void internal_add_built_successor( successor_type &s) { + void internal_add_built_successor( successor_type &s) __TBB_override { spin_mutex::scoped_lock l( my_mutex ); my_successors.internal_add_built_successor(s); } - /*override*/void internal_delete_built_successor( successor_type &s) { + void internal_delete_built_successor( successor_type &s) __TBB_override { spin_mutex::scoped_lock l( my_mutex ); my_successors.internal_delete_built_successor(s); } - /*override*/size_t successor_count() { + size_t successor_count() __TBB_override { spin_mutex::scoped_lock l( my_mutex ); return my_successors.successor_count(); } - /*override*/ void copy_successors(successor_list_type &v) { + void copy_successors(successor_list_type &v) __TBB_override { spin_mutex::scoped_lock l( my_mutex ); my_successors.copy_successors(v); } - /*override*/ void internal_add_built_predecessor( predecessor_type &p) { + void internal_add_built_predecessor( predecessor_type &p) __TBB_override { spin_mutex::scoped_lock l( my_mutex ); my_built_predecessors.add_edge(p); } - /*override*/ void internal_delete_built_predecessor( predecessor_type &p) { + void internal_delete_built_predecessor( predecessor_type &p) __TBB_override { spin_mutex::scoped_lock l( my_mutex ); my_built_predecessors.delete_edge(p); } - /*override*/size_t predecessor_count() { + size_t predecessor_count() __TBB_override { spin_mutex::scoped_lock l( my_mutex ); return my_built_predecessors.edge_count(); } - /*override*/void copy_predecessors(predecessor_list_type &v) { + void copy_predecessors(predecessor_list_type &v) __TBB_override { spin_mutex::scoped_lock l( my_mutex ); my_built_predecessors.copy_edges(v); } - /*override*/ void extract() { + void extract() __TBB_override { my_buffer_is_valid = false; built_successors().sender_extract(*this); built_predecessors().receiver_extract(*this); @@ -1456,7 +1688,7 @@ public: #endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */ - /* override */ bool try_get( input_type &v ) { + bool try_get( input_type &v ) __TBB_override { spin_mutex::scoped_lock l( my_mutex ); if ( my_buffer_is_valid ) { v = my_buffer; @@ -1479,8 +1711,12 @@ protected: template< typename R, typename B > friend class run_and_put_task; template friend class internal::broadcast_cache; template 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 { spin_mutex::scoped_lock l( my_mutex ); + return try_put_task_impl(v); + } + + task * try_put_task_impl(const input_type &v) { my_buffer = v; my_buffer_is_valid = true; task * rtask = my_successors.try_put_task(v); @@ -1495,9 +1731,9 @@ protected: #endif input_type my_buffer; bool my_buffer_is_valid; - /*override*/void reset_receiver(reset_flags /*f*/) {} + void reset_receiver(reset_flags /*f*/) __TBB_override {} - /*override*/void reset_node( reset_flags f) { + void reset_node( reset_flags f) __TBB_override { my_buffer_is_valid = false; if (f&rf_clear_edges) { my_successors.clear(); @@ -1510,11 +1746,11 @@ class write_once_node : public overwrite_node { public: typedef T input_type; typedef T output_type; - typedef sender< input_type > predecessor_type; - typedef receiver< output_type > successor_type; + typedef typename receiver::predecessor_type predecessor_type; + typedef typename sender::successor_type successor_type; //! Constructor - write_once_node(graph& g) : overwrite_node(g) { + explicit write_once_node(graph& g) : overwrite_node(g) { tbb::internal::fgt_node( tbb::internal::FLOW_WRITE_ONCE_NODE, &(this->my_graph), static_cast *>(this), static_cast *>(this) ); @@ -1528,7 +1764,7 @@ public: } #if TBB_PREVIEW_FLOW_GRAPH_TRACE - /* override */ void set_name( const char *name ) { + void set_name( const char *name ) __TBB_override { tbb::internal::fgt_node_desc( this, name ); } #endif @@ -1537,30 +1773,20 @@ protected: template< typename R, typename B > friend class run_and_put_task; template friend class internal::broadcast_cache; template friend class internal::round_robin_cache; - /* override */ task *try_put_task( const T &v ) { + task *try_put_task( const T &v ) __TBB_override { spin_mutex::scoped_lock l( this->my_mutex ); - if ( this->my_buffer_is_valid ) { - return NULL; - } else { - this->my_buffer = v; - this->my_buffer_is_valid = true; - task *res = this->my_successors.try_put_task(v); - if (!res) res = SUCCESSFULLY_ENQUEUED; - return res; - } + return this->my_buffer_is_valid ? NULL : this->try_put_task_impl(v); } }; //! Forwards messages of type T to all successors template class broadcast_node : public graph_node, public receiver, public sender { -protected: - using graph_node::my_graph; public: typedef T input_type; typedef T output_type; - typedef sender< input_type > predecessor_type; - typedef receiver< output_type > successor_type; + typedef typename receiver::predecessor_type predecessor_type; + typedef typename sender::successor_type successor_type; #if TBB_PREVIEW_FLOW_GRAPH_FEATURES typedef typename receiver::predecessor_list_type predecessor_list_type; typedef typename sender::successor_list_type successor_list_type; @@ -1573,7 +1799,7 @@ private: #endif public: - broadcast_node(graph& g) : graph_node(g) { + explicit broadcast_node(graph& g) : graph_node(g) { my_successors.set_owner( this ); tbb::internal::fgt_node( tbb::internal::FLOW_BROADCAST_NODE, &this->my_graph, static_cast *>(this), static_cast *>(this) ); @@ -1589,19 +1815,19 @@ public: } #if TBB_PREVIEW_FLOW_GRAPH_TRACE - /* override */ void set_name( const char *name ) { + void set_name( const char *name ) __TBB_override { tbb::internal::fgt_node_desc( this, name ); } #endif //! Adds a successor - virtual bool register_successor( receiver &r ) { + bool register_successor( successor_type &r ) __TBB_override { my_successors.register_successor( r ); return true; } //! Removes s as a successor - virtual bool remove_successor( receiver &r ) { + bool remove_successor( successor_type &r ) __TBB_override { my_successors.remove_successor( r ); return true; } @@ -1609,49 +1835,49 @@ public: #if TBB_PREVIEW_FLOW_GRAPH_FEATURES typedef typename sender::built_successors_type built_successors_type; - /*override sender*/ built_successors_type &built_successors() { return my_successors.built_successors(); } + built_successors_type &built_successors() __TBB_override { return my_successors.built_successors(); } - /*override sender*/ void internal_add_built_successor(successor_type &r) { + void internal_add_built_successor(successor_type &r) __TBB_override { my_successors.internal_add_built_successor(r); } - /*override sender*/ void internal_delete_built_successor(successor_type &r) { + void internal_delete_built_successor(successor_type &r) __TBB_override { my_successors.internal_delete_built_successor(r); } - /*override sender*/ size_t successor_count() { + size_t successor_count() __TBB_override { return my_successors.successor_count(); } - /*override*/ void copy_successors(successor_list_type &v) { + void copy_successors(successor_list_type &v) __TBB_override { my_successors.copy_successors(v); } typedef typename receiver::built_predecessors_type built_predecessors_type; - /*override receiver*/ 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( predecessor_type &p) { + void internal_add_built_predecessor( predecessor_type &p) __TBB_override { spin_mutex::scoped_lock l(pred_mutex); my_built_predecessors.add_edge(p); } - /*override*/ void internal_delete_built_predecessor( predecessor_type &p) { + void internal_delete_built_predecessor( predecessor_type &p) __TBB_override { spin_mutex::scoped_lock l(pred_mutex); my_built_predecessors.delete_edge(p); } - /*override*/ size_t predecessor_count() { + size_t predecessor_count() __TBB_override { spin_mutex::scoped_lock l(pred_mutex); return my_built_predecessors.edge_count(); } - /*override*/ void copy_predecessors(predecessor_list_type &v) { + void copy_predecessors(predecessor_list_type &v) __TBB_override { spin_mutex::scoped_lock l(pred_mutex); my_built_predecessors.copy_edges(v); } - /*override graph_node*/ void extract() { + void extract() __TBB_override { my_built_predecessors.receiver_extract(*this); my_successors.built_successors().sender_extract(*this); } @@ -1662,15 +1888,15 @@ protected: template friend class internal::broadcast_cache; template friend class internal::round_robin_cache; //! build a task to run the successor if possible. Default is old behavior. - /*override*/ task *try_put_task(const T& t) { + task *try_put_task(const T& t) __TBB_override { task *new_task = my_successors.try_put_task(t); if (!new_task) new_task = SUCCESSFULLY_ENQUEUED; return new_task; } - /*override*/void reset_receiver(reset_flags /*f*/) {} + void reset_receiver(reset_flags /*f*/) __TBB_override {} - /*override*/void reset_node(reset_flags f) { + void reset_node(reset_flags f) __TBB_override { if (f&rf_clear_edges) { my_successors.clear(); #if TBB_PREVIEW_FLOW_GRAPH_FEATURES @@ -1684,13 +1910,11 @@ protected: //! Forwards messages in arbitrary order template > class buffer_node : public graph_node, public internal::reservable_item_buffer, public receiver, public sender { -protected: - using graph_node::my_graph; public: typedef T input_type; typedef T output_type; - typedef sender< input_type > predecessor_type; - typedef receiver< output_type > successor_type; + typedef typename receiver::predecessor_type predecessor_type; + typedef typename sender::successor_type successor_type; typedef buffer_node class_type; #if TBB_PREVIEW_FLOW_GRAPH_FEATURES typedef typename receiver::predecessor_list_type predecessor_list_type; @@ -1714,7 +1938,6 @@ protected: blt_succ_cpy, blt_pred_cpy // create vector copies of preds and succs #endif }; - enum op_stat {WAIT=0, SUCCEEDED, FAILED}; // implements the aggregator_operation concept class buffer_operation : public internal::aggregated_operation< buffer_operation > { @@ -1752,19 +1975,26 @@ protected: internal::aggregator< handler_type, buffer_operation> my_aggregator; virtual void handle_operations(buffer_operation *op_list) { + handle_operations_impl(op_list, this); + } + + template + void handle_operations_impl(buffer_operation *op_list, derived_type* derived) { + __TBB_ASSERT(static_cast(derived) == this, "'this' is not a base class for derived"); + buffer_operation *tmp = NULL; - bool try_forwarding=false; + bool try_forwarding = false; while (op_list) { tmp = op_list; op_list = op_list->next; switch (tmp->type) { - case reg_succ: internal_reg_succ(tmp); try_forwarding = true; break; + case reg_succ: internal_reg_succ(tmp); try_forwarding = true; break; case rem_succ: internal_rem_succ(tmp); break; case req_item: internal_pop(tmp); break; case res_item: internal_reserve(tmp); break; - case rel_res: internal_release(tmp); try_forwarding = true; break; - case con_res: internal_consume(tmp); try_forwarding = true; break; - case put_item: internal_push(tmp); try_forwarding = (tmp->status == SUCCEEDED); break; + case rel_res: internal_release(tmp); try_forwarding = true; break; + case con_res: internal_consume(tmp); try_forwarding = true; break; + case put_item: try_forwarding = internal_push(tmp); break; case try_fwd_task: internal_forward_task(tmp); break; #if TBB_PREVIEW_FLOW_GRAPH_FEATURES // edge recording @@ -1779,6 +2009,9 @@ protected: #endif } } + + derived->order(); + if (try_forwarding && !forwarder_busy) { if(this->my_graph.is_active()) { forwarder_busy = true; @@ -1811,144 +2044,161 @@ protected: buffer_operation op_data(try_fwd_task); task *last_task = NULL; do { - op_data.status = WAIT; + op_data.status = internal::WAIT; op_data.ltask = NULL; my_aggregator.execute(&op_data); tbb::task *xtask = op_data.ltask; last_task = combine_tasks(last_task, xtask); - } while (op_data.status == SUCCEEDED); + } while (op_data.status ==internal::SUCCEEDED); return last_task; } //! Register successor virtual void internal_reg_succ(buffer_operation *op) { my_successors.register_successor(*(op->r)); - __TBB_store_with_release(op->status, SUCCEEDED); + __TBB_store_with_release(op->status, internal::SUCCEEDED); } //! Remove successor virtual void internal_rem_succ(buffer_operation *op) { my_successors.remove_successor(*(op->r)); - __TBB_store_with_release(op->status, SUCCEEDED); + __TBB_store_with_release(op->status, internal::SUCCEEDED); } #if TBB_PREVIEW_FLOW_GRAPH_FEATURES typedef typename sender::built_successors_type built_successors_type; - /*override sender*/ built_successors_type &built_successors() { return my_successors.built_successors(); } + built_successors_type &built_successors() __TBB_override { return my_successors.built_successors(); } virtual void internal_add_built_succ(buffer_operation *op) { my_successors.internal_add_built_successor(*(op->r)); - __TBB_store_with_release(op->status, SUCCEEDED); + __TBB_store_with_release(op->status, internal::SUCCEEDED); } virtual void internal_del_built_succ(buffer_operation *op) { my_successors.internal_delete_built_successor(*(op->r)); - __TBB_store_with_release(op->status, SUCCEEDED); + __TBB_store_with_release(op->status, internal::SUCCEEDED); } typedef typename receiver::built_predecessors_type built_predecessors_type; - /*override receiver*/ built_predecessors_type &built_predecessors() { return my_built_predecessors; } + built_predecessors_type &built_predecessors() __TBB_override { return my_built_predecessors; } virtual void internal_add_built_pred(buffer_operation *op) { my_built_predecessors.add_edge(*(op->p)); - __TBB_store_with_release(op->status, SUCCEEDED); + __TBB_store_with_release(op->status, internal::SUCCEEDED); } virtual void internal_del_built_pred(buffer_operation *op) { my_built_predecessors.delete_edge(*(op->p)); - __TBB_store_with_release(op->status, SUCCEEDED); + __TBB_store_with_release(op->status, internal::SUCCEEDED); } virtual void internal_succ_cnt(buffer_operation *op) { op->cnt_val = my_successors.successor_count(); - __TBB_store_with_release(op->status, SUCCEEDED); + __TBB_store_with_release(op->status, internal::SUCCEEDED); } virtual void internal_pred_cnt(buffer_operation *op) { op->cnt_val = my_built_predecessors.edge_count(); - __TBB_store_with_release(op->status, SUCCEEDED); + __TBB_store_with_release(op->status, internal::SUCCEEDED); } virtual void internal_copy_succs(buffer_operation *op) { my_successors.copy_successors(*(op->svec)); - __TBB_store_with_release(op->status, SUCCEEDED); + __TBB_store_with_release(op->status, internal::SUCCEEDED); } virtual void internal_copy_preds(buffer_operation *op) { my_built_predecessors.copy_edges(*(op->pvec)); - __TBB_store_with_release(op->status, SUCCEEDED); + __TBB_store_with_release(op->status, internal::SUCCEEDED); } #endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */ +private: + void order() {} + + bool is_item_valid() { + return this->my_item_valid(this->my_tail - 1); + } + + void try_put_and_add_task(task*& last_task) { + task *new_task = my_successors.try_put_task(this->back()); + if (new_task) { + last_task = combine_tasks(last_task, new_task); + this->destroy_back(); + } + } + +protected: //! Tries to forward valid items to successors virtual void internal_forward_task(buffer_operation *op) { - if (this->my_reserved || !this->my_item_valid(this->my_tail-1)) { - __TBB_store_with_release(op->status, FAILED); + internal_forward_task_impl(op, this); + } + + template + void internal_forward_task_impl(buffer_operation *op, derived_type* derived) { + __TBB_ASSERT(static_cast(derived) == this, "'this' is not a base class for derived"); + + if (this->my_reserved || !derived->is_item_valid()) { + __TBB_store_with_release(op->status, internal::FAILED); this->forwarder_busy = false; return; } - T i_copy; + // Try forwarding, giving each successor a chance task * last_task = NULL; size_type counter = my_successors.size(); - // Try forwarding, giving each successor a chance - while (counter>0 && !this->buffer_empty() && this->my_item_valid(this->my_tail-1)) { - this->copy_back(i_copy); - task *new_task = my_successors.try_put_task(i_copy); - if(new_task) { - last_task = combine_tasks(last_task, new_task); - this->destroy_back(); - } - --counter; - } + for (; counter > 0 && derived->is_item_valid(); --counter) + derived->try_put_and_add_task(last_task); + op->ltask = last_task; // return task if (last_task && !counter) { - __TBB_store_with_release(op->status, SUCCEEDED); + __TBB_store_with_release(op->status, internal::SUCCEEDED); } else { - __TBB_store_with_release(op->status, FAILED); + __TBB_store_with_release(op->status, internal::FAILED); forwarder_busy = false; } } - virtual void internal_push(buffer_operation *op) { + virtual bool internal_push(buffer_operation *op) { this->push_back(*(op->elem)); - __TBB_store_with_release(op->status, SUCCEEDED); + __TBB_store_with_release(op->status, internal::SUCCEEDED); + return true; } virtual void internal_pop(buffer_operation *op) { if(this->pop_back(*(op->elem))) { - __TBB_store_with_release(op->status, SUCCEEDED); + __TBB_store_with_release(op->status, internal::SUCCEEDED); } else { - __TBB_store_with_release(op->status, FAILED); + __TBB_store_with_release(op->status, internal::FAILED); } } virtual void internal_reserve(buffer_operation *op) { if(this->reserve_front(*(op->elem))) { - __TBB_store_with_release(op->status, SUCCEEDED); + __TBB_store_with_release(op->status, internal::SUCCEEDED); } else { - __TBB_store_with_release(op->status, FAILED); + __TBB_store_with_release(op->status, internal::FAILED); } } virtual void internal_consume(buffer_operation *op) { this->consume_front(); - __TBB_store_with_release(op->status, SUCCEEDED); + __TBB_store_with_release(op->status, internal::SUCCEEDED); } virtual void internal_release(buffer_operation *op) { this->release_front(); - __TBB_store_with_release(op->status, SUCCEEDED); + __TBB_store_with_release(op->status, internal::SUCCEEDED); } public: //! Constructor - buffer_node( graph &g ) : graph_node(g), internal::reservable_item_buffer(), + explicit buffer_node( graph &g ) : graph_node(g), internal::reservable_item_buffer(), forwarder_busy(false) { my_successors.set_owner(this); my_aggregator.initialize_handler(handler_type(this)); @@ -1966,10 +2216,8 @@ public: static_cast *>(this), static_cast *>(this) ); } - virtual ~buffer_node() {} - #if TBB_PREVIEW_FLOW_GRAPH_TRACE - /* override */ void set_name( const char *name ) { + void set_name( const char *name ) __TBB_override { tbb::internal::fgt_node_desc( this, name ); } #endif @@ -1980,7 +2228,7 @@ public: //! Adds a new successor. /** Adds successor r to the list of successors; may forward tasks. */ - /* override */ bool register_successor( successor_type &r ) { + bool register_successor( successor_type &r ) __TBB_override { buffer_operation op_data(reg_succ); op_data.r = &r; my_aggregator.execute(&op_data); @@ -1989,49 +2237,49 @@ public: } #if TBB_PREVIEW_FLOW_GRAPH_FEATURES - /*override*/ void internal_add_built_successor( successor_type &r) { + void internal_add_built_successor( successor_type &r) __TBB_override { buffer_operation op_data(add_blt_succ); op_data.r = &r; my_aggregator.execute(&op_data); } - /*override*/ void internal_delete_built_successor( successor_type &r) { + void internal_delete_built_successor( successor_type &r) __TBB_override { buffer_operation op_data(del_blt_succ); op_data.r = &r; my_aggregator.execute(&op_data); } - /*override*/ void internal_add_built_predecessor( predecessor_type &p) { + void internal_add_built_predecessor( predecessor_type &p) __TBB_override { buffer_operation op_data(add_blt_pred); op_data.p = &p; my_aggregator.execute(&op_data); } - /*override*/ void internal_delete_built_predecessor( predecessor_type &p) { + void internal_delete_built_predecessor( predecessor_type &p) __TBB_override { buffer_operation op_data(del_blt_pred); op_data.p = &p; my_aggregator.execute(&op_data); } - /*override*/ size_t predecessor_count() { + size_t predecessor_count() __TBB_override { buffer_operation op_data(blt_pred_cnt); my_aggregator.execute(&op_data); return op_data.cnt_val; } - /*override*/ size_t successor_count() { + size_t successor_count() __TBB_override { buffer_operation op_data(blt_succ_cnt); my_aggregator.execute(&op_data); return op_data.cnt_val; } - /*override*/ void copy_predecessors( predecessor_list_type &v ) { + void copy_predecessors( predecessor_list_type &v ) __TBB_override { buffer_operation op_data(blt_pred_cpy); op_data.pvec = &v; my_aggregator.execute(&op_data); } - /*override*/ void copy_successors( successor_list_type &v ) { + void copy_successors( successor_list_type &v ) __TBB_override { buffer_operation op_data(blt_succ_cpy); op_data.svec = &v; my_aggregator.execute(&op_data); @@ -2042,7 +2290,7 @@ public: //! Removes a successor. /** Removes successor r from the list of successors. It also calls r.remove_predecessor(*this) to remove this node as a predecessor. */ - /* override */ bool remove_successor( successor_type &r ) { + bool remove_successor( successor_type &r ) __TBB_override { r.remove_predecessor(*this); buffer_operation op_data(rem_succ); op_data.r = &r; @@ -2057,28 +2305,28 @@ public: //! Request an item from the buffer_node /** true = v contains the returned item
false = no item has been returned */ - /* override */ bool try_get( T &v ) { + bool try_get( T &v ) __TBB_override { buffer_operation op_data(req_item); op_data.elem = &v; my_aggregator.execute(&op_data); (void)enqueue_forwarding_task(op_data); - return (op_data.status==SUCCEEDED); + return (op_data.status==internal::SUCCEEDED); } //! Reserves an item. /** false = no item can be reserved
true = an item is reserved */ - /* override */ bool try_reserve( T &v ) { + bool try_reserve( T &v ) __TBB_override { buffer_operation op_data(res_item); op_data.elem = &v; my_aggregator.execute(&op_data); (void)enqueue_forwarding_task(op_data); - return (op_data.status==SUCCEEDED); + return (op_data.status==internal::SUCCEEDED); } //! Release a reserved item. /** true = item has been released and so remains in sender */ - /* override */ bool try_release() { + bool try_release() __TBB_override { buffer_operation op_data(rel_res); my_aggregator.execute(&op_data); (void)enqueue_forwarding_task(op_data); @@ -2087,7 +2335,7 @@ public: //! Consumes a reserved item. /** true = item is removed from sender and reservation removed */ - /* override */ bool try_consume() { + bool try_consume() __TBB_override { buffer_operation op_data(con_res); my_aggregator.execute(&op_data); (void)enqueue_forwarding_task(op_data); @@ -2100,37 +2348,37 @@ protected: template friend class internal::broadcast_cache; template friend class internal::round_robin_cache; //! receive an item, return a task *if possible - /* override */ task *try_put_task(const T &t) { + task *try_put_task(const T &t) __TBB_override { buffer_operation op_data(t, put_item); my_aggregator.execute(&op_data); task *ft = grab_forwarding_task(op_data); // sequencer_nodes can return failure (if an item has been previously inserted) // We have to spawn the returned task if our own operation fails. - if(ft && op_data.status == FAILED) { + if(ft && op_data.status ==internal::FAILED) { // we haven't succeeded queueing the item, but for some reason the // call returned a task (if another request resulted in a successful // forward this could happen.) Queue the task and reset the pointer. FLOW_SPAWN(*ft); ft = NULL; } - else if(!ft && op_data.status == SUCCEEDED) { + else if(!ft && op_data.status ==internal::SUCCEEDED) { ft = SUCCESSFULLY_ENQUEUED; } return ft; } - /*override*/void reset_receiver(reset_flags /*f*/) { } + void reset_receiver(reset_flags /*f*/) __TBB_override { } #if TBB_PREVIEW_FLOW_GRAPH_FEATURES public: - /* override*/ void extract() { + void extract() __TBB_override { my_built_predecessors.receiver_extract(*this); my_successors.built_successors().sender_extract(*this); } #endif protected: - /*override*/void reset_node( reset_flags f) { + void reset_node( reset_flags f) __TBB_override { internal::reservable_item_buffer::reset(); // TODO: just clear structures if (f&rf_clear_edges) { @@ -2141,8 +2389,6 @@ protected: } forwarder_busy = false; } - - }; // buffer_node //! Forwards messages in FIFO order @@ -2152,68 +2398,59 @@ protected: typedef buffer_node base_type; typedef typename base_type::size_type size_type; typedef typename base_type::buffer_operation queue_operation; + typedef queue_node class_type; - enum op_stat {WAIT=0, SUCCEEDED, FAILED}; +private: + template friend class buffer_node; - /* override */ void internal_forward_task(queue_operation *op) { - if (this->my_reserved || !this->my_item_valid(this->my_head)) { - __TBB_store_with_release(op->status, FAILED); - this->forwarder_busy = false; - return; - } - T i_copy; - task *last_task = NULL; - size_type counter = this->my_successors.size(); - // Keep trying to send items while there is at least one accepting successor - while (counter>0 && this->my_item_valid(this->my_head)) { - this->copy_front(i_copy); - task *new_task = this->my_successors.try_put_task(i_copy); - if(new_task) { - this->destroy_front(); - last_task = combine_tasks(last_task, new_task); - } - --counter; - } - op->ltask = last_task; - if (last_task && !counter) - __TBB_store_with_release(op->status, SUCCEEDED); - else { - __TBB_store_with_release(op->status, FAILED); - this->forwarder_busy = false; + bool is_item_valid() { + return this->my_item_valid(this->my_head); + } + + void try_put_and_add_task(task*& last_task) { + task *new_task = this->my_successors.try_put_task(this->front()); + if (new_task) { + last_task = combine_tasks(last_task, new_task); + this->destroy_front(); } } - /* override */ void internal_pop(queue_operation *op) { +protected: + void internal_forward_task(queue_operation *op) __TBB_override { + this->internal_forward_task_impl(op, this); + } + + void internal_pop(queue_operation *op) __TBB_override { if ( this->my_reserved || !this->my_item_valid(this->my_head)){ - __TBB_store_with_release(op->status, FAILED); + __TBB_store_with_release(op->status, internal::FAILED); } else { this->pop_front(*(op->elem)); - __TBB_store_with_release(op->status, SUCCEEDED); + __TBB_store_with_release(op->status, internal::SUCCEEDED); } } - /* override */ void internal_reserve(queue_operation *op) { + void internal_reserve(queue_operation *op) __TBB_override { if (this->my_reserved || !this->my_item_valid(this->my_head)) { - __TBB_store_with_release(op->status, FAILED); + __TBB_store_with_release(op->status, internal::FAILED); } else { this->reserve_front(*(op->elem)); - __TBB_store_with_release(op->status, SUCCEEDED); + __TBB_store_with_release(op->status, internal::SUCCEEDED); } } - /* override */ void internal_consume(queue_operation *op) { + void internal_consume(queue_operation *op) __TBB_override { this->consume_front(); - __TBB_store_with_release(op->status, SUCCEEDED); + __TBB_store_with_release(op->status, internal::SUCCEEDED); } public: typedef T input_type; typedef T output_type; - typedef sender< input_type > predecessor_type; - typedef receiver< output_type > successor_type; + typedef typename receiver::predecessor_type predecessor_type; + typedef typename sender::successor_type successor_type; //! Constructor - queue_node( graph &g ) : base_type(g) { + explicit queue_node( graph &g ) : base_type(g) { tbb::internal::fgt_node( tbb::internal::FLOW_QUEUE_NODE, &(this->my_graph), static_cast *>(this), static_cast *>(this) ); @@ -2227,13 +2464,13 @@ public: } #if TBB_PREVIEW_FLOW_GRAPH_TRACE - /* override */ void set_name( const char *name ) { + void set_name( const char *name ) __TBB_override { tbb::internal::fgt_node_desc( this, name ); } #endif protected: - /*override*/void reset_node( reset_flags f) { + void reset_node( reset_flags f) __TBB_override { base_type::reset_node(f); } }; // queue_node @@ -2247,8 +2484,8 @@ class sequencer_node : public queue_node { public: typedef T input_type; typedef T output_type; - typedef sender< input_type > predecessor_type; - typedef receiver< output_type > successor_type; + typedef typename receiver::predecessor_type predecessor_type; + typedef typename sender::successor_type successor_type; //! Constructor template< typename Sequencer > @@ -2271,7 +2508,7 @@ public: ~sequencer_node() { delete my_sequencer; } #if TBB_PREVIEW_FLOW_GRAPH_TRACE - /* override */ void set_name( const char *name ) { + void set_name( const char *name ) __TBB_override { tbb::internal::fgt_node_desc( this, name ); } #endif @@ -2280,32 +2517,27 @@ protected: typedef typename buffer_node::size_type size_type; typedef typename buffer_node::buffer_operation sequencer_operation; - enum op_stat {WAIT=0, SUCCEEDED, FAILED}; - private: - /* override */ void internal_push(sequencer_operation *op) { + bool internal_push(sequencer_operation *op) __TBB_override { size_type tag = (*my_sequencer)(*(op->elem)); #if !TBB_DEPRECATED_SEQUENCER_DUPLICATES - if(tag < this->my_head) { + if (tag < this->my_head) { // have already emitted a message with this tag - __TBB_store_with_release(op->status, FAILED); - return; + __TBB_store_with_release(op->status, internal::FAILED); + return false; } #endif // cannot modify this->my_tail now; the buffer would be inconsistent. size_t new_tail = (tag+1 > this->my_tail) ? tag+1 : this->my_tail; - if(this->size(new_tail) > this->capacity()) { + if (this->size(new_tail) > this->capacity()) { this->grow_my_array(this->size(new_tail)); } this->my_tail = new_tail; - if(this->place_item(tag,*(op->elem))) { - __TBB_store_with_release(op->status, SUCCEEDED); - } - else { - // already have a message with this tag - __TBB_store_with_release(op->status, FAILED); - } + + const internal::op_stat res = this->place_item(tag, *(op->elem)) ? internal::SUCCEEDED : internal::FAILED; + __TBB_store_with_release(op->status, res); + return res ==internal::SUCCEEDED; } }; // sequencer_node @@ -2316,11 +2548,12 @@ public: typedef T input_type; typedef T output_type; typedef buffer_node base_type; - typedef sender< input_type > predecessor_type; - typedef receiver< output_type > successor_type; + typedef priority_queue_node class_type; + typedef typename receiver::predecessor_type predecessor_type; + typedef typename sender::successor_type successor_type; //! Constructor - priority_queue_node( graph &g ) : buffer_node(g), mark(0) { + explicit priority_queue_node( graph &g ) : buffer_node(g), mark(0) { tbb::internal::fgt_node( tbb::internal::FLOW_PRIORITY_QUEUE_NODE, &(this->my_graph), static_cast *>(this), static_cast *>(this) ); @@ -2334,15 +2567,14 @@ public: } #if TBB_PREVIEW_FLOW_GRAPH_TRACE - /* override */ void set_name( const char *name ) { + void set_name( const char *name ) __TBB_override { tbb::internal::fgt_node_desc( this, name ); } #endif - protected: - /*override*/void reset_node( reset_flags f) { + void reset_node( reset_flags f) __TBB_override { mark = 0; base_type::reset_node(f); } @@ -2351,127 +2583,80 @@ protected: typedef typename buffer_node::item_type item_type; typedef typename buffer_node::buffer_operation prio_operation; - enum op_stat {WAIT=0, SUCCEEDED, FAILED}; - - /* override */ void handle_operations(prio_operation *op_list) { - prio_operation *tmp = op_list /*, *pop_list*/ ; - bool try_forwarding=false; - while (op_list) { - tmp = op_list; - op_list = op_list->next; - switch (tmp->type) { - case buffer_node::reg_succ: this->internal_reg_succ(tmp); try_forwarding = true; break; - case buffer_node::rem_succ: this->internal_rem_succ(tmp); break; - case buffer_node::put_item: internal_push(tmp); try_forwarding = true; break; - case buffer_node::try_fwd_task: internal_forward_task(tmp); break; - case buffer_node::rel_res: internal_release(tmp); try_forwarding = true; break; - case buffer_node::con_res: internal_consume(tmp); try_forwarding = true; break; - case buffer_node::req_item: internal_pop(tmp); break; - case buffer_node::res_item: internal_reserve(tmp); break; -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - case buffer_node::add_blt_succ: this->internal_add_built_succ(tmp); break; - case buffer_node::del_blt_succ: this->internal_del_built_succ(tmp); break; - case buffer_node::add_blt_pred: this->internal_add_built_pred(tmp); break; - case buffer_node::del_blt_pred: this->internal_del_built_pred(tmp); break; - case buffer_node::blt_succ_cnt: this->internal_succ_cnt(tmp); break; - case buffer_node::blt_pred_cnt: this->internal_pred_cnt(tmp); break; - case buffer_node::blt_succ_cpy: this->internal_copy_succs(tmp); break; - case buffer_node::blt_pred_cpy: this->internal_copy_preds(tmp); break; -#endif - } - } - // process pops! for now, no special pop processing - // concurrent_priority_queue handles pushes first, then pops. - // that is the genesis of this comment - if (markmy_tail) heapify(); - __TBB_ASSERT(mark == this->my_tail, "mark unequal after heapify"); - if (try_forwarding && !this->forwarder_busy) { // could we also test for this->my_tail (queue non-empty)? - if(this->my_graph.is_active()) { - this->forwarder_busy = true; - task *new_task = new(task::allocate_additional_child_of(*(this->my_graph.root_task()))) internal:: - forward_task_bypass - < buffer_node >(*this); - // tmp should point to the last item handled by the aggregator. This is the operation - // the handling thread enqueued. So modifying that record will be okay. - tbb::task *tmp1 = tmp->ltask; - tmp->ltask = combine_tasks(tmp1, new_task); - } - } - } - //! Tries to forward valid items to successors - /* override */ void internal_forward_task(prio_operation *op) { - T i_copy; - task * last_task = NULL; // flagged when a successor accepts - size_type counter = this->my_successors.size(); - - if (this->my_reserved || this->my_tail == 0) { - __TBB_store_with_release(op->status, FAILED); - this->forwarder_busy = false; - return; - } - // Keep trying to send while there exists an accepting successor - while (counter>0 && this->my_tail > 0) { - prio_copy(i_copy); - task * new_task = this->my_successors.try_put_task(i_copy); - if ( new_task ) { - last_task = combine_tasks(last_task, new_task); - prio_pop(); - } - --counter; - } - op->ltask = last_task; - if (last_task && !counter) - __TBB_store_with_release(op->status, SUCCEEDED); - else { - __TBB_store_with_release(op->status, FAILED); - this->forwarder_busy = false; - } + void internal_forward_task(prio_operation *op) __TBB_override { + this->internal_forward_task_impl(op, this); } - /* override */ void internal_push(prio_operation *op) { + void handle_operations(prio_operation *op_list) __TBB_override { + this->handle_operations_impl(op_list, this); + } + + bool internal_push(prio_operation *op) __TBB_override { prio_push(*(op->elem)); - __TBB_store_with_release(op->status, SUCCEEDED); + __TBB_store_with_release(op->status, internal::SUCCEEDED); + return true; } - /* override */ void internal_pop(prio_operation *op) { + void internal_pop(prio_operation *op) __TBB_override { // if empty or already reserved, don't pop if ( this->my_reserved == true || this->my_tail == 0 ) { - __TBB_store_with_release(op->status, FAILED); + __TBB_store_with_release(op->status, internal::FAILED); return; } - prio_copy(*(op->elem)); - __TBB_store_with_release(op->status, SUCCEEDED); + *(op->elem) = prio(); + __TBB_store_with_release(op->status, internal::SUCCEEDED); prio_pop(); } // pops the highest-priority item, saves copy - /* override */ void internal_reserve(prio_operation *op) { + void internal_reserve(prio_operation *op) __TBB_override { if (this->my_reserved == true || this->my_tail == 0) { - __TBB_store_with_release(op->status, FAILED); + __TBB_store_with_release(op->status, internal::FAILED); return; } this->my_reserved = true; - prio_copy(*(op->elem)); + *(op->elem) = prio(); reserved_item = *(op->elem); - __TBB_store_with_release(op->status, SUCCEEDED); + __TBB_store_with_release(op->status, internal::SUCCEEDED); prio_pop(); } - /* override */ void internal_consume(prio_operation *op) { - __TBB_store_with_release(op->status, SUCCEEDED); + void internal_consume(prio_operation *op) __TBB_override { + __TBB_store_with_release(op->status, internal::SUCCEEDED); this->my_reserved = false; reserved_item = input_type(); } - /* override */ void internal_release(prio_operation *op) { - __TBB_store_with_release(op->status, SUCCEEDED); + void internal_release(prio_operation *op) __TBB_override { + __TBB_store_with_release(op->status, internal::SUCCEEDED); prio_push(reserved_item); this->my_reserved = false; reserved_item = input_type(); } + +private: + template friend class buffer_node; + + void order() { + if (mark < this->my_tail) heapify(); + __TBB_ASSERT(mark == this->my_tail, "mark unequal after heapify"); + } + + bool is_item_valid() { + return this->my_tail > 0; + } + + void try_put_and_add_task(task*& last_task) { + task * new_task = this->my_successors.try_put_task(this->prio()); + if (new_task) { + last_task = combine_tasks(last_task, new_task); + prio_pop(); + } + } + private: Compare compare; size_type mark; @@ -2498,7 +2683,7 @@ private: // and mark. Assumes the array has already been tested for emptiness; no failure. void prio_pop() { if (prio_use_tail()) { - // there are newly pushed elems; last one higher than top + // there are newly pushed elements; last one higher than top // copy the data this->destroy_item(this->my_tail-1); --(this->my_tail); @@ -2518,13 +2703,8 @@ private: __TBB_ASSERT(mark <= this->my_tail, "mark outside bounds after pop"); } - void prio_copy(T &res) { - if (prio_use_tail()) { - res = this->get_my_item(this->my_tail - 1); - } - else { - res = this->get_my_item(0); - } + const T& prio() { + return this->get_my_item(prio_use_tail() ? this->my_tail-1 : 0); } // turn array into heap @@ -2576,19 +2756,18 @@ private: message is dropped. */ template< typename T > class limiter_node : public graph_node, public receiver< T >, public sender< T > { -protected: - using graph_node::my_graph; public: typedef T input_type; typedef T output_type; - typedef sender< input_type > predecessor_type; - typedef receiver< output_type > successor_type; + typedef typename receiver::predecessor_type predecessor_type; + typedef typename sender::successor_type successor_type; #if TBB_PREVIEW_FLOW_GRAPH_FEATURES typedef typename receiver::built_predecessors_type built_predecessors_type; typedef typename sender::built_successors_type built_successors_type; typedef typename receiver::predecessor_list_type predecessor_list_type; typedef typename sender::successor_list_type successor_list_type; #endif + //TODO: There is a lack of predefined types for its controlling "decrementer" port. It should be fixed later. private: size_t my_threshold; @@ -2622,7 +2801,7 @@ private: } //SUCCESS - // if we can reserve and can put, we consume the reservation + // if we can reserve and can put, we consume the reservation // we increment the count and decrement the tries if ( (my_predecessors.try_reserve(v)) == true ){ reserved=true; @@ -2709,13 +2888,13 @@ public: } #if TBB_PREVIEW_FLOW_GRAPH_TRACE - /* override */ void set_name( const char *name ) { + void set_name( const char *name ) __TBB_override { tbb::internal::fgt_node_desc( this, name ); } #endif //! Replace the current successor with this new successor - /* override */ bool register_successor( receiver &r ) { + bool register_successor( successor_type &r ) __TBB_override { spin_mutex::scoped_lock lock(my_mutex); bool was_empty = my_successors.empty(); my_successors.register_successor(r); @@ -2731,45 +2910,45 @@ public: //! Removes a successor from this node /** r.remove_predecessor(*this) is also called. */ - /* override */ bool remove_successor( receiver &r ) { + bool remove_successor( successor_type &r ) __TBB_override { r.remove_predecessor(*this); my_successors.remove_successor(r); return true; } #if TBB_PREVIEW_FLOW_GRAPH_FEATURES - /*override*/ built_successors_type &built_successors() { return my_successors.built_successors(); } - /*override*/ built_predecessors_type &built_predecessors() { return my_predecessors.built_predecessors(); } + built_successors_type &built_successors() __TBB_override { return my_successors.built_successors(); } + built_predecessors_type &built_predecessors() __TBB_override { return my_predecessors.built_predecessors(); } - /*override*/void internal_add_built_successor(receiver &src) { + void internal_add_built_successor(successor_type &src) __TBB_override { my_successors.internal_add_built_successor(src); } - /*override*/void internal_delete_built_successor(receiver &src) { + void internal_delete_built_successor(successor_type &src) __TBB_override { my_successors.internal_delete_built_successor(src); } - /*override*/size_t successor_count() { return my_successors.successor_count(); } + size_t successor_count() __TBB_override { return my_successors.successor_count(); } - /*override*/ void copy_successors(successor_list_type &v) { + void copy_successors(successor_list_type &v) __TBB_override { my_successors.copy_successors(v); } - /*override*/void internal_add_built_predecessor(sender &src) { + void internal_add_built_predecessor(predecessor_type &src) __TBB_override { my_predecessors.internal_add_built_predecessor(src); } - /*override*/void internal_delete_built_predecessor(sender &src) { + void internal_delete_built_predecessor(predecessor_type &src) __TBB_override { my_predecessors.internal_delete_built_predecessor(src); } - /*override*/size_t predecessor_count() { return my_predecessors.predecessor_count(); } + size_t predecessor_count() __TBB_override { return my_predecessors.predecessor_count(); } - /*override*/ void copy_predecessors(predecessor_list_type &v) { + void copy_predecessors(predecessor_list_type &v) __TBB_override { my_predecessors.copy_predecessors(v); } - /*override*/void extract() { + void extract() __TBB_override { my_count = 0; my_successors.built_successors().sender_extract(*this); my_predecessors.built_predecessors().receiver_extract(*this); @@ -2778,7 +2957,7 @@ public: #endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */ //! Adds src to the list of cached predecessors. - /* override */ bool register_predecessor( predecessor_type &src ) { + bool register_predecessor( predecessor_type &src ) __TBB_override { spin_mutex::scoped_lock lock(my_mutex); my_predecessors.add( src ); if ( my_count + my_tries < my_threshold && !my_successors.empty() && this->my_graph.is_active() ) { @@ -2789,7 +2968,7 @@ public: } //! Removes src from the list of cached predecessors. - /* override */ bool remove_predecessor( predecessor_type &src ) { + bool remove_predecessor( predecessor_type &src ) __TBB_override { my_predecessors.remove( src ); return true; } @@ -2800,7 +2979,7 @@ protected: template friend class internal::broadcast_cache; template friend class internal::round_robin_cache; //! Puts an item to this receiver - /* override */ task *try_put_task( const T &t ) { + task *try_put_task( const T &t ) __TBB_override { { spin_mutex::scoped_lock lock(my_mutex); if ( my_count + my_tries >= my_threshold ) @@ -2827,11 +3006,11 @@ protected: return rtask; } - /*override*/void reset_receiver(reset_flags /*f*/) { + void reset_receiver(reset_flags /*f*/) __TBB_override { __TBB_ASSERT(false,NULL); // should never be called } - /*override*/void reset_node( reset_flags f) { + void reset_node( reset_flags f) __TBB_override { my_count = 0; if(f & rf_clear_edges) { my_predecessors.clear(); @@ -2863,7 +3042,7 @@ private: public: typedef OutputTuple output_type; typedef typename unfolded_type::input_ports_type input_ports_type; - join_node(graph &g) : unfolded_type(g) { + explicit join_node(graph &g) : unfolded_type(g) { tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_JOIN_NODE_RESERVING, &this->my_graph, this->input_ports(), static_cast< sender< output_type > *>(this) ); } @@ -2873,7 +3052,7 @@ public: } #if TBB_PREVIEW_FLOW_GRAPH_TRACE - /* override */ void set_name( const char *name ) { + void set_name( const char *name ) __TBB_override { tbb::internal::fgt_node_desc( this, name ); } #endif @@ -2888,7 +3067,7 @@ private: public: typedef OutputTuple output_type; typedef typename unfolded_type::input_ports_type input_ports_type; - join_node(graph &g) : unfolded_type(g) { + explicit join_node(graph &g) : unfolded_type(g) { tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_JOIN_NODE_QUEUEING, &this->my_graph, this->input_ports(), static_cast< sender< output_type > *>(this) ); } @@ -2898,7 +3077,7 @@ public: } #if TBB_PREVIEW_FLOW_GRAPH_TRACE - /* override */ void set_name( const char *name ) { + void set_name( const char *name ) __TBB_override { tbb::internal::fgt_node_desc( this, name ); } #endif @@ -2993,7 +3172,7 @@ public: } #if TBB_PREVIEW_FLOW_GRAPH_TRACE - /* override */ void set_name( const char *name ) { + void set_name( const char *name ) __TBB_override { tbb::internal::fgt_node_desc( this, name ); } #endif @@ -3003,6 +3182,7 @@ public: // indexer node #include "internal/_flow_graph_indexer_impl.h" +// TODO: Implement interface with variadic template or tuple template class indexer_node; @@ -3102,7 +3282,7 @@ public: } #if TBB_PREVIEW_FLOW_GRAPH_TRACE - /* override */ void set_name( const char *name ) { + void set_name( const char *name ) __TBB_override { tbb::internal::fgt_node_desc( this, name ); } #endif @@ -3127,7 +3307,7 @@ public: } #if TBB_PREVIEW_FLOW_GRAPH_TRACE - /* override */ void set_name( const char *name ) { + void set_name( const char *name ) __TBB_override { tbb::internal::fgt_node_desc( this, name ); } #endif @@ -3153,7 +3333,7 @@ public: } #if TBB_PREVIEW_FLOW_GRAPH_TRACE - /* override */ void set_name( const char *name ) { + void set_name( const char *name ) __TBB_override { tbb::internal::fgt_node_desc( this, name ); } #endif @@ -3181,7 +3361,7 @@ public: } #if TBB_PREVIEW_FLOW_GRAPH_TRACE - /* override */ void set_name( const char *name ) { + void set_name( const char *name ) __TBB_override { tbb::internal::fgt_node_desc( this, name ); } #endif @@ -3209,7 +3389,7 @@ public: } #if TBB_PREVIEW_FLOW_GRAPH_TRACE - /* override */ void set_name( const char *name ) { + void set_name( const char *name ) __TBB_override { tbb::internal::fgt_node_desc( this, name ); } #endif @@ -3237,7 +3417,7 @@ public: } #if TBB_PREVIEW_FLOW_GRAPH_TRACE - /* override */ void set_name( const char *name ) { + void set_name( const char *name ) __TBB_override { tbb::internal::fgt_node_desc( this, name ); } #endif @@ -3265,16 +3445,19 @@ public: } #if TBB_PREVIEW_FLOW_GRAPH_TRACE - /* override */ void set_name( const char *name ) { + void set_name( const char *name ) __TBB_override { tbb::internal::fgt_node_desc( this, name ); } #endif }; #endif //variadic max 10 -//! Makes an edge between a single predecessor and a single successor +#if __TBB_PREVIEW_ASYNC_MSG +inline void internal_make_edge( internal::untyped_sender &p, internal::untyped_receiver &s ) { +#else template< typename T > -inline void make_edge( sender &p, receiver &s ) { +inline void internal_make_edge( sender &p, receiver &s ) { +#endif #if TBB_PREVIEW_FLOW_GRAPH_FEATURES s.internal_add_built_predecessor(p); p.internal_add_built_successor(s); @@ -3283,6 +3466,32 @@ inline void make_edge( sender &p, receiver &s ) { tbb::internal::fgt_make_edge( &p, &s ); } +//! Makes an edge between a single predecessor and a single successor +template< typename T > +inline void make_edge( sender &p, receiver &s ) { + internal_make_edge( p, s ); +} + +#if __TBB_PREVIEW_ASYNC_MSG +template< typename TS, typename TR, + typename = typename tbb::internal::enable_if::value + || tbb::internal::is_same_type::value>::type> +inline void make_edge( TS &p, TR &s ) { + internal_make_edge( p, s ); +} + +template< typename T > +inline void make_edge( sender &p, receiver &s ) { + internal_make_edge( p, s ); +} + +template< typename T > +inline void make_edge( sender &p, receiver &s ) { + internal_make_edge( p, s ); +} + +#endif // __TBB_PREVIEW_ASYNC_MSG + #if __TBB_FLOW_GRAPH_CPP11_FEATURES //Makes an edge from port 0 of a multi-output predecessor to port 0 of a multi-input successor. template< typename T, typename V, @@ -3306,9 +3515,12 @@ inline void make_edge( sender& output, V& input) { } #endif -//! Removes an edge between a single predecessor and a single successor +#if __TBB_PREVIEW_ASYNC_MSG +inline void internal_remove_edge( internal::untyped_sender &p, internal::untyped_receiver &s ) { +#else template< typename T > -inline void remove_edge( sender &p, receiver &s ) { +inline void internal_remove_edge( sender &p, receiver &s ) { +#endif p.remove_successor( s ); #if TBB_PREVIEW_FLOW_GRAPH_FEATURES // TODO: should we try to remove p from the predecessor list of s, in case the edge is reversed? @@ -3318,6 +3530,31 @@ inline void remove_edge( sender &p, receiver &s ) { tbb::internal::fgt_remove_edge( &p, &s ); } +//! Removes an edge between a single predecessor and a single successor +template< typename T > +inline void remove_edge( sender &p, receiver &s ) { + internal_remove_edge( p, s ); +} + +#if __TBB_PREVIEW_ASYNC_MSG +template< typename TS, typename TR, + typename = typename tbb::internal::enable_if::value + || tbb::internal::is_same_type::value>::type> +inline void remove_edge( TS &p, TR &s ) { + internal_remove_edge( p, s ); +} + +template< typename T > +inline void remove_edge( sender &p, receiver &s ) { + internal_remove_edge( p, s ); +} + +template< typename T > +inline void remove_edge( sender &p, receiver &s ) { + internal_remove_edge( p, s ); +} +#endif // __TBB_PREVIEW_ASYNC_MSG + #if __TBB_FLOW_GRAPH_CPP11_FEATURES //Removes an edge between port 0 of a multi-output predecessor and port 0 of a multi-input successor. template< typename T, typename V, @@ -3372,7 +3609,7 @@ Body copy_body( Node &n ) { template< typename InputTuple, typename OutputTuple > class composite_node; template< typename... InputTypes, typename... OutputTypes> -class composite_node , tbb::flow::tuple > : public graph_node, tbb::internal::no_copy { +class composite_node , tbb::flow::tuple > : public graph_node{ public: typedef tbb::flow::tuple< receiver&... > input_ports_type; @@ -3389,7 +3626,7 @@ private: static const size_t NUM_OUTPUTS = sizeof...(OutputTypes); protected: - /*override*/void reset_node(reset_flags) {} + void reset_node(reset_flags) __TBB_override {} public: #if TBB_PREVIEW_FLOW_GRAPH_TRACE @@ -3426,7 +3663,7 @@ public: #endif #if TBB_PREVIEW_FLOW_GRAPH_TRACE - /* override */ void set_name( const char *name ) { + void set_name( const char *name ) __TBB_override { tbb::internal::fgt_multiinput_multioutput_node_desc( this, name ); } #endif @@ -3447,7 +3684,7 @@ public: } #if TBB_PREVIEW_FLOW_GRAPH_FEATURES - /*override*/void extract() { + void extract() __TBB_override { __TBB_ASSERT(false, "Current composite_node implementation does not support extract"); } #endif @@ -3455,7 +3692,7 @@ public: //composite_node with only input ports template< typename... InputTypes> -class composite_node , tbb::flow::tuple<> > : public graph_node, tbb::internal::no_copy { +class composite_node , tbb::flow::tuple<> > : public graph_node { public: typedef tbb::flow::tuple< receiver&... > input_ports_type; @@ -3467,7 +3704,7 @@ private: static const size_t NUM_INPUTS = sizeof...(InputTypes); protected: - /*override*/void reset_node(reset_flags) {} + void reset_node(reset_flags) __TBB_override {} public: #if TBB_PREVIEW_FLOW_GRAPH_TRACE @@ -3502,7 +3739,7 @@ public: #endif #if TBB_PREVIEW_FLOW_GRAPH_TRACE - /* override */ void set_name( const char *name ) { + void set_name( const char *name ) __TBB_override { tbb::internal::fgt_multiinput_multioutput_node_desc( this, name ); } #endif @@ -3517,7 +3754,7 @@ public: } #if TBB_PREVIEW_FLOW_GRAPH_FEATURES - /*override*/void extract() { + void extract() __TBB_override { __TBB_ASSERT(false, "Current composite_node implementation does not support extract"); } #endif @@ -3526,7 +3763,7 @@ public: //composite_nodes with only output_ports template -class composite_node , tbb::flow::tuple > : public graph_node, tbb::internal::no_copy { +class composite_node , tbb::flow::tuple > : public graph_node { public: typedef tbb::flow::tuple< sender&... > output_ports_type; @@ -3538,7 +3775,7 @@ private: static const size_t NUM_OUTPUTS = sizeof...(OutputTypes); protected: - /*override*/void reset_node(reset_flags) {} + void reset_node(reset_flags) __TBB_override {} public: #if TBB_PREVIEW_FLOW_GRAPH_TRACE @@ -3573,7 +3810,7 @@ public: #endif #if TBB_PREVIEW_FLOW_GRAPH_TRACE - /* override */ void set_name( const char *name ) { + void set_name( const char *name ) __TBB_override { tbb::internal::fgt_multiinput_multioutput_node_desc( this, name ); } #endif @@ -3588,7 +3825,7 @@ public: } #if TBB_PREVIEW_FLOW_GRAPH_FEATURES - /*override*/void extract() { + void extract() __TBB_override { __TBB_ASSERT(false, "Current composite_node implementation does not support extract"); } #endif @@ -3597,68 +3834,59 @@ public: #endif // __TBB_FLOW_GRAPH_CPP11_FEATURES -#if __TBB_PREVIEW_ASYNC_NODE namespace internal { -//! Pure virtual template class that defines interface for async communication -template < typename Output > -class async_gateway { + +template +class async_body_base: tbb::internal::no_assign { public: - typedef Output output_type; + typedef Gateway gateway_type; - //! Submit signal from an asynchronous activity to FG - virtual bool async_try_put( const output_type &i ) = 0; + async_body_base(gateway_type *gateway): my_gateway(gateway) { } + void set_gateway(gateway_type *gateway) { + my_gateway = gateway; + } - //! Increment reference count of graph to prevent premature return from wait_for_all - virtual void async_reserve() = 0; - - //! Decrement reference count of graph to allow return from wait_for_all - virtual void async_commit() = 0; - - virtual ~async_gateway() {} +protected: + gateway_type *my_gateway; }; -template -class async_body { +template +class async_body: public async_body_base { public: - typedef AsyncGateway async_gateway_type; + typedef async_body_base base_type; + typedef Gateway gateway_type; - async_body(const Body &body, async_gateway_type *gateway) : my_body(body), my_async_gateway(gateway) { } - - async_body(const async_body &other) : my_body(other.my_body), my_async_gateway(other.my_async_gateway) { } + async_body(const Body &body, gateway_type *gateway) + : base_type(gateway), my_body(body) { } void operator()( const Input &v, Ports & ) { - my_body(v, *my_async_gateway); + my_body(v, *this->my_gateway); } Body get_body() { return my_body; } - void set_async_gateway(async_gateway_type *gateway) { - my_async_gateway = gateway; - } - private: Body my_body; - async_gateway_type *my_async_gateway; }; } //! Implements async node template < typename Input, typename Output, typename Policy = queueing, typename Allocator=cache_aligned_allocator > -class async_node : public multifunction_node< Input, tuple< Output >, Policy, Allocator >, public internal::async_gateway, public sender< Output > { -protected: +class async_node : public multifunction_node< Input, tuple< Output >, Policy, Allocator >, public sender< Output > { typedef multifunction_node< Input, tuple< Output >, Policy, Allocator > base_type; + typedef typename internal::multifunction_input mfn_input_type; public: typedef Input input_type; typedef Output output_type; - typedef sender< input_type > predecessor_type; - typedef receiver< output_type > successor_type; - typedef internal::async_gateway< output_type > async_gateway_type; - -protected: - typedef typename internal::multifunction_input mfn_input_type; + typedef receiver receiver_type; + typedef typename receiver_type::predecessor_type predecessor_type; + typedef typename sender::successor_type successor_type; + typedef receiver_gateway gateway_type; + typedef internal::async_body_base async_body_base_type; +private: struct try_put_functor { typedef internal::multifunction_output output_port_type; output_port_type *port; @@ -3670,55 +3898,65 @@ protected: } }; + class receiver_gateway_impl: public receiver_gateway { + public: + receiver_gateway_impl(async_node* node): my_node(node) {} + void reserve_wait() __TBB_override { + my_node->my_graph.reserve_wait(); + tbb::internal::fgt_async_reserve(static_cast(my_node), &my_node->my_graph); + } + + void release_wait() __TBB_override { + my_node->my_graph.release_wait(); + tbb::internal::fgt_async_commit(static_cast(my_node), &my_node->my_graph); + } + + //! Implements gateway_type::try_put for an external activity to submit a message to FG + bool try_put(const Output &i) __TBB_override { + return my_node->try_put_impl(i); + } + + private: + async_node* my_node; + } my_gateway; + + //The substitute of 'this' for member construction, to prevent compiler warnings + async_node* self() { return this; } + + //! Implements gateway_type::try_put for an external activity to submit a message to FG + bool try_put_impl(const Output &i) { + internal::multifunction_output &port_0 = internal::output_port<0>(*this); + tbb::internal::fgt_async_try_put_begin(this, &port_0); + __TBB_ASSERT(this->my_graph.my_task_arena && this->my_graph.my_task_arena->is_active(), NULL); + try_put_functor tpf(port_0, i); + this->my_graph.my_task_arena->execute(tpf); + tbb::internal::fgt_async_try_put_end(this, &port_0); + return tpf.result; + } + public: template async_node( graph &g, size_t concurrency, Body body ) : - base_type( g, concurrency, internal::async_body(body, this) ) { + base_type( g, concurrency, internal::async_body(body, &my_gateway) ), my_gateway(self()) { tbb::internal::fgt_multioutput_node<1>( tbb::internal::FLOW_ASYNC_NODE, - &this->graph_node::my_graph, + &this->my_graph, static_cast *>(this), this->output_ports() ); } - async_node( const async_node &other ) : base_type(other) { - typedef internal::multifunction_body mfn_body_type; - mfn_body_type &body_ref = *this->my_body; - body_ref.set_gateway(static_cast(this)); - mfn_body_type &init_body_ref = *this->my_init_body; - init_body_ref.set_gateway(static_cast(this)); - tbb::internal::fgt_multioutput_node<1>( tbb::internal::FLOW_ASYNC_NODE, &this->graph_node::my_graph, static_cast *>(this), this->output_ports() ); + async_node( const async_node &other ) : base_type(other), sender(), my_gateway(self()) { + static_cast(this->my_body->get_body_ptr())->set_gateway(&my_gateway); + static_cast(this->my_init_body->get_body_ptr())->set_gateway(&my_gateway); + + tbb::internal::fgt_multioutput_node<1>( tbb::internal::FLOW_ASYNC_NODE, &this->my_graph, static_cast *>(this), this->output_ports() ); } - virtual ~async_node() {} - - /* override */ async_gateway_type& async_gateway() { - return static_cast< async_gateway_type& >(*this); - } - - //! Implements async_gateway::async_try_put for an external activity to submit a message to FG - /*override*/ bool async_try_put(const output_type &i ) { - internal::multifunction_output &port_0 = internal::output_port<0>(*this); - graph &g = this->graph_node::my_graph; - tbb::internal::fgt_async_try_put_begin(static_cast *>(this), &port_0); - __TBB_ASSERT(g.my_task_arena && g.my_task_arena->is_active(), NULL); - try_put_functor tpf(port_0, i); - g.my_task_arena->execute(tpf); - tbb::internal::fgt_async_try_put_end(static_cast *>(this), &port_0); - return tpf.result; - } - - /*override*/ void async_reserve() { - this->graph_node::my_graph.increment_wait_count(); - tbb::internal::fgt_async_reserve(static_cast *>(this), &this->graph_node::my_graph); - } - - /*override*/ void async_commit() { - this->graph_node::my_graph.decrement_wait_count(); - tbb::internal::fgt_async_commit(static_cast *>(this), &this->graph_node::my_graph); + gateway_type& gateway() { + return my_gateway; } #if TBB_PREVIEW_FLOW_GRAPH_TRACE - /* override */ void set_name( const char *name ) { + void set_name( const char *name ) __TBB_override { tbb::internal::fgt_node_desc( this, name ); } #endif @@ -3726,21 +3964,21 @@ public: // Define sender< Output > //! Add a new successor to this node - /* override */ bool register_successor( successor_type &r ) { + bool register_successor( successor_type &r ) __TBB_override { return internal::output_port<0>(*this).register_successor(r); } //! Removes a successor from this node - /* override */ bool remove_successor( successor_type &r ) { + bool remove_successor( successor_type &r ) __TBB_override { return internal::output_port<0>(*this).remove_successor(r); } template Body copy_function_object() { typedef internal::multifunction_body mfn_body_type; - typedef internal::async_body async_body_type; + typedef internal::async_body async_body_type; mfn_body_type &body_ref = *this->my_body; - async_body_type ab = dynamic_cast< internal::multifunction_body_leaf & >(body_ref).get_body(); + async_body_type ab = *static_cast(dynamic_cast< internal::multifunction_body_leaf & >(body_ref).get_body_ptr()); return ab.get_body(); } @@ -3748,79 +3986,86 @@ public: //! interface to record edges for traversal & deletion typedef typename internal::edge_container built_successors_type; typedef typename built_successors_type::edge_list_type successor_list_type; - /* override */ built_successors_type &built_successors() { + built_successors_type &built_successors() __TBB_override { return internal::output_port<0>(*this).built_successors(); } - /* override */ void internal_add_built_successor( successor_type &r ) { + void internal_add_built_successor( successor_type &r ) __TBB_override { internal::output_port<0>(*this).internal_add_built_successor(r); } - /* override */ void internal_delete_built_successor( successor_type &r ) { + void internal_delete_built_successor( successor_type &r ) __TBB_override { internal::output_port<0>(*this).internal_delete_built_successor(r); } - /* override */ void copy_successors( successor_list_type &l ) { + void copy_successors( successor_list_type &l ) __TBB_override { internal::output_port<0>(*this).copy_successors(l); } - /* override */ size_t successor_count() { + size_t successor_count() __TBB_override { return internal::output_port<0>(*this).successor_count(); } #endif protected: - /*override*/ void reset_node( reset_flags f) { + void reset_node( reset_flags f) __TBB_override { base_type::reset_node(f); } - }; -#endif // __TBB_PREVIEW_ASYNC_NODE +#if __TBB_PREVIEW_STREAMING_NODE +#include "internal/_flow_graph_streaming_node.h" +#endif // __TBB_PREVIEW_STREAMING_NODE -} // interface8 +} // interface9 - using interface8::reset_flags; - using interface8::rf_reset_protocol; - using interface8::rf_reset_bodies; - using interface8::rf_clear_edges; + using interface9::reset_flags; + using interface9::rf_reset_protocol; + using interface9::rf_reset_bodies; + using interface9::rf_clear_edges; - using interface8::graph; - using interface8::graph_node; - using interface8::continue_msg; + using interface9::graph; + using interface9::graph_node; + using interface9::continue_msg; - using interface8::source_node; - using interface8::function_node; - using interface8::multifunction_node; - using interface8::split_node; - using interface8::internal::output_port; - using interface8::indexer_node; - using interface8::internal::tagged_msg; - using interface8::internal::cast_to; - using interface8::internal::is_a; - using interface8::continue_node; - using interface8::overwrite_node; - using interface8::write_once_node; - using interface8::broadcast_node; - using interface8::buffer_node; - using interface8::queue_node; - using interface8::sequencer_node; - using interface8::priority_queue_node; - using interface8::limiter_node; - using namespace interface8::internal::graph_policy_namespace; - using interface8::join_node; - using interface8::input_port; - using interface8::copy_body; - using interface8::make_edge; - using interface8::remove_edge; - using interface8::internal::tag_value; + using interface9::source_node; + using interface9::function_node; + using interface9::multifunction_node; + using interface9::split_node; + using interface9::internal::output_port; + using interface9::indexer_node; + using interface9::internal::tagged_msg; + using interface9::internal::cast_to; + using interface9::internal::is_a; + using interface9::continue_node; + using interface9::overwrite_node; + using interface9::write_once_node; + using interface9::broadcast_node; + using interface9::buffer_node; + using interface9::queue_node; + using interface9::sequencer_node; + using interface9::priority_queue_node; + using interface9::limiter_node; + using namespace interface9::internal::graph_policy_namespace; + using interface9::join_node; + using interface9::input_port; + using interface9::copy_body; + using interface9::make_edge; + using interface9::remove_edge; + using interface9::internal::tag_value; #if __TBB_FLOW_GRAPH_CPP11_FEATURES - using interface8::composite_node; + using interface9::composite_node; #endif -#if __TBB_PREVIEW_ASYNC_NODE - using interface8::async_node; + using interface9::async_node; +#if __TBB_PREVIEW_ASYNC_MSG + using interface9::async_msg; #endif +#if __TBB_PREVIEW_STREAMING_NODE + using interface9::port_ref; + using interface9::streaming_node; +#endif // __TBB_PREVIEW_STREAMING_NODE + } // flow } // tbb diff --git a/lib/3rdParty/tbb/include/tbb/flow_graph_abstractions.h b/lib/3rdParty/tbb/include/tbb/flow_graph_abstractions.h new file mode 100644 index 0000000..f6eb3fb --- /dev/null +++ b/lib/3rdParty/tbb/include/tbb/flow_graph_abstractions.h @@ -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 +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 diff --git a/lib/3rdParty/tbb/include/tbb/flow_graph_opencl_node.h b/lib/3rdParty/tbb/include/tbb/flow_graph_opencl_node.h index c82d26f..0a98a77 100644 --- a/lib/3rdParty/tbb/include/tbb/flow_graph_opencl_node.h +++ b/lib/3rdParty/tbb/include/tbb/flow_graph_opencl_node.h @@ -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_opencl_node_H @@ -32,9 +32,7 @@ #include #include #include -#include #include -#include #ifdef __APPLE__ #include @@ -45,7 +43,7 @@ namespace tbb { namespace flow { -namespace interface8 { +namespace interface9 { class opencl_foundation; class opencl_device_list; @@ -53,6 +51,9 @@ class opencl_device_list; template class opencl_buffer_impl; +template +class opencl_program; + class default_opencl_factory; class opencl_graph : public graph { @@ -80,289 +81,16 @@ protected: friend class opencl_factory; }; +template +class opencl_factory; + template class dependency_msg; -template< typename T, typename Factory > -class proxy_dependency_receiver; - -template< typename T, typename Factory > -class receiver> { -public: - //! The predecessor type for this node - typedef sender> predecessor_type; - typedef proxy_dependency_receiver proxy; - - receiver() : my_ordinary_receiver( *this ) {} - - //! Put an item to the receiver - bool try_put( const T& t ) { - return my_ordinary_receiver.try_put(t); - } - - //! Put an item to the receiver - virtual task *try_put_task( const dependency_msg& ) = 0; - - //! Add a predecessor to the node - virtual bool register_predecessor( predecessor_type & ) { return false; } - - //! Remove a predecessor from the node - virtual bool remove_predecessor( predecessor_type & ) { return false; } - -protected: - //! put receiver back in initial state - virtual void reset_receiver( reset_flags f = rf_reset_protocol ) = 0; - virtual bool is_continue_receiver() { return false; } -private: - class ordinary_receiver : public receiver < T >, tbb::internal::no_assign { - //! The predecessor type for this node - typedef sender predecessor_type; - typedef sender> dependency_predecessor_type; - public: - ordinary_receiver(receiver>& owner) : my_owner(owner) {} - - //! Put an item to the receiver - /* override */ task *try_put_task( const T& t ) { - return my_owner.try_put_task( dependency_msg( t ) ); - } - - //! Add a predecessor to the node - /* override */ bool register_predecessor( predecessor_type &p ) { - tbb::spin_mutex::scoped_lock lock( my_predecessor_map_mutex ); - typename predecessor_map_type::iterator it = my_predecessor_map.emplace( std::piecewise_construct_t(), std::make_tuple( &p ), std::tie( p ) ); - if ( !my_owner.register_predecessor( it->second ) ) { - my_predecessor_map.erase( it ); - return false; - } - return true; - } - - //! Remove a predecessor from the node - /* override */ bool remove_predecessor( predecessor_type &p ) { - tbb::spin_mutex::scoped_lock lock( my_predecessor_map_mutex ); - typename predecessor_map_type::iterator it = my_predecessor_map.find( &p ); - __TBB_ASSERT( it != my_predecessor_map.end(), "Failed to find the predecessor" ); - if ( !my_owner.remove_predecessor( it->second ) ) - return false; - my_predecessor_map.erase( it ); - return true; - } - - protected: - //! put receiver back in initial state - /* override */ void reset_receiver( reset_flags f = rf_reset_protocol ) { - my_owner.reset_receiver( f ); - }; - /* override */ bool is_continue_receiver() { - return my_owner.is_continue_receiver(); - } - - private: - receiver>& my_owner; - - typedef std::multimap predecessor_map_type; - predecessor_map_type my_predecessor_map; - tbb::spin_mutex my_predecessor_map_mutex; - }; - ordinary_receiver my_ordinary_receiver; -public: - ordinary_receiver& ordinary_receiver() { return my_ordinary_receiver; } -}; - -template< typename T, typename Factory > -class proxy_dependency_sender; - -template< typename T, typename Factory > -class proxy_dependency_receiver : public receiver < dependency_msg >, tbb::internal::no_assign { -public: - typedef sender> predecessor_type; - - proxy_dependency_receiver( receiver& r ) : my_r( r ) {} - - //! Put an item to the receiver - /* override */ task *try_put_task( const dependency_msg &d ) { - receive_if_memory_object( d ); - receiver *r = &my_r; - d.register_callback( [r]( const T& t ) { - r->try_put( t ); - } ); - d.clear_event(); - return SUCCESSFULLY_ENQUEUED; - } - - //! Add a predecessor to the node - /* override */ bool register_predecessor( predecessor_type &s ) { - return my_r.register_predecessor( s.ordinary_sender() ); - } - //! Remove a predecessor from the node - /* override */ bool remove_predecessor( predecessor_type &s ) { - return my_r.remove_predecessor( s.ordinary_sender() ); - } -protected: - //! put receiver back in initial state - /* override */ void reset_receiver( reset_flags f = rf_reset_protocol ) { - my_r.reset_receiver( f ); - }; - - /* override */ bool is_continue_receiver() { - return my_r.is_continue_receiver(); - } -private: - receiver &my_r; -}; - -template< typename T, typename Factory > -class sender> { -public: - sender() : my_ordinary_sender( *this ) {} - - //! The successor type for this sender - typedef receiver> successor_type; - typedef proxy_dependency_sender proxy; - - //! Add a new successor to this node - virtual bool register_successor( successor_type &r ) = 0; - - //! Removes a successor from this node - virtual bool remove_successor( successor_type &r ) = 0; - - //! Request an item from the sender - virtual bool try_get( dependency_msg & ) { return false; } - - //! Reserves an item in the sender - virtual bool try_reserve( dependency_msg & ) { return false; } -private: - class ordinary_sender : public sender < T >, tbb::internal::no_assign { - //! The successor type for this sender - typedef receiver successor_type; - typedef receiver> dependency_successor_type; - public: - ordinary_sender(sender>& owner) : my_owner(owner) {} - - //! Add a new successor to this node - /* override */ bool register_successor( successor_type &r ) { - tbb::spin_mutex::scoped_lock lock( my_successor_map_mutex ); - typename successor_map_type::iterator it = my_successor_map.emplace( std::piecewise_construct_t(), std::make_tuple( &r ), std::tie( r ) ); - if ( !my_owner.register_successor( it->second ) ) { - my_successor_map.erase( it ); - return false; - } - return true; - } - - //! Removes a successor from this node - /* override */ bool remove_successor( successor_type &r ) { - tbb::spin_mutex::scoped_lock lock( my_successor_map_mutex ); - typename successor_map_type::iterator it = my_successor_map.find( &r ); - __TBB_ASSERT( it != my_successor_map.end(), "The predecessor has already been registered" ); - if ( !my_owner.remove_successor( it->second ) ) - return false; - my_successor_map.erase( it ); - return true; - } - - //! Request an item from the sender - /* override */ bool try_get( T &t ) { - dependency_msg d; - if ( my_owner.try_get( d ) ) { - t = d.data(); - return true; - } - return false; - } - - /* override */ bool try_reserve( T &t ) { - dependency_msg d; - if ( my_owner.try_reserve( d ) ) { - t = d.data(); - return true; - } - return false; - } - - bool has_host_successors() { - tbb::spin_mutex::scoped_lock lock( my_successor_map_mutex ); - return !my_successor_map.empty(); - } - private: - sender>& my_owner; - - typedef std::multimap successor_map_type; - successor_map_type my_successor_map; - tbb::spin_mutex my_successor_map_mutex; - }; - ordinary_sender my_ordinary_sender; -public: - ordinary_sender& ordinary_sender() { return my_ordinary_sender; } - - bool has_host_successors() { - return my_ordinary_sender.has_host_successors(); - } -}; - -template< typename T, typename Factory > -class proxy_dependency_sender : public sender < dependency_msg >, tbb::internal::no_assign { -public: - typedef receiver> successor_type; - - proxy_dependency_sender( sender& s ) : my_s( s ) {} - - //! Add a new successor to this node - /* override */ bool register_successor( successor_type &r ) { - return my_s.register_successor( r.ordinary_receiver() ); - } - - //! Removes a successor from this node - /* override */ bool remove_successor( successor_type &r ) { - return my_s.remove_successor( r.ordinary_receiver() ); - } - - //! Request an item from the sender - /* override */ bool try_get( dependency_msg &d ) { - return my_s.try_get( d.data() ); - } - - //! Reserves an item in the sender - /* override */ bool try_reserve( dependency_msg &d ) { - return my_s.try_reserve( d.data() ); - } - - //! Releases the reserved item - /* override */ bool try_release() { - return my_s.try_release(); - } - - //! Consumes the reserved item - /* override */ bool try_consume() { - return my_s.try_consume(); - } -private: - sender &my_s; -}; - -template -inline void make_edge( sender &s, receiver> &r ) { - make_edge( s, r.ordinary_receiver() ); -} - -template -inline void make_edge( sender> &s, receiver &r ) { - make_edge( s.ordinary_sender(), r ); -} - -template -inline void remove_edge( sender &s, receiver> &r ) { - remove_edge( s, r.ordinary_receiver() ); -} - -template -inline void remove_edge( sender> &s, receiver &r ) { - remove_edge( s.ordinary_sender(), r ); -} inline void enforce_cl_retcode( cl_int err, std::string msg ) { if ( err != CL_SUCCESS ) { - std::cerr << msg << std::endl; + std::cerr << msg << "; error code: " << err << std::endl; throw msg; } } @@ -568,6 +296,7 @@ public: void add( opencl_device d ) { my_container.push_back( d ); } size_type size() const { return my_container.size(); } + bool empty() const { return my_container.empty(); } iterator begin() { return my_container.begin(); } iterator end() { return my_container.end(); } const_iterator begin() const { return my_container.begin(); } @@ -580,7 +309,7 @@ private: class callback_base : tbb::internal::no_copy { public: - virtual void call() const = 0; + virtual void call() = 0; virtual ~callback_base() {} }; @@ -598,22 +327,33 @@ public: // Release the reference to the graph. my_graph.decrement_wait_count(); } - /* override */ void call() const { + void call() __TBB_override { my_callback( my_data ); } }; template -class dependency_msg { +class dependency_msg : public async_msg { public: typedef T value_type; - dependency_msg() = default; - explicit dependency_msg( const T& data ) : my_data( data ) {} - dependency_msg( opencl_graph &g, const T& data ) : my_data( data ), my_graph( &g ) {} - dependency_msg( const T& data, cl_event event ) : my_data( data ), my_event( event ), my_is_event( true ) { + dependency_msg() : my_callback_flag_ptr( std::make_shared< tbb::atomic>() ) { + my_callback_flag_ptr->store(false); + } + + explicit dependency_msg( const T& data ) : my_data(data), my_callback_flag_ptr( std::make_shared>() ) { + my_callback_flag_ptr->store(false); + } + + dependency_msg( opencl_graph &g, const T& data ) : my_data(data), my_graph(&g), my_callback_flag_ptr( std::make_shared>() ) { + my_callback_flag_ptr->store(false); + } + + dependency_msg( const T& data, cl_event event ) : my_data(data), my_event(event), my_is_event(true), my_callback_flag_ptr( std::make_shared>() ) { + my_callback_flag_ptr->store(false); enforce_cl_retcode( clRetainEvent( my_event ), "Failed to retain an event" ); } + T& data( bool wait = true ) { if ( my_is_event && wait ) { enforce_cl_retcode( clWaitForEvents( 1, &my_event ), "Failed to wait for an event" ); @@ -632,22 +372,38 @@ public: return my_data; } - dependency_msg( const dependency_msg &dmsg ) : my_data( dmsg.my_data ), my_event( dmsg.my_event ), my_is_event( dmsg.my_is_event ), my_graph( dmsg.my_graph ) { + dependency_msg( const dependency_msg &dmsg ) : async_msg(dmsg), + my_data(dmsg.my_data), my_event(dmsg.my_event), my_is_event( dmsg.my_is_event ), my_graph( dmsg.my_graph ), + my_callback_flag_ptr(dmsg.my_callback_flag_ptr) + { if ( my_is_event ) enforce_cl_retcode( clRetainEvent( my_event ), "Failed to retain an event" ); } - dependency_msg( dependency_msg &&dmsg ) : my_data( std::move(dmsg.my_data) ), my_event( dmsg.my_event ), my_is_event( dmsg.my_is_event ), my_graph( dmsg.my_graph ) { + dependency_msg( dependency_msg &&dmsg ) : async_msg(std::move(dmsg)), + my_data(std::move(dmsg.my_data)), my_event(dmsg.my_event), my_is_event(dmsg.my_is_event), my_graph(dmsg.my_graph), + my_callback_flag_ptr( std::move(dmsg.my_callback_flag_ptr) ) + { dmsg.my_is_event = false; } dependency_msg& operator=(const dependency_msg &dmsg) { + async_msg::operator =(dmsg); + + // Release original event + if ( my_is_event ) + enforce_cl_retcode( clReleaseEvent( my_event ), "Failed to retain an event" ); + my_data = dmsg.my_data; my_event = dmsg.my_event; my_is_event = dmsg.my_is_event; my_graph = dmsg.my_graph; + + // Retain copied event if ( my_is_event ) enforce_cl_retcode( clRetainEvent( my_event ), "Failed to retain an event" ); + + my_callback_flag_ptr = dmsg.my_callback_flag_ptr; return *this; } @@ -691,6 +447,25 @@ public: operator T&() { return data(); } operator const T&() const { return data(); } +protected: + // Overridden in this derived class to inform that + // async calculation chain is over + void finalize() const __TBB_override { + receive_if_memory_object(*this); + if (! my_callback_flag_ptr->fetch_and_store(true)) { + dependency_msg a(*this); + if (my_is_event) { + register_callback([a](const T& t) mutable { + a.set(t); + }); + } + else { + a.set(my_data); + } + } + clear_event(); + } + private: static void CL_CALLBACK register_callback_func( cl_event, cl_int event_command_exec_status, void *data ) { tbb::internal::suppress_unused_warning( event_command_exec_status ); @@ -705,6 +480,8 @@ private: mutable cl_event my_event; mutable bool my_is_event = false; graph *my_graph = NULL; + + std::shared_ptr< tbb::atomic > my_callback_flag_ptr; }; template @@ -779,7 +556,7 @@ public: return my_size; } - /* override */ void map_memory( opencl_device device, dependency_msg &dmsg ) { + void map_memory( opencl_device device, dependency_msg &dmsg ) __TBB_override { this->my_factory->enque_map_buffer( device, *this, dmsg ); } @@ -887,14 +664,152 @@ opencl_subbuffer opencl_buffer::subbuffer( size_t index, } +#define is_typedef(type) \ + template \ + struct is_##type { \ + template \ + static std::true_type check( typename C::type* ); \ + template \ + static std::false_type check( ... ); \ + \ + static const bool value = decltype(check(0))::value; \ + } + +is_typedef( native_object_type ); +is_typedef( memory_object_type ); + +template +typename std::enable_if::value, typename T::native_object_type>::type get_native_object( const T &t ) { + return t.native_object(); +} + +template +typename std::enable_if::value, T>::type get_native_object( T t ) { + return t; +} + +// send_if_memory_object checks if the T type has memory_object_type and call the send method for the object. +template +typename std::enable_if::value>::type send_if_memory_object( opencl_device device, dependency_msg &dmsg ) { + const T &t = dmsg.data( false ); + typedef typename T::memory_object_type mem_obj_t; + mem_obj_t mem_obj = t.memory_object(); + dependency_msg d( mem_obj ); + if ( dmsg.get_event() ) d.set_event( *dmsg.get_event() ); + mem_obj.send( device, d ); + if ( d.get_event() ) dmsg.set_event( *d.get_event() ); +} + +template +typename std::enable_if::value>::type send_if_memory_object( opencl_device device, T &t ) { + typedef typename T::memory_object_type mem_obj_t; + mem_obj_t mem_obj = t.memory_object(); + dependency_msg dmsg( mem_obj ); + mem_obj.send( device, dmsg ); +} + +template +typename std::enable_if::value>::type send_if_memory_object( opencl_device, T& ) {}; + +// receive_if_memory_object checks if the T type has memory_object_type and call the receive method for the object. +template +typename std::enable_if::value>::type receive_if_memory_object( const dependency_msg &dmsg ) { + const T &t = dmsg.data( false ); + typedef typename T::memory_object_type mem_obj_t; + mem_obj_t mem_obj = t.memory_object(); + dependency_msg d( mem_obj ); + if ( dmsg.get_event() ) d.set_event( *dmsg.get_event() ); + mem_obj.receive( d ); + if ( d.get_event() ) dmsg.set_event( *d.get_event() ); +} + +template +typename std::enable_if::value>::type receive_if_memory_object( const T& ) {} + +class opencl_range { +public: + typedef size_t range_index_type; + typedef std::array nd_range_type; + + template , typename L = std::initializer_list, + typename = typename std::enable_if::type, opencl_range>::value>::type> + opencl_range(G&& global_work = std::initializer_list({ 0 }), L&& local_work = std::initializer_list({ 0, 0, 0 })) { + auto g_it = global_work.begin(); + auto l_it = local_work.begin(); + my_global_work_size = { size_t(-1), size_t(-1), size_t(-1) }; + // my_local_work_size is still uninitialized + for (int s = 0; s < 3 && g_it != global_work.end(); ++g_it, ++l_it, ++s) { + __TBB_ASSERT(l_it != local_work.end(), "global_work & local_work must have same size"); + my_global_work_size[s] = *g_it; + my_local_work_size[s] = *l_it; + } + } + + const nd_range_type& global_range() const { return my_global_work_size; } + const nd_range_type& local_range() const { return my_local_work_size; } + +private: + nd_range_type my_global_work_size; + nd_range_type my_local_work_size; +}; + template class opencl_factory { public: + template using async_msg_type = dependency_msg>; + typedef opencl_device device_type; + + class kernel : tbb::internal::no_assign { + public: + kernel( const kernel& k ) : my_factory( k.my_factory ) { + // Clone my_cl_kernel via opencl_program + size_t ret_size = 0; + + std::vector kernel_name; + for ( size_t curr_size = 32;; curr_size <<= 1 ) { + kernel_name.resize( curr_size <<= 1 ); + enforce_cl_retcode( clGetKernelInfo( k.my_cl_kernel, CL_KERNEL_FUNCTION_NAME, curr_size, kernel_name.data(), &ret_size ), "Failed to get kernel info" ); + if ( ret_size < curr_size ) break; + } + + cl_program program; + enforce_cl_retcode( clGetKernelInfo( k.my_cl_kernel, CL_KERNEL_PROGRAM, sizeof(program), &program, &ret_size ), "Failed to get kernel info" ); + __TBB_ASSERT( ret_size == sizeof(program), NULL ); + + my_cl_kernel = opencl_program< factory_type >( my_factory, program ).get_cl_kernel( kernel_name.data() ); + } + + ~kernel() { + enforce_cl_retcode( clReleaseKernel( my_cl_kernel ), "Failed to release a kernel" ); + } + + private: + typedef opencl_factory factory_type; + + kernel( const cl_kernel& k, factory_type& f ) : my_cl_kernel( k ), my_factory( f ) {} + + // Data + cl_kernel my_cl_kernel; + factory_type& my_factory; + + template + friend class opencl_factory; + + template + friend class opencl_program; + }; + + typedef kernel kernel_type; + + // 'range_type' enables kernel_executor with range support + // it affects expectations for enqueue_kernel(.....) interface method + typedef opencl_range range_type; + opencl_factory( opencl_graph &g ) : my_graph( g ) {} ~opencl_factory() { if ( my_devices.size() ) { - for ( opencl_device d : my_devices ) { - enforce_cl_retcode( clReleaseCommandQueue( d.my_cl_command_queue ), "Failed to release a command queue" ); + for ( auto d = my_devices.begin(); d != my_devices.end(); ++d ) { + enforce_cl_retcode( clReleaseCommandQueue( (*d).my_cl_command_queue ), "Failed to release a command queue" ); } enforce_cl_retcode( clReleaseContext( my_cl_context ), "Failed to release a context" ); } @@ -936,19 +851,85 @@ private: enforce_cl_retcode( clReleaseEvent( e2 ), "Failed to release an event" ); } - template - cl_event enqueue_kernel( opencl_device device, cl_kernel kernel, - GlbNDRange&& global_work_size, LclNDRange&& local_work_size, cl_uint num_events, cl_event* event_list ) { - auto g_it = global_work_size.begin(); - auto l_it = local_work_size.begin(); - __TBB_ASSERT( g_it != global_work_size.end() , "Empty global work size" ); - __TBB_ASSERT( l_it != local_work_size.end() , "Empty local work size" ); - std::array g_size, l_size, g_offset = { { 0, 0, 0 } }; - cl_uint s; - for ( s = 0; s < 3 && g_it != global_work_size.end() && l_it != local_work_size.end(); ++s ) { - g_size[s] = *g_it++; - l_size[s] = *l_it++; + // --------- Kernel argument & event list helpers --------- // + template + void process_one_arg( const kernel_type& kernel, std::array&, int&, int& place, const T& t ) { + auto p = get_native_object(t); + enforce_cl_retcode( clSetKernelArg(kernel.my_cl_kernel, place++, sizeof(p), &p), "Failed to set a kernel argument" ); + } + + template + void process_one_arg( const kernel_type& kernel, std::array& events, int& num_events, int& place, const dependency_msg& msg ) { + __TBB_ASSERT((static_cast::size_type>(num_events) < events.size()), NULL); + + const cl_event * const e = msg.get_event(); + if (e != NULL) { + events[num_events++] = *e; } + + process_one_arg( kernel, events, num_events, place, msg.data(false) ); + } + + template + void process_arg_list( const kernel_type& kernel, std::array& events, int& num_events, int& place, const T& t, const Rest&... args ) { + process_one_arg( kernel, events, num_events, place, t ); + process_arg_list( kernel, events, num_events, place, args... ); + } + + template + void process_arg_list( const kernel_type&, std::array&, int&, int& ) {} + // ------------------------------------------- // + template + void update_one_arg( cl_event, T& ) {} + + template + void update_one_arg( cl_event e, dependency_msg& msg ) { + msg.set_event( e ); + msg.set_graph( my_graph ); + } + + template + void update_arg_list( cl_event e, T& t, Rest&... args ) { + update_one_arg( e, t ); + update_arg_list( e, args... ); + } + + void update_arg_list( cl_event ) {} + // ------------------------------------------- // +public: + template + void send_kernel( opencl_device device, const kernel_type& kernel, const range_type& work_size, Args&... args ) { + std::array events; + int num_events = 0; + int place = 0; + process_arg_list( kernel, events, num_events, place, args... ); + + const cl_event e = send_kernel_impl( device, kernel.my_cl_kernel, work_size, num_events, events.data() ); + + update_arg_list(e, args...); + + // Release our own reference to cl_event + enforce_cl_retcode( clReleaseEvent(e), "Failed to release an event" ); + } + + // ------------------------------------------- // + template + void send_data(opencl_device device, T& t, Rest&... args) { + send_if_memory_object( device, t ); + send_data( device, args... ); + } + + void send_data(opencl_device) {} + // ------------------------------------------- // + +private: + cl_event send_kernel_impl( opencl_device device, const cl_kernel& kernel, + const range_type& work_size, cl_uint num_events, cl_event* event_list ) { + const typename range_type::nd_range_type g_offset = { { 0, 0, 0 } }; + const typename range_type::nd_range_type& g_size = work_size.global_range(); + const typename range_type::nd_range_type& l_size = work_size.local_range(); + cl_uint s; + for ( s = 1; s < 3 && g_size[s] != size_t(-1); ++s) {} cl_event event; enforce_cl_retcode( clEnqueueNDRangeKernel( device.my_cl_command_queue, kernel, s, @@ -957,7 +938,71 @@ private: return event; } - void flush( opencl_device device ) { + // ------------------------------------------- // + template + bool get_event_from_one_arg( cl_event&, const T& ) { + return false; + } + + template + bool get_event_from_one_arg( cl_event& e, const dependency_msg& msg) { + cl_event const *e_ptr = msg.get_event(); + + if ( e_ptr != NULL ) { + e = *e_ptr; + return true; + } + + return false; + } + + template + bool get_event_from_args( cl_event& e, const T& t, const Rest&... args ) { + if ( get_event_from_one_arg( e, t ) ) { + return true; + } + + return get_event_from_args( e, args... ); + } + + bool get_event_from_args( cl_event& ) { + return false; + } + // ------------------------------------------- // + + struct finalize_fn : tbb::internal::no_assign { + virtual ~finalize_fn() {} + virtual void operator() () {} + }; + + template + struct finalize_fn_leaf : public finalize_fn { + Fn my_fn; + finalize_fn_leaf(Fn fn) : my_fn(fn) {} + void operator() () __TBB_override { my_fn(); } + }; + + static void CL_CALLBACK finalize_callback(cl_event, cl_int event_command_exec_status, void *data) { + tbb::internal::suppress_unused_warning(event_command_exec_status); + __TBB_ASSERT(event_command_exec_status == CL_COMPLETE, NULL); + + finalize_fn * const fn_ptr = static_cast(data); + __TBB_ASSERT(fn_ptr != NULL, "Invalid finalize function pointer"); + (*fn_ptr)(); + + // Function pointer was created by 'new' & this callback must be called once only + delete fn_ptr; + } +public: + template + void finalize( opencl_device device, FinalizeFn fn, Args&... args ) { + cl_event e; + + if ( get_event_from_args( e, args... ) ) { + enforce_cl_retcode( clSetEventCallback( e, CL_COMPLETE, finalize_callback, + new finalize_fn_leaf(fn) ), "Failed to set a callback" ); + } + enforce_cl_retcode( clFlush( device.my_cl_command_queue ), "Failed to flush an OpenCL command queue" ); } @@ -966,6 +1011,7 @@ private: return my_devices; } +private: bool is_same_context( opencl_device::device_id_type d1, opencl_device::device_id_type d2 ) { __TBB_ASSERT( d1 != opencl_device::unknown && d2 != opencl_device::unknown, NULL ); // Currently, factory supports only one context so if the both devices are not host it means the are in the same context. @@ -973,7 +1019,7 @@ private: return true; return d1 == d2; } - +private: opencl_factory( const opencl_factory& ); opencl_factory& operator=(const opencl_factory&); @@ -997,8 +1043,6 @@ private: friend class opencl_buffer_impl; template friend class opencl_memory; - template - friend class opencl_node; }; template @@ -1022,7 +1066,6 @@ template dependency_msg opencl_memory::send( opencl_device device, const cl_event *e ) { opencl_device::device_id_type device_id = device.my_device_id; if ( !my_factory->is_same_context( my_curr_device_id.load(), device_id ) ) { - __TBB_ASSERT( !e, "The buffer has come from another opencl_node but it is not on a device" ); { tbb::spin_mutex::scoped_lock lock( my_sending_lock ); if ( !my_factory->is_same_context( my_curr_device_id.load(), device_id ) ) { @@ -1056,6 +1099,8 @@ struct default_opencl_factory_device_filter { class default_opencl_factory : public opencl_factory < default_opencl_factory_device_filter > { public: + template using async_msg_type = dependency_msg; + default_opencl_factory( opencl_graph &g ) : opencl_factory( g ) {} private: default_opencl_factory( const default_opencl_factory& ); @@ -1064,34 +1109,43 @@ private: class opencl_foundation : tbb::internal::no_assign { struct default_device_selector_type { - opencl_device operator()( const opencl_device_list& devices ) { - return *devices.begin(); + opencl_device operator()( default_opencl_factory& f ) { + __TBB_ASSERT( ! f.devices().empty(), "No available devices" ); + return *( f.devices().begin() ); } }; public: - opencl_foundation( opencl_graph &g ) : my_default_opencl_factory( g ), my_default_device_selector() { + opencl_foundation(opencl_graph &g) : my_default_opencl_factory(g), my_default_device_selector() { cl_uint num_platforms; - enforce_cl_retcode( clGetPlatformIDs( 0, NULL, &num_platforms ), "clGetPlatformIDs failed" ); + enforce_cl_retcode(clGetPlatformIDs(0, NULL, &num_platforms), "clGetPlatformIDs failed"); - std::vector platforms( num_platforms ); - enforce_cl_retcode( clGetPlatformIDs( num_platforms, platforms.data(), NULL ), "clGetPlatformIDs failed" ); + std::vector platforms(num_platforms); + enforce_cl_retcode(clGetPlatformIDs(num_platforms, platforms.data(), NULL), "clGetPlatformIDs failed"); + cl_uint num_devices; + std::vector::iterator platforms_it = platforms.begin(); cl_uint num_all_devices = 0; - for ( cl_platform_id p : platforms ) { - cl_uint num_devices; - enforce_cl_retcode( clGetDeviceIDs( p, CL_DEVICE_TYPE_ALL, 0, NULL, &num_devices ), "clGetDeviceIDs failed" ); - num_all_devices += num_devices; + while (platforms_it != platforms.end()) { + cl_int err = clGetDeviceIDs(*platforms_it, CL_DEVICE_TYPE_ALL, 0, NULL, &num_devices); + if (err == CL_DEVICE_NOT_FOUND) { + platforms_it = platforms.erase(platforms_it); + } else { + enforce_cl_retcode(err, "clGetDeviceIDs failed"); + num_all_devices += num_devices; + ++platforms_it; + } } - std::vector devices( num_all_devices ); - std::vector::iterator it = devices.begin(); - for ( cl_platform_id p : platforms ) { - cl_uint num_devices; - enforce_cl_retcode( clGetDeviceIDs( p, CL_DEVICE_TYPE_ALL, (cl_uint)std::distance( it, devices.end() ), &*it, &num_devices ), "clGetDeviceIDs failed" ); - it += num_devices; + std::vector devices(num_all_devices); + std::vector::iterator devices_it = devices.begin(); + for (auto p = platforms.begin(); p != platforms.end(); ++p) { + enforce_cl_retcode(clGetDeviceIDs((*p), CL_DEVICE_TYPE_ALL, (cl_uint)std::distance(devices_it, devices.end()), &*devices_it, &num_devices), "clGetDeviceIDs failed"); + devices_it += num_devices; } - for ( cl_device_id d : devices ) my_devices.add( opencl_device( d ) ); + for (auto d = devices.begin(); d != devices.end(); ++d) { + my_devices.add(opencl_device((*d))); + } } default_opencl_factory &get_default_opencl_factory() { @@ -1145,7 +1199,9 @@ void opencl_factory::init_once() { enforce_cl_retcode( it->platform() == platform_id ? CL_SUCCESS : CL_INVALID_PLATFORM, "All devices should be in the same platform" ); std::vector cl_device_ids; - for ( opencl_device d : my_devices ) cl_device_ids.push_back( d.my_cl_device_id ); + for (auto d = my_devices.begin(); d != my_devices.end(); ++d) { + cl_device_ids.push_back((*d).my_cl_device_id); + } cl_context_properties context_properties[3] = { CL_CONTEXT_PLATFORM, (cl_context_properties)platform_id, (cl_context_properties)NULL }; cl_int err; @@ -1157,23 +1213,23 @@ void opencl_factory::init_once() { my_cl_context = ctx; size_t device_counter = 0; - for ( opencl_device &d : my_devices ) { - d.my_device_id = device_counter++; + for ( auto d = my_devices.begin(); d != my_devices.end(); d++ ) { + (*d).my_device_id = device_counter++; cl_int err2; cl_command_queue cq; #if CL_VERSION_2_0 - if ( d.major_version() >= 2 ) { - if ( d.out_of_order_exec_mode_on_host_present() ) { + if ( (*d).major_version() >= 2 ) { + if ( (*d).out_of_order_exec_mode_on_host_present() ) { cl_queue_properties props[] = { CL_QUEUE_PROPERTIES, CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE, 0 }; - cq = clCreateCommandQueueWithProperties( ctx, d.my_cl_device_id, props, &err2 ); + cq = clCreateCommandQueueWithProperties( ctx, (*d).my_cl_device_id, props, &err2 ); } else { cl_queue_properties props[] = { 0 }; - cq = clCreateCommandQueueWithProperties( ctx, d.my_cl_device_id, props, &err2 ); + cq = clCreateCommandQueueWithProperties( ctx, (*d).my_cl_device_id, props, &err2 ); } } else #endif { - cl_command_queue_properties props = d.out_of_order_exec_mode_on_host_present() ? CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE : 0; + cl_command_queue_properties props = (*d).out_of_order_exec_mode_on_host_present() ? CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE : 0; // Suppress "declared deprecated" warning for the next line. #if __TBB_GCC_WARNING_SUPPRESSION_PRESENT #pragma GCC diagnostic push @@ -1187,7 +1243,7 @@ void opencl_factory::init_once() { #pragma warning (disable: 4996) #endif #endif - cq = clCreateCommandQueue( ctx, d.my_cl_device_id, props, &err2 ); + cq = clCreateCommandQueue( ctx, (*d).my_cl_device_id, props, &err2 ); #if _MSC_VER || __INTEL_COMPILER #pragma warning( pop ) #endif @@ -1196,7 +1252,7 @@ void opencl_factory::init_once() { #endif } enforce_cl_retcode( err2, "Failed to create command queue" ); - d.my_cl_command_queue = cq; + (*d).my_cl_command_queue = cq; } } @@ -1221,22 +1277,34 @@ enum class opencl_program_type { template class opencl_program : tbb::internal::no_assign { public: - opencl_program( opencl_program_type type, const std::string& program_name ) : my_type(type) , my_arg_str( program_name) {} - opencl_program( const char* program_name ) : opencl_program( std::string( program_name ) ) {} - opencl_program( const std::string& program_name ) : opencl_program( opencl_program_type::SOURCE, program_name ) {} + typedef typename Factory::kernel_type kernel_type; - opencl_program( const opencl_program &src ) : my_type( src.type ), my_arg_str( src.my_arg_str ), my_cl_program( src.my_cl_program ) { + opencl_program( Factory& factory, opencl_program_type type, const std::string& program_name ) : my_factory( factory ), my_type(type) , my_arg_str( program_name) {} + opencl_program( Factory& factory, const char* program_name ) : opencl_program( factory, std::string( program_name ) ) {} + opencl_program( Factory& factory, const std::string& program_name ) : opencl_program( factory, opencl_program_type::SOURCE, program_name ) {} + + opencl_program( opencl_graph& graph, opencl_program_type type, const std::string& program_name ) : opencl_program( graph.opencl_factory(), type, program_name ) {} + opencl_program( opencl_graph& graph, const char* program_name ) : opencl_program( graph.opencl_factory(), program_name ) {} + opencl_program( opencl_graph& graph, const std::string& program_name ) : opencl_program( graph.opencl_factory(), program_name ) {} + opencl_program( opencl_graph& graph, opencl_program_type type ) : opencl_program( graph.opencl_factory(), type ) {} + + opencl_program( const opencl_program &src ) : my_factory( src.my_factory ), my_type( src.type ), my_arg_str( src.my_arg_str ), my_cl_program( src.my_cl_program ) { // Set my_do_once_flag to the called state. std::call_once( my_do_once_flag, [](){} ); } + + kernel_type get_kernel( const std::string& k ) const { + return kernel_type( get_cl_kernel(k), my_factory ); + } + private: - opencl_program( cl_program program ) : my_cl_program( program ) { + opencl_program( Factory& factory, cl_program program ) : my_factory( factory ), my_cl_program( program ) { // Set my_do_once_flag to the called state. std::call_once( my_do_once_flag, [](){} ); } - cl_kernel get_kernel( const std::string& k, Factory &f ) const { - std::call_once( my_do_once_flag, [this, &k, &f](){ this->init( f, k ); } ); + cl_kernel get_cl_kernel( const std::string& k ) const { + std::call_once( my_do_once_flag, [this, &k](){ this->init( k ); } ); cl_int err; cl_kernel kernel = clCreateKernel( my_cl_program, k.c_str(), &err ); enforce_cl_retcode( err, std::string( "Failed to create kernel: " ) + k ); @@ -1280,18 +1348,18 @@ private: std::string str = std::string( "Failed to build program: " ) + name; if ( err == CL_BUILD_PROGRAM_FAILURE ) { const opencl_device_list &devices = f.devices(); - for ( opencl_device d : devices ) { - std::cerr << "Build log for device: " << d.name() << std::endl; + for ( auto d = devices.begin(); d != devices.end(); ++d ) { + std::cerr << "Build log for device: " << (*d).name() << std::endl; size_t log_size; cl_int query_err = clGetProgramBuildInfo( - program, d.my_cl_device_id, CL_PROGRAM_BUILD_LOG, 0, NULL, + program, (*d).my_cl_device_id, CL_PROGRAM_BUILD_LOG, 0, NULL, &log_size ); enforce_cl_retcode( query_err, "Failed to get build log size" ); if( log_size ) { std::vector output; output.resize( log_size ); query_err = clGetProgramBuildInfo( - program, d.my_cl_device_id, CL_PROGRAM_BUILD_LOG, + program, (*d).my_cl_device_id, CL_PROGRAM_BUILD_LOG, output.size(), output.data(), NULL ); enforce_cl_retcode( query_err, "Failed to get build output" ); std::cerr << output.data() << std::endl; @@ -1318,14 +1386,14 @@ private: } }; - void init( Factory &f, const std::string& ) const { + void init( const std::string& ) const { cl_uint num_devices; - enforce_cl_retcode( clGetContextInfo( f.context(), CL_CONTEXT_NUM_DEVICES, sizeof( num_devices ), &num_devices, NULL ), + enforce_cl_retcode( clGetContextInfo( my_factory.context(), CL_CONTEXT_NUM_DEVICES, sizeof( num_devices ), &num_devices, NULL ), "Failed to get OpenCL context info" ); if ( !num_devices ) enforce_cl_retcode( CL_DEVICE_NOT_FOUND, "No supported devices found" ); cl_device_id *device_list = (cl_device_id *)alloca( num_devices*sizeof( cl_device_id ) ); - enforce_cl_retcode( clGetContextInfo( f.context(), CL_CONTEXT_DEVICES, num_devices*sizeof( cl_device_id ), device_list, NULL ), + enforce_cl_retcode( clGetContextInfo( my_factory.context(), CL_CONTEXT_DEVICES, num_devices*sizeof( cl_device_id ), device_list, NULL ), "Failed to get OpenCL context info" ); const char *options = NULL; switch ( my_type ) { @@ -1334,7 +1402,7 @@ private: const char *s[] = { fr.content() }; const size_t l[] = { fr.length() }; cl_int err; - my_cl_program = clCreateProgramWithSource( f.context(), 1, s, l, &err ); + my_cl_program = clCreateProgramWithSource( my_factory.context(), 1, s, l, &err ); enforce_cl_retcode( err, std::string( "Failed to create program: " ) + my_arg_str ); opencl_device_filter( num_devices, device_list, @@ -1342,7 +1410,7 @@ private: return !d.compiler_available() || !d.linker_available(); }, "No one device supports building program from sources" ); opencl_program_builder( - f, my_arg_str, my_cl_program, num_devices, device_list, + my_factory, my_arg_str, my_cl_program, num_devices, device_list, options, /*callback*/ NULL, /*user data*/NULL ); break; } @@ -1355,18 +1423,20 @@ private: std::vector l( num_devices, fr.length() ); std::vector bin_statuses( num_devices, -1 ); cl_int err; - my_cl_program = clCreateProgramWithBinary( f.context(), num_devices, + my_cl_program = clCreateProgramWithBinary( my_factory.context(), num_devices, device_list, l.data(), s.data(), bin_statuses.data(), &err ); if( err != CL_SUCCESS ) { std::string statuses_str; - for( cl_int st : bin_statuses ) - statuses_str += std::to_string( st ); + for (auto st = bin_statuses.begin(); st != bin_statuses.end(); ++st) { + statuses_str += std::to_string((*st)); + } + enforce_cl_retcode( err, std::string( "Failed to create program, error " + std::to_string( err ) + " : " ) + my_arg_str + std::string( ", binary_statuses = " ) + statuses_str ); } opencl_program_builder( - f, my_arg_str, my_cl_program, num_devices, device_list, + my_factory, my_arg_str, my_cl_program, num_devices, device_list, options, /*callback*/ NULL, /*user data*/NULL ); break; } @@ -1375,720 +1445,55 @@ private: } } + Factory& my_factory; opencl_program_type my_type; std::string my_arg_str; mutable cl_program my_cl_program; mutable std::once_flag my_do_once_flag; - template - friend class opencl_node; -}; + template + friend class opencl_factory; -template -struct port_ref_impl { - // "+1" since the port_ref range is a closed interval (includes its endpoints). - static const int size = N2-N1+1; - -}; - -// 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 -port_ref_impl port_ref() { - return port_ref_impl(); -}; - -template -struct num_arguments { - static const int value = 1; -}; - -template -struct num_arguments(*)()> { - static const int value = port_ref_impl::size; -}; - -template -struct num_arguments> { - static const int value = port_ref_impl::size; + template + friend class opencl_factory::kernel; }; template class opencl_node; -template -void ignore_return_values( Args&&... ) {} - -template -T or_return_values( T&& t ) { return t; } -template -T or_return_values( T&& t, Rest&&... rest ) { - return t | or_return_values( std::forward(rest)... ); -} - - -#define is_typedef(type) \ - template \ - struct is_##type { \ - template \ - static std::true_type check( typename C::type* ); \ - template \ - static std::false_type check( ... ); \ - \ - static const bool value = decltype(check(0))::value; \ - } - -is_typedef( native_object_type ); -is_typedef( memory_object_type ); - -template -typename std::enable_if::value, typename T::native_object_type>::type get_native_object( const T &t ) { - return t.native_object(); -} - -template -typename std::enable_if::value, T>::type get_native_object( T t ) { - return t; -} - -// send_if_memory_object checks if the T type has memory_object_type and call the send method for the object. -template -typename std::enable_if::value>::type send_if_memory_object( opencl_device device, dependency_msg &dmsg ) { - const T &t = dmsg.data( false ); - typedef typename T::memory_object_type mem_obj_t; - mem_obj_t mem_obj = t.memory_object(); - dependency_msg d( mem_obj ); - if ( dmsg.get_event() ) d.set_event( *dmsg.get_event() ); - mem_obj.send( device, d ); - if ( d.get_event() ) dmsg.set_event( *d.get_event() ); -} - -template -typename std::enable_if::value>::type send_if_memory_object( opencl_device device, const T &t ) { - typedef typename T::memory_object_type mem_obj_t; - mem_obj_t mem_obj = t.memory_object(); - dependency_msg dmsg( mem_obj ); - mem_obj.send( device, dmsg ); -} - -template -typename std::enable_if::value>::type send_if_memory_object( opencl_device, const T& ) {}; - -// receive_if_memory_object checks if the T type has memory_object_type and call the receive method for the object. -template -typename std::enable_if::value>::type receive_if_memory_object( const dependency_msg &dmsg ) { - const T &t = dmsg.data( false ); - typedef typename T::memory_object_type mem_obj_t; - mem_obj_t mem_obj = t.memory_object(); - dependency_msg d( mem_obj ); - if ( dmsg.get_event() ) d.set_event( *dmsg.get_event() ); - mem_obj.receive( d ); - if ( d.get_event() ) dmsg.set_event( *d.get_event() ); -} - -template -typename std::enable_if::value>::type receive_if_memory_object( const T& ) {} - -template -struct key_from_policy { - typedef size_t type; - typedef std::false_type is_key_matching; -}; - -template -struct key_from_policy< key_matching > { - typedef Key type; - typedef std::true_type is_key_matching; -}; - -template -struct key_from_policy< key_matching > { - typedef const Key &type; - typedef std::true_type is_key_matching; -}; - -template -class opencl_device_with_key { - opencl_device my_device; - typename std::decay::type my_key; -public: - // TODO: investigate why defaul ctor is required - opencl_device_with_key() {} - opencl_device_with_key( opencl_device d, Key k ) : my_device( d ), my_key( k ) {} - Key key() const { return my_key; } - opencl_device device() const { return my_device; } -}; - -/* - /---------------------------------------- opencl_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 -class opencl_node< tuple, JP, Factory > : public composite_node < tuple...>, tuple...> >{ - typedef tuple...> input_tuple; - typedef input_tuple output_tuple; - typedef typename key_from_policy::type key_type; - typedef composite_node base_type; - static const size_t NUM_INPUTS = tuple_size::value; - static const size_t NUM_OUTPUTS = tuple_size::value; - - typedef typename internal::make_sequence::type input_sequence; - typedef typename internal::make_sequence::type output_sequence; - - typedef indexer_node...> indexer_node_type; - typedef typename indexer_node_type::output_type indexer_node_output_type; - typedef tuple, dependency_msg...> kernel_input_tuple; - typedef multifunction_node device_selector_node; - typedef multifunction_node kernel_multifunction_node; - - template - typename base_type::input_ports_type get_input_ports( internal::sequence ) { - return std::tie( internal::input_port( my_indexer_node )... ); - } - - template - typename base_type::output_ports_type get_output_ports( internal::sequence ) { - return std::tie( internal::output_port( 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 make_Nth_edge() { - make_edge( internal::output_port( my_device_selector_node ), internal::input_port( my_join_node ) ); - return 0; - } - - template - void make_edges( internal::sequence ) { - make_edge( my_indexer_node, my_device_selector_node ); - make_edge( my_device_selector_node, my_join_node ); - ignore_return_values( make_Nth_edge()... ); - 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( opencl_node &n ) const = 0; - virtual ~device_selector_base() {} - }; - - template - class device_selector : public device_selector_base, tbb::internal::no_assign { - public: - device_selector( UserFunctor uf, opencl_node &n, Factory &f ) : my_user_functor( uf ), my_node(n), my_factory( f ) { - my_port_epoches.fill( 0 ); - } - - /* override */ void operator()( const indexer_node_output_type &v, typename device_selector_node::output_ports_type &op ) { - send_and_put( my_port_epoches[v.tag()], v, op, input_sequence() ); - __TBB_ASSERT( (std::is_same::is_key_matching, std::false_type>::value) || my_port_epoches[v.tag()] == 0, "Epoch is changed when key matching is requested" ); - } - - /* override */ device_selector_base *clone( opencl_node &n ) const { - return new device_selector( my_user_functor, n, my_factory ); - } - private: - template - void send_and_put( size_t &epoch, const indexer_node_output_type &v, typename device_selector_node::output_ports_type &op, internal::sequence ) { - typedef void(device_selector::*send_and_put_fn)(size_t &, const indexer_node_output_type &, typename device_selector_node::output_ports_type &); - static std::array dispatch = { { &device_selector::send_and_put_impl... } }; - (this->*dispatch[v.tag()])( epoch, v, op ); - } - - template - key_type get_key( std::false_type, const T &, size_t &epoch ) { - __TBB_STATIC_ASSERT( (std::is_same::value), "" ); - return epoch++; - } - - template - key_type get_key( std::true_type, const T &t, size_t &/*epoch*/ ) { - using tbb::flow::key_from_message; - return key_from_message( t ); - } - - template - 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::type::output_type elem_type; - elem_type e = internal::cast_to( v ); - opencl_device device = get_device( get_key( typename key_from_policy::is_key_matching(), e, epoch ), get<0>( op ) ); - send_if_memory_object( device, e ); - get( op ).try_put( e ); - } - - template< typename DevicePort > - opencl_device get_device( key_type key, DevicePort& dp ) { - typename std::unordered_map::type, epoch_desc>::iterator it = my_devices.find( key ); - if ( it == my_devices.end() ) { - opencl_device d = my_user_functor( my_factory.devices() ); - std::tie( it, std::ignore ) = my_devices.insert( std::make_pair( key, d ) ); - bool res = dp.try_put( opencl_device_with_key( d, key ) ); - __TBB_ASSERT_EX( res, NULL ); - my_node.notify_new_device( d ); - } - epoch_desc &e = it->second; - opencl_device d = e.my_device; - if ( ++e.my_request_number == NUM_INPUTS ) my_devices.erase( it ); - return d; - } - - struct epoch_desc { - epoch_desc( opencl_device d ) : my_device( d ), my_request_number( 0 ) {} - opencl_device my_device; - size_t my_request_number; - }; - - std::unordered_map::type, epoch_desc> my_devices; - std::array my_port_epoches; - UserFunctor my_user_functor; - opencl_node &my_node; - Factory &my_factory; - }; - - class device_selector_body { - public: - device_selector_body( device_selector_base *d ) : my_device_selector( d ) {} - - /* override */ 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; - }; - - // Forward declaration. - class ndranges_mapper_base; - - class opencl_kernel_base : tbb::internal::no_copy { - cl_kernel clone_kernel() const { - size_t ret_size; - - std::vector kernel_name; - for ( size_t curr_size = 32;; curr_size <<= 1 ) { - kernel_name.resize( curr_size <<= 1 ); - enforce_cl_retcode( clGetKernelInfo( my_kernel, CL_KERNEL_FUNCTION_NAME, curr_size, kernel_name.data(), &ret_size ), "Failed to get kernel info" ); - if ( ret_size < curr_size ) break; - } - - cl_program program; - enforce_cl_retcode( clGetKernelInfo( my_kernel, CL_KERNEL_PROGRAM, sizeof( program ), &program, &ret_size ), "Failed to get kernel info" ); - __TBB_ASSERT( ret_size == sizeof( program ), NULL ); - - return opencl_program( program ).get_kernel( kernel_name.data(), my_factory ); - } - - // ------------- NDRange getters ------------- // - template - NDRange ndrange_value( NDRange&& r, const kernel_input_tuple& ) const { return r; } - template - typename tuple_element::type::value_type ndrange_value( port_ref_impl, const kernel_input_tuple& ip ) const { - // "+1" since get<0>(ip) is opencl_device. - return get(ip).data(false); - } - template - void ndrange_value( port_ref_impl, const kernel_input_tuple& ip ) const { - __TBB_STATIC_ASSERT( N1==N2, "Do not use a port_ref range (e.g. port_ref<0,2>) as an argument for the set_ndranges routine" ); - } - template - typename tuple_element::type::value_type ndrange_value( port_ref_impl(*)(), const kernel_input_tuple& ip ) const { - return ndrange_value(port_ref(), ip); - } - template - void ndrange_value( port_ref_impl(*)(), const kernel_input_tuple& ip ) const { - return ndrange_value(port_ref(), ip); - } - // ------------------------------------------- // - public: - typedef typename kernel_multifunction_node::output_ports_type output_ports_type; - - virtual void enqueue( const ndranges_mapper_base *ndranges_mapper, const kernel_input_tuple &ip, output_ports_type &op, graph &g ) = 0; - virtual void send_memory_objects( opencl_device d ) = 0; - virtual opencl_kernel_base *clone() const = 0; - virtual ~opencl_kernel_base () { - enforce_cl_retcode( clReleaseKernel( my_kernel ), "Failed to release a kernel" ); - } - - template - cl_event enqueue( GlbNDRange&& glb_range, LclNDRange&& lcl_range, int num_events, std::array events, const kernel_input_tuple& ip ) { - return my_factory.enqueue_kernel( get<0>( ip ).device(), my_kernel, ndrange_value( glb_range, ip ), ndrange_value( lcl_range, ip ), num_events, events.data() ); - } - protected: - opencl_kernel_base( const opencl_program& p, const std::string& kernel_name, Factory &f ) - : my_kernel( p.get_kernel( kernel_name, f ) ), my_factory( f ) - {} - - opencl_kernel_base( const opencl_kernel_base &k ) - : my_kernel( k.clone_kernel() ), my_factory( k.my_factory ) - {} - - const cl_kernel my_kernel; - Factory &my_factory; - }; - - // Container for ndrandes. It can contain either port references or real ndranges. - class ndranges_mapper_base { - public: - virtual cl_event enqueue_kernel( opencl_kernel_base *k, const kernel_input_tuple& ip, int num_events, const std::array &events ) const = 0; - virtual ndranges_mapper_base *clone() const = 0; - virtual ~ndranges_mapper_base() {} - }; - - template - class opencl_kernel : public opencl_kernel_base { - typedef typename opencl_kernel_base::output_ports_type output_ports_type; - // --------- Kernel argument helpers --------- // - template - void set_one_kernel_arg(const T& t) { - auto p = get_native_object( t ); - enforce_cl_retcode( clSetKernelArg( this->my_kernel, Place, sizeof( p ), &p ), "Failed to set a kernel argument" ); - } - - template - int set_one_arg_from_range( const kernel_input_tuple& ip ) { - // "+1" since get<0>(ip) is opencl_device - set_one_kernel_arg( get( ip ).data( false ) ); - return 0; - } - - template - void set_args_range(const kernel_input_tuple& ip, internal::sequence) { - ignore_return_values( set_one_arg_from_range( ip )... ); - } - - template - void set_arg_impl( const kernel_input_tuple& ip, port_ref_impl ) { - set_args_range( ip, typename internal::make_sequence::size>::type() ); - } - - template - void set_arg_impl( const kernel_input_tuple& ip, port_ref_impl(*)() ) { - set_arg_impl( ip, port_ref() ); - } - - template - void set_arg_impl( const kernel_input_tuple&, const T& t ) { - set_one_kernel_arg( t ); - } - - template - void set_args( const kernel_input_tuple& ) {} - - template - void set_args( const kernel_input_tuple& ip, const T& t, Rest&&... rest ) { - set_arg_impl( ip, t ); - set_args::value>( ip, std::forward(rest)... ); - } - // ------------------------------------------- // - - // -------- Kernel event list helpers -------- // - int add_event_to_list( std::array &events, int &num_events, const cl_event *e ) { - __TBB_ASSERT( (static_cast::size_type>(num_events) < events.size()), NULL ); - if ( e ) events[num_events++] = *e; - return 0; - } - - template - int generate_event_list( std::array &events, const kernel_input_tuple& ip, internal::sequence ) { - int num_events = 0; - ignore_return_values( add_event_to_list( events, num_events, get( ip ).get_event() )... ); - return num_events; - } - // ------------------------------------------- // - - // ---------- Update events helpers ---------- // - template - bool update_event_and_try_put( graph &g, cl_event e, const kernel_input_tuple& ip, output_ports_type &op ) { - auto t = get( ip ); - t.set_event( e ); - t.set_graph( g ); - auto &port = get( op ); - return port.try_put( t ); - } - - template - bool update_events_and_try_put( graph &g, cl_event e, const kernel_input_tuple& ip, output_ports_type &op, internal::sequence ) { - return or_return_values( update_event_and_try_put( g, e, ip, op )... ); - } - // ------------------------------------------- // - - class set_args_func : tbb::internal::no_assign { - public: - set_args_func( opencl_kernel &k, const kernel_input_tuple &ip ) : my_opencl_kernel( k ), my_ip( ip ) {} - // 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 - void operator()( A&&... a ) { - my_opencl_kernel.set_args<0>( my_ip, std::forward( a )... ); - } - private: - opencl_kernel &my_opencl_kernel; - const kernel_input_tuple &my_ip; - }; - - class send_func : tbb::internal::no_assign { - public: - send_func( opencl_device d ) : my_device( d ) {} - void operator()() {} - template - void operator()( T &&t, Rest&&... rest ) { - send_if_memory_object( my_device, std::forward( t ) ); - (*this)( std::forward( rest )... ); - } - private: - opencl_device my_device; - }; - - static void CL_CALLBACK decrement_wait_count_callback( cl_event, cl_int event_command_exec_status, void *data ) { - tbb::internal::suppress_unused_warning( event_command_exec_status ); - __TBB_ASSERT( event_command_exec_status == CL_COMPLETE, NULL ); - graph &g = *static_cast(data); - g.decrement_wait_count(); - } - - public: - opencl_kernel( const opencl_program& p, const std::string &kernel_name, Factory &f, Args&&... args ) - : opencl_kernel_base( p, kernel_name, f ) - , my_args_pack( std::forward( args )... ) - {} - - opencl_kernel( const opencl_kernel_base &k ) : opencl_kernel_base( k ), my_args_pack( k.my_args_pack ) {} - - opencl_kernel( const opencl_kernel_base &k, Args&&... args ) : opencl_kernel_base( k ), my_args_pack( std::forward(args)... ) {} - - /* override */ void enqueue( const ndranges_mapper_base *ndrange_mapper, const kernel_input_tuple &ip, output_ports_type &op, graph &g ) { - // Set arguments for the kernel. - tbb::internal::call( set_args_func( *this, ip ), my_args_pack ); - - // Gather events from all ports to an array. - std::array events; - int num_events = generate_event_list( events, ip, input_sequence() ); - - // Enqueue the kernel. ndrange_mapper is used only to obtain ndrange. Actually, it calls opencl_kernel_base::enqueue. - cl_event e = ndrange_mapper->enqueue_kernel( this, ip, num_events, events ); - - // Update events in dependency messages and try_put them to the output ports. - if ( !update_events_and_try_put( g, e, ip, op, input_sequence() ) ) { - // No one message was passed to successors so set a callback to extend the graph lifetime until the kernel completion. - g.increment_wait_count(); - enforce_cl_retcode( clSetEventCallback( e, CL_COMPLETE, decrement_wait_count_callback, &g ), "Failed to set a callback" ); - this->my_factory.flush( get<0>( ip ).device() ); - } - // Release our own reference to cl_event. - enforce_cl_retcode( clReleaseEvent( e ), "Failed to release an event" ); - } - - virtual void send_memory_objects( opencl_device d ) { - // Find opencl_buffer and send them to the devece. - tbb::internal::call( send_func( d ), my_args_pack ); - } - - /* override */ opencl_kernel_base *clone() const { - // Create new opencl_kernel with copying constructor. - return new opencl_kernel( *this ); - } - - private: - tbb::internal::stored_pack my_args_pack; - }; - - template - class ndranges_mapper : public ndranges_mapper_base, tbb::internal::no_assign { - public: - template - ndranges_mapper( GRange&& glb, LRange&& lcl ) : my_global_work_size( glb ), my_local_work_size( lcl ) {} - - /*override*/ cl_event enqueue_kernel( opencl_kernel_base *k, const kernel_input_tuple &ip, int num_events, const std::array &events ) const { - return k->enqueue( my_global_work_size, my_local_work_size, num_events, events, ip ); - } - - /*override*/ ndranges_mapper_base *clone() const { - return new ndranges_mapper( my_global_work_size, my_local_work_size ); - } - - private: - GlbNDRange my_global_work_size; - LclNDRange my_local_work_size; - }; - - void enqueue_kernel( const kernel_input_tuple &ip, typename opencl_kernel_base::output_ports_type &op ) const { - __TBB_ASSERT(my_ndranges_mapper, "NDRanges are not set. Call set_ndranges before running opencl_node."); - my_opencl_kernel->enqueue( my_ndranges_mapper, ip, op, this->my_graph ); - } - - // Body for kernel_multifunction_node. - class kernel_body : tbb::internal::no_assign { - public: - kernel_body( const opencl_node &node ) : my_opencl_node( node ) {} - void operator()( const kernel_input_tuple &ip, typename opencl_kernel_base::output_ports_type &op ) { - my_opencl_node.enqueue_kernel( ip, op ); - } - private: - const opencl_node &my_opencl_node; - }; - - template - opencl_kernel_base *make_opencl_kernel( const opencl_program &p, const std::string &kernel_name, Factory &f, Args&&... args ) const { - return new opencl_kernel( p, kernel_name, f, std::forward( args )... ); - } - - template > - void set_ndranges_impl( GlobalNDRange&& global_work_size, LocalNDRange&& local_work_size = std::array( { { 0, 0, 0 } } ) ) { - if ( my_ndranges_mapper ) delete my_ndranges_mapper; - my_ndranges_mapper = new ndranges_mapper::type, typename std::decay::type> - ( std::forward( global_work_size ), std::forward( local_work_size ) ); - } - - void notify_new_device( opencl_device d ) { - my_opencl_kernel->send_memory_objects( d ); - } - +class opencl_node< tuple, JP, Factory > : public streaming_node< tuple, JP, Factory > { + typedef streaming_node < tuple, JP, Factory > base_type; public: + typedef typename base_type::kernel_type kernel_type; + + opencl_node( opencl_graph &g, const kernel_type& kernel ) + : base_type( g, kernel, g.get_opencl_foundation().get_default_device_selector(), g.get_opencl_foundation().get_default_opencl_factory() ) + {} + + opencl_node( opencl_graph &g, const kernel_type& kernel, Factory &f ) + : base_type( g, kernel, g.get_opencl_foundation().get_default_device_selector(), f ) + {} + template - opencl_node( opencl_graph &g, const opencl_program &p, const std::string &kernel_name, DeviceSelector d, Factory &f ) - : base_type( g ) - , my_indexer_node( g ) - , my_device_selector( new device_selector( 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, opencl_node maps all its ports to the kernel arguments on a one-to-one basis. - , my_opencl_kernel( make_opencl_kernel( p , kernel_name, f, port_ref<0, NUM_INPUTS - 1>()) ) - , my_ndranges_mapper( NULL ) - { - base_type::set_external_ports( get_input_ports(), get_output_ports() ); - make_edges(); - } - - opencl_node( opencl_graph &g, const opencl_program &p, const std::string &kernel_name, Factory &f ) - : opencl_node( g, p, kernel_name, g.get_opencl_foundation().get_default_device_selector(), f ) - {} - - - opencl_node( const opencl_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_opencl_kernel( node.my_opencl_kernel->clone() ) - , my_ndranges_mapper( node.my_ndranges_mapper ? node.my_ndranges_mapper->clone() : NULL ) - { - base_type::set_external_ports( get_input_ports(), get_output_ports() ); - make_edges(); - } - - opencl_node( opencl_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_opencl_kernel( node.my_opencl_kernel ) - , my_ndranges_mapper( node.my_ndranges_mapper ) - { - 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_opencl_kernel = NULL; - node.my_ndranges_mapper = NULL; - } - - ~opencl_node() { - if ( my_opencl_kernel ) delete my_opencl_kernel; - if ( my_ndranges_mapper ) delete my_ndranges_mapper; - if ( my_device_selector ) delete my_device_selector; - } - - template - void set_ndranges( std::initializer_list global_work_size ) { - set_ndranges_impl( internal::initializer_list_wrapper( global_work_size ) ); - } - - template - void set_ndranges( GlobalNDRange&& global_work_size ) { - set_ndranges_impl( std::forward( global_work_size ) ); - } - - template - void set_ndranges( std::initializer_list global_work_size, LocalNDRange&& local_work_size ) { - set_ndranges_impl( internal::initializer_list_wrapper(global_work_size), std::forward( local_work_size ) ); - } - - template - void set_ndranges( std::initializer_list global_work_size, std::initializer_list local_work_size ) { - set_ndranges_impl( internal::initializer_list_wrapper(global_work_size), internal::initializer_list_wrapper(local_work_size) ); - } - - template - void set_ndranges( GlobalNDRange&& global_work_size, LocalNDRange&& local_work_size ) { - set_ndranges_impl( std::forward(global_work_size), std::forward(local_work_size) ); - } - - template - void set_ndranges( GlobalNDRange&& global_work_size, std::initializer_list local_work_size ) { - set_ndranges_impl( std::forward( global_work_size ), internal::initializer_list_wrapper( local_work_size ) ); - } - - template - void set_args( Args&&... args ) { - // Copy the base class of opencl_kernal and create new storage for "Args...". - opencl_kernel_base *new_opencl_kernel = new opencl_kernel( *my_opencl_kernel, std::forward( args )... ); - delete my_opencl_kernel; - my_opencl_kernel = new_opencl_kernel; - } - -protected: - /* override */ void reset_node( reset_flags = rf_reset_protocol ) { __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 my_join_node; - kernel_multifunction_node my_kernel_node; - - opencl_kernel_base *my_opencl_kernel; - ndranges_mapper_base *my_ndranges_mapper; + opencl_node( opencl_graph &g, const kernel_type& kernel, DeviceSelector d, Factory &f) + : base_type( g, kernel, d, f) + {} }; template class opencl_node< tuple, JP > : public opencl_node < tuple, JP, default_opencl_factory > { typedef opencl_node < tuple, JP, default_opencl_factory > base_type; public: - opencl_node( opencl_graph &g, const std::string &kernel ) + typedef typename base_type::kernel_type kernel_type; + + opencl_node( opencl_graph &g, const kernel_type& kernel ) : base_type( g, kernel, g.get_opencl_foundation().get_default_device_selector(), g.get_opencl_foundation().get_default_opencl_factory() ) {} - opencl_node( opencl_graph &g, const opencl_program &p, const std::string &kernel ) - : base_type( g, p, kernel, - g.get_opencl_foundation().get_default_device_selector(), g.get_opencl_foundation().get_default_opencl_factory() ) - {} + template - opencl_node( opencl_graph &g, const opencl_program &p, const std::string &kernel, DeviceSelector d ) - : base_type( g, p , kernel, d, g.get_opencl_foundation().get_default_opencl_factory() ) + opencl_node( opencl_graph &g, const kernel_type& kernel, DeviceSelector d ) + : base_type( g, kernel, d, g.get_opencl_foundation().get_default_opencl_factory() ) {} }; @@ -2096,35 +1501,34 @@ template class opencl_node< tuple > : public opencl_node < tuple, queueing, default_opencl_factory > { typedef opencl_node < tuple, queueing, default_opencl_factory > base_type; public: - opencl_node( opencl_graph &g, const std::string &kernel ) + typedef typename base_type::kernel_type kernel_type; + + opencl_node( opencl_graph &g, const kernel_type& kernel ) : base_type( g, kernel, g.get_opencl_foundation().get_default_device_selector(), g.get_opencl_foundation().get_default_opencl_factory() ) {} - opencl_node( opencl_graph &g, const opencl_program &p, const std::string &kernel ) - : base_type( g, p, kernel, - g.get_opencl_foundation().get_default_device_selector(), g.get_opencl_foundation().get_default_opencl_factory() ) - {} + template - opencl_node( opencl_graph &g, const opencl_program &p, const std::string &kernel, DeviceSelector d ) - : base_type( g, p, kernel, d, g.get_opencl_foundation().get_default_opencl_factory() ) + opencl_node( opencl_graph &g, const kernel_type& kernel, DeviceSelector d ) + : base_type( g, kernel, d, g.get_opencl_foundation().get_default_opencl_factory() ) {} }; -} // namespace interface8 +} // namespace interface9 -using interface8::opencl_graph; -using interface8::opencl_node; -using interface8::read_only; -using interface8::read_write; -using interface8::write_only; -using interface8::opencl_buffer; -using interface8::opencl_subbuffer; -using interface8::opencl_device; -using interface8::opencl_device_list; -using interface8::opencl_program; -using interface8::opencl_program_type; -using interface8::dependency_msg; -using interface8::port_ref; -using interface8::opencl_factory; +using interface9::opencl_graph; +using interface9::opencl_node; +using interface9::read_only; +using interface9::read_write; +using interface9::write_only; +using interface9::opencl_buffer; +using interface9::opencl_subbuffer; +using interface9::opencl_device; +using interface9::opencl_device_list; +using interface9::opencl_program; +using interface9::opencl_program_type; +using interface9::dependency_msg; +using interface9::opencl_factory; +using interface9::opencl_range; } // namespace flow } // namespace tbb diff --git a/lib/3rdParty/tbb/include/tbb/gfx_factory.h b/lib/3rdParty/tbb/include/tbb/gfx_factory.h new file mode 100644 index 0000000..76ca355 --- /dev/null +++ b/lib/3rdParty/tbb/include/tbb/gfx_factory.h @@ -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 +#include +#include +#include + +#include +#include +#include + +namespace tbb { + +namespace flow { + +namespace interface9 { + +template +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 + void share(DataType* p, SizeType n) { check_gfx_retcode(_GFX_share(p, sizeof(*p)*n)); } + template + void unshare(DataType* p) { check_gfx_retcode(_GFX_unshare(p)); } + + // Retrieving array pointer from shared gfx_buffer + // Other types remain the same + template + T* raw_data(gfx_buffer& buffer) { return buffer.data(); } + template + const T* raw_data(const gfx_buffer& buffer) { return buffer.data(); } + template + T& raw_data(T& data) { return data; } + template + const T& raw_data(const T& data) { return data; } + + // Kernel enqueuing on device with arguments + template + 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 +class gfx_buffer { +public: + + typedef typename std::vector::iterator iterator; + typedef typename std::vector::const_iterator const_iterator; + + typedef std::size_t size_type; + + gfx_buffer() : my_vector_ptr(std::make_shared< std::vector >()) {} + gfx_buffer(size_type size) : my_vector_ptr(std::make_shared< std::vector >(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 > my_vector_ptr; +}; + +template +class gfx_async_msg : public tbb::flow::async_msg { +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 + func_wrapper(F ptr) { my_ptr = reinterpret_cast(ptr); } + + template + void operator()(Args&&... args) {} + + operator void*() { return my_ptr; } + + private: + void* my_ptr; + }; + +public: + + // Device specific types + template using async_msg_type = gfx_async_msg; + + 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 + void send_data(device_type /*device*/, Args&... args) { + send_data_impl(args...); + } + + // Run kernel on the device + template + void send_kernel(device_type /*device*/, const kernel_type& kernel, Args&... args) { + // Get packed T data from async_msg 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 lock(future_assignment_mutex); + + // Set callback that waits for kernel execution + callback_future = std::async(std::launch::async, &gfx_factory::callback, this, id, args...); + } + + // Finalization action after the kernel run + template + 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 + void callback(kernel_id_type id, Args... args) { + // Waiting for specific tasks id to complete + { + std::lock_guard 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 + void share_data(T) {} + + template + void share_data(gfx_buffer& buffer) { + gfx_offload::share(buffer.data(), buffer.size()); + } + + template + void send_arg(T) {} + + template + void send_arg(async_msg_type& msg) { + share_data(msg.data()); + } + + void send_data_impl() {} + + template + void send_data_impl(T& arg, Rest&... args) { + send_arg(arg); + send_data_impl(args...); + } + + //---------------------------------------------------------------------- + // send_kernel() arguments processing + //---------------------------------------------------------------------- + + template + void set_kernel_id_arg(kernel_id_type, T) {} + + template + void set_kernel_id_arg(kernel_id_type id, async_msg_type& msg) { + msg.set_task_id(id); + } + + void set_kernel_id(kernel_id_type) {} + + template + 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 + void unshare_data(T) {} + + template + void unshare_data(gfx_buffer& buffer) { + gfx_offload::unshare(buffer.data()); + } + + template + void receive_arg(T) {} + + template + void receive_arg(async_msg_type& msg) { + unshare_data(msg.data()); + msg.set(msg.data()); + } + + void receive_data() {} + + template + void receive_data(T& arg, Rest&... args) { + receive_arg(arg); + receive_data(args...); + } + + //----------------------------------------------------------------------- + int current_task_id; + + std::future 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 diff --git a/lib/3rdParty/tbb/include/tbb/global_control.h b/lib/3rdParty/tbb/include/tbb/global_control.h index d43ff5a..fe74202 100644 --- a/lib/3rdParty/tbb/include/tbb/global_control.h +++ b/lib/3rdParty/tbb/include/tbb/global_control.h @@ -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 diff --git a/lib/3rdParty/tbb/include/tbb/index.html b/lib/3rdParty/tbb/include/tbb/index.html index f0702e2..2eddd45 100644 --- a/lib/3rdParty/tbb/include/tbb/index.html +++ b/lib/3rdParty/tbb/include/tbb/index.html @@ -19,7 +19,7 @@ Include files for Intel® Threading Building Blocks classes and functions.
Up to parent directory

-Copyright © 2005-2016 Intel Corporation. All Rights Reserved. +Copyright © 2005-2017 Intel Corporation. All Rights Reserved.

Intel is a registered trademark or trademark of Intel Corporation or its subsidiaries in the United States and other countries. diff --git a/lib/3rdParty/tbb/include/tbb/internal/_aggregator_impl.h b/lib/3rdParty/tbb/include/tbb/internal/_aggregator_impl.h index 111a6c3..40bbd49 100644 --- a/lib/3rdParty/tbb/include/tbb/internal/_aggregator_impl.h +++ b/lib/3rdParty/tbb/include/tbb/internal/_aggregator_impl.h @@ -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 @@ -36,7 +36,9 @@ using namespace tbb::internal; template class aggregated_operation { 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; + Derived *next; aggregated_operation() : status(0), next(NULL) {} }; @@ -52,19 +54,21 @@ class aggregator_generic { public: aggregator_generic() : handler_busy(false) { pending_operations = NULL; } - //! Place operation in list - /** Place operation in list and either handle list or wait for operation to - complete. - long_life_time specifies life time of an operation inserting in an aggregator. - "Long" (long_life_time == true) life time operation can be accessed - even after executing it. - "Short" (long_life_time == false) life time operations can be destroyed - during executing so any access to it after executing is invalid.*/ + //! Execute an operation + /** Places an operation into the waitlist (pending_operations), and either handles the list, + or waits for the operation to complete, or returns. + The long_life_time parameter specifies the life time of the given operation object. + Operations with long_life_time == true may be accessed after execution. + A "short" life time operation (long_life_time == false) can be destroyed + during execution, and so any access to it after it was put into the waitlist, + including status check, is invalid. As a consequence, waiting for completion + of such operation causes undefined behavior. + */ template < typename handler_type > void execute(operation_type *op, handler_type &handle_operations, bool long_life_time = true) { operation_type *res; - // op->status should be read before inserting the operation in the - // aggregator queue since it can become invalid after executing a + // op->status should be read before inserting the operation into the + // aggregator waitlist since it can become invalid after executing a // handler (if the operation has 'short' life time.) const uintptr_t status = op->status; @@ -76,7 +80,7 @@ public: call_itt_notify(releasing, &(op->status)); // insert the operation in the queue. 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 op->next = res = pending_operations; // NOT A RACE } while (pending_operations.compare_and_swap(op, res) != res); @@ -92,7 +96,7 @@ public: } // not first; wait for op to be ready. 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)); spin_wait_while_eq(op->status, uintptr_t(0)); itt_load_word_with_acquire(op->status); diff --git a/lib/3rdParty/tbb/include/tbb/internal/_concurrent_queue_impl.h b/lib/3rdParty/tbb/include/tbb/internal/_concurrent_queue_impl.h index fc99409..a99a68f 100644 --- a/lib/3rdParty/tbb/include/tbb/internal/_concurrent_queue_impl.h +++ b/lib/3rdParty/tbb/include/tbb/internal/_concurrent_queue_impl.h @@ -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 @@ -33,7 +33,7 @@ #include "../tbb_exception.h" #include "../tbb_profiling.h" #include -#include +#include __TBB_STD_SWAP_HEADER #if !TBB_USE_EXCEPTIONS && _MSC_VER // Suppress "C++ exception handler used, but unwind semantics are not enabled" warning in STL headers @@ -281,15 +281,15 @@ bool micro_queue::pop( void* dst, ticket k, concurrent_queue_base_v3& base call_itt_notify(acquired, &head_counter); if( tail_counter==k ) spin_wait_while_eq( tail_counter, k ); call_itt_notify(acquired, &tail_counter); - page& p = *head_page; - __TBB_ASSERT( &p, NULL ); + page *p = head_page; + __TBB_ASSERT( p, NULL ); size_t index = modulo_power_of_two( k/concurrent_queue_rep_base::n_queue, base.my_rep->items_per_page ); bool success = false; { - micro_queue_pop_finalizer 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)< 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)<n_invalid_entries; } @@ -450,13 +450,13 @@ private: typedef typename micro_queue::padded_page padded_page; typedef typename micro_queue::item_constructor_t item_constructor_t; - /* override */ virtual page *allocate_page() { + virtual page *allocate_page() __TBB_override { concurrent_queue_rep& r = *my_rep; size_t n = sizeof(padded_page) + (r.items_per_page-1)*sizeof(T); return reinterpret_cast(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& r = *my_rep; size_t n = sizeof(padded_page) + (r.items_per_page-1)*sizeof(T); deallocate_block( reinterpret_cast(p), n ); @@ -471,7 +471,7 @@ private: protected: concurrent_queue_base_v3(); - /* override */ virtual ~concurrent_queue_base_v3() { + virtual ~concurrent_queue_base_v3() { #if TBB_USE_ASSERT size_t nq = my_rep->n_queue; for( size_t i=0; i& queue ) : + explicit concurrent_queue_iterator( const concurrent_queue_base_v3::type>& queue ) : concurrent_queue_iterator_base_v3::type>(queue) { } @@ -772,6 +772,8 @@ public: public: 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& other ) : concurrent_queue_iterator_base_v3::type>(other) {} @@ -1023,7 +1025,7 @@ public: #endif //! 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,last)) { } diff --git a/lib/3rdParty/tbb/include/tbb/internal/_concurrent_unordered_impl.h b/lib/3rdParty/tbb/include/tbb/internal/_concurrent_unordered_impl.h index 21f2ae6..b34bc16 100644 --- a/lib/3rdParty/tbb/include/tbb/internal/_concurrent_unordered_impl.h +++ b/lib/3rdParty/tbb/include/tbb/internal/_concurrent_unordered_impl.h @@ -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 @@ -40,7 +40,7 @@ #include // Need std::equal_to (in ../concurrent_unordered_*.h) #include // For tbb_hasher #include // Need std::memset -#include // Need std::swap +#include __TBB_STD_SWAP_HEADER #if !TBB_USE_EXCEPTIONS && _MSC_VER #pragma warning (pop) @@ -269,7 +269,8 @@ public: // Allocate a new node with the given order key and value template - 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); //TODO: use RAII scoped guard instead of explicit catch @@ -284,6 +285,14 @@ public: return (pnode); } + // A helper to avoid excessive requiremens in internal_insert + template + 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 template 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::key_type key_type; typedef typename Traits::hash_compare hash_compare; - typedef typename Traits::value_compare value_compare; typedef typename Traits::allocator_type allocator_type; typedef typename hash_compare::hasher hasher; typedef typename hash_compare::key_equal key_equal; @@ -708,7 +716,7 @@ protected: my_allocator(a), my_maximum_bucket_size((float) initial_bucket_load) { 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(); } @@ -958,7 +966,7 @@ public: // Modifiers std::pair insert(const value_type& value) { - return internal_insert(value); + return internal_insert(value); } iterator insert(const_iterator, const value_type& value) { @@ -968,7 +976,7 @@ public: #if __TBB_CPP11_RVALUE_REF_PRESENT std::pair insert(value_type&& value) { - return internal_insert(std::move(value)); + return internal_insert(std::move(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); pnode->init(order_key); - return internal_insert(pnode->my_element, pnode); + return internal_insert(pnode->my_element, pnode); } template @@ -1194,7 +1202,7 @@ public: size_type current_buckets = my_number_of_buckets; if (current_buckets >= buckets) 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: @@ -1260,40 +1268,34 @@ private: } // Insert an element in the hash given its value - template< typename ValueType> - std::pair internal_insert( __TBB_FORWARDING_REF(ValueType) value, nodeptr_t pnode = NULL) + template + std::pair internal_insert(__TBB_FORWARDING_REF(ValueType) value, nodeptr_t pnode = NULL) { - sokey_t order_key = (sokey_t) my_hash_compare(get_key(value)); - size_type bucket = order_key % my_number_of_buckets; - - //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); - + const key_type *pkey = &get_key(value); + sokey_t hash_key = (sokey_t) my_hash_compare(*pkey); size_type new_count = 0; - order_key = split_order_key_regular(order_key); - raw_iterator it = get_bucket(bucket); + sokey_t order_key = split_order_key_regular(hash_key); + raw_iterator previous = prepare_bucket(hash_key); raw_iterator last = my_solist.raw_end(); - raw_iterator where = it; - - __TBB_ASSERT(where != last, "Invalid head node"); + __TBB_ASSERT(previous != last, "Invalid head node"); // First node is a dummy node - ++where; - - for (;;) + for (raw_iterator where = previous;;) { + ++where; if (where == last || solist_t::get_order_key(where) > order_key || - // if multimapped, stop at the first item equal to us. - (allow_multimapping && solist_t::get_order_key(where) == order_key && - !my_hash_compare(get_key(*where), get_key(value)))) + // if multimapped, stop at the first item equal to us. + (allow_multimapping && solist_t::get_order_key(where) == order_key && + !my_hash_compare(get_key(*where), *pkey))) // TODO: fix negation { - if (!pnode) - pnode = my_solist.create_node(order_key, tbb::internal::forward(value)); + if (!pnode) { + pnode = my_solist.create_node(order_key, tbb::internal::forward(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' - std::pair result = my_solist.try_insert(it, where, pnode, &new_count); + // Try to insert 'pnode' between 'previous' and 'where' + std::pair result = my_solist.try_insert(previous, where, pnode, &new_count); if (result.second) { @@ -1308,38 +1310,30 @@ private: // 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 // concurrent erase operation supported). - where = it; - ++where; + where = previous; continue; } } 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 if (pnode) my_solist.destroy_node(pnode); return std::pair(my_solist.get_iterator(where), false); } // Move the iterator forward - it = where; - ++where; + previous = where; } } // Find the element in the split-ordered list iterator internal_find(const key_type& 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); + sokey_t hash_key = (sokey_t) my_hash_compare(key); + sokey_t order_key = split_order_key_regular(hash_key); 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) { @@ -1352,7 +1346,7 @@ private: // 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 // 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); } } @@ -1363,35 +1357,18 @@ private: // Erase an element from the list. This is not a concurrency safe function. iterator internal_erase(const_iterator it) { - //const reference extends lifetime of possible temporary coming from get_key - const key_type& key = get_key(*it); - 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); + sokey_t hash_key = (sokey_t) my_hash_compare(get_key(*it)); + raw_iterator previous = prepare_bucket(hash_key); raw_iterator last = my_solist.raw_end(); - raw_iterator where = previous; - - __TBB_ASSERT(where != last, "Invalid head node"); + __TBB_ASSERT(previous != last, "Invalid head node"); // First node is a dummy node - ++where; - - for (;;) { + for (raw_iterator where = previous; ; previous = where) { + ++where; if (where == last) return end(); else if (my_solist.get_iterator(where) == 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. pairii_t internal_equal_range(const key_type& 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); + sokey_t hash_key = (sokey_t) my_hash_compare(key); + sokey_t order_key = split_order_key_regular(hash_key); 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) { // There is no element with the given key 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 last = first; @@ -1490,6 +1462,15 @@ private: 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) { size_type segment = segment_index_of(bucket); bucket -= segment_base(segment); diff --git a/lib/3rdParty/tbb/include/tbb/internal/_flow_graph_async_msg_impl.h b/lib/3rdParty/tbb/include/tbb/internal/_flow_graph_async_msg_impl.h new file mode 100644 index 0000000..7d2c3ae --- /dev/null +++ b/lib/3rdParty/tbb/include/tbb/internal/_flow_graph_async_msg_impl.h @@ -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 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(&t); + } + + static void* to_void_ptr(T& t) { + return static_cast(&t); + } + + static const T& from_void_ptr(const void* p) { + return *static_cast(p); + } + + static T& from_void_ptr(void* p) { + return *static_cast(p); + } + + static task* try_put_task_wrapper_impl( receiver* const this_recv, const void *p, bool is_async ) { + if ( is_async ) { + // This (T) is NOT async and incoming 'A t' IS async + // Get data from async_msg + const async_msg& msg = async_helpers< async_msg >::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, 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( &static_cast&>(t) ); + } + + static void* to_void_ptr(T& t) { + return static_cast( &static_cast&>(t) ); + } + + // Sender-classes use non-const interfaces + static const T& from_void_ptr(const void* p) { + return *static_cast( static_cast*>(p) ); + } + + static T& from_void_ptr(void* p) { + return *static_cast( static_cast*>(p) ); + } + + // Used in receiver class + static task* try_put_task_wrapper_impl(receiver* 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::from_void_ptr(p); + const T msg(t); + return this_recv->try_put_task(msg); + } + } +}; + +template +class async_storage { +public: + typedef receiver async_storage_client; + + async_storage() { my_data_ready.store(false); } + + template + async_storage(C&& data) : my_data( std::forward(data) ) { + using namespace tbb::internal; + __TBB_STATIC_ASSERT( (is_same_type::type, typename strip::type>::value), "incoming type must be T" ); + + my_data_ready.store(true); + } + + template + bool set(C&& data) { + using namespace tbb::internal; + __TBB_STATIC_ASSERT( (is_same_type::type, typename strip::type>::value), "incoming type must be T" ); + + { + tbb::spin_mutex::scoped_lock locker(my_mutex); + + if (my_data_ready.load()) { + __TBB_ASSERT(false, "double set() call"); + return false; + } + + my_data = std::forward(data); + my_data_ready.store(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::spin_mutex::scoped_lock locker(my_mutex); + + if (! my_data_ready.load()) { +#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(), "data is NOT ready"); + return client.try_put_task(my_data); + } + +private: + tbb::spin_mutex my_mutex; + + tbb::atomic my_data_ready; + T my_data; + + typedef std::vector subscriber_list_type; + subscriber_list_type my_clients; +}; + +} // namespace internal + +template +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 >()) {} + + async_msg(const T& t) : my_storage(std::make_shared< internal::async_storage >(t)) {} + + async_msg(T&& t) : my_storage(std::make_shared< internal::async_storage >( 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 > async_storage_ptr; + async_storage_ptr my_storage; +}; + +#endif // __TBB__flow_graph_async_msg_impl_H diff --git a/lib/3rdParty/tbb/include/tbb/internal/_flow_graph_impl.h b/lib/3rdParty/tbb/include/tbb/internal/_flow_graph_impl.h index 665efc5..92278ca 100644 --- a/lib/3rdParty/tbb/include/tbb/internal/_flow_graph_impl.h +++ b/lib/3rdParty/tbb/include/tbb/internal/_flow_graph_impl.h @@ -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 @@ -69,8 +69,8 @@ namespace internal { class source_body_leaf : public source_body { public: source_body_leaf( const Body &_body ) : body(_body) { } - /*override*/ bool operator()(Output &output) { return body( output ); } - /*override*/ source_body_leaf* clone() { + bool operator()(Output &output) __TBB_override { return body( output ); } + source_body_leaf* clone() __TBB_override { return new source_body_leaf< Output, Body >(body); } Body get_body() { return body; } @@ -92,9 +92,9 @@ namespace internal { class function_body_leaf : public function_body< Input, Output > { public: 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; } - /*override*/ function_body_leaf* clone() { + function_body_leaf* clone() __TBB_override { return new function_body_leaf< Input, Output, B >(body); } private: @@ -106,12 +106,12 @@ namespace internal { class function_body_leaf< continue_msg, continue_msg, B> : public function_body< continue_msg, continue_msg > { public: 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); return i; } 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); } private: @@ -123,12 +123,12 @@ namespace internal { class function_body_leaf< Input, continue_msg, B> : public function_body< Input, continue_msg > { public: function_body_leaf( const B &_body ) : body(_body) { } - continue_msg operator()(const Input &i) { + continue_msg operator()(const Input &i) __TBB_override { body(i); return continue_msg(); } 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); } private: @@ -140,26 +140,17 @@ namespace internal { class function_body_leaf< continue_msg, Output, B > : public function_body< continue_msg, Output > { public: 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); } 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); } private: 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(g)); -} - -inline void set_async_gateway(...) { } -#endif - //! function_body that takes an Input and a set of output ports template class multifunction_body : tbb::internal::no_assign { @@ -167,9 +158,7 @@ inline void set_async_gateway(...) { } virtual ~multifunction_body () {} virtual void operator()(const Input &/* input*/, OutputSet &/*oset*/) = 0; virtual multifunction_body* clone() = 0; -#if __TBB_PREVIEW_ASYNC_NODE - virtual void set_gateway(void *gateway) = 0; -#endif + virtual void* get_body_ptr() = 0; }; //! 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 { public: 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. } - B get_body() { return body; } - -#if __TBB_PREVIEW_ASYNC_NODE - /*override*/ void set_gateway(void *gateway) { - set_async_gateway(&body, gateway); - } -#endif - /*override*/ multifunction_body_leaf* clone() { + void* get_body_ptr() __TBB_override { return &body; } + multifunction_body_leaf* clone() __TBB_override { return new multifunction_body_leaf(body); } @@ -218,9 +201,9 @@ template class type_to_key_function_body_leaf : public type_to_key_function_body { public: 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; } - /*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); } private: @@ -231,17 +214,13 @@ template class type_to_key_function_body_leaf : public type_to_key_function_body< Input, Output&> { public: type_to_key_function_body_leaf( const B &_body ) : body(_body) { } - - /*override*/const Output& operator()(const Input &i) { + const Output& operator()(const Input &i) __TBB_override { return body(i); } - 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); } - private: B body; }; @@ -260,7 +239,7 @@ private: forward_task_bypass( NodeType &n ) : my_node(n) {} - task *execute() { + task *execute() __TBB_override { task * new_task = my_node.forward_task(); if (new_task == SUCCESSFULLY_ENQUEUED) new_task = NULL; return new_task; @@ -279,7 +258,7 @@ private: 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 ); if(next_task == SUCCESSFULLY_ENQUEUED) next_task = NULL; return next_task; @@ -296,7 +275,7 @@ private: source_task_bypass( NodeType &n ) : my_node(n) {} - task *execute() { + task *execute() __TBB_override { task *new_task = my_node.apply_body_bypass( ); if(new_task == SUCCESSFULLY_ENQUEUED) return NULL; return new_task; @@ -405,12 +384,22 @@ private: //! A cache of predecessors that only supports try_get 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, M > { +#endif // __TBB_PREVIEW_ASYNC_MSG public: typedef M mutex_type; typedef T output_type; +#if __TBB_PREVIEW_ASYNC_MSG + typedef untyped_sender predecessor_type; + typedef untyped_receiver successor_type; +#else typedef sender predecessor_type; typedef receiver successor_type; +#endif // __TBB_PREVIEW_ASYNC_MSG predecessor_cache( ) : my_owner( NULL ) { } @@ -462,19 +451,25 @@ private: protected: #if TBB_PREVIEW_FLOW_GRAPH_FEATURES - using node_cache< sender, M >::my_built_predecessors; + using node_cache< predecessor_type, M >::my_built_predecessors; #endif successor_type *my_owner; }; //! 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 > class reservable_predecessor_cache : public predecessor_cache< T, M > { public: typedef M mutex_type; typedef T output_type; +#if __TBB_PREVIEW_ASYNC_MSG + typedef untyped_sender predecessor_type; + typedef untyped_receiver successor_type; +#else typedef sender predecessor_type; typedef receiver successor_type; +#endif // __TBB_PREVIEW_ASYNC_MSG reservable_predecessor_cache( ) : reserved_src(NULL) { } @@ -538,6 +533,7 @@ private: //! An abstract cache of successors + // TODO: make successor_cache type T-independent when async_msg becomes regular feature template class successor_cache : tbb::internal::no_copy { protected: @@ -545,15 +541,22 @@ private: typedef M mutex_type; 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 successor_type; typedef receiver *pointer_type; + typedef sender owner_type; +#endif // __TBB_PREVIEW_ASYNC_MSG typedef std::list< pointer_type > successors_type; #if TBB_PREVIEW_FLOW_GRAPH_FEATURES edge_container my_built_successors; #endif successors_type my_successors; - sender *my_owner; + owner_type *my_owner; public: #if TBB_PREVIEW_FLOW_GRAPH_FEATURES @@ -585,7 +588,7 @@ private: successor_cache( ) : my_owner(NULL) {} - void set_owner( sender *owner ) { my_owner = owner; } + void set_owner( owner_type *owner ) { my_owner = owner; } virtual ~successor_cache() {} @@ -617,7 +620,9 @@ private: #endif } +#if !__TBB_PREVIEW_ASYNC_MSG virtual task * try_put_task( const T &t ) = 0; +#endif // __TBB_PREVIEW_ASYNC_MSG }; // successor_cache //! An abstract cache of successors, specialized to continue_msg @@ -628,8 +633,13 @@ private: typedef spin_rw_mutex mutex_type; mutex_type my_mutex; +#if __TBB_PREVIEW_ASYNC_MSG + typedef untyped_receiver successor_type; + typedef untyped_receiver *pointer_type; +#else typedef receiver successor_type; typedef receiver *pointer_type; +#endif // __TBB_PREVIEW_ASYNC_MSG typedef std::list< pointer_type > successors_type; successors_type my_successors; #if TBB_PREVIEW_FLOW_GRAPH_FEATURES @@ -708,11 +718,14 @@ private: #endif } +#if !__TBB_PREVIEW_ASYNC_MSG virtual task * try_put_task( const continue_msg &t ) = 0; +#endif // __TBB_PREVIEW_ASYNC_MSG }; // successor_cache< continue_msg > //! A cache of successors that are broadcast to + // TODO: make broadcast_cache type T-independent when async_msg becomes regular feature template class broadcast_cache : public successor_cache { typedef M mutex_type; @@ -723,7 +736,12 @@ private: broadcast_cache( ) {} // 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 + 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; bool upgraded = true; 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 + // TODO: make round_robin_cache type T-independent when async_msg becomes regular feature template class round_robin_cache : public successor_cache { typedef size_t size_type; @@ -767,7 +786,12 @@ private: return this->my_successors.size(); } - /*override*/task *try_put_task( const T &t ) { +#if __TBB_PREVIEW_ASYNC_MSG + template + 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; typename mutex_type::scoped_lock l(this->my_mutex, upgraded); typename successors_type::iterator i = this->my_successors.begin(); @@ -797,7 +821,7 @@ private: T *my_node; - task *execute() { + task *execute() __TBB_override { return my_node->decrement_counter(); } diff --git a/lib/3rdParty/tbb/include/tbb/internal/_flow_graph_indexer_impl.h b/lib/3rdParty/tbb/include/tbb/internal/_flow_graph_indexer_impl.h index ee2bef8..1fc6690 100644 --- a/lib/3rdParty/tbb/include/tbb/internal/_flow_graph_indexer_impl.h +++ b/lib/3rdParty/tbb/include/tbb/internal/_flow_graph_indexer_impl.h @@ -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 @@ -25,7 +25,7 @@ #error Do not #include this internal file directly; use public TBB headers instead. #endif -#include "tbb/internal/_flow_graph_types_impl.h" +#include "_flow_graph_types_impl.h" namespace internal { @@ -106,43 +106,40 @@ namespace internal { } #if TBB_PREVIEW_FLOW_GRAPH_FEATURES typedef typename receiver::predecessor_list_type predecessor_list_type; + typedef typename receiver::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); return my_built_predecessors.edge_count(); } - /*override*/void internal_add_built_predecessor(sender &p) { + void internal_add_built_predecessor(predecessor_type &p) __TBB_override { spin_mutex::scoped_lock l(my_pred_mutex); my_built_predecessors.add_edge(p); } - /*override*/void internal_delete_built_predecessor(sender &p) { + void internal_delete_built_predecessor(predecessor_type &p) __TBB_override { spin_mutex::scoped_lock l(my_pred_mutex); 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); - return my_built_predecessors.copy_edges(v); - } - /*override*/void clear_predecessors() { - spin_mutex::scoped_lock l(my_pred_mutex); - my_built_predecessors.clear(); + my_built_predecessors.copy_edges(v); } #endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */ protected: template< typename R, typename B > friend class run_and_put_task; template friend class internal::broadcast_cache; template 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); } public: #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 - /*override*/void reset_receiver(reset_flags /*f*/) { } + void reset_receiver(reset_flags /*f*/) __TBB_override { } #endif #if TBB_PREVIEW_FLOW_GRAPH_FEATURES @@ -175,7 +172,7 @@ namespace internal { static const size_t N = tbb::flow::tuple_size::value; typedef OutputType output_type; typedef StructTypes tuple_types; - typedef receiver successor_type; + typedef typename sender::successor_type successor_type; typedef indexer_node_FE input_ports_type; #if TBB_PREVIEW_FLOW_GRAPH_FEATURES typedef typename sender::built_successors_type built_successors_type; @@ -190,7 +187,6 @@ namespace internal { blt_succ_cnt, blt_succ_cpy #endif }; - enum op_stat {WAIT=0, SUCCEEDED, FAILED}; typedef indexer_node_base class_type; class indexer_node_base_operation : public aggregated_operation { @@ -272,19 +268,19 @@ namespace internal { 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); my_aggregator.execute(&op_data); 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); my_aggregator.execute(&op_data); 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); my_aggregator.execute(&op_data); return op_data.bypass_t; @@ -292,36 +288,36 @@ namespace internal { #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); 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); my_aggregator.execute(&op_data); } - size_t successor_count() { + size_t successor_count() __TBB_override { indexer_node_base_operation op_data(blt_succ_cnt); my_aggregator.execute(&op_data); 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); op_data.succv = &v; my_aggregator.execute(&op_data); } - void extract() { + void extract() __TBB_override { my_successors.built_successors().sender_extract(*this); indexer_helper::extract(this->my_inputs); } #endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */ protected: - /*override*/void reset_node(reset_flags f) { + void reset_node(reset_flags f) __TBB_override { if(f & rf_clear_edges) { my_successors.clear(); indexer_helper::reset_inputs(this->my_inputs,f); diff --git a/lib/3rdParty/tbb/include/tbb/internal/_flow_graph_item_buffer_impl.h b/lib/3rdParty/tbb/include/tbb/internal/_flow_graph_item_buffer_impl.h index 08b2ffc..85d2686 100644 --- a/lib/3rdParty/tbb/include/tbb/internal/_flow_graph_item_buffer_impl.h +++ b/lib/3rdParty/tbb/include/tbb/internal/_flow_graph_item_buffer_impl.h @@ -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 @@ -56,7 +56,7 @@ namespace internal { size_type my_head; 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) { __TBB_ASSERT(!(size_type(&(my_array[i&(my_array_size-1)].second))%alignment_of::value),NULL); @@ -64,11 +64,17 @@ namespace internal { 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); } - bool my_item_reserved(size_type i) { return item(i).second == reserved_item; } + const buffer_item_type &item(size_type i) const { + __TBB_ASSERT(!(size_type(&(my_array[i&(my_array_size-1)].second))%alignment_of::value), NULL); + __TBB_ASSERT(!(size_type(&(my_array[i&(my_array_size-1)].first))%alignment_of::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 - 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"); item_type *itm = (tbb::internal::punned_cast(&(item(i).first))); return *(const item_type *)itm; @@ -124,15 +130,18 @@ namespace internal { item(i).second = no_item; } - // returns a copy of the front - void copy_front(item_type &v) { + // returns the front element + const item_type& front() const + { __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) { - __TBB_ASSERT(my_item_valid(my_tail-1), "attempt to fetch head non-item"); - v = get_my_item(my_tail-1); + + // returns the back element + const item_type& back() const + { + __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. @@ -191,7 +200,7 @@ namespace internal { if (!my_item_valid(my_tail-1)) { return false; } - copy_back(v); + v = this->back(); destroy_back(); return true; } @@ -200,7 +209,7 @@ namespace internal { if(!my_item_valid(my_head)) { return false; } - copy_front(v); + v = this->front(); destroy_front(); return true; } @@ -251,10 +260,10 @@ namespace internal { protected: 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; // reserving the head - this->copy_front(v); + v = this->front(); this->reserve_item(this->my_head); return true; } diff --git a/lib/3rdParty/tbb/include/tbb/internal/_flow_graph_join_impl.h b/lib/3rdParty/tbb/include/tbb/internal/_flow_graph_join_impl.h index da7495a..4999bef 100644 --- a/lib/3rdParty/tbb/include/tbb/internal/_flow_graph_join_impl.h +++ b/lib/3rdParty/tbb/include/tbb/internal/_flow_graph_join_impl.h @@ -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 @@ -213,7 +213,7 @@ namespace internal { class reserving_port : public receiver { public: typedef T input_type; - typedef sender predecessor_type; + typedef typename receiver::predecessor_type predecessor_type; #if TBB_PREVIEW_FLOW_GRAPH_FEATURES typedef typename receiver::predecessor_list_type predecessor_list_type; typedef typename receiver::built_predecessors_type built_predecessors_type; @@ -320,7 +320,7 @@ namespace internal { template< typename R, typename B > friend class run_and_put_task; template friend class internal::broadcast_cache; template friend class internal::round_robin_cache; - task *try_put_task( const T & ) { + task *try_put_task( const T & ) __TBB_override { return NULL; } @@ -346,14 +346,14 @@ namespace internal { } //! Add a predecessor - bool register_predecessor( sender &src ) { + bool register_predecessor( predecessor_type &src ) __TBB_override { reserving_port_operation op_data(src, reg_pred); my_aggregator.execute(&op_data); return op_data.status == SUCCEEDED; } //! Remove a predecessor - bool remove_predecessor( sender &src ) { + bool remove_predecessor( predecessor_type &src ) __TBB_override { reserving_port_operation op_data(src, rem_pred); my_aggregator.execute(&op_data); return op_data.status == SUCCEEDED; @@ -379,24 +379,24 @@ namespace internal { } #if TBB_PREVIEW_FLOW_GRAPH_FEATURES - /*override*/ built_predecessors_type &built_predecessors() { return my_predecessors.built_predecessors(); } - /*override*/void internal_add_built_predecessor(predecessor_type &src) { + built_predecessors_type &built_predecessors() __TBB_override { return my_predecessors.built_predecessors(); } + void internal_add_built_predecessor(predecessor_type &src) __TBB_override { reserving_port_operation op_data(src, add_blt_pred); 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); my_aggregator.execute(&op_data); } - /*override*/size_t predecessor_count() { + size_t predecessor_count() __TBB_override { reserving_port_operation op_data(blt_pred_cnt); my_aggregator.execute(&op_data); 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); op_data.plist = &l; my_aggregator.execute(&op_data); @@ -408,7 +408,7 @@ namespace internal { #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(); else my_predecessors.reset(); @@ -427,7 +427,7 @@ namespace internal { class queueing_port : public receiver, public item_buffer { public: typedef T input_type; - typedef sender predecessor_type; + typedef typename receiver::predecessor_type predecessor_type; typedef queueing_port class_type; #if TBB_PREVIEW_FLOW_GRAPH_FEATURES typedef typename receiver::built_predecessors_type built_predecessors_type; @@ -449,7 +449,7 @@ namespace internal { T my_val; T *my_arg; #if TBB_PREVIEW_FLOW_GRAPH_FEATURES - sender *pred; + predecessor_type *pred; size_t cnt_val; predecessor_list_type *plist; #endif @@ -494,7 +494,7 @@ namespace internal { break; case get__item: if(!this->buffer_empty()) { - this->copy_front(*(current->my_arg)); + *(current->my_arg) = this->front(); __TBB_store_with_release(current->status, SUCCEEDED); } else { @@ -536,7 +536,7 @@ namespace internal { template< typename R, typename B > friend class run_and_put_task; template friend class internal::broadcast_cache; template 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); my_aggregator.execute(&op_data); __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 - /*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 &p) { + void internal_add_built_predecessor(predecessor_type &p) __TBB_override { queueing_port_operation op_data(add_blt_pred); op_data.pred = &p; my_aggregator.execute(&op_data); } - /*override*/void internal_delete_built_predecessor(sender &p) { + void internal_delete_built_predecessor(predecessor_type &p) __TBB_override { queueing_port_operation op_data(del_blt_pred); op_data.pred = &p; my_aggregator.execute(&op_data); } - /*override*/size_t predecessor_count() { + size_t predecessor_count() __TBB_override { queueing_port_operation op_data(blt_pred_cnt); my_aggregator.execute(&op_data); 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); op_data.plist = &l; my_aggregator.execute(&op_data); @@ -610,7 +610,7 @@ namespace internal { } #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); item_buffer::reset(); #if TBB_PREVIEW_FLOW_GRAPH_FEATURES @@ -622,7 +622,7 @@ namespace internal { private: forwarding_base *my_join; #if TBB_PREVIEW_FLOW_GRAPH_FEATURES - edge_container > my_built_predecessors; + edge_container my_built_predecessors; #endif }; // queueing_port @@ -655,7 +655,7 @@ namespace internal { typedef typename TraitsType::T input_type; typedef typename TraitsType::K key_type; typedef typename tbb::internal::strip::type noref_key_type; - typedef sender predecessor_type; + typedef typename receiver::predecessor_type predecessor_type; typedef typename TraitsType::TtoK type_to_key_func_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; @@ -747,7 +747,7 @@ namespace internal { template< typename R, typename B > friend class run_and_put_task; template friend class internal::broadcast_cache; template 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); task *rtask = NULL; my_aggregator.execute(&op_data); @@ -790,27 +790,27 @@ namespace internal { } #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 &p) { + void internal_add_built_predecessor(predecessor_type &p) __TBB_override { key_matching_port_operation op_data(add_blt_pred); op_data.pred = &p; my_aggregator.execute(&op_data); } - /*override*/void internal_delete_built_predecessor(sender &p) { + void internal_delete_built_predecessor(predecessor_type &p) __TBB_override { key_matching_port_operation op_data(del_blt_pred); op_data.pred = &p; 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); my_aggregator.execute(&op_data); 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); op_data.plist = &l; my_aggregator.execute(&op_data); @@ -831,7 +831,7 @@ namespace internal { my_built_predecessors.receiver_extract(*this); } #endif - /*override*/void reset_receiver(reset_flags f ) { + void reset_receiver(reset_flags f ) __TBB_override { tbb::internal::suppress_unused_warning(f); buffer_type::reset(); #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 increment_port_count() { + void increment_port_count() __TBB_override { ++ports_with_no_inputs; } // 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(this->graph_pointer->is_active()) { 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 - 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(this->graph_pointer->is_active()) { @@ -975,7 +975,7 @@ namespace internal { 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; } @@ -1148,7 +1148,7 @@ namespace internal { __TBB_store_with_release(current->status, FAILED); } else { - this->copy_front(*(current->my_output)); + *(current->my_output) = this->front(); __TBB_store_with_release(current->status, SUCCEEDED); } break; @@ -1188,15 +1188,15 @@ namespace internal { // if all input_ports have items, spawn forward to try and consume tuples // 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); my_aggregator.execute(&op_data); 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; } @@ -1256,7 +1256,7 @@ namespace internal { public: typedef OutputTuple output_type; - typedef receiver successor_type; + typedef typename sender::successor_type successor_type; typedef join_node_FE input_ports_type; using input_ports_type::tuple_build_may_succeed; using input_ports_type::try_to_make_tuple; @@ -1402,44 +1402,44 @@ namespace internal { 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); my_aggregator.execute(&op_data); 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); my_aggregator.execute(&op_data); 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); my_aggregator.execute(&op_data); return op_data.status == SUCCEEDED; } #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); 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); 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); my_aggregator.execute(&op_data); 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); op_data.slist = &l; my_aggregator.execute(&op_data); @@ -1447,7 +1447,7 @@ namespace internal { #endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */ #if TBB_PREVIEW_FLOW_GRAPH_FEATURES - /*override*/void extract() { + void extract() __TBB_override { input_ports_type::extract(); my_successors.built_successors().sender_extract(*this); } @@ -1455,7 +1455,7 @@ namespace internal { protected: - /*override*/void reset_node(reset_flags f) { + void reset_node(reset_flags f) __TBB_override { input_ports_type::reset(f); if(f & rf_clear_edges) my_successors.clear(); } diff --git a/lib/3rdParty/tbb/include/tbb/internal/_flow_graph_node_impl.h b/lib/3rdParty/tbb/include/tbb/internal/_flow_graph_node_impl.h index 0c441fa..eeff72b 100644 --- a/lib/3rdParty/tbb/include/tbb/internal/_flow_graph_node_impl.h +++ b/lib/3rdParty/tbb/include/tbb/internal/_flow_graph_node_impl.h @@ -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 @@ -37,10 +37,22 @@ namespace internal { template< typename T, typename A > class function_input_queue : public item_buffer { public: + bool empty() const { + return this->buffer_empty(); + } + + const T& front() const { + return this->item_buffer::front(); + } + bool pop( T& t ) { return this->pop_front( t ); } + void pop() { + this->destroy_front(); + } + bool push( T& t ) { return this->push_back( t ); } @@ -51,7 +63,6 @@ namespace internal { // call and any handling of the result. template< typename Input, typename A, typename ImplType > class function_input_base : public receiver, 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 #if TBB_PREVIEW_FLOW_GRAPH_FEATURES , add_blt_pred, del_blt_pred, @@ -64,7 +75,7 @@ namespace internal { //! The input type of this receiver typedef Input input_type; - typedef sender predecessor_type; + typedef typename receiver::predecessor_type predecessor_type; typedef predecessor_cache predecessor_cache_type; typedef function_input_queue input_queue_type; typedef typename A::template rebind< input_queue_type >::other queue_allocator_type; @@ -76,7 +87,7 @@ namespace internal { //! Constructor for function_input_base 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_predecessors.set_owner(this); my_aggregator.initialize_handler(handler_type(this)); @@ -85,7 +96,7 @@ namespace internal { //! Copy constructor function_input_base( const function_input_base& src, input_queue_type *q = NULL) : receiver(), 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_predecessors.set_owner(this); @@ -101,13 +112,13 @@ namespace internal { } //! 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 ) { return create_body_task( t ); } else { operation_type op_data(t, tryput_bypass); my_aggregator.execute(&op_data); - if(op_data.status == SUCCEEDED ) { + if(op_data.status == internal::SUCCEEDED) { return op_data.bypass_t; } return NULL; @@ -115,7 +126,7 @@ namespace internal { } //! 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); op_data.r = &src; my_aggregator.execute(&op_data); @@ -123,7 +134,7 @@ namespace internal { } //! 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); op_data.r = &src; my_aggregator.execute(&op_data); @@ -132,32 +143,32 @@ namespace internal { #if TBB_PREVIEW_FLOW_GRAPH_FEATURES //! 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); op_data.r = &src; my_aggregator.execute(&op_data); } //! 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); op_data.r = &src; my_aggregator.execute(&op_data); } - /*override*/ size_t predecessor_count() { + size_t predecessor_count() __TBB_override { operation_type op_data(blt_pred_cnt); my_aggregator.execute(&op_data); 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); op_data.predv = &v; my_aggregator.execute(&op_data); } - /*override*/built_predecessors_type &built_predecessors() { + built_predecessors_type &built_predecessors() __TBB_override { return my_predecessors.built_predecessors(); } #endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */ @@ -173,13 +184,13 @@ namespace internal { forwarder_busy = false; } - graph& my_graph; + graph* my_graph_ptr; const size_t my_max_concurrency; size_t my_concurrency; input_queue_type *my_queue; predecessor_cache 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(); else my_predecessors.reset(); @@ -213,6 +224,32 @@ namespace internal { friend class internal::aggregating_functor; 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) { operation_type *tmp; while (op_list) { @@ -236,35 +273,16 @@ namespace internal { --my_concurrency; __TBB_store_with_release(tmp->status, SUCCEEDED); if (my_concurrencypop(i); - else - item_was_retrieved = my_predecessors.get_item(i); - if (item_was_retrieved) { - ++my_concurrency; - spawn_body_task(i); - } + create_and_spawn_task(/*spawn=*/true); } break; case app_body_bypass: { - task * new_task = NULL; + tmp->bypass_t = NULL; __TBB_ASSERT(my_max_concurrency != 0, NULL); --my_concurrency; - if (my_concurrencypop(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; + if(my_concurrencybypass_t = create_and_spawn_task(/*spawn=*/false); + __TBB_store_with_release(tmp->status, SUCCEEDED); } break; @@ -313,22 +331,14 @@ namespace internal { //! Tries to spawn bodies if available and if concurrency allows void internal_forward(operation_type *op) { op->bypass_t = NULL; - if (my_concurrencypop(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); - return; - } + if (my_concurrency < my_max_concurrency || !my_max_concurrency) + op->bypass_t = create_and_spawn_task(/*spawn=*/false); + if(op->bypass_t) + __TBB_store_with_release(op->status, SUCCEEDED); + else { + forwarder_busy = false; + __TBB_store_with_release(op->status, FAILED); } - __TBB_store_with_release(op->status, FAILED); - forwarder_busy = false; } //! Applies the body to the provided input @@ -347,21 +357,12 @@ namespace internal { //! allocates a task to apply a body inline task * create_body_task( const input_type &input ) { - return (my_graph.is_active()) ? - new(task::allocate_additional_child_of(*(my_graph.root_task()))) + return (my_graph_ptr->is_active()) ? + new(task::allocate_additional_child_of(*(my_graph_ptr->root_task()))) apply_body_task_bypass < class_type, input_type >(*this, input) : 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" task *forward_task() { operation_type op_data(try_fwd); @@ -378,8 +379,8 @@ namespace internal { } inline task *create_forward_task() { - return (my_graph.is_active()) ? - new(task::allocate_additional_child_of(*(my_graph.root_task()))) forward_task_bypass< class_type >(*this) : + return (my_graph_ptr->is_active()) ? + new(task::allocate_additional_child_of(*(my_graph_ptr->root_task()))) forward_task_bypass< class_type >(*this) : NULL; } @@ -540,7 +541,7 @@ namespace internal { template< typename Body > Body copy_function_object() { multifunction_body_type &body_ref = *this->my_body; - return dynamic_cast< internal::multifunction_body_leaf & >(body_ref).get_body(); + return *static_cast(dynamic_cast< internal::multifunction_body_leaf & >(body_ref).get_body_ptr()); } // for multifunction nodes we do not have a single successor as such. So we just tell @@ -557,12 +558,12 @@ namespace internal { protected: #if TBB_PREVIEW_FLOW_GRAPH_FEATURES - /*override*/void extract() { + void extract() { extract_element::extract_this(my_output_ports); } #endif - /*override*/void reset(reset_flags f) { + void reset(reset_flags f) { base_type::reset_function_input_base(f); if(f & rf_clear_edges)clear_element::clear_this(my_output_ports); if(f & rf_reset_bodies) { @@ -644,7 +645,7 @@ namespace internal { return dynamic_cast< internal::function_body_leaf & >(body_ref).get_body(); } - /*override*/void reset_receiver( reset_flags f) { + void reset_receiver( reset_flags f) __TBB_override { continue_receiver::reset_receiver(f); if(f & rf_reset_bodies) { function_body_type *tmp = my_init_body->clone(); @@ -678,7 +679,7 @@ namespace internal { } //! Spawns a task that applies the body - /* override */ task *execute( ) { + task *execute( ) __TBB_override { return (my_graph_ptr->is_active()) ? new ( task::allocate_additional_child_of( *(my_graph_ptr->root_task()) ) ) apply_body_task_bypass< continue_input< Output >, continue_msg >( *this, continue_msg() ) : @@ -694,7 +695,7 @@ namespace internal { template friend struct clear_element; typedef Output output_type; - typedef receiver successor_type; + typedef typename sender::successor_type successor_type; typedef broadcast_cache broadcast_cache_type; #if TBB_PREVIEW_FLOW_GRAPH_FEATURES typedef typename sender::built_successors_type built_successors_type; @@ -707,34 +708,34 @@ namespace internal { } //! Adds a new successor to this node - /* override */ bool register_successor( receiver &r ) { + bool register_successor( successor_type &r ) __TBB_override { successors().register_successor( r ); return true; } //! Removes a successor from this node - /* override */ bool remove_successor( receiver &r ) { + bool remove_successor( successor_type &r ) __TBB_override { successors().remove_successor( r ); return true; } #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 &r) { + void internal_add_built_successor( successor_type &r) __TBB_override { successors().internal_add_built_successor( r ); } - /*override*/ void internal_delete_built_successor( receiver &r) { + void internal_delete_built_successor( successor_type &r) __TBB_override { successors().internal_delete_built_successor( r ); } - /*override*/ size_t successor_count() { + size_t successor_count() __TBB_override { 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); } #endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */ @@ -747,7 +748,9 @@ namespace internal { // // if task pointer is returned will always spawn and return true, else // 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; } protected: diff --git a/lib/3rdParty/tbb/include/tbb/internal/_flow_graph_streaming_node.h b/lib/3rdParty/tbb/include/tbb/internal/_flow_graph_streaming_node.h new file mode 100644 index 0000000..493f76e --- /dev/null +++ b/lib/3rdParty/tbb/include/tbb/internal/_flow_graph_streaming_node.h @@ -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 +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 +internal::port_ref_impl port_ref() { + return internal::port_ref_impl(); +}; + +namespace internal { + +template +struct num_arguments { + static const int value = 1; +}; + +template +struct num_arguments(*)()> { + static const int value = port_ref_impl::size; +}; + +template +struct num_arguments> { + static const int value = port_ref_impl::size; +}; + +template +void ignore_return_values( Args&&... ) {} + +template +T or_return_values( T&& t ) { return t; } +template +T or_return_values( T&& t, Rest&&... rest ) { + return t | or_return_values( std::forward(rest)... ); +} + +template +struct key_from_policy { + typedef size_t type; + typedef std::false_type is_key_matching; +}; + +template +struct key_from_policy< key_matching > { + typedef Key type; + typedef std::true_type is_key_matching; +}; + +template +struct key_from_policy< key_matching > { + typedef const Key &type; + typedef std::true_type is_key_matching; +}; + +template +class streaming_device_with_key { + Device my_device; + typename std::decay::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 +struct is_port_ref_impl { + typedef std::false_type type; +}; + +template +struct is_port_ref_impl< port_ref_impl > { + typedef std::true_type type; +}; + +template +struct is_port_ref_impl< port_ref_impl( * )() > { + typedef std::true_type type; +}; + +template +struct is_port_ref { + typedef typename is_port_ref_impl< typename tbb::internal::strip::type >::type type; +}; + +template +struct convert_and_call_impl; + +template +struct convert_and_call_impl { + static const size_t my_delta = 1; // Index 0 contains device + + template + static void doit(F& f, Tuple& t, A1& a1, Args1&... args1, Args2&... args2) { + convert_and_call_impl::doit_impl(typename is_port_ref::type(), f, t, a1, args1..., args2...); + } + template + static void doit_impl(std::false_type, F& f, Tuple& t, A1& a1, Args1&... args1, Args2&... args2) { + convert_and_call_impl::doit(f, t, args1..., args2..., a1); + } + template + static void doit_impl(std::true_type x, F& f, Tuple& t, port_ref_impl, Args1&... args1, Args2&... args2) { + convert_and_call_impl, Args1...>::doit_impl(x, f, t, port_ref(), args1..., + args2..., std::get(t)); + } + template + static void doit_impl(std::true_type, F& f, Tuple& t, port_ref_impl, Args1&... args1, Args2&... args2) { + convert_and_call_impl::doit(f, t, args1..., args2..., std::get(t)); + } + + template + static void doit_impl(std::true_type x, F& f, Tuple& t, port_ref_impl(* fn)(), Args1&... args1, Args2&... args2) { + doit_impl(x, f, t, fn(), args1..., args2...); + } + template + static void doit_impl(std::true_type x, F& f, Tuple& t, port_ref_impl(* fn)(), Args1&... args1, Args2&... args2) { + doit_impl(x, f, t, fn(), args1..., args2...); + } +}; + +template <> +struct convert_and_call_impl<> { + template + static void doit(F& f, Tuple&, Args2&... args2) { + f(args2...); + } +}; +// ------------------------------------------- // + +template +struct streaming_node_traits { + // Do not use 'using' instead of 'struct' because Microsoft Visual C++ 12.0 fails to compile. + template + struct async_msg_type { + typedef typename StreamFactory::template async_msg_type type; + }; + + typedef tuple< typename async_msg_type::type... > input_tuple; + typedef input_tuple output_tuple; + typedef tuple< streaming_device_with_key< typename StreamFactory::device_type, typename key_from_policy::type >, + typename async_msg_type::type... > kernel_input_tuple; + + // indexer_node parameters pack expansion workaround for VS2013 for streaming_node + typedef indexer_node< typename async_msg_type::type... > indexer_node_type; +}; + +// Default empty implementation +template +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 + 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 +class kernel_executor_helper::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 + 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(ip).data(false); + } + + range_wrapper *clone() const __TBB_override { + return new range_mapper; + } + }; + +protected: + template + 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 + void set_range(port_ref_impl) { + my_range_wrapper = new range_mapper; + } + + template + void set_range(port_ref_impl(*)()) { + my_range_wrapper = new range_mapper; + } + +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 +class streaming_node; + +template +class streaming_node< tuple, JP, StreamFactory > + : public composite_node < typename internal::streaming_node_traits::input_tuple, + typename internal::streaming_node_traits::output_tuple > + , public internal::kernel_executor_helper< StreamFactory, typename internal::streaming_node_traits::kernel_input_tuple > +{ + typedef typename internal::streaming_node_traits::input_tuple input_tuple; + typedef typename internal::streaming_node_traits::output_tuple output_tuple; + typedef typename internal::key_from_policy::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_with_key_type; + typedef composite_node base_type; + static const size_t NUM_INPUTS = tuple_size::value; + static const size_t NUM_OUTPUTS = tuple_size::value; + + typedef typename internal::make_sequence::type input_sequence; + typedef typename internal::make_sequence::type output_sequence; + + typedef typename internal::streaming_node_traits::indexer_node_type indexer_node_type; + typedef typename indexer_node_type::output_type indexer_node_output_type; + typedef typename internal::streaming_node_traits::kernel_input_tuple kernel_input_tuple; + typedef multifunction_node device_selector_node; + typedef multifunction_node kernel_multifunction_node; + + template + typename base_type::input_ports_type get_input_ports( internal::sequence ) { + return std::tie( internal::input_port( my_indexer_node )... ); + } + + template + typename base_type::output_ports_type get_output_ports( internal::sequence ) { + return std::tie( internal::output_port( 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 make_Nth_edge() { + make_edge( internal::output_port( my_device_selector_node ), internal::input_port( my_join_node ) ); + return 0; + } + + template + void make_edges( internal::sequence ) { + 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()... ); + 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 + 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::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::*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 + static dispatch_funcs_type create_dispatch_funcs( internal::sequence ) { + dispatch_funcs_type dispatch = { { &device_selector::send_and_put_impl... } }; + return dispatch; + } + + template + key_type get_key( std::false_type, const T &, size_t &epoch ) { + __TBB_STATIC_ASSERT( (tbb::internal::is_same_type::value), "" ); + return epoch++; + } + + template + key_type get_key( std::true_type, const T &t, size_t &/*epoch*/ ) { + using tbb::flow::key_from_message; + return key_from_message( t ); + } + + template + 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::type::output_type elem_type; + elem_type e = internal::cast_to( v ); + device_type device = get_device( get_key( typename internal::key_from_policy::is_key_matching(), e, epoch ), get<0>( op ) ); + my_factory.send_data( device, e ); + get( op ).try_put( e ); + } + + template< typename DevicePort > + device_type get_device( key_type key, DevicePort& dp ) { + typename std::unordered_map::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::type, epoch_desc> my_devices; + std::array 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 + class args_storage : public args_storage_base { + typedef typename args_storage_base::output_ports_type output_ports_type; + + // ---------- Update events helpers ---------- // + template + bool do_try_put( const kernel_input_tuple& ip, output_ports_type &op ) const { + const auto& t = get( ip ); + auto &port = get( op ); + return port.try_put( t ); + } + + template + bool do_try_put( const kernel_input_tuple& ip, output_ports_type &op, internal::sequence ) const { + return internal::or_return_values( do_try_put( 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 + void operator()( FnArgs&... args ) { + internal::convert_and_call_impl::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 + 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 + 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 + void operator()( FnArgs&... args ) { + internal::convert_and_call_impl::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 + void operator()( FnArgs&... args ) { + my_factory.finalize( my_device, my_fn, args... ); + } + } my_finalize_func; + }; + + template + static run_finalize_func make_run_finalize_func( kernel_input_tuple &ip, StreamFactory &factory, FinalizeFn fn ) { + return run_finalize_func( 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 + 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_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)... ) {} + + 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( *this ); + } + + private: + typedef tbb::internal::stored_pack 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 ::type > + struct wrap_to_async { + typedef T type; // Keep port_ref as it is + }; + + template + struct wrap_to_async { + typedef typename StreamFactory::template async_msg_type< typename tbb::internal::strip::type > type; + }; + + template + 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' + return new args_storage(storage, std::forward(args)...); + } + + void notify_new_device( device_type d ) { + my_args_storage->send( d ); + } + + template + 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 + 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( 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 + 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::type(std::forward(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 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 diff --git a/lib/3rdParty/tbb/include/tbb/internal/_flow_graph_tagged_buffer_impl.h b/lib/3rdParty/tbb/include/tbb/internal/_flow_graph_tagged_buffer_impl.h index c49e9c1..46755fe 100644 --- a/lib/3rdParty/tbb/include/tbb/internal/_flow_graph_tagged_buffer_impl.h +++ b/lib/3rdParty/tbb/include/tbb/internal/_flow_graph_tagged_buffer_impl.h @@ -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 diff --git a/lib/3rdParty/tbb/include/tbb/internal/_flow_graph_trace_impl.h b/lib/3rdParty/tbb/include/tbb/internal/_flow_graph_trace_impl.h index 24dd3a9..b798888 100644 --- a/lib/3rdParty/tbb/include/tbb/internal/_flow_graph_trace_impl.h +++ b/lib/3rdParty/tbb/include/tbb/internal/_flow_graph_trace_impl.h @@ -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 diff --git a/lib/3rdParty/tbb/include/tbb/internal/_flow_graph_types_impl.h b/lib/3rdParty/tbb/include/tbb/internal/_flow_graph_types_impl.h index cb18270..73b5f54 100644 --- a/lib/3rdParty/tbb/include/tbb/internal/_flow_graph_types_impl.h +++ b/lib/3rdParty/tbb/include/tbb/internal/_flow_graph_types_impl.h @@ -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 @@ -451,12 +451,12 @@ public: explicit Wrapper( const T& other ) : value_space(other) { } 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); (void) new(newSpace) Wrapper(value_space); guard.space = NULL; } - /*override*/~Wrapper() { } + ~Wrapper() { } }; // specialization for array objects @@ -519,11 +519,11 @@ public: 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 } - /*override*/~Wrapper() { + ~Wrapper() { // have to destroy explicitly in reverse order pointer_type vp = reinterpret_cast(&value_space); 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(); } template bool is_a(T const &t) { return t.template is_a(); } +enum op_stat { WAIT = 0, SUCCEEDED, FAILED }; + } // namespace internal #endif /* __TBB__flow_graph_types_impl_H */ diff --git a/lib/3rdParty/tbb/include/tbb/internal/_mutex_padding.h b/lib/3rdParty/tbb/include/tbb/internal/_mutex_padding.h index 9dc7a18..6c1d9b5 100644 --- a/lib/3rdParty/tbb/include/tbb/internal/_mutex_padding.h +++ b/lib/3rdParty/tbb/include/tbb/internal/_mutex_padding.h @@ -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 diff --git a/lib/3rdParty/tbb/include/tbb/internal/_range_iterator.h b/lib/3rdParty/tbb/include/tbb/internal/_range_iterator.h index 030f5bf..5ebc42e 100644 --- a/lib/3rdParty/tbb/include/tbb/internal/_range_iterator.h +++ b/lib/3rdParty/tbb/include/tbb/internal/_range_iterator.h @@ -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 diff --git a/lib/3rdParty/tbb/include/tbb/internal/_tbb_hash_compare_impl.h b/lib/3rdParty/tbb/include/tbb/internal/_tbb_hash_compare_impl.h index 748ec65..6381e2d 100644 --- a/lib/3rdParty/tbb/include/tbb/internal/_tbb_hash_compare_impl.h +++ b/lib/3rdParty/tbb/include/tbb/internal/_tbb_hash_compare_impl.h @@ -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. @@ -47,6 +47,7 @@ public: } bool operator()(const Key& key1, const Key& key2) const { + // TODO: get rid of the result invertion return (!my_key_compare_object(key1, key2)); } diff --git a/lib/3rdParty/tbb/include/tbb/internal/_tbb_strings.h b/lib/3rdParty/tbb/include/tbb/internal/_tbb_strings.h index f5469fb..1aa532f 100644 --- a/lib/3rdParty/tbb/include/tbb/internal/_tbb_strings.h +++ b/lib/3rdParty/tbb/include/tbb/internal/_tbb_strings.h @@ -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") diff --git a/lib/3rdParty/tbb/include/tbb/internal/_tbb_windef.h b/lib/3rdParty/tbb/include/tbb/internal/_tbb_windef.h index 6b80e0b..e798dee 100644 --- a/lib/3rdParty/tbb/include/tbb/internal/_tbb_windef.h +++ b/lib/3rdParty/tbb/include/tbb/internal/_tbb_windef.h @@ -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 diff --git a/lib/3rdParty/tbb/include/tbb/internal/_template_helpers.h b/lib/3rdParty/tbb/include/tbb/internal/_template_helpers.h index b55ebc6..1e0abbe 100644 --- a/lib/3rdParty/tbb/include/tbb/internal/_template_helpers.h +++ b/lib/3rdParty/tbb/include/tbb/internal/_template_helpers.h @@ -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 #define __TBB_template_helpers_H #include +#include namespace tbb { namespace internal { @@ -47,10 +48,10 @@ template struct strip { typedef T type; }; template struct strip { typedef T type; }; #endif //! Specialization for arrays converts to a corresponding pointer -template struct strip { typedef T* type; }; -template struct strip { typedef const T* type; }; -template struct strip { typedef volatile T* type; }; -template struct strip { typedef const volatile T* type; }; +template struct strip { typedef T* type; }; +template struct strip { typedef const T* type; }; +template struct strip { typedef volatile T* type; }; +template struct strip { typedef const volatile T* type; }; //! Detects whether two given types are the same template struct is_same_type { static const bool value = false; }; @@ -59,6 +60,11 @@ template struct is_same_type { static const bool value = template struct is_ref { static const bool value = false; }; template struct is_ref { 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 struct void_t { typedef void type; }; +#endif + #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 @@ -107,6 +113,13 @@ struct stored_pack : stored_pack template< typename Ret, typename F, typename Pack > friend Ret call_and_return( F&& f, Pack&& p ); protected: + template< typename Ret, typename F, typename... Preceding > + static Ret call( F&& f, pack_type& pack, Preceding&&... params ) { + return pack_remainder::template call( + std::forward(f), static_cast(pack), + std::forward(params)... , pack.leftmost_value + ); + } template< typename Ret, typename F, typename... Preceding > static Ret call( F&& f, const pack_type& pack, Preceding&&... params ) { return pack_remainder::template call( diff --git a/lib/3rdParty/tbb/include/tbb/internal/_x86_eliding_mutex_impl.h b/lib/3rdParty/tbb/include/tbb/internal/_x86_eliding_mutex_impl.h index 954248b..ef5f922 100644 --- a/lib/3rdParty/tbb/include/tbb/internal/_x86_eliding_mutex_impl.h +++ b/lib/3rdParty/tbb/include/tbb/internal/_x86_eliding_mutex_impl.h @@ -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 diff --git a/lib/3rdParty/tbb/include/tbb/internal/_x86_rtm_rw_mutex_impl.h b/lib/3rdParty/tbb/include/tbb/internal/_x86_rtm_rw_mutex_impl.h index 9274c9a..b08c233 100644 --- a/lib/3rdParty/tbb/include/tbb/internal/_x86_rtm_rw_mutex_impl.h +++ b/lib/3rdParty/tbb/include/tbb/internal/_x86_rtm_rw_mutex_impl.h @@ -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 diff --git a/lib/3rdParty/tbb/include/tbb/machine/gcc_armv7.h b/lib/3rdParty/tbb/include/tbb/machine/gcc_armv7.h index dcd7c8a..642c14f 100644 --- a/lib/3rdParty/tbb/include/tbb/machine/gcc_armv7.h +++ b/lib/3rdParty/tbb/include/tbb/machine/gcc_armv7.h @@ -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" "strexeq %0, %5, [%3]\n" : "=&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"); } while (res); @@ -116,7 +116,7 @@ static inline int64_t __TBB_machine_cmpswp8(volatile void *ptr, int64_t value, i "it eq\n" "strexdeq %0, %5, %H5, [%3]" : "=&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"); } while (res); @@ -139,7 +139,7 @@ static inline int32_t __TBB_machine_fetchadd4(volatile void* ptr, int32_t addend " cmp %1, #0\n" " bne 1b\n" : "=&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"); __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" " bne 1b" : "=&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"); diff --git a/lib/3rdParty/tbb/include/tbb/machine/gcc_generic.h b/lib/3rdParty/tbb/include/tbb/machine/gcc_generic.h index bd698a4..5fc2a90 100644 --- a/lib/3rdParty/tbb/include/tbb/machine/gcc_generic.h +++ b/lib/3rdParty/tbb/include/tbb/machine/gcc_generic.h @@ -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) @@ -27,7 +27,7 @@ #include #include -#define __TBB_WORDSIZE __SIZEOF_POINTER__ +#define __TBB_WORDSIZE __SIZEOF_POINTER__ #if __TBB_GCC_64BIT_ATOMIC_BUILTINS_BROKEN #define __TBB_64BIT_ATOMICS 0 diff --git a/lib/3rdParty/tbb/include/tbb/machine/gcc_ia32_common.h b/lib/3rdParty/tbb/include/tbb/machine/gcc_ia32_common.h index 965593f..f5efc37 100644 --- a/lib/3rdParty/tbb/include/tbb/machine/gcc_ia32_common.h +++ b/lib/3rdParty/tbb/include/tbb/machine/gcc_ia32_common.h @@ -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 #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 //platform-specific headers. //TODO: Check if use of gcc intrinsic gives a better chance for cross call optimizations diff --git a/lib/3rdParty/tbb/include/tbb/machine/gcc_itsx.h b/lib/3rdParty/tbb/include/tbb/machine/gcc_itsx.h index 1583379..caa3544 100644 --- a/lib/3rdParty/tbb/include/tbb/machine/gcc_itsx.h +++ b/lib/3rdParty/tbb/include/tbb/machine/gcc_itsx.h @@ -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) diff --git a/lib/3rdParty/tbb/include/tbb/machine/ibm_aix51.h b/lib/3rdParty/tbb/include/tbb/machine/ibm_aix51.h index 28dd0da..a905b4e 100644 --- a/lib/3rdParty/tbb/include/tbb/machine/ibm_aix51.h +++ b/lib/3rdParty/tbb/include/tbb/machine/ibm_aix51.h @@ -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 diff --git a/lib/3rdParty/tbb/include/tbb/machine/icc_generic.h b/lib/3rdParty/tbb/include/tbb/machine/icc_generic.h index 7dae6e7..0486300 100644 --- a/lib/3rdParty/tbb/include/tbb/machine/icc_generic.h +++ b/lib/3rdParty/tbb/include/tbb/machine/icc_generic.h @@ -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) diff --git a/lib/3rdParty/tbb/include/tbb/machine/linux_common.h b/lib/3rdParty/tbb/include/tbb/machine/linux_common.h index 2080813..4d2d355 100644 --- a/lib/3rdParty/tbb/include/tbb/machine/linux_common.h +++ b/lib/3rdParty/tbb/include/tbb/machine/linux_common.h @@ -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 diff --git a/lib/3rdParty/tbb/include/tbb/machine/linux_ia32.h b/lib/3rdParty/tbb/include/tbb/machine/linux_ia32.h index f644000..932d343 100644 --- a/lib/3rdParty/tbb/include/tbb/machine/linux_ia32.h +++ b/lib/3rdParty/tbb/include/tbb/machine/linux_ia32.h @@ -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) diff --git a/lib/3rdParty/tbb/include/tbb/machine/linux_ia64.h b/lib/3rdParty/tbb/include/tbb/machine/linux_ia64.h index 60e83b4..f477228 100644 --- a/lib/3rdParty/tbb/include/tbb/machine/linux_ia64.h +++ b/lib/3rdParty/tbb/include/tbb/machine/linux_ia64.h @@ -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) diff --git a/lib/3rdParty/tbb/include/tbb/machine/linux_intel64.h b/lib/3rdParty/tbb/include/tbb/machine/linux_intel64.h index cc538ab..02153c2 100644 --- a/lib/3rdParty/tbb/include/tbb/machine/linux_intel64.h +++ b/lib/3rdParty/tbb/include/tbb/machine/linux_intel64.h @@ -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) diff --git a/lib/3rdParty/tbb/include/tbb/machine/mac_ppc.h b/lib/3rdParty/tbb/include/tbb/machine/mac_ppc.h index 7f5474e..13f387b 100644 --- a/lib/3rdParty/tbb/include/tbb/machine/mac_ppc.h +++ b/lib/3rdParty/tbb/include/tbb/machine/mac_ppc.h @@ -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) diff --git a/lib/3rdParty/tbb/include/tbb/machine/macos_common.h b/lib/3rdParty/tbb/include/tbb/machine/macos_common.h index c2c86c3..119ad97 100644 --- a/lib/3rdParty/tbb/include/tbb/machine/macos_common.h +++ b/lib/3rdParty/tbb/include/tbb/machine/macos_common.h @@ -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) @@ -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) { - __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; while( !OSAtomicCompareAndSwap64Barrier(comparand, value, address) ){ #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) { - __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; while( !OSAtomicCompareAndSwap32Barrier(comparand, value, 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) { - __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; } 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; } diff --git a/lib/3rdParty/tbb/include/tbb/machine/mic_common.h b/lib/3rdParty/tbb/include/tbb/machine/mic_common.h index 606b345..8765d39 100644 --- a/lib/3rdParty/tbb/include/tbb/machine/mic_common.h +++ b/lib/3rdParty/tbb/include/tbb/machine/mic_common.h @@ -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 diff --git a/lib/3rdParty/tbb/include/tbb/machine/msvc_armv7.h b/lib/3rdParty/tbb/include/tbb/machine/msvc_armv7.h index cc1c1bf..40d2202 100644 --- a/lib/3rdParty/tbb/include/tbb/machine/msvc_armv7.h +++ b/lib/3rdParty/tbb/include/tbb/machine/msvc_armv7.h @@ -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) diff --git a/lib/3rdParty/tbb/include/tbb/machine/msvc_ia32_common.h b/lib/3rdParty/tbb/include/tbb/machine/msvc_ia32_common.h index 9caaa2b..8b4814b 100644 --- a/lib/3rdParty/tbb/include/tbb/machine/msvc_ia32_common.h +++ b/lib/3rdParty/tbb/include/tbb/machine/msvc_ia32_common.h @@ -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) diff --git a/lib/3rdParty/tbb/include/tbb/machine/sunos_sparc.h b/lib/3rdParty/tbb/include/tbb/machine/sunos_sparc.h index f28401f..9119f40 100644 --- a/lib/3rdParty/tbb/include/tbb/machine/sunos_sparc.h +++ b/lib/3rdParty/tbb/include/tbb/machine/sunos_sparc.h @@ -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. */ diff --git a/lib/3rdParty/tbb/include/tbb/machine/windows_api.h b/lib/3rdParty/tbb/include/tbb/machine/windows_api.h index bafa1d1..d362abc 100644 --- a/lib/3rdParty/tbb/include/tbb/machine/windows_api.h +++ b/lib/3rdParty/tbb/include/tbb/machine/windows_api.h @@ -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 @@ -23,18 +23,8 @@ #if _WIN32 || _WIN64 -#if _XBOX - -#define NONET -#define NOD3D -#include - -#else // Assume "usual" Windows - #include -#endif // _XBOX - #if _WIN32_WINNT < 0x0600 // The following Windows API function is declared explicitly; // otherwise it fails to compile by VS2005. diff --git a/lib/3rdParty/tbb/include/tbb/machine/windows_ia32.h b/lib/3rdParty/tbb/include/tbb/machine/windows_ia32.h index c118672..8db0d2b 100644 --- a/lib/3rdParty/tbb/include/tbb/machine/windows_ia32.h +++ b/lib/3rdParty/tbb/include/tbb/machine/windows_ia32.h @@ -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) diff --git a/lib/3rdParty/tbb/include/tbb/machine/windows_intel64.h b/lib/3rdParty/tbb/include/tbb/machine/windows_intel64.h index 3ddae49..86abd6a 100644 --- a/lib/3rdParty/tbb/include/tbb/machine/windows_intel64.h +++ b/lib/3rdParty/tbb/include/tbb/machine/windows_intel64.h @@ -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) diff --git a/lib/3rdParty/tbb/include/tbb/memory_pool.h b/lib/3rdParty/tbb/include/tbb/memory_pool.h index 4bfc818..b3bba39 100644 --- a/lib/3rdParty/tbb/include/tbb/memory_pool.h +++ b/lib/3rdParty/tbb/include/tbb/memory_pool.h @@ -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 @@ -107,7 +107,7 @@ public: typedef memory_pool_allocator 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) {} template memory_pool_allocator(const memory_pool_allocator& src) throw() : my_pool(src.my_pool) {} @@ -165,7 +165,7 @@ public: typedef memory_pool_allocator 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) {} template memory_pool_allocator(const memory_pool_allocator& src) throw() : my_pool(src.my_pool) {} @@ -196,7 +196,7 @@ class memory_pool : public internal::pool_base { public: //! construct pool with underlying allocator - memory_pool(const Alloc &src = Alloc()); + explicit memory_pool(const Alloc &src = Alloc()); //! destroy pool ~memory_pool() { destroy(); } // call the callbacks first and destroy my_alloc latter diff --git a/lib/3rdParty/tbb/include/tbb/mutex.h b/lib/3rdParty/tbb/include/tbb/mutex.h index 358809e..e40b4cd 100644 --- a/lib/3rdParty/tbb/include/tbb/mutex.h +++ b/lib/3rdParty/tbb/include/tbb/mutex.h @@ -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 @@ -34,9 +34,8 @@ namespace tbb { -//! Wrapper around the platform's native reader-writer lock. -/** For testing purposes only. - @ingroup synchronization */ +//! Wrapper around the platform's native lock. +/** @ingroup synchronization */ class mutex : internal::mutex_copy_deprecated_and_disabled { public: //! Construct unacquired mutex. diff --git a/lib/3rdParty/tbb/include/tbb/null_mutex.h b/lib/3rdParty/tbb/include/tbb/null_mutex.h index ca93ae3..85c660e 100644 --- a/lib/3rdParty/tbb/include/tbb/null_mutex.h +++ b/lib/3rdParty/tbb/include/tbb/null_mutex.h @@ -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 diff --git a/lib/3rdParty/tbb/include/tbb/null_rw_mutex.h b/lib/3rdParty/tbb/include/tbb/null_rw_mutex.h index 7ec6b46..fa0c803 100644 --- a/lib/3rdParty/tbb/include/tbb/null_rw_mutex.h +++ b/lib/3rdParty/tbb/include/tbb/null_rw_mutex.h @@ -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 diff --git a/lib/3rdParty/tbb/include/tbb/parallel_do.h b/lib/3rdParty/tbb/include/tbb/parallel_do.h index 5c6e5d7..1527568 100644 --- a/lib/3rdParty/tbb/include/tbb/parallel_do.h +++ b/lib/3rdParty/tbb/include/tbb/parallel_do.h @@ -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 @@ -28,31 +28,37 @@ #include namespace tbb { - +namespace interface9 { //! @cond INTERNAL namespace internal { template class parallel_do_feeder_impl; - template class do_group_task; } // namespace internal //! @endcond //! Class the user supplied algorithm body uses to add new tasks /** \param Item Work item type **/ -template -class parallel_do_feeder: internal::no_copy -{ - parallel_do_feeder() {} - virtual ~parallel_do_feeder () {} - virtual void internal_add( const Item& item ) = 0; - template friend class internal::parallel_do_feeder_impl; -public: - //! Add a work item to a running parallel_do. - // TODO: add an overload for r-value reference - void add( const Item& item ) {internal_add(item);} -}; + template + class parallel_do_feeder: ::tbb::internal::no_copy + { + parallel_do_feeder() {} + virtual ~parallel_do_feeder () {} + 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 friend class internal::parallel_do_feeder_impl; + public: + //! Add a work item to a running parallel_do. + void add( const Item& item ) {internal_add_copy(item);} +#if __TBB_CPP11_RVALUE_REF_PRESENT + void add( Item&& item ) {internal_add_move(std::move(item));} +#endif + }; //! @cond INTERNAL namespace internal { + template class do_group_task; + //! For internal use only. /** Selects one of the two possible forms of function call member operator. @ingroup algorithms **/ @@ -61,19 +67,26 @@ namespace internal { { typedef parallel_do_feeder Feeder; template - 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(arg1)); + } + template + static void internal_call( const Body& obj, __TBB_FORWARDING_REF(A1) arg1, A2& arg2, void (Body::*)(CvItem, parallel_do_feeder&) const ) { + obj(tbb::internal::forward(arg1), arg2); + } + template + static void internal_call( const Body& obj, __TBB_FORWARDING_REF(A1) arg1, A2&, void (Body::*)(CvItem&) const ) { obj(arg1); } template - static void internal_call( const Body& obj, A1& arg1, A2& arg2, void (Body::*)(CvItem, parallel_do_feeder&) const ) { + static void internal_call( const Body& obj, __TBB_FORWARDING_REF(A1) arg1, A2& arg2, void (Body::*)(CvItem&, parallel_do_feeder&) const ) { obj(arg1, arg2); } - public: - template - static void call( const Body& obj, A1& arg1, A2& arg2 ) + template + 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(arg1), arg2, &Body::operator() ); } }; @@ -92,11 +105,15 @@ namespace internal { my_value(value), my_feeder(feeder) {} - /*override*/ - task* execute() +#if __TBB_CPP11_RVALUE_REF_PRESENT + 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::call(*my_feeder.my_body, my_value, my_feeder); + parallel_do_operator_selector::call(*my_feeder.my_body, tbb::internal::move(my_value), my_feeder); return NULL; } @@ -115,8 +132,7 @@ namespace internal { my_iter(iter), my_feeder(feeder) {} - /*override*/ - task* execute() + task* execute() __TBB_override { parallel_do_operator_selector::call(*my_feeder.my_body, *my_iter, my_feeder); return NULL; @@ -133,15 +149,37 @@ namespace internal { template class parallel_do_feeder_impl : public parallel_do_feeder { - /*override*/ - void internal_add( const Item& item ) +#if __TBB_CPP11_RVALUE_REF_PRESENT + //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 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::type(), item); +#else + internal_add_copy_impl(std::true_type(), item); +#endif + } + void internal_add_move( Item&& item ) __TBB_override { typedef do_iteration_task iteration_type; - - iteration_type& t = *new (task::allocate_additional_child_of(*my_barrier)) iteration_type(item, *this); - - t.spawn( t ); + iteration_type& t = *new (task::allocate_additional_child_of(*my_barrier)) iteration_type(std::move(item), *this); + task::spawn(t); } +#else /* ! __TBB_CPP11_RVALUE_REF_PRESENT */ + void internal_add_copy(const Item& item) __TBB_override { + typedef do_iteration_task 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: const Body* my_body; empty_task* my_barrier; @@ -186,7 +224,7 @@ namespace internal { : my_feeder(feeder), my_first(first), my_size(size) {} - /*override*/ task* execute() + task* execute() __TBB_override { typedef do_iteration_task_iter iteration_type; __TBB_ASSERT( my_size>0, NULL ); @@ -223,15 +261,20 @@ namespace internal { : my_feeder(feeder), my_size(0) {} - /*override*/ task* execute() + task* execute() __TBB_override { - typedef do_iteration_task_iter iteration_type; +#if __TBB_CPP11_RVALUE_REF_PRESENT + typedef std::move_iterator Item_iterator; +#else + typedef Item* Item_iterator; +#endif + typedef do_iteration_task_iter iteration_type; __TBB_ASSERT( my_size>0, NULL ); task_list list; task* t; size_t k=0; 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; list.push_back(*t); } @@ -277,7 +320,7 @@ namespace internal { templates. Besides template functions would always fall back to the least efficient variant (the one for input iterators) in case of iterators having custom tags derived from basic ones. */ - /*override*/ task* execute() + task* execute() __TBB_override { typedef typename std::iterator_traits::iterator_category iterator_tag; 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); size_t k=0; 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); ++my_first; 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 #if __TBB_TASK_GROUP_CONTEXT , task_group_context& context -#endif // __TBB_TASK_GROUP_CONTEXT +#endif ) { - run_parallel_do::type>( first, last, body + run_parallel_do::type>( first, last, body #if __TBB_TASK_GROUP_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 #if __TBB_TASK_GROUP_CONTEXT , task_group_context& context -#endif // __TBB_TASK_GROUP_CONTEXT +#endif ) { - run_parallel_do::type>( first, last, body + run_parallel_do::type>( first, last, body #if __TBB_TASK_GROUP_CONTEXT , context -#endif // __TBB_TASK_GROUP_CONTEXT +#endif ); } } // namespace internal +} // namespace interface9 //! @endcond - /** \page parallel_do_body_req Requirements on parallel_do body Class \c Body implementing the concept of parallel_do body must define: - \code @@ -458,11 +501,11 @@ void parallel_do( Iterator first, Iterator last, const Body& body ) return; #if __TBB_TASK_GROUP_CONTEXT task_group_context context; -#endif // __TBB_TASK_GROUP_CONTEXT - internal::select_parallel_do( first, last, body, &Body::operator() +#endif + interface9::internal::select_parallel_do( first, last, body, &Body::operator() #if __TBB_TASK_GROUP_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 ) return; - internal::select_parallel_do( first, last, body, &Body::operator(), context ); + interface9::internal::select_parallel_do( first, last, body, &Body::operator(), context ); } template @@ -501,6 +544,8 @@ void parallel_do(const Range& rng, const Body& body, task_group_context& context //@} +using interface9::parallel_do_feeder; + } // namespace #endif /* __TBB_parallel_do_H */ diff --git a/lib/3rdParty/tbb/include/tbb/parallel_for.h b/lib/3rdParty/tbb/include/tbb/parallel_for.h index bbba853..2cab658 100644 --- a/lib/3rdParty/tbb/include/tbb/parallel_for.h +++ b/lib/3rdParty/tbb/include/tbb/parallel_for.h @@ -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 @@ -43,10 +43,10 @@ namespace internal { Range my_range; const Body my_body; typename Partitioner::task_partition_type my_partition; - /*override*/ task* execute(); + task* execute() __TBB_override; //! 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 ); } @@ -200,14 +200,12 @@ void parallel_for( const Range& range, const Body& body, const auto_partitioner& internal::start_for::run(range,body,partitioner); } -#if TBB_PREVIEW_STATIC_PARTITIONER //! Parallel iteration over range with static_partitioner. /** @ingroup algorithms **/ template void parallel_for( const Range& range, const Body& body, const static_partitioner& partitioner ) { internal::start_for::run(range,body,partitioner); } -#endif //! Parallel iteration over range with affinity_partitioner. /** @ingroup algorithms **/ @@ -238,14 +236,12 @@ void parallel_for( const Range& range, const Body& body, const auto_partitioner& internal::start_for::run(range, body, partitioner, context); } -#if TBB_PREVIEW_STATIC_PARTITIONER //! Parallel iteration over range with static_partitioner and user-supplied context. /** @ingroup algorithms **/ template void parallel_for( const Range& range, const Body& body, const static_partitioner& partitioner, task_group_context& context ) { internal::start_for::run(range, body, partitioner, context); } -#endif //! Parallel iteration over range with affinity_partitioner and user-supplied context. /** @ingroup algorithms **/ @@ -288,13 +284,11 @@ template void parallel_for(Index first, Index last, Index step, const Function& f, const auto_partitioner& partitioner) { parallel_for_impl(first, last, step, f, partitioner); } -#if TBB_PREVIEW_STATIC_PARTITIONER //! Parallel iteration over a range of integers with a step provided and static partitioner template void parallel_for(Index first, Index last, Index step, const Function& f, const static_partitioner& partitioner) { parallel_for_impl(first, last, step, f, partitioner); } -#endif //! Parallel iteration over a range of integers with a step provided and affinity partitioner template void parallel_for(Index first, Index last, Index step, const Function& f, affinity_partitioner& partitioner) { @@ -316,13 +310,11 @@ template void parallel_for(Index first, Index last, const Function& f, const auto_partitioner& partitioner) { parallel_for_impl(first, last, static_cast(1), f, partitioner); } -#if TBB_PREVIEW_STATIC_PARTITIONER //! Parallel iteration over a range of integers with a default step value and static partitioner template void parallel_for(Index first, Index last, const Function& f, const static_partitioner& partitioner) { parallel_for_impl(first, last, static_cast(1), f, partitioner); } -#endif //! Parallel iteration over a range of integers with a default step value and affinity partitioner template 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) { parallel_for_impl(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 template void parallel_for(Index first, Index last, Index step, const Function& f, const static_partitioner& partitioner, tbb::task_group_context &context) { parallel_for_impl(first, last, step, f, partitioner, context); } -#endif //! Parallel iteration over a range of integers with explicit step, task group context, and affinity partitioner template 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) { parallel_for_impl(first, last, static_cast(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 template void parallel_for(Index first, Index last, const Function& f, const static_partitioner& partitioner, tbb::task_group_context &context) { parallel_for_impl(first, last, static_cast(1), f, partitioner, context); } -#endif //! Parallel iteration over a range of integers with a default step value, explicit task group context, and affinity_partitioner template void parallel_for(Index first, Index last, const Function& f, affinity_partitioner& partitioner, tbb::task_group_context &context) { diff --git a/lib/3rdParty/tbb/include/tbb/parallel_for_each.h b/lib/3rdParty/tbb/include/tbb/parallel_for_each.h index 46f1e34..6c2ec9f 100644 --- a/lib/3rdParty/tbb/include/tbb/parallel_for_each.h +++ b/lib/3rdParty/tbb/include/tbb/parallel_for_each.h @@ -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 diff --git a/lib/3rdParty/tbb/include/tbb/parallel_invoke.h b/lib/3rdParty/tbb/include/tbb/parallel_invoke.h index 0c193bc..0dd7590 100644 --- a/lib/3rdParty/tbb/include/tbb/parallel_invoke.h +++ b/lib/3rdParty/tbb/include/tbb/parallel_invoke.h @@ -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 @@ -24,7 +24,7 @@ #include "task.h" #if __TBB_VARIADIC_PARALLEL_INVOKE - #include + #include // std::forward #endif namespace tbb { @@ -43,8 +43,7 @@ namespace internal { function_invoker(const function& _function) : my_function(_function) {} private: const function &my_function; - /*override*/ - task* execute() + task* execute() __TBB_override { my_function(); return NULL; @@ -60,7 +59,7 @@ namespace internal { const function3& my_func3; bool is_recycled; - task* execute (){ + task* execute () __TBB_override { if(is_recycled){ return NULL; }else{ diff --git a/lib/3rdParty/tbb/include/tbb/parallel_reduce.h b/lib/3rdParty/tbb/include/tbb/parallel_reduce.h index d387c44..0596ae0 100644 --- a/lib/3rdParty/tbb/include/tbb/parallel_reduce.h +++ b/lib/3rdParty/tbb/include/tbb/parallel_reduce.h @@ -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 @@ -62,7 +62,7 @@ namespace internal { if( has_right_zombie ) zombie_space.begin()->~Body(); } - task* execute() { + task* execute() __TBB_override { if( has_right_zombie ) { // Right child was stolen. Body* s = zombie_space.begin(); @@ -89,9 +89,9 @@ namespace internal { Range my_range; typename Partitioner::task_partition_type my_partition; reduction_context my_context; - /*override*/ task* execute(); + task* execute() __TBB_override; //! 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 ); } template @@ -209,7 +209,7 @@ public: my_right_body( body, split() ) { } - task* execute() { + task* execute() __TBB_override { my_left_body.join( my_right_body ); return NULL; } @@ -224,7 +224,7 @@ public: typedef finish_deterministic_reduce finish_type; Body &my_body; Range my_range; - /*override*/ task* execute(); + task* execute() __TBB_override; //! Constructor used for root task 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::run( range, body, partitioner ); } -#if TBB_PREVIEW_STATIC_PARTITIONER //! Parallel iteration with reduction and static_partitioner /** @ingroup algorithms **/ template void parallel_reduce( const Range& range, Body& body, const static_partitioner& partitioner ) { internal::start_reduce::run( range, body, partitioner ); } -#endif //! Parallel iteration with reduction and affinity_partitioner /** @ingroup algorithms **/ @@ -405,14 +403,12 @@ void parallel_reduce( const Range& range, Body& body, const auto_partitioner& pa internal::start_reduce::run( range, body, partitioner, context ); } -#if TBB_PREVIEW_STATIC_PARTITIONER //! Parallel iteration with reduction, static_partitioner and user-supplied context /** @ingroup algorithms **/ template void parallel_reduce( const Range& range, Body& body, const static_partitioner& partitioner, task_group_context& context ) { internal::start_reduce::run( range, body, partitioner, context ); } -#endif //! Parallel iteration with reduction, affinity_partitioner and user-supplied context /** @ingroup algorithms **/ @@ -457,7 +453,6 @@ Value parallel_reduce( const Range& range, const Value& identity, const RealBody return body.result(); } -#if TBB_PREVIEW_STATIC_PARTITIONER //! Parallel iteration with reduction and static_partitioner /** @ingroup algorithms **/ template @@ -468,7 +463,6 @@ Value parallel_reduce( const Range& range, const Value& identity, const RealBody ::run( range, body, partitioner ); return body.result(); } -#endif //! Parallel iteration with reduction and affinity_partitioner /** @ingroup algorithms **/ @@ -504,7 +498,6 @@ Value parallel_reduce( const Range& range, const Value& identity, const RealBody return body.result(); } -#if TBB_PREVIEW_STATIC_PARTITIONER //! Parallel iteration with reduction, static_partitioner and user-supplied context /** @ingroup algorithms **/ template @@ -515,7 +508,6 @@ Value parallel_reduce( const Range& range, const Value& identity, const RealBody ::run( range, body, partitioner, context ); return body.result(); } -#endif //! Parallel iteration with reduction, affinity_partitioner and user-supplied context /** @ingroup algorithms **/ diff --git a/lib/3rdParty/tbb/include/tbb/parallel_scan.h b/lib/3rdParty/tbb/include/tbb/parallel_scan.h index 00c9b4c..faf6b31 100644 --- a/lib/3rdParty/tbb/include/tbb/parallel_scan.h +++ b/lib/3rdParty/tbb/include/tbb/parallel_scan.h @@ -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 @@ -67,7 +67,7 @@ namespace internal { my_stuff_last = stuff_last_; } private: - /*override*/ task* execute() { + task* execute() __TBB_override { my_body( *my_range.begin(), final_scan_tag() ); if( my_stuff_last ) my_stuff_last->assign(my_body); @@ -91,6 +91,7 @@ namespace internal { bool my_left_is_final; Range my_range; sum_node( const Range range_, bool left_is_final_ ) : + my_stuff_last(NULL), my_left_sum(NULL), my_left(NULL), my_right(NULL), @@ -113,7 +114,7 @@ namespace internal { return n; } } - /*override*/ task* execute() { + task* execute() __TBB_override { if( my_body ) { if( my_incoming ) my_left_sum->my_body.reverse_join( my_incoming->my_body ); @@ -149,7 +150,7 @@ namespace internal { final_sum_type* my_right_zombie; 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 ); if( my_result.my_left ) my_result.my_left_is_final = false; @@ -194,7 +195,7 @@ namespace internal { bool my_is_right_child; Range my_range; typename Partitioner::partition_type my_partition; - /*override*/ task* execute(); + task* execute() __TBB_override ; public: start_scan( sum_node_type*& return_slot_, start_scan& parent_, sum_node_type* parent_sum_ ) : my_body(parent_.my_body), @@ -233,6 +234,7 @@ namespace internal { range_, *temp_body, partitioner_ ); + temp_body->my_body.reverse_join(body_); task::spawn_root_and_wait( pass1 ); if( root ) { root->my_body = temp_body; diff --git a/lib/3rdParty/tbb/include/tbb/parallel_sort.h b/lib/3rdParty/tbb/include/tbb/parallel_sort.h index a642969..07d3907 100644 --- a/lib/3rdParty/tbb/include/tbb/parallel_sort.h +++ b/lib/3rdParty/tbb/include/tbb/parallel_sort.h @@ -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 diff --git a/lib/3rdParty/tbb/include/tbb/parallel_while.h b/lib/3rdParty/tbb/include/tbb/parallel_while.h index 1f9ff37..2f37a41 100644 --- a/lib/3rdParty/tbb/include/tbb/parallel_while.h +++ b/lib/3rdParty/tbb/include/tbb/parallel_while.h @@ -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 @@ -41,7 +41,7 @@ namespace internal { class while_iteration_task: public task { const Body& my_body; typename Body::argument_type my_value; - /*override*/ task* execute() { + task* execute() __TBB_override { my_body(my_value); return NULL; } @@ -62,7 +62,7 @@ namespace internal { size_t size; typename Body::argument_type my_arg[max_arg_size]; while_group_task( const Body& body ) : my_body(body), size(0) {} - /*override*/ task* execute() { + task* execute() __TBB_override { typedef while_iteration_task iteration_type; __TBB_ASSERT( size>0, NULL ); task_list list; @@ -89,7 +89,7 @@ namespace internal { Stream& my_stream; const Body& my_body; empty_task& my_barrier; - /*override*/ task* execute() { + task* execute() __TBB_override { typedef while_group_task block_type; block_type& t = *new( allocate_additional_child_of(my_barrier) ) block_type(my_body); size_t k=0; diff --git a/lib/3rdParty/tbb/include/tbb/partitioner.h b/lib/3rdParty/tbb/include/tbb/partitioner.h index 6321933..96a0b75 100644 --- a/lib/3rdParty/tbb/include/tbb/partitioner.h +++ b/lib/3rdParty/tbb/include/tbb/partitioner.h @@ -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 @@ -35,7 +35,7 @@ #endif #ifndef __TBB_DEMAND_DEPTH_ADD // when imbalance is found range splits this value times more -#define __TBB_DEMAND_DEPTH_ADD 2 +#define __TBB_DEMAND_DEPTH_ADD 1 #endif #ifndef __TBB_STATIC_THRESHOLD // necessary number of clocks for the work to be distributed among all tasks @@ -64,9 +64,7 @@ namespace tbb { class auto_partitioner; class simple_partitioner; -#if TBB_PREVIEW_STATIC_PARTITIONER class static_partitioner; -#endif class affinity_partitioner; namespace interface9 { @@ -130,7 +128,7 @@ class flag_task: public task { public: tbb::atomic my_child_stolen; flag_task() { my_child_stolen = false; } - task* execute() { return NULL; } + task* execute() __TBB_override { return NULL; } static void mark_task_stolen(task &t) { tbb::atomic &flag = static_cast(t.parent())->my_child_stolen; #if TBB_USE_THREADING_TOOLS @@ -519,22 +517,16 @@ public: } }; -#if TBB_PREVIEW_STATIC_PARTITIONER -#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 > { +class static_partition_type : public unbalancing_partition_type > { public: typedef proportional_split split_type; static_partition_type( const static_partitioner& ) - : __TBB_STATIC_PARTITIONER_BASE_TYPE >() {} + : unbalancing_partition_type >() {} static_partition_type( static_partition_type& p, split ) - : __TBB_STATIC_PARTITIONER_BASE_TYPE >(p, split()) {} + : unbalancing_partition_type >(p, split()) {} static_partition_type( static_partition_type& p, const proportional_split& split_obj ) - : __TBB_STATIC_PARTITIONER_BASE_TYPE >(p, split_obj) {} + : unbalancing_partition_type >(p, split_obj) {} }; -#undef __TBB_STATIC_PARTITIONER_BASE_TYPE -#endif class affinity_partition_type : public balancing_partition_type > { 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; }; -#if TBB_PREVIEW_STATIC_PARTITIONER //! A static partitioner class static_partitioner { public: @@ -659,7 +650,6 @@ private: // TODO: consider to make split_type public typedef interface9::internal::static_partition_type::split_type split_type; }; -#endif //! An affinity partitioner class affinity_partitioner: internal::affinity_partitioner_base_v3 { diff --git a/lib/3rdParty/tbb/include/tbb/pipeline.h b/lib/3rdParty/tbb/include/tbb/pipeline.h index a602666..20a8ec9 100644 --- a/lib/3rdParty/tbb/include/tbb/pipeline.h +++ b/lib/3rdParty/tbb/include/tbb/pipeline.h @@ -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 @@ -103,7 +103,7 @@ public: serial = serial_in_order }; protected: - filter( bool is_serial_ ) : + explicit filter( bool is_serial_ ) : next_filter_in_pipeline(not_in_pipeline()), my_input_buffer(NULL), my_filter_mode(static_cast((is_serial_ ? serial : parallel) | exact_exception_propagation)), @@ -112,7 +112,7 @@ protected: next_segment(NULL) {} - filter( mode filter_mode ) : + explicit filter( mode filter_mode ) : next_filter_in_pipeline(not_in_pipeline()), my_input_buffer(NULL), my_filter_mode(static_cast(filter_mode | exact_exception_propagation)), @@ -205,7 +205,7 @@ public: end_of_stream }; protected: - thread_bound_filter(mode filter_mode): + explicit thread_bound_filter(mode filter_mode): filter(static_cast(filter_mode | filter::filter_is_bound)) { __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::value > u_helper; 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); u_pointer output_u = u_helper::create_token(my_body(t_helper::token(temp_input))); t_helper::destroy_token(temp_input); 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_helper::destroy_token(temp_input); } @@ -435,7 +435,7 @@ class concrete_filter: public filter { typedef token_helper::value > u_helper; typedef typename u_helper::pointer u_pointer; - /*override*/void* operator()(void*) { + void* operator()(void*) __TBB_override { flow_control control; u_pointer output_u = u_helper::create_token(my_body(control)); if(control.is_pipeline_stopped) { @@ -459,13 +459,13 @@ class concrete_filter: public filter { typedef token_helper::value > t_helper; 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); my_body(t_helper::token(temp_input)); t_helper::destroy_token(temp_input); 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_helper::destroy_token(temp_input); } @@ -479,7 +479,7 @@ class concrete_filter: public filter { const Body& my_body; /** Override privately because it is always called virtually */ - /*override*/ void* operator()(void*) { + void* operator()(void*) __TBB_override { flow_control control; my_body(control); void* output = control.is_pipeline_stopped ? NULL : (void*)(intptr_t)-1; @@ -537,7 +537,7 @@ template class filter_node_leaf: public filter_node { const tbb::filter::mode mode; const Body body; - /*override*/void add_to( pipeline& p ) { + void add_to( pipeline& p ) __TBB_override { concrete_filter* f = new concrete_filter(mode,body); 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 filter_node& left; filter_node& right; - /*override*/~filter_node_join() { + ~filter_node_join() { left.remove_ref(); right.remove_ref(); } - /*override*/void add_to( pipeline& p ) { + void add_to( pipeline& p ) __TBB_override { left.add_to(p); right.add_to(p); } diff --git a/lib/3rdParty/tbb/include/tbb/queuing_mutex.h b/lib/3rdParty/tbb/include/tbb/queuing_mutex.h index 2de1a72..0fe4b3e 100644 --- a/lib/3rdParty/tbb/include/tbb/queuing_mutex.h +++ b/lib/3rdParty/tbb/include/tbb/queuing_mutex.h @@ -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 diff --git a/lib/3rdParty/tbb/include/tbb/queuing_rw_mutex.h b/lib/3rdParty/tbb/include/tbb/queuing_rw_mutex.h index 9c15fd8..e0224ed 100644 --- a/lib/3rdParty/tbb/include/tbb/queuing_rw_mutex.h +++ b/lib/3rdParty/tbb/include/tbb/queuing_rw_mutex.h @@ -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 diff --git a/lib/3rdParty/tbb/include/tbb/reader_writer_lock.h b/lib/3rdParty/tbb/include/tbb/reader_writer_lock.h index 2925b05..353beec 100644 --- a/lib/3rdParty/tbb/include/tbb/reader_writer_lock.h +++ b/lib/3rdParty/tbb/include/tbb/reader_writer_lock.h @@ -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 diff --git a/lib/3rdParty/tbb/include/tbb/recursive_mutex.h b/lib/3rdParty/tbb/include/tbb/recursive_mutex.h index f8c345c..5a23c09 100644 --- a/lib/3rdParty/tbb/include/tbb/recursive_mutex.h +++ b/lib/3rdParty/tbb/include/tbb/recursive_mutex.h @@ -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 diff --git a/lib/3rdParty/tbb/include/tbb/runtime_loader.h b/lib/3rdParty/tbb/include/tbb/runtime_loader.h index a89faa8..df28464 100644 --- a/lib/3rdParty/tbb/include/tbb/runtime_loader.h +++ b/lib/3rdParty/tbb/include/tbb/runtime_loader.h @@ -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_runtime_loader_H diff --git a/lib/3rdParty/tbb/include/tbb/scalable_allocator.h b/lib/3rdParty/tbb/include/tbb/scalable_allocator.h index 26853b4..c2a8149 100644 --- a/lib/3rdParty/tbb/include/tbb/scalable_allocator.h +++ b/lib/3rdParty/tbb/include/tbb/scalable_allocator.h @@ -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_scalable_allocator_H @@ -282,18 +282,18 @@ public: template void construct(U *p, Args&&... args) { ::new((void *)p) U(std::forward(args)...); } -#else // __TBB_ALLOCATOR_CONSTRUCT_VARIADIC +#else /* __TBB_ALLOCATOR_CONSTRUCT_VARIADIC */ #if __TBB_CPP11_RVALUE_REF_PRESENT void construct( pointer p, value_type&& value ) { ::new((void*)(p)) value_type( std::move( value ) ); } #endif void construct( pointer p, const value_type& value ) {::new((void*)(p)) value_type(value);} -#endif // __TBB_ALLOCATOR_CONSTRUCT_VARIADIC +#endif /* __TBB_ALLOCATOR_CONSTRUCT_VARIADIC */ void destroy( pointer p ) {p->~value_type();} }; #if _MSC_VER && !defined(__INTEL_COMPILER) #pragma warning (pop) -#endif // warning 4100 is back +#endif /* warning 4100 is back */ //! Analogous to std::allocator, as defined in ISO C++ Standard, Section 20.4.1 /** @ingroup memory_allocation */ @@ -336,6 +336,6 @@ inline bool operator!=( const scalable_allocator&, const scalable_allocator class delegated_function : public delegate_base { F &my_func; - /*override*/ void operator()() const { + void operator()() const __TBB_override { my_func(); } public: @@ -105,12 +109,17 @@ protected: void __TBB_EXPORTED_METHOD internal_execute( delegate_base& ) const; void __TBB_EXPORTED_METHOD internal_wait() const; static int __TBB_EXPORTED_FUNC internal_current_slot(); + static int __TBB_EXPORTED_FUNC internal_max_concurrency( const task_arena * ); public: //! Typedef for number of threads that is automatic. - static const int automatic = -1; // any value < 1 means 'automatic' + static const int automatic = -1; + static const int not_initialized = -2; }; +#if __TBB_TASK_ISOLATION +void __TBB_EXPORTED_FUNC isolate_within_arena( delegate_base& d, intptr_t reserved = 0 ); +#endif /* __TBB_TASK_ISOLATION */ } // namespace internal //! @endcond @@ -121,6 +130,7 @@ public: */ class task_arena : public internal::task_arena_base { friend class tbb::internal::task_scheduler_observer_v3; + friend int tbb::this_task_arena::max_concurrency(); bool my_initialized; void mark_initialized() { __TBB_ASSERT( my_arena, "task_arena initialization is incomplete" ); @@ -143,8 +153,8 @@ public: * @arg reserved_for_masters specifies number of slots to be used by master threads only. * Value of 1 is default and reflects behavior of implicit arenas. **/ - task_arena(int max_concurrency = automatic, unsigned reserved_for_masters = 1) - : task_arena_base(max_concurrency, reserved_for_masters) + task_arena(int max_concurrency_ = automatic, unsigned reserved_for_masters = 1) + : task_arena_base(max_concurrency_, reserved_for_masters) , my_initialized(false) {} @@ -158,7 +168,7 @@ public: struct attach {}; //! Creates an instance of task_arena attached to the current arena of the thread - task_arena( attach ) + explicit task_arena( attach ) : task_arena_base(automatic, 1) // use default settings if attach fails , my_initialized(false) { @@ -175,11 +185,11 @@ public: } //! Overrides concurrency level and forces initialization of internal representation - inline void initialize(int max_concurrency, unsigned reserved_for_masters = 1) { + inline void initialize(int max_concurrency_, unsigned reserved_for_masters = 1) { // TODO: decide if this call must be thread-safe __TBB_ASSERT( !my_arena, "Impossible to modify settings of an already initialized task_arena"); if( !my_initialized ) { - my_max_concurrency = max_concurrency; + my_max_concurrency = max_concurrency_; my_master_slots = reserved_for_masters; initialize(); } @@ -273,17 +283,51 @@ public: #endif //__TBB_EXTRA_DEBUG //! Returns the index, aka slot number, of the calling thread in its current arena + //! This method is deprecated and replaced with this_task_arena::current_thread_index() inline static int current_thread_index() { return internal_current_slot(); } + + //! Returns the maximal number of threads that can work inside the arena + inline int max_concurrency() const { + // Handle special cases inside the library + return (my_max_concurrency>1) ? my_max_concurrency : internal_max_concurrency(this); + } }; +#if __TBB_TASK_ISOLATION +namespace this_task_arena { + template + void isolate( const F& f ) { + internal::delegated_function d(f); + internal::isolate_within_arena( d ); + } +} +#endif /* __TBB_TASK_ISOLATION */ + } // namespace interfaceX using interface7::task_arena; +#if __TBB_TASK_ISOLATION +namespace this_task_arena { + using namespace interface7::this_task_arena; +} +#endif /* __TBB_TASK_ISOLATION */ + +namespace this_task_arena { + //! Returns the index, aka slot number, of the calling thread in its current arena + inline int current_thread_index() { + int idx = tbb::task_arena::current_thread_index(); + return idx == -1 ? tbb::task_arena::not_initialized : idx; + } + + //! Returns the maximal number of threads that can work inside the arena + inline int max_concurrency() { + return tbb::task_arena::internal_max_concurrency(NULL); + } + +} // namespace this_task_arena } // namespace tbb -#endif /* __TBB_TASK_ARENA */ - #endif /* __TBB_task_arena_H */ diff --git a/lib/3rdParty/tbb/include/tbb/task_group.h b/lib/3rdParty/tbb/include/tbb/task_group.h index 54f38ac..bf6922b 100644 --- a/lib/3rdParty/tbb/include/tbb/task_group.h +++ b/lib/3rdParty/tbb/include/tbb/task_group.h @@ -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_task_group_H @@ -69,7 +69,7 @@ namespace internal { template class task_handle_task : public task { task_handle& my_handle; - /*override*/ task* execute() { + task* execute() __TBB_override { my_handle(); return NULL; } diff --git a/lib/3rdParty/tbb/include/tbb/task_scheduler_init.h b/lib/3rdParty/tbb/include/tbb/task_scheduler_init.h index d4f91f3..928e7a4 100644 --- a/lib/3rdParty/tbb/include/tbb/task_scheduler_init.h +++ b/lib/3rdParty/tbb/include/tbb/task_scheduler_init.h @@ -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_task_scheduler_init_H @@ -23,6 +23,9 @@ #include "tbb_stddef.h" #include "limits.h" +#if __TBB_SUPPORTS_WORKERS_WAITING_IN_TERMINATE +#include // nothrow_t +#endif namespace tbb { @@ -56,14 +59,14 @@ class task_scheduler_init: internal::no_copy { propagation_mode_captured = 2u, propagation_mode_mask = propagation_mode_exact | propagation_mode_captured }; -#if __TBB_SUPPORTS_WORKERS_WAITING_IN_TERMINATE - enum { - wait_workers_in_terminate_flag = 128u - }; -#endif /** NULL if not currently initialized. */ internal::scheduler* my_scheduler; + + bool internal_terminate( bool blocking ); +#if __TBB_SUPPORTS_WORKERS_WAITING_IN_TERMINATE + bool __TBB_EXPORTED_METHOD internal_blocking_terminate( bool throwing ); +#endif public: //! Typedef for number of threads that is automatic. @@ -93,12 +96,21 @@ public: //! Inverse of method initialize. void __TBB_EXPORTED_METHOD terminate(); - //! Shorthand for default constructor followed by call to initialize(number_of_threads). #if __TBB_SUPPORTS_WORKERS_WAITING_IN_TERMINATE - task_scheduler_init( int number_of_threads=automatic, stack_size_type thread_stack_size=0, bool wait_workers_in_terminate = false ) : my_scheduler(NULL) -#else - task_scheduler_init( int number_of_threads=automatic, stack_size_type thread_stack_size=0 ) : my_scheduler(NULL) +#if TBB_USE_EXCEPTIONS + //! terminate() that waits for worker threads termination. Throws exception on error. + void blocking_terminate() { + internal_blocking_terminate( /*throwing=*/true ); + } #endif + //! terminate() that waits for worker threads termination. Returns false on error. + bool blocking_terminate(const std::nothrow_t&) __TBB_NOEXCEPT(true) { + return internal_blocking_terminate( /*throwing=*/false ); + } +#endif // __TBB_SUPPORTS_WORKERS_WAITING_IN_TERMINATE + + //! Shorthand for default constructor followed by call to initialize(number_of_threads). + task_scheduler_init( int number_of_threads=automatic, stack_size_type thread_stack_size=0 ) : my_scheduler(NULL) { // Two lowest order bits of the stack size argument may be taken to communicate // default exception propagation mode of the client to be used when the @@ -111,10 +123,6 @@ public: #if TBB_USE_EXCEPTIONS thread_stack_size |= TBB_USE_CAPTURED_EXCEPTION ? propagation_mode_captured : propagation_mode_exact; #endif /* TBB_USE_EXCEPTIONS */ -#if __TBB_SUPPORTS_WORKERS_WAITING_IN_TERMINATE - if (wait_workers_in_terminate) - my_scheduler = (internal::scheduler*)wait_workers_in_terminate_flag; -#endif initialize( number_of_threads, thread_stack_size ); } diff --git a/lib/3rdParty/tbb/include/tbb/task_scheduler_observer.h b/lib/3rdParty/tbb/include/tbb/task_scheduler_observer.h index ba5854f..5586ad4 100644 --- a/lib/3rdParty/tbb/include/tbb/task_scheduler_observer.h +++ b/lib/3rdParty/tbb/include/tbb/task_scheduler_observer.h @@ -1,30 +1,30 @@ /* - 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_task_scheduler_observer_H #define __TBB_task_scheduler_observer_H #include "atomic.h" -#if __TBB_TASK_ARENA +#if __TBB_ARENA_OBSERVER || __TBB_SLEEP_PERMISSION #include "task_arena.h" -#endif //__TBB_TASK_ARENA +#endif #if __TBB_SCHEDULER_OBSERVER @@ -88,7 +88,7 @@ public: } // namespace internal -#if __TBB_ARENA_OBSERVER +#if __TBB_ARENA_OBSERVER || __TBB_SLEEP_PERMISSION namespace interface6 { class task_scheduler_observer : public internal::task_scheduler_observer_v3 { friend class internal::task_scheduler_observer_v3; @@ -115,19 +115,24 @@ public: guarantees and is not composable. Thus the current default behavior of the constructor is obsolete too and will be changed in one of the future versions of the library. **/ - task_scheduler_observer( bool local = false ) { + explicit task_scheduler_observer( bool local = false ) { +#if __TBB_ARENA_OBSERVER my_context_tag = local? implicit_tag : global_tag; +#else + __TBB_ASSERT_EX( !local, NULL ); + my_context_tag = global_tag; +#endif } -#if __TBB_TASK_ARENA +#if __TBB_ARENA_OBSERVER //! Construct local observer for a given arena in inactive state (observation disabled). /** entry/exit notifications are invoked whenever a thread joins/leaves arena. If a thread is already in the arena when the observer is activated, the entry notification is called before it executes the first stolen task. **/ - task_scheduler_observer( task_arena & a) { + explicit task_scheduler_observer( task_arena & a) { my_context_tag = (intptr_t)&a; } -#endif //__TBB_TASK_ARENA +#endif /* __TBB_ARENA_OBSERVER */ /** Destructor protects instance of the observer from concurrent notification. It is recommended to disable observation before destructor of a derived class starts, @@ -145,6 +150,7 @@ public: internal::task_scheduler_observer_v3::observe(state); } +#if __TBB_SLEEP_PERMISSION //! Return commands for may_sleep() enum { keep_awake = false, allow_sleep = true }; @@ -152,13 +158,14 @@ public: /** If it returns false ('keep_awake'), the thread will keep spinning and looking for work. It will not be called for master threads. **/ virtual bool may_sleep() { return allow_sleep; } +#endif /*__TBB_SLEEP_PERMISSION*/ }; } //namespace interface6 using interface6::task_scheduler_observer; -#else /*__TBB_ARENA_OBSERVER*/ +#else /*__TBB_ARENA_OBSERVER || __TBB_SLEEP_PERMISSION*/ typedef tbb::internal::task_scheduler_observer_v3 task_scheduler_observer; -#endif /*__TBB_ARENA_OBSERVER*/ +#endif /*__TBB_ARENA_OBSERVER || __TBB_SLEEP_PERMISSION*/ } // namespace tbb diff --git a/lib/3rdParty/tbb/include/tbb/tbb.h b/lib/3rdParty/tbb/include/tbb/tbb.h index d6c9d75..5e385ea 100644 --- a/lib/3rdParty/tbb/include/tbb/tbb.h +++ b/lib/3rdParty/tbb/include/tbb/tbb.h @@ -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_H diff --git a/lib/3rdParty/tbb/include/tbb/tbb_allocator.h b/lib/3rdParty/tbb/include/tbb/tbb_allocator.h index 3707ef6..6346d86 100644 --- a/lib/3rdParty/tbb/include/tbb/tbb_allocator.h +++ b/lib/3rdParty/tbb/include/tbb/tbb_allocator.h @@ -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_allocator_H diff --git a/lib/3rdParty/tbb/include/tbb/tbb_config.h b/lib/3rdParty/tbb/include/tbb/tbb_config.h index caade25..25f9f24 100644 --- a/lib/3rdParty/tbb/include/tbb/tbb_config.h +++ b/lib/3rdParty/tbb/include/tbb/tbb_config.h @@ -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_config_H @@ -34,15 +34,27 @@ */ #define __TBB_TODO 0 -/*Check which standard library we use on OS X.*/ +/*Check which standard library we use on macOS*.*/ /*__TBB_SYMBOL is defined only while processing exported symbols list where C++ is not allowed.*/ -#if !defined(__TBB_SYMBOL) && __APPLE__ +#if !defined(__TBB_SYMBOL) && (__APPLE__ || __ANDROID__) #include #endif -// note that when ICC is in use __TBB_GCC_VERSION might not closely match GCC version on the machine +// note that when ICC or Clang is in use, __TBB_GCC_VERSION might not fully match +// the actual GCC version on the system. #define __TBB_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) +// Since GNU libstdc++ does not have a convenient macro for its version, +// we rely on the version of GCC or the user-specified macro below. +// The format of TBB_USE_GLIBCXX_VERSION should match the __TBB_GCC_VERSION above, +// e.g. it should be set to 40902 for libstdc++ coming with GCC 4.9.2. +#ifdef TBB_USE_GLIBCXX_VERSION +#define __TBB_GLIBCXX_VERSION TBB_USE_GLIBCXX_VERSION +#else +#define __TBB_GLIBCXX_VERSION __TBB_GCC_VERSION +//TODO: analyze __GLIBCXX__ instead of __TBB_GCC_VERSION ? +#endif + #if __clang__ /**according to clang documentation version can be vendor specific **/ #define __TBB_CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) @@ -86,7 +98,7 @@ #define __TBB_DEFINE_MIC 1 #endif -#define __TBB_TSX_AVAILABLE (__TBB_x86_32 || __TBB_x86_64) && !__TBB_DEFINE_MIC +#define __TBB_TSX_AVAILABLE ((__TBB_x86_32 || __TBB_x86_64) && !__TBB_DEFINE_MIC) /** Presence of compiler features **/ @@ -102,7 +114,7 @@ #endif /* Select particular features of C++11 based on compiler version. - ICC 12.1 (Linux), GCC 4.3 and higher, clang 2.9 and higher + ICC 12.1 (Linux*), GCC 4.3 and higher, clang 2.9 and higher set __GXX_EXPERIMENTAL_CXX0X__ in c++11 mode. Compilers that mimics other compilers (ICC, clang) must be processed before @@ -112,144 +124,194 @@ support added. */ -#if __INTEL_COMPILER - /** C++11 mode detection macros for Intel C++ compiler (enabled by -std=c++0x option): - __INTEL_CXX11_MODE__ for version >=13.0 - __STDC_HOSTED__ for version >=12.0 on Windows, - __GXX_EXPERIMENTAL_CXX0X__ for version >=12.0 on Linux and OS X. **/ - // On Windows, C++11 features supported by Visual Studio 2010 and higher are enabled by default - #ifndef __INTEL_CXX11_MODE__ - #define __INTEL_CXX11_MODE__ ((_MSC_VER && __STDC_HOSTED__) || __GXX_EXPERIMENTAL_CXX0X__) - // TODO: check if more conditions can be simplified with the above macro - #endif - #define __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT (__INTEL_CXX11_MODE__ && __VARIADIC_TEMPLATES) +/** C++11 mode detection macros for Intel(R) C++ compiler (enabled by -std=c++XY option): + __INTEL_CXX11_MODE__ for version >=13.0 (not available for ICC 15.0 if -std=c++14 is used), + __STDC_HOSTED__ for version >=12.0 (useful only on Windows), + __GXX_EXPERIMENTAL_CXX0X__ for version >=12.0 on Linux and macOS. **/ +#if __INTEL_COMPILER && !__INTEL_CXX11_MODE__ + // __INTEL_CXX11_MODE__ is not set, try to deduce it + #define __INTEL_CXX11_MODE__ (__GXX_EXPERIMENTAL_CXX0X__ || (_MSC_VER && __STDC_HOSTED__)) +#endif + +// Intel(R) C++ Compiler offloading API to the Intel(R) Graphics Technology presence macro +// TODO: add support for ICC 15.00 _GFX_enqueue API and then decrease Intel compiler supported version +// TODO: add linux support and restict it with (__linux__ && __TBB_x86_64 && !__ANDROID__) macro +#if __INTEL_COMPILER >= 1600 && _WIN32 +#define __TBB_GFX_PRESENT 1 +#endif + +#if __INTEL_COMPILER && (!_MSC_VER || __INTEL_CXX11_MODE__) + // On Windows, C++11 features supported by Visual Studio 2010 and higher are enabled by default, + // so in absence of /Qstd= use MSVC branch for __TBB_CPP11_* detection. + // On other platforms, no -std= means C++03. + + #define __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT (__INTEL_CXX11_MODE__ && __VARIADIC_TEMPLATES) // Both r-value reference support in compiler and std::move/std::forward // presence in C++ standard library is checked. - #define __TBB_CPP11_RVALUE_REF_PRESENT ((__GXX_EXPERIMENTAL_CXX0X__ && (__TBB_GCC_VERSION >= 40300 || _LIBCPP_VERSION) || _MSC_VER >= 1600) && __INTEL_COMPILER >= 1200) + #define __TBB_CPP11_RVALUE_REF_PRESENT ((_MSC_VER >= 1700 || __GXX_EXPERIMENTAL_CXX0X__ && (__TBB_GLIBCXX_VERSION >= 40500 || _LIBCPP_VERSION)) && __INTEL_COMPILER >= 1400) + #define __TBB_IMPLICIT_MOVE_PRESENT (__INTEL_CXX11_MODE__ && __INTEL_COMPILER >= 1400 && (_MSC_VER >= 1900 || __TBB_GCC_VERSION >= 40600 || __clang__)) #if _MSC_VER >= 1600 - #define __TBB_EXCEPTION_PTR_PRESENT ( __INTEL_COMPILER > 1300 \ - /*ICC 12.1 Upd 10 and 13 beta Upd 2 fixed exception_ptr linking issue*/ \ - || (__INTEL_COMPILER == 1300 && __INTEL_COMPILER_BUILD_DATE >= 20120530) \ - || (__INTEL_COMPILER == 1210 && __INTEL_COMPILER_BUILD_DATE >= 20120410) ) + #define __TBB_EXCEPTION_PTR_PRESENT ( __INTEL_COMPILER > 1300 \ + /*ICC 12.1 Upd 10 and 13 beta Upd 2 fixed exception_ptr linking issue*/ \ + || (__INTEL_COMPILER == 1300 && __INTEL_COMPILER_BUILD_DATE >= 20120530) \ + || (__INTEL_COMPILER == 1210 && __INTEL_COMPILER_BUILD_DATE >= 20120410) ) /** libstdc++ that comes with GCC 4.6 use C++11 features not supported by ICC 12.1. - * Because of that ICC 12.1 does not support C++11 mode with with gcc 4.6 (or higher), - * and therefore does not define __GXX_EXPERIMENTAL_CXX0X__ macro **/ - #elif __TBB_GCC_VERSION >= 40404 && __TBB_GCC_VERSION < 40600 - #define __TBB_EXCEPTION_PTR_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __INTEL_COMPILER >= 1200) - #elif __TBB_GCC_VERSION >= 40600 - #define __TBB_EXCEPTION_PTR_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __INTEL_COMPILER >= 1300) + * Because of that ICC 12.1 does not support C++11 mode with gcc 4.6 (or higher), + * and therefore does not define __GXX_EXPERIMENTAL_CXX0X__ macro **/ + #elif __TBB_GLIBCXX_VERSION >= 40404 && __TBB_GLIBCXX_VERSION < 40600 + #define __TBB_EXCEPTION_PTR_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __INTEL_COMPILER >= 1200) + #elif __TBB_GLIBCXX_VERSION >= 40600 + #define __TBB_EXCEPTION_PTR_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __INTEL_COMPILER >= 1300) #elif _LIBCPP_VERSION - #define __TBB_EXCEPTION_PTR_PRESENT __GXX_EXPERIMENTAL_CXX0X__ + #define __TBB_EXCEPTION_PTR_PRESENT __GXX_EXPERIMENTAL_CXX0X__ #else - #define __TBB_EXCEPTION_PTR_PRESENT 0 + #define __TBB_EXCEPTION_PTR_PRESENT 0 #endif - #define __TBB_STATIC_ASSERT_PRESENT (__INTEL_CXX11_MODE__ || _MSC_VER >= 1600) - #define __TBB_CPP11_TUPLE_PRESENT (_MSC_VER >= 1600 || (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40300)) + #define __TBB_STATIC_ASSERT_PRESENT (__INTEL_CXX11_MODE__ || _MSC_VER >= 1600) + #define __TBB_CPP11_TUPLE_PRESENT (_MSC_VER >= 1600 || __GXX_EXPERIMENTAL_CXX0X__ && (__TBB_GLIBCXX_VERSION >= 40300 || _LIBCPP_VERSION)) #if (__clang__ && __INTEL_COMPILER > 1400) /* Older versions of Intel Compiler do not have __has_include */ #if (__has_feature(__cxx_generalized_initializers__) && __has_include()) - #define __TBB_INITIALIZER_LISTS_PRESENT 1 + #define __TBB_INITIALIZER_LISTS_PRESENT 1 #endif #else - #define __TBB_INITIALIZER_LISTS_PRESENT __INTEL_CXX11_MODE__ && __INTEL_COMPILER >= 1400 && (_MSC_VER >= 1800 || __TBB_GCC_VERSION >= 40400 || _LIBCPP_VERSION) + #define __TBB_INITIALIZER_LISTS_PRESENT (__INTEL_CXX11_MODE__ && __INTEL_COMPILER >= 1400 && (_MSC_VER >= 1800 || __TBB_GLIBCXX_VERSION >= 40400 || _LIBCPP_VERSION)) #endif - - #define __TBB_CONSTEXPR_PRESENT __INTEL_CXX11_MODE__ && __INTEL_COMPILER >= 1400 - #define __TBB_DEFAULTED_AND_DELETED_FUNC_PRESENT __INTEL_CXX11_MODE__ && __INTEL_COMPILER >= 1200 + #define __TBB_CONSTEXPR_PRESENT (__INTEL_CXX11_MODE__ && __INTEL_COMPILER >= 1400) + #define __TBB_DEFAULTED_AND_DELETED_FUNC_PRESENT (__INTEL_CXX11_MODE__ && __INTEL_COMPILER >= 1200) /** ICC seems to disable support of noexcept event in c++11 when compiling in compatibility mode for gcc <4.6 **/ - #define __TBB_NOEXCEPT_PRESENT __INTEL_CXX11_MODE__ && __INTEL_COMPILER >= 1300 && (__TBB_GCC_VERSION >= 40600 || _LIBCPP_VERSION || _MSC_VER) - #define __TBB_CPP11_STD_BEGIN_END_PRESENT (_MSC_VER >= 1700 || __GXX_EXPERIMENTAL_CXX0X__ && __INTEL_COMPILER >= 1310 && (__TBB_GCC_VERSION >= 40600 || _LIBCPP_VERSION)) - #define __TBB_CPP11_AUTO_PRESENT (_MSC_VER >= 1600 || __GXX_EXPERIMENTAL_CXX0X__ && __INTEL_COMPILER >= 1210) - #define __TBB_CPP11_DECLTYPE_PRESENT (_MSC_VER >= 1600 || __GXX_EXPERIMENTAL_CXX0X__ && __INTEL_COMPILER >= 1210) - #define __TBB_CPP11_LAMBDAS_PRESENT (__INTEL_CXX11_MODE__ && __INTEL_COMPILER >= 1200) + #define __TBB_NOEXCEPT_PRESENT (__INTEL_CXX11_MODE__ && __INTEL_COMPILER >= 1300 && (__TBB_GLIBCXX_VERSION >= 40600 || _LIBCPP_VERSION || _MSC_VER)) + #define __TBB_CPP11_STD_BEGIN_END_PRESENT (_MSC_VER >= 1700 || __GXX_EXPERIMENTAL_CXX0X__ && __INTEL_COMPILER >= 1310 && (__TBB_GLIBCXX_VERSION >= 40600 || _LIBCPP_VERSION)) + #define __TBB_CPP11_AUTO_PRESENT (_MSC_VER >= 1600 || __GXX_EXPERIMENTAL_CXX0X__ && __INTEL_COMPILER >= 1210) + #define __TBB_CPP11_DECLTYPE_PRESENT (_MSC_VER >= 1600 || __GXX_EXPERIMENTAL_CXX0X__ && __INTEL_COMPILER >= 1210) + #define __TBB_CPP11_LAMBDAS_PRESENT (__INTEL_CXX11_MODE__ && __INTEL_COMPILER >= 1200) + #define __TBB_CPP11_DEFAULT_FUNC_TEMPLATE_ARGS_PRESENT (_MSC_VER >= 1800 || __GXX_EXPERIMENTAL_CXX0X__ && __INTEL_COMPILER >= 1210) + #define __TBB_OVERRIDE_PRESENT (__INTEL_CXX11_MODE__ && __INTEL_COMPILER >= 1400) + #define __TBB_ALIGNAS_PRESENT (__INTEL_CXX11_MODE__ && __INTEL_COMPILER >= 1500) + #define __TBB_CPP11_TEMPLATE_ALIASES_PRESENT (__INTEL_CXX11_MODE__ && __INTEL_COMPILER >= 1210) #elif __clang__ -//TODO: these options need to be rechecked -/** on OS X* the only way to get C++11 is to use clang. For library features (e.g. exception_ptr) libc++ is also +/** TODO: these options need to be rechecked **/ +/** on macOS the only way to get C++11 is to use clang. For library features (e.g. exception_ptr) libc++ is also * required. So there is no need to check GCC version for clang**/ - #define __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT (__has_feature(__cxx_variadic_templates__)) - #define __TBB_CPP11_RVALUE_REF_PRESENT (__has_feature(__cxx_rvalue_references__) && (__TBB_GCC_VERSION >= 40300 || _LIBCPP_VERSION)) + #define __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT __has_feature(__cxx_variadic_templates__) + #define __TBB_CPP11_RVALUE_REF_PRESENT (__has_feature(__cxx_rvalue_references__) && (_LIBCPP_VERSION || __TBB_GLIBCXX_VERSION >= 40500)) + #define __TBB_IMPLICIT_MOVE_PRESENT __has_feature(cxx_implicit_moves) /** TODO: extend exception_ptr related conditions to cover libstdc++ **/ - #define __TBB_EXCEPTION_PTR_PRESENT (__cplusplus >= 201103L && _LIBCPP_VERSION) - #define __TBB_STATIC_ASSERT_PRESENT __has_feature(__cxx_static_assert__) + #define __TBB_EXCEPTION_PTR_PRESENT (__cplusplus >= 201103L && (_LIBCPP_VERSION || __TBB_GLIBCXX_VERSION >= 40600)) + #define __TBB_STATIC_ASSERT_PRESENT __has_feature(__cxx_static_assert__) /**Clang (preprocessor) has problems with dealing with expression having __has_include in #ifs * used inside C++ code. (At least version that comes with OS X 10.8 : Apple LLVM version 4.2 (clang-425.0.28) (based on LLVM 3.2svn)) **/ #if (__GXX_EXPERIMENTAL_CXX0X__ && __has_include()) - #define __TBB_CPP11_TUPLE_PRESENT 1 + #define __TBB_CPP11_TUPLE_PRESENT 1 #endif #if (__has_feature(__cxx_generalized_initializers__) && __has_include()) - #define __TBB_INITIALIZER_LISTS_PRESENT 1 + #define __TBB_INITIALIZER_LISTS_PRESENT 1 #endif - #define __TBB_CONSTEXPR_PRESENT __has_feature(__cxx_constexpr__) - #define __TBB_DEFAULTED_AND_DELETED_FUNC_PRESENT (__has_feature(__cxx_defaulted_functions__) && __has_feature(__cxx_deleted_functions__)) + #define __TBB_CONSTEXPR_PRESENT __has_feature(__cxx_constexpr__) + #define __TBB_DEFAULTED_AND_DELETED_FUNC_PRESENT (__has_feature(__cxx_defaulted_functions__) && __has_feature(__cxx_deleted_functions__)) /**For some unknown reason __has_feature(__cxx_noexcept) does not yield true for all cases. Compiler bug ? **/ - #define __TBB_NOEXCEPT_PRESENT (__cplusplus >= 201103L) - #define __TBB_CPP11_STD_BEGIN_END_PRESENT (__has_feature(__cxx_range_for__) && _LIBCPP_VERSION) - #define __TBB_CPP11_AUTO_PRESENT __has_feature(__cxx_auto_type__) - #define __TBB_CPP11_DECLTYPE_PRESENT __has_feature(__cxx_decltype__) - #define __TBB_CPP11_LAMBDAS_PRESENT __has_feature(cxx_lambdas) + #define __TBB_NOEXCEPT_PRESENT (__cplusplus >= 201103L) + #define __TBB_CPP11_STD_BEGIN_END_PRESENT (__has_feature(__cxx_range_for__) && (_LIBCPP_VERSION || __TBB_GLIBCXX_VERSION >= 40600)) + #define __TBB_CPP11_AUTO_PRESENT __has_feature(__cxx_auto_type__) + #define __TBB_CPP11_DECLTYPE_PRESENT __has_feature(__cxx_decltype__) + #define __TBB_CPP11_LAMBDAS_PRESENT __has_feature(cxx_lambdas) + #define __TBB_CPP11_DEFAULT_FUNC_TEMPLATE_ARGS_PRESENT __has_feature(cxx_default_function_template_args) + #define __TBB_OVERRIDE_PRESENT __has_feature(cxx_override_control) + #define __TBB_ALIGNAS_PRESENT __has_feature(cxx_alignas) + #define __TBB_CPP11_TEMPLATE_ALIASES_PRESENT __has_feature(cxx_alias_templates) #elif __GNUC__ - #define __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT __GXX_EXPERIMENTAL_CXX0X__ - #define __TBB_CPP11_RVALUE_REF_PRESENT __GXX_EXPERIMENTAL_CXX0X__ + #define __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT __GXX_EXPERIMENTAL_CXX0X__ + #define __TBB_CPP11_VARIADIC_FIXED_LENGTH_EXP_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40700) + #define __TBB_CPP11_RVALUE_REF_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40500) + #define __TBB_IMPLICIT_MOVE_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40600) /** __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 here is a substitution for _GLIBCXX_ATOMIC_BUILTINS_4, which is a prerequisite for exception_ptr but cannot be used in this file because it is defined in a header, not by the compiler. If the compiler has no atomic intrinsics, the C++ library should not expect those as well. **/ - #define __TBB_EXCEPTION_PTR_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40404 && __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) - #define __TBB_STATIC_ASSERT_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40300) - #define __TBB_CPP11_TUPLE_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40300) - #define __TBB_INITIALIZER_LISTS_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40400) + #define __TBB_EXCEPTION_PTR_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40404 && __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) + #define __TBB_STATIC_ASSERT_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40300) + #define __TBB_CPP11_TUPLE_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40300) + #define __TBB_INITIALIZER_LISTS_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40400) /** gcc seems have to support constexpr from 4.4 but tests in (test_atomic) seeming reasonable fail to compile prior 4.6**/ - #define __TBB_CONSTEXPR_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40400) - #define __TBB_DEFAULTED_AND_DELETED_FUNC_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40400) - #define __TBB_NOEXCEPT_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40600) - #define __TBB_CPP11_STD_BEGIN_END_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40600) - #define __TBB_CPP11_AUTO_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40400) - #define __TBB_CPP11_DECLTYPE_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40400) - #define __TBB_CPP11_LAMBDAS_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40500) + #define __TBB_CONSTEXPR_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40400) + #define __TBB_DEFAULTED_AND_DELETED_FUNC_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40400) + #define __TBB_NOEXCEPT_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40600) + #define __TBB_CPP11_STD_BEGIN_END_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40600) + #define __TBB_CPP11_AUTO_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40400) + #define __TBB_CPP11_DECLTYPE_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40400) + #define __TBB_CPP11_LAMBDAS_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40500) + #define __TBB_CPP11_DEFAULT_FUNC_TEMPLATE_ARGS_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40300) + #define __TBB_OVERRIDE_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40700) + #define __TBB_ALIGNAS_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40800) + #define __TBB_CPP11_TEMPLATE_ALIASES_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40700) #elif _MSC_VER - #define __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT (_MSC_VER >= 1800) - #define __TBB_CPP11_RVALUE_REF_PRESENT (_MSC_VER >= 1600) - #define __TBB_EXCEPTION_PTR_PRESENT (_MSC_VER >= 1600) - #define __TBB_STATIC_ASSERT_PRESENT (_MSC_VER >= 1600) - #define __TBB_CPP11_TUPLE_PRESENT (_MSC_VER >= 1600) - #define __TBB_INITIALIZER_LISTS_PRESENT (_MSC_VER >= 1800) - #define __TBB_CONSTEXPR_PRESENT (_MSC_VER >= 1900) - #define __TBB_DEFAULTED_AND_DELETED_FUNC_PRESENT (_MSC_VER >= 1800) - #define __TBB_NOEXCEPT_PRESENT (_MSC_VER >= 1900) - #define __TBB_CPP11_STD_BEGIN_END_PRESENT (_MSC_VER >= 1700) - #define __TBB_CPP11_AUTO_PRESENT (_MSC_VER >= 1600) - #define __TBB_CPP11_DECLTYPE_PRESENT (_MSC_VER >= 1600) - #define __TBB_CPP11_LAMBDAS_PRESENT (_MSC_VER >= 1600) + // These definitions are also used with Intel Compiler in "default" mode; see a comment above. + + #define __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT (_MSC_VER >= 1800) + // Contains a workaround for ICC 13 + #define __TBB_CPP11_RVALUE_REF_PRESENT (_MSC_VER >= 1700 && (!__INTEL_COMPILER || __INTEL_COMPILER >= 1400)) + #define __TBB_IMPLICIT_MOVE_PRESENT (_MSC_VER >= 1900) + #define __TBB_EXCEPTION_PTR_PRESENT (_MSC_VER >= 1600) + #define __TBB_STATIC_ASSERT_PRESENT (_MSC_VER >= 1600) + #define __TBB_CPP11_TUPLE_PRESENT (_MSC_VER >= 1600) + #define __TBB_INITIALIZER_LISTS_PRESENT (_MSC_VER >= 1800) + #define __TBB_CONSTEXPR_PRESENT (_MSC_VER >= 1900) + #define __TBB_DEFAULTED_AND_DELETED_FUNC_PRESENT (_MSC_VER >= 1800) + #define __TBB_NOEXCEPT_PRESENT (_MSC_VER >= 1900) + #define __TBB_CPP11_STD_BEGIN_END_PRESENT (_MSC_VER >= 1700) + #define __TBB_CPP11_AUTO_PRESENT (_MSC_VER >= 1600) + #define __TBB_CPP11_DECLTYPE_PRESENT (_MSC_VER >= 1600) + #define __TBB_CPP11_LAMBDAS_PRESENT (_MSC_VER >= 1600) + #define __TBB_CPP11_DEFAULT_FUNC_TEMPLATE_ARGS_PRESENT (_MSC_VER >= 1800) + #define __TBB_OVERRIDE_PRESENT (_MSC_VER >= 1700) + #define __TBB_ALIGNAS_PRESENT (_MSC_VER >= 1900) + #define __TBB_CPP11_TEMPLATE_ALIASES_PRESENT (_MSC_VER >= 1800) #else - #define __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT 0 - #define __TBB_CPP11_RVALUE_REF_PRESENT 0 - #define __TBB_EXCEPTION_PTR_PRESENT 0 - #define __TBB_STATIC_ASSERT_PRESENT 0 - #define __TBB_CPP11_TUPLE_PRESENT 0 - #define __TBB_INITIALIZER_LISTS_PRESENT 0 - #define __TBB_CONSTEXPR_PRESENT 0 - #define __TBB_DEFAULTED_AND_DELETED_FUNC_PRESENT 0 - #define __TBB_NOEXCEPT_PRESENT 0 - #define __TBB_CPP11_STD_BEGIN_END_PRESENT 0 - #define __TBB_CPP11_AUTO_PRESENT 0 - #define __TBB_CPP11_DECLTYPE_PRESENT 0 - #define __TBB_CPP11_LAMBDAS_PRESENT 0 + #define __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT 0 + #define __TBB_CPP11_RVALUE_REF_PRESENT 0 + #define __TBB_IMPLICIT_MOVE_PRESENT 0 + #define __TBB_EXCEPTION_PTR_PRESENT 0 + #define __TBB_STATIC_ASSERT_PRESENT 0 + #define __TBB_CPP11_TUPLE_PRESENT 0 + #define __TBB_INITIALIZER_LISTS_PRESENT 0 + #define __TBB_CONSTEXPR_PRESENT 0 + #define __TBB_DEFAULTED_AND_DELETED_FUNC_PRESENT 0 + #define __TBB_NOEXCEPT_PRESENT 0 + #define __TBB_CPP11_STD_BEGIN_END_PRESENT 0 + #define __TBB_CPP11_AUTO_PRESENT 0 + #define __TBB_CPP11_DECLTYPE_PRESENT 0 + #define __TBB_CPP11_LAMBDAS_PRESENT 0 + #define __TBB_CPP11_DEFAULT_FUNC_TEMPLATE_ARGS_PRESENT 0 + #define __TBB_OVERRIDE_PRESENT 0 + #define __TBB_ALIGNAS_PRESENT 0 + #define __TBB_CPP11_TEMPLATE_ALIASES_PRESENT 0 #endif // C++11 standard library features +#ifndef __TBB_CPP11_VARIADIC_FIXED_LENGTH_EXP_PRESENT +#define __TBB_CPP11_VARIADIC_FIXED_LENGTH_EXP_PRESENT __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT +#endif #define __TBB_CPP11_VARIADIC_TUPLE_PRESENT (!_MSC_VER || _MSC_VER >=1800) -#define __TBB_CPP11_TYPE_PROPERTIES_PRESENT (_LIBCPP_VERSION || _MSC_VER >= 1700 || (__TBB_GCC_VERSION >= 50000 && __GXX_EXPERIMENTAL_CXX0X__)) -#define __TBB_TR1_TYPE_PROPERTIES_IN_STD_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40300 || _MSC_VER >= 1600) -// GCC supported some of type properties since 4.7 -#define __TBB_CPP11_IS_COPY_CONSTRUCTIBLE_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40700 || __TBB_CPP11_TYPE_PROPERTIES_PRESENT) -// In GCC and MSVC, implementation of std::move_if_noexcept is not aligned with noexcept -#define __TBB_MOVE_IF_NOEXCEPT_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40700 || _MSC_VER >= 1900 || __clang__ && _LIBCPP_VERSION && __TBB_NOEXCEPT_PRESENT) -//TODO: Probably more accurate way is to analyze version of stdlibc++ via__GLIBCXX__ instead of __TBB_GCC_VERSION -#define __TBB_ALLOCATOR_TRAITS_PRESENT (__cplusplus >= 201103L && _LIBCPP_VERSION || _MSC_VER >= 1700 || \ - __GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40700 && !(__TBB_GCC_VERSION == 40700 && __TBB_DEFINE_MIC) \ - ) -#define __TBB_MAKE_EXCEPTION_PTR_PRESENT (__TBB_EXCEPTION_PTR_PRESENT && (_MSC_VER >= 1700 || __TBB_GCC_VERSION >= 40600 || _LIBCPP_VERSION)) +#define __TBB_CPP11_TYPE_PROPERTIES_PRESENT (_LIBCPP_VERSION || _MSC_VER >= 1700 || (__TBB_GLIBCXX_VERSION >= 50000 && __GXX_EXPERIMENTAL_CXX0X__)) +#define __TBB_TR1_TYPE_PROPERTIES_IN_STD_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GLIBCXX_VERSION >= 40300 || _MSC_VER >= 1600) +// GCC supported some of type properties since 4.7 +#define __TBB_CPP11_IS_COPY_CONSTRUCTIBLE_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GLIBCXX_VERSION >= 40700 || __TBB_CPP11_TYPE_PROPERTIES_PRESENT) + +// In GCC, std::move_if_noexcept appeared later than noexcept +#define __TBB_MOVE_IF_NOEXCEPT_PRESENT (__TBB_NOEXCEPT_PRESENT && (__TBB_GLIBCXX_VERSION >= 40700 || _MSC_VER >= 1900 || _LIBCPP_VERSION)) +#define __TBB_ALLOCATOR_TRAITS_PRESENT (__cplusplus >= 201103L && _LIBCPP_VERSION || _MSC_VER >= 1700 || \ + __GXX_EXPERIMENTAL_CXX0X__ && __TBB_GLIBCXX_VERSION >= 40700 && !(__TBB_GLIBCXX_VERSION == 40700 && __TBB_DEFINE_MIC)) +#define __TBB_MAKE_EXCEPTION_PTR_PRESENT (__TBB_EXCEPTION_PTR_PRESENT && (_MSC_VER >= 1700 || __TBB_GLIBCXX_VERSION >= 40600 || _LIBCPP_VERSION)) + +#define __TBB_CPP11_FUTURE_PRESENT (_MSC_VER >= 1700 || __TBB_GLIBCXX_VERSION >= 40600 && _GXX_EXPERIMENTAL_CXX0X__ || _LIBCPP_VERSION) + +// std::swap is in only since C++11, though MSVC had it at least since VS2005 +#if _MSC_VER>=1400 || _LIBCPP_VERSION || __GXX_EXPERIMENTAL_CXX0X__ +#define __TBB_STD_SWAP_HEADER +#else +#define __TBB_STD_SWAP_HEADER +#endif //TODO: not clear how exactly this macro affects exception_ptr - investigate // On linux ICC fails to find existing std::exception_ptr in libstdc++ without this define @@ -285,11 +347,32 @@ #define __TBB_TSX_INTRINSICS_PRESENT ((__RTM__ || _MSC_VER>=1700 || __INTEL_COMPILER>=1300) && !__TBB_DEFINE_MIC && !__ANDROID__) -/** User controlled TBB features & modes **/ +/** Macro helpers **/ +#define __TBB_CONCAT_AUX(A,B) A##B +// The additional level of indirection is needed to expand macros A and B (not to get the AB macro). +// See [cpp.subst] and [cpp.concat] for more details. +#define __TBB_CONCAT(A,B) __TBB_CONCAT_AUX(A,B) +// The IGNORED argument and comma are needed to always have 2 arguments (even when A is empty). +#define __TBB_IS_MACRO_EMPTY(A,IGNORED) __TBB_CONCAT_AUX(__TBB_MACRO_EMPTY,A) +#define __TBB_MACRO_EMPTY 1 +/** User controlled TBB features & modes **/ #ifndef TBB_USE_DEBUG +/* +There are four cases that are supported: + 1. "_DEBUG is undefined" means "no debug"; + 2. "_DEBUG defined to something that is evaluated to 0 (the "garbage" is also evaluated to 0 [cpp.cond])" means "no debug"; + 3. "_DEBUG defined to something that is evaluated to non-zero value" means "debug"; + 4. "_DEBUG defined to nothing (empty)" means "debug". +*/ #ifdef _DEBUG +// Check if _DEBUG is empty. +#define __TBB_IS__DEBUG_EMPTY (__TBB_IS_MACRO_EMPTY(_DEBUG,IGNORED)==__TBB_MACRO_EMPTY) +#if __TBB_IS__DEBUG_EMPTY +#define TBB_USE_DEBUG 1 +#else #define TBB_USE_DEBUG _DEBUG +#endif /* __TBB_IS__DEBUG_EMPTY */ #else #define TBB_USE_DEBUG 0 #endif @@ -311,7 +394,7 @@ #endif /* TBB_PEFORMANCE_WARNINGS */ #endif /* TBB_USE_PERFORMANCE_WARNINGS */ -#if __TBB_DEFINE_MIC || defined(_XBOX) +#if __TBB_DEFINE_MIC #if TBB_USE_EXCEPTIONS #error The platform does not properly support exception handling. Please do not set TBB_USE_EXCEPTIONS macro or set it to 0. #elif !defined(TBB_USE_EXCEPTIONS) @@ -340,7 +423,7 @@ #if __clang__ /* Old versions of Intel Compiler do not have __has_include or cannot use it in #define */ #if (__INTEL_COMPILER && (__INTEL_COMPILER < 1500 || __INTEL_COMPILER == 1500 && __INTEL_COMPILER_UPDATE <= 1)) - #define TBB_IMPLEMENT_CPP0X !(_LIBCPP_VERSION && (__cplusplus >= 201103L)) + #define TBB_IMPLEMENT_CPP0X (__cplusplus < 201103L || !_LIBCPP_VERSION) #else #define TBB_IMPLEMENT_CPP0X (__cplusplus < 201103L || (!__has_include() && !__has_include())) #endif @@ -413,15 +496,7 @@ #error __TBB_FP_CONTEXT requires __TBB_TASK_GROUP_CONTEXT to be enabled #endif -#ifndef __TBB_TASK_ARENA - #define __TBB_TASK_ARENA 1 -#endif /* __TBB_TASK_ARENA */ -#if __TBB_TASK_ARENA - #define __TBB_RECYCLE_TO_ENQUEUE __TBB_BUILD // keep non-official - #if !__TBB_SCHEDULER_OBSERVER - #error __TBB_TASK_ARENA requires __TBB_SCHEDULER_OBSERVER to be enabled - #endif -#endif /* __TBB_TASK_ARENA */ +#define __TBB_RECYCLE_TO_ENQUEUE __TBB_BUILD // keep non-official #ifndef __TBB_ARENA_OBSERVER #define __TBB_ARENA_OBSERVER ((__TBB_BUILD||TBB_PREVIEW_LOCAL_OBSERVER)&& __TBB_SCHEDULER_OBSERVER) @@ -431,6 +506,10 @@ #define __TBB_SLEEP_PERMISSION ((__TBB_CPF_BUILD||TBB_PREVIEW_LOCAL_OBSERVER)&& __TBB_SCHEDULER_OBSERVER) #endif /* __TBB_SLEEP_PERMISSION */ +#ifndef __TBB_TASK_ISOLATION + #define __TBB_TASK_ISOLATION (__TBB_CPF_BUILD||TBB_PREVIEW_TASK_ISOLATION) +#endif /* __TBB_TASK_ISOLATION */ + #if TBB_PREVIEW_FLOW_GRAPH_TRACE // Users of flow-graph trace need to explicitly link against the preview library. This // prevents the linker from implicitly linking an application with a preview version of @@ -512,7 +591,7 @@ versions go out of the support list. **/ -#if __ANDROID__ && __TBB_GCC_VERSION <= 40403 && !__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 +#if __SIZEOF_POINTER__ < 8 && __ANDROID__ && __TBB_GCC_VERSION <= 40403 && !__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 /** Necessary because on Android 8-byte CAS and F&A are not available for some processor architectures, but no mandatory warning message appears from GCC 4.4.3. Instead, only a linkage error occurs when these atomic operations are used (such as in unit test test_atomic.exe). **/ @@ -535,23 +614,20 @@ #define __TBB_DEFAULT_DTOR_THROW_SPEC_BROKEN 1 #endif -#if !__INTEL_COMPILER && (_MSC_VER && _MSC_VER < 1500 || __TBB_GCC_VERSION && __TBB_GCC_VERSION < 40102) +#if !__INTEL_COMPILER && (_MSC_VER && _MSC_VER < 1500 || __GNUC__ && __TBB_GCC_VERSION < 40102) /** gcc 3.4.6 (and earlier) and VS2005 (and earlier) do not allow declaring template class as a friend of classes defined in other namespaces. **/ #define __TBB_TEMPLATE_FRIENDS_BROKEN 1 #endif -//TODO: recheck for different clang versions #if __GLIBC__==2 && __GLIBC_MINOR__==3 || (__APPLE__ && ( __INTEL_COMPILER==1200 && !TBB_USE_DEBUG)) /** Macro controlling EH usages in TBB tests. Some older versions of glibc crash when exception handling happens concurrently. **/ #define __TBB_THROW_ACROSS_MODULE_BOUNDARY_BROKEN 1 -#else - #define __TBB_THROW_ACROSS_MODULE_BOUNDARY_BROKEN 0 #endif #if (_WIN32||_WIN64) && __INTEL_COMPILER == 1110 - /** That's a bug in Intel compiler 11.1.044/IA-32/Windows, that leads to a worker thread crash on the thread's startup. **/ + /** That's a bug in Intel(R) C++ Compiler 11.1.044/IA-32 architecture/Windows* OS, that leads to a worker thread crash on the thread's startup. **/ #define __TBB_ICL_11_1_CODE_GEN_BROKEN 1 #endif @@ -564,8 +640,6 @@ /** MinGW has a bug with stack alignment for routines invoked from MS RTLs. Since GCC 4.2, the bug can be worked around via a special attribute. **/ #define __TBB_SSE_STACK_ALIGNMENT_BROKEN 1 -#else - #define __TBB_SSE_STACK_ALIGNMENT_BROKEN 0 #endif #if __TBB_GCC_VERSION==40300 && !__INTEL_COMPILER && !__clang__ @@ -584,7 +658,7 @@ #endif /* __FreeBSD__ */ #if (__linux__ || __APPLE__) && __i386__ && defined(__INTEL_COMPILER) - /** The Intel compiler for IA-32 (Linux|OS X) crashes or generates + /** The Intel(R) C++ Compiler for IA-32 architecture (Linux* OS|macOS) crashes or generates incorrect code when __asm__ arguments have a cast to volatile. **/ #define __TBB_ICC_ASM_VOLATILE_BROKEN 1 #endif @@ -602,26 +676,22 @@ #if __GXX_EXPERIMENTAL_CXX0X__ && !defined(__EXCEPTIONS) && \ ((!__INTEL_COMPILER && !__clang__ && (__TBB_GCC_VERSION>=40400 && __TBB_GCC_VERSION<40600)) || \ - (__INTEL_COMPILER<=1400 && (__TBB_GCC_VERSION>=40400 && __TBB_GCC_VERSION<=40801))) + (__INTEL_COMPILER<=1400 && (__TBB_GLIBCXX_VERSION>=40400 && __TBB_GLIBCXX_VERSION<=40801))) /* There is an issue for specific GCC toolchain when C++11 is enabled and exceptions are disabled: exceprion_ptr.h/nested_exception.h use throw unconditionally. GCC can ignore 'throw' since 4.6; but with ICC the issue still exists. */ #define __TBB_LIBSTDCPP_EXCEPTION_HEADERS_BROKEN 1 -#else - #define __TBB_LIBSTDCPP_EXCEPTION_HEADERS_BROKEN 0 #endif -#if __INTEL_COMPILER==1300 && __TBB_GCC_VERSION>=40700 && defined(__GXX_EXPERIMENTAL_CXX0X__) +#if __INTEL_COMPILER==1300 && __TBB_GLIBCXX_VERSION>=40700 && defined(__GXX_EXPERIMENTAL_CXX0X__) /* Some C++11 features used inside libstdc++ are not supported by Intel compiler. * Checking version of gcc instead of libstdc++ because * - they are directly connected, * - for now it is not possible to check version of any standard library in this file */ #define __TBB_ICC_13_0_CPP11_STDLIB_SUPPORT_BROKEN 1 -#else - #define __TBB_ICC_13_0_CPP11_STDLIB_SUPPORT_BROKEN 0 #endif #if (__GNUC__==4 && __GNUC_MINOR__==4 ) && !defined(__INTEL_COMPILER) && !defined(__clang__) @@ -638,13 +708,15 @@ #define __TBB_GCC_CAS8_BUILTIN_INLINING_BROKEN 1 #endif -#if __TBB_x86_32 && (__linux__ || __APPLE__ || _WIN32 || __sun || __ANDROID__) && (__INTEL_COMPILER || (__GNUC__==3 && __GNUC_MINOR__==3 )||(__MINGW32__ ) && (__GNUC__==4 && __GNUC_MINOR__==5 ) || __SUNPRO_CC) - // Some compilers for IA-32 fail to provide 8-byte alignment of objects on the stack, - // even if the object specifies 8-byte alignment. On such platforms, the IA-32 implementation - // of 64 bit atomics (e.g. atomic) use different tactics depending upon - // whether the object is properly aligned or not. +#if __TBB_x86_32 && ( __INTEL_COMPILER || (__GNUC__==5 && __GNUC_MINOR__>=2 && __GXX_EXPERIMENTAL_CXX0X__) \ + || (__GNUC__==3 && __GNUC_MINOR__==3) || (__MINGW32__ && __GNUC__==4 && __GNUC_MINOR__==5) || __SUNPRO_CC ) + // Some compilers for IA-32 architecture fail to provide 8-byte alignment of objects on the stack, + // even if the object specifies 8-byte alignment. On such platforms, the implementation + // of 64 bit atomics for IA-32 architecture (e.g. atomic) use different tactics + // depending upon whether the object is properly aligned or not. #define __TBB_FORCE_64BIT_ALIGNMENT_BROKEN 1 #else + // Define to 0 explicitly because the macro is used in a compiled code of test_atomic #define __TBB_FORCE_64BIT_ALIGNMENT_BROKEN 0 #endif @@ -661,18 +733,15 @@ // A compiler bug: a disabled copy constructor prevents use of the moving constructor #define __TBB_IF_NO_COPY_CTOR_MOVE_SEMANTICS_BROKEN (_MSC_VER && (__INTEL_COMPILER >= 1300 && __INTEL_COMPILER <= 1310) && !__INTEL_CXX11_MODE__) -// MSVC 2013 and ICC do not generate implicit move constructor for empty derived class -#define __TBB_CPP11_IMPLICIT_MOVE_MEMBERS_GENERATION_FOR_DERIVED_BROKEN (__TBB_CPP11_RVALUE_REF_PRESENT && \ - ( !__INTEL_COMPILER && _MSC_VER && _MSC_VER <= 1800 || __INTEL_COMPILER && __INTEL_COMPILER <= 1600 )) - #define __TBB_CPP11_DECLVAL_BROKEN (_MSC_VER == 1600 || (__GNUC__ && __TBB_GCC_VERSION < 40500) ) // Intel C++ compiler has difficulties with copying std::pair with VC11 std::reference_wrapper being a const member #define __TBB_COPY_FROM_NON_CONST_REF_BROKEN (_MSC_VER == 1700 && __INTEL_COMPILER && __INTEL_COMPILER < 1600) -//The implicit upcasting of the tuple of a reference of a derived class to a base class fails on icc 13.X -//if the system's gcc environment is 4.8 -#if (__INTEL_COMPILER >=1300 && __INTEL_COMPILER <=1310) && __TBB_GCC_VERSION>=40700 && __GXX_EXPERIMENTAL_CXX0X__ - #define __TBB_UPCAST_OF_TUPLE_OF_REF_BROKEN 1 + +// The implicit upcasting of the tuple of a reference of a derived class to a base class fails on icc 13.X if the system's gcc environment is 4.8 +// Also in gcc 4.4 standard library the implementation of the tuple<&> conversion (tuple a = tuple, B is inherited from A) is broken. +#if __GXX_EXPERIMENTAL_CXX0X__ && ((__INTEL_COMPILER >=1300 && __INTEL_COMPILER <=1310 && __TBB_GLIBCXX_VERSION>=40700) || (__TBB_GLIBCXX_VERSION < 40500)) +#define __TBB_UPCAST_OF_TUPLE_OF_REF_BROKEN 1 #endif /** End of __TBB_XXX_BROKEN macro section **/ @@ -685,8 +754,8 @@ #define __TBB_ATOMIC_CTORS (__TBB_CONSTEXPR_PRESENT && __TBB_DEFAULTED_AND_DELETED_FUNC_PRESENT && (!__TBB_ZERO_INIT_WITH_DEFAULTED_CTOR_BROKEN)) // Many OS versions (Android 4.0.[0-3] for example) need workaround for dlopen to avoid non-recursive loader lock hang -// Setting the workaround for all compile targets ($APP_PLATFORM) below Android 4.4 (android-19) -#if __ANDROID__ +// Setting the workaround for all compile targets ($APP_PLATFORM) below Android 4.4 (android-19) +#if __ANDROID__ #include #define __TBB_USE_DLOPEN_REENTRANCY_WORKAROUND (__ANDROID_API__ < 19) #endif @@ -696,8 +765,15 @@ #define __TBB_VARIADIC_PARALLEL_INVOKE (TBB_PREVIEW_VARIADIC_PARALLEL_INVOKE && __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT && __TBB_CPP11_RVALUE_REF_PRESENT) #define __TBB_FLOW_GRAPH_CPP11_FEATURES (__TBB_CPP11_VARIADIC_TEMPLATES_PRESENT \ && __TBB_CPP11_RVALUE_REF_PRESENT && __TBB_CPP11_AUTO_PRESENT) \ - && __TBB_CPP11_VARIADIC_TUPLE_PRESENT && !__TBB_UPCAST_OF_TUPLE_OF_REF_BROKEN -#define __TBB_PREVIEW_ASYNC_NODE (__TBB_FLOW_GRAPH_CPP11_FEATURES && TBB_PREVIEW_FLOW_GRAPH_NODES) -#define __TBB_PREVIEW_OPENCL_NODE (__TBB_FLOW_GRAPH_CPP11_FEATURES && TBB_PREVIEW_FLOW_GRAPH_NODES && !TBB_IMPLEMENT_CPP0X) + && __TBB_CPP11_VARIADIC_TUPLE_PRESENT && __TBB_CPP11_DEFAULT_FUNC_TEMPLATE_ARGS_PRESENT \ + && !__TBB_UPCAST_OF_TUPLE_OF_REF_BROKEN +#define __TBB_PREVIEW_STREAMING_NODE (__TBB_CPP11_VARIADIC_FIXED_LENGTH_EXP_PRESENT && __TBB_FLOW_GRAPH_CPP11_FEATURES \ + && TBB_PREVIEW_FLOW_GRAPH_NODES && !TBB_IMPLEMENT_CPP0X && !__TBB_UPCAST_OF_TUPLE_OF_REF_BROKEN) +#define __TBB_PREVIEW_OPENCL_NODE (__TBB_PREVIEW_STREAMING_NODE && __TBB_CPP11_TEMPLATE_ALIASES_PRESENT) #define __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING (TBB_PREVIEW_FLOW_GRAPH_FEATURES || __TBB_PREVIEW_OPENCL_NODE) +#define __TBB_PREVIEW_ASYNC_MSG (TBB_PREVIEW_FLOW_GRAPH_FEATURES && __TBB_FLOW_GRAPH_CPP11_FEATURES) + +#define __TBB_PREVIEW_GFX_FACTORY (__TBB_GFX_PRESENT && TBB_PREVIEW_FLOW_GRAPH_FEATURES && !__TBB_MIC_OFFLOAD \ + && __TBB_FLOW_GRAPH_CPP11_FEATURES && __TBB_CPP11_TEMPLATE_ALIASES_PRESENT \ + && __TBB_CPP11_FUTURE_PRESENT) #endif /* __TBB_tbb_config_H */ diff --git a/lib/3rdParty/tbb/include/tbb/tbb_exception.h b/lib/3rdParty/tbb/include/tbb/tbb_exception.h index 73948c3..1c84330 100644 --- a/lib/3rdParty/tbb/include/tbb/tbb_exception.h +++ b/lib/3rdParty/tbb/include/tbb/tbb_exception.h @@ -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_exception_H @@ -42,34 +42,34 @@ namespace tbb { //! Exception for concurrent containers class bad_last_alloc : public std::bad_alloc { public: - /*override*/ const char* what() const throw(); + const char* what() const throw() __TBB_override; #if __TBB_DEFAULT_DTOR_THROW_SPEC_BROKEN - /*override*/ ~bad_last_alloc() throw() {} + ~bad_last_alloc() throw() __TBB_override {} #endif }; //! Exception for PPL locks class improper_lock : public std::exception { public: - /*override*/ const char* what() const throw(); + const char* what() const throw() __TBB_override; }; //! Exception for user-initiated abort class user_abort : public std::exception { public: - /*override*/ const char* what() const throw(); + const char* what() const throw() __TBB_override; }; //! Exception for missing wait on structured_task_group class missing_wait : public std::exception { public: - /*override*/ const char* what() const throw(); + const char* what() const throw() __TBB_override; }; //! Exception for repeated scheduling of the same task_handle class invalid_multiple_scheduling : public std::exception { public: - /*override*/ const char* what() const throw(); + const char* what() const throw() __TBB_override; }; namespace internal { @@ -97,9 +97,9 @@ enum exception_id { eid_user_abort, eid_reserved1, #if __TBB_SUPPORTS_WORKERS_WAITING_IN_TERMINATE - // This id is used only inside library and only for support of CPF functionality. + // This id is used only from inside the library and only for support of CPF functionality. // So, if we drop the functionality, eid_reserved1 can be safely renamed and reused. - eid_blocking_sch_init = eid_reserved1, + eid_blocking_thread_join_impossible = eid_reserved1, #endif eid_bad_tagged_msg_cast, //! The last enumerator tracks the number of defined IDs. It must remain the last one. @@ -182,7 +182,7 @@ public: virtual const char* name() const throw() = 0; //! Returns the result of originally intercepted exception's what() method. - virtual const char* what() const throw() = 0; + virtual const char* what() const throw() __TBB_override = 0; /** Operator delete is provided only to allow using existing smart pointers with TBB exception objects obtained as the result of applying move() @@ -225,20 +225,15 @@ public: return *this; } - /*override*/ - captured_exception* __TBB_EXPORTED_METHOD move () throw(); + captured_exception* __TBB_EXPORTED_METHOD move () throw() __TBB_override; - /*override*/ - void __TBB_EXPORTED_METHOD destroy () throw(); + void __TBB_EXPORTED_METHOD destroy () throw() __TBB_override; - /*override*/ - void throw_self () { __TBB_THROW(*this); } + void throw_self () __TBB_override { __TBB_THROW(*this); } - /*override*/ - const char* __TBB_EXPORTED_METHOD name() const throw(); + const char* __TBB_EXPORTED_METHOD name() const throw() __TBB_override; - /*override*/ - const char* __TBB_EXPORTED_METHOD what() const throw(); + const char* __TBB_EXPORTED_METHOD what() const throw() __TBB_override; void __TBB_EXPORTED_METHOD set ( const char* name, const char* info ) throw(); void __TBB_EXPORTED_METHOD clear () throw(); @@ -299,12 +294,11 @@ public: const ExceptionData& data () const throw() { return my_exception_data; } - /*override*/ const char* name () const throw() { return my_exception_name; } + const char* name () const throw() __TBB_override { return my_exception_name; } - /*override*/ const char* what () const throw() { return "tbb::movable_exception"; } + const char* what () const throw() __TBB_override { return "tbb::movable_exception"; } - /*override*/ - movable_exception* move () throw() { + movable_exception* move () throw() __TBB_override { void* e = internal::allocate_via_handler_v3(sizeof(movable_exception)); if ( e ) { ::new (e) movable_exception(*this); @@ -312,16 +306,14 @@ public: } return (movable_exception*)e; } - /*override*/ - void destroy () throw() { + void destroy () throw() __TBB_override { __TBB_ASSERT ( my_dynamic, "Method destroy can be called only on dynamically allocated movable_exceptions" ); if ( my_dynamic ) { this->~movable_exception(); internal::deallocate_via_handler_v3(this); } } - /*override*/ - void throw_self () { __TBB_THROW( *this ); } + void throw_self () __TBB_override { __TBB_THROW( *this ); } protected: //! User data diff --git a/lib/3rdParty/tbb/include/tbb/tbb_machine.h b/lib/3rdParty/tbb/include/tbb/tbb_machine.h index 5fe13bc..68d1d5d 100644 --- a/lib/3rdParty/tbb/include/tbb/tbb_machine.h +++ b/lib/3rdParty/tbb/include/tbb/tbb_machine.h @@ -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 @@ -38,7 +38,7 @@ __TBB_USE_GENERIC_RELAXED_LOAD_STORE __TBB_USE_FETCHSTORE_AS_FULL_FENCED_STORE - In this case tbb_machine.h will add missing functionality based on a minimal set + In this case tbb_machine.h will add missing functionality based on a minimal set of APIs that are required to be implemented by all plug-n headers as described further. Note that these generic implementations may be sub-optimal for a particular @@ -208,10 +208,8 @@ template<> struct atomic_selector<8> { #include "machine/icc_generic.h" #elif defined(_M_IX86) && !defined(__TBB_WIN32_USE_CL_BUILTINS) #include "machine/windows_ia32.h" - #elif defined(_M_X64) + #elif defined(_M_X64) #include "machine/windows_intel64.h" - #elif defined(_XBOX) - #include "machine/xbox360_ppc.h" #elif defined(_M_ARM) || defined(__TBB_WIN32_USE_CL_BUILTINS) #include "machine/msvc_armv7.h" #endif @@ -243,7 +241,7 @@ template<> struct atomic_selector<8> { #include "machine/linux_ia64.h" #elif __powerpc__ #include "machine/mac_ppc.h" - #elif __arm__ + #elif __ARM_ARCH_7A__ #include "machine/gcc_armv7.h" #elif __TBB_GCC_BUILTIN_ATOMICS_PRESENT #include "machine/gcc_generic.h" @@ -751,7 +749,16 @@ inline void __TBB_store_relaxed ( volatile size_t& location, size_t value ) { // strictest alignment is 64. #ifndef __TBB_TypeWithAlignmentAtLeastAsStrict -#if __TBB_ATTRIBUTE_ALIGNED_PRESENT +#if __TBB_ALIGNAS_PRESENT + +// Use C++11 keywords alignas and alignof +#define __TBB_DefineTypeWithAlignment(PowerOf2) \ +struct alignas(PowerOf2) __TBB_machine_type_with_alignment_##PowerOf2 { \ + uint32_t member[PowerOf2/sizeof(uint32_t)]; \ +}; +#define __TBB_alignof(T) alignof(T) + +#elif __TBB_ATTRIBUTE_ALIGNED_PRESENT #define __TBB_DefineTypeWithAlignment(PowerOf2) \ struct __TBB_machine_type_with_alignment_##PowerOf2 { \ @@ -916,7 +923,7 @@ inline __TBB_Flag __TBB_LockByte( __TBB_atomic_flag& flag ) { #define __TBB_UnlockByte(addr) __TBB_store_with_release((addr),0) #endif -// lock primitives with TSX +// lock primitives with Intel(R) Transactional Synchronization Extensions (Intel(R) TSX) #if ( __TBB_x86_32 || __TBB_x86_64 ) /* only on ia32/intel64 */ inline void __TBB_TryLockByteElidedCancel() { __TBB_machine_try_lock_elided_cancel(); } diff --git a/lib/3rdParty/tbb/include/tbb/tbb_profiling.h b/lib/3rdParty/tbb/include/tbb/tbb_profiling.h index 5ef8166..ffaf98b 100644 --- a/lib/3rdParty/tbb/include/tbb/tbb_profiling.h +++ b/lib/3rdParty/tbb/include/tbb/tbb_profiling.h @@ -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_profiling_H diff --git a/lib/3rdParty/tbb/include/tbb/tbb_stddef.h b/lib/3rdParty/tbb/include/tbb/tbb_stddef.h index 944a0d8..236f3d8 100644 --- a/lib/3rdParty/tbb/include/tbb/tbb_stddef.h +++ b/lib/3rdParty/tbb/include/tbb/tbb_stddef.h @@ -1,32 +1,32 @@ /* - 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_stddef_H #define __TBB_tbb_stddef_H // Marketing-driven product version -#define TBB_VERSION_MAJOR 4 -#define TBB_VERSION_MINOR 4 +#define TBB_VERSION_MAJOR 2017 +#define TBB_VERSION_MINOR 0 // Engineering-focused interface version -#define TBB_INTERFACE_VERSION 9003 +#define TBB_INTERFACE_VERSION 9107 #define TBB_INTERFACE_VERSION_MAJOR TBB_INTERFACE_VERSION/1000 // The oldest major interface version still supported @@ -240,6 +240,12 @@ const size_t NFS_MaxLineSize = 128; TODO: apply wherever relevant **/ #define __TBB_atomic // intentionally empty, see above +#if __TBB_OVERRIDE_PRESENT +#define __TBB_override override +#else +#define __TBB_override // formal comment only +#endif + template struct padded_base : T { char pad[S - R]; @@ -528,7 +534,7 @@ struct STATIC_ASSERTION_FAILED; //intentionally left undefined to cause co enum {static_assert_on_line_##line = tbb::internal::STATIC_ASSERTION_FAILED::value} #define __TBB_STATIC_ASSERT_IMPL(condition,msg,line) __TBB_STATIC_ASSERT_IMPL1(condition,msg,line) -//! Verify at compile time that passed in condition is hold +//! Verify condition, at compile time #define __TBB_STATIC_ASSERT(condition,msg) __TBB_STATIC_ASSERT_IMPL(condition,msg,__LINE__) #endif diff --git a/lib/3rdParty/tbb/include/tbb/tbb_thread.h b/lib/3rdParty/tbb/include/tbb/tbb_thread.h index e25351c..d1cafd6 100644 --- a/lib/3rdParty/tbb/include/tbb/tbb_thread.h +++ b/lib/3rdParty/tbb/include/tbb/tbb_thread.h @@ -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_thread_H @@ -53,7 +53,7 @@ namespace tbb { namespace internal { #pragma warning (disable: 4530) #endif -#include //for swap +#include __TBB_STD_SWAP_HEADER #include #if !TBB_USE_EXCEPTIONS && _MSC_VER diff --git a/lib/3rdParty/tbb/include/tbb/tbbmalloc_proxy.h b/lib/3rdParty/tbb/include/tbb/tbbmalloc_proxy.h index e33516c..76cbd6d 100644 --- a/lib/3rdParty/tbb/include/tbb/tbbmalloc_proxy.h +++ b/lib/3rdParty/tbb/include/tbb/tbbmalloc_proxy.h @@ -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. */ /* diff --git a/lib/3rdParty/tbb/include/tbb/tick_count.h b/lib/3rdParty/tbb/include/tbb/tick_count.h index 20ce722..a7f4e0f 100644 --- a/lib/3rdParty/tbb/include/tbb/tick_count.h +++ b/lib/3rdParty/tbb/include/tbb/tick_count.h @@ -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_tick_count_H diff --git a/lib/3rdParty/tbb/index.html b/lib/3rdParty/tbb/index.html index 4e95262..13f29bc 100644 --- a/lib/3rdParty/tbb/index.html +++ b/lib/3rdParty/tbb/index.html @@ -1,7 +1,7 @@

Overview

-Top level directory for Intel® Threading Building Blocks. +Top level directory for Intel® Threading Building Blocks (Intel® TBB).

Common directories

doc @@ -10,6 +10,8 @@ Top level directory for Intel® Threading Building Blocks.
Include files required for compiling code that uses the library.
examples
Examples of how to use the library. +
python +
Python* API for Intel TBB.

Intel TBB source package

@@ -25,20 +27,20 @@ To port Intel TBB to a new platform, operating system or architecture, see the <

src
Source code for the library. -
build -
Internal Makefile infrastructure for Intel TBB. Do not use directly; see the build directions. +
build, jni +
Internal Makefile infrastructure for Intel TBB. Do not use directly; see the build directions.

Intel TBB binary package

Directories

bin -
Start-up scripts for sourcing library for Linux* OS and OS X*. For Windows* OS: start-up scripts and dynamic-link libraries. +
Start-up scripts for sourcing library for Linux* OS and macOS*. For Windows* OS: start-up scripts and dynamic-link libraries.
lib
Platform-specific binary files for the library.

-Copyright © 2005-2016 Intel Corporation. All Rights Reserved. +Copyright © 2005-2017 Intel Corporation. All Rights Reserved.

Intel is a registered trademark or trademark of Intel Corporation or its subsidiaries in the United States and other countries. diff --git a/lib/3rdParty/tbb/lib/x64/v140/tbb.def b/lib/3rdParty/tbb/lib/x64/v140/tbb.def index 92dd1ea..62145ca 100644 --- a/lib/3rdParty/tbb/lib/x64/v140/tbb.def +++ b/lib/3rdParty/tbb/lib/x64/v140/tbb.def @@ -1,21 +1,21 @@ +; 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. +; +; +; +; -; Copyright 2005-2016 Intel Corporation. All Rights Reserved. -; -; The source code contained or described herein and all documents related -; to the source code ("Material") are owned by Intel Corporation or its -; suppliers or licensors. Title to the Material remains with Intel -; Corporation or its suppliers and licensors. The Material is protected -; by worldwide copyright laws and treaty provisions. No part of the -; Material may be used, copied, reproduced, modified, published, uploaded, -; posted, transmitted, distributed, or disclosed in any way without -; Intel's prior express written permission. -; -; No license under any patent, copyright, trade secret or other -; intellectual property right is granted to or conferred upon you by -; disclosure or delivery of the Materials, either expressly, by -; implication, inducement, estoppel or otherwise. Any license under such -; intellectual property rights must be express and approved by Intel in -; writing. ; This file is organized with a section for each .cpp file. ; Each of these sections is in alphabetical order. @@ -24,23 +24,43 @@ EXPORTS -; Copyright 2005-2016 Intel Corporation. All Rights Reserved. -; -; The source code contained or described herein and all documents related -; to the source code ("Material") are owned by Intel Corporation or its -; suppliers or licensors. Title to the Material remains with Intel -; Corporation or its suppliers and licensors. The Material is protected -; by worldwide copyright laws and treaty provisions. No part of the -; Material may be used, copied, reproduced, modified, published, uploaded, -; posted, transmitted, distributed, or disclosed in any way without -; Intel's prior express written permission. -; -; No license under any patent, copyright, trade secret or other -; intellectual property right is granted to or conferred upon you by -; disclosure or delivery of the Materials, either expressly, by -; implication, inducement, estoppel or otherwise. Any license under such -; intellectual property rights must be express and approved by Intel in -; writing. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -255,6 +275,14 @@ EXPORTS + + + + + + + + @@ -314,6 +342,22 @@ EXPORTS + + + + + + + + + + + + + + + + @@ -372,6 +416,27 @@ EXPORTS + + + + + + + + + + + + + + + + + + + + + @@ -462,13 +527,9 @@ EXPORTS - - - - @@ -594,7 +655,6 @@ EXPORTS - @@ -612,10 +672,6 @@ EXPORTS - - - - @@ -655,43 +711,6 @@ EXPORTS - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -729,6 +748,44 @@ EXPORTS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -791,12 +848,13 @@ __TBB_machine_is_in_transaction ?initialize@task_scheduler_init@tbb@@QEAAXH_K@Z ?initialize@task_scheduler_init@tbb@@QEAAXH@Z ?terminate@task_scheduler_init@tbb@@QEAAXXZ +?internal_blocking_terminate@task_scheduler_init@tbb@@AEAA_N_N@Z ?observe@task_scheduler_observer_v3@internal@tbb@@QEAAX_N@Z - +?internal_max_concurrency@task_arena_base@internal@interface7@tbb@@KAHPEBVtask_arena@34@@Z ?internal_current_slot@task_arena_base@internal@interface7@tbb@@KAHXZ ?internal_initialize@task_arena_base@internal@interface7@tbb@@IEAAXXZ ?internal_terminate@task_arena_base@internal@interface7@tbb@@IEAAXXZ @@ -808,6 +866,7 @@ __TBB_machine_is_in_transaction + ?destroy@task@tbb@@QEAAXAEAV12@@Z diff --git a/lib/3rdParty/tbb/lib/x64/v140/tbb.lib b/lib/3rdParty/tbb/lib/x64/v140/tbb.lib index 0e242a2..7db38e1 100644 Binary files a/lib/3rdParty/tbb/lib/x64/v140/tbb.lib and b/lib/3rdParty/tbb/lib/x64/v140/tbb.lib differ diff --git a/lib/3rdParty/tbb/lib/x64/v140/tbb_debug.lib b/lib/3rdParty/tbb/lib/x64/v140/tbb_debug.lib index 19d8e52..0573414 100644 Binary files a/lib/3rdParty/tbb/lib/x64/v140/tbb_debug.lib and b/lib/3rdParty/tbb/lib/x64/v140/tbb_debug.lib differ diff --git a/lib/3rdParty/tbb/lib/x64/v140/tbb_preview.lib b/lib/3rdParty/tbb/lib/x64/v140/tbb_preview.lib index 0d6678f..f3b8e82 100644 Binary files a/lib/3rdParty/tbb/lib/x64/v140/tbb_preview.lib and b/lib/3rdParty/tbb/lib/x64/v140/tbb_preview.lib differ diff --git a/lib/3rdParty/tbb/lib/x64/v140/tbbmalloc.def b/lib/3rdParty/tbb/lib/x64/v140/tbbmalloc.def index 2a9f814..9a99833 100644 --- a/lib/3rdParty/tbb/lib/x64/v140/tbbmalloc.def +++ b/lib/3rdParty/tbb/lib/x64/v140/tbbmalloc.def @@ -1,21 +1,21 @@ +; 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. +; +; +; +; -; Copyright 2005-2016 Intel Corporation. All Rights Reserved. -; -; The source code contained or described herein and all documents related -; to the source code ("Material") are owned by Intel Corporation or its -; suppliers or licensors. Title to the Material remains with Intel -; Corporation or its suppliers and licensors. The Material is protected -; by worldwide copyright laws and treaty provisions. No part of the -; Material may be used, copied, reproduced, modified, published, uploaded, -; posted, transmitted, distributed, or disclosed in any way without -; Intel's prior express written permission. -; -; No license under any patent, copyright, trade secret or other -; intellectual property right is granted to or conferred upon you by -; disclosure or delivery of the Materials, either expressly, by -; implication, inducement, estoppel or otherwise. Any license under such -; intellectual property rights must be express and approved by Intel in -; writing. EXPORTS diff --git a/lib/3rdParty/tbb/lib/x64/v140/tbbmalloc.lib b/lib/3rdParty/tbb/lib/x64/v140/tbbmalloc.lib index c070c23..fb67b97 100644 Binary files a/lib/3rdParty/tbb/lib/x64/v140/tbbmalloc.lib and b/lib/3rdParty/tbb/lib/x64/v140/tbbmalloc.lib differ diff --git a/lib/3rdParty/tbb/lib/x64/v140/tbbmalloc_proxy.lib b/lib/3rdParty/tbb/lib/x64/v140/tbbmalloc_proxy.lib index 1ae2540..45c14df 100644 Binary files a/lib/3rdParty/tbb/lib/x64/v140/tbbmalloc_proxy.lib and b/lib/3rdParty/tbb/lib/x64/v140/tbbmalloc_proxy.lib differ diff --git a/lib/3rdParty/tbb/lib/x64/v140/tbbproxy.lib b/lib/3rdParty/tbb/lib/x64/v140/tbbproxy.lib index de44641..0d3d0e4 100644 Binary files a/lib/3rdParty/tbb/lib/x64/v140/tbbproxy.lib and b/lib/3rdParty/tbb/lib/x64/v140/tbbproxy.lib differ diff --git a/lib/3rdParty/tbb/lib/x86/v140/tbb.def b/lib/3rdParty/tbb/lib/x86/v140/tbb.def index 93e99de..395056c 100644 --- a/lib/3rdParty/tbb/lib/x86/v140/tbb.def +++ b/lib/3rdParty/tbb/lib/x86/v140/tbb.def @@ -1,21 +1,21 @@ +; 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. +; +; +; +; -; Copyright 2005-2016 Intel Corporation. All Rights Reserved. -; -; The source code contained or described herein and all documents related -; to the source code ("Material") are owned by Intel Corporation or its -; suppliers or licensors. Title to the Material remains with Intel -; Corporation or its suppliers and licensors. The Material is protected -; by worldwide copyright laws and treaty provisions. No part of the -; Material may be used, copied, reproduced, modified, published, uploaded, -; posted, transmitted, distributed, or disclosed in any way without -; Intel's prior express written permission. -; -; No license under any patent, copyright, trade secret or other -; intellectual property right is granted to or conferred upon you by -; disclosure or delivery of the Materials, either expressly, by -; implication, inducement, estoppel or otherwise. Any license under such -; intellectual property rights must be express and approved by Intel in -; writing. EXPORTS @@ -24,23 +24,43 @@ EXPORTS -; Copyright 2005-2016 Intel Corporation. All Rights Reserved. -; -; The source code contained or described herein and all documents related -; to the source code ("Material") are owned by Intel Corporation or its -; suppliers or licensors. Title to the Material remains with Intel -; Corporation or its suppliers and licensors. The Material is protected -; by worldwide copyright laws and treaty provisions. No part of the -; Material may be used, copied, reproduced, modified, published, uploaded, -; posted, transmitted, distributed, or disclosed in any way without -; Intel's prior express written permission. -; -; No license under any patent, copyright, trade secret or other -; intellectual property right is granted to or conferred upon you by -; disclosure or delivery of the Materials, either expressly, by -; implication, inducement, estoppel or otherwise. Any license under such -; intellectual property rights must be express and approved by Intel in -; writing. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -252,6 +272,14 @@ EXPORTS + + + + + + + + @@ -311,6 +339,22 @@ EXPORTS + + + + + + + + + + + + + + + + @@ -369,6 +413,27 @@ EXPORTS + + + + + + + + + + + + + + + + + + + + + @@ -459,13 +524,9 @@ EXPORTS - - - - @@ -591,7 +652,6 @@ EXPORTS - @@ -609,10 +669,6 @@ EXPORTS - - - - @@ -652,43 +708,6 @@ EXPORTS - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -729,6 +748,44 @@ EXPORTS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -795,12 +852,13 @@ __TBB_machine_is_in_transaction ?initialize@task_scheduler_init@tbb@@QAEXHI@Z ?initialize@task_scheduler_init@tbb@@QAEXH@Z ?terminate@task_scheduler_init@tbb@@QAEXXZ +?internal_blocking_terminate@task_scheduler_init@tbb@@AAE_N_N@Z ?observe@task_scheduler_observer_v3@internal@tbb@@QAEX_N@Z - +?internal_max_concurrency@task_arena_base@internal@interface7@tbb@@KAHPBVtask_arena@34@@Z ?internal_current_slot@task_arena_base@internal@interface7@tbb@@KAHXZ ?internal_initialize@task_arena_base@internal@interface7@tbb@@IAEXXZ ?internal_terminate@task_arena_base@internal@interface7@tbb@@IAEXXZ @@ -812,6 +870,8 @@ __TBB_machine_is_in_transaction + + ?destroy@task@tbb@@QAEXAAV12@@Z diff --git a/lib/3rdParty/tbb/lib/x86/v140/tbb.lib b/lib/3rdParty/tbb/lib/x86/v140/tbb.lib index e357aab..07aca34 100644 Binary files a/lib/3rdParty/tbb/lib/x86/v140/tbb.lib and b/lib/3rdParty/tbb/lib/x86/v140/tbb.lib differ diff --git a/lib/3rdParty/tbb/lib/x86/v140/tbb_debug.lib b/lib/3rdParty/tbb/lib/x86/v140/tbb_debug.lib index 417605d..1dee678 100644 Binary files a/lib/3rdParty/tbb/lib/x86/v140/tbb_debug.lib and b/lib/3rdParty/tbb/lib/x86/v140/tbb_debug.lib differ diff --git a/lib/3rdParty/tbb/lib/x86/v140/tbb_preview.lib b/lib/3rdParty/tbb/lib/x86/v140/tbb_preview.lib index 5ec7e13..da1cfbf 100644 Binary files a/lib/3rdParty/tbb/lib/x86/v140/tbb_preview.lib and b/lib/3rdParty/tbb/lib/x86/v140/tbb_preview.lib differ diff --git a/lib/3rdParty/tbb/lib/x86/v140/tbbmalloc.def b/lib/3rdParty/tbb/lib/x86/v140/tbbmalloc.def index bc1cf77..ac00e3f 100644 --- a/lib/3rdParty/tbb/lib/x86/v140/tbbmalloc.def +++ b/lib/3rdParty/tbb/lib/x86/v140/tbbmalloc.def @@ -1,21 +1,21 @@ +; 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. +; +; +; +; -; Copyright 2005-2016 Intel Corporation. All Rights Reserved. -; -; The source code contained or described herein and all documents related -; to the source code ("Material") are owned by Intel Corporation or its -; suppliers or licensors. Title to the Material remains with Intel -; Corporation or its suppliers and licensors. The Material is protected -; by worldwide copyright laws and treaty provisions. No part of the -; Material may be used, copied, reproduced, modified, published, uploaded, -; posted, transmitted, distributed, or disclosed in any way without -; Intel's prior express written permission. -; -; No license under any patent, copyright, trade secret or other -; intellectual property right is granted to or conferred upon you by -; disclosure or delivery of the Materials, either expressly, by -; implication, inducement, estoppel or otherwise. Any license under such -; intellectual property rights must be express and approved by Intel in -; writing. EXPORTS diff --git a/lib/3rdParty/tbb/lib/x86/v140/tbbmalloc.lib b/lib/3rdParty/tbb/lib/x86/v140/tbbmalloc.lib index c8946ad..d293df9 100644 Binary files a/lib/3rdParty/tbb/lib/x86/v140/tbbmalloc.lib and b/lib/3rdParty/tbb/lib/x86/v140/tbbmalloc.lib differ diff --git a/lib/3rdParty/tbb/lib/x86/v140/tbbmalloc_proxy.lib b/lib/3rdParty/tbb/lib/x86/v140/tbbmalloc_proxy.lib index d6de2f3..e76e38e 100644 Binary files a/lib/3rdParty/tbb/lib/x86/v140/tbbmalloc_proxy.lib and b/lib/3rdParty/tbb/lib/x86/v140/tbbmalloc_proxy.lib differ diff --git a/lib/3rdParty/tbb/lib/x86/v140/tbbproxy.lib b/lib/3rdParty/tbb/lib/x86/v140/tbbproxy.lib index 356ff59..bb6c5da 100644 Binary files a/lib/3rdParty/tbb/lib/x86/v140/tbbproxy.lib and b/lib/3rdParty/tbb/lib/x86/v140/tbbproxy.lib differ