From 77eae167322a82153e81535015e415591fe56f9e Mon Sep 17 00:00:00 2001 From: Tadas Baltrusaitis Date: Sat, 20 Oct 2018 10:45:35 +0100 Subject: [PATCH] Removing TBB dependency (#590) Removing a TBB dependence for code parallelization (done through OpenCV's parralel_for_ --- .travis.yml | 3 +- CMakeLists.txt | 19 - README.md | 2 +- appveyor.yml | 1 + exe/FaceLandmarkImg/FaceLandmarkImg.cpp | 2 - exe/FaceLandmarkImg/FaceLandmarkImg.vcxproj | 4 - exe/FaceLandmarkVid/FaceLandmarkVid.vcxproj | 4 - .../FaceLandmarkVidMulti.cpp | 12 +- .../FaceLandmarkVidMulti.vcxproj | 4 - .../FeatureExtraction.vcxproj | 4 - lib/3rdParty/tbb/CHANGES | 2359 ---------- lib/3rdParty/tbb/LICENSE | 201 - lib/3rdParty/tbb/README | 11 - lib/3rdParty/tbb/bin/x64/v140/irml/irml.dll | Bin 79600 -> 0 bytes .../tbb/bin/x64/v140/irml/irml_debug.dll | Bin 138992 -> 0 bytes lib/3rdParty/tbb/bin/x64/v140/tbb.dll | Bin 261392 -> 0 bytes lib/3rdParty/tbb/bin/x64/v140/tbb_debug.dll | Bin 478992 -> 0 bytes lib/3rdParty/tbb/bin/x64/v140/tbb_preview.dll | Bin 268560 -> 0 bytes lib/3rdParty/tbb/bin/x64/v140/tbbmalloc.dll | Bin 126224 -> 0 bytes .../tbb/bin/x64/v140/tbbmalloc_proxy.dll | Bin 42768 -> 0 bytes lib/3rdParty/tbb/bin/x86/v140/irml/irml.dll | Bin 62704 -> 0 bytes .../tbb/bin/x86/v140/irml/irml_debug.dll | Bin 104688 -> 0 bytes lib/3rdParty/tbb/bin/x86/v140/tbb.dll | Bin 200976 -> 0 bytes lib/3rdParty/tbb/bin/x86/v140/tbb_debug.dll | Bin 375568 -> 0 bytes lib/3rdParty/tbb/bin/x86/v140/tbb_preview.dll | Bin 205584 -> 0 bytes lib/3rdParty/tbb/bin/x86/v140/tbbmalloc.dll | Bin 87312 -> 0 bytes .../tbb/bin/x86/v140/tbbmalloc_proxy.dll | Bin 35088 -> 0 bytes lib/3rdParty/tbb/include/index.html | 25 - .../tbb/include/serial/tbb/parallel_for.h | 219 - .../tbb/include/serial/tbb/tbb_annotate.h | 36 - lib/3rdParty/tbb/include/tbb/aggregator.h | 202 - lib/3rdParty/tbb/include/tbb/aligned_space.h | 47 - lib/3rdParty/tbb/include/tbb/atomic.h | 558 --- lib/3rdParty/tbb/include/tbb/blocked_range.h | 159 - .../tbb/include/tbb/blocked_range2d.h | 108 - .../tbb/include/tbb/blocked_range3d.h | 128 - .../tbb/include/tbb/cache_aligned_allocator.h | 137 - lib/3rdParty/tbb/include/tbb/combinable.h | 85 - .../tbb/include/tbb/compat/condition_variable | 476 -- lib/3rdParty/tbb/include/tbb/compat/ppl.h | 62 - lib/3rdParty/tbb/include/tbb/compat/thread | 60 - lib/3rdParty/tbb/include/tbb/compat/tuple | 488 -- .../tbb/include/tbb/concurrent_hash_map.h | 1510 ------ .../tbb/include/tbb/concurrent_lru_cache.h | 235 - .../include/tbb/concurrent_priority_queue.h | 490 -- .../tbb/include/tbb/concurrent_queue.h | 458 -- .../include/tbb/concurrent_unordered_map.h | 299 -- .../include/tbb/concurrent_unordered_set.h | 256 -- .../tbb/include/tbb/concurrent_vector.h | 1374 ------ .../tbb/include/tbb/critical_section.h | 133 - .../include/tbb/enumerable_thread_specific.h | 1137 ----- lib/3rdParty/tbb/include/tbb/flow_graph.h | 4075 ----------------- .../tbb/include/tbb/flow_graph_abstractions.h | 57 - .../tbb/include/tbb/flow_graph_opencl_node.h | 1537 ------- lib/3rdParty/tbb/include/tbb/gfx_factory.h | 359 -- lib/3rdParty/tbb/include/tbb/global_control.h | 86 - lib/3rdParty/tbb/include/tbb/index.html | 29 - .../include/tbb/internal/_aggregator_impl.h | 184 - .../tbb/internal/_concurrent_queue_impl.h | 1086 ----- .../tbb/internal/_concurrent_unordered_impl.h | 1528 ------ .../tbb/internal/_flow_graph_async_msg_impl.h | 221 - .../include/tbb/internal/_flow_graph_impl.h | 839 ---- .../tbb/internal/_flow_graph_indexer_impl.h | 478 -- .../internal/_flow_graph_item_buffer_impl.h | 288 -- .../tbb/internal/_flow_graph_join_impl.h | 1991 -------- .../tbb/internal/_flow_graph_node_impl.h | 798 ---- .../tbb/internal/_flow_graph_streaming_node.h | 745 --- .../internal/_flow_graph_tagged_buffer_impl.h | 253 - .../tbb/internal/_flow_graph_trace_impl.h | 238 - .../tbb/internal/_flow_graph_types_impl.h | 713 --- .../tbb/include/tbb/internal/_mutex_padding.h | 102 - .../include/tbb/internal/_range_iterator.h | 70 - .../tbb/internal/_tbb_hash_compare_impl.h | 109 - .../tbb/include/tbb/internal/_tbb_strings.h | 67 - .../tbb/include/tbb/internal/_tbb_windef.h | 73 - .../include/tbb/internal/_template_helpers.h | 158 - .../tbb/internal/_x86_eliding_mutex_impl.h | 148 - .../tbb/internal/_x86_rtm_rw_mutex_impl.h | 225 - .../tbb/include/tbb/machine/gcc_armv7.h | 217 - .../tbb/include/tbb/machine/gcc_generic.h | 184 - .../tbb/include/tbb/machine/gcc_ia32_common.h | 112 - .../tbb/include/tbb/machine/gcc_itsx.h | 123 - .../tbb/include/tbb/machine/ibm_aix51.h | 70 - .../tbb/include/tbb/machine/icc_generic.h | 262 -- .../tbb/include/tbb/machine/linux_common.h | 84 - .../tbb/include/tbb/machine/linux_ia32.h | 232 - .../tbb/include/tbb/machine/linux_ia64.h | 181 - .../tbb/include/tbb/machine/linux_intel64.h | 96 - .../tbb/include/tbb/machine/mac_ppc.h | 313 -- .../tbb/include/tbb/machine/macos_common.h | 133 - .../tbb/include/tbb/machine/mic_common.h | 57 - .../tbb/include/tbb/machine/msvc_armv7.h | 171 - .../include/tbb/machine/msvc_ia32_common.h | 280 -- .../tbb/include/tbb/machine/sunos_sparc.h | 203 - .../tbb/include/tbb/machine/windows_api.h | 69 - .../tbb/include/tbb/machine/windows_ia32.h | 109 - .../tbb/include/tbb/machine/windows_intel64.h | 74 - lib/3rdParty/tbb/include/tbb/memory_pool.h | 279 -- lib/3rdParty/tbb/include/tbb/mutex.h | 233 - lib/3rdParty/tbb/include/tbb/null_mutex.h | 54 - lib/3rdParty/tbb/include/tbb/null_rw_mutex.h | 56 - lib/3rdParty/tbb/include/tbb/parallel_do.h | 551 --- lib/3rdParty/tbb/include/tbb/parallel_for.h | 407 -- .../tbb/include/tbb/parallel_for_each.h | 137 - .../tbb/include/tbb/parallel_invoke.h | 455 -- .../tbb/include/tbb/parallel_reduce.h | 569 --- lib/3rdParty/tbb/include/tbb/parallel_scan.h | 348 -- lib/3rdParty/tbb/include/tbb/parallel_sort.h | 266 -- lib/3rdParty/tbb/include/tbb/parallel_while.h | 186 - lib/3rdParty/tbb/include/tbb/partitioner.h | 681 --- lib/3rdParty/tbb/include/tbb/pipeline.h | 665 --- lib/3rdParty/tbb/include/tbb/queuing_mutex.h | 123 - .../tbb/include/tbb/queuing_rw_mutex.h | 163 - .../tbb/include/tbb/reader_writer_lock.h | 232 - .../tbb/include/tbb/recursive_mutex.h | 234 - lib/3rdParty/tbb/include/tbb/runtime_loader.h | 180 - .../tbb/include/tbb/scalable_allocator.h | 341 -- lib/3rdParty/tbb/include/tbb/spin_mutex.h | 212 - lib/3rdParty/tbb/include/tbb/spin_rw_mutex.h | 259 -- lib/3rdParty/tbb/include/tbb/task.h | 1050 ----- lib/3rdParty/tbb/include/tbb/task_arena.h | 333 -- lib/3rdParty/tbb/include/tbb/task_group.h | 223 - .../tbb/include/tbb/task_scheduler_init.h | 161 - .../tbb/include/tbb/task_scheduler_observer.h | 174 - lib/3rdParty/tbb/include/tbb/tbb.h | 85 - lib/3rdParty/tbb/include/tbb/tbb_allocator.h | 218 - lib/3rdParty/tbb/include/tbb/tbb_config.h | 779 ---- lib/3rdParty/tbb/include/tbb/tbb_exception.h | 371 -- lib/3rdParty/tbb/include/tbb/tbb_machine.h | 974 ---- lib/3rdParty/tbb/include/tbb/tbb_profiling.h | 284 -- lib/3rdParty/tbb/include/tbb/tbb_stddef.h | 542 --- lib/3rdParty/tbb/include/tbb/tbb_thread.h | 342 -- .../tbb/include/tbb/tbbmalloc_proxy.h | 66 - lib/3rdParty/tbb/include/tbb/tick_count.h | 140 - lib/3rdParty/tbb/index.html | 50 - lib/3rdParty/tbb/lib/x64/v140/irml/irml.lib | Bin 2934 -> 0 bytes .../tbb/lib/x64/v140/irml/irml_debug.lib | Bin 3036 -> 0 bytes lib/3rdParty/tbb/lib/x64/v140/tbb.def | 1126 ----- lib/3rdParty/tbb/lib/x64/v140/tbb.lib | Bin 96548 -> 0 bytes lib/3rdParty/tbb/lib/x64/v140/tbb_debug.lib | Bin 98000 -> 0 bytes lib/3rdParty/tbb/lib/x64/v140/tbb_preview.lib | Bin 102718 -> 0 bytes lib/3rdParty/tbb/lib/x64/v140/tbbmalloc.def | 49 - lib/3rdParty/tbb/lib/x64/v140/tbbmalloc.lib | Bin 9268 -> 0 bytes .../tbb/lib/x64/v140/tbbmalloc_proxy.lib | Bin 1928 -> 0 bytes lib/3rdParty/tbb/lib/x64/v140/tbbproxy.lib | Bin 275858 -> 0 bytes lib/3rdParty/tbb/lib/x86/v140/irml/irml.lib | Bin 2956 -> 0 bytes .../tbb/lib/x86/v140/irml/irml_debug.lib | Bin 3058 -> 0 bytes lib/3rdParty/tbb/lib/x86/v140/tbb.def | 1133 ----- lib/3rdParty/tbb/lib/x86/v140/tbb.lib | Bin 94556 -> 0 bytes lib/3rdParty/tbb/lib/x86/v140/tbb_debug.lib | Bin 96002 -> 0 bytes lib/3rdParty/tbb/lib/x86/v140/tbb_preview.lib | Bin 100676 -> 0 bytes lib/3rdParty/tbb/lib/x86/v140/tbbmalloc.def | 48 - lib/3rdParty/tbb/lib/x86/v140/tbbmalloc.lib | Bin 9204 -> 0 bytes .../tbb/lib/x86/v140/tbbmalloc_proxy.lib | Bin 1924 -> 0 bytes lib/3rdParty/tbb/lib/x86/v140/tbbproxy.lib | Bin 261956 -> 0 bytes lib/3rdParty/tbb/tbb.props | 19 - lib/3rdParty/tbb/tbb_d.props | 19 - lib/local/CppInerop/CppInerop.vcxproj | 4 - lib/local/FaceAnalyser/CMakeLists.txt | 3 +- lib/local/FaceAnalyser/FaceAnalyser.vcxproj | 4 - lib/local/GazeAnalyser/CMakeLists.txt | 3 +- lib/local/GazeAnalyser/GazeAnalyser.vcxproj | 4 - lib/local/LandmarkDetector/CMakeLists.txt | 3 +- .../LandmarkDetector/LandmarkDetector.vcxproj | 4 - .../src/FaceDetectorMTCNN.cpp | 8 +- .../src/LandmarkDetectionValidator.cpp | 3 - .../src/LandmarkDetectorModel.cpp | 71 +- .../LandmarkDetector/src/Patch_experts.cpp | 221 +- lib/local/Utilities/CMakeLists.txt | 3 +- lib/local/Utilities/Utilities.vcxproj | 5 +- lib/local/Utilities/Utilities.vcxproj.filters | 3 + lib/local/Utilities/include/ConcurrentQueue.h | 101 + .../Utilities/include/RecorderOpenFace.h | 23 +- lib/local/Utilities/include/SequenceCapture.h | 15 +- lib/local/Utilities/src/RecorderOpenFace.cpp | 32 +- lib/local/Utilities/src/SequenceCapture.cpp | 26 +- 176 files changed, 301 insertions(+), 45787 deletions(-) delete mode 100644 lib/3rdParty/tbb/CHANGES delete mode 100644 lib/3rdParty/tbb/LICENSE delete mode 100644 lib/3rdParty/tbb/README delete mode 100644 lib/3rdParty/tbb/bin/x64/v140/irml/irml.dll delete mode 100644 lib/3rdParty/tbb/bin/x64/v140/irml/irml_debug.dll delete mode 100644 lib/3rdParty/tbb/bin/x64/v140/tbb.dll delete mode 100644 lib/3rdParty/tbb/bin/x64/v140/tbb_debug.dll delete mode 100644 lib/3rdParty/tbb/bin/x64/v140/tbb_preview.dll delete mode 100644 lib/3rdParty/tbb/bin/x64/v140/tbbmalloc.dll delete mode 100644 lib/3rdParty/tbb/bin/x64/v140/tbbmalloc_proxy.dll delete mode 100644 lib/3rdParty/tbb/bin/x86/v140/irml/irml.dll delete mode 100644 lib/3rdParty/tbb/bin/x86/v140/irml/irml_debug.dll delete mode 100644 lib/3rdParty/tbb/bin/x86/v140/tbb.dll delete mode 100644 lib/3rdParty/tbb/bin/x86/v140/tbb_debug.dll delete mode 100644 lib/3rdParty/tbb/bin/x86/v140/tbb_preview.dll delete mode 100644 lib/3rdParty/tbb/bin/x86/v140/tbbmalloc.dll delete mode 100644 lib/3rdParty/tbb/bin/x86/v140/tbbmalloc_proxy.dll delete mode 100644 lib/3rdParty/tbb/include/index.html delete mode 100644 lib/3rdParty/tbb/include/serial/tbb/parallel_for.h delete mode 100644 lib/3rdParty/tbb/include/serial/tbb/tbb_annotate.h delete mode 100644 lib/3rdParty/tbb/include/tbb/aggregator.h delete mode 100644 lib/3rdParty/tbb/include/tbb/aligned_space.h delete mode 100644 lib/3rdParty/tbb/include/tbb/atomic.h delete mode 100644 lib/3rdParty/tbb/include/tbb/blocked_range.h delete mode 100644 lib/3rdParty/tbb/include/tbb/blocked_range2d.h delete mode 100644 lib/3rdParty/tbb/include/tbb/blocked_range3d.h delete mode 100644 lib/3rdParty/tbb/include/tbb/cache_aligned_allocator.h delete mode 100644 lib/3rdParty/tbb/include/tbb/combinable.h delete mode 100644 lib/3rdParty/tbb/include/tbb/compat/condition_variable delete mode 100644 lib/3rdParty/tbb/include/tbb/compat/ppl.h delete mode 100644 lib/3rdParty/tbb/include/tbb/compat/thread delete mode 100644 lib/3rdParty/tbb/include/tbb/compat/tuple delete mode 100644 lib/3rdParty/tbb/include/tbb/concurrent_hash_map.h delete mode 100644 lib/3rdParty/tbb/include/tbb/concurrent_lru_cache.h delete mode 100644 lib/3rdParty/tbb/include/tbb/concurrent_priority_queue.h delete mode 100644 lib/3rdParty/tbb/include/tbb/concurrent_queue.h delete mode 100644 lib/3rdParty/tbb/include/tbb/concurrent_unordered_map.h delete mode 100644 lib/3rdParty/tbb/include/tbb/concurrent_unordered_set.h delete mode 100644 lib/3rdParty/tbb/include/tbb/concurrent_vector.h delete mode 100644 lib/3rdParty/tbb/include/tbb/critical_section.h delete mode 100644 lib/3rdParty/tbb/include/tbb/enumerable_thread_specific.h delete mode 100644 lib/3rdParty/tbb/include/tbb/flow_graph.h delete mode 100644 lib/3rdParty/tbb/include/tbb/flow_graph_abstractions.h delete mode 100644 lib/3rdParty/tbb/include/tbb/flow_graph_opencl_node.h delete mode 100644 lib/3rdParty/tbb/include/tbb/gfx_factory.h delete mode 100644 lib/3rdParty/tbb/include/tbb/global_control.h delete mode 100644 lib/3rdParty/tbb/include/tbb/index.html delete mode 100644 lib/3rdParty/tbb/include/tbb/internal/_aggregator_impl.h delete mode 100644 lib/3rdParty/tbb/include/tbb/internal/_concurrent_queue_impl.h delete mode 100644 lib/3rdParty/tbb/include/tbb/internal/_concurrent_unordered_impl.h delete mode 100644 lib/3rdParty/tbb/include/tbb/internal/_flow_graph_async_msg_impl.h delete mode 100644 lib/3rdParty/tbb/include/tbb/internal/_flow_graph_impl.h delete mode 100644 lib/3rdParty/tbb/include/tbb/internal/_flow_graph_indexer_impl.h delete mode 100644 lib/3rdParty/tbb/include/tbb/internal/_flow_graph_item_buffer_impl.h delete mode 100644 lib/3rdParty/tbb/include/tbb/internal/_flow_graph_join_impl.h delete mode 100644 lib/3rdParty/tbb/include/tbb/internal/_flow_graph_node_impl.h delete mode 100644 lib/3rdParty/tbb/include/tbb/internal/_flow_graph_streaming_node.h delete mode 100644 lib/3rdParty/tbb/include/tbb/internal/_flow_graph_tagged_buffer_impl.h delete mode 100644 lib/3rdParty/tbb/include/tbb/internal/_flow_graph_trace_impl.h delete mode 100644 lib/3rdParty/tbb/include/tbb/internal/_flow_graph_types_impl.h delete mode 100644 lib/3rdParty/tbb/include/tbb/internal/_mutex_padding.h delete mode 100644 lib/3rdParty/tbb/include/tbb/internal/_range_iterator.h delete mode 100644 lib/3rdParty/tbb/include/tbb/internal/_tbb_hash_compare_impl.h delete mode 100644 lib/3rdParty/tbb/include/tbb/internal/_tbb_strings.h delete mode 100644 lib/3rdParty/tbb/include/tbb/internal/_tbb_windef.h delete mode 100644 lib/3rdParty/tbb/include/tbb/internal/_template_helpers.h delete mode 100644 lib/3rdParty/tbb/include/tbb/internal/_x86_eliding_mutex_impl.h delete mode 100644 lib/3rdParty/tbb/include/tbb/internal/_x86_rtm_rw_mutex_impl.h delete mode 100644 lib/3rdParty/tbb/include/tbb/machine/gcc_armv7.h delete mode 100644 lib/3rdParty/tbb/include/tbb/machine/gcc_generic.h delete mode 100644 lib/3rdParty/tbb/include/tbb/machine/gcc_ia32_common.h delete mode 100644 lib/3rdParty/tbb/include/tbb/machine/gcc_itsx.h delete mode 100644 lib/3rdParty/tbb/include/tbb/machine/ibm_aix51.h delete mode 100644 lib/3rdParty/tbb/include/tbb/machine/icc_generic.h delete mode 100644 lib/3rdParty/tbb/include/tbb/machine/linux_common.h delete mode 100644 lib/3rdParty/tbb/include/tbb/machine/linux_ia32.h delete mode 100644 lib/3rdParty/tbb/include/tbb/machine/linux_ia64.h delete mode 100644 lib/3rdParty/tbb/include/tbb/machine/linux_intel64.h delete mode 100644 lib/3rdParty/tbb/include/tbb/machine/mac_ppc.h delete mode 100644 lib/3rdParty/tbb/include/tbb/machine/macos_common.h delete mode 100644 lib/3rdParty/tbb/include/tbb/machine/mic_common.h delete mode 100644 lib/3rdParty/tbb/include/tbb/machine/msvc_armv7.h delete mode 100644 lib/3rdParty/tbb/include/tbb/machine/msvc_ia32_common.h delete mode 100644 lib/3rdParty/tbb/include/tbb/machine/sunos_sparc.h delete mode 100644 lib/3rdParty/tbb/include/tbb/machine/windows_api.h delete mode 100644 lib/3rdParty/tbb/include/tbb/machine/windows_ia32.h delete mode 100644 lib/3rdParty/tbb/include/tbb/machine/windows_intel64.h delete mode 100644 lib/3rdParty/tbb/include/tbb/memory_pool.h delete mode 100644 lib/3rdParty/tbb/include/tbb/mutex.h delete mode 100644 lib/3rdParty/tbb/include/tbb/null_mutex.h delete mode 100644 lib/3rdParty/tbb/include/tbb/null_rw_mutex.h delete mode 100644 lib/3rdParty/tbb/include/tbb/parallel_do.h delete mode 100644 lib/3rdParty/tbb/include/tbb/parallel_for.h delete mode 100644 lib/3rdParty/tbb/include/tbb/parallel_for_each.h delete mode 100644 lib/3rdParty/tbb/include/tbb/parallel_invoke.h delete mode 100644 lib/3rdParty/tbb/include/tbb/parallel_reduce.h delete mode 100644 lib/3rdParty/tbb/include/tbb/parallel_scan.h delete mode 100644 lib/3rdParty/tbb/include/tbb/parallel_sort.h delete mode 100644 lib/3rdParty/tbb/include/tbb/parallel_while.h delete mode 100644 lib/3rdParty/tbb/include/tbb/partitioner.h delete mode 100644 lib/3rdParty/tbb/include/tbb/pipeline.h delete mode 100644 lib/3rdParty/tbb/include/tbb/queuing_mutex.h delete mode 100644 lib/3rdParty/tbb/include/tbb/queuing_rw_mutex.h delete mode 100644 lib/3rdParty/tbb/include/tbb/reader_writer_lock.h delete mode 100644 lib/3rdParty/tbb/include/tbb/recursive_mutex.h delete mode 100644 lib/3rdParty/tbb/include/tbb/runtime_loader.h delete mode 100644 lib/3rdParty/tbb/include/tbb/scalable_allocator.h delete mode 100644 lib/3rdParty/tbb/include/tbb/spin_mutex.h delete mode 100644 lib/3rdParty/tbb/include/tbb/spin_rw_mutex.h delete mode 100644 lib/3rdParty/tbb/include/tbb/task.h delete mode 100644 lib/3rdParty/tbb/include/tbb/task_arena.h delete mode 100644 lib/3rdParty/tbb/include/tbb/task_group.h delete mode 100644 lib/3rdParty/tbb/include/tbb/task_scheduler_init.h delete mode 100644 lib/3rdParty/tbb/include/tbb/task_scheduler_observer.h delete mode 100644 lib/3rdParty/tbb/include/tbb/tbb.h delete mode 100644 lib/3rdParty/tbb/include/tbb/tbb_allocator.h delete mode 100644 lib/3rdParty/tbb/include/tbb/tbb_config.h delete mode 100644 lib/3rdParty/tbb/include/tbb/tbb_exception.h delete mode 100644 lib/3rdParty/tbb/include/tbb/tbb_machine.h delete mode 100644 lib/3rdParty/tbb/include/tbb/tbb_profiling.h delete mode 100644 lib/3rdParty/tbb/include/tbb/tbb_stddef.h delete mode 100644 lib/3rdParty/tbb/include/tbb/tbb_thread.h delete mode 100644 lib/3rdParty/tbb/include/tbb/tbbmalloc_proxy.h delete mode 100644 lib/3rdParty/tbb/include/tbb/tick_count.h delete mode 100644 lib/3rdParty/tbb/index.html delete mode 100644 lib/3rdParty/tbb/lib/x64/v140/irml/irml.lib delete mode 100644 lib/3rdParty/tbb/lib/x64/v140/irml/irml_debug.lib delete mode 100644 lib/3rdParty/tbb/lib/x64/v140/tbb.def delete mode 100644 lib/3rdParty/tbb/lib/x64/v140/tbb.lib delete mode 100644 lib/3rdParty/tbb/lib/x64/v140/tbb_debug.lib delete mode 100644 lib/3rdParty/tbb/lib/x64/v140/tbb_preview.lib delete mode 100644 lib/3rdParty/tbb/lib/x64/v140/tbbmalloc.def delete mode 100644 lib/3rdParty/tbb/lib/x64/v140/tbbmalloc.lib delete mode 100644 lib/3rdParty/tbb/lib/x64/v140/tbbmalloc_proxy.lib delete mode 100644 lib/3rdParty/tbb/lib/x64/v140/tbbproxy.lib delete mode 100644 lib/3rdParty/tbb/lib/x86/v140/irml/irml.lib delete mode 100644 lib/3rdParty/tbb/lib/x86/v140/irml/irml_debug.lib delete mode 100644 lib/3rdParty/tbb/lib/x86/v140/tbb.def delete mode 100644 lib/3rdParty/tbb/lib/x86/v140/tbb.lib delete mode 100644 lib/3rdParty/tbb/lib/x86/v140/tbb_debug.lib delete mode 100644 lib/3rdParty/tbb/lib/x86/v140/tbb_preview.lib delete mode 100644 lib/3rdParty/tbb/lib/x86/v140/tbbmalloc.def delete mode 100644 lib/3rdParty/tbb/lib/x86/v140/tbbmalloc.lib delete mode 100644 lib/3rdParty/tbb/lib/x86/v140/tbbmalloc_proxy.lib delete mode 100644 lib/3rdParty/tbb/lib/x86/v140/tbbproxy.lib delete mode 100644 lib/3rdParty/tbb/tbb.props delete mode 100644 lib/3rdParty/tbb/tbb_d.props create mode 100644 lib/local/Utilities/include/ConcurrentQueue.h diff --git a/.travis.yml b/.travis.yml index e169a021..efc7d1d6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,6 +8,7 @@ branches: - master - develop - feature/code_cleanup + - feature/parallel_for compiler: - gcc @@ -46,7 +47,7 @@ before_install: - if [ "$CXX" = "g++" ]; then if [ ${TRAVIS_OS_NAME} = linux ]; then $CXX --version; - sudo cmake -D CMAKE_BUILD_TYPE=RELEASE -D WITH_V4L=ON -D WITH_OPENCL=OFF -D INSTALL_C_EXAMPLES=OFF -D BUILD_EXAMPLES=OFF -D BUILD_TESTS=OFF -D BUILD_PERF_TESTS=OFF -D BUILD_EXAMPLES=OFF -D INSTALL_PYTHON_EXAMPLES=OFF ..; + sudo cmake -D CMAKE_BUILD_TYPE=RELEASE -D WITH_V4L=ON -D WITH_OPENCL=OFF -D INSTALL_C_EXAMPLES=OFF -D WITH_TBB=ON -D BUILD_EXAMPLES=OFF -D BUILD_TESTS=OFF -D BUILD_PERF_TESTS=OFF -D BUILD_EXAMPLES=OFF -D INSTALL_PYTHON_EXAMPLES=OFF ..; sudo make -j4; sudo make install; cd ../..; diff --git a/CMakeLists.txt b/CMakeLists.txt index 734665d6..d965b766 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,25 +48,6 @@ else() MESSAGE(FATAL_ERROR "Boost not found in the system.") endif() -# Try finding TBB in default location -find_package( TBB CONFIG ) - -# If not found, use FindTBB.cmake -if ("${TBB_LIBRARIES}" STREQUAL "") - MESSAGE("TBB not found in CONFIG, searching with FindTBB.cmake.") - find_package( TBB REQUIRED ) - if ("${TBB_LIBRARIES}" STREQUAL "") - MESSAGE(FATAL_ERROR "TBB not found") - endif() -else() - MESSAGE("TBB found in CONFIG: ${TBB_LIBRARIES}") -endif() - -MESSAGE("TBB information:") -MESSAGE(" TBB_VERSION: ${TBB_VERSION}") -MESSAGE(" TBB_INCLUDE_DIRS: ${TBB_INCLUDE_DIRS}") -MESSAGE(" TBB_LIBRARIES: ${TBB_LIBRARIES}") - # Move LandmarkDetector model file(GLOB files "lib/local/LandmarkDetector/model/*.txt") foreach(file ${files}) diff --git a/README.md b/README.md index 659b68ab..c0a7d656 100644 --- a/README.md +++ b/README.md @@ -100,6 +100,6 @@ I did my best to make sure that the code runs out of the box but there are alway Copyright can be found in the Copyright.txt -You have to respect boost, TBB, dlib, OpenBLAS, and OpenCV licenses. +You have to respect boost, dlib, OpenBLAS, and OpenCV licenses. Furthermore you have to respect the licenses of the datasets used for model training - https://github.com/TadasBaltrusaitis/OpenFace/wiki/Datasets diff --git a/appveyor.yml b/appveyor.yml index df31985e..45e9ae0d 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -4,6 +4,7 @@ branches: - develop - master - feature/code_cleanup + - feature/parallel_for max_jobs: 4 configuration: - Release diff --git a/exe/FaceLandmarkImg/FaceLandmarkImg.cpp b/exe/FaceLandmarkImg/FaceLandmarkImg.cpp index 10b1eb06..58c0faec 100644 --- a/exe/FaceLandmarkImg/FaceLandmarkImg.cpp +++ b/exe/FaceLandmarkImg/FaceLandmarkImg.cpp @@ -38,8 +38,6 @@ #include "LandmarkCoreIncludes.h" -#include - #include #include diff --git a/exe/FaceLandmarkImg/FaceLandmarkImg.vcxproj b/exe/FaceLandmarkImg/FaceLandmarkImg.vcxproj index e59e5312..814e186f 100644 --- a/exe/FaceLandmarkImg/FaceLandmarkImg.vcxproj +++ b/exe/FaceLandmarkImg/FaceLandmarkImg.vcxproj @@ -59,7 +59,6 @@ - @@ -67,7 +66,6 @@ - @@ -75,7 +73,6 @@ - @@ -83,7 +80,6 @@ - diff --git a/exe/FaceLandmarkVid/FaceLandmarkVid.vcxproj b/exe/FaceLandmarkVid/FaceLandmarkVid.vcxproj index 33fd71d9..dc88e5ff 100644 --- a/exe/FaceLandmarkVid/FaceLandmarkVid.vcxproj +++ b/exe/FaceLandmarkVid/FaceLandmarkVid.vcxproj @@ -59,7 +59,6 @@ - @@ -67,7 +66,6 @@ - @@ -75,7 +73,6 @@ - @@ -83,7 +80,6 @@ - diff --git a/exe/FaceLandmarkVidMulti/FaceLandmarkVidMulti.cpp b/exe/FaceLandmarkVidMulti/FaceLandmarkVidMulti.cpp index 423d368a..4333b913 100644 --- a/exe/FaceLandmarkVidMulti/FaceLandmarkVidMulti.cpp +++ b/exe/FaceLandmarkVidMulti/FaceLandmarkVidMulti.cpp @@ -263,13 +263,11 @@ int main(int argc, char **argv) } - // Keep only non overlapping detections (also convert to a concurrent vector + // Keep only non overlapping detections (so as not to start tracking where the face is already tracked) NonOverlapingDetections(face_models, face_detections); - - vector > face_detections_used(face_detections.size()); + std::vector face_detections_used(face_detections.size(), false); // Go through every model and update the tracking - //tbb::parallel_for(0, (int)face_models.size(), [&](int model) { for (unsigned int model = 0; model < face_models.size(); ++model) { @@ -288,9 +286,10 @@ int main(int argc, char **argv) for (size_t detection_ind = 0; detection_ind < face_detections.size(); ++detection_ind) { - // if it was not taken by another tracker take it (if it is false swap it to true and enter detection, this makes it parallel safe) - if (face_detections_used[detection_ind].compare_and_swap(true, false) == false) + // if it was not taken by another tracker take it + if (!face_detections_used[detection_ind]) { + face_detections_used[detection_ind] = true; // Reinitialise the model face_models[model].Reset(); @@ -314,7 +313,6 @@ int main(int argc, char **argv) detection_success = LandmarkDetector::DetectLandmarksInVideo(rgb_image, face_models[model], det_parameters[model], grayscale_image); } } - //}); // Keeping track of FPS fps_tracker.AddFrame(); diff --git a/exe/FaceLandmarkVidMulti/FaceLandmarkVidMulti.vcxproj b/exe/FaceLandmarkVidMulti/FaceLandmarkVidMulti.vcxproj index 3d68ce0f..72793b84 100644 --- a/exe/FaceLandmarkVidMulti/FaceLandmarkVidMulti.vcxproj +++ b/exe/FaceLandmarkVidMulti/FaceLandmarkVidMulti.vcxproj @@ -58,7 +58,6 @@ - @@ -66,7 +65,6 @@ - @@ -74,7 +72,6 @@ - @@ -82,7 +79,6 @@ - diff --git a/exe/FeatureExtraction/FeatureExtraction.vcxproj b/exe/FeatureExtraction/FeatureExtraction.vcxproj index 992ac525..9a5c7e01 100644 --- a/exe/FeatureExtraction/FeatureExtraction.vcxproj +++ b/exe/FeatureExtraction/FeatureExtraction.vcxproj @@ -58,7 +58,6 @@ - @@ -66,7 +65,6 @@ - @@ -74,7 +72,6 @@ - @@ -82,7 +79,6 @@ - diff --git a/lib/3rdParty/tbb/CHANGES b/lib/3rdParty/tbb/CHANGES deleted file mode 100644 index ab1d1a13..00000000 --- a/lib/3rdParty/tbb/CHANGES +++ /dev/null @@ -1,2359 +0,0 @@ ------------------------------------------------------------------------- -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 - -Changes (w.r.t. Intel TBB 4.4 Update 2): - -- Modified parallel_sort to not require a default constructor for values - and to use iter_swap() for value swapping. -- Added support for creating or initializing a task_arena instance that - is connected to the arena currently used by the thread. -- graph/binpack example modified to use multifunction_node. -- For performance analysis, use Intel(R) VTune(TM) Amplifier XE 2015 - and higher; older versions are no longer supported. -- Improved support for compilation with disabled RTTI, by omitting its use - in auxiliary code, such as assertions. However some functionality, - particularly the flow graph, does not work if RTTI is disabled. -- The tachyon example for Android* can be built using Android Studio 1.5 - and higher with experimental Gradle plugin 0.4.0. - -Preview Features: - -- Added class opencl_subbufer that allows using OpenCL* sub-buffer - objects with opencl_node. -- Class global_control supports the value of 1 for - max_allowed_parallelism. - -Bugs fixed: - -- Fixed a race causing "TBB Warning: setaffinity syscall failed" message. -- Fixed a compilation issue on OS X* with Intel(R) C++ Compiler 15.0. -- Fixed a bug in queuing_rw_mutex::downgrade() that could temporarily - block new readers. -- Fixed speculative_spin_rw_mutex to stop using the lazy subscription - technique due to its known flaws. -- Fixed memory leaks in the tool support code. - ------------------------------------------------------------------------- -Intel TBB 4.4 Update 2 -TBB_INTERFACE_VERSION == 9002 - -Changes (w.r.t. Intel TBB 4.4 Update 1): - -- Improved interoperability with Intel(R) OpenMP RTL (libiomp) on Linux: - OpenMP affinity settings do not affect the default number of threads - used in the task scheduler. Intel(R) C++ Compiler 16.0 Update 1 - or later is required. -- Added a new flow graph example with different implementations of the - Cholesky Factorization algorithm. - -Preview Features: - -- Added template class opencl_node to the flow graph API. It allows a - flow graph to offload computations to OpenCL* devices. -- Extended join_node to use type-specified message keys. It simplifies - the API of the node by obtaining message keys via functions - associated with the message type (instead of node ports). -- Added static_partitioner that minimizes overhead of parallel_for and - parallel_reduce for well-balanced workloads. -- Improved template class async_node in the flow graph API to support - user settable concurrency limits. - -Bugs fixed: - -- Fixed a possible crash in the GUI layer for library examples on Linux. - ------------------------------------------------------------------------- -Intel TBB 4.4 Update 1 -TBB_INTERFACE_VERSION == 9001 - -Changes (w.r.t. Intel TBB 4.4): - -- Added support for Microsoft* Visual Studio* 2015. -- Intel TBB no longer performs dynamic replacement of memory allocation - functions for Microsoft Visual Studio 2005 and earlier versions. -- For GCC 4.7 and higher, the intrinsics-based platform isolation layer - uses __atomic_* built-ins instead of the legacy __sync_* ones. - This change is inspired by a contribution from Mathieu Malaterre. -- Improvements in task_arena: - Several application threads may join a task_arena and execute tasks - simultaneously. The amount of concurrency reserved for application - threads at task_arena construction can be set to any value between - 0 and the arena concurrency limit. -- The fractal example was modified to demonstrate class task_arena - and moved to examples/task_arena/fractal. - -Bugs fixed: - -- Fixed a deadlock during destruction of task_scheduler_init objects - when one of destructors is set to wait for worker threads. -- Added a workaround for a possible crash on OS X* when dynamic memory - allocator replacement (libtbbmalloc_proxy) is used and memory is - released during application startup. -- Usage of mutable functors with task_group::run_and_wait() and - task_arena::enqueue() is disabled. An attempt to pass a functor - which operator()() is not const will produce compilation errors. -- Makefiles and environment scripts now properly recognize GCC 5.0 and - higher. - -Open-source contributions integrated: - -- Improved performance of parallel_for_each for inputs allowing random - access, by Raf Schietekat. - ------------------------------------------------------------------------- -Intel TBB 4.4 -TBB_INTERFACE_VERSION == 9000 - -Changes (w.r.t. Intel TBB 4.3 Update 6): - -- The following features are now fully supported: - tbb::flow::composite_node; - additional policies of tbb::flow::graph_node::reset(). -- Platform abstraction layer for Windows* OS updated to use compiler - intrinsics for most atomic operations. -- The tbb/compat/thread header updated to automatically include - C++11 where available. -- Fixes and refactoring in the task scheduler and class task_arena. -- Added key_matching policy to tbb::flow::join_node, which removes - the restriction on the type that can be compared-against. -- For tag_matching join_node, tag_value is redefined to be 64 bits - wide on all architectures. -- Expanded the documentation for the flow graph with details about - node semantics and behavior. -- Added dynamic replacement of C11 standard function aligned_alloc() - under Linux* OS. -- Added C++11 move constructors and assignment operators to - tbb::enumerable_thread_specific container. -- Added hashing support for tbb::tbb_thread::id. -- On OS X*, binaries that depend on libstdc++ are not provided anymore. - In the makefiles, libc++ is now used by default; for building with - libstdc++, specify stdlib=libstdc++ in the make command line. - -Preview Features: - -- Added a new example, graph/fgbzip2, that shows usage of - tbb::flow::async_node. -- Modification to the low-level API for memory pools: - added a function for finding a memory pool by an object allocated - from that pool. -- tbb::memory_pool now does not request memory till the first allocation - from the pool. - -Changes affecting backward compatibility: - -- Internal layout of flow graph nodes has changed; recompilation is - recommended for all binaries that use the flow graph. -- Resetting a tbb::flow::source_node will immediately activate it, - unless it was created in inactive state. - -Bugs fixed: - -- Failure at creation of a memory pool will not cause process - termination anymore. - -Open-source contributions integrated: - -- Supported building TBB with Clang on AArch64 with use of built-in - intrinsics by David A. - ------------------------------------------------------------------------- -Intel TBB 4.3 Update 6 -TBB_INTERFACE_VERSION == 8006 - -Changes (w.r.t. Intel TBB 4.3 Update 5): - -- Supported zero-copy realloc for objects >1MB under Linux* via - mremap system call. -- C++11 move-aware insert and emplace methods have been added to - concurrent_hash_map container. -- install_name is set to @rpath/ on OS X*. - -Preview Features: - -- Added template class async_node to the flow graph API. It allows a - flow graph to communicate with an external activity managed by - the user or another runtime. -- Improved speed of flow::graph::reset() clearing graph edges. - rf_extract flag has been renamed rf_clear_edges. -- extract() method of graph nodes now takes no arguments. - -Bugs fixed: - -- concurrent_unordered_{set,map} behaves correctly for degenerate - hashes. -- Fixed a race condition in the memory allocator that may lead to - excessive memory consumption under high multithreading load. - ------------------------------------------------------------------------- -Intel TBB 4.3 Update 5 -TBB_INTERFACE_VERSION == 8005 - -Changes (w.r.t. Intel TBB 4.3 Update 4): - -- Added add_ref_count() method of class tbb::task. - -Preview Features: - -- Added class global_control for application-wide control of allowed - parallelism and thread stack size. -- memory_pool_allocator now throws the std::bad_alloc exception on - allocation failure. -- Exceptions thrown for by memory pool constructors changed from - std::bad_alloc to std::invalid_argument and std::runtime_error. - -Bugs fixed: - -- scalable_allocator now throws the std::bad_alloc exception on - allocation failure. -- Fixed a race condition in the memory allocator that may lead to - excessive memory consumption under high multithreading load. -- A new scheduler created right after destruction of the previous one - might be unable to modify the number of worker threads. - -Open-source contributions integrated: - -- (Added but not enabled) push_front() method of class tbb::task_list - by Raf Schietekat. - ------------------------------------------------------------------------- -Intel TBB 4.3 Update 4 -TBB_INTERFACE_VERSION == 8004 - -Changes (w.r.t. Intel TBB 4.3 Update 3): - -- Added a C++11 variadic constructor for enumerable_thread_specific. - The arguments from this constructor are used to construct - thread-local values. -- Improved exception safety for enumerable_thread_specific. -- Added documentation for tbb::flow::tagged_msg class and - tbb::flow::output_port function. -- Fixed build errors for systems that do not support dynamic linking. -- C++11 move-aware insert and emplace methods have been added to - concurrent unordered containers. - -Preview Features: - -- Interface-breaking change: typedefs changed for node predecessor and - successor lists, affecting copy_predecessors and copy_successors - methods. -- Added template class composite_node to the flow graph API. It packages - a subgraph to represent it as a first-class flow graph node. -- make_edge and remove_edge now accept multiport nodes as arguments, - automatically using the node port with index 0 for an edge. - -Open-source contributions integrated: - -- Draft code for enumerable_thread_specific constructor with multiple - arguments (see above) by Adrien Guinet. -- Fix for GCC invocation on IBM* Blue Gene* - by Jeff Hammond and Raf Schietekat. -- Extended testing with smart pointers for Clang & libc++ - by Raf Schietekat. - ------------------------------------------------------------------------- -Intel TBB 4.3 Update 3 -TBB_INTERFACE_VERSION == 8003 - -Changes (w.r.t. Intel TBB 4.3 Update 2): - -- Move constructor and assignment operator were added to unique_lock. - -Preview Features: - -- Time overhead for memory pool destruction was reduced. - -Open-source contributions integrated: - -- Build error fix for iOS* by Raf Schietekat. - ------------------------------------------------------------------------- -Intel TBB 4.3 Update 2 -TBB_INTERFACE_VERSION == 8002 - -Changes (w.r.t. Intel TBB 4.3 Update 1): - -- Binary files for 64-bit Android* applications were added as part of the - Linux* OS package. -- Exact exception propagation is enabled for Intel C++ Compiler on OS X*. -- concurrent_vector::shrink_to_fit was optimized for types that support - C++11 move semantics. - -Bugs fixed: - -- Fixed concurrent unordered containers to insert elements much faster - in debug mode. -- Fixed concurrent priority queue to support types that do not have - copy constructors. -- Fixed enumerable_thread_specific to forbid copying from an instance - with a different value type. - -Open-source contributions integrated: - -- Support for PathScale* EKOPath* Compiler by Erik Lindahl. - ------------------------------------------------------------------------- -Intel TBB 4.3 Update 1 -TBB_INTERFACE_VERSION == 8001 - -Changes (w.r.t. Intel TBB 4.3): - -- The ability to split blocked_ranges in a proportion, used by - affinity_partitioner since version 4.2 Update 4, became a formal - extension of the Range concept. -- More checks for an incorrect address to release added to the debug - version of the memory allocator. -- Different kind of solutions for each TBB example were merged. - -Preview Features: - -- Task priorities are re-enabled in preview binaries. - -Bugs fixed: - -- Fixed a duplicate symbol when TBB_PREVIEW_VARIADIC_PARALLEL_INVOKE is - used in multiple compilation units. -- Fixed a crash in __itt_fini_ittlib seen on Ubuntu 14.04. -- Fixed a crash in memory release after dynamic replacement of the - OS X* memory allocator. -- Fixed incorrect indexing of arrays in seismic example. -- Fixed a data race in lazy initialization of task_arena. - -Open-source contributions integrated: - -- Fix for dumping information about gcc and clang compiler versions - by Misty De Meo. - ------------------------------------------------------------------------- -Intel TBB 4.3 -TBB_INTERFACE_VERSION == 8000 - -Changes (w.r.t. Intel TBB 4.2 Update 5): - -- The following features are now fully supported: flow::indexer_node, - task_arena, speculative_spin_rw_mutex. -- Compatibility with C++11 standard improved for tbb/compat/thread - and tbb::mutex. -- C++11 move constructors have been added to concurrent_queue and - concurrent_bounded_queue. -- C++11 move constructors and assignment operators have been added to - concurrent_vector, concurrent_hash_map, concurrent_priority_queue, - concurrent_unordered_{set,multiset,map,multimap}. -- C++11 move-aware emplace/push/pop methods have been added to - concurrent_vector, concurrent_queue, concurrent_bounded_queue, - concurrent_priority_queue. -- Methods to insert a C++11 initializer list have been added: - concurrent_vector::grow_by(), concurrent_hash_map::insert(), - concurrent_unordered_{set,multiset,map,multimap}::insert(). -- Testing for compatibility of containers with some C++11 standard - library types has been added. -- Dynamic replacement of standard memory allocation routines has been - added for OS X*. -- Microsoft* Visual Studio* projects for Intel TBB examples updated - to VS 2010. -- For open-source packages, debugging information (line numbers) in - precompiled binaries now matches the source code. -- Debug information was added to release builds for OS X*, Solaris*, - FreeBSD* operating systems and MinGW*. -- Various improvements in documentation, debug diagnostics and examples. - -Preview Features: - -- Additional actions on reset of graphs, and extraction of individual - nodes from a graph (TBB_PREVIEW_FLOW_GRAPH_FEATURES). -- Support for an arbitrary number of arguments in parallel_invoke - (TBB_PREVIEW_VARIADIC_PARALLEL_INVOKE). - -Changes affecting backward compatibility: - -- For compatibility with C++11 standard, copy and move constructors and - assignment operators are disabled for all mutex classes. To allow - the old behavior, use TBB_DEPRECATED_MUTEX_COPYING macro. -- flow::sequencer_node rejects messages with repeating sequence numbers. -- Changed internal interface between tbbmalloc and tbbmalloc_proxy. -- Following deprecated functionality has been removed: - old debugging macros TBB_DO_ASSERT & TBB_DO_THREADING_TOOLS; - no-op depth-related methods in class task; - tbb::deprecated::concurrent_queue; - deprecated variants of concurrent_vector methods. -- register_successor() and remove_successor() are deprecated as methods - to add and remove edges in flow::graph; use make_edge() and - remove_edge() instead. - -Bugs fixed: - -- Fixed incorrect scalable_msize() implementation for aligned objects. -- Flow graph buffering nodes now destroy their copy of forwarded items. -- Multiple fixes in task_arena implementation, including for: - inconsistent task scheduler state inside executed functions; - incorrect floating-point settings and exception propagation; - possible stalls in concurrent invocations of execute(). -- Fixed floating-point settings propagation when the same instance of - task_group_context is used in different arenas. -- Fixed compilation error in pipeline.h with Intel Compiler on OS X*. -- Added missed headers for individual components to tbb.h. - -Open-source contributions integrated: - -- Range interface addition to parallel_do, parallel_for_each and - parallel_sort by Stephan Dollberg. -- Variadic template implementation of parallel_invoke - by Kizza George Mbidde (see Preview Features). -- Improvement in Seismic example for MacBook Pro* with Retina* display - by Raf Schietekat. - ------------------------------------------------------------------------- -Intel TBB 4.2 Update 5 -TBB_INTERFACE_VERSION == 7005 - -Changes (w.r.t. Intel TBB 4.2 Update 4): - -- The second template argument of class aligned_space now is set - to 1 by default. - -Preview Features: - -- Better support for exception safety, task priorities and floating - point settings in class task_arena. -- task_arena::current_slot() has been renamed to - task_arena::current_thread_index(). - -Bugs fixed: - -- Task priority change possibly ignored by a worker thread entering - a nested parallel construct. -- Memory leaks inside the task scheduler when running on - Intel(R) Xeon Phi(tm) coprocessor. - -Open-source contributions integrated: - -- Improved detection of X Window support for Intel TBB examples - and other feedback by Raf Schietekat. - ------------------------------------------------------------------------- -Intel TBB 4.2 Update 4 -TBB_INTERFACE_VERSION == 7004 - -Changes (w.r.t. Intel TBB 4.2 Update 3): - -- Added possibility to specify floating-point settings at invocation - of most parallel algorithms (including flow::graph) via - task_group_context. -- Added dynamic replacement of malloc_usable_size() under - Linux*/Android* and dlmalloc_usable_size() under Android*. -- Added new methods to concurrent_vector: - grow_by() that appends a sequence between two given iterators; - grow_to_at_least() that initializes new elements with a given value. -- Improved affinity_partitioner for better performance on balanced - workloads. -- Improvements in the task scheduler, including better scalability - when threads search for a task arena, and better diagnostics. -- Improved allocation performance for workloads that do intensive - allocation/releasing of same-size objects larger than ~8KB from - multiple threads. -- Exception support is enabled by default for 32-bit MinGW compilers. -- The tachyon example for Android* can be built for all targets - supported by the installed NDK. -- Added Windows Store* version of the tachyon example. -- GettingStarted/sub_string_finder example ported to offload execution - on Windows* for Intel(R) Many Integrated Core Architecture. - -Preview Features: - -- Removed task_scheduler_observer::on_scheduler_leaving() callback. -- Added task_scheduler_observer::may_sleep() callback. -- The CPF or_node has been renamed indexer_node. The input to - indexer_node is now a list of types. The output of indexer_node is - a tagged_msg type composed of a tag and a value. For indexer_node, - the tag is a size_t. - -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 cancellation of structured task group in C++11. - -Open-source contributions integrated: - -- Improved concurrency detection for BG/Q, and other improvements - by Raf Schietekat. -- Fix for crashes in enumerable_thread_specific in case if a contained - object is too big to be constructed on the stack by Adrien Guinet. - ------------------------------------------------------------------------- -Intel TBB 4.2 Update 3 -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 - support of auto-vectorization. -- Added a new example for cancellation and reset in the flow graph: - Kohonen self-organizing map (examples/graph/som). -- Various improvements in source code, tests, and makefiles. - -Bugs fixed: - -- Added dynamic replacement of _aligned_msize() previously missed. -- Fixed task_group::run_and_wait() to throw invalid_multiple_scheduling - exception if the specified task handle is already scheduled. - -Open-source contributions integrated: - -- A fix for ARM* processors by Steve Capper. -- Improvements in std::swap calls by Robert Maynard. - ------------------------------------------------------------------------- -Intel TBB 4.2 Update 2 -TBB_INTERFACE_VERSION == 7002 - -Changes (w.r.t. Intel TBB 4.2 Update 1): - -- Enable C++11 features for Microsoft* Visual Studio* 2013 Preview. -- Added a test for compatibility of TBB containers with C++11 - range-based for loop. - -Changes affecting backward compatibility: - -- Internal layout changed for class tbb::flow::limiter_node. - -Preview Features: - -- Added speculative_spin_rw_mutex, a read-write lock class which uses - Intel(R) Transactional Synchronization Extensions. - -Bugs fixed: - -- When building for Intel(R) Xeon Phi(tm) coprocessor, TBB programs - no longer require explicit linking with librt and libpthread. - -Open-source contributions integrated: - -- Fixes for ARM* processors by Steve Capper, Leif Lindholm - and Steven Noonan. -- Support for Clang on Linux by Raf Schietekat. -- Typo correction in scheduler.cpp by Julien Schueller. - ------------------------------------------------------------------------- -Intel TBB 4.2 Update 1 -TBB_INTERFACE_VERSION == 7001 - -Changes (w.r.t. Intel TBB 4.2): - -- Added project files for Microsoft* Visual Studio* 2010. -- Initial support of Microsoft* Visual Studio* 2013 Preview. -- Enable C++11 features available in Intel(R) C++ Compiler 14.0. -- scalable_allocation_mode(TBBMALLOC_SET_SOFT_HEAP_LIMIT, ) can be - used to urge releasing memory from tbbmalloc internal buffers when - the given limit is exceeded. - -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 task scheduler is not initialized in the thread. - -Changes affecting backward compatibility: - -- Because of changes in internal layout of graph nodes, the namespace - interface number of flow::graph has been incremented from 6 to 7. - -Bugs fixed: - -- Fixed a race in lazy initialization of task_arena. -- Fixed flow::graph::reset() to prevent situations where tasks would be - spawned in the process of resetting the graph to its initial state. -- Fixed decrement bug in limiter_node. -- Fixed a race in arc deletion in the flow graph. - -Open-source contributions integrated: - -- Improved support for IBM* Blue Gene* by Raf Schietekat. - ------------------------------------------------------------------------- -Intel TBB 4.2 -TBB_INTERFACE_VERSION == 7000 - -Changes (w.r.t. Intel TBB 4.1 Update 4): - -- Added speculative_spin_mutex, which uses Intel(R) Transactional - Synchronization Extensions when they are supported by hardware. -- Binary files linked with libc++ (the C++ standard library in Clang) - were added on OS X*. -- For OS X* exact exception propagation is supported with Clang; - it requires use of libc++ and corresponding Intel TBB binaries. -- Support for C++11 initializer lists in constructor and assigment - has been added to concurrent_hash_map, concurrent_unordered_set, - concurrent_unordered_multiset, concurrent_unordered_map, - concurrent_unordered_multimap. -- The memory allocator may now clean its per-thread memory caches - when it cannot get more memory. -- Added the scalable_allocation_command() function for on-demand - cleaning of internal memory caches. -- Reduced the time overhead for freeing memory objects smaller than ~8K. -- Simplified linking with the debug library for applications that use - Intel TBB in code offloaded to Intel(R) Xeon Phi(tm) coprocessors. - See an example in - examples/GettingStarted/sub_string_finder/Makefile. -- Various improvements in source code, scripts and makefiles. - -Changes affecting backward compatibility: - -- tbb::flow::graph has been modified to spawn its tasks; - the old behaviour (task enqueuing) is deprecated. This change may - impact applications that expected a flow graph to make progress - without calling wait_for_all(), which is no longer guaranteed. See - the documentation for more details. -- Changed the return values of the scalable_allocation_mode() function. - -Bugs fixed: - -- Fixed a leak of parallel_reduce body objects when execution is - cancelled or an exception is thrown, as suggested by Darcy Harrison. -- Fixed a race in the task scheduler which can lower the effective - priority despite the existence of higher priority tasks. -- On Linux an error during destruction of the internal thread local - storage no longer results in an exception. - -Open-source contributions integrated: - -- Fixed task_group_context state propagation to unrelated context trees - by Raf Schietekat. - ------------------------------------------------------------------------- -Intel TBB 4.1 Update 4 -TBB_INTERFACE_VERSION == 6105 - -Changes (w.r.t. Intel TBB 4.1 Update 3): - -- Use /volatile:iso option with VS 2012 to disable extended - semantics for volatile variables. -- Various improvements in affinity_partitioner, scheduler, - tests, examples, makefiles. -- Concurrent_priority_queue class now supports initialization/assignment - via C++11 initializer list feature (std::initializer_list). - -Bugs fixed: - -- Fixed more possible stalls in concurrent invocations of - task_arena::execute(), especially waiting for enqueued tasks. -- Fixed requested number of workers for task_arena(P,0). -- Fixed interoperability with Intel(R) VTune(TM) Amplifier XE in - case of using task_arena::enqueue() from a terminating thread. - -Open-source contributions integrated: - -- Type fixes, cleanups, and code beautification by Raf Schietekat. -- Improvements in atomic operations for big endian platforms - by Raf Schietekat. - ------------------------------------------------------------------------- -Intel TBB 4.1 Update 3 -TBB_INTERFACE_VERSION == 6103 - -Changes (w.r.t. Intel TBB 4.1 Update 2): - -- Binary files for Android* applications were added to the Linux* OS - package. -- Binary files for Windows Store* applications were added to the - Windows* OS package. -- Exact exception propagation (exception_ptr) support on Linux OS is - now turned on by default for GCC 4.4 and higher. -- Stopped implicit use of large memory pages by tbbmalloc (Linux-only). - Now use of large pages must be explicitly enabled with - scalable_allocation_mode() function or TBB_MALLOC_USE_HUGE_PAGES - environment variable. - -Community Preview Features: - -- Extended class task_arena constructor and method initialize() to - allow some concurrency to be reserved strictly for application - threads. -- New methods terminate() and is_active() were added to class - task_arena. - -Bugs fixed: - -- Fixed initialization of hashing helper constant in the hash - containers. -- Fixed possible stalls in concurrent invocations of - task_arena::execute() when no worker thread is available to make - progress. -- Fixed incorrect calculation of hardware concurrency in the presence - of inactive processor groups, particularly on systems running - Windows* 8 and Windows* Server 2012. - -Open-source contributions integrated: - -- The fix for the GUI examples on OS X* systems by Raf Schietekat. -- Moved some power-of-2 calculations to functions to improve readability - by Raf Schietekat. -- C++11/Clang support improvements by arcata. -- ARM* platform isolation layer by Steve Capper, Leif Lindholm, Leo Lara - (ARM). - ------------------------------------------------------------------------- -Intel TBB 4.1 Update 2 -TBB_INTERFACE_VERSION == 6102 - -Changes (w.r.t. Intel TBB 4.1 Update 1): - -- Objects up to 128 MB are now cached by the tbbmalloc. Previously - the threshold was 8MB. Objects larger than 128 MB are still - processed by direct OS calls. -- concurrent_unordered_multiset and concurrent_unordered_multimap - have been added, based on Microsoft* PPL prototype. -- Ability to value-initialize a tbb::atomic variable on construction - in C++11, with const expressions properly supported. - -Community Preview Features: - -- Added a possibility to wait until all worker threads terminate. - This is necessary before calling fork() from an application. - -Bugs fixed: - -- Fixed data race in tbbmalloc that might lead to memory leaks - for large object allocations. -- Fixed task_arena::enqueue() to use task_group_context of target arena. -- Improved implementation of 64 bit atomics on ia32. - ------------------------------------------------------------------------- -Intel TBB 4.1 Update 1 -TBB_INTERFACE_VERSION == 6101 - -Changes (w.r.t. Intel TBB 4.1): - -- concurrent_vector class now supports initialization/assignment - via C++11 initializer list feature (std::initializer_list) -- Added implementation of the platform isolation layer based on - Intel compiler atomic built-ins; it is supposed to work on - 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: - parallel_for(first, last, [step,] f[, context]) now accepts an - optional partitioner parameter after the function f. - -Backward-incompatible API changes: - -- The library no longer injects tuple in to namespace std. - In previous releases, tuple was injected into namespace std by - flow_graph.h when std::tuple was not available. In this release, - flow_graph.h now uses tbb::flow::tuple. On platforms where - std::tuple is available, tbb::flow::tuple is typedef'ed to - std::tuple. On all other platforms, tbb::flow::tuple provides - a subset of the functionality defined by std::tuple. Users of - flow_graph.h may need to change their uses of std::tuple to - tbb::flow::tuple to ensure compatibility with non-C++11 compliant - compilers. - -Bugs fixed: - -- Fixed local observer to be able to override propagated CPU state and - to provide correct value of task_arena::current_slot() in callbacks. - ------------------------------------------------------------------------- -Intel TBB 4.1 -TBB_INTERFACE_VERSION == 6100 - -Changes (w.r.t. Intel TBB 4.0 Update 5): - -- _WIN32_WINNT must be set to 0x0501 or greater in order to use TBB - on Microsoft* Windows*. -- parallel_deterministic_reduce template function is fully supported. -- TBB headers can be used with C++0x/C++11 mode (-std=c++0x) of GCC - and Intel(R) Compiler. -- C++11 std::make_exception_ptr is used where available, instead of - std::copy_exception from earlier C++0x implementations. -- Improvements in the TBB allocator to reduce extra memory consumption. -- Partial refactoring of the task scheduler data structures. -- TBB examples allow more flexible specification of the thread number, - including arithmetic and geometric progression. - -Bugs fixed: - -- On Linux & OS X*, pre-built TBB binaries do not yet support exact - exception propagation via C++11 exception_ptr. To prevent run time - errors, by default TBB headers disable exact exception propagation - even if the C++ implementation provides exception_ptr. - -Community Preview Features: - -- Added: class task_arena, for work submission by multiple application - threads with thread-independent control of concurrency level. -- Added: task_scheduler_observer can be created as local to a master - thread, to observe threads that work on behalf of that master. - Local observers may have new on_scheduler_leaving() callback. - ------------------------------------------------------------------------- -Intel TBB 4.0 Update 5 -TBB_INTERFACE_VERSION == 6005 - -Changes (w.r.t. Intel TBB 4.0 Update 4): - -- Parallel pipeline optimization (directly storing small objects in the - interstage data buffers) limited to trivially-copyable types for - C++11 and a short list of types for earlier compilers. -- _VARIADIC_MAX switch is honored for TBB tuple implementation - and flow::graph nodes based on tuple. -- Support of Cocoa framework was added to the GUI examples on OS X* - systems. - -Bugs fixed: - -- 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. -- Fixed duplicate symbol problem when linking multiple compilation - units that include flow_graph.h on VC 10. - ------------------------------------------------------------------------- -Intel TBB 4.0 Update 4 -TBB_INTERFACE_VERSION == 6004 - -Changes (w.r.t. Intel TBB 4.0 Update 3): - -- The TBB memory allocator transparently supports large pages on Linux. -- A new flow_graph example, logic_sim, was added. -- Support for DirectX* 9 was added to GUI examples. - -Community Preview Features: - -- Added: aggregator, a new concurrency control mechanism. - -Bugs fixed: - -- The abort operation on concurrent_bounded_queue now leaves the queue - in a reusable state. If a bad_alloc or bad_last_alloc exception is - thrown while the queue is recovering from an abort, that exception - will be reported instead of user_abort on the thread on which it - occurred, and the queue will not be reusable. -- Steal limiting heuristic fixed to avoid premature stealing disabling - when large amount of __thread data is allocated on thread stack. -- Fixed a low-probability leak of arenas in the task scheduler. -- In STL-compatible allocator classes, the method construct() was fixed - to comply with C++11 requirements. -- Fixed a bug that prevented creation of fixed-size memory pools - smaller than 2M. -- Significantly reduced the amount of warnings from various compilers. - -Open-source contributions integrated: - -- Multiple improvements by Raf Schietekat. -- Basic support for Clang on OS X* by Blas Rodriguez Somoza. -- Fixes for warnings and corner-case bugs by Blas Rodriguez Somoza - and Edward Lam. - ------------------------------------------------------------------------- -Intel TBB 4.0 Update 3 -TBB_INTERFACE_VERSION == 6003 - -Changes (w.r.t. Intel TBB 4.0 Update 2): - -- Modifications to the low-level API for memory pools: - added support for aligned allocations; - pool policies reworked to allow backward-compatible extensions; - added a policy to not return memory space till destruction; - pool_reset() does not return memory space anymore. -- Class tbb::flow::graph_iterator added to iterate over all nodes - registered with a graph instance. -- multioutput_function_node has been renamed multifunction_node. - multifunction_node and split_node are now fully-supported features. -- For the tagged join node, the policy for try_put of an item with - already existing tag has been defined: the item will be rejected. -- Matching the behavior on Windows, on other platforms the optional - shared libraries (libtbbmalloc, libirml) now are also searched - only in the directory where libtbb is located. -- The platform isolation layer based on GCC built-ins is extended. - -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, - write_once_node, broadcast_node, and the CPF or_node. -- the following tbb::flow node methods and typedefs have been renamed: - Old New - join_node and or_node: - inputs() -> input_ports() - input_ports_tuple_type -> input_ports_type - multifunction_node and split_node: - ports_type -> output_ports_type - -Bugs fixed: - -- Not all logical processors were utilized on systems with more than - 64 cores split by Windows into several processor groups. - ------------------------------------------------------------------------- -Intel TBB 4.0 Update 2 commercial-aligned release -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 - threads will receive a tbb::user_abort exception. -- Added Community Preview Feature: concurrent_lru_cache container, - a concurrent implementation of LRU (least-recently-used) cache. - -Bugs fixed: - -- fixed a race condition in the TBB scalable allocator. -- concurrent_queue counter wraparound bug was fixed, which occurred when - the number of push and pop operations exceeded ~>4 billion on IA32. -- fixed races in the TBB scheduler that could put workers asleep too - early, especially in presence of affinitized tasks. - ------------------------------------------------------------------------- -Intel TBB 4.0 Update 1 commercial-aligned release -TBB_INTERFACE_VERSION == 6000 (forgotten to increment) - -Changes (w.r.t. Intel TBB 4.0 commercial-aligned release): - -- Memory leaks fixed in binpack example. -- Improvements and fixes in the TBB allocator. - ------------------------------------------------------------------------- -Intel TBB 4.0 commercial-aligned release -TBB_INTERFACE_VERSION == 6000 - -Changes (w.r.t. Intel TBB 3.0 Update 8 commercial-aligned release): - -- concurrent_priority_queue is now a fully supported feature. - Capacity control methods were removed. -- Flow graph is now a fully supported feature. -- A new memory backend has been implemented in the TBB allocator. - It can reuse freed memory for both small and large objects, and - returns unused memory blocks to the OS more actively. -- Improved partitioning algorithms for parallel_for and parallel_reduce - to better handle load imbalance. -- The convex_hull example has been refactored for reproducible - performance results. -- The major interface version has changed from 5 to 6. - Deprecated interfaces might be removed in future releases. - -Community Preview Features: - -- Added: serial subset, i.e. sequential implementations of TBB generic - algorithms (currently, only provided for parallel_for). -- Preview of new flow graph nodes: - or_node (accepts multiple inputs, forwards each input separately - to all successors), - split_node (accepts tuples, and forwards each element of a tuple - to a corresponding successor), and - multioutput_function_node (accepts one input, and passes the input - and a tuple of output ports to the function body to support outputs - to multiple successors). -- Added: memory pools for more control on memory source, grouping, - and collective deallocation. - ------------------------------------------------------------------------- -Intel TBB 3.0 Update 8 commercial-aligned release -TBB_INTERFACE_VERSION == 5008 - -Changes (w.r.t. Intel TBB 3.0 Update 7 commercial-aligned release): - -- Task priorities become an official feature of TBB, - not community preview as before. -- Atomics API extended, and implementation refactored. -- Added task::set_parent() method. -- Added concurrent_unordered_set container. - -Open-source contributions integrated: - -- PowerPC support by Raf Schietekat. -- Fix of potential task pool overrun and other improvements - in the task scheduler by Raf Schietekat. -- Fix in parallel_for_each to work with std::set in Visual* C++ 2010. - -Community Preview Features: - -- Graph community preview feature was renamed to flow graph. - Multiple improvements in the implementation. - Binpack example was added for the feature. -- A number of improvements to concurrent_priority_queue. - Shortpath example was added for the feature. -- TBB runtime loaded functionality was added (Windows*-only). - It allows to specify which versions of TBB should be used, - as well as to set directories for the library search. -- parallel_deterministic_reduce template function was added. - ------------------------------------------------------------------------- -Intel TBB 3.0 Update 7 commercial-aligned release -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 - where GCC has these built-ins. - -Community Preview Features: - -- Graph's dining_philosophers example added. -- A number of improvements to graph and concurrent_priority_queue. - - ------------------------------------------------------------------------- -Intel TBB 3.0 Update 6 commercial-aligned release -TBB_INTERFACE_VERSION == 5006 - -Changes (w.r.t. Intel TBB 3.0 Update 5 commercial-aligned release): - -- Added Community Preview feature: task and task group priority, and - Fractal example demonstrating it. -- parallel_pipeline optimized for data items of small and large sizes. -- Graph's join_node is now parametrized with a tuple of up to 10 types. -- Improved performance of concurrent_priority_queue. - -Open-source contributions integrated: - -- Initial NetBSD support by Aleksej Saushev. - -Bugs fixed: - -- Failure to enable interoperability with Intel(R) Cilk(tm) Plus runtime - library, and a crash caused by invoking the interoperability layer - after one of the libraries was unloaded. -- Data race that could result in concurrent_unordered_map structure - corruption after call to clear() method. -- Stack corruption caused by PIC version of 64-bit CAS compiled by Intel - compiler on Linux. -- Inconsistency of exception propagation mode possible when application - built with Microsoft* Visual Studio* 2008 or earlier uses TBB built - with Microsoft* Visual Studio* 2010. -- Affinitizing master thread to a subset of available CPUs after TBB - scheduler was initialized tied all worker threads to the same CPUs. -- Method is_stolen_task() always returned 'false' for affinitized tasks. -- write_once_node and overwrite_node did not immediately send buffered - items to successors - ------------------------------------------------------------------------- -Intel TBB 3.0 Update 5 commercial-aligned release -TBB_INTERFACE_VERSION == 5005 - -Changes (w.r.t. Intel TBB 3.0 Update 4 commercial-aligned release): - -- Added Community Preview feature: graph. -- Added automatic propagation of master thread FPU settings to - TBB worker threads. -- Added a public function to perform a sequentially consistent full - memory fence: tbb::atomic_fence() in tbb/atomic.h. - -Bugs fixed: - -- Data race that could result in scheduler data structures corruption - when using fire-and-forget tasks. -- Potential referencing of destroyed concurrent_hash_map element after - using erase(accessor&A) method with A acquired as const_accessor. -- Fixed a correctness bug in the convex hull example. - -Open-source contributions integrated: - -- Patch for calls to internal::atomic_do_once() by Andrey Semashev. - ------------------------------------------------------------------------- -Intel TBB 3.0 Update 4 commercial-aligned release -TBB_INTERFACE_VERSION == 5004 - -Changes (w.r.t. Intel TBB 3.0 Update 3 commercial-aligned release): - -- Added Community Preview feature: concurrent_priority_queue. -- 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 - http://msdn.microsoft.com/en-us/library/dd405503.aspx. -- Default number of worker threads is adjusted in accordance with - process affinity mask. - -Bugs fixed: - -- Calls of scalable_* functions from inside the allocator library - caused issues if the functions were overridden by another module. -- A crash occurred if methods run() and wait() were called concurrently - for an empty tbb::task_group (1736). -- The tachyon example exhibited build problems associated with - bug 554339 on Microsoft* Visual Studio* 2010. Project files were - modified as a partial workaround to overcome the problem. See - http://connect.microsoft.com/VisualStudio/feedback/details/554339. - ------------------------------------------------------------------------- -Intel TBB 3.0 Update 3 commercial-aligned release -TBB_INTERFACE_VERSION == 5003 - -Changes (w.r.t. Intel TBB 3.0 Update 2 commercial-aligned release): - -- cache_aligned_allocator class reworked to use scalable_aligned_malloc. -- Improved performance of count() and equal_range() methods - in concurrent_unordered_map. -- Improved implementation of 64-bit atomic loads and stores on 32-bit - platforms, including compilation with VC 7.1. -- Added implementation of atomic operations on top of OSAtomic API - provided by OS X*. -- Removed gratuitous try/catch blocks surrounding thread function calls - in tbb_thread. -- Xcode* projects were added for sudoku and game_of_life examples. -- Xcode* projects were updated to work without TBB framework. - -Bugs fixed: - -- Fixed a data race in task scheduler destruction that on rare occasion - could result in memory corruption. -- Fixed idle spinning in thread bound filters in tbb::pipeline (1670). - -Open-source contributions integrated: - -- MinGW-64 basic support by brsomoza (partially). -- Patch for atomic.h by Andrey Semashev. -- Support for AIX & GCC on PowerPC by Giannis Papadopoulos. -- Various improvements by Raf Schietekat. - ------------------------------------------------------------------------- -Intel TBB 3.0 Update 2 commercial-aligned release -TBB_INTERFACE_VERSION == 5002 - -Changes (w.r.t. Intel TBB 3.0 Update 1 commercial-aligned release): - -- Destructor of tbb::task_group class throws missing_wait exception - if there are tasks running when it is invoked. -- Interoperability layer with Intel Cilk Plus runtime library added - to protect TBB TLS in case of nested usage with Intel Cilk Plus. -- Compilation fix for dependent template names in concurrent_queue. -- Memory allocator code refactored to ease development and maintenance. - -Bugs fixed: - -- Improved interoperability with other Intel software tools on Linux in - case of dynamic replacement of memory allocator (1700) -- Fixed install issues that prevented installation on - Mac OS* X 10.6.4 (1711). - ------------------------------------------------------------------------- -Intel TBB 3.0 Update 1 commercial-aligned release -TBB_INTERFACE_VERSION == 5000 (forgotten to increment) - -Changes (w.r.t. Intel TBB 3.0 commercial-aligned release): - -- Decreased memory fragmentation by allocations bigger than 8K. -- Lazily allocate worker threads, to avoid creating unnecessary stacks. - -Bugs fixed: - -- TBB allocator used much more memory than malloc (1703) - see above. -- Deadlocks happened in some specific initialization scenarios - of the TBB allocator (1701, 1704). -- Regression in enumerable_thread_specific: excessive requirements - for object constructors. -- A bug in construction of parallel_pipeline filters when body instance - 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 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. -- Return type of postfix form of operator++ for hash map's iterators. - ------------------------------------------------------------------------- -Intel TBB 3.0 commercial-aligned release -TBB_INTERFACE_VERSION == 5000 - -Changes (w.r.t. Intel TBB 2.2 Update 3 commercial-aligned release): - -- All open-source-release changes down to TBB 2.2 U3 below - were incorporated into this release. - ------------------------------------------------------------------------- -20100406 open-source release - -Changes (w.r.t. 20100310 open-source release): - -- Added support for Microsoft* Visual Studio* 2010, including binaries. -- Added a PDF file with recommended Design Patterns for TBB. -- Added parallel_pipeline function and companion classes and functions - that provide a strongly typed lambda-friendly pipeline interface. -- Reworked enumerable_thread_specific to use a custom implementation of - hash map that is more efficient for ETS usage models. -- Added example for class task_group; see examples/task_group/sudoku. -- Removed two examples, as they were long outdated and superceded: - pipeline/text_filter (use pipeline/square); - parallel_while/parallel_preorder (use parallel_do/parallel_preorder). -- PDF documentation updated. -- Other fixes and changes in code, tests, and examples. - -Bugs fixed: - -- Eliminated build errors with MinGW32. -- Fixed post-build step and other issues in VS projects for examples. -- Fixed discrepancy between scalable_realloc and scalable_msize that - caused crashes with malloc replacement on Windows. - ------------------------------------------------------------------------- -20100310 open-source release - -Changes (w.r.t. Intel TBB 2.2 Update 3 commercial-aligned release): - -- Version macros changed in anticipation of a future release. -- Directory structure aligned with Intel(R) C++ Compiler; - now TBB binaries reside in //[bin|lib] - (in TBB 2.x, it was [bin|lib]//). -- Visual Studio projects changed for examples: instead of separate set - of files for each VS version, now there is single 'msvs' directory - that contains workspaces for MS C++ compiler (_cl.sln) and - Intel C++ compiler (_icl.sln). Works with VS 2005 and above. -- The name versioning scheme for backward compatibility was improved; - now compatibility-breaking changes are done in a separate namespace. -- Added concurrent_unordered_map implementation based on a prototype - developed in Microsoft for a future version of PPL. -- Added PPL-compatible writer-preference RW lock (reader_writer_lock). -- Added TBB_IMPLEMENT_CPP0X macro to control injection of C++0x names - implemented in TBB into namespace std. -- Added almost-C++0x-compatible std::condition_variable, plus a bunch - of other C++0x classes required by condition_variable. -- With TBB_IMPLEMENT_CPP0X, tbb_thread can be also used as std::thread. -- task.cpp was split into several translation units to structure - TBB scheduler sources layout. Static data layout and library - initialization logic were also updated. -- TBB scheduler reworked to prevent master threads from stealing - work belonging to other masters. -- Class task was extended with enqueue() method, and slightly changed - semantics of methods spawn() and destroy(). For exact semantics, - refer to TBB Reference manual. -- task_group_context now allows for destruction by non-owner threads. -- Added TBB_USE_EXCEPTIONS macro to control use of exceptions in TBB - headers. It turns off (i.e. sets to 0) automatically if specified - compiler options disable exception handling. -- TBB is enabled to run on top of Microsoft's Concurrency Runtime - on Windows* 7 (via our worker dispatcher known as RML). -- Removed old unused busy-waiting code in concurrent_queue. -- Described the advanced build & test options in src/index.html. -- Warning level for GCC raised with -Wextra and a few other options. -- Multiple fixes and improvements in code, tests, examples, and docs. - -Open-source contributions integrated: - -- Xbox support by Roman Lut (Deep Shadows), though further changes are - required to make it working; e.g. post-2.1 entry points are missing. -- "Eventcount" by Dmitry Vyukov evolved into concurrent_monitor, - an internal class used in the implementation of concurrent_queue. - ------------------------------------------------------------------------- -Intel TBB 2.2 Update 3 commercial-aligned release -TBB_INTERFACE_VERSION == 4003 - -Changes (w.r.t. Intel TBB 2.2 Update 2 commercial-aligned release): - -- PDF documentation updated. - -Bugs fixed: - -- concurrent_hash_map compatibility issue exposed on Linux in case - two versions of the container were used by different modules. -- enforce 16 byte stack alignment for consistence with GCC; required - to work correctly with 128-bit variables processed by SSE. -- construct() methods of allocator classes now use global operator new. - ------------------------------------------------------------------------- -Intel TBB 2.2 Update 2 commercial-aligned release -TBB_INTERFACE_VERSION == 4002 - -Changes (w.r.t. Intel TBB 2.2 Update 1 commercial-aligned release): - -- parallel_invoke and parallel_for_each now take function objects - by const reference, not by value. -- Building TBB with /MT is supported, to avoid dependency on particular - versions of Visual C++* runtime DLLs. TBB DLLs built with /MT - are located in vc_mt directory. -- Class critical_section introduced. -- Improvements in exception support: new exception classes introduced, - all exceptions are thrown via an out-of-line internal method. -- Improvements and fixes in the TBB allocator and malloc replacement, - including robust memory identification, and more reliable dynamic - function substitution on Windows*. -- Method swap() added to class tbb_thread. -- Methods rehash() and bucket_count() added to concurrent_hash_map. -- Added support for Visual Studio* 2010 Beta2. No special binaries - provided, but CRT-independent DLLs (vc_mt) should work. -- Other fixes and improvements in code, tests, examples, and docs. - -Open-source contributions integrated: - -- The fix to build 32-bit TBB on Mac OS* X 10.6. -- GCC-based port for SPARC Solaris by Michailo Matijkiw, with use of - earlier work by Raf Schietekat. - -Bugs fixed: - -- 159 - TBB build for PowerPC* running Mac OS* X. -- 160 - IBM* Java segfault if used with TBB allocator. -- crash in concurrent_queue (1616). - ------------------------------------------------------------------------- -Intel TBB 2.2 Update 1 commercial-aligned release -TBB_INTERFACE_VERSION == 4001 - -Changes (w.r.t. Intel TBB 2.2 commercial-aligned release): - -- Incorporates all changes from open-source releases below. -- Documentation was updated. -- TBB scheduler auto-initialization now covers all possible use cases. -- concurrent_queue: made argument types of sizeof used in paddings - consistent with those actually used. -- Memory allocator was improved: supported corner case of user's malloc - calling scalable_malloc (non-Windows), corrected processing of - memory allocation requests during tbb memory allocator startup - (Linux). -- Windows malloc replacement has got better support for static objects. -- In pipeline setups that do not allow actual parallelism, execution - by a single thread is guaranteed, idle spinning eliminated, and - performance improved. -- RML refactoring and clean-up. -- New constructor for concurrent_hash_map allows reserving space for - a number of items. -- Operator delete() added to the TBB exception classes. -- Lambda support was improved in parallel_reduce. -- gcc 4.3 warnings were fixed for concurrent_queue. -- Fixed possible initialization deadlock in modules using TBB entities - during construction of global static objects. -- Copy constructor in concurrent_hash_map was fixed. -- Fixed a couple of rare crashes in the scheduler possible before - in very specific use cases. -- Fixed a rare crash in the TBB allocator running out of memory. -- New tests were implemented, including test_lambda.cpp that checks - support for lambda expressions. -- A few other small changes in code, tests, and documentation. - ------------------------------------------------------------------------- -20090809 open-source release - -Changes (w.r.t. Intel TBB 2.2 commercial-aligned release): - -- Fixed known exception safety issues in concurrent_vector. -- Better concurrency of simultaneous grow requests in concurrent_vector. -- TBB allocator further improves performance of large object allocation. -- Problem with source of text relocations was fixed on Linux -- Fixed bugs related to malloc replacement under Windows -- A few other small changes in code and documentation. - ------------------------------------------------------------------------- -Intel TBB 2.2 commercial-aligned release -TBB_INTERFACE_VERSION == 4000 - -Changes (w.r.t. Intel TBB 2.1 U4 commercial-aligned release): - -- Incorporates all changes from open-source releases below. -- Architecture folders renamed from em64t to intel64 and from itanium - to ia64. -- Major Interface version changed from 3 to 4. Deprecated interfaces - might be removed in future releases. -- Parallel algorithms that use partitioners have switched to use - the auto_partitioner by default. -- Improved memory allocator performance for allocations bigger than 8K. -- Added new thread-bound filters functionality for pipeline. -- New implementation of concurrent_hash_map that improves performance - significantly. -- A few other small changes in code and documentation. - ------------------------------------------------------------------------- -20090511 open-source release - -Changes (w.r.t. previous open-source release): - -- Basic support for MinGW32 development kit. -- Added tbb::zero_allocator class that initializes memory with zeros. - It can be used as an adaptor to any STL-compatible allocator class. -- Added tbb::parallel_for_each template function as alias to parallel_do. -- Added more overloads for tbb::parallel_for. -- Added support for exact exception propagation (can only be used with - compilers that support C++0x std::exception_ptr). -- tbb::atomic template class can be used with enumerations. -- mutex, recursive_mutex, spin_mutex, spin_rw_mutex classes extended - with explicit lock/unlock methods. -- Fixed size() and grow_to_at_least() methods of tbb::concurrent_vector - to provide space allocation guarantees. More methods added for - compatibility with std::vector, including some from C++0x. -- Preview of a lambda-friendly interface for low-level use of tasks. -- scalable_msize function added to the scalable allocator (Windows only). -- Rationalized internal auxiliary functions for spin-waiting and backoff. -- Several tests undergo decent refactoring. - -Changes affecting backward compatibility: - -- Improvements in concurrent_queue, including limited API changes. - The previous version is deprecated; its functionality is accessible - via methods of the new tbb::concurrent_bounded_queue class. -- grow* and push_back methods of concurrent_vector changed to return - iterators; old semantics is deprecated. - ------------------------------------------------------------------------- -Intel TBB 2.1 Update 4 commercial-aligned release -TBB_INTERFACE_VERSION == 3016 - -Changes (w.r.t. Intel TBB 2.1 U3 commercial-aligned release): - -- Added tests for aligned memory allocations and malloc replacement. -- Several improvements for better bundling with Intel(R) C++ Compiler. -- A few other small changes in code and documentaion. - -Bugs fixed: - -- 150 - request to build TBB examples with debug info in release mode. -- backward compatibility issue with concurrent_queue on Windows. -- dependency on VS 2005 SP1 runtime libraries removed. -- compilation of GUI examples under Xcode* 3.1 (1577). -- On Windows, TBB allocator classes can be instantiated with const types - for compatibility with MS implementation of STL containers (1566). - ------------------------------------------------------------------------- -20090313 open-source release - -Changes (w.r.t. 20081109 open-source release): - -- Includes all changes introduced in TBB 2.1 Update 2 & Update 3 - commercial-aligned releases (see below for details). -- Added tbb::parallel_invoke template function. It runs up to 10 - user-defined functions in parallel and waits for them to complete. -- Added a special library providing ability to replace the standard - memory allocation routines in Microsoft* C/C++ RTL (malloc/free, - global new/delete, etc.) with the TBB memory allocator. - Usage details are described in include/tbb/tbbmalloc_proxy.h file. -- Task scheduler switched to use new implementation of its core - functionality (deque based task pool, new structure of arena slots). -- Preview of Microsoft* Visual Studio* 2005 project files for - building the library is available in build/vsproject folder. -- Added tests for aligned memory allocations and malloc replacement. -- Added parallel_for/game_of_life.net example (for Windows only) - showing TBB usage in a .NET application. -- A number of other fixes and improvements to code, tests, makefiles, - examples and documents. - -Bugs fixed: - -- The same list as in TBB 2.1 Update 4 right above. - ------------------------------------------------------------------------- -Intel TBB 2.1 Update 3 commercial-aligned release -TBB_INTERFACE_VERSION == 3015 - -Changes (w.r.t. Intel TBB 2.1 U2 commercial-aligned release): - -- Added support for aligned allocations to the TBB memory allocator. -- Added a special library to use with LD_PRELOAD on Linux* in order to - replace the standard memory allocation routines in C/C++ with the - TBB memory allocator. -- Added null_mutex and null_rw_mutex: no-op classes interface-compliant - to other TBB mutexes. -- Improved performance of parallel_sort, to close most of the serial gap - with std::sort, and beat it on 2 and more cores. -- A few other small changes. - -Bugs fixed: - -- the problem where parallel_for hanged after exception throw - if affinity_partitioner was used (1556). -- get rid of VS warnings about mbstowcs deprecation (1560), - as well as some other warnings. -- operator== for concurrent_vector::iterator fixed to work correctly - with different vector instances. - ------------------------------------------------------------------------- -Intel TBB 2.1 Update 2 commercial-aligned release -TBB_INTERFACE_VERSION == 3014 - -Changes (w.r.t. Intel TBB 2.1 U1 commercial-aligned release): - -- Incorporates all open-source-release changes down to TBB 2.1 U1, - except for: - - 20081019 addition of enumerable_thread_specific; -- Warning level for Microsoft* Visual C++* compiler raised to /W4 /Wp64; - warnings found on this level were cleaned or suppressed. -- Added TBB_runtime_interface_version API function. -- Added new example: pipeline/square. -- Added exception handling and cancellation support - for parallel_do and pipeline. -- Added copy constructor and [begin,end) constructor to concurrent_queue. -- Added some support for beta version of Intel(R) Parallel Amplifier. -- Added scripts to set environment for cross-compilation of 32-bit - applications on 64-bit Linux with Intel(R) C++ Compiler. -- Fixed semantics of concurrent_vector::clear() to not deallocate - internal arrays. Fixed compact() to perform such deallocation later. -- Fixed the issue with atomic when T is incomplete type. -- Improved support for PowerPC* Macintosh*, including the fix - for a bug in masked compare-and-swap reported by a customer. -- As usual, a number of other improvements everywhere. - ------------------------------------------------------------------------- -20081109 open-source release - -Changes (w.r.t. previous open-source release): - -- Added new serial out of order filter for tbb::pipeline. -- Fixed the issue with atomic::operator= reported at the forum. -- Fixed the issue with using tbb::task::self() in task destructor - reported at the forum. -- A number of other improvements to code, tests, makefiles, examples - and documents. - -Open-source contributions integrated: -- Changes in the memory allocator were partially integrated. - ------------------------------------------------------------------------- -20081019 open-source release - -Changes (w.r.t. previous open-source release): - -- Introduced enumerable_thread_specific. This new class provides a - wrapper around native thread local storage as well as iterators and - ranges for accessing the thread local copies (1533). -- Improved support for Intel(R) Threading Analysis Tools - on Intel(R) 64 architecture. -- Dependency from Microsoft* CRT was integrated to the libraries using - manifests, to avoid issues if called from code that uses different - version of Visual C++* runtime than the library. -- Introduced new defines TBB_USE_ASSERT, TBB_USE_DEBUG, - TBB_USE_PERFORMANCE_WARNINGS, TBB_USE_THREADING_TOOLS. -- A number of other improvements to code, tests, makefiles, examples - and documents. - -Open-source contributions integrated: - -- linker optimization: /incremental:no . - ------------------------------------------------------------------------- -20080925 open-source release - -Changes (w.r.t. previous open-source release): - -- Same fix for a memory leak in the memory allocator as in TBB 2.1 U1. -- Improved support for lambda functions. -- Fixed more concurrent_queue issues reported at the forum. -- A number of other improvements to code, tests, makefiles, examples - and documents. - ------------------------------------------------------------------------- -Intel TBB 2.1 Update 1 commercial-aligned release -TBB_INTERFACE_VERSION == 3013 - -Changes (w.r.t. Intel TBB 2.1 commercial-aligned release): - -- Fixed small memory leak in the memory allocator. -- Incorporates all open-source-release changes since TBB 2.1, - except for: - - 20080825 changes for parallel_do; - ------------------------------------------------------------------------- -20080825 open-source release - -Changes (w.r.t. previous open-source release): - -- Added exception handling and cancellation support for parallel_do. -- Added default HashCompare template argument for concurrent_hash_map. -- Fixed concurrent_queue.clear() issues due to incorrect assumption - about clear() being private method. -- Added the possibility to use TBB in applications that change - default calling conventions (Windows* only). -- Many improvements to code, tests, examples, makefiles and documents. - -Bugs fixed: - -- 120, 130 - memset declaration missed in concurrent_hash_map.h - ------------------------------------------------------------------------- -20080724 open-source release - -Changes (w.r.t. previous open-source release): - -- Inline assembly for atomic operations improved for gcc 4.3 -- A few more improvements to the code. - ------------------------------------------------------------------------- -20080709 open-source release - -Changes (w.r.t. previous open-source release): - -- operator=() was added to the tbb_thread class according to - the current working draft for std::thread. -- Recognizing SPARC* in makefiles for Linux* and Sun Solaris*. - -Bugs fixed: - -- 127 - concurrent_hash_map::range fixed to split correctly. - -Open-source contributions integrated: - -- fix_set_midpoint.diff by jyasskin -- SPARC* support in makefiles by Raf Schietekat - ------------------------------------------------------------------------- -20080622 open-source release - -Changes (w.r.t. previous open-source release): - -- Fixed a hang that rarely happened on Linux - during deinitialization of the TBB scheduler. -- Improved support for Intel(R) Thread Checker. -- A few more improvements to the code. - ------------------------------------------------------------------------- -Intel TBB 2.1 commercial-aligned release -TBB_INTERFACE_VERSION == 3011 - -Changes (w.r.t. Intel TBB 2.0 U3 commercial-aligned release): - -- All open-source-release changes down to, and including, TBB 2.0 below, - were incorporated into this release. - ------------------------------------------------------------------------- -20080605 open-source release - -Changes (w.r.t. previous open-source release): - -- Explicit control of exported symbols by version scripts added on Linux. -- Interfaces polished for exception handling & algorithm cancellation. -- Cache behavior improvements in the scalable allocator. -- Improvements in text_filter, polygon_overlay, and other examples. -- A lot of other stability improvements in code, tests, and makefiles. -- First release where binary packages include headers/docs/examples, so - binary packages are now self-sufficient for using TBB. - -Open-source contributions integrated: - -- atomics patch (partially). -- tick_count warning patch. - -Bugs fixed: - -- 118 - fix for boost compatibility. -- 123 - fix for tbb_machine.h. - ------------------------------------------------------------------------- -20080512 open-source release - -Changes (w.r.t. previous open-source release): - -- Fixed a problem with backward binary compatibility - of debug Linux builds. -- Sun* Studio* support added. -- soname support added on Linux via linker script. To restore backward - binary compatibility, *.so -> *.so.2 softlinks should be created. -- concurrent_hash_map improvements - added few new forms of insert() - method and fixed precondition and guarantees of erase() methods. - Added runtime warning reporting about bad hash function used for - the container. Various improvements for performance and concurrency. -- Cancellation mechanism reworked so that it does not hurt scalability. -- Algorithm parallel_do reworked. Requirement for Body::argument_type - definition removed, and work item argument type can be arbitrarily - cv-qualified. -- polygon_overlay example added. -- A few more improvements to code, tests, examples and Makefiles. - -Open-source contributions integrated: - -- Soname support patch for Bugzilla #112. - -Bugs fixed: - -- 112 - fix for soname support. - ------------------------------------------------------------------------- -Intel TBB 2.0 U3 commercial-aligned release (package 017, April 20, 2008) - -Corresponds to commercial 019 (for Linux*, 020; for Mac OS* X, 018) -packages. - -Changes (w.r.t. Intel TBB 2.0 U2 commercial-aligned release): - -- Does not contain open-source-release changes below; this release is - only a minor update of TBB 2.0 U2. -- Removed spin-waiting in pipeline and concurrent_queue. -- A few more small bug fixes from open-source releases below. - ------------------------------------------------------------------------- -20080408 open-source release - -Changes (w.r.t. previous open-source release): - -- count_strings example reworked: new word generator implemented, hash - function replaced, and tbb_allocator is used with std::string class. -- Static methods of spin_rw_mutex were replaced by normal member - functions, and the class name was versioned. -- tacheon example was renamed to tachyon. -- Improved support for Intel(R) Thread Checker. -- A few more minor improvements. - -Open-source contributions integrated: - -- Two sets of Sun patches for IA Solaris support. - ------------------------------------------------------------------------- -20080402 open-source release - -Changes (w.r.t. previous open-source release): - -- Exception handling and cancellation support for tasks and algorithms - fully enabled. -- Exception safety guaranties defined and fixed for all concurrent - containers. -- User-defined memory allocator support added to all concurrent - containers. -- Performance improvement of concurrent_hash_map, spin_rw_mutex. -- Critical fix for a rare race condition during scheduler - initialization/de-initialization. -- New methods added for concurrent containers to be closer to STL, - as well as automatic filters removal from pipeline - and __TBB_AtomicAND function. -- The volatile keyword dropped from where it is not really needed. -- A few more minor improvements. - ------------------------------------------------------------------------- -20080319 open-source release - -Changes (w.r.t. previous open-source release): - -- Support for gcc version 4.3 was added. -- tbb_thread class, near compatible with std::thread expected in C++0x, - was added. - -Bugs fixed: - -- 116 - fix for compilation issues with gcc version 4.2.1. -- 120 - fix for compilation issues with gcc version 4.3. - ------------------------------------------------------------------------- -20080311 open-source release - -Changes (w.r.t. previous open-source release): - -- An enumerator added for pipeline filter types (serial vs. parallel). -- New task_scheduler_observer class introduced, to observe when - threads start and finish interacting with the TBB task scheduler. -- task_scheduler_init reverted to not use internal versioned class; - binary compatibility guaranteed with stable releases only. -- Various improvements to code, tests, examples and Makefiles. - ------------------------------------------------------------------------- -20080304 open-source release - -Changes (w.r.t. previous open-source release): - -- Task-to-thread affinity support, previously kept under a macro, - now fully legalized. -- Work-in-progress on cache_aligned_allocator improvements. -- Pipeline really supports parallel input stage; it's no more serialized. -- Various improvements to code, tests, examples and Makefiles. - -Bugs fixed: - -- 119 - fix for scalable_malloc sometimes failing to return a big block. -- TR575 - fixed a deadlock occurring on Windows in startup/shutdown - under some conditions. - ------------------------------------------------------------------------- -20080226 open-source release - -Changes (w.r.t. previous open-source release): - -- Introduced tbb_allocator to select between standard allocator and - tbb::scalable_allocator when available. -- Removed spin-waiting in pipeline and concurrent_queue. -- Improved performance of concurrent_hash_map by using tbb_allocator. -- Improved support for Intel(R) Thread Checker. -- Various improvements to code, tests, examples and Makefiles. - ------------------------------------------------------------------------- -Intel TBB 2.0 U2 commercial-aligned release (package 017, February 14, 2008) - -Corresponds to commercial 017 (for Linux*, 018; for Mac OS* X, 016) -packages. - -Changes (w.r.t. Intel TBB 2.0 U1 commercial-aligned release): - -- Does not contain open-source-release changes below; this release is - only a minor update of TBB 2.0 U1. -- Add support for Microsoft* Visual Studio* 2008, including binary - libraries and VS2008 projects for examples. -- Use SwitchToThread() not Sleep() to yield threads on Windows*. -- Enhancements to Doxygen-readable comments in source code. -- A few more small bug fixes from open-source releases below. - -Bugs fixed: - -- TR569 - Memory leak in concurrent_queue. - ------------------------------------------------------------------------- -20080207 open-source release - -Changes (w.r.t. previous open-source release): - -- Improvements and minor fixes in VS2008 projects for examples. -- Improvements in code for gating worker threads that wait for work, - previously consolidated under #if IMPROVED_GATING, now legalized. -- Cosmetic changes in code, examples, tests. - -Bugs fixed: - -- 113 - Iterators and ranges should be convertible to their const - counterparts. -- TR569 - Memory leak in concurrent_queue. - ------------------------------------------------------------------------- -20080122 open-source release - -Changes (w.r.t. previous open-source release): - -- Updated examples/parallel_for/seismic to improve the visuals and to - use the affinity_partitioner (20071127 and forward) for better - performance. -- Minor improvements to unittests and performance tests. - ------------------------------------------------------------------------- -20080115 open-source release - -Changes (w.r.t. previous open-source release): - -- Cleanup, simplifications and enhancements to the Makefiles for - building the libraries (see build/index.html for high-level - changes) and the examples. -- Use SwitchToThread() not Sleep() to yield threads on Windows*. -- Engineering work-in-progress on exception safety/support. -- Engineering work-in-progress on affinity_partitioner for - parallel_reduce. -- Engineering work-in-progress on improved gating for worker threads - (idle workers now block in the OS instead of spinning). -- Enhancements to Doxygen-readable comments in source code. - -Bugs fixed: - -- 102 - Support for parallel build with gmake -j -- 114 - /Wp64 build warning on Windows*. - ------------------------------------------------------------------------- -20071218 open-source release - -Changes (w.r.t. previous open-source release): - -- Full support for Microsoft* Visual Studio* 2008 in open-source. - Binaries for vc9/ will be available in future stable releases. -- New recursive_mutex class. -- Full support for 32-bit PowerMac including export files for builds. -- Improvements to parallel_do. - ------------------------------------------------------------------------- -20071206 open-source release - -Changes (w.r.t. previous open-source release): - -- Support for Microsoft* Visual Studio* 2008 in building libraries - from source as well as in vc9/ projects for examples. -- Small fixes to the affinity_partitioner first introduced in 20071127. -- Small fixes to the thread-stack size hook first introduced in 20071127. -- Engineering work in progress on concurrent_vector. -- Engineering work in progress on exception behavior. -- Unittest improvements. - ------------------------------------------------------------------------- -20071127 open-source release - -Changes (w.r.t. previous open-source release): - -- Task-to-thread affinity support (affinity partitioner) first appears. -- More work on concurrent_vector. -- New parallel_do algorithm (function-style version of parallel while) - and parallel_do/parallel_preorder example. -- New task_scheduler_init() hooks for getting default_num_threads() and - for setting thread stack size. -- Support for weak memory consistency models in the code base. -- Futex usage in the task scheduler (Linux). -- Started adding 32-bit PowerMac support. -- Intel(R) 9.1 compilers are now the base supported Intel(R) compiler - version. -- TBB libraries added to link line automatically on Microsoft Windows* - systems via #pragma comment linker directives. - -Open-source contributions integrated: - -- FreeBSD platform support patches. -- AIX weak memory model patch. - -Bugs fixed: - -- 108 - Removed broken affinity.h reference. -- 101 - Does not build on Debian Lenny (replaced arch with uname -m). - ------------------------------------------------------------------------- -20071030 open-source release - -Changes (w.r.t. previous open-source release): - -- More work on concurrent_vector. -- Better support for building with -Wall -Werror (or not) as desired. -- A few fixes to eliminate extraneous warnings. -- Begin introduction of versioning hooks so that the internal/API - version is tracked via TBB_INTERFACE_VERSION. The newest binary - libraries should always work with previously-compiled code when- - ever possible. -- Engineering work in progress on using futex inside the mutexes (Linux). -- Engineering work in progress on exception behavior. -- Engineering work in progress on a new parallel_do algorithm. -- Unittest improvements. - ------------------------------------------------------------------------- -20070927 open-source release - -Changes (w.r.t. Intel TBB 2.0 U1 commercial-aligned release): - -- Minor update to TBB 2.0 U1 below. -- Begin introduction of new concurrent_vector interfaces not released - with TBB 2.0 U1. - ------------------------------------------------------------------------- -Intel TBB 2.0 U1 commercial-aligned release (package 014, October 1, 2007) - -Corresponds to commercial 014 (for Linux*, 016) packages. - -Changes (w.r.t. Intel TBB 2.0 commercial-aligned release): - -- All open-source-release changes down to, and including, TBB 2.0 - below, were incorporated into this release. -- Made a number of changes to the officially supported OS list: - Added Linux* OSs: - Asianux* 3, Debian* 4.0, Fedora Core* 6, Fedora* 7, - Turbo Linux* 11, Ubuntu* 7.04; - Dropped Linux* OSs: - Asianux* 2, Fedora Core* 4, Haansoft* Linux 2006 Server, - Mandriva/Mandrake* 10.1, Miracle Linux* 4.0, - Red Flag* DC Server 5.0; - Only Mac OS* X 10.4.9 (and forward) and Xcode* tool suite 2.4.1 (and - forward) are now supported. -- Commercial installers on Linux* fixed to recommend the correct - binaries to use in more cases, with less unnecessary warnings. -- Changes to eliminate spurious build warnings. - -Open-source contributions integrated: - -- Two small header guard macro patches; it also fixed bug #94. -- New blocked_range3d class. - -Bugs fixed: - -- 93 - Removed misleading comments in task.h. -- 94 - See above. - ------------------------------------------------------------------------- -20070815 open-source release - -Changes: - -- Changes to eliminate spurious build warnings. -- Engineering work in progress on concurrent_vector allocator behavior. -- Added hooks to use the Intel(R) compiler code coverage tools. - -Open-source contributions integrated: - -- Mac OS* X build warning patch. - -Bugs fixed: - -- 88 - Fixed TBB compilation errors if both VS2005 and Windows SDK are - installed. - ------------------------------------------------------------------------- -20070719 open-source release - -Changes: - -- Minor update to TBB 2.0 commercial-aligned release below. -- Changes to eliminate spurious build warnings. - ------------------------------------------------------------------------- -Intel TBB 2.0 commercial-aligned release (package 010, July 19, 2007) - -Corresponds to commercial 010 (for Linux*, 012) packages. - -- TBB open-source debut release. - ------------------------------------------------------------------------- -Intel TBB 1.1 commercial release (April 10, 2007) - -Changes (w.r.t. Intel TBB 1.0 commercial release): - -- auto_partitioner which offered an automatic alternative to specifying - a grain size parameter to estimate the best granularity for tasks. -- The release was added to the Intel(R) C++ Compiler 10.0 Pro. - ------------------------------------------------------------------------- -Intel TBB 1.0 Update 2 commercial release - -Changes (w.r.t. Intel TBB 1.0 Update 1 commercial release): - -- Mac OS* X 64-bit support added. -- Source packages for commercial releases introduced. - ------------------------------------------------------------------------- -Intel TBB 1.0 Update 1 commercial-aligned release - -Changes (w.r.t. Intel TBB 1.0 commercial release): - -- Fix for critical package issue on Mac OS* X. - ------------------------------------------------------------------------- -Intel TBB 1.0 commercial release (August 29, 2006) - -Changes (w.r.t. Intel TBB 1.0 beta commercial release): - -- New namespace (and compatibility headers for old namespace). - Namespaces are tbb and tbb::internal and all classes are in the - underscore_style not the WindowsStyle. -- New class: scalable_allocator (and cache_aligned_allocator using that - if it exists). -- Added parallel_for/tacheon example. -- Removed C-style casts from headers for better C++ compliance. -- Bug fixes. -- Documentation improvements. -- Improved performance of the concurrent_hash_map class. -- Upgraded parallel_sort() to support STL-style random-access iterators - instead of just pointers. -- The Windows vs7_1 directories renamed to vs7.1 in examples. -- New class: spin version of reader-writer lock. -- Added push_back() interface to concurrent_vector(). - ------------------------------------------------------------------------- -Intel TBB 1.0 beta commercial release - -Initial release. - -Features / APIs: - -- Concurrent containers: ConcurrentHashTable, ConcurrentVector, - ConcurrentQueue. -- Parallel algorithms: ParallelFor, ParallelReduce, ParallelScan, - ParallelWhile, Pipeline, ParallelSort. -- Support: AlignedSpace, BlockedRange (i.e., 1D), BlockedRange2D -- Task scheduler with multi-master support. -- Atomics: read, write, fetch-and-store, fetch-and-add, compare-and-swap. -- Locks: spin, reader-writer, queuing, OS-wrapper. -- Memory allocation: STL-style memory allocator that avoids false - sharing. -- Timers. - -Tools Support: -- Intel(R) Thread Checker 3.0. -- Intel(R) Thread Profiler 3.0. - -Documentation: -- First Use Documents: README.txt, INSTALL.txt, Release_Notes.txt, - Doc_Index.html, Getting_Started.pdf, Tutorial.pdf, Reference.pdf. -- Class hierarchy HTML pages (Doxygen). -- Tree of index.html pages for navigating the installed package, esp. - for the examples. - -Examples: -- One for each of these TBB features: ConcurrentHashTable, ParallelFor, - ParallelReduce, ParallelWhile, Pipeline, Task. -- Live copies of examples from Getting_Started.pdf. -- TestAll example that exercises every class and header in the package - (i.e., a "liveness test"). -- Compilers: see Release_Notes.txt. -- APIs: OpenMP, WinThreads, Pthreads. - -Packaging: -- Package for Windows installs IA-32 and EM64T bits. -- Package for Linux installs IA-32, EM64T and IPF bits. -- Package for Mac OS* X installs IA-32 bits. -- All packages support Intel(R) software setup assistant (ISSA) and - install-time FLEXlm license checking. -- ISSA support allows license file to be specified directly in case of - no Internet connection or problems with IRC or serial #s. -- Linux installer allows root or non-root, RPM or non-RPM installs. -- FLEXlm license servers (for those who need floating/counted licenses) - are provided separately on Intel(R) Premier. - ------------------------------------------------------------------------- -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 deleted file mode 100644 index 261eeb9e..00000000 --- a/lib/3rdParty/tbb/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - 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/README b/lib/3rdParty/tbb/README deleted file mode 100644 index fcc87af0..00000000 --- a/lib/3rdParty/tbb/README +++ /dev/null @@ -1,11 +0,0 @@ -Intel(R) Threading Building Blocks - README - -See index.html for directions and documentation. - -If source is present (./Makefile and src/ directories), -type 'gmake' in this directory to build and test. - -See examples/index.html for runnable examples and directions. - -See http://threadingbuildingblocks.org for full documentation -and software information. diff --git a/lib/3rdParty/tbb/bin/x64/v140/irml/irml.dll b/lib/3rdParty/tbb/bin/x64/v140/irml/irml.dll deleted file mode 100644 index eff1eeee571cadd45fad700656726c1a03b172bd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 79600 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 diff --git a/lib/3rdParty/tbb/bin/x64/v140/irml/irml_debug.dll b/lib/3rdParty/tbb/bin/x64/v140/irml/irml_debug.dll deleted file mode 100644 index c6863995dbf3f5ce8bb9f5a0ed360da25003e306..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 138992 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 U{o;pLvuh2v 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

PrMwZd+J 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

8T1YB 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 ZAx}H68++BpE6nx}y>0HlarkYV{{Z0|`+NWZ diff --git a/lib/3rdParty/tbb/bin/x64/v140/tbbmalloc_proxy.dll b/lib/3rdParty/tbb/bin/x64/v140/tbbmalloc_proxy.dll deleted file mode 100644 index 7e5330959a9c068fdba4232a2dee5a7c61995758..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 42768 zcmeFa3tUvy_cwe77(fsQg;BhZii-E)rYNF}fF5*E6ue|AAPg5pz+v!SqJW7fv@A=_ z49rSRQ_B)B6^II6%3I~NB(oaC@|u!q^M2PpXKrY}-~ai%|L1w1=Xrmp_E~$cz0O*D zt-bcz`|N!fV}v|n|KPtV9z z<><51^hvW+$w^sR*#^~gol2jVrOL=sMUIJ6&B{*E_4V*@^OacZ-}w1<|A)f6<}`Gb z&$~lV_Sm{&QxM?u+eGNGbvY}0Y+bo2gw?OwG#GF*=z;$=r(T^HVt59 z!@D9ZX611i$>}7kv1YMR9G9}pl^ZcR=s9!UZLYJ*-Ju!BjRaaf$=*jZ=P+!bD zaGWzkSs}-v7Dj#R0mnITi71EhE&ZR7;|p$1+DE?1m&g-gvB0x@aqMlRhGI{? zB;1EDsFUU0-gnGr2ei#t-1MTWxYgAu6#n*Kr zvq6bmL6pLuXuEKU2RoBe2kHk^GK0r{ALZ|=Y2m+9*>VWMUNni$Iq@+nzh8F-i+oQH0oLPFpJ$=$==A$cY8Ed+`e`Ks8+ z&1=dA#t0qGLFxEs?LAMOEi{;Va`1g#5w^gBLF> zy5h&1s!T`uB2(VwU9$S_`zQeN$v>EsKgMvJR?uEiVGPEQ7@;OcIBFc%p5p>4$WGv` zMQa038aps$xBKSPvjvA^HPaHNHMXC@*OU4~%_A}-^1>r(u!L|$YKG$|uk>rU~-2I5kKHns+VR;V)WZpU%^ z5UDtm@@r-du;2v)T3T>eZSGdqpWx~{lODRL70yKk9!pJ4Rdg)GlN=WtpeC9b!@mW)@*O@#Q-c(U^Ebq6Xvj(qdQ)P6)AHN80FSf4zQLpsNC6F9!TXD)^ahG9jxW&sC>7lg&(WGCY7~< zM_nfBZ&=IwsC>y;oxFkCVJtN#1HJJ(IW8THa0ddTV(Jm8VJayr{b@4sC1L$iDf}x6%Mt5oUP))Q+7gdBX~>b~F*qd3kut+N=S zM>j3M!5#g9=~aiMBQ>-eTRL zyntRYI@+ihVUZan$&@C$38K^ws2i=O^^>GlC@m^}kJnR@`x{APa^Ka_Gh&ziD$30v zxq`}S+7m#Cx_(6xtdr~yV28F3wU@gKMbehH%GHrvvqfRx-$;`175wKD5F0y4!WP4@ z(|{0#B@$b!u-T%prG&LA8G#}RyX+;_YzwmTSM-%)!=66+`j5F7JsgnbHTqLO=w zt+k_SzynI2u@|-;MN%@rDr^i1gOdHoq)bVrjgo(&2jC!Q(ILhsSX7#g8)lI^)Lw3^ zD7TDy(CQ$aCAs@sSd=_JOq5$q(wN-0r_(cHr`{3e&LFu(Hgb;uA?jOA60G`O06XYA z&|dB~6iMGY`zX;Ww*wij zM7a}ejMv&)<#x8n^|hB9EXsY+UapHI_Z?4*)eeT+chPlA7de2~m}evGQ!tbKpV(Tv zs0KX9|LujXN0IrzRoEC32LE40CKdhPM#(1kMgK>K7@xGUDj8;xJJeootSGmPdeG_` zoh7;Z6&5AW4;AHhx5#}v!D?KYD0c?QEwYh&1PIChNrF}13t&h7Z!dQnip>A5auZ0d zjsK4zNi4YR0I|_W62|-=2+9A6tyS1eQP?8FT9ph#k@|HRhXMK$0-{%Vtj(t zp;^f=i`=31a$`lgWz>UK*XS(C-QU!rHg##>rUQn!9K{5R(5R zXVdx}XcYNB+|j1>i$TQv-`e^h*7_3pLFyPL_t9jl+#zBY?F1X+HLNntaywh(`r6A4 z7UjNZFV{tq`;ME%Y6l0|cTps1DEdE$jd?c0J_R$$|B0=&i)z4w{NG;KdK8)eTZN4w zVetP`WKz-pZItZsyXgPu5aSc949!Z0S>z72mm4d}Eu$W^x<+S7?*1kgCC?8O<)&HW zzKz2wbEkF^<<20vMK*Ge03rE5NwDgB0qn^C?d5Jmk@>$>ZUV`*@&6A3Y#ekTSQo^l3^$^|97=0c^6Bar~Mz>>d#*Po7X>aFe2JyTzJFI|DC8~ zME{>el12X?eoOR!j7j5UtZU6(v>ph_|BCfu=OZ1|F;SoL&D(yJISP?|Jx`zuwL|kbcpc@R)%IJ!z^-# z+RKd<<(5$oT3w^FBzM2FMalDYt^~OwEOOtTU^TA4D0c?QEwYh&1PIChNrF}13t&h7 zZ!dQnip>A5auZ0djsKq~NuvLQ*ytk(WBw0>TSwB>yM2)-I|65AuI|Ve3(3{%;jFhJ?WnZ;?qw z|F=;x+9>)zI>h({D?_uAVHUYV?d8Uba?7X(t*+5olDps0qU8BNQSM6?xo^i=jjIvm z&LFu(Hgb;uA^AT^up>K^Gg0= zS58rQn1fW>RN_VpdwS*Ma~!nM3PYoX??wxSz2*TCEu0!AZ10tiEZaUb4#Rqvx~>J( zQ51ay4h2tSilX71W zZtC+@e2K>ij2^KwzCzBXGk);rxESGUGLcF=WZMG*>IkjO(h(UTf|q*~S-8Ap&t>gX zT(TrC&Q>m6h>P{Yc|V~B>IENmk{K;rj20Sr;Vv)K8BZ`H z<2-T-cF%>Q*o@=_95ioMLmbWp!+CT7Psfn4WP9^5q(wizINsM&i?HjXEynR#+yv>Y z^bucTpySeu#u*S`8C!HveU1r;AOXa2+Vhsif-7I#9Ov|Oq#lWL{3?83KqvRb8do~i z#{oV&zsJGzMZQGi8F*|zecD0i#OD1}zL>|?9ehJEtV~~b+^~M#5#3k(x}&(j)rXYB zhZ=8jl*7TVr45H{`i_*uX9%{j(2>*7u3u0 zV0AjGhgos(NC)5rwukoYBL$0fPoC5YSK>4iG!ywHH(wzS5ac&T1BfT?Igx_LPqWFf z@922Jsp}+AL@7RNh%TP#1IhcGP>wEMcwwaAR1+yQl|>HpC`^aFR&_u)(hAB16k>23 z+(J7rI2rl8CcNM=4w?FKqY4Ip$Bim+`VJU6?=TF+5pyIp00XqfgrnsA!46#BLq4<; z--Xmfn+{o?$h*uJdo;x}+G6FCGy=iSC!Z1=4o zSny|J}jL-~U}NfA{0(-E6mE7aipJo@29)~?T7 z^Z)E=aMlcJ%H=hO+R-IVWqjyy{V#YRZ!GQChhEZejVd%5{Lnd1QXv*Dp~1ZKBO=58 zdb9)Q3U$aM)cg)$It`!32M9Uz0m9p)-jc)AwVDJCh5~=)246DFRR4W`SUGrcd1u*C z%2D|?lyE@f)Q9*f-vcAfK4OmWro|XkK}aDJqHGReOnGcFNry0Ju(l$q68RXBKt%)* zR)Sq3fl2ueGA3mb?i3fFgG6I^D}>mv7-UU~qGRlc%Oe~mbgDnqSG2_8=x*SRJ+TC* z@he3cjL{`*bRo?2s-!{CM;vSoKDi!b0RxNXu?bb0a)bg{2TGvFP0D>eQ7ULq=Ut?6 zl`gzQ!xclxaSBEZZmJUA#6LX4ce%)i-kamfBWU%is&}RV-RmeHcGYBBtSH$^7PV!3 z!lX=;7%Ped)Gk@%8%|#_=4})u@B{H7ivCsMO%kVJV@FfYQIrz!tT#O?oTk1V%L^|t zRS@+O3E?NK5+e#)%j2`M;#k*W9>auDVIW#GwW5g929Jo4Zf6rq1i<$Oep;cJ36PdT5Sov{1wMI!?+TkM32&FZq+Sf5BUTct=oF>O1fS6+Y3(oQxKZ z8>eCPiCW|-5qJEmqDy!c!X@}rurd$E_`V7_d}l=j)CE3lL4$985Qgw^Rt!b91{T>a zYQDtM7$1inr+%p9dmW;t96^7G{jkU>u%bSSe1eZDdSGatKd>%uq@a;SJD%blYod#r z^r}DVSXc0yym+QeQ(%(M!D?fnyqpb(k}-eX+g8rl!%{p&P54x%?<5MCG+5v{yYNvL zrjt{~Z*d$HDKr!`$a6bl=zW1uzuyG|A5MQ3d3bX!fU%h~^RF;0bGpi{1@E;hnT?&IWXgJ zm=PbKLGkDIt6-++;{NoFNqBXnZ#Y~JE%`dKWEj3X{IWY+{RQGMB!Nf^f)P0Y#)nCwG@IZW|#a3MtHSwD9=8l8r zG1E!&uER%?^oudVpV9c{O1P`}9EO3wliJW;MN)6ix&ZW{4>=DGI%i&kwE3Yb!*^_>xg_<`Igz$7qQbL4(w*HuvyX#(Ox@ zi4=?l4bH5GuOLY6A1U^*4`L#E_*I~cy)oxOPhFBlodN$^9Un`VDwgh`PLWhP#=7;S zv6qcX>sY7Rb*-Y1R%}sd+Az?v0dl z=wBD~uUr<{>t1TLqp7Q=;CJW9;#>z!!4qdTE}W%t5%UP+g8Hi-M`z4Vb=jCyDSk}B z=)e$3q}Y;f9w(Zqnkklb8@YzK6l7oIvG4dWM?YeQ%R;BT87Ev#??16J!#oFu7_E8EWT@w>qR4Hms;LsAPQ1!FMmY!&Q_7MPUzXbz&HsNheX zZ53>f2mT8RK1ehxc!eq0O;qqILqowgB&PqMpvyli_zeBjSjPoVr2$H>N$f3&f_f_x zoWtJv*b7m9m;%IH-Zg2VCPN7ewdY~;NE#=WFN)?P%4>yc<1yO0FS=}KFRjn~K}pVE zqI?My@O9${ppYuPsq4u79g#69k3dm#*D$EX#E!%G{!o}|ZBCMA7`#f(>Q4D$nCD2pm6M8zt2tmp0CD*vs# zwsgb-u2>a)%@>?N9`E=pcF>C}2{tKjbs}-LVh~!W>+EHb0sra!^^)}d`loRl4qUau z37Ss*m_T!=GzTn6=mH2u)WG-uB!%8;O6!Yl(qy`u=Ww@*uRP{imn;|CTOvP#7={;h%lGvq@=pkZ z_*X1@a7bowW8bSA+hCruepC-%YY*OVP%Ie&4;B14ls{JkPt*!>Im1_Kgwy+w;|i_~ z?R6ZL(acj3g9R#ql>T1A&$zHTUJz% zB~9~VN}P_xgw_~3XoTpdeCQdyyGGEsI#$xE&N;fE(y#ug z$E6OG<=x}Kop-EU5<-7cm3Mugy8~75K8n|A6tVYkdY?g_we45*DMn%^O9hXPsF(9- zfOlZUZC{l|DG)doWYWjddv5>e>VqjEqA@oZA(j$rX6G=-2_+fm1|Q zEti|ncgB?%N5*4#Ub2F>@t{~}0-Jq~Z2gTD(jSqSbsoyTov#+xr0 z>%%*qMwSgAZAsJPe6hE0bm$p_k1(<+y=S@!!!U%jm{Bm`4*AtzMdxFKgiPXHu)vpl zfpTteZf8IT=IcH*e#JgpanblCx+m}~tms~N8GowqlCs5ftZT6V6KV3p1^~mYxM*-H zJe${S#R;P;Vitf5fH^Cz)kIoYyegC|auIF93d~kyK7^k=GInn!f-55L=jg@1G$70mh^+iz{`?M_Q zA6{r%@$iC)g(qwKE(RVmDP7u78?n3apfyeIYjMY1zrTqSN3lTlJpO#>CgHHN3aj1> z*@w*-&PcNa?Bv2$2w(Mp+-hq7CBz|`d_(Y;Y9GN;Jod7%=&Zo(EgwQ4>H zlgf<5I^84MjKqUGI--U616&jIVt+|NF=-!hHqx66u!vNWntr01kHvxJiiWC%8m8w} zh&L`p^QiS$TgZ=+CeYJQ(sKgSOgy(Oma9NsEqBIU)Qv+<)Xh!GnVUbxU8E%9wmM_FX zVzoR8cd?PrBS($I-xKlN9PA=3@{Q&4T(Rijfo14sbKJn1H`QQ;MMAJESu795bGGUP zq6~G=$KEpYilv^OQ-K+yW<@eTcs6zvD5MT<1oj~ z_Rwl5*3nW2vV|S32E#GPOv?7HNT&l0q&7D45b96ieafWtAUvEkfGGLZ_HyrlKw4=sruZIU6Jv3J*S@nk`iwv$zVLec_pwopML6WQM3+f)O2 z1FiDXNnWB=-cgd5V=pfYkD00qOb&~7Gl}AvgtQiw{s2tH1bOsAq}^YNZZ}>;#DZn6 zwWG1ylr`xBWGf0!GAk(SP{Ee&4KzuWDF0+-#FpD8<PKJXEL?gSrr zi7yV@$3}bm{RB!pz66~ym2GC=Rg&Iy4HO>e>;b1U&@J$orerJ@&kod%VtFn-hB^0e zz56~FdNu%~^`w~XPFch_K|U2tcxwFyeAKh>Sl9Jo_`7uy}av@b(^AY%!M8w5EctrH7~UPFbLYfL)vcwl1++mzZ1rJ=u$kNN0fLM71`FB zlpDYaX4Vm2lJ%-2s}tc&U1u;^jmAo#34i4|Fsv^~^6(zhKG-bP7Z|Hl2S|;?{(Xt^ zn+af6;_(N7=^Wd9sSiZ?b1Exc#75Mj07n(RGbxpX!Qb=%Lt8mNV9qVNjK!9;#I(3J zTZ7|dXCMv&4SsZMiPKesoAo%==!`E(>*dDt_;gkASp{<-n$6)zbr|J1AHz-%tp@z+ zdeh7!z7HcNSohCV*oMOq9F~y_zzfSu7wpO!sZSr_WAzmmmeYRkURgm{|5zXmZsH)i zhEA=PtAL_#ZyXBw_|w)j;|+{9sMZgrF@A=xyp6Ali1h%*_Xx3>A(Y2N8+;64{2m{( zVX*cv9%i4%8&ohU^%EE^p!&V2uaCaBE+WFda&LqzqZ+!83uEiz*h=$v`ZoFnKp%jAyXp5x$}UmI^5dQ&2O_W;)=A>K~w0ar=hR z$U4GK;VVuVtI)i_v*9bgHh#|ucw7qxUC3mtV)tQ zSsGRE9C#W2s1_BU2c5&sf59x--n`k%4sI|GKW$09XWrDhoF^}dkk#Xz?SyeI+!2#8 zZRdVv!kG#)r2QFn-ABm)sqp%gPHpCNxC4 zpJfq1v8g!fcBF7DvN)zes41R$zj*xPC^*D8zQCibA3~3&pvI}|?V%<`WU+h+IEGc= z(+`7RSfaB7XXq4`L!ga(*PoB!Fsiw2dAxJde;7)NcdK&U@wg06j=+;qcwub4En!Ga`C5|7UZjeaBWwHxcH#x` z35@haEU#mgSVjQGQ{S7EpSi=T4S0<}4ef)5^CeNY6|ch@Sap+74-$%XXt+uF2($Cqb90DE>B7LXG%CSV` z6nn9tRzy|ed3uKJWYOA*1gC%!(VbRy^hQ3wvafa5eqZY+%f43Lg@W=zuxU2uR6%(I zGSt5`AJP|Cm{w>FK=RQ>TAvBBB_YYVvug9&70mN-%4;d`s*)wOk1~J3hgx&U^~2Z6 z3<$K0gV7&4oCJd-um_7PDsw2{3v@mle;{Df)jsQbQJdv=2!vMUWuyCiOv;|L8Wy5( z&Kc!tQu?BVGi-m#tHgXsj7lu~P&rD4$2|GUS`{CNd|;F(A6Uun!_cvrHx3myAZi)O9^<0NqPGW}{qp8V-POu=0>+`*FsZ zm*}0z)yen^o4r?$)0M#?%%N5@7VnUyFaa02%}ue z?uG3B5xbYN`)YRI%M1-tKJ_f70> zVE2`{pFFt>`|XXB%~6iElTKRq^G&tk7-2UsOaqTC2|;wJP`q9#R3gRz&whF5#)_D5 z=HqpV_{P|ZHWuSA4_3smseEc(q@@lEKVpaP!YH(gpCWk_VU?y8qH=`sc>Rt^H15L} zwXcAynguhPmch^dr(R7LiR|w#6yX&K9+lvB39gsmG6~KxX8BzRncY6>T8l~W}+S%R?=d@S+XFVRnzU~j43 zTY?P|{)z-kC1{pDLn=E-u%!eIjp!yxr}C`aImvo|wK}D5N@gaA z%w?%4mHivl`>XBi0~*x_SnBhV^@iz5xjGAdQYQPIxMT??BxPo#W$989W{HRd-MpNn ztQ2nO(17sgG_g^dNeQFECvzw#jJHJ$9U6$@BqE?{s-Iwske=5}iq;GpkDpmg*Jsa7 zFofqCQo_S+`TY|?P)JB%R75}sU~t610oZ;JuSWP_8$6>691t8xf8!K2P(47+t_WP% z*BKBL6c7YMOIOG+@k!7P6Hy`^_zw(@2nbS#1P>rSR1RWgv*ckKdNL>ic;ZMc92m@a zGyGHZ#05XemoE8*X3j;CF^G4 z^^ATOvuo}kRi4yN{CH+&c3PfJm71-$JOK(U(YVwMIF58lEV$uG8JW5il_486w)Dgo zzqOf{sS_X8>m>g(`=c2l@zdny>h#n)#z$m|LMC1vRb5k5*{P~j2$C9tXCie5ktju% zo2<`ZrX3_zckLT6$=uF}bY1eyF*(Wj*-x~OJ;J3XW#%%Yf~arbe)u21!Pw6*eY$8l z$|abMm0)A5zR5W`X1>u`$=Q0nE*ZZsI^Uop_NtsDgF&ay8p=qrMUkWPW=+@WRYSs5 zanX~b62=Tq7#F1-IX(uvO5*j8bkUmQf0$oIQRtoajSrd}<8A;PKMN7nG>U23zRYk;^pP!gCQ>V$y ze2T(cZwt-8VM<$3rASj|AW1!9uEYBT=Z*9jb&ng>Vc(w9;>E*rCX3T3S+Ccv+5gsD z#S+n;jhW_57xD8X*tni;CJ^$pNarfSn$2Rl-0nHGg`6HyE#)|$3>G`6_{@vuDm7@# zSGY}{aKyuW;UxfXN_f#lBEGg4@iAWwOE~To)FTG{<3)Y9#iqUj`Np#8Vd7=xZ7ZMn z+g@fG!trRcC;A;e{f`&X`+>%Mh1lc?M?B1ztz6=3zQ)Bx#u=Ob74vSCepFePhVk;b zpZ`sKlLt+SkBW(%f^lxpT&#$?-n z`he7cf&Eib1A_WyWf^i(a#Ml>`ltg#rug?&Pnn*Vk(n~Z4nHT^KPaJp5W+{M4%0IU z5Ti>1BJ8~R__^8XteI_ar$m>J2w)uXCvDkp;rga9DpIIabr zG2?vIYK~6jS6XoMxKflclq8z@V*E}Ne}lJg2L0x(FPmfG=OmWvt5zqcrs2b1l<^Y7 z^^F*ZuR|g<$a2f=ao87zAKBw*slctZ!$q@aOYL!(vEg6#IQHx=JDiq1i!o%=7A>Qz zu*1bNx*B^NqdRSfi)VBf>~V~)7C56E`bxhmZ2tXXvFwZ8XK|d;SJM(sPdJKgPS~1~ za0?bJNSO}vaf#?5Wcaz26Q1%s9>Ziq@WH$d^ zvXf2O7c3A@S$v^--^rpaxLRp^&~GREs{KL6B?4CqM`ypM?5k$F68_&^GH+MTJH?Ij zj&H(w2O&SsGe_3aiEBBoMNacXPqhr60z1Js{+B`QSUU$esAXo#YOjJV?RC;*@C*5}yqm@U~?cqrtv7 z$xLa&xs7wq5ubDA!o4|eF4D`=bGBufyEErL&ZSnK!9w`+L>#8zZvK8jRz+` z+?3nZn&Xc4<+y|FSvV8wIMi{C>X;70pi664u5}7hybISFy0;Ec<~*~1{#~E3dh{ju zc!Q630Q&SMzof;3o7} z2RWyZwcuQDJJ&j?(KqNXu;n^=I&q!`PtGachpT`W|AEv%@?0G_*Ocb0{3b@N=WMYb zsou71_Y8-?1YTTYUXWu;C-ZXUyyD$CuOK(hD?oAEqt;#QfA~W90DO=~Ns?z@h7B6g z$l5jK+NF4K?cxE0+_`oEKDS%edY^7lfj&^Wa!P|cr^I+uV!SEGHLo@MnP(_|;vVUy zB*(TabC7Wku#wq@Xg-SxmT_UWt<;}QsN5O9COk=`bC2StLC_6fCvbUR-&{om5_ja18Iv$T%ZzVI!*4<_40hI z9pIa^Rxn?kY0oebxVdHw$K4=Y5@MtcZaMZ2CjsYa!*3gKr-2Kx!5s�l4Kh&)x)% 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

  • %*u8ebRw2T9(>pFh2|J(qoigj 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

    T)6z<2M#k}QUo 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 U*c;Bruu^TggxRr4yC5rW0RA2Ega7~l diff --git a/lib/3rdParty/tbb/bin/x86/v140/tbb_debug.dll b/lib/3rdParty/tbb/bin/x86/v140/tbb_debug.dll deleted file mode 100644 index 96c5011acfb716d329f9ced4df6b4987c20dd82e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 375568 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

    Overview

    -Include files for Intel® Threading Building Blocks (Intel® TBB). - -

    Directories

    -
    -
    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-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. -

    -* Other names and brands may be claimed as the property of others. - - diff --git a/lib/3rdParty/tbb/include/serial/tbb/parallel_for.h b/lib/3rdParty/tbb/include/serial/tbb/parallel_for.h deleted file mode 100644 index c8f9a790..00000000 --- a/lib/3rdParty/tbb/include/serial/tbb/parallel_for.h +++ /dev/null @@ -1,219 +0,0 @@ -/* - 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_SERIAL_parallel_for_H -#define __TBB_SERIAL_parallel_for_H - -#if !TBB_USE_EXCEPTIONS && _MSC_VER - // Suppress "C++ exception handler used, but unwind semantics are not enabled" warning in STL headers - #pragma warning (push) - #pragma warning (disable: 4530) -#endif - -#include -#include // required to construct std exception classes - -#if !TBB_USE_EXCEPTIONS && _MSC_VER - #pragma warning (pop) -#endif - -#include "tbb_annotate.h" - -#ifndef __TBB_NORMAL_EXECUTION -#include "tbb/blocked_range.h" -#include "tbb/partitioner.h" -#endif - -namespace tbb { -namespace serial { -namespace interface9 { - -// parallel_for serial annotated implementation - -template< typename Range, typename Body, typename Partitioner > -class start_for : tbb::internal::no_copy { - Range my_range; - const Body my_body; - typename Partitioner::task_partition_type my_partition; - void execute(); - - //! Constructor for root task. - start_for( const Range& range, const Body& body, Partitioner& partitioner ) : - my_range( range ), - my_body( body ), - my_partition( partitioner ) - { - } - - //! Splitting constructor used to generate children. - /** this becomes left child. Newly constructed object is right child. */ - start_for( start_for& parent_, typename Partitioner::split_type& split_obj ) : - my_range( parent_.my_range, split_obj ), - my_body( parent_.my_body ), - my_partition( parent_.my_partition, split_obj ) - { - } - -public: - static void run( const Range& range, const Body& body, Partitioner& partitioner ) { - if( !range.empty() ) { - ANNOTATE_SITE_BEGIN( tbb_parallel_for ); - { - start_for a( range, body, partitioner ); - a.execute(); - } - ANNOTATE_SITE_END( tbb_parallel_for ); - } - } -}; - -template< typename Range, typename Body, typename Partitioner > -void start_for< Range, Body, Partitioner >::execute() { - if( !my_range.is_divisible() || !my_partition.is_divisible() ) { - ANNOTATE_TASK_BEGIN( tbb_parallel_for_range ); - { - my_body( my_range ); - } - ANNOTATE_TASK_END( tbb_parallel_for_range ); - } else { - typename Partitioner::split_type split_obj; - start_for b( *this, split_obj ); - this->execute(); // Execute the left interval first to keep the serial order. - b.execute(); // Execute the right interval then. - } -} - -//! Parallel iteration over range with default partitioner. -/** @ingroup algorithms **/ -template -void parallel_for( const Range& range, const Body& body ) { - serial::interface9::start_for::run(range,body,__TBB_DEFAULT_PARTITIONER()); -} - -//! Parallel iteration over range with simple partitioner. -/** @ingroup algorithms **/ -template -void parallel_for( const Range& range, const Body& body, const simple_partitioner& partitioner ) { - serial::interface9::start_for::run(range,body,partitioner); -} - -//! Parallel iteration over range with auto_partitioner. -/** @ingroup algorithms **/ -template -void parallel_for( const Range& range, const Body& body, const auto_partitioner& partitioner ) { - serial::interface9::start_for::run(range,body,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); -} - -//! Parallel iteration over range with affinity_partitioner. -/** @ingroup algorithms **/ -template -void parallel_for( const Range& range, const Body& body, affinity_partitioner& partitioner ) { - serial::interface9::start_for::run(range,body,partitioner); -} - -//! Implementation of parallel iteration over stepped range of integers with explicit step and partitioner (ignored) -template -void parallel_for_impl(Index first, Index last, Index step, const Function& f, Partitioner& ) { - if (step <= 0 ) - throw std::invalid_argument( "nonpositive_step" ); - else if (last > first) { - // Above "else" avoids "potential divide by zero" warning on some platforms - ANNOTATE_SITE_BEGIN( tbb_parallel_for ); - for( Index i = first; i < last; i = i + step ) { - ANNOTATE_TASK_BEGIN( tbb_parallel_for_iteration ); - { f( i ); } - ANNOTATE_TASK_END( tbb_parallel_for_iteration ); - } - ANNOTATE_SITE_END( tbb_parallel_for ); - } -} - -//! Parallel iteration over a range of integers with explicit step and default partitioner -template -void parallel_for(Index first, Index last, Index step, const Function& f) { - parallel_for_impl(first, last, step, f, auto_partitioner()); -} -//! Parallel iteration over a range of integers with explicit step and simple partitioner -template -void parallel_for(Index first, Index last, Index step, const Function& f, const simple_partitioner& p) { - parallel_for_impl(first, last, step, f, p); -} -//! Parallel iteration over a range of integers with explicit step and auto partitioner -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); -} -//! 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); -} -//! 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) { - parallel_for_impl(first, last, step, f, p); -} - -//! Parallel iteration over a range of integers with default step and default partitioner -template -void parallel_for(Index first, Index last, const Function& f) { - parallel_for_impl(first, last, static_cast(1), f, auto_partitioner()); -} -//! Parallel iteration over a range of integers with default step and simple partitioner -template -void parallel_for(Index first, Index last, const Function& f, const simple_partitioner& p) { - parallel_for_impl(first, last, static_cast(1), f, p); -} -//! Parallel iteration over a range of integers with default step and auto partitioner -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); -} -//! 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); -} -//! 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) { - parallel_for_impl(first, last, static_cast(1), f, p); -} - -} // namespace interfaceX - -using interface9::parallel_for; - -} // namespace serial - -#ifndef __TBB_NORMAL_EXECUTION -using serial::interface9::parallel_for; -#endif - -} // namespace tbb - -#endif /* __TBB_SERIAL_parallel_for_H */ diff --git a/lib/3rdParty/tbb/include/serial/tbb/tbb_annotate.h b/lib/3rdParty/tbb/include/serial/tbb/tbb_annotate.h deleted file mode 100644 index 81c8d3a4..00000000 --- a/lib/3rdParty/tbb/include/serial/tbb/tbb_annotate.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - 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_annotate_H -#define __TBB_annotate_H - -// Macros used by the Intel(R) Parallel Advisor. -#ifdef __TBB_NORMAL_EXECUTION - #define ANNOTATE_SITE_BEGIN( site ) - #define ANNOTATE_SITE_END( site ) - #define ANNOTATE_TASK_BEGIN( task ) - #define ANNOTATE_TASK_END( task ) - #define ANNOTATE_LOCK_ACQUIRE( lock ) - #define ANNOTATE_LOCK_RELEASE( lock ) -#else - #include -#endif - -#endif /* __TBB_annotate_H */ diff --git a/lib/3rdParty/tbb/include/tbb/aggregator.h b/lib/3rdParty/tbb/include/tbb/aggregator.h deleted file mode 100644 index 6aecbb74..00000000 --- a/lib/3rdParty/tbb/include/tbb/aggregator.h +++ /dev/null @@ -1,202 +0,0 @@ -/* - 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__aggregator_H -#define __TBB__aggregator_H - -#if !TBB_PREVIEW_AGGREGATOR -#error Set TBB_PREVIEW_AGGREGATOR before including aggregator.h -#endif - -#include "atomic.h" -#include "tbb_profiling.h" - -namespace tbb { -namespace interface6 { - -using namespace tbb::internal; - -class aggregator_operation { - template friend class aggregator_ext; - uintptr_t status; - aggregator_operation* my_next; -public: - enum aggregator_operation_status { agg_waiting=0, agg_finished }; - aggregator_operation() : status(agg_waiting), my_next(NULL) {} - /// Call start before handling this operation - void start() { call_itt_notify(acquired, &status); } - /// Call finish when done handling this operation - /** The operation will be released to its originating thread, and possibly deleted. */ - void finish() { itt_store_word_with_release(status, uintptr_t(agg_finished)); } - aggregator_operation* next() { return itt_hide_load_word(my_next);} - void set_next(aggregator_operation* n) { itt_hide_store_word(my_next, n); } -}; - -namespace internal { - -class basic_operation_base : public aggregator_operation { - friend class basic_handler; - virtual void apply_body() = 0; -public: - basic_operation_base() : aggregator_operation() {} - virtual ~basic_operation_base() {} -}; - -template -class basic_operation : public basic_operation_base, no_assign { - const Body& my_body; - void apply_body() __TBB_override { my_body(); } -public: - basic_operation(const Body& b) : basic_operation_base(), my_body(b) {} -}; - -class basic_handler { -public: - basic_handler() {} - void operator()(aggregator_operation* op_list) const { - while (op_list) { - // ITT note: &(op_list->status) tag is used to cover accesses to the operation data. - // The executing thread "acquires" the tag (see start()) and then performs - // the associated operation w/o triggering a race condition diagnostics. - // A thread that created the operation is waiting for its status (see execute_impl()), - // so when this thread is done with the operation, it will "release" the tag - // and update the status (see finish()) to give control back to the waiting thread. - basic_operation_base& request = static_cast(*op_list); - // IMPORTANT: need to advance op_list to op_list->next() before calling request.finish() - op_list = op_list->next(); - request.start(); - request.apply_body(); - request.finish(); - } - } -}; - -} // namespace internal - -//! Aggregator base class and expert interface -/** An aggregator for collecting operations coming from multiple sources and executing - them serially on a single thread. */ -template -class aggregator_ext : tbb::internal::no_copy { -public: - aggregator_ext(const handler_type& h) : handler_busy(0), handle_operations(h) { mailbox = NULL; } - - //! EXPERT INTERFACE: Enter a user-made operation into the aggregator's mailbox. - /** Details of user-made operations must be handled by user-provided handler */ - void process(aggregator_operation *op) { execute_impl(*op); } - -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) { - aggregator_operation* res; - - // ITT note: &(op.status) tag is used to cover accesses to this operation. This - // thread has created the operation, and now releases it so that the handler - // thread may handle the associated operation w/o triggering a race condition; - // 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 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 - op.my_next = res = mailbox; // NOT A RACE - } while (mailbox.compare_and_swap(&op, res) != res); - if (!res) { // first in the list; handle the operations - // ITT note: &mailbox tag covers access to the handler_busy flag, which this - // waiting handler thread will try to set before entering handle_operations. - call_itt_notify(acquired, &mailbox); - start_handle_operations(); - __TBB_ASSERT(op.status, NULL); - } - else { // not first; wait for op to be ready - call_itt_notify(prepare, &(op.status)); - spin_wait_while_eq(op.status, uintptr_t(aggregator_operation::agg_waiting)); - itt_load_word_with_acquire(op.status); - } - } - - -private: - //! An atomically updated list (aka mailbox) of aggregator_operations - atomic mailbox; - - //! Controls thread access to handle_operations - /** Behaves as boolean flag where 0=false, 1=true */ - uintptr_t handler_busy; - - handler_type handle_operations; - - //! Trigger the handling of operations when the handler is free - void start_handle_operations() { - aggregator_operation *pending_operations; - - // ITT note: &handler_busy tag covers access to mailbox as it is passed - // between active and waiting handlers. Below, the waiting handler waits until - // the active handler releases, and the waiting handler acquires &handler_busy as - // it becomes the active_handler. The release point is at the end of this - // function, when all operations in mailbox have been handled by the - // owner of this aggregator. - call_itt_notify(prepare, &handler_busy); - // get handler_busy: only one thread can possibly spin here at a time - spin_wait_until_eq(handler_busy, uintptr_t(0)); - call_itt_notify(acquired, &handler_busy); - // acquire fence not necessary here due to causality rule and surrounding atomics - __TBB_store_with_release(handler_busy, uintptr_t(1)); - - // ITT note: &mailbox tag covers access to the handler_busy flag itself. - // Capturing the state of the mailbox signifies that handler_busy has been - // set and a new active handler will now process that list's operations. - call_itt_notify(releasing, &mailbox); - // grab pending_operations - pending_operations = mailbox.fetch_and_store(NULL); - - // handle all the operations - handle_operations(pending_operations); - - // release the handler - itt_store_word_with_release(handler_busy, uintptr_t(0)); - } -}; - -//! Basic aggregator interface -class aggregator : private aggregator_ext { -public: - aggregator() : aggregator_ext(internal::basic_handler()) {} - //! BASIC INTERFACE: Enter a function for exclusive execution by the aggregator. - /** The calling thread stores the function object in a basic_operation and - places the operation in the aggregator's mailbox */ - template - void execute(const Body& b) { - internal::basic_operation op(b); - this->execute_impl(op); - } -}; - -} // namespace interface6 - -using interface6::aggregator; -using interface6::aggregator_ext; -using interface6::aggregator_operation; - -} // namespace tbb - -#endif // __TBB__aggregator_H diff --git a/lib/3rdParty/tbb/include/tbb/aligned_space.h b/lib/3rdParty/tbb/include/tbb/aligned_space.h deleted file mode 100644 index 56fd85f3..00000000 --- a/lib/3rdParty/tbb/include/tbb/aligned_space.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - 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_aligned_space_H -#define __TBB_aligned_space_H - -#include "tbb_stddef.h" -#include "tbb_machine.h" - -namespace tbb { - -//! Block of space aligned sufficiently to construct an array T with N elements. -/** The elements are not constructed or destroyed by this class. - @ingroup memory_allocation */ -template -class aligned_space { -private: - typedef __TBB_TypeWithAlignmentAtLeastAsStrict(T) element_type; - element_type array[(sizeof(T)*N+sizeof(element_type)-1)/sizeof(element_type)]; -public: - //! Pointer to beginning of array - T* begin() {return internal::punned_cast(this);} - - //! Pointer to one past last element in array. - T* end() {return begin()+N;} -}; - -} // namespace tbb - -#endif /* __TBB_aligned_space_H */ diff --git a/lib/3rdParty/tbb/include/tbb/atomic.h b/lib/3rdParty/tbb/include/tbb/atomic.h deleted file mode 100644 index 72ec534e..00000000 --- a/lib/3rdParty/tbb/include/tbb/atomic.h +++ /dev/null @@ -1,558 +0,0 @@ -/* - 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_atomic_H -#define __TBB_atomic_H - -#include - -#if _MSC_VER -#define __TBB_LONG_LONG __int64 -#else -#define __TBB_LONG_LONG long long -#endif /* _MSC_VER */ - -#include "tbb_machine.h" - -#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 - -namespace tbb { - -//! Specifies memory semantics. -enum memory_semantics { - //! Sequential consistency - full_fence, - //! Acquire - acquire, - //! Release - release, - //! No ordering - relaxed -}; - -//! @cond INTERNAL -namespace internal { - -#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; -#else - #error Do not know syntax for forcing alignment. -#endif - -template -struct atomic_rep; // Primary template declared, but never defined. - -template<> -struct atomic_rep<1> { // Specialization - typedef int8_t word; -}; -template<> -struct atomic_rep<2> { // Specialization - typedef int16_t word; -}; -template<> -struct atomic_rep<4> { // Specialization -#if _MSC_VER && !_WIN64 - // Work-around that avoids spurious /Wp64 warnings - typedef intptr_t word; -#else - typedef int32_t word; -#endif -}; -#if __TBB_64BIT_ATOMICS -template<> -struct atomic_rep<8> { // Specialization - typedef int64_t word; -}; -#endif - -template -struct aligned_storage; - -//the specializations are needed to please MSVC syntax of __declspec(align()) which accept _literal_ constants only -#if __TBB_ATOMIC_CTORS - #define ATOMIC_STORAGE_PARTIAL_SPECIALIZATION(S) \ - template \ - struct aligned_storage { \ - __TBB_DECL_ATOMIC_FIELD(value_type,my_value,S) \ - aligned_storage() = default ; \ - constexpr aligned_storage(value_type value):my_value(value){} \ - }; \ - -#else - #define ATOMIC_STORAGE_PARTIAL_SPECIALIZATION(S) \ - template \ - struct aligned_storage { \ - __TBB_DECL_ATOMIC_FIELD(value_type,my_value,S) \ - }; \ - -#endif - -template -struct aligned_storage { - value_type my_value; -#if __TBB_ATOMIC_CTORS - aligned_storage() = default ; - constexpr aligned_storage(value_type value):my_value(value){} -#endif -}; - -ATOMIC_STORAGE_PARTIAL_SPECIALIZATION(2) -ATOMIC_STORAGE_PARTIAL_SPECIALIZATION(4) -#if __TBB_64BIT_ATOMICS -ATOMIC_STORAGE_PARTIAL_SPECIALIZATION(8) -#endif - -template -struct atomic_traits; // Primary template declared, but not defined. - -#define __TBB_DECL_FENCED_ATOMIC_PRIMITIVES(S,M) \ - template<> struct atomic_traits { \ - typedef atomic_rep::word word; \ - inline static word compare_and_swap( volatile void* location, word new_value, word comparand ) { \ - return __TBB_machine_cmpswp##S##M(location,new_value,comparand); \ - } \ - inline static word fetch_and_add( volatile void* location, word addend ) { \ - return __TBB_machine_fetchadd##S##M(location,addend); \ - } \ - inline static word fetch_and_store( volatile void* location, word value ) { \ - return __TBB_machine_fetchstore##S##M(location,value); \ - } \ - }; - -#define __TBB_DECL_ATOMIC_PRIMITIVES(S) \ - template \ - struct atomic_traits { \ - typedef atomic_rep::word word; \ - inline static word compare_and_swap( volatile void* location, word new_value, word comparand ) { \ - return __TBB_machine_cmpswp##S(location,new_value,comparand); \ - } \ - inline static word fetch_and_add( volatile void* location, word addend ) { \ - return __TBB_machine_fetchadd##S(location,addend); \ - } \ - inline static word fetch_and_store( volatile void* location, word value ) { \ - return __TBB_machine_fetchstore##S(location,value); \ - } \ - }; - -template -struct atomic_load_store_traits; // Primary template declaration - -#define __TBB_DECL_ATOMIC_LOAD_STORE_PRIMITIVES(M) \ - template<> struct atomic_load_store_traits { \ - template \ - inline static T load( const volatile T& location ) { \ - return __TBB_load_##M( location ); \ - } \ - template \ - inline static void store( volatile T& location, T value ) { \ - __TBB_store_##M( location, value ); \ - } \ - } - -#if __TBB_USE_FENCED_ATOMICS -__TBB_DECL_FENCED_ATOMIC_PRIMITIVES(1,full_fence) -__TBB_DECL_FENCED_ATOMIC_PRIMITIVES(2,full_fence) -__TBB_DECL_FENCED_ATOMIC_PRIMITIVES(4,full_fence) -__TBB_DECL_FENCED_ATOMIC_PRIMITIVES(1,acquire) -__TBB_DECL_FENCED_ATOMIC_PRIMITIVES(2,acquire) -__TBB_DECL_FENCED_ATOMIC_PRIMITIVES(4,acquire) -__TBB_DECL_FENCED_ATOMIC_PRIMITIVES(1,release) -__TBB_DECL_FENCED_ATOMIC_PRIMITIVES(2,release) -__TBB_DECL_FENCED_ATOMIC_PRIMITIVES(4,release) -__TBB_DECL_FENCED_ATOMIC_PRIMITIVES(1,relaxed) -__TBB_DECL_FENCED_ATOMIC_PRIMITIVES(2,relaxed) -__TBB_DECL_FENCED_ATOMIC_PRIMITIVES(4,relaxed) -#if __TBB_64BIT_ATOMICS -__TBB_DECL_FENCED_ATOMIC_PRIMITIVES(8,full_fence) -__TBB_DECL_FENCED_ATOMIC_PRIMITIVES(8,acquire) -__TBB_DECL_FENCED_ATOMIC_PRIMITIVES(8,release) -__TBB_DECL_FENCED_ATOMIC_PRIMITIVES(8,relaxed) -#endif -#else /* !__TBB_USE_FENCED_ATOMICS */ -__TBB_DECL_ATOMIC_PRIMITIVES(1) -__TBB_DECL_ATOMIC_PRIMITIVES(2) -__TBB_DECL_ATOMIC_PRIMITIVES(4) -#if __TBB_64BIT_ATOMICS -__TBB_DECL_ATOMIC_PRIMITIVES(8) -#endif -#endif /* !__TBB_USE_FENCED_ATOMICS */ - -__TBB_DECL_ATOMIC_LOAD_STORE_PRIMITIVES(full_fence); -__TBB_DECL_ATOMIC_LOAD_STORE_PRIMITIVES(acquire); -__TBB_DECL_ATOMIC_LOAD_STORE_PRIMITIVES(release); -__TBB_DECL_ATOMIC_LOAD_STORE_PRIMITIVES(relaxed); - -//! Additive inverse of 1 for type T. -/** Various compilers issue various warnings if -1 is used with various integer types. - The baroque expression below avoids all the warnings (we hope). */ -#define __TBB_MINUS_ONE(T) (T(T(0)-T(1))) - -//! Base class that provides basic functionality for atomic without fetch_and_add. -/** Works for any type T that has the same size as an integral type, has a trivial constructor/destructor, - and can be copied/compared by memcpy/memcmp. */ -template -struct atomic_impl { -protected: - aligned_storage my_storage; -private: - //TODO: rechecks on recent versions of gcc if union is still the _only_ way to do a conversion without warnings - //! Union type used to convert type T to underlying integral type. - template - union converter { - typedef typename atomic_rep::word bits_type; - converter(){} - converter(value_type a_value) : value(a_value) {} - value_type value; - bits_type bits; - }; - - template - static typename converter::bits_type to_bits(value_t value){ - return converter(value).bits; - } - template - static value_t to_value(typename converter::bits_type bits){ - converter u; - u.bits = bits; - return u.value; - } - - template - union ptr_converter; //Primary template declared, but never defined. - - template - union ptr_converter { - ptr_converter(){} - ptr_converter(value_t* a_value) : value(a_value) {} - value_t* value; - uintptr_t bits; - }; - //TODO: check if making to_bits accepting reference (thus unifying it with to_bits_ref) - //does not hurt performance - template - static typename converter::bits_type & to_bits_ref(value_t& value){ - //TODO: this #ifdef is temporary workaround, as union conversion seems to fail - //on suncc for 64 bit types for 32 bit target - #if !__SUNPRO_CC - return *(typename converter::bits_type*)ptr_converter(&value).bits; - #else - return *(typename converter::bits_type*)(&value); - #endif - } - - -public: - typedef T value_type; - -#if __TBB_ATOMIC_CTORS - atomic_impl() = default ; - constexpr atomic_impl(value_type value):my_storage(value){} -#endif - template - value_type fetch_and_store( value_type value ) { - return to_value( - internal::atomic_traits::fetch_and_store( &my_storage.my_value, to_bits(value) ) - ); - } - - value_type fetch_and_store( value_type value ) { - return fetch_and_store(value); - } - - template - value_type compare_and_swap( value_type value, value_type comparand ) { - return to_value( - internal::atomic_traits::compare_and_swap( &my_storage.my_value, to_bits(value), to_bits(comparand) ) - ); - } - - value_type compare_and_swap( value_type value, value_type comparand ) { - return compare_and_swap(value,comparand); - } - - operator value_type() const volatile { // volatile qualifier here for backwards compatibility - return to_value( - __TBB_load_with_acquire( to_bits_ref(my_storage.my_value) ) - ); - } - - template - value_type load () const { - return to_value( - internal::atomic_load_store_traits::load( to_bits_ref(my_storage.my_value) ) - ); - } - - value_type load () const { - return load(); - } - - template - void store ( value_type value ) { - internal::atomic_load_store_traits::store( to_bits_ref(my_storage.my_value), to_bits(value)); - } - - void store ( value_type value ) { - store( value ); - } - -protected: - value_type store_with_release( value_type rhs ) { - //TODO: unify with store - __TBB_store_with_release( to_bits_ref(my_storage.my_value), to_bits(rhs) ); - return rhs; - } -}; - -//! Base class that provides basic functionality for atomic with fetch_and_add. -/** I is the underlying type. - D is the difference type. - StepType should be char if I is an integral type, and T if I is a T*. */ -template -struct atomic_impl_with_arithmetic: atomic_impl { -public: - typedef I value_type; -#if __TBB_ATOMIC_CTORS - atomic_impl_with_arithmetic() = default ; - constexpr atomic_impl_with_arithmetic(value_type value): atomic_impl(value){} -#endif - template - value_type fetch_and_add( D addend ) { - return value_type(internal::atomic_traits::fetch_and_add( &this->my_storage.my_value, addend*sizeof(StepType) )); - } - - value_type fetch_and_add( D addend ) { - return fetch_and_add(addend); - } - - template - value_type fetch_and_increment() { - return fetch_and_add(1); - } - - value_type fetch_and_increment() { - return fetch_and_add(1); - } - - template - value_type fetch_and_decrement() { - return fetch_and_add(__TBB_MINUS_ONE(D)); - } - - value_type fetch_and_decrement() { - return fetch_and_add(__TBB_MINUS_ONE(D)); - } - -public: - value_type operator+=( D value ) { - return fetch_and_add(value)+value; - } - - value_type operator-=( D value ) { - // Additive inverse of value computed using binary minus, - // instead of unary minus, for sake of avoiding compiler warnings. - return operator+=(D(0)-value); - } - - value_type operator++() { - return fetch_and_add(1)+1; - } - - value_type operator--() { - return fetch_and_add(__TBB_MINUS_ONE(D))-1; - } - - value_type operator++(int) { - return fetch_and_add(1); - } - - value_type operator--(int) { - return fetch_and_add(__TBB_MINUS_ONE(D)); - } -}; - -} /* Internal */ -//! @endcond - -//! Primary template for atomic. -/** See the Reference for details. - @ingroup synchronization */ -template -struct atomic: internal::atomic_impl { -#if __TBB_ATOMIC_CTORS - atomic() = default; - constexpr atomic(T arg): internal::atomic_impl(arg) {} -#endif - T operator=( T rhs ) { - // "this" required here in strict ISO C++ because store_with_release is a dependent name - return this->store_with_release(rhs); - } - atomic& operator=( const atomic& rhs ) {this->store_with_release(rhs); return *this;} -}; - -#if __TBB_ATOMIC_CTORS - #define __TBB_DECL_ATOMIC(T) \ - template<> struct atomic: internal::atomic_impl_with_arithmetic { \ - atomic() = default; \ - constexpr atomic(T arg): internal::atomic_impl_with_arithmetic(arg) {} \ - \ - T operator=( T rhs ) {return store_with_release(rhs);} \ - atomic& operator=( const atomic& rhs ) {store_with_release(rhs); return *this;} \ - }; -#else - #define __TBB_DECL_ATOMIC(T) \ - template<> struct atomic: internal::atomic_impl_with_arithmetic { \ - T operator=( T rhs ) {return store_with_release(rhs);} \ - atomic& operator=( const atomic& rhs ) {store_with_release(rhs); return *this;} \ - }; -#endif - -#if __TBB_64BIT_ATOMICS -//TODO: consider adding non-default (and atomic) copy constructor for 32bit platform -__TBB_DECL_ATOMIC(__TBB_LONG_LONG) -__TBB_DECL_ATOMIC(unsigned __TBB_LONG_LONG) -#else -// test_atomic will verify that sizeof(long long)==8 -#endif -__TBB_DECL_ATOMIC(long) -__TBB_DECL_ATOMIC(unsigned long) - -#if _MSC_VER && !_WIN64 -#if __TBB_ATOMIC_CTORS -/* Special version of __TBB_DECL_ATOMIC that avoids gratuitous warnings from cl /Wp64 option. - It is identical to __TBB_DECL_ATOMIC(unsigned) except that it replaces operator=(T) - with an operator=(U) that explicitly converts the U to a T. Types T and U should be - type synonyms on the platform. Type U should be the wider variant of T from the - perspective of /Wp64. */ -#define __TBB_DECL_ATOMIC_ALT(T,U) \ - template<> struct atomic: internal::atomic_impl_with_arithmetic { \ - atomic() = default ; \ - constexpr atomic(T arg): internal::atomic_impl_with_arithmetic(arg) {} \ - T operator=( U rhs ) {return store_with_release(T(rhs));} \ - atomic& operator=( const atomic& rhs ) {store_with_release(rhs); return *this;} \ - }; -#else -#define __TBB_DECL_ATOMIC_ALT(T,U) \ - template<> struct atomic: internal::atomic_impl_with_arithmetic { \ - T operator=( U rhs ) {return store_with_release(T(rhs));} \ - atomic& operator=( const atomic& rhs ) {store_with_release(rhs); return *this;} \ - }; -#endif -__TBB_DECL_ATOMIC_ALT(unsigned,size_t) -__TBB_DECL_ATOMIC_ALT(int,ptrdiff_t) -#else -__TBB_DECL_ATOMIC(unsigned) -__TBB_DECL_ATOMIC(int) -#endif /* _MSC_VER && !_WIN64 */ - -__TBB_DECL_ATOMIC(unsigned short) -__TBB_DECL_ATOMIC(short) -__TBB_DECL_ATOMIC(char) -__TBB_DECL_ATOMIC(signed char) -__TBB_DECL_ATOMIC(unsigned char) - -#if !_MSC_VER || defined(_NATIVE_WCHAR_T_DEFINED) -__TBB_DECL_ATOMIC(wchar_t) -#endif /* _MSC_VER||!defined(_NATIVE_WCHAR_T_DEFINED) */ - -//! Specialization for atomic with arithmetic and operator->. -template struct atomic: internal::atomic_impl_with_arithmetic { -#if __TBB_ATOMIC_CTORS - atomic() = default ; - constexpr atomic(T* arg): internal::atomic_impl_with_arithmetic(arg) {} -#endif - T* operator=( T* rhs ) { - // "this" required here in strict ISO C++ because store_with_release is a dependent name - return this->store_with_release(rhs); - } - atomic& operator=( const atomic& rhs ) { - this->store_with_release(rhs); return *this; - } - T* operator->() const { - return (*this); - } -}; - -//! Specialization for atomic, for sake of not allowing arithmetic or operator->. -template<> struct atomic: internal::atomic_impl { -#if __TBB_ATOMIC_CTORS - atomic() = default ; - constexpr atomic(void* arg): internal::atomic_impl(arg) {} -#endif - void* operator=( void* rhs ) { - // "this" required here in strict ISO C++ because store_with_release is a dependent name - return this->store_with_release(rhs); - } - atomic& operator=( const atomic& rhs ) { - this->store_with_release(rhs); return *this; - } -}; - -// Helpers to workaround ugly syntax of calling template member function of a -// template class with template argument dependent on template parameters. - -template -T load ( const atomic& a ) { return a.template load(); } - -template -void store ( atomic& a, T value ) { a.template store(value); } - -namespace interface6{ -//! Make an atomic for use in an initialization (list), as an alternative to zero-initialization or normal assignment. -template -atomic make_atomic(T t) { - atomic a; - store(a,t); - return a; -} -} -using interface6::make_atomic; - -namespace internal { -template -void swap(atomic & lhs, atomic & rhs){ - T tmp = load(lhs); - store(lhs,load(rhs)); - store(rhs,tmp); -} - -// only to aid in the gradual conversion of ordinary variables to proper atomics -template -inline atomic& as_atomic( T& t ) { - return (atomic&)t; -} -} // namespace tbb::internal - -} // namespace tbb - -#if _MSC_VER && !__INTEL_COMPILER - #pragma warning (pop) -#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 deleted file mode 100644 index 9f24cd2b..00000000 --- a/lib/3rdParty/tbb/include/tbb/blocked_range.h +++ /dev/null @@ -1,159 +0,0 @@ -/* - 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_blocked_range_H -#define __TBB_blocked_range_H - -#include "tbb_stddef.h" - -namespace tbb { - -/** \page range_req Requirements on range concept - Class \c R implementing the concept of range must define: - - \code R::R( const R& ); \endcode Copy constructor - - \code R::~R(); \endcode Destructor - - \code bool R::is_divisible() const; \endcode True if range can be partitioned into two subranges - - \code bool R::empty() const; \endcode True if range is empty - - \code R::R( R& r, split ); \endcode Split range \c r into two subranges. -**/ - -//! A range over which to iterate. -/** @ingroup algorithms */ -template -class blocked_range { -public: - //! Type of a value - /** Called a const_iterator for sake of algorithms that need to treat a blocked_range - as an STL container. */ - typedef Value const_iterator; - - //! Type for size of a range - typedef std::size_t size_type; - - //! Construct range with default-constructed values for begin and end. - /** Requires that Value have a default constructor. */ - blocked_range() : my_end(), my_begin() {} - - //! Construct range over half-open interval [begin,end), with the given grainsize. - blocked_range( Value begin_, Value end_, size_type grainsize_=1 ) : - my_end(end_), my_begin(begin_), my_grainsize(grainsize_) - { - __TBB_ASSERT( my_grainsize>0, "grainsize must be positive" ); - } - - //! Beginning of range. - const_iterator begin() const {return my_begin;} - - //! One past last value in range. - const_iterator end() const {return my_end;} - - //! Size of the range - /** Unspecified if end() - friend class blocked_range2d; - - template - friend class blocked_range3d; -}; - -} // namespace tbb - -#endif /* __TBB_blocked_range_H */ diff --git a/lib/3rdParty/tbb/include/tbb/blocked_range2d.h b/lib/3rdParty/tbb/include/tbb/blocked_range2d.h deleted file mode 100644 index f1b9f35d..00000000 --- a/lib/3rdParty/tbb/include/tbb/blocked_range2d.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - 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_blocked_range2d_H -#define __TBB_blocked_range2d_H - -#include "tbb_stddef.h" -#include "blocked_range.h" - -namespace tbb { - -//! A 2-dimensional range that models the Range concept. -/** @ingroup algorithms */ -template -class blocked_range2d { -public: - //! Type for size of an iteration range - typedef blocked_range row_range_type; - typedef blocked_range col_range_type; - -private: - row_range_type my_rows; - col_range_type my_cols; - -public: - - blocked_range2d( RowValue row_begin, RowValue row_end, typename row_range_type::size_type row_grainsize, - ColValue col_begin, ColValue col_end, typename col_range_type::size_type col_grainsize ) : - my_rows(row_begin,row_end,row_grainsize), - my_cols(col_begin,col_end,col_grainsize) - { - } - - blocked_range2d( RowValue row_begin, RowValue row_end, - ColValue col_begin, ColValue col_end ) : - my_rows(row_begin,row_end), - my_cols(col_begin,col_end) - { - } - - //! True if range is empty - bool empty() const { - // Yes, it is a logical OR here, not AND. - return my_rows.empty() || my_cols.empty(); - } - - //! True if range is divisible into two pieces. - bool is_divisible() const { - return my_rows.is_divisible() || my_cols.is_divisible(); - } - - blocked_range2d( blocked_range2d& r, split ) : - my_rows(r.my_rows), - my_cols(r.my_cols) - { - split split_obj; - do_split(r, split_obj); - } - -#if __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES - //! Static field to support proportional split - static const bool is_splittable_in_proportion = true; - - blocked_range2d( blocked_range2d& r, proportional_split& proportion ) : - my_rows(r.my_rows), - my_cols(r.my_cols) - { - do_split(r, proportion); - } -#endif /* __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES */ - - template - void do_split( blocked_range2d& r, Split& split_obj ) - { - if( my_rows.size()*double(my_cols.grainsize()) < my_cols.size()*double(my_rows.grainsize()) ) { - my_cols.my_begin = col_range_type::do_split(r.my_cols, split_obj); - } else { - my_rows.my_begin = row_range_type::do_split(r.my_rows, split_obj); - } - } - - //! The rows of the iteration space - const row_range_type& rows() const {return my_rows;} - - //! The columns of the iteration space - const col_range_type& cols() const {return my_cols;} -}; - -} // namespace tbb - -#endif /* __TBB_blocked_range2d_H */ diff --git a/lib/3rdParty/tbb/include/tbb/blocked_range3d.h b/lib/3rdParty/tbb/include/tbb/blocked_range3d.h deleted file mode 100644 index c62565ee..00000000 --- a/lib/3rdParty/tbb/include/tbb/blocked_range3d.h +++ /dev/null @@ -1,128 +0,0 @@ -/* - 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_blocked_range3d_H -#define __TBB_blocked_range3d_H - -#include "tbb_stddef.h" -#include "blocked_range.h" - -namespace tbb { - -//! A 3-dimensional range that models the Range concept. -/** @ingroup algorithms */ -template -class blocked_range3d { -public: - //! Type for size of an iteration range - typedef blocked_range page_range_type; - typedef blocked_range row_range_type; - typedef blocked_range col_range_type; - -private: - page_range_type my_pages; - row_range_type my_rows; - col_range_type my_cols; - -public: - - blocked_range3d( PageValue page_begin, PageValue page_end, - RowValue row_begin, RowValue row_end, - ColValue col_begin, ColValue col_end ) : - my_pages(page_begin,page_end), - my_rows(row_begin,row_end), - my_cols(col_begin,col_end) - { - } - - blocked_range3d( PageValue page_begin, PageValue page_end, typename page_range_type::size_type page_grainsize, - RowValue row_begin, RowValue row_end, typename row_range_type::size_type row_grainsize, - ColValue col_begin, ColValue col_end, typename col_range_type::size_type col_grainsize ) : - my_pages(page_begin,page_end,page_grainsize), - my_rows(row_begin,row_end,row_grainsize), - my_cols(col_begin,col_end,col_grainsize) - { - } - - //! True if range is empty - bool empty() const { - // Yes, it is a logical OR here, not AND. - return my_pages.empty() || my_rows.empty() || my_cols.empty(); - } - - //! True if range is divisible into two pieces. - bool is_divisible() const { - return my_pages.is_divisible() || my_rows.is_divisible() || my_cols.is_divisible(); - } - - blocked_range3d( blocked_range3d& r, split ) : - my_pages(r.my_pages), - my_rows(r.my_rows), - my_cols(r.my_cols) - { - split split_obj; - do_split(r, split_obj); - } - -#if __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES - //! Static field to support proportional split - static const bool is_splittable_in_proportion = true; - - blocked_range3d( blocked_range3d& r, proportional_split& proportion ) : - my_pages(r.my_pages), - my_rows(r.my_rows), - my_cols(r.my_cols) - { - do_split(r, proportion); - } -#endif /* __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES */ - - template - void do_split( blocked_range3d& r, Split& split_obj) - { - if ( my_pages.size()*double(my_rows.grainsize()) < my_rows.size()*double(my_pages.grainsize()) ) { - if ( my_rows.size()*double(my_cols.grainsize()) < my_cols.size()*double(my_rows.grainsize()) ) { - my_cols.my_begin = col_range_type::do_split(r.my_cols, split_obj); - } else { - my_rows.my_begin = row_range_type::do_split(r.my_rows, split_obj); - } - } else { - if ( my_pages.size()*double(my_cols.grainsize()) < my_cols.size()*double(my_pages.grainsize()) ) { - my_cols.my_begin = col_range_type::do_split(r.my_cols, split_obj); - } else { - my_pages.my_begin = page_range_type::do_split(r.my_pages, split_obj); - } - } - } - - //! The pages of the iteration space - const page_range_type& pages() const {return my_pages;} - - //! The rows of the iteration space - const row_range_type& rows() const {return my_rows;} - - //! The columns of the iteration space - const col_range_type& cols() const {return my_cols;} - -}; - -} // namespace tbb - -#endif /* __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 deleted file mode 100644 index d435e785..00000000 --- a/lib/3rdParty/tbb/include/tbb/cache_aligned_allocator.h +++ /dev/null @@ -1,137 +0,0 @@ -/* - 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_cache_aligned_allocator_H -#define __TBB_cache_aligned_allocator_H - -#include -#include "tbb_stddef.h" -#if __TBB_ALLOCATOR_CONSTRUCT_VARIADIC - #include // std::forward -#endif - -namespace tbb { - -//! @cond INTERNAL -namespace internal { - //! Cache/sector line size. - /** @ingroup memory_allocation */ - size_t __TBB_EXPORTED_FUNC NFS_GetLineSize(); - - //! Allocate memory on cache/sector line boundary. - /** @ingroup memory_allocation */ - void* __TBB_EXPORTED_FUNC NFS_Allocate( size_t n_element, size_t element_size, void* hint ); - - //! Free memory allocated by NFS_Allocate. - /** Freeing a NULL pointer is allowed, but has no effect. - @ingroup memory_allocation */ - void __TBB_EXPORTED_FUNC NFS_Free( void* ); -} -//! @endcond - -#if _MSC_VER && !defined(__INTEL_COMPILER) - // Workaround for erroneous "unreferenced parameter" warning in method destroy. - #pragma warning (push) - #pragma warning (disable: 4100) -#endif - -//! Meets "allocator" requirements of ISO C++ Standard, Section 20.1.5 -/** The members are ordered the same way they are in section 20.4.1 - of the ISO C++ standard. - @ingroup memory_allocation */ -template -class cache_aligned_allocator { -public: - typedef typename internal::allocator_type::value_type value_type; - typedef value_type* pointer; - typedef const value_type* const_pointer; - typedef value_type& reference; - typedef const value_type& const_reference; - typedef size_t size_type; - typedef ptrdiff_t difference_type; - template struct rebind { - typedef cache_aligned_allocator other; - }; - - cache_aligned_allocator() throw() {} - cache_aligned_allocator( const cache_aligned_allocator& ) throw() {} - template cache_aligned_allocator(const cache_aligned_allocator&) throw() {} - - pointer address(reference x) const {return &x;} - const_pointer address(const_reference x) const {return &x;} - - //! Allocate space for n objects, starting on a cache/sector line. - pointer allocate( size_type n, const void* hint=0 ) { - // The "hint" argument is always ignored in NFS_Allocate thus const_cast shouldn't hurt - return pointer(internal::NFS_Allocate( n, sizeof(value_type), const_cast(hint) )); - } - - //! Free block of memory that starts on a cache line - void deallocate( pointer p, size_type ) { - internal::NFS_Free(p); - } - - //! Largest value for which method allocate might succeed. - size_type max_size() const throw() { - return (~size_t(0)-internal::NFS_MaxLineSize)/sizeof(value_type); - } - - //! Copy-construct value at location pointed to by p. -#if __TBB_ALLOCATOR_CONSTRUCT_VARIADIC - template - void construct(U *p, Args&&... args) - { ::new((void *)p) U(std::forward(args)...); } -#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 - - //! Destroy value at location pointed to by p. - void destroy( pointer p ) {p->~value_type();} -}; - -#if _MSC_VER && !defined(__INTEL_COMPILER) - #pragma warning (pop) -#endif // warning 4100 is back - -//! Analogous to std::allocator, as defined in ISO C++ Standard, Section 20.4.1 -/** @ingroup memory_allocation */ -template<> -class cache_aligned_allocator { -public: - typedef void* pointer; - typedef const void* const_pointer; - typedef void value_type; - template struct rebind { - typedef cache_aligned_allocator other; - }; -}; - -template -inline bool operator==( const cache_aligned_allocator&, const cache_aligned_allocator& ) {return true;} - -template -inline bool operator!=( const cache_aligned_allocator&, const cache_aligned_allocator& ) {return false;} - -} // namespace tbb - -#endif /* __TBB_cache_aligned_allocator_H */ diff --git a/lib/3rdParty/tbb/include/tbb/combinable.h b/lib/3rdParty/tbb/include/tbb/combinable.h deleted file mode 100644 index 0063dbb4..00000000 --- a/lib/3rdParty/tbb/include/tbb/combinable.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - 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_combinable_H -#define __TBB_combinable_H - -#include "enumerable_thread_specific.h" -#include "cache_aligned_allocator.h" - -namespace tbb { -/** \name combinable - **/ -//@{ -//! Thread-local storage with optional reduction -/** @ingroup containers */ - template - 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; - - public: - - combinable() { } - - template - explicit combinable( finit _finit) : my_ets(_finit) { } - - //! destructor - ~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; - } - -#if __TBB_ETS_USE_CPP11 - combinable & operator=( combinable && other) { - my_ets=std::move(other.my_ets); - return *this; - } -#endif - - void clear() { my_ets.clear(); } - - T& local() { return my_ets.local(); } - - T& local(bool & exists) { return my_ets.local(exists); } - - // combine_func_t has signature T(T,T) or T(const T&, const T&) - template - T combine(combine_func_t f_combine) { return my_ets.combine(f_combine); } - - // combine_func_t has signature void(T) or void(const T&) - template - void combine_each(combine_func_t f_combine) { my_ets.combine_each(f_combine); } - - }; -} // namespace tbb -#endif /* __TBB_combinable_H */ diff --git a/lib/3rdParty/tbb/include/tbb/compat/condition_variable b/lib/3rdParty/tbb/include/tbb/compat/condition_variable deleted file mode 100644 index 43edfc03..00000000 --- a/lib/3rdParty/tbb/include/tbb/compat/condition_variable +++ /dev/null @@ -1,476 +0,0 @@ -/* - 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_condition_variable_H -#define __TBB_condition_variable_H - -#if _WIN32||_WIN64 -#include "../machine/windows_api.h" - -namespace tbb { -namespace interface5 { -namespace internal { -struct condition_variable_using_event -{ - //! Event for blocking waiting threads. - HANDLE event; - //! Protects invariants involving n_waiters, release_count, and epoch. - CRITICAL_SECTION mutex; - //! Number of threads waiting on this condition variable - int n_waiters; - //! Number of threads remaining that should no longer wait on this condition variable. - int release_count; - //! To keep threads from waking up prematurely with earlier signals. - unsigned epoch; -}; -}}} // namespace tbb::interface5::internal - -#ifndef CONDITION_VARIABLE_INIT -typedef void* CONDITION_VARIABLE; -typedef CONDITION_VARIABLE* PCONDITION_VARIABLE; -#endif - -#else /* if not _WIN32||_WIN64 */ -#include // some systems need it for ETIMEDOUT -#include -#if __linux__ -#include -#else /* generic Unix */ -#include -#endif -#endif /* _WIN32||_WIN64 */ - -#include "../tbb_stddef.h" -#include "../mutex.h" -#include "../tbb_thread.h" -#include "../tbb_exception.h" -#include "../tbb_profiling.h" - -namespace tbb { - -namespace interface5 { - -// C++0x standard working draft 30.4.3 -// Lock tag types -struct defer_lock_t { }; //! do not acquire ownership of the mutex -struct try_to_lock_t { }; //! try to acquire ownership of the mutex without blocking -struct adopt_lock_t { }; //! assume the calling thread has already -const defer_lock_t defer_lock = {}; -const try_to_lock_t try_to_lock = {}; -const adopt_lock_t adopt_lock = {}; - -// C++0x standard working draft 30.4.3.1 -//! lock_guard -template -class lock_guard : tbb::internal::no_copy { -public: - //! mutex type - typedef M mutex_type; - - //! Constructor - /** precondition: If mutex_type is not a recursive mutex, the calling thread - does not own the mutex m. */ - explicit lock_guard(mutex_type& m) : pm(m) {m.lock();} - - //! Adopt_lock constructor - /** precondition: the calling thread owns the mutex m. */ - lock_guard(mutex_type& m, adopt_lock_t) : pm(m) {} - - //! Destructor - ~lock_guard() { pm.unlock(); } -private: - mutex_type& pm; -}; - -// C++0x standard working draft 30.4.3.2 -//! unique_lock -template -class unique_lock : tbb::internal::no_copy { - friend class condition_variable; -public: - typedef M mutex_type; - - // 30.4.3.2.1 construct/copy/destroy - // NB: Without constructors that take an r-value reference to a unique_lock, the following constructor is of little use. - //! Constructor - /** postcondition: pm==0 && owns==false */ - unique_lock() : pm(NULL), owns(false) {} - - //! Constructor - /** precondition: if mutex_type is not a recursive mutex, the calling thread - does not own the mutex m. If the precondition is not met, a deadlock occurs. - postcondition: pm==&m and owns==true */ - explicit unique_lock(mutex_type& m) : pm(&m) {m.lock(); owns=true;} - - //! Defer_lock constructor - /** postcondition: pm==&m and owns==false */ - unique_lock(mutex_type& m, defer_lock_t) : pm(&m), owns(false) {} - - //! Try_to_lock constructor - /** precondition: if mutex_type is not a recursive mutex, the calling thread - does not own the mutex m. If the precondition is not met, a deadlock occurs. - postcondition: pm==&m and owns==res where res is the value returned by - the call to m.try_lock(). */ - unique_lock(mutex_type& m, try_to_lock_t) : pm(&m) {owns = m.try_lock();} - - //! Adopt_lock constructor - /** precondition: the calling thread owns the mutex. If it does not, mutex->unlock() would fail. - postcondition: pm==&m and owns==true */ - unique_lock(mutex_type& m, adopt_lock_t) : pm(&m), owns(true) {} - - //! Timed unique_lock acquisition. - /** To avoid requiring support for namespace chrono, this method deviates from the working draft in that - it uses tbb::tick_count::interval_t to specify the time duration. */ - unique_lock(mutex_type& m, const tick_count::interval_t &i) : pm(&m) {owns = try_lock_for( i );} - -#if __TBB_CPP11_RVALUE_REF_PRESENT - //! Move constructor - /** postconditions: pm == src_p.pm and owns == src_p.owns (where src_p is the state of src just prior to this - construction), src.pm == 0 and src.owns == false. */ - unique_lock(unique_lock && src): pm(NULL), owns(false) {this->swap(src);} - - //! Move assignment - /** effects: If owns calls pm->unlock(). - Postconditions: pm == src_p.pm and owns == src_p.owns (where src_p is the state of src just prior to this - assignment), src.pm == 0 and src.owns == false. */ - unique_lock& operator=(unique_lock && src) { - if (owns) - this->unlock(); - pm = NULL; - this->swap(src); - return *this; - } -#endif // __TBB_CPP11_RVALUE_REF_PRESENT - - //! Destructor - ~unique_lock() { if( owns ) pm->unlock(); } - - // 30.4.3.2.2 locking - //! Lock the mutex and own it. - void lock() { - if( pm ) { - if( !owns ) { - pm->lock(); - owns = true; - } else - throw_exception_v4( tbb::internal::eid_possible_deadlock ); - } else - throw_exception_v4( tbb::internal::eid_operation_not_permitted ); - __TBB_ASSERT( owns, NULL ); - } - - //! Try to lock the mutex. - /** If successful, note that this lock owns it. Otherwise, set it false. */ - bool try_lock() { - if( pm ) { - if( !owns ) - owns = pm->try_lock(); - else - throw_exception_v4( tbb::internal::eid_possible_deadlock ); - } else - throw_exception_v4( tbb::internal::eid_operation_not_permitted ); - return owns; - } - - //! Try to lock the mutex. - bool try_lock_for( const tick_count::interval_t &i ); - - //! Unlock the mutex - /** And note that this lock no longer owns it. */ - void unlock() { - if( owns ) { - pm->unlock(); - owns = false; - } else - throw_exception_v4( tbb::internal::eid_operation_not_permitted ); - __TBB_ASSERT( !owns, NULL ); - } - - // 30.4.3.2.3 modifiers - //! Swap the two unique locks - void swap(unique_lock& u) { - mutex_type* t_pm = u.pm; u.pm = pm; pm = t_pm; - bool t_owns = u.owns; u.owns = owns; owns = t_owns; - } - - //! Release control over the mutex. - mutex_type* release() { - mutex_type* o_pm = pm; - pm = NULL; - owns = false; - return o_pm; - } - - // 30.4.3.2.4 observers - //! Does this lock own the mutex? - bool owns_lock() const { return owns; } - - // TODO: Un-comment 'explicit' when the last non-C++0x compiler support is dropped - //! Does this lock own the mutex? - /*explicit*/ operator bool() const { return owns; } - - //! Return the mutex that this lock currently has. - mutex_type* mutex() const { return pm; } - -private: - mutex_type* pm; - bool owns; -}; - -template -bool unique_lock::try_lock_for( const tick_count::interval_t &i) -{ - const int unique_lock_tick = 100; /* microseconds; 0.1 milliseconds */ - // the smallest wait-time is 0.1 milliseconds. - bool res = pm->try_lock(); - int duration_in_micro; - if( !res && (duration_in_micro=int(i.seconds()*1e6))>unique_lock_tick ) { - tick_count::interval_t i_100( double(unique_lock_tick)/1e6 /* seconds */); // 100 microseconds = 0.1*10E-3 - do { - this_tbb_thread::sleep(i_100); // sleep for 100 micro seconds - duration_in_micro -= unique_lock_tick; - res = pm->try_lock(); - } while( !res && duration_in_micro>unique_lock_tick ); - } - return (owns=res); -} - -//! Swap the two unique locks that have the mutexes of same type -template -void swap(unique_lock& x, unique_lock& y) { x.swap( y ); } - -namespace internal { - -#if _WIN32||_WIN64 -union condvar_impl_t { - condition_variable_using_event cv_event; - CONDITION_VARIABLE cv_native; -}; -void __TBB_EXPORTED_FUNC internal_initialize_condition_variable( condvar_impl_t& cv ); -void __TBB_EXPORTED_FUNC internal_destroy_condition_variable( condvar_impl_t& cv ); -void __TBB_EXPORTED_FUNC internal_condition_variable_notify_one( condvar_impl_t& cv ); -void __TBB_EXPORTED_FUNC internal_condition_variable_notify_all( condvar_impl_t& cv ); -bool __TBB_EXPORTED_FUNC internal_condition_variable_wait( condvar_impl_t& cv, mutex* mtx, const tick_count::interval_t* i = NULL ); - -#else /* if !(_WIN32||_WIN64), i.e., POSIX threads */ -typedef pthread_cond_t condvar_impl_t; -#endif - -} // namespace internal - -//! cv_status -/** C++0x standard working draft 30.5 */ -enum cv_status { no_timeout, timeout }; - -//! condition variable -/** C++0x standard working draft 30.5.1 - @ingroup synchronization */ -class condition_variable : tbb::internal::no_copy { -public: - //! Constructor - condition_variable() { -#if _WIN32||_WIN64 - internal_initialize_condition_variable( my_cv ); -#else - pthread_cond_init( &my_cv, NULL ); -#endif - } - - //! Destructor - ~condition_variable() { - //precondition: There shall be no thread blocked on *this. -#if _WIN32||_WIN64 - internal_destroy_condition_variable( my_cv ); -#else - pthread_cond_destroy( &my_cv ); -#endif - } - - //! Notify one thread and wake it up - void notify_one() { -#if _WIN32||_WIN64 - internal_condition_variable_notify_one( my_cv ); -#else - pthread_cond_signal( &my_cv ); -#endif - } - - //! Notify all threads - void notify_all() { -#if _WIN32||_WIN64 - internal_condition_variable_notify_all( my_cv ); -#else - pthread_cond_broadcast( &my_cv ); -#endif - } - - //! Release the mutex associated with the lock and wait on this condition variable - void wait(unique_lock& lock); - - //! Wait on this condition variable while pred is false - template - void wait(unique_lock& lock, Predicate pred) { - while( !pred() ) - wait( lock ); - } - - //! Timed version of wait() - cv_status wait_for(unique_lock& lock, const tick_count::interval_t &i ); - - //! Timed version of the predicated wait - /** The loop terminates when pred() returns true or when the time duration specified by rel_time (i) has elapsed. */ - template - bool wait_for(unique_lock& lock, const tick_count::interval_t &i, Predicate pred) - { - while( !pred() ) { - cv_status st = wait_for( lock, i ); - if( st==timeout ) - return pred(); - } - return true; - } - - // C++0x standard working draft. 30.2.3 - typedef internal::condvar_impl_t* native_handle_type; - - native_handle_type native_handle() { return (native_handle_type) &my_cv; } - -private: - internal::condvar_impl_t my_cv; -}; - - -#if _WIN32||_WIN64 -inline void condition_variable::wait( unique_lock& lock ) -{ - __TBB_ASSERT( lock.owns, NULL ); - lock.owns = false; - if( !internal_condition_variable_wait( my_cv, lock.mutex() ) ) { - int ec = GetLastError(); - // on Windows 7, SleepConditionVariableCS() may return ERROR_TIMEOUT while the doc says it returns WAIT_TIMEOUT - __TBB_ASSERT_EX( ec!=WAIT_TIMEOUT&&ec!=ERROR_TIMEOUT, NULL ); - lock.owns = true; - throw_exception_v4( tbb::internal::eid_condvar_wait_failed ); - } - lock.owns = true; -} - -inline cv_status condition_variable::wait_for( unique_lock& lock, const tick_count::interval_t& i ) -{ - cv_status rc = no_timeout; - __TBB_ASSERT( lock.owns, NULL ); - lock.owns = false; - // condvar_wait could be SleepConditionVariableCS (or SleepConditionVariableSRW) or our own pre-vista cond_var_wait() - if( !internal_condition_variable_wait( my_cv, lock.mutex(), &i ) ) { - int ec = GetLastError(); - if( ec==WAIT_TIMEOUT || ec==ERROR_TIMEOUT ) - rc = timeout; - else { - lock.owns = true; - throw_exception_v4( tbb::internal::eid_condvar_wait_failed ); - } - } - lock.owns = true; - return rc; -} - -#else /* !(_WIN32||_WIN64) */ -inline void condition_variable::wait( unique_lock& lock ) -{ - __TBB_ASSERT( lock.owns, NULL ); - lock.owns = false; - if( pthread_cond_wait( &my_cv, lock.mutex()->native_handle() ) ) { - lock.owns = true; - throw_exception_v4( tbb::internal::eid_condvar_wait_failed ); - } - // upon successful return, the mutex has been locked and is owned by the calling thread. - lock.owns = true; -} - -inline cv_status condition_variable::wait_for( unique_lock& lock, const tick_count::interval_t& i ) -{ -#if __linux__ - struct timespec req; - double sec = i.seconds(); - clock_gettime( CLOCK_REALTIME, &req ); - req.tv_sec += static_cast(sec); - req.tv_nsec += static_cast( (sec - static_cast(sec))*1e9 ); -#else /* generic Unix */ - struct timeval tv; - struct timespec req; - double sec = i.seconds(); - int status = gettimeofday(&tv, NULL); - __TBB_ASSERT_EX( status==0, "gettimeofday failed" ); - req.tv_sec = tv.tv_sec + static_cast(sec); - req.tv_nsec = tv.tv_usec*1000 + static_cast( (sec - static_cast(sec))*1e9 ); -#endif /*(choice of OS) */ - if( req.tv_nsec>=1e9 ) { - req.tv_sec += 1; - req.tv_nsec -= static_cast(1e9); - } - __TBB_ASSERT( 0<=req.tv_nsec && req.tv_nsec<1e9, NULL ); - - int ec; - cv_status rc = no_timeout; - __TBB_ASSERT( lock.owns, NULL ); - lock.owns = false; - if( ( ec=pthread_cond_timedwait( &my_cv, lock.mutex()->native_handle(), &req ) ) ) { - if( ec==ETIMEDOUT ) - rc = timeout; - else { - __TBB_ASSERT( lock.try_lock()==false, NULL ); - lock.owns = true; - throw_exception_v4( tbb::internal::eid_condvar_wait_failed ); - } - } - lock.owns = true; - return rc; -} -#endif /* !(_WIN32||_WIN64) */ - -} // namespace interface5 - -__TBB_DEFINE_PROFILING_SET_NAME(interface5::condition_variable) - -} // namespace tbb - -#if TBB_IMPLEMENT_CPP0X - -namespace std { - -using tbb::interface5::defer_lock_t; -using tbb::interface5::try_to_lock_t; -using tbb::interface5::adopt_lock_t; -using tbb::interface5::defer_lock; -using tbb::interface5::try_to_lock; -using tbb::interface5::adopt_lock; -using tbb::interface5::lock_guard; -using tbb::interface5::unique_lock; -using tbb::interface5::swap; /* this is for void std::swap(unique_lock&,unique_lock&) */ -using tbb::interface5::condition_variable; -using tbb::interface5::cv_status; -using tbb::interface5::timeout; -using tbb::interface5::no_timeout; - -} // namespace std - -#endif /* TBB_IMPLEMENT_CPP0X */ - -#endif /* __TBB_condition_variable_H */ diff --git a/lib/3rdParty/tbb/include/tbb/compat/ppl.h b/lib/3rdParty/tbb/include/tbb/compat/ppl.h deleted file mode 100644 index 840dfb22..00000000 --- a/lib/3rdParty/tbb/include/tbb/compat/ppl.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - 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_compat_ppl_H -#define __TBB_compat_ppl_H - -#include "../task_group.h" -#include "../parallel_invoke.h" -#include "../parallel_for_each.h" -#include "../parallel_for.h" -#include "../tbb_exception.h" -#include "../critical_section.h" -#include "../reader_writer_lock.h" -#include "../combinable.h" - -namespace Concurrency { - -#if __TBB_TASK_GROUP_CONTEXT - using tbb::task_handle; - using tbb::task_group_status; - using tbb::task_group; - using tbb::structured_task_group; - using tbb::invalid_multiple_scheduling; - using tbb::missing_wait; - using tbb::make_task; - - using tbb::not_complete; - using tbb::complete; - using tbb::canceled; - - using tbb::is_current_task_group_canceling; -#endif /* __TBB_TASK_GROUP_CONTEXT */ - - using tbb::parallel_invoke; - using tbb::strict_ppl::parallel_for; - using tbb::parallel_for_each; - using tbb::critical_section; - using tbb::reader_writer_lock; - using tbb::combinable; - - using tbb::improper_lock; - -} // namespace Concurrency - -#endif /* __TBB_compat_ppl_H */ diff --git a/lib/3rdParty/tbb/include/tbb/compat/thread b/lib/3rdParty/tbb/include/tbb/compat/thread deleted file mode 100644 index 0edd9289..00000000 --- a/lib/3rdParty/tbb/include/tbb/compat/thread +++ /dev/null @@ -1,60 +0,0 @@ -/* - 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_thread_H -#define __TBB_thread_H - -#include "../tbb_config.h" - -#if TBB_IMPLEMENT_CPP0X - -#include "../tbb_thread.h" - -namespace std { - -typedef tbb::tbb_thread thread; - -namespace this_thread { - using tbb::this_tbb_thread::get_id; - using tbb::this_tbb_thread::yield; - - inline void sleep_for(const tbb::tick_count::interval_t& rel_time) { - tbb::internal::thread_sleep_v3( rel_time ); - } -} - -} // namespace std - -#else /* TBB_IMPLEMENT_CPP0X */ - -#define __TBB_COMPAT_THREAD_RECURSION_PROTECTOR 1 -#include -#undef __TBB_COMPAT_THREAD_RECURSION_PROTECTOR - -#endif /* TBB_IMPLEMENT_CPP0X */ - -#else /* __TBB_thread_H */ - -#if __TBB_COMPAT_THREAD_RECURSION_PROTECTOR -#error The tbb/compat/thread header attempts to include itself. \ - Please make sure that {TBBROOT}/include/tbb/compat is NOT in include paths. -#endif - -#endif /* __TBB_thread_H */ diff --git a/lib/3rdParty/tbb/include/tbb/compat/tuple b/lib/3rdParty/tbb/include/tbb/compat/tuple deleted file mode 100644 index 5767c49e..00000000 --- a/lib/3rdParty/tbb/include/tbb/compat/tuple +++ /dev/null @@ -1,488 +0,0 @@ -/* - 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_tuple_H -#define __TBB_tuple_H - -#include -#include "../tbb_stddef.h" - -// build preprocessor variables for varying number of arguments -// Need the leading comma so the empty __TBB_T_PACK will not cause a syntax error. -#if __TBB_VARIADIC_MAX <= 5 -#define __TBB_T_PACK -#define __TBB_U_PACK -#define __TBB_TYPENAME_T_PACK -#define __TBB_TYPENAME_U_PACK -#define __TBB_NULL_TYPE_PACK -#define __TBB_REF_T_PARAM_PACK -#define __TBB_CONST_REF_T_PARAM_PACK -#define __TBB_T_PARAM_LIST_PACK -#define __TBB_CONST_NULL_REF_PACK -// -#elif __TBB_VARIADIC_MAX == 6 -#define __TBB_T_PACK ,__T5 -#define __TBB_U_PACK ,__U5 -#define __TBB_TYPENAME_T_PACK , typename __T5 -#define __TBB_TYPENAME_U_PACK , typename __U5 -#define __TBB_NULL_TYPE_PACK , null_type -#define __TBB_REF_T_PARAM_PACK ,__T5& t5 -#define __TBB_CONST_REF_T_PARAM_PACK ,const __T5& t5 -#define __TBB_T_PARAM_LIST_PACK ,t5 -#define __TBB_CONST_NULL_REF_PACK , const null_type& -// -#elif __TBB_VARIADIC_MAX == 7 -#define __TBB_T_PACK ,__T5, __T6 -#define __TBB_U_PACK ,__U5, __U6 -#define __TBB_TYPENAME_T_PACK , typename __T5 , typename __T6 -#define __TBB_TYPENAME_U_PACK , typename __U5 , typename __U6 -#define __TBB_NULL_TYPE_PACK , null_type, null_type -#define __TBB_REF_T_PARAM_PACK ,__T5& t5, __T6& t6 -#define __TBB_CONST_REF_T_PARAM_PACK ,const __T5& t5, const __T6& t6 -#define __TBB_T_PARAM_LIST_PACK ,t5 ,t6 -#define __TBB_CONST_NULL_REF_PACK , const null_type&, const null_type& -// -#elif __TBB_VARIADIC_MAX == 8 -#define __TBB_T_PACK ,__T5, __T6, __T7 -#define __TBB_U_PACK ,__U5, __U6, __U7 -#define __TBB_TYPENAME_T_PACK , typename __T5 , typename __T6, typename __T7 -#define __TBB_TYPENAME_U_PACK , typename __U5 , typename __U6, typename __U7 -#define __TBB_NULL_TYPE_PACK , null_type, null_type, null_type -#define __TBB_REF_T_PARAM_PACK ,__T5& t5, __T6& t6, __T7& t7 -#define __TBB_CONST_REF_T_PARAM_PACK , const __T5& t5, const __T6& t6, const __T7& t7 -#define __TBB_T_PARAM_LIST_PACK ,t5 ,t6 ,t7 -#define __TBB_CONST_NULL_REF_PACK , const null_type&, const null_type&, const null_type& -// -#elif __TBB_VARIADIC_MAX == 9 -#define __TBB_T_PACK ,__T5, __T6, __T7, __T8 -#define __TBB_U_PACK ,__U5, __U6, __U7, __U8 -#define __TBB_TYPENAME_T_PACK , typename __T5, typename __T6, typename __T7, typename __T8 -#define __TBB_TYPENAME_U_PACK , typename __U5, typename __U6, typename __U7, typename __U8 -#define __TBB_NULL_TYPE_PACK , null_type, null_type, null_type, null_type -#define __TBB_REF_T_PARAM_PACK ,__T5& t5, __T6& t6, __T7& t7, __T8& t8 -#define __TBB_CONST_REF_T_PARAM_PACK , const __T5& t5, const __T6& t6, const __T7& t7, const __T8& t8 -#define __TBB_T_PARAM_LIST_PACK ,t5 ,t6 ,t7 ,t8 -#define __TBB_CONST_NULL_REF_PACK , const null_type&, const null_type&, const null_type&, const null_type& -// -#elif __TBB_VARIADIC_MAX >= 10 -#define __TBB_T_PACK ,__T5, __T6, __T7, __T8, __T9 -#define __TBB_U_PACK ,__U5, __U6, __U7, __U8, __U9 -#define __TBB_TYPENAME_T_PACK , typename __T5, typename __T6, typename __T7, typename __T8, typename __T9 -#define __TBB_TYPENAME_U_PACK , typename __U5, typename __U6, typename __U7, typename __U8, typename __U9 -#define __TBB_NULL_TYPE_PACK , null_type, null_type, null_type, null_type, null_type -#define __TBB_REF_T_PARAM_PACK ,__T5& t5, __T6& t6, __T7& t7, __T8& t8, __T9& t9 -#define __TBB_CONST_REF_T_PARAM_PACK , const __T5& t5, const __T6& t6, const __T7& t7, const __T8& t8, const __T9& t9 -#define __TBB_T_PARAM_LIST_PACK ,t5 ,t6 ,t7 ,t8 ,t9 -#define __TBB_CONST_NULL_REF_PACK , const null_type&, const null_type&, const null_type&, const null_type&, const null_type& -#endif - - - -namespace tbb { -namespace interface5 { - -namespace internal { -struct null_type { }; -} -using internal::null_type; - -// tuple forward declaration -template = 6 -, typename __T5=null_type -#if __TBB_VARIADIC_MAX >= 7 -, typename __T6=null_type -#if __TBB_VARIADIC_MAX >= 8 -, typename __T7=null_type -#if __TBB_VARIADIC_MAX >= 9 -, typename __T8=null_type -#if __TBB_VARIADIC_MAX >= 10 -, typename __T9=null_type -#endif -#endif -#endif -#endif -#endif -> -class tuple; - -namespace internal { - -// const null_type temp -inline const null_type cnull() { return null_type(); } - -// cons forward declaration -template struct cons; - -// type of a component of the cons -template -struct component { - typedef typename __T::tail_type next; - typedef typename component<__N-1,next>::type type; -}; - -template -struct component<0,__T> { - typedef typename __T::head_type type; -}; - -template<> -struct component<0,null_type> { - typedef null_type type; -}; - -// const version of component - -template -struct component<__N, const __T> -{ - typedef typename __T::tail_type next; - typedef const typename component<__N-1,next>::type type; -}; - -template -struct component<0, const __T> -{ - typedef const typename __T::head_type type; -}; - - -// helper class for getting components of cons -template< int __N> -struct get_helper { -template -inline static typename component<__N, cons<__HT,__TT> >::type& get(cons<__HT,__TT>& ti) { - return get_helper<__N-1>::get(ti.tail); -} -template -inline static typename component<__N, cons<__HT,__TT> >::type const& get(const cons<__HT,__TT>& ti) { - return get_helper<__N-1>::get(ti.tail); -} -}; - -template<> -struct get_helper<0> { -template -inline static typename component<0, cons<__HT,__TT> >::type& get(cons<__HT,__TT>& ti) { - return ti.head; -} -template -inline static typename component<0, cons<__HT,__TT> >::type const& get(const cons<__HT,__TT>& ti) { - return ti.head; -} -}; - -// traits adaptor -template -struct tuple_traits { - typedef cons <__T0, typename tuple_traits<__T1, __T2, __T3, __T4 __TBB_T_PACK , null_type>::U > U; -}; - -template -struct tuple_traits<__T0, null_type, null_type, null_type, null_type __TBB_NULL_TYPE_PACK > { - typedef cons<__T0, null_type> U; -}; - -template<> -struct tuple_traits { - typedef null_type U; -}; - - -// core cons defs -template -struct cons{ - - typedef __HT head_type; - typedef __TT tail_type; - - head_type head; - tail_type tail; - - static const int length = 1 + tail_type::length; - - // default constructors - explicit cons() : head(), tail() { } - - // non-default constructors - cons(head_type& h, const tail_type& t) : head(h), tail(t) { } - - template - cons(const __T0& t0, const __T1& t1, const __T2& t2, const __T3& t3, const __T4& t4 __TBB_CONST_REF_T_PARAM_PACK) : - head(t0), tail(t1, t2, t3, t4 __TBB_T_PARAM_LIST_PACK, cnull()) { } - - template - cons(__T0& t0, __T1& t1, __T2& t2, __T3& t3, __T4& t4 __TBB_REF_T_PARAM_PACK) : - head(t0), tail(t1, t2, t3, t4 __TBB_T_PARAM_LIST_PACK , cnull()) { } - - template - cons(const cons<__HT1,__TT1>& other) : head(other.head), tail(other.tail) { } - - cons& operator=(const cons& other) { head = other.head; tail = other.tail; return *this; } - - friend bool operator==(const cons& me, const cons& other) { - return me.head == other.head && me.tail == other.tail; - } - friend bool operator<(const cons& me, const cons& other) { - return me.head < other.head || (!(other.head < me.head) && me.tail < other.tail); - } - friend bool operator>(const cons& me, const cons& other) { return other=(const cons& me, const cons& other) { return !(meother); } - - template - friend bool operator==(const cons<__HT,__TT>& me, const cons<__HT1,__TT1>& other) { - return me.head == other.head && me.tail == other.tail; - } - - template - friend bool operator<(const cons<__HT,__TT>& me, const cons<__HT1,__TT1>& other) { - return me.head < other.head || (!(other.head < me.head) && me.tail < other.tail); - } - - template - friend bool operator>(const cons<__HT,__TT>& me, const cons<__HT1,__TT1>& other) { return other - friend bool operator!=(const cons<__HT,__TT>& me, const cons<__HT1,__TT1>& other) { return !(me==other); } - - template - friend bool operator>=(const cons<__HT,__TT>& me, const cons<__HT1,__TT1>& other) { return !(me - friend bool operator<=(const cons<__HT,__TT>& me, const cons<__HT1,__TT1>& other) { return !(me>other); } - - -}; // cons - - -template -struct cons<__HT,null_type> { - - typedef __HT head_type; - typedef null_type tail_type; - - head_type head; - - static const int length = 1; - - // default constructor - cons() : head() { /*std::cout << "default constructor 1\n";*/ } - - cons(const null_type&, const null_type&, const null_type&, const null_type&, const null_type& __TBB_CONST_NULL_REF_PACK) : head() { /*std::cout << "default constructor 2\n";*/ } - - // non-default constructor - template - cons(__T1& t1, const null_type&, const null_type&, const null_type&, const null_type& __TBB_CONST_NULL_REF_PACK) : head(t1) { /*std::cout << "non-default a1, t1== " << t1 << "\n";*/} - - cons(head_type& h, const null_type& = null_type() ) : head(h) { } - cons(const head_type& t0, const null_type&, const null_type&, const null_type&, const null_type& __TBB_CONST_NULL_REF_PACK) : head(t0) { } - - // converting constructor - template - cons(__HT1 h1, const null_type&, const null_type&, const null_type&, const null_type& __TBB_CONST_NULL_REF_PACK) : head(h1) { } - - // copy constructor - template - cons( const cons<__HT1, null_type>& other) : head(other.head) { } - - // assignment operator - cons& operator=(const cons& other) { head = other.head; return *this; } - - friend bool operator==(const cons& me, const cons& other) { return me.head == other.head; } - friend bool operator<(const cons& me, const cons& other) { return me.head < other.head; } - friend bool operator>(const cons& me, const cons& other) { return otherother); } - friend bool operator>=(const cons& me, const cons& other) {return !(me - friend bool operator==(const cons<__HT,null_type>& me, const cons<__HT1,null_type>& other) { - return me.head == other.head; - } - - template - friend bool operator<(const cons<__HT,null_type>& me, const cons<__HT1,null_type>& other) { - return me.head < other.head; - } - - template - friend bool operator>(const cons<__HT,null_type>& me, const cons<__HT1,null_type>& other) { return other - friend bool operator!=(const cons<__HT,null_type>& me, const cons<__HT1,null_type>& other) { return !(me==other); } - - template - friend bool operator<=(const cons<__HT,null_type>& me, const cons<__HT1,null_type>& other) { return !(me>other); } - - template - friend bool operator>=(const cons<__HT,null_type>& me, const cons<__HT1,null_type>& other) { return !(me -struct cons { typedef null_type tail_type; static const int length = 0; }; - -// wrapper for default constructor -template -inline const __T wrap_dcons(__T*) { return __T(); } - -} // namespace internal - -// tuple definition -template -class tuple : public internal::tuple_traits<__T0, __T1, __T2, __T3, __T4 __TBB_T_PACK >::U { - // friends - template friend class tuple_size; - template friend struct tuple_element; - - // stl components - typedef tuple<__T0,__T1,__T2,__T3,__T4 __TBB_T_PACK > value_type; - typedef value_type *pointer; - typedef const value_type *const_pointer; - typedef value_type &reference; - typedef const value_type &const_reference; - typedef size_t size_type; - - typedef typename internal::tuple_traits<__T0,__T1,__T2,__T3, __T4 __TBB_T_PACK >::U my_cons; - -public: - tuple(const __T0& t0=internal::wrap_dcons((__T0*)NULL) - ,const __T1& t1=internal::wrap_dcons((__T1*)NULL) - ,const __T2& t2=internal::wrap_dcons((__T2*)NULL) - ,const __T3& t3=internal::wrap_dcons((__T3*)NULL) - ,const __T4& t4=internal::wrap_dcons((__T4*)NULL) -#if __TBB_VARIADIC_MAX >= 6 - ,const __T5& t5=internal::wrap_dcons((__T5*)NULL) -#if __TBB_VARIADIC_MAX >= 7 - ,const __T6& t6=internal::wrap_dcons((__T6*)NULL) -#if __TBB_VARIADIC_MAX >= 8 - ,const __T7& t7=internal::wrap_dcons((__T7*)NULL) -#if __TBB_VARIADIC_MAX >= 9 - ,const __T8& t8=internal::wrap_dcons((__T8*)NULL) -#if __TBB_VARIADIC_MAX >= 10 - ,const __T9& t9=internal::wrap_dcons((__T9*)NULL) -#endif -#endif -#endif -#endif -#endif - ) : - my_cons(t0,t1,t2,t3,t4 __TBB_T_PARAM_LIST_PACK) { } - - template - struct internal_tuple_element { - typedef typename internal::component<__N,my_cons>::type type; - }; - - template - typename internal_tuple_element<__N>::type& get() { return internal::get_helper<__N>::get(*this); } - - template - typename internal_tuple_element<__N>::type const& get() const { return internal::get_helper<__N>::get(*this); } - - template - tuple& operator=(const internal::cons<__U1,__U2>& other) { - my_cons::operator=(other); - return *this; - } - - template - tuple& operator=(const std::pair<__U1,__U2>& other) { - // __TBB_ASSERT(tuple_size::value == 2, "Invalid size for pair to tuple assignment"); - this->head = other.first; - this->tail.head = other.second; - return *this; - } - - friend bool operator==(const tuple& me, const tuple& other) {return static_cast(me)==(other);} - friend bool operator<(const tuple& me, const tuple& other) {return static_cast(me)<(other);} - friend bool operator>(const tuple& me, const tuple& other) {return static_cast(me)>(other);} - friend bool operator!=(const tuple& me, const tuple& other) {return static_cast(me)!=(other);} - friend bool operator>=(const tuple& me, const tuple& other) {return static_cast(me)>=(other);} - friend bool operator<=(const tuple& me, const tuple& other) {return static_cast(me)<=(other);} - -}; // tuple - -// empty tuple -template<> -class tuple : public null_type { -}; - -// helper classes - -template < typename __T> -class tuple_size { -public: - static const size_t value = 1 + tuple_size::value; -}; - -template <> -class tuple_size > { -public: - static const size_t value = 0; -}; - -template <> -class tuple_size { -public: - static const size_t value = 0; -}; - -template -struct tuple_element { - typedef typename internal::component<__N, typename __T::my_cons>::type type; -}; - -template -inline static typename tuple_element<__N,tuple<__T0,__T1,__T2,__T3,__T4 __TBB_T_PACK > >::type& - get(tuple<__T0,__T1,__T2,__T3,__T4 __TBB_T_PACK >& t) { return internal::get_helper<__N>::get(t); } - -template -inline static typename tuple_element<__N,tuple<__T0,__T1,__T2,__T3,__T4 __TBB_T_PACK > >::type const& - get(const tuple<__T0,__T1,__T2,__T3,__T4 __TBB_T_PACK >& t) { return internal::get_helper<__N>::get(t); } - -} // interface5 -} // tbb - -#if !__TBB_CPP11_TUPLE_PRESENT -namespace tbb { - namespace flow { - using tbb::interface5::tuple; - using tbb::interface5::tuple_size; - using tbb::interface5::tuple_element; - using tbb::interface5::get; - } -} -#endif - -#undef __TBB_T_PACK -#undef __TBB_U_PACK -#undef __TBB_TYPENAME_T_PACK -#undef __TBB_TYPENAME_U_PACK -#undef __TBB_NULL_TYPE_PACK -#undef __TBB_REF_T_PARAM_PACK -#undef __TBB_CONST_REF_T_PARAM_PACK -#undef __TBB_T_PARAM_LIST_PACK -#undef __TBB_CONST_NULL_REF_PACK - -#endif /* __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 deleted file mode 100644 index 09b2765b..00000000 --- a/lib/3rdParty/tbb/include/tbb/concurrent_hash_map.h +++ /dev/null @@ -1,1510 +0,0 @@ -/* - 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_concurrent_hash_map_H -#define __TBB_concurrent_hash_map_H - -#include "tbb_stddef.h" - -#if !TBB_USE_EXCEPTIONS && _MSC_VER - // Suppress "C++ exception handler used, but unwind semantics are not enabled" warning in STL headers - #pragma warning (push) - #pragma warning (disable: 4530) -#endif - -#include -#include // Need std::pair -#include // Need std::memset -#include __TBB_STD_SWAP_HEADER - -#if !TBB_USE_EXCEPTIONS && _MSC_VER - #pragma warning (pop) -#endif - -#include "cache_aligned_allocator.h" -#include "tbb_allocator.h" -#include "spin_rw_mutex.h" -#include "atomic.h" -#include "tbb_exception.h" -#include "tbb_profiling.h" -#include "internal/_tbb_hash_compare_impl.h" -#if __TBB_INITIALIZER_LISTS_PRESENT -#include -#endif -#if TBB_USE_PERFORMANCE_WARNINGS || __TBB_STATISTICS -#include -#endif -#if __TBB_STATISTICS -#include -#endif - -namespace tbb { - -namespace interface5 { - - template, typename A = tbb_allocator > > - class concurrent_hash_map; - - //! @cond INTERNAL - namespace internal { - using namespace tbb::internal; - - - //! Type of a hash code. - typedef size_t hashcode_t; - //! Node base type - struct hash_map_node_base : tbb::internal::no_copy { - //! Mutex type - typedef spin_rw_mutex mutex_t; - //! Scoped lock type for mutex - typedef mutex_t::scoped_lock scoped_t; - //! Next node in chain - hash_map_node_base *next; - mutex_t mutex; - }; - //! Incompleteness flag value - static hash_map_node_base *const rehash_req = reinterpret_cast(size_t(3)); - //! Rehashed empty bucket flag - static hash_map_node_base *const empty_rehashed = reinterpret_cast(size_t(0)); - //! base class of concurrent_hash_map - class hash_map_base { - public: - //! Size type - typedef size_t size_type; - //! Type of a hash code. - typedef size_t hashcode_t; - //! Segment index type - typedef size_t segment_index_t; - //! Node base type - typedef hash_map_node_base node_base; - //! Bucket type - struct bucket : tbb::internal::no_copy { - //! Mutex type for buckets - typedef spin_rw_mutex mutex_t; - //! Scoped lock type for mutex - typedef mutex_t::scoped_lock scoped_t; - mutex_t mutex; - node_base *node_list; - }; - //! Count of segments in the first block - static size_type const embedded_block = 1; - //! Count of segments in the first block - static size_type const embedded_buckets = 1< my_mask; - //! Segment pointers table. Also prevents false sharing between my_mask and my_size - segments_table_t my_table; - //! Size of container in stored items - atomic my_size; // It must be in separate cache line from my_mask due to performance effects - //! Zero segment - bucket my_embedded_segment[embedded_buckets]; -#if __TBB_STATISTICS - atomic my_info_resizes; // concurrent ones - mutable atomic my_info_restarts; // race collisions - atomic my_info_rehashes; // invocations of rehash_bucket -#endif - //! Constructor - hash_map_base() { - std::memset( this, 0, pointers_per_table*sizeof(segment_ptr_t) // 32*4=128 or 64*8=512 - + sizeof(my_size) + sizeof(my_mask) // 4+4 or 8+8 - + embedded_buckets*sizeof(bucket) ); // n*8 or n*16 - for( size_type i = 0; i < embedded_block; i++ ) // fill the table - my_table[i] = my_embedded_segment + segment_base(i); - my_mask = embedded_buckets - 1; - __TBB_ASSERT( embedded_block <= first_block, "The first block number must include embedded blocks"); -#if __TBB_STATISTICS - my_info_resizes = 0; // concurrent ones - my_info_restarts = 0; // race collisions - my_info_rehashes = 0; // invocations of rehash_bucket -#endif - } - - //! @return segment index of given index in the array - static segment_index_t segment_index_of( size_type index ) { - return segment_index_t( __TBB_Log2( index|1 ) ); - } - - //! @return the first array index of given segment - static segment_index_t segment_base( segment_index_t k ) { - return (segment_index_t(1)<(ptr) > uintptr_t(63); - } - - //! Initialize buckets - static void init_buckets( segment_ptr_t ptr, size_type sz, bool is_initial ) { - if( is_initial ) std::memset(ptr, 0, sz*sizeof(bucket) ); - else for(size_type i = 0; i < sz; i++, ptr++) { - *reinterpret_cast(&ptr->mutex) = 0; - ptr->node_list = rehash_req; - } - } - - //! Add node @arg n to bucket @arg b - static void add_to_bucket( bucket *b, node_base *n ) { - __TBB_ASSERT(b->node_list != rehash_req, NULL); - n->next = b->node_list; - b->node_list = n; // its under lock and flag is set - } - - //! Exception safety helper - struct enable_segment_failsafe : tbb::internal::no_copy { - segment_ptr_t *my_segment_ptr; - enable_segment_failsafe(segments_table_t &table, segment_index_t k) : my_segment_ptr(&table[k]) {} - ~enable_segment_failsafe() { - if( my_segment_ptr ) *my_segment_ptr = 0; // indicate no allocation in progress - } - }; - - //! Enable segment - void enable_segment( segment_index_t k, bool is_initial = false ) { - __TBB_ASSERT( k, "Zero segment must be embedded" ); - enable_segment_failsafe watchdog( my_table, k ); - cache_aligned_allocator alloc; - size_type sz; - __TBB_ASSERT( !is_valid(my_table[k]), "Wrong concurrent assignment"); - if( k >= first_block ) { - sz = segment_size( k ); - segment_ptr_t ptr = alloc.allocate( sz ); - init_buckets( ptr, sz, is_initial ); - itt_hide_store_word( my_table[k], ptr ); - sz <<= 1;// double it to get entire capacity of the container - } else { // the first block - __TBB_ASSERT( k == embedded_block, "Wrong segment index" ); - sz = segment_size( first_block ); - segment_ptr_t ptr = alloc.allocate( sz - embedded_buckets ); - init_buckets( ptr, sz - embedded_buckets, is_initial ); - ptr -= segment_base(embedded_block); - for(segment_index_t i = embedded_block; i < first_block; i++) // calc the offsets - itt_hide_store_word( my_table[i], ptr + segment_base(i) ); - } - itt_store_word_with_release( my_mask, sz-1 ); - watchdog.my_segment_ptr = 0; - } - - //! Get bucket by (masked) hashcode - bucket *get_bucket( hashcode_t h ) const throw() { // TODO: add throw() everywhere? - segment_index_t s = segment_index_of( h ); - h -= segment_base(s); - segment_ptr_t seg = my_table[s]; - __TBB_ASSERT( is_valid(seg), "hashcode must be cut by valid mask for allocated segments" ); - return &seg[h]; - } - - // internal serial rehashing helper - void mark_rehashed_levels( hashcode_t h ) throw () { - segment_index_t s = segment_index_of( h ); - while( segment_ptr_t seg = my_table[++s] ) - if( seg[h].node_list == rehash_req ) { - seg[h].node_list = empty_rehashed; - mark_rehashed_levels( h + ((hashcode_t)1<node_list) != rehash_req ) - { -#if __TBB_STATISTICS - my_info_restarts++; // race collisions -#endif - return true; - } - } - return false; - } - - //! Insert a node and check for load factor. @return segment index to enable. - segment_index_t insert_new_node( bucket *b, node_base *n, hashcode_t mask ) { - size_type sz = ++my_size; // prefix form is to enforce allocation after the first item inserted - add_to_bucket( b, n ); - // check load factor - if( sz >= mask ) { // TODO: add custom load_factor - segment_index_t new_seg = __TBB_Log2( mask+1 ); //optimized segment_index_of - __TBB_ASSERT( is_valid(my_table[new_seg-1]), "new allocations must not publish new mask until segment has allocated"); - static const segment_ptr_t is_allocating = (segment_ptr_t)2; - if( !itt_hide_load_word(my_table[new_seg]) - && as_atomic(my_table[new_seg]).compare_and_swap(is_allocating, NULL) == NULL ) - return new_seg; // The value must be processed - } - return 0; - } - - //! Prepare enough segments for number of buckets - void reserve(size_type buckets) { - if( !buckets-- ) return; - bool is_initial = !my_size; - for( size_type m = my_mask; buckets > m; m = my_mask ) - enable_segment( segment_index_of( m+1 ), is_initial ); - } - //! Swap hash_map_bases - void internal_swap(hash_map_base &table) { - using std::swap; - swap(this->my_mask, table.my_mask); - swap(this->my_size, table.my_size); - for(size_type i = 0; i < embedded_buckets; i++) - swap(this->my_embedded_segment[i].node_list, table.my_embedded_segment[i].node_list); - for(size_type i = embedded_block; i < pointers_per_table; i++) - swap(this->my_table[i], table.my_table[i]); - } - }; - - template - class hash_map_range; - - //! Meets requirements of a forward iterator for STL */ - /** Value is either the T or const T type of the container. - @ingroup containers */ - template - class hash_map_iterator - : public std::iterator - { - typedef Container map_type; - typedef typename Container::node node; - typedef hash_map_base::node_base node_base; - typedef hash_map_base::bucket bucket; - - template - friend bool operator==( const hash_map_iterator& i, const hash_map_iterator& j ); - - template - friend bool operator!=( const hash_map_iterator& i, const hash_map_iterator& j ); - - template - friend ptrdiff_t operator-( const hash_map_iterator& i, const hash_map_iterator& j ); - - template - friend class hash_map_iterator; - - template - friend class hash_map_range; - - void advance_to_next_bucket() { // TODO?: refactor to iterator_base class - size_t k = my_index+1; - __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 - ++my_bucket; - else my_bucket = my_map->get_bucket( k ); - my_node = static_cast( my_bucket->node_list ); - if( hash_map_base::is_valid(my_node) ) { - my_index = k; return; - } - ++k; - } - my_bucket = 0; my_node = 0; my_index = k; // the end - } -#if !defined(_MSC_VER) || defined(__INTEL_COMPILER) - template - friend class interface5::concurrent_hash_map; -#else - public: // workaround -#endif - //! concurrent_hash_map over which we are iterating. - const Container *my_map; - - //! Index in hash table for current item - size_t my_index; - - //! Pointer to bucket - const bucket *my_bucket; - - //! Pointer to node that has current item - node *my_node; - - hash_map_iterator( const Container &map, size_t index, const bucket *b, node_base *n ); - - public: - //! Construct undefined 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), - my_bucket(other.my_bucket), - my_node(other.my_node) - {} - Value& operator*() const { - __TBB_ASSERT( hash_map_base::is_valid(my_node), "iterator uninitialized or at end of container?" ); - return my_node->item; - } - Value* operator->() const {return &operator*();} - hash_map_iterator& operator++(); - - //! Post increment - hash_map_iterator operator++(int) { - hash_map_iterator old(*this); - operator++(); - return old; - } - }; - - template - hash_map_iterator::hash_map_iterator( const Container &map, size_t index, const bucket *b, node_base *n ) : - my_map(&map), - my_index(index), - my_bucket(b), - my_node( static_cast(n) ) - { - if( b && !hash_map_base::is_valid(n) ) - advance_to_next_bucket(); - } - - template - hash_map_iterator& hash_map_iterator::operator++() { - my_node = static_cast( my_node->next ); - if( !my_node ) advance_to_next_bucket(); - return *this; - } - - template - bool operator==( const hash_map_iterator& i, const hash_map_iterator& j ) { - return i.my_node == j.my_node && i.my_map == j.my_map; - } - - template - bool operator!=( const hash_map_iterator& i, const hash_map_iterator& j ) { - return i.my_node != j.my_node || i.my_map != j.my_map; - } - - //! Range class used with concurrent_hash_map - /** @ingroup containers */ - template - class hash_map_range { - typedef typename Iterator::map_type map_type; - Iterator my_begin; - Iterator my_end; - mutable Iterator my_midpoint; - size_t my_grainsize; - //! Set my_midpoint to point approximately half way between my_begin and my_end. - void set_midpoint() const; - template friend class hash_map_range; - public: - //! Type for size of a range - typedef std::size_t size_type; - typedef typename Iterator::value_type value_type; - typedef typename Iterator::reference reference; - typedef typename Iterator::difference_type difference_type; - typedef Iterator iterator; - - //! True if range is empty. - bool empty() const {return my_begin==my_end;} - - //! True if range can be partitioned into two subranges. - bool is_divisible() const { - return my_midpoint!=my_end; - } - //! Split range. - hash_map_range( hash_map_range& r, split ) : - my_end(r.my_end), - my_grainsize(r.my_grainsize) - { - r.my_end = my_begin = r.my_midpoint; - __TBB_ASSERT( !empty(), "Splitting despite the range is not divisible" ); - __TBB_ASSERT( !r.empty(), "Splitting despite the range is not divisible" ); - set_midpoint(); - r.set_midpoint(); - } - //! type conversion - template - hash_map_range( hash_map_range& r) : - my_begin(r.my_begin), - my_end(r.my_end), - my_midpoint(r.my_midpoint), - my_grainsize(r.my_grainsize) - {} - //! Init range with container and grainsize specified - hash_map_range( const map_type &map, size_type grainsize_ = 1 ) : - my_begin( Iterator( map, 0, map.my_embedded_segment, map.my_embedded_segment->node_list ) ), - my_end( Iterator( map, map.my_mask + 1, 0, 0 ) ), - my_grainsize( grainsize_ ) - { - __TBB_ASSERT( grainsize_>0, "grainsize must be positive" ); - set_midpoint(); - } - const Iterator& begin() const {return my_begin;} - const Iterator& end() const {return my_end;} - //! The grain size for this range. - size_type grainsize() const {return my_grainsize;} - }; - - template - void hash_map_range::set_midpoint() const { - // Split by groups of nodes - size_t m = my_end.my_index-my_begin.my_index; - if( m > my_grainsize ) { - m = my_begin.my_index + m/2u; - hash_map_base::bucket *b = my_begin.my_map->get_bucket(m); - my_midpoint = Iterator(*my_begin.my_map,m,b,b->node_list); - } else { - my_midpoint = my_end; - } - __TBB_ASSERT( my_begin.my_index <= my_midpoint.my_index, - "my_begin is after my_midpoint" ); - __TBB_ASSERT( my_midpoint.my_index <= my_end.my_index, - "my_midpoint is after my_end" ); - __TBB_ASSERT( my_begin != my_midpoint || my_begin == my_end, - "[my_begin, my_midpoint) range should not be empty" ); - } - - } // internal -//! @endcond - -#if _MSC_VER && !defined(__INTEL_COMPILER) - // Suppress "conditional expression is constant" warning. - #pragma warning( push ) - #pragma warning( disable: 4127 ) -#endif - -//! Unordered map from Key to T. -/** concurrent_hash_map is associative container with concurrent access. - -@par Compatibility - The class meets all Container Requirements from C++ Standard (See ISO/IEC 14882:2003(E), clause 23.1). - -@par Exception Safety - - Hash function is not permitted to throw an exception. User-defined types Key and T are forbidden from throwing an exception in destructors. - - If exception happens during insert() operations, it has no effect (unless exception raised by HashCompare::hash() function during grow_segment). - - If exception happens during operator=() operation, the container can have a part of source items, and methods size() and empty() can return wrong results. - -@par Changes since TBB 2.1 - - Replaced internal algorithm and data structure. Patent is pending. - - Added buckets number argument for constructor - -@par Changes since TBB 2.0 - - Fixed exception-safety - - Added template argument for allocator - - Added allocator argument in constructors - - Added constructor from a range of iterators - - Added several new overloaded insert() methods - - Added get_allocator() - - Added swap() - - Added count() - - Added overloaded erase(accessor &) and erase(const_accessor&) - - Added equal_range() [const] - - Added [const_]pointer, [const_]reference, and allocator_type types - - Added global functions: operator==(), operator!=(), and swap() - - @ingroup containers */ -template -class concurrent_hash_map : protected internal::hash_map_base { - template - friend class internal::hash_map_iterator; - - template - friend class internal::hash_map_range; - -public: - typedef Key key_type; - typedef T mapped_type; - typedef std::pair value_type; - typedef hash_map_base::size_type size_type; - typedef ptrdiff_t difference_type; - typedef value_type *pointer; - typedef const value_type *const_pointer; - typedef value_type &reference; - typedef const value_type &const_reference; - typedef internal::hash_map_iterator iterator; - typedef internal::hash_map_iterator const_iterator; - typedef internal::hash_map_range range_type; - typedef internal::hash_map_range const_range_type; - typedef Allocator allocator_type; - -protected: - friend class const_accessor; - struct node; - typedef typename Allocator::template rebind::other node_allocator_type; - node_allocator_type my_allocator; - HashCompare my_hash_compare; - - struct node : public node_base { - value_type item; - node( const Key &key ) : item(key, T()) {} - node( const Key &key, const T &t ) : item(key, t) {} -#if __TBB_CPP11_RVALUE_REF_PRESENT - node( const Key &key, T &&t ) : item(key, std::move(t)) {} - node( value_type&& i ) : item(std::move(i)){} -#if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT - template - node( Args&&... args ) : item(std::forward(args)...) {} -#if __TBB_COPY_FROM_NON_CONST_REF_BROKEN - node( value_type& i ) : item(const_cast(i)) {} -#endif //__TBB_COPY_FROM_NON_CONST_REF_BROKEN -#endif //__TBB_CPP11_VARIADIC_TEMPLATES_PRESENT -#endif //__TBB_CPP11_RVALUE_REF_PRESENT - node( const value_type& i ) : item(i) {} - - // exception-safe allocation, see C++ Standard 2003, clause 5.3.4p17 - void *operator new( size_t /*size*/, node_allocator_type &a ) { - void *ptr = a.allocate(1); - if(!ptr) - tbb::internal::throw_exception(tbb::internal::eid_bad_alloc); - return ptr; - } - // match placement-new form above to be called if exception thrown in constructor - void operator delete( void *ptr, node_allocator_type &a ) { a.deallocate(static_cast(ptr),1); } - }; - - void delete_node( node_base *n ) { - my_allocator.destroy( static_cast(n) ); - my_allocator.deallocate( static_cast(n), 1); - } - - static node* allocate_node_copy_construct(node_allocator_type& allocator, const Key &key, const T * t){ - return new( allocator ) node(key, *t); - } - -#if __TBB_CPP11_RVALUE_REF_PRESENT - static node* allocate_node_move_construct(node_allocator_type& allocator, const Key &key, const T * t){ - return new( allocator ) node(key, std::move(*const_cast(t))); - } -#if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT - template - static node* allocate_node_emplace_construct(node_allocator_type& allocator, Args&&... args){ - return new( allocator ) node(std::forward(args)...); - } -#endif //#if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT -#endif - - static node* allocate_node_default_construct(node_allocator_type& allocator, const Key &key, const T * ){ - return new( allocator ) node(key); - } - - static node* do_not_allocate_node(node_allocator_type& , const Key &, const T * ){ - __TBB_ASSERT(false,"this dummy function should not be called"); - return NULL; - } - - node *search_bucket( const key_type &key, bucket *b ) const { - node *n = static_cast( b->node_list ); - while( is_valid(n) && !my_hash_compare.equal(key, n->item.first) ) - n = static_cast( n->next ); - __TBB_ASSERT(n != internal::rehash_req, "Search can be executed only for rehashed bucket"); - return n; - } - - //! bucket accessor is to find, rehash, acquire a lock, and access a bucket - class bucket_accessor : public bucket::scoped_t { - bucket *my_b; - public: - bucket_accessor( concurrent_hash_map *base, const hashcode_t h, bool writer = false ) { acquire( base, h, writer ); } - //! find a bucket by masked hashcode, optionally rehash, and acquire the lock - inline void acquire( concurrent_hash_map *base, const hashcode_t h, bool writer = false ) { - my_b = base->get_bucket( h ); - // TODO: actually, notification is unnecessary here, just hiding double-check - if( itt_load_word_with_acquire(my_b->node_list) == internal::rehash_req - && try_acquire( my_b->mutex, /*write=*/true ) ) - { - if( my_b->node_list == internal::rehash_req ) base->rehash_bucket( my_b, h ); //recursive rehashing - } - else bucket::scoped_t::acquire( my_b->mutex, writer ); - __TBB_ASSERT( my_b->node_list != internal::rehash_req, NULL); - } - //! check whether bucket is locked for write - bool is_writer() { return bucket::scoped_t::is_writer; } - //! get bucket pointer - bucket *operator() () { return my_b; } - }; - - // TODO refactor to hash_base - void rehash_bucket( bucket *b_new, const hashcode_t h ) { - __TBB_ASSERT( *(intptr_t*)(&b_new->mutex), "b_new must be locked (for write)"); - __TBB_ASSERT( h > 1, "The lowermost buckets can't be rehashed" ); - __TBB_store_with_release(b_new->node_list, internal::empty_rehashed); // mark rehashed - hashcode_t mask = ( 1u<<__TBB_Log2( h ) ) - 1; // get parent mask from the topmost bit -#if __TBB_STATISTICS - my_info_rehashes++; // invocations of rehash_bucket -#endif - - bucket_accessor b_old( this, h & mask ); - - mask = (mask<<1) | 1; // get full mask for new bucket - __TBB_ASSERT( (mask&(mask+1))==0 && (h & mask) == h, NULL ); - restart: - for( node_base **p = &b_old()->node_list, *n = __TBB_load_with_acquire(*p); is_valid(n); n = *p ) { - hashcode_t c = my_hash_compare.hash( static_cast(n)->item.first ); -#if TBB_USE_ASSERT - hashcode_t bmask = h & (mask>>1); - bmask = bmask==0? 1 : ( 1u<<(__TBB_Log2( bmask )+1 ) ) - 1; // minimal mask of parent bucket - __TBB_ASSERT( (c & bmask) == (h & bmask), "hash() function changed for key in table" ); -#endif - if( (c & mask) == h ) { - if( !b_old.is_writer() ) - if( !b_old.upgrade_to_writer() ) { - goto restart; // node ptr can be invalid due to concurrent erase - } - *p = n->next; // exclude from b_old - add_to_bucket( b_new, n ); - } else p = &n->next; // iterate to next item - } - } - - struct call_clear_on_leave { - concurrent_hash_map* my_ch_map; - call_clear_on_leave( concurrent_hash_map* a_ch_map ) : my_ch_map(a_ch_map) {} - void dismiss() {my_ch_map = 0;} - ~call_clear_on_leave(){ - if (my_ch_map){ - my_ch_map->clear(); - } - } - }; -public: - - class accessor; - //! Combines data access, locking, and garbage collection. - class const_accessor : private node::scoped_t /*which derived from no_copy*/ { - friend class concurrent_hash_map; - friend class accessor; - public: - //! Type of value - typedef const typename concurrent_hash_map::value_type value_type; - - //! True if result is empty. - bool empty() const { return !my_node; } - - //! Set to null - void release() { - if( my_node ) { - node::scoped_t::release(); - my_node = 0; - } - } - - //! Return reference to associated value in hash table. - const_reference operator*() const { - __TBB_ASSERT( my_node, "attempt to dereference empty accessor" ); - return my_node->item; - } - - //! Return pointer to associated value in hash table. - const_pointer operator->() const { - return &operator*(); - } - - //! Create empty result - const_accessor() : my_node(NULL) {} - - //! Destroy result after releasing the underlying reference. - ~const_accessor() { - my_node = NULL; // scoped lock's release() is called in its destructor - } - protected: - bool is_writer() { return node::scoped_t::is_writer; } - node *my_node; - hashcode_t my_hash; - }; - - //! Allows write access to elements and combines data access, locking, and garbage collection. - class accessor: public const_accessor { - public: - //! Type of value - typedef typename concurrent_hash_map::value_type value_type; - - //! Return reference to associated value in hash table. - reference operator*() const { - __TBB_ASSERT( this->my_node, "attempt to dereference empty accessor" ); - return this->my_node->item; - } - - //! Return pointer to associated value in hash table. - pointer operator->() const { - return &operator*(); - } - }; - - //! Construct empty table. - explicit concurrent_hash_map( const allocator_type &a = allocator_type() ) - : internal::hash_map_base(), my_allocator(a) - {} - - //! Construct empty table with n preallocated buckets. This number serves also as initial concurrency level. - concurrent_hash_map( size_type n, const allocator_type &a = allocator_type() ) - : my_allocator(a) - { - reserve( n ); - } - - //! Copy constructor - concurrent_hash_map( const concurrent_hash_map &table, const allocator_type &a = allocator_type() ) - : internal::hash_map_base(), my_allocator(a) - { - internal_copy(table); - } - -#if __TBB_CPP11_RVALUE_REF_PRESENT - //! Move constructor - concurrent_hash_map( concurrent_hash_map &&table ) - : internal::hash_map_base(), my_allocator(std::move(table.get_allocator())) - { - swap(table); - } - - //! Move constructor - concurrent_hash_map( concurrent_hash_map &&table, const allocator_type &a ) - : internal::hash_map_base(), my_allocator(a) - { - if (a == table.get_allocator()){ - this->swap(table); - }else{ - call_clear_on_leave scope_guard(this); - internal_copy(std::make_move_iterator(table.begin()), std::make_move_iterator(table.end())); - scope_guard.dismiss(); - } - } -#endif //__TBB_CPP11_RVALUE_REF_PRESENT - - //! Construction with copying iteration range and given allocator instance - template - concurrent_hash_map( I first, I last, const allocator_type &a = allocator_type() ) - : my_allocator(a) - { - reserve( std::distance(first, last) ); // TODO: load_factor? - internal_copy(first, last); - } - -#if __TBB_INITIALIZER_LISTS_PRESENT - //! Construct empty table with n preallocated buckets. This number serves also as initial concurrency level. - concurrent_hash_map( std::initializer_list il, const allocator_type &a = allocator_type() ) - : my_allocator(a) - { - reserve(il.size()); - internal_copy(il.begin(), il.end()); - } - -#endif //__TBB_INITIALIZER_LISTS_PRESENT - - //! Assignment - concurrent_hash_map& operator=( const concurrent_hash_map &table ) { - if( this!=&table ) { - clear(); - internal_copy(table); - } - return *this; - } - -#if __TBB_CPP11_RVALUE_REF_PRESENT - //! Move Assignment - concurrent_hash_map& operator=( concurrent_hash_map &&table ) { - if(this != &table){ - typedef typename tbb::internal::allocator_traits::propagate_on_container_move_assignment pocma_t; - if(pocma_t::value || this->my_allocator == table.my_allocator) { - concurrent_hash_map trash (std::move(*this)); - //TODO: swapping allocators here may be a problem, replace with single direction moving iff pocma is set - this->swap(table); - } else { - //do per element move - concurrent_hash_map moved_copy(std::move(table), this->my_allocator); - this->swap(moved_copy); - } - } - return *this; - } -#endif //__TBB_CPP11_RVALUE_REF_PRESENT - -#if __TBB_INITIALIZER_LISTS_PRESENT - //! Assignment - concurrent_hash_map& operator=( std::initializer_list il ) { - clear(); - reserve(il.size()); - internal_copy(il.begin(), il.end()); - return *this; - } -#endif //__TBB_INITIALIZER_LISTS_PRESENT - - - //! Rehashes and optionally resizes the whole table. - /** Useful to optimize performance before or after concurrent operations. - Also enables using of find() and count() concurrent methods in serial context. */ - void rehash(size_type n = 0); - - //! Clear table - void clear(); - - //! Clear table and destroy it. - ~concurrent_hash_map() { clear(); } - - //------------------------------------------------------------------------ - // Parallel algorithm support - //------------------------------------------------------------------------ - range_type range( size_type grainsize=1 ) { - return range_type( *this, grainsize ); - } - const_range_type range( size_type grainsize=1 ) const { - return const_range_type( *this, grainsize ); - } - - //------------------------------------------------------------------------ - // STL support - not thread-safe methods - //------------------------------------------------------------------------ - iterator begin() { return iterator( *this, 0, my_embedded_segment, my_embedded_segment->node_list ); } - iterator end() { return iterator( *this, 0, 0, 0 ); } - const_iterator begin() const { return const_iterator( *this, 0, my_embedded_segment, my_embedded_segment->node_list ); } - const_iterator end() const { return const_iterator( *this, 0, 0, 0 ); } - std::pair equal_range( const Key& key ) { return internal_equal_range( key, end() ); } - std::pair equal_range( const Key& key ) const { return internal_equal_range( key, end() ); } - - //! Number of items in table. - size_type size() const { return my_size; } - - //! True if size()==0. - bool empty() const { return my_size == 0; } - - //! Upper bound on size. - size_type max_size() const {return (~size_type(0))/sizeof(node);} - - //! Returns the current number of buckets - size_type bucket_count() const { return my_mask+1; } - - //! return allocator object - allocator_type get_allocator() const { return this->my_allocator; } - - //! swap two instances. Iterators are invalidated - void swap( concurrent_hash_map &table ); - - //------------------------------------------------------------------------ - // concurrent map operations - //------------------------------------------------------------------------ - - //! Return count of items (0 or 1) - size_type count( const Key &key ) const { - return const_cast(this)->lookup(/*insert*/false, key, NULL, NULL, /*write=*/false, &do_not_allocate_node ); - } - - //! Find item and acquire a read lock on the item. - /** Return true if item is found, false otherwise. */ - bool find( const_accessor &result, const Key &key ) const { - result.release(); - return const_cast(this)->lookup(/*insert*/false, key, NULL, &result, /*write=*/false, &do_not_allocate_node ); - } - - //! Find item and acquire a write lock on the item. - /** Return true if item is found, false otherwise. */ - bool find( accessor &result, const Key &key ) { - result.release(); - return lookup(/*insert*/false, key, NULL, &result, /*write=*/true, &do_not_allocate_node ); - } - - //! Insert item (if not already present) and acquire a read lock on the item. - /** Returns true if item is new. */ - bool insert( const_accessor &result, const Key &key ) { - result.release(); - return lookup(/*insert*/true, key, NULL, &result, /*write=*/false, &allocate_node_default_construct ); - } - - //! Insert item (if not already present) and acquire a write lock on the item. - /** Returns true if item is new. */ - bool insert( accessor &result, const Key &key ) { - result.release(); - return lookup(/*insert*/true, key, NULL, &result, /*write=*/true, &allocate_node_default_construct ); - } - - //! Insert item by copying if there is no such key present already and acquire a read lock on the item. - /** Returns true if item is new. */ - bool insert( const_accessor &result, const value_type &value ) { - result.release(); - return lookup(/*insert*/true, value.first, &value.second, &result, /*write=*/false, &allocate_node_copy_construct ); - } - - //! Insert item by copying if there is no such key present already and acquire a write lock on the item. - /** Returns true if item is new. */ - bool insert( accessor &result, const value_type &value ) { - result.release(); - return lookup(/*insert*/true, value.first, &value.second, &result, /*write=*/true, &allocate_node_copy_construct ); - } - - //! Insert item by copying if there is no such key present already - /** Returns true if item is inserted. */ - bool insert( const value_type &value ) { - return lookup(/*insert*/true, value.first, &value.second, NULL, /*write=*/false, &allocate_node_copy_construct ); - } - -#if __TBB_CPP11_RVALUE_REF_PRESENT - //! Insert item by copying if there is no such key present already and acquire a read lock on the item. - /** Returns true if item is new. */ - bool insert( const_accessor &result, value_type && value ) { - return generic_move_insert(result, std::move(value)); - } - - //! Insert item by copying if there is no such key present already and acquire a write lock on the item. - /** Returns true if item is new. */ - bool insert( accessor &result, value_type && value ) { - return generic_move_insert(result, std::move(value)); - } - - //! Insert item by copying if there is no such key present already - /** Returns true if item is inserted. */ - bool insert( value_type && value ) { - return generic_move_insert(accessor_not_used(), std::move(value)); - } - -#if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT - //! Insert item by copying if there is no such key present already and acquire a read lock on the item. - /** Returns true if item is new. */ - template - bool emplace( const_accessor &result, Args&&... args ) { - return generic_emplace(result, std::forward(args)...); - } - - //! Insert item by copying if there is no such key present already and acquire a write lock on the item. - /** Returns true if item is new. */ - template - bool emplace( accessor &result, Args&&... args ) { - return generic_emplace(result, std::forward(args)...); - } - - //! Insert item by copying if there is no such key present already - /** Returns true if item is inserted. */ - template - bool emplace( Args&&... args ) { - return generic_emplace(accessor_not_used(), std::forward(args)...); - } -#endif //__TBB_CPP11_VARIADIC_TEMPLATES_PRESENT -#endif //__TBB_CPP11_RVALUE_REF_PRESENT - - //! Insert range [first, last) - template - void insert( I first, I last ) { - for ( ; first != last; ++first ) - insert( *first ); - } - -#if __TBB_INITIALIZER_LISTS_PRESENT - //! Insert initializer list - void insert( std::initializer_list il ) { - insert( il.begin(), il.end() ); - } -#endif //__TBB_INITIALIZER_LISTS_PRESENT - - //! Erase item. - /** Return true if item was erased by particularly this call. */ - bool erase( const Key& key ); - - //! Erase item by const_accessor. - /** Return true if item was erased by particularly this call. */ - bool erase( const_accessor& item_accessor ) { - return exclude( item_accessor ); - } - - //! Erase item by accessor. - /** Return true if item was erased by particularly this call. */ - bool erase( accessor& item_accessor ) { - return exclude( item_accessor ); - } - -protected: - //! Insert or find item and optionally acquire a lock on the item. - bool lookup(bool op_insert, const Key &key, const T *t, const_accessor *result, bool write, node* (*allocate_node)(node_allocator_type& , const Key &, const T * ), node *tmp_n = 0 ) ; - - struct accessor_not_used { void release(){}}; - friend const_accessor* accessor_location( accessor_not_used const& ){ return NULL;} - friend const_accessor* accessor_location( const_accessor & a ) { return &a;} - - friend bool is_write_access_needed( accessor const& ) { return true;} - friend bool is_write_access_needed( const_accessor const& ) { return false;} - friend bool is_write_access_needed( accessor_not_used const& ) { return false;} - -#if __TBB_CPP11_RVALUE_REF_PRESENT - template - bool generic_move_insert( Accessor && result, value_type && value ) { - result.release(); - return lookup(/*insert*/true, value.first, &value.second, accessor_location(result), is_write_access_needed(result), &allocate_node_move_construct ); - } - -#if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT - template - bool generic_emplace( Accessor && result, Args &&... args ) { - result.release(); - node * node_ptr = allocate_node_emplace_construct(my_allocator, std::forward(args)...); - return lookup(/*insert*/true, node_ptr->item.first, NULL, accessor_location(result), is_write_access_needed(result), &do_not_allocate_node, node_ptr ); - } -#endif //__TBB_CPP11_VARIADIC_TEMPLATES_PRESENT -#endif //__TBB_CPP11_RVALUE_REF_PRESENT - - //! delete item by accessor - bool exclude( const_accessor &item_accessor ); - - //! Returns an iterator for an item defined by the key, or for the next item after it (if upper==true) - template - std::pair internal_equal_range( const Key& key, I end ) const; - - //! Copy "source" to *this, where *this must start out empty. - void internal_copy( const concurrent_hash_map& source ); - - template - void internal_copy( I first, I last ); - - //! Fast find when no concurrent erasure is used. For internal use inside TBB only! - /** Return pointer to item with given key, or NULL if no such item exists. - Must not be called concurrently with erasure operations. */ - const_pointer internal_fast_find( const Key& key ) const { - hashcode_t h = my_hash_compare.hash( key ); - hashcode_t m = (hashcode_t) itt_load_word_with_acquire( my_mask ); - node *n; - restart: - __TBB_ASSERT((m&(m+1))==0, "data structure is invalid"); - bucket *b = get_bucket( h & m ); - // TODO: actually, notification is unnecessary here, just hiding double-check - if( itt_load_word_with_acquire(b->node_list) == internal::rehash_req ) - { - bucket::scoped_t lock; - if( lock.try_acquire( b->mutex, /*write=*/true ) ) { - if( b->node_list == internal::rehash_req) - const_cast(this)->rehash_bucket( b, h & m ); //recursive rehashing - } - else lock.acquire( b->mutex, /*write=*/false ); - __TBB_ASSERT(b->node_list!=internal::rehash_req,NULL); - } - n = search_bucket( key, b ); - if( n ) - return &n->item; - else if( check_mask_race( h, m ) ) - goto restart; - return 0; - } -}; - -template -bool concurrent_hash_map::lookup( bool op_insert, const Key &key, const T *t, const_accessor *result, bool write, node* (*allocate_node)(node_allocator_type& , const Key&, const T*), node *tmp_n ) { - __TBB_ASSERT( !result || !result->my_node, NULL ); - bool return_value; - hashcode_t const h = my_hash_compare.hash( key ); - hashcode_t m = (hashcode_t) itt_load_word_with_acquire( my_mask ); - segment_index_t grow_segment = 0; - node *n; - restart: - {//lock scope - __TBB_ASSERT((m&(m+1))==0, "data structure is invalid"); - return_value = false; - // get bucket - bucket_accessor b( this, h & m ); - - // find a node - n = search_bucket( key, b() ); - if( op_insert ) { - // [opt] insert a key - if( !n ) { - if( !tmp_n ) { - tmp_n = allocate_node(my_allocator, key, t); - } - if( !b.is_writer() && !b.upgrade_to_writer() ) { // TODO: improved insertion - // Rerun search_list, in case another thread inserted the item during the upgrade. - n = search_bucket( key, b() ); - if( is_valid(n) ) { // unfortunately, it did - b.downgrade_to_reader(); - goto exists; - } - } - if( check_mask_race(h, m) ) - goto restart; // b.release() is done in ~b(). - // insert and set flag to grow the container - grow_segment = insert_new_node( b(), n = tmp_n, m ); - tmp_n = 0; - return_value = true; - } - } else { // find or count - if( !n ) { - if( check_mask_race( h, m ) ) - goto restart; // b.release() is done in ~b(). TODO: replace by continue - return false; - } - return_value = true; - } - exists: - if( !result ) goto check_growth; - // TODO: the following seems as generic/regular operation - // acquire the item - if( !result->try_acquire( n->mutex, write ) ) { - for( tbb::internal::atomic_backoff backoff(true);; ) { - if( result->try_acquire( n->mutex, write ) ) break; - if( !backoff.bounded_pause() ) { - // the wait takes really long, restart the operation - b.release(); - __TBB_ASSERT( !op_insert || !return_value, "Can't acquire new item in locked bucket?" ); - __TBB_Yield(); - m = (hashcode_t) itt_load_word_with_acquire( my_mask ); - goto restart; - } - } - } - }//lock scope - result->my_node = n; - result->my_hash = h; -check_growth: - // [opt] grow the container - if( grow_segment ) { -#if __TBB_STATISTICS - my_info_resizes++; // concurrent ones -#endif - enable_segment( grow_segment ); - } - if( tmp_n ) // if op_insert only - delete_node( tmp_n ); - return return_value; -} - -template -template -std::pair concurrent_hash_map::internal_equal_range( const Key& key, I end_ ) const { - hashcode_t h = my_hash_compare.hash( key ); - hashcode_t m = my_mask; - __TBB_ASSERT((m&(m+1))==0, "data structure is invalid"); - h &= m; - bucket *b = get_bucket( h ); - while( b->node_list == internal::rehash_req ) { - m = ( 1u<<__TBB_Log2( h ) ) - 1; // get parent mask from the topmost bit - b = get_bucket( h &= m ); - } - node *n = search_bucket( key, b ); - if( !n ) - return std::make_pair(end_, end_); - iterator lower(*this, h, b, n), upper(lower); - return std::make_pair(lower, ++upper); -} - -template -bool concurrent_hash_map::exclude( const_accessor &item_accessor ) { - __TBB_ASSERT( item_accessor.my_node, NULL ); - node_base *const n = item_accessor.my_node; - hashcode_t const h = item_accessor.my_hash; - hashcode_t m = (hashcode_t) itt_load_word_with_acquire( my_mask ); - do { - // get bucket - bucket_accessor b( this, h & m, /*writer=*/true ); - node_base **p = &b()->node_list; - while( *p && *p != n ) - p = &(*p)->next; - if( !*p ) { // someone else was first - if( check_mask_race( h, m ) ) - continue; - item_accessor.release(); - return false; - } - __TBB_ASSERT( *p == n, NULL ); - *p = n->next; // remove from container - my_size--; - break; - } while(true); - if( !item_accessor.is_writer() ) // need to get exclusive lock - item_accessor.upgrade_to_writer(); // return value means nothing here - item_accessor.release(); - delete_node( n ); // Only one thread can delete it - return true; -} - -template -bool concurrent_hash_map::erase( const Key &key ) { - node_base *n; - hashcode_t const h = my_hash_compare.hash( key ); - hashcode_t m = (hashcode_t) itt_load_word_with_acquire( my_mask ); -restart: - {//lock scope - // get bucket - bucket_accessor b( this, h & m ); - search: - node_base **p = &b()->node_list; - n = *p; - while( is_valid(n) && !my_hash_compare.equal(key, static_cast(n)->item.first ) ) { - p = &n->next; - n = *p; - } - if( !n ) { // not found, but mask could be changed - if( check_mask_race( h, m ) ) - goto restart; - return false; - } - else if( !b.is_writer() && !b.upgrade_to_writer() ) { - if( check_mask_race( h, m ) ) // contended upgrade, check mask - goto restart; - goto search; - } - *p = n->next; - my_size--; - } - { - typename node::scoped_t item_locker( n->mutex, /*write=*/true ); - } - // note: there should be no threads pretending to acquire this mutex again, do not try to upgrade const_accessor! - delete_node( n ); // Only one thread can delete it due to write lock on the bucket - return true; -} - -template -void concurrent_hash_map::swap(concurrent_hash_map &table) { - //TODO: respect C++11 allocator_traits::propogate_on_constainer_swap - using std::swap; - swap(this->my_allocator, table.my_allocator); - swap(this->my_hash_compare, table.my_hash_compare); - internal_swap(table); -} - -template -void concurrent_hash_map::rehash(size_type sz) { - reserve( sz ); // TODO: add reduction of number of buckets as well - hashcode_t mask = my_mask; - hashcode_t b = (mask+1)>>1; // size or first index of the last segment - __TBB_ASSERT((b&(b-1))==0, NULL); // zero or power of 2 - bucket *bp = get_bucket( b ); // only the last segment should be scanned for rehashing - for(; b <= mask; b++, bp++ ) { - node_base *n = bp->node_list; - __TBB_ASSERT( is_valid(n) || n == internal::empty_rehashed || n == internal::rehash_req, "Broken internal structure" ); - __TBB_ASSERT( *reinterpret_cast(&bp->mutex) == 0, "concurrent or unexpectedly terminated operation during rehash() execution" ); - if( n == internal::rehash_req ) { // rehash bucket, conditional because rehashing of a previous bucket may affect this one - hashcode_t h = b; bucket *b_old = bp; - do { - __TBB_ASSERT( h > 1, "The lowermost buckets can't be rehashed" ); - hashcode_t m = ( 1u<<__TBB_Log2( h ) ) - 1; // get parent mask from the topmost bit - b_old = get_bucket( h &= m ); - } while( b_old->node_list == internal::rehash_req ); - // now h - is index of the root rehashed bucket b_old - mark_rehashed_levels( h ); // mark all non-rehashed children recursively across all segments - for( node_base **p = &b_old->node_list, *q = *p; is_valid(q); q = *p ) { - hashcode_t c = my_hash_compare.hash( static_cast(q)->item.first ); - if( (c & mask) != h ) { // should be rehashed - *p = q->next; // exclude from b_old - bucket *b_new = get_bucket( c & mask ); - __TBB_ASSERT( b_new->node_list != internal::rehash_req, "hash() function changed for key in table or internal error" ); - add_to_bucket( b_new, q ); - } else p = &q->next; // iterate to next item - } - } - } -#if TBB_USE_PERFORMANCE_WARNINGS - int current_size = int(my_size), buckets = int(mask)+1, empty_buckets = 0, overpopulated_buckets = 0; // usage statistics - static bool reported = false; -#endif -#if TBB_USE_ASSERT || TBB_USE_PERFORMANCE_WARNINGS - for( b = 0; b <= mask; b++ ) {// only last segment should be scanned for rehashing - if( b & (b-2) ) ++bp; // not the beginning of a segment - else bp = get_bucket( b ); - node_base *n = bp->node_list; - __TBB_ASSERT( *reinterpret_cast(&bp->mutex) == 0, "concurrent or unexpectedly terminated operation during rehash() execution" ); - __TBB_ASSERT( is_valid(n) || n == internal::empty_rehashed, "Broken internal structure" ); -#if TBB_USE_PERFORMANCE_WARNINGS - if( n == internal::empty_rehashed ) empty_buckets++; - else if( n->next ) overpopulated_buckets++; -#endif -#if TBB_USE_ASSERT - for( ; is_valid(n); n = n->next ) { - hashcode_t h = my_hash_compare.hash( static_cast(n)->item.first ) & mask; - __TBB_ASSERT( h == b, "hash() function changed for key in table or internal error" ); - } -#endif - } -#endif // TBB_USE_ASSERT || TBB_USE_PERFORMANCE_WARNINGS -#if TBB_USE_PERFORMANCE_WARNINGS - if( buckets > current_size) empty_buckets -= buckets - current_size; - else overpopulated_buckets -= current_size - buckets; // TODO: load_factor? - if( !reported && buckets >= 512 && ( 2*empty_buckets > current_size || 2*overpopulated_buckets > current_size ) ) { - tbb::internal::runtime_warning( - "Performance is not optimal because the hash function produces bad randomness in lower bits in %s.\nSize: %d Empties: %d Overlaps: %d", -#if __TBB_USE_OPTIONAL_RTTI - typeid(*this).name(), -#else - "concurrent_hash_map", -#endif - current_size, empty_buckets, overpopulated_buckets ); - reported = true; - } -#endif -} - -template -void concurrent_hash_map::clear() { - hashcode_t m = my_mask; - __TBB_ASSERT((m&(m+1))==0, "data structure is invalid"); -#if TBB_USE_ASSERT || TBB_USE_PERFORMANCE_WARNINGS || __TBB_STATISTICS -#if TBB_USE_PERFORMANCE_WARNINGS || __TBB_STATISTICS - int current_size = int(my_size), buckets = int(m)+1, empty_buckets = 0, overpopulated_buckets = 0; // usage statistics - static bool reported = false; -#endif - bucket *bp = 0; - // check consistency - for( segment_index_t b = 0; b <= m; b++ ) { - if( b & (b-2) ) ++bp; // not the beginning of a segment - else bp = get_bucket( b ); - node_base *n = bp->node_list; - __TBB_ASSERT( is_valid(n) || n == internal::empty_rehashed || n == internal::rehash_req, "Broken internal structure" ); - __TBB_ASSERT( *reinterpret_cast(&bp->mutex) == 0, "concurrent or unexpectedly terminated operation during clear() execution" ); -#if TBB_USE_PERFORMANCE_WARNINGS || __TBB_STATISTICS - if( n == internal::empty_rehashed ) empty_buckets++; - else if( n == internal::rehash_req ) buckets--; - else if( n->next ) overpopulated_buckets++; -#endif -#if __TBB_EXTRA_DEBUG - for(; is_valid(n); n = n->next ) { - hashcode_t h = my_hash_compare.hash( static_cast(n)->item.first ); - h &= m; - __TBB_ASSERT( h == b || get_bucket(h)->node_list == internal::rehash_req, "hash() function changed for key in table or internal error" ); - } -#endif - } -#if TBB_USE_PERFORMANCE_WARNINGS || __TBB_STATISTICS -#if __TBB_STATISTICS - printf( "items=%d buckets: capacity=%d rehashed=%d empty=%d overpopulated=%d" - " concurrent: resizes=%u rehashes=%u restarts=%u\n", - current_size, int(m+1), buckets, empty_buckets, overpopulated_buckets, - unsigned(my_info_resizes), unsigned(my_info_rehashes), unsigned(my_info_restarts) ); - my_info_resizes = 0; // concurrent ones - my_info_restarts = 0; // race collisions - my_info_rehashes = 0; // invocations of rehash_bucket -#endif - if( buckets > current_size) empty_buckets -= buckets - current_size; - else overpopulated_buckets -= current_size - buckets; // TODO: load_factor? - if( !reported && buckets >= 512 && ( 2*empty_buckets > current_size || 2*overpopulated_buckets > current_size ) ) { - tbb::internal::runtime_warning( - "Performance is not optimal because the hash function produces bad randomness in lower bits in %s.\nSize: %d Empties: %d Overlaps: %d", -#if __TBB_USE_OPTIONAL_RTTI - typeid(*this).name(), -#else - "concurrent_hash_map", -#endif - current_size, empty_buckets, overpopulated_buckets ); - reported = true; - } -#endif -#endif//TBB_USE_ASSERT || TBB_USE_PERFORMANCE_WARNINGS || __TBB_STATISTICS - my_size = 0; - segment_index_t s = segment_index_of( m ); - __TBB_ASSERT( s+1 == pointers_per_table || !my_table[s+1], "wrong mask or concurrent grow" ); - cache_aligned_allocator alloc; - do { - __TBB_ASSERT( is_valid( my_table[s] ), "wrong mask or concurrent grow" ); - segment_ptr_t buckets_ptr = my_table[s]; - size_type sz = segment_size( s ? s : 1 ); - for( segment_index_t i = 0; i < sz; i++ ) - for( node_base *n = buckets_ptr[i].node_list; is_valid(n); n = buckets_ptr[i].node_list ) { - buckets_ptr[i].node_list = n->next; - delete_node( n ); - } - if( s >= first_block) // the first segment or the next - alloc.deallocate( buckets_ptr, sz ); - else if( s == embedded_block && embedded_block != first_block ) - alloc.deallocate( buckets_ptr, segment_size(first_block)-embedded_buckets ); - if( s >= embedded_block ) my_table[s] = 0; - } while(s-- > 0); - my_mask = embedded_buckets - 1; -} - -template -void concurrent_hash_map::internal_copy( const concurrent_hash_map& source ) { - reserve( source.my_size ); // TODO: load_factor? - hashcode_t mask = source.my_mask; - if( my_mask == mask ) { // optimized version - bucket *dst = 0, *src = 0; - bool rehash_required = false; - for( hashcode_t k = 0; k <= mask; k++ ) { - if( k & (k-2) ) ++dst,src++; // not the beginning of a segment - else { dst = get_bucket( k ); src = source.get_bucket( k ); } - __TBB_ASSERT( dst->node_list != internal::rehash_req, "Invalid bucket in destination table"); - node *n = static_cast( src->node_list ); - if( n == internal::rehash_req ) { // source is not rehashed, items are in previous buckets - rehash_required = true; - dst->node_list = internal::rehash_req; - } else for(; n; n = static_cast( n->next ) ) { - add_to_bucket( dst, new( my_allocator ) node(n->item.first, n->item.second) ); - ++my_size; // TODO: replace by non-atomic op - } - } - if( rehash_required ) rehash(); - } else internal_copy( source.begin(), source.end() ); -} - -template -template -void concurrent_hash_map::internal_copy(I first, I last) { - hashcode_t m = my_mask; - for(; first != last; ++first) { - hashcode_t h = my_hash_compare.hash( (*first).first ); - bucket *b = get_bucket( h & m ); - __TBB_ASSERT( b->node_list != internal::rehash_req, "Invalid bucket in destination table"); - node *n = new( my_allocator ) node(*first); - add_to_bucket( b, n ); - ++my_size; // TODO: replace by non-atomic op - } -} - -} // namespace interface5 - -using interface5::concurrent_hash_map; - - -template -inline bool operator==(const concurrent_hash_map &a, const concurrent_hash_map &b) { - if(a.size() != b.size()) return false; - typename concurrent_hash_map::const_iterator i(a.begin()), i_end(a.end()); - typename concurrent_hash_map::const_iterator j, j_end(b.end()); - for(; i != i_end; ++i) { - j = b.equal_range(i->first).first; - if( j == j_end || !(i->second == j->second) ) return false; - } - return true; -} - -template -inline bool operator!=(const concurrent_hash_map &a, const concurrent_hash_map &b) -{ return !(a == b); } - -template -inline void swap(concurrent_hash_map &a, concurrent_hash_map &b) -{ a.swap( b ); } - -#if _MSC_VER && !defined(__INTEL_COMPILER) - #pragma warning( pop ) -#endif // warning 4127 is back - -} // namespace tbb - -#endif /* __TBB_concurrent_hash_map_H */ diff --git a/lib/3rdParty/tbb/include/tbb/concurrent_lru_cache.h b/lib/3rdParty/tbb/include/tbb/concurrent_lru_cache.h deleted file mode 100644 index 8aacf241..00000000 --- a/lib/3rdParty/tbb/include/tbb/concurrent_lru_cache.h +++ /dev/null @@ -1,235 +0,0 @@ -/* - 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_concurrent_lru_cache_H -#define __TBB_concurrent_lru_cache_H - -#if ! TBB_PREVIEW_CONCURRENT_LRU_CACHE - #error Set TBB_PREVIEW_CONCURRENT_LRU_CACHE to include concurrent_lru_cache.h -#endif - -#include -#include - -#include "tbb_stddef.h" -#include "atomic.h" -#include "internal/_aggregator_impl.h" - -namespace tbb{ -namespace interface6 { - - -template -class concurrent_lru_cache : internal::no_assign{ -private: - typedef concurrent_lru_cache self_type; - typedef value_functor_type value_function_type; - typedef std::size_t ref_counter_type; - struct map_value_type; - typedef std::map map_storage_type; - typedef std::list lru_list_type; - struct map_value_type { - value_type my_value; - ref_counter_type my_ref_counter; - typename lru_list_type::iterator my_lru_list_iterator; - bool my_is_ready; - - map_value_type (value_type const& a_value, ref_counter_type a_ref_counter, typename lru_list_type::iterator a_lru_list_iterator, bool a_is_ready) - : my_value(a_value), my_ref_counter(a_ref_counter), my_lru_list_iterator (a_lru_list_iterator), my_is_ready(a_is_ready) - {} - }; - - class handle_object; - - struct aggregator_operation; - typedef aggregator_operation aggregated_operation_type; - typedef tbb::internal::aggregating_functor aggregator_function_type; - friend class tbb::internal::aggregating_functor; - typedef tbb::internal::aggregator aggregator_type; - -private: - value_function_type my_value_function; - std::size_t const my_number_of_lru_history_items; - map_storage_type my_map_storage; - lru_list_type my_lru_list; - aggregator_type my_aggregator; - -public: - typedef handle_object handle; - -public: - concurrent_lru_cache(value_function_type f, std::size_t number_of_lru_history_items) - : my_value_function(f),my_number_of_lru_history_items(number_of_lru_history_items) - { - my_aggregator.initialize_handler(aggregator_function_type(this)); - } - - handle_object operator[](key_type k){ - retrieve_aggregator_operation op(k); - my_aggregator.execute(&op); - if (op.is_new_value_needed()){ - op.result().second.my_value = my_value_function(k); - __TBB_store_with_release(op.result().second.my_is_ready, true); - }else{ - tbb::internal::spin_wait_while_eq(op.result().second.my_is_ready,false); - } - return handle_object(*this,op.result()); - } -private: - void signal_end_of_usage(typename map_storage_type::reference value_ref){ - signal_end_of_usage_aggregator_operation op(value_ref); - my_aggregator.execute(&op); - } - -private: - struct handle_move_t:no_assign{ - concurrent_lru_cache & my_cache_ref; - typename map_storage_type::reference my_map_record_ref; - handle_move_t(concurrent_lru_cache & cache_ref, typename map_storage_type::reference value_ref):my_cache_ref(cache_ref),my_map_record_ref(value_ref) {}; - }; - class handle_object { - concurrent_lru_cache * my_cache_pointer; - typename map_storage_type::reference my_map_record_ref; - public: - handle_object(concurrent_lru_cache & cache_ref, typename map_storage_type::reference value_ref):my_cache_pointer(&cache_ref), my_map_record_ref(value_ref) {} - handle_object(handle_move_t m):my_cache_pointer(&m.my_cache_ref), my_map_record_ref(m.my_map_record_ref){} - operator handle_move_t(){ return move(*this);} - value_type& value(){ - __TBB_ASSERT(my_cache_pointer,"get value from moved from object?"); - return my_map_record_ref.second.my_value; - } - ~handle_object(){ - if (my_cache_pointer){ - my_cache_pointer->signal_end_of_usage(my_map_record_ref); - } - } - private: - friend handle_move_t move(handle_object& h){ - return handle_object::move(h); - } - 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 = h.my_cache_pointer; - h.my_cache_pointer = NULL; - return handle_move_t(*cache_pointer,h.my_map_record_ref); - } - private: - void operator=(handle_object&); -#if __SUNPRO_CC - // Presumably due to a compiler error, private copy constructor - // breaks expressions like handle h = cache[key]; - public: -#endif - handle_object(handle_object &); - }; -private: - //TODO: looks like aggregator_operation is a perfect match for statically typed variant type - struct aggregator_operation : tbb::internal::aggregated_operation{ - enum e_op_type {op_retive, op_signal_end_of_usage}; - //TODO: try to use pointer to function apply_visitor here - //TODO: try virtual functions and measure the difference - e_op_type my_operation_type; - aggregator_operation(e_op_type operation_type): my_operation_type(operation_type) {} - void cast_and_handle(self_type& container ){ - if (my_operation_type==op_retive){ - static_cast(this)->handle(container); - }else{ - static_cast(this)->handle(container); - } - } - }; - struct retrieve_aggregator_operation : aggregator_operation, private internal::no_assign { - key_type my_key; - typename map_storage_type::pointer my_result_map_record_pointer; - bool my_is_new_value_needed; - retrieve_aggregator_operation(key_type key):aggregator_operation(aggregator_operation::op_retive),my_key(key),my_is_new_value_needed(false){} - void handle(self_type& container ){ - my_result_map_record_pointer = & container.retrieve_serial(my_key,my_is_new_value_needed); - } - typename map_storage_type::reference result(){ return * my_result_map_record_pointer; } - bool is_new_value_needed(){return my_is_new_value_needed;} - }; - struct signal_end_of_usage_aggregator_operation : aggregator_operation, private internal::no_assign { - typename map_storage_type::reference my_map_record_ref; - signal_end_of_usage_aggregator_operation(typename map_storage_type::reference map_record_ref):aggregator_operation(aggregator_operation::op_signal_end_of_usage),my_map_record_ref(map_record_ref){} - void handle(self_type& container ){ - container.signal_end_of_usage_serial(my_map_record_ref); - } - }; - -private: - void handle_operations(aggregator_operation* op_list){ - while(op_list){ - op_list->cast_and_handle(*this); - aggregator_operation* tmp = op_list; - op_list=op_list->next; - tbb::internal::itt_store_word_with_release(tmp->status, uintptr_t(1)); - } - } - -private: - typename map_storage_type::reference retrieve_serial(key_type k, bool& is_new_value_needed){ - typename map_storage_type::iterator it = my_map_storage.find(k); - if (it == my_map_storage.end()){ - it = my_map_storage.insert(it,std::make_pair(k,map_value_type(value_type(),0,my_lru_list.end(),false))); - is_new_value_needed = true; - }else { - typename lru_list_type::iterator list_it = it->second.my_lru_list_iterator; - if (list_it!=my_lru_list.end()) { - __TBB_ASSERT(!it->second.my_ref_counter,"item to be evicted should not have a live references"); - //item is going to be used. Therefore it is not a subject for eviction - //so - remove it from LRU history. - my_lru_list.erase(list_it); - it->second.my_lru_list_iterator= my_lru_list.end(); - } - } - ++(it->second.my_ref_counter); - return *it; - } - - void signal_end_of_usage_serial(typename map_storage_type::reference map_record_ref){ - typename map_storage_type::iterator it = my_map_storage.find(map_record_ref.first); - __TBB_ASSERT(it!=my_map_storage.end(),"cache should not return past-end iterators to outer world"); - __TBB_ASSERT(&(*it) == &map_record_ref,"dangling reference has been returned to outside world? data race ?"); - __TBB_ASSERT( my_lru_list.end()== std::find(my_lru_list.begin(),my_lru_list.end(),it), - "object in use should not be in list of unused objects "); - if (! --(it->second.my_ref_counter)){ - //it was the last reference so put it to the LRU history - if (my_lru_list.size()>=my_number_of_lru_history_items){ - //evict items in order to get a space - size_t number_of_elements_to_evict = 1 + my_lru_list.size() - my_number_of_lru_history_items; - for (size_t i=0; isecond.my_ref_counter,"item to be evicted should not have a live references"); - my_lru_list.pop_back(); - my_map_storage.erase(it_to_evict); - } - } - my_lru_list.push_front(it); - it->second.my_lru_list_iterator = my_lru_list.begin(); - } - } -}; -} // namespace interface6 - -using interface6::concurrent_lru_cache; - -} // namespace tbb -#endif //__TBB_concurrent_lru_cache_H diff --git a/lib/3rdParty/tbb/include/tbb/concurrent_priority_queue.h b/lib/3rdParty/tbb/include/tbb/concurrent_priority_queue.h deleted file mode 100644 index 89297d85..00000000 --- a/lib/3rdParty/tbb/include/tbb/concurrent_priority_queue.h +++ /dev/null @@ -1,490 +0,0 @@ -/* - 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_concurrent_priority_queue_H -#define __TBB_concurrent_priority_queue_H - -#include "atomic.h" -#include "cache_aligned_allocator.h" -#include "tbb_exception.h" -#include "tbb_stddef.h" -#include "tbb_profiling.h" -#include "internal/_aggregator_impl.h" -#include -#include -#include -#include __TBB_STD_SWAP_HEADER - -#if __TBB_INITIALIZER_LISTS_PRESENT - #include -#endif - -#if __TBB_CPP11_IS_COPY_CONSTRUCTIBLE_PRESENT - #include -#endif - -namespace tbb { -namespace interface5 { -namespace internal { -#if __TBB_CPP11_IS_COPY_CONSTRUCTIBLE_PRESENT - template::value> - struct use_element_copy_constructor { - typedef tbb::internal::true_type type; - }; - template - struct use_element_copy_constructor { - typedef tbb::internal::false_type type; - }; -#else - template - struct use_element_copy_constructor { - typedef tbb::internal::true_type type; - }; -#endif -} // namespace internal - -using namespace tbb::internal; - -//! Concurrent priority queue -template , typename A=cache_aligned_allocator > -class concurrent_priority_queue { - public: - //! Element type in the queue. - typedef T value_type; - - //! Reference type - typedef T& reference; - - //! Const reference type - typedef const T& const_reference; - - //! Integral type for representing size of the queue. - typedef size_t size_type; - - //! Difference type for iterator - typedef ptrdiff_t difference_type; - - //! Allocator type - typedef A allocator_type; - - //! Constructs a new concurrent_priority_queue with default capacity - explicit concurrent_priority_queue(const allocator_type& a = allocator_type()) : mark(0), my_size(0), data(a) - { - my_aggregator.initialize_handler(my_functor_t(this)); - } - - //! Constructs a new concurrent_priority_queue with init_sz capacity - explicit concurrent_priority_queue(size_type init_capacity, const allocator_type& a = allocator_type()) : - mark(0), my_size(0), data(a) - { - data.reserve(init_capacity); - my_aggregator.initialize_handler(my_functor_t(this)); - } - - //! [begin,end) constructor - template - concurrent_priority_queue(InputIterator begin, InputIterator end, const allocator_type& a = allocator_type()) : - mark(0), data(begin, end, a) - { - my_aggregator.initialize_handler(my_functor_t(this)); - heapify(); - my_size = data.size(); - } - -#if __TBB_INITIALIZER_LISTS_PRESENT - //! Constructor from std::initializer_list - concurrent_priority_queue(std::initializer_list init_list, const allocator_type &a = allocator_type()) : - mark(0),data(init_list.begin(), init_list.end(), a) - { - my_aggregator.initialize_handler(my_functor_t(this)); - heapify(); - my_size = data.size(); - } -#endif //# __TBB_INITIALIZER_LISTS_PRESENT - - //! Copy constructor - /** This operation is unsafe if there are pending concurrent operations on the src queue. */ - explicit concurrent_priority_queue(const concurrent_priority_queue& src) : mark(src.mark), - my_size(src.my_size), data(src.data.begin(), src.data.end(), src.data.get_allocator()) - { - my_aggregator.initialize_handler(my_functor_t(this)); - heapify(); - } - - //! Copy constructor with specific allocator - /** This operation is unsafe if there are pending concurrent operations on the src queue. */ - concurrent_priority_queue(const concurrent_priority_queue& src, const allocator_type& a) : mark(src.mark), - my_size(src.my_size), data(src.data.begin(), src.data.end(), a) - { - my_aggregator.initialize_handler(my_functor_t(this)); - heapify(); - } - - //! Assignment operator - /** This operation is unsafe if there are pending concurrent operations on the src queue. */ - concurrent_priority_queue& operator=(const concurrent_priority_queue& src) { - if (this != &src) { - vector_t(src.data.begin(), src.data.end(), src.data.get_allocator()).swap(data); - mark = src.mark; - my_size = src.my_size; - } - return *this; - } - -#if __TBB_CPP11_RVALUE_REF_PRESENT - //! Move constructor - /** This operation is unsafe if there are pending concurrent operations on the src queue. */ - concurrent_priority_queue(concurrent_priority_queue&& src) : mark(src.mark), - my_size(src.my_size), data(std::move(src.data)) - { - my_aggregator.initialize_handler(my_functor_t(this)); - } - - //! Move constructor with specific allocator - /** This operation is unsafe if there are pending concurrent operations on the src queue. */ - concurrent_priority_queue(concurrent_priority_queue&& src, const allocator_type& a) : mark(src.mark), - my_size(src.my_size), -#if __TBB_ALLOCATOR_TRAITS_PRESENT - data(std::move(src.data), a) -#else - // Some early version of C++11 STL vector does not have a constructor of vector(vector&& , allocator). - // It seems that the reason is absence of support of allocator_traits (stateful allocators). - data(a) -#endif //__TBB_ALLOCATOR_TRAITS_PRESENT - { - my_aggregator.initialize_handler(my_functor_t(this)); -#if !__TBB_ALLOCATOR_TRAITS_PRESENT - if (a != src.data.get_allocator()){ - data.reserve(src.data.size()); - data.assign(std::make_move_iterator(src.data.begin()), std::make_move_iterator(src.data.end())); - }else{ - data = std::move(src.data); - } -#endif //!__TBB_ALLOCATOR_TRAITS_PRESENT - } - - //! Move assignment operator - /** This operation is unsafe if there are pending concurrent operations on the src queue. */ - concurrent_priority_queue& operator=( concurrent_priority_queue&& src) { - if (this != &src) { - mark = src.mark; - my_size = src.my_size; -#if !__TBB_ALLOCATOR_TRAITS_PRESENT - if (data.get_allocator() != src.data.get_allocator()){ - vector_t(std::make_move_iterator(src.data.begin()), std::make_move_iterator(src.data.end()), data.get_allocator()).swap(data); - }else -#endif //!__TBB_ALLOCATOR_TRAITS_PRESENT - { - data = std::move(src.data); - } - } - return *this; - } -#endif //__TBB_CPP11_RVALUE_REF_PRESENT - - //! Assign the queue from [begin,end) range, not thread-safe - template - void assign(InputIterator begin, InputIterator end) { - vector_t(begin, end, data.get_allocator()).swap(data); - mark = 0; - my_size = data.size(); - heapify(); - } - -#if __TBB_INITIALIZER_LISTS_PRESENT - //! Assign the queue from std::initializer_list, not thread-safe - void assign(std::initializer_list il) { this->assign(il.begin(), il.end()); } - - //! Assign from std::initializer_list, not thread-safe - concurrent_priority_queue& operator=(std::initializer_list il) { - this->assign(il.begin(), il.end()); - return *this; - } -#endif //# __TBB_INITIALIZER_LISTS_PRESENT - - //! Returns true if empty, false otherwise - /** Returned value may not reflect results of pending operations. - This operation reads shared data and will trigger a race condition. */ - bool empty() const { return size()==0; } - - //! Returns the current number of elements contained in the queue - /** Returned value may not reflect results of pending operations. - This operation reads shared data and will trigger a race condition. */ - size_type size() const { return __TBB_load_with_acquire(my_size); } - - //! Pushes elem onto the queue, increasing capacity of queue if necessary - /** This operation can be safely used concurrently with other push, try_pop or emplace operations. */ - void push(const_reference elem) { -#if __TBB_CPP11_IS_COPY_CONSTRUCTIBLE_PRESENT - __TBB_STATIC_ASSERT( std::is_copy_constructible::value, "The type is not copy constructible. Copying push operation is impossible." ); -#endif - cpq_operation op_data(elem, PUSH_OP); - my_aggregator.execute(&op_data); - if (op_data.status == FAILED) // exception thrown - throw_exception(eid_bad_alloc); - } - -#if __TBB_CPP11_RVALUE_REF_PRESENT - //! Pushes elem onto the queue, increasing capacity of queue if necessary - /** This operation can be safely used concurrently with other push, try_pop or emplace operations. */ - void push(value_type &&elem) { - cpq_operation op_data(elem, PUSH_RVALUE_OP); - my_aggregator.execute(&op_data); - if (op_data.status == FAILED) // exception thrown - throw_exception(eid_bad_alloc); - } - -#if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT - //! Constructs a new element using args as the arguments for its construction and pushes it onto the queue */ - /** This operation can be safely used concurrently with other push, try_pop or emplace operations. */ - template - void emplace(Args&&... args) { - push(value_type(std::forward(args)...)); - } -#endif /* __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT */ -#endif /* __TBB_CPP11_RVALUE_REF_PRESENT */ - - //! Gets a reference to and removes highest priority element - /** If a highest priority element was found, sets elem and returns true, - otherwise returns false. - This operation can be safely used concurrently with other push, try_pop or emplace operations. */ - bool try_pop(reference elem) { - cpq_operation op_data(POP_OP); - op_data.elem = &elem; - my_aggregator.execute(&op_data); - return op_data.status==SUCCEEDED; - } - - //! Clear the queue; not thread-safe - /** This operation is unsafe if there are pending concurrent operations on the queue. - Resets size, effectively emptying queue; does not free space. - May not clear elements added in pending operations. */ - void clear() { - data.clear(); - mark = 0; - my_size = 0; - } - - //! Swap this queue with another; not thread-safe - /** This operation is unsafe if there are pending concurrent operations on the queue. */ - void swap(concurrent_priority_queue& q) { - using std::swap; - data.swap(q.data); - swap(mark, q.mark); - swap(my_size, q.my_size); - } - - //! Return allocator object - allocator_type get_allocator() const { return data.get_allocator(); } - - private: - enum operation_type {INVALID_OP, PUSH_OP, POP_OP, PUSH_RVALUE_OP}; - enum operation_status { WAIT=0, SUCCEEDED, FAILED }; - - class cpq_operation : public aggregated_operation { - public: - operation_type type; - union { - value_type *elem; - size_type sz; - }; - cpq_operation(const_reference e, operation_type t) : - type(t), elem(const_cast(&e)) {} - cpq_operation(operation_type t) : type(t) {} - }; - - class my_functor_t { - concurrent_priority_queue *cpq; - public: - my_functor_t() {} - my_functor_t(concurrent_priority_queue *cpq_) : cpq(cpq_) {} - void operator()(cpq_operation* op_list) { - cpq->handle_operations(op_list); - } - }; - - typedef tbb::internal::aggregator< my_functor_t, cpq_operation > aggregator_t; - aggregator_t my_aggregator; - //! Padding added to avoid false sharing - char padding1[NFS_MaxLineSize - sizeof(aggregator_t)]; - //! The point at which unsorted elements begin - size_type mark; - __TBB_atomic size_type my_size; - Compare compare; - //! Padding added to avoid false sharing - char padding2[NFS_MaxLineSize - (2*sizeof(size_type)) - sizeof(Compare)]; - //! Storage for the heap of elements in queue, plus unheapified elements - /** data has the following structure: - - binary unheapified - heap elements - ____|_______|____ - | | | - v v v - [_|...|_|_|...|_| |...| ] - 0 ^ ^ ^ - | | |__capacity - | |__my_size - |__mark - - Thus, data stores the binary heap starting at position 0 through - mark-1 (it may be empty). Then there are 0 or more elements - that have not yet been inserted into the heap, in positions - mark through my_size-1. */ - typedef std::vector vector_t; - vector_t data; - - void handle_operations(cpq_operation *op_list) { - cpq_operation *tmp, *pop_list=NULL; - - __TBB_ASSERT(mark == data.size(), NULL); - - // First pass processes all constant (amortized; reallocation may happen) time pushes and pops. - while (op_list) { - // ITT note: &(op_list->status) tag is used to cover accesses to op_list - // node. This thread is going to handle the operation, and so will acquire it - // and perform the associated operation w/o triggering a race condition; the - // thread that created the operation is waiting on the status field, so when - // this thread is done with the operation, it will perform a - // store_with_release to give control back to the waiting thread in - // aggregator::insert_operation. - call_itt_notify(acquired, &(op_list->status)); - __TBB_ASSERT(op_list->type != INVALID_OP, NULL); - tmp = op_list; - op_list = itt_hide_load_word(op_list->next); - if (tmp->type == POP_OP) { - if (mark < data.size() && - compare(data[0], data[data.size()-1])) { - // there are newly pushed elems and the last one - // is higher than top - *(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(); - __TBB_ASSERT(mark<=data.size(), NULL); - } - else { // no convenient item to pop; postpone - itt_hide_store_word(tmp->next, pop_list); - pop_list = tmp; - } - } else { // PUSH_OP or PUSH_RVALUE_OP - __TBB_ASSERT(tmp->type == PUSH_OP || tmp->type == PUSH_RVALUE_OP, "Unknown operation" ); - __TBB_TRY{ - if (tmp->type == PUSH_OP) { - push_back_helper(*(tmp->elem), typename internal::use_element_copy_constructor::type()); - } else { - 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)); - } __TBB_CATCH(...) { - itt_store_word_with_release(tmp->status, uintptr_t(FAILED)); - } - } - } - - // second pass processes pop operations - while (pop_list) { - tmp = pop_list; - pop_list = itt_hide_load_word(pop_list->next); - __TBB_ASSERT(tmp->type == POP_OP, NULL); - if (data.empty()) { - itt_store_word_with_release(tmp->status, uintptr_t(FAILED)); - } - else { - __TBB_ASSERT(mark<=data.size(), NULL); - if (mark < data.size() && - compare(data[0], data[data.size()-1])) { - // there are newly pushed elems and the last one is - // higher than top - *(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) = 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(); - } - } - } - - // heapify any leftover pushed elements before doing the next - // batch of operations - if (mark0) mark = 1; - for (; mark>1; - if (!compare(data[parent], to_place)) break; - data[cur_pos] = tbb::internal::move(data[parent]); - cur_pos = parent; - } while( cur_pos ); - data[cur_pos] = tbb::internal::move(to_place); - } - } - - //! Re-heapify after an extraction - /** Re-heapify by pushing last element down the heap from the root. */ - void reheap() { - size_type cur_pos=0, child=1; - - while (child < mark) { - size_type target = child; - if (child+1 < mark && compare(data[child], data[child+1])) - ++target; - // target now has the higher priority child - if (compare(data[target], data[data.size()-1])) break; - 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] = tbb::internal::move(data[data.size()-1]); - data.pop_back(); - if (mark > data.size()) mark = data.size(); - } - - void push_back_helper(const T& t, tbb::internal::true_type) { - data.push_back(t); - } - - void push_back_helper(const T&, tbb::internal::false_type) { - __TBB_ASSERT( false, "The type is not copy constructible. Copying push operation is impossible." ); - } -}; - -} // namespace interface5 - -using interface5::concurrent_priority_queue; - -} // namespace tbb - -#endif /* __TBB_concurrent_priority_queue_H */ diff --git a/lib/3rdParty/tbb/include/tbb/concurrent_queue.h b/lib/3rdParty/tbb/include/tbb/concurrent_queue.h deleted file mode 100644 index 81db58a3..00000000 --- a/lib/3rdParty/tbb/include/tbb/concurrent_queue.h +++ /dev/null @@ -1,458 +0,0 @@ -/* - 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_concurrent_queue_H -#define __TBB_concurrent_queue_H - -#include "internal/_concurrent_queue_impl.h" - -namespace tbb { - -namespace strict_ppl { - -//! A high-performance thread-safe non-blocking concurrent queue. -/** Multiple threads may each push and pop concurrently. - Assignment construction is not allowed. - @ingroup containers */ -template > -class concurrent_queue: public internal::concurrent_queue_base_v3 { - template friend class internal::concurrent_queue_iterator; - - //! Allocator type - typedef typename A::template rebind::other page_allocator_type; - page_allocator_type my_allocator; - - //! Allocates a block of size n (bytes) - 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); - return b; - } - - //! Deallocates block created by allocate_block. - virtual void deallocate_block( void *b, size_t n ) __TBB_override { - my_allocator.deallocate( reinterpret_cast(b), n ); - } - - static void copy_construct_item(T* location, const void* src){ - new (location) T(*static_cast(src)); - } - -#if __TBB_CPP11_RVALUE_REF_PRESENT - static void move_construct_item(T* location, const void* src) { - new (location) T( std::move(*static_cast(const_cast(src))) ); - } -#endif /* __TBB_CPP11_RVALUE_REF_PRESENT */ -public: - //! Element type in the queue. - typedef T value_type; - - //! Reference type - typedef T& reference; - - //! Const reference type - typedef const T& const_reference; - - //! Integral type for representing size of the queue. - typedef size_t size_type; - - //! Difference type for iterator - typedef ptrdiff_t difference_type; - - //! Allocator type - typedef A allocator_type; - - //! Construct empty queue - explicit concurrent_queue(const allocator_type& a = allocator_type()) : - my_allocator( a ) - { - } - - //! [begin,end) constructor - template - concurrent_queue( InputIterator begin, InputIterator end, const allocator_type& a = allocator_type()) : - my_allocator( a ) - { - for( ; begin != end; ++begin ) - this->push(*begin); - } - - //! Copy constructor - concurrent_queue( const concurrent_queue& src, const allocator_type& a = allocator_type()) : - internal::concurrent_queue_base_v3(), my_allocator( a ) - { - this->assign( src, copy_construct_item ); - } - -#if __TBB_CPP11_RVALUE_REF_PRESENT - //! Move constructors - concurrent_queue( concurrent_queue&& src ) : - internal::concurrent_queue_base_v3(), my_allocator( std::move(src.my_allocator) ) - { - this->internal_swap( src ); - } - - concurrent_queue( concurrent_queue&& src, const allocator_type& a ) : - internal::concurrent_queue_base_v3(), my_allocator( a ) - { - // checking that memory allocated by one instance of allocator can be deallocated - // with another - if( my_allocator == src.my_allocator) { - this->internal_swap( src ); - } else { - // allocators are different => performing per-element move - this->assign( src, move_construct_item ); - src.clear(); - } - } -#endif /* __TBB_CPP11_RVALUE_REF_PRESENT */ - - //! Destroy queue - ~concurrent_queue(); - - //! Enqueue an item at tail of queue. - void push( const T& source ) { - this->internal_push( &source, copy_construct_item ); - } - -#if __TBB_CPP11_RVALUE_REF_PRESENT - void push( T&& source ) { - this->internal_push( &source, move_construct_item ); - } - -#if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT - template - void emplace( Arguments&&... args ) { - push( T(std::forward( args )...) ); - } -#endif //__TBB_CPP11_VARIADIC_TEMPLATES_PRESENT -#endif /* __TBB_CPP11_RVALUE_REF_PRESENT */ - - //! Attempt to dequeue an item from head of queue. - /** Does not wait for item to become available. - Returns true if successful; false otherwise. */ - bool try_pop( T& result ) { - return this->internal_try_pop( &result ); - } - - //! Return the number of items in the queue; thread unsafe - size_type unsafe_size() const {return this->internal_size();} - - //! Equivalent to size()==0. - bool empty() const {return this->internal_empty();} - - //! Clear the queue. not thread-safe. - void clear() ; - - //! Return allocator object - allocator_type get_allocator() const { return this->my_allocator; } - - typedef internal::concurrent_queue_iterator iterator; - typedef internal::concurrent_queue_iterator const_iterator; - - //------------------------------------------------------------------------ - // The iterators are intended only for debugging. They are slow and not thread safe. - //------------------------------------------------------------------------ - iterator unsafe_begin() {return iterator(*this);} - iterator unsafe_end() {return iterator();} - const_iterator unsafe_begin() const {return const_iterator(*this);} - const_iterator unsafe_end() const {return const_iterator();} -} ; - -template -concurrent_queue::~concurrent_queue() { - clear(); - this->internal_finish_clear(); -} - -template -void concurrent_queue::clear() { - T value; - while( !empty() ) try_pop(value); -} - -} // namespace strict_ppl - -//! A high-performance thread-safe blocking concurrent bounded queue. -/** This is the pre-PPL TBB concurrent queue which supports boundedness and blocking semantics. - Note that method names agree with the PPL-style concurrent queue. - Multiple threads may each push and pop concurrently. - Assignment construction is not allowed. - @ingroup containers */ -template > -class concurrent_bounded_queue: public internal::concurrent_queue_base_v8 { - template friend class internal::concurrent_queue_iterator; - - //! Allocator type - typedef typename A::template rebind::other page_allocator_type; - page_allocator_type my_allocator; - - typedef typename concurrent_queue_base_v3::padded_page padded_page; - typedef typename concurrent_queue_base_v3::copy_specifics copy_specifics; - - //! Class used to ensure exception-safety of method "pop" - class destroyer: internal::no_copy { - T& my_value; - public: - destroyer( T& value ) : my_value(value) {} - ~destroyer() {my_value.~T();} - }; - - T& get_ref( page& p, size_t index ) { - __TBB_ASSERT( index(static_cast(&p))->last)[index]; - } - - 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 - 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 - virtual void move_item( page&, size_t, const void* ) __TBB_override { - __TBB_ASSERT( false, "Unreachable code" ); - } -#endif - - 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 - 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 - virtual void move_page_item( page&, size_t, const page&, size_t ) __TBB_override { - __TBB_ASSERT( false, "Unreachable code" ); - } -#endif - - 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 ); - } - - 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 ) - internal::throw_exception(internal::eid_bad_alloc); - return 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 ); - } - -public: - //! Element type in the queue. - typedef T value_type; - - //! Allocator type - typedef A allocator_type; - - //! Reference type - typedef T& reference; - - //! Const reference type - typedef const T& const_reference; - - //! Integral type for representing size of the queue. - /** Note that the size_type is a signed integral type. - This is because the size can be negative if there are pending pops without corresponding pushes. */ - typedef std::ptrdiff_t size_type; - - //! Difference type for iterator - typedef std::ptrdiff_t difference_type; - - //! Construct empty queue - explicit concurrent_bounded_queue(const allocator_type& a = allocator_type()) : - concurrent_queue_base_v8( sizeof(T) ), my_allocator( a ) - { - } - - //! Copy constructor - concurrent_bounded_queue( const concurrent_bounded_queue& src, const allocator_type& a = allocator_type()) - : concurrent_queue_base_v8( sizeof(T) ), my_allocator( a ) - { - assign( src ); - } - -#if __TBB_CPP11_RVALUE_REF_PRESENT - //! Move constructors - concurrent_bounded_queue( concurrent_bounded_queue&& src ) - : concurrent_queue_base_v8( sizeof(T) ), my_allocator( std::move(src.my_allocator) ) - { - internal_swap( src ); - } - - concurrent_bounded_queue( concurrent_bounded_queue&& src, const allocator_type& a ) - : concurrent_queue_base_v8( sizeof(T) ), my_allocator( a ) - { - // checking that memory allocated by one instance of allocator can be deallocated - // with another - if( my_allocator == src.my_allocator) { - this->internal_swap( src ); - } else { - // allocators are different => performing per-element move - this->move_content( src ); - src.clear(); - } - } -#endif /* __TBB_CPP11_RVALUE_REF_PRESENT */ - - //! [begin,end) constructor - template - concurrent_bounded_queue( InputIterator begin, InputIterator end, - const allocator_type& a = allocator_type()) - : concurrent_queue_base_v8( sizeof(T) ), my_allocator( a ) - { - for( ; begin != end; ++begin ) - internal_push_if_not_full(&*begin); - } - - //! Destroy queue - ~concurrent_bounded_queue(); - - //! Enqueue an item at tail of queue. - void push( const T& source ) { - internal_push( &source ); - } - -#if __TBB_CPP11_RVALUE_REF_PRESENT - //! Move an item at tail of queue. - void push( T&& source ) { - internal_push_move( &source ); - } - -#if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT - template - void emplace( Arguments&&... args ) { - push( T(std::forward( args )...) ); - } -#endif /* __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT */ -#endif /* __TBB_CPP11_RVALUE_REF_PRESENT */ - - //! Dequeue item from head of queue. - /** Block until an item becomes available, and then dequeue it. */ - void pop( T& destination ) { - internal_pop( &destination ); - } - -#if TBB_USE_EXCEPTIONS - //! Abort all pending queue operations - void abort() { - internal_abort(); - } -#endif - - //! Enqueue an item at tail of queue if queue is not already full. - /** Does not wait for queue to become not full. - Returns true if item is pushed; false if queue was already full. */ - bool try_push( const T& source ) { - return internal_push_if_not_full( &source ); - } - -#if __TBB_CPP11_RVALUE_REF_PRESENT - //! Move an item at tail of queue if queue is not already full. - /** Does not wait for queue to become not full. - Returns true if item is pushed; false if queue was already full. */ - bool try_push( T&& source ) { - return internal_push_move_if_not_full( &source ); - } -#if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT - template - bool try_emplace( Arguments&&... args ) { - return try_push( T(std::forward( args )...) ); - } -#endif /* __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT */ -#endif /* __TBB_CPP11_RVALUE_REF_PRESENT */ - - //! Attempt to dequeue an item from head of queue. - /** Does not wait for item to become available. - Returns true if successful; false otherwise. */ - bool try_pop( T& destination ) { - return internal_pop_if_present( &destination ); - } - - //! Return number of pushes minus number of pops. - /** Note that the result can be negative if there are pops waiting for the - corresponding pushes. The result can also exceed capacity() if there - are push operations in flight. */ - size_type size() const {return internal_size();} - - //! Equivalent to size()<=0. - bool empty() const {return internal_empty();} - - //! Maximum number of allowed elements - size_type capacity() const { - return my_capacity; - } - - //! Set the capacity - /** Setting the capacity to 0 causes subsequent try_push operations to always fail, - and subsequent push operations to block forever. */ - void set_capacity( size_type new_capacity ) { - internal_set_capacity( new_capacity, sizeof(T) ); - } - - //! return allocator object - allocator_type get_allocator() const { return this->my_allocator; } - - //! clear the queue. not thread-safe. - void clear() ; - - typedef internal::concurrent_queue_iterator iterator; - typedef internal::concurrent_queue_iterator const_iterator; - - //------------------------------------------------------------------------ - // The iterators are intended only for debugging. They are slow and not thread safe. - //------------------------------------------------------------------------ - iterator unsafe_begin() {return iterator(*this);} - iterator unsafe_end() {return iterator();} - const_iterator unsafe_begin() const {return const_iterator(*this);} - const_iterator unsafe_end() const {return const_iterator();} - -}; - -template -concurrent_bounded_queue::~concurrent_bounded_queue() { - clear(); - internal_finish_clear(); -} - -template -void concurrent_bounded_queue::clear() { - T value; - while( try_pop(value) ) /*noop*/; -} - -using strict_ppl::concurrent_queue; - -} // namespace tbb - -#endif /* __TBB_concurrent_queue_H */ diff --git a/lib/3rdParty/tbb/include/tbb/concurrent_unordered_map.h b/lib/3rdParty/tbb/include/tbb/concurrent_unordered_map.h deleted file mode 100644 index c959a7ec..00000000 --- a/lib/3rdParty/tbb/include/tbb/concurrent_unordered_map.h +++ /dev/null @@ -1,299 +0,0 @@ -/* - 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. - - - - -*/ - -/* Container implementations in this header are based on PPL implementations - provided by Microsoft. */ - -#ifndef __TBB_concurrent_unordered_map_H -#define __TBB_concurrent_unordered_map_H - -#include "internal/_concurrent_unordered_impl.h" - -namespace tbb -{ - -namespace interface5 { - -// Template class for hash map traits -template -class concurrent_unordered_map_traits -{ -protected: - typedef std::pair value_type; - typedef Key key_type; - typedef Hash_compare hash_compare; - typedef typename Allocator::template rebind::other allocator_type; - enum { allow_multimapping = Allow_multimapping }; - - concurrent_unordered_map_traits() : my_hash_compare() {} - concurrent_unordered_map_traits(const hash_compare& hc) : my_hash_compare(hc) {} - - template - static const Key& get_key(const std::pair& value) { - return (value.first); - } - - hash_compare my_hash_compare; // the comparator predicate for keys -}; - -template , typename Key_equality = std::equal_to, - typename Allocator = tbb::tbb_allocator > > -class concurrent_unordered_map : - public internal::concurrent_unordered_base< concurrent_unordered_map_traits, Allocator, false> > -{ - // Base type definitions - typedef internal::hash_compare hash_compare; - typedef concurrent_unordered_map_traits traits_type; - typedef internal::concurrent_unordered_base< traits_type > base_type; -#if __TBB_EXTRA_DEBUG -public: -#endif - using traits_type::allow_multimapping; -public: - using base_type::end; - using base_type::find; - using base_type::insert; - - // Type definitions - typedef Key key_type; - typedef typename base_type::value_type value_type; - typedef T mapped_type; - typedef Hasher hasher; - typedef Key_equality key_equal; - typedef hash_compare key_compare; - - typedef typename base_type::allocator_type allocator_type; - typedef typename base_type::pointer pointer; - typedef typename base_type::const_pointer const_pointer; - typedef typename base_type::reference reference; - typedef typename base_type::const_reference const_reference; - - typedef typename base_type::size_type size_type; - typedef typename base_type::difference_type difference_type; - - typedef typename base_type::iterator iterator; - typedef typename base_type::const_iterator const_iterator; - typedef typename base_type::iterator local_iterator; - typedef typename base_type::const_iterator const_local_iterator; - - // Construction/destruction/copying - explicit concurrent_unordered_map(size_type n_of_buckets = base_type::initial_bucket_number, - 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) - {} - - 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, - 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) - { - insert(first, last); - } - -#if __TBB_INITIALIZER_LISTS_PRESENT - //! Constructor from initializer_list - concurrent_unordered_map(std::initializer_list il, size_type n_of_buckets = base_type::initial_bucket_number, - 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) - { - this->insert(il.begin(),il.end()); - } -#endif //# __TBB_INITIALIZER_LISTS_PRESENT - -#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) - { - return static_cast(base_type::operator=(table)); - } - - 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_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) - {} - - // Observers - mapped_type& operator[](const key_type& key) - { - iterator where = find(key); - - if (where == end()) - { - where = insert(std::pair(key, mapped_type())).first; - } - - return ((*where).second); - } - - mapped_type& at(const key_type& key) - { - iterator where = find(key); - - if (where == end()) - { - tbb::internal::throw_exception(tbb::internal::eid_invalid_key); - } - - return ((*where).second); - } - - const mapped_type& at(const key_type& key) const - { - const_iterator where = find(key); - - if (where == end()) - { - tbb::internal::throw_exception(tbb::internal::eid_invalid_key); - } - - return ((*where).second); - } -}; - -template < typename Key, typename T, typename Hasher = tbb::tbb_hash, typename Key_equality = std::equal_to, - typename Allocator = tbb::tbb_allocator > > -class concurrent_unordered_multimap : - public internal::concurrent_unordered_base< concurrent_unordered_map_traits< Key, T, - internal::hash_compare, Allocator, true> > -{ - // Base type definitions - typedef internal::hash_compare hash_compare; - typedef concurrent_unordered_map_traits traits_type; - typedef internal::concurrent_unordered_base base_type; -#if __TBB_EXTRA_DEBUG -public: -#endif - using traits_type::allow_multimapping; -public: - using base_type::insert; - - // Type definitions - typedef Key key_type; - typedef typename base_type::value_type value_type; - typedef T mapped_type; - typedef Hasher hasher; - typedef Key_equality key_equal; - typedef hash_compare key_compare; - - typedef typename base_type::allocator_type allocator_type; - typedef typename base_type::pointer pointer; - typedef typename base_type::const_pointer const_pointer; - typedef typename base_type::reference reference; - typedef typename base_type::const_reference const_reference; - - typedef typename base_type::size_type size_type; - typedef typename base_type::difference_type difference_type; - - typedef typename base_type::iterator iterator; - typedef typename base_type::const_iterator const_iterator; - typedef typename base_type::iterator local_iterator; - typedef typename base_type::const_iterator const_local_iterator; - - // Construction/destruction/copying - explicit concurrent_unordered_multimap(size_type n_of_buckets = base_type::initial_bucket_number, - 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) - {} - - 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, - 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) - { - insert(first, last); - } - -#if __TBB_INITIALIZER_LISTS_PRESENT - //! Constructor from initializer_list - concurrent_unordered_multimap(std::initializer_list il, size_type n_of_buckets = base_type::initial_bucket_number, - 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) - { - this->insert(il.begin(),il.end()); - } -#endif //# __TBB_INITIALIZER_LISTS_PRESENT - -#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) - { - return static_cast(base_type::operator=(table)); - } - - 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_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) - {} -}; -} // namespace interface5 - -using interface5::concurrent_unordered_map; -using interface5::concurrent_unordered_multimap; - -} // namespace tbb - -#endif// __TBB_concurrent_unordered_map_H diff --git a/lib/3rdParty/tbb/include/tbb/concurrent_unordered_set.h b/lib/3rdParty/tbb/include/tbb/concurrent_unordered_set.h deleted file mode 100644 index a26fee1a..00000000 --- a/lib/3rdParty/tbb/include/tbb/concurrent_unordered_set.h +++ /dev/null @@ -1,256 +0,0 @@ -/* - 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. - - - - -*/ - -/* Container implementations in this header are based on PPL implementations - provided by Microsoft. */ - -#ifndef __TBB_concurrent_unordered_set_H -#define __TBB_concurrent_unordered_set_H - -#include "internal/_concurrent_unordered_impl.h" - -namespace tbb -{ - -namespace interface5 { - -// Template class for hash set traits -template -class concurrent_unordered_set_traits -{ -protected: - typedef Key value_type; - typedef Key key_type; - typedef Hash_compare hash_compare; - typedef typename Allocator::template rebind::other allocator_type; - enum { allow_multimapping = Allow_multimapping }; - - concurrent_unordered_set_traits() : my_hash_compare() {} - concurrent_unordered_set_traits(const hash_compare& hc) : my_hash_compare(hc) {} - - static const Key& get_key(const value_type& value) { - return value; - } - - hash_compare my_hash_compare; // the comparator predicate for keys -}; - -template , typename Key_equality = std::equal_to, typename Allocator = tbb::tbb_allocator > -class concurrent_unordered_set : public internal::concurrent_unordered_base< concurrent_unordered_set_traits, Allocator, false> > -{ - // Base type definitions - typedef internal::hash_compare hash_compare; - typedef concurrent_unordered_set_traits traits_type; - typedef internal::concurrent_unordered_base< traits_type > base_type; -#if __TBB_EXTRA_DEBUG -public: -#endif - using traits_type::allow_multimapping; -public: - using base_type::insert; - - // Type definitions - typedef Key key_type; - typedef typename base_type::value_type value_type; - typedef Key mapped_type; - typedef Hasher hasher; - typedef Key_equality key_equal; - typedef hash_compare key_compare; - - typedef typename base_type::allocator_type allocator_type; - typedef typename base_type::pointer pointer; - typedef typename base_type::const_pointer const_pointer; - typedef typename base_type::reference reference; - typedef typename base_type::const_reference const_reference; - - typedef typename base_type::size_type size_type; - typedef typename base_type::difference_type difference_type; - - typedef typename base_type::iterator iterator; - typedef typename base_type::const_iterator const_iterator; - typedef typename base_type::iterator local_iterator; - typedef typename base_type::const_iterator const_local_iterator; - - // Construction/destruction/copying - 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) - {} - - 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(), - 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) - { - insert(first, last); - } - -#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(), - 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) - { - this->insert(il.begin(),il.end()); - } -#endif //# __TBB_INITIALIZER_LISTS_PRESENT - -#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) - { - return static_cast(base_type::operator=(table)); - } - - 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_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) - {} - -}; - -template , typename Key_equality = std::equal_to, - typename Allocator = tbb::tbb_allocator > -class concurrent_unordered_multiset : - public internal::concurrent_unordered_base< concurrent_unordered_set_traits, Allocator, true> > -{ - // Base type definitions - typedef internal::hash_compare hash_compare; - typedef concurrent_unordered_set_traits traits_type; - typedef internal::concurrent_unordered_base< traits_type > base_type; -#if __TBB_EXTRA_DEBUG -public: -#endif - using traits_type::allow_multimapping; -public: - using base_type::insert; - - // Type definitions - typedef Key key_type; - typedef typename base_type::value_type value_type; - typedef Key mapped_type; - typedef Hasher hasher; - typedef Key_equality key_equal; - typedef hash_compare key_compare; - - typedef typename base_type::allocator_type allocator_type; - typedef typename base_type::pointer pointer; - typedef typename base_type::const_pointer const_pointer; - typedef typename base_type::reference reference; - typedef typename base_type::const_reference const_reference; - - typedef typename base_type::size_type size_type; - typedef typename base_type::difference_type difference_type; - - typedef typename base_type::iterator iterator; - typedef typename base_type::const_iterator const_iterator; - typedef typename base_type::iterator local_iterator; - typedef typename base_type::const_iterator const_local_iterator; - - // Construction/destruction/copying - explicit concurrent_unordered_multiset(size_type n_of_buckets = base_type::initial_bucket_number, - 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) - {} - - 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, - 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) - { - insert(first, last); - } - -#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(), - 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) - { - this->insert(il.begin(),il.end()); - } -#endif //# __TBB_INITIALIZER_LISTS_PRESENT - -#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) - { - return static_cast(base_type::operator=(table)); - } - - concurrent_unordered_multiset(concurrent_unordered_multiset&& table) - : base_type(std::move(table)) - {} - - concurrent_unordered_multiset& operator=(concurrent_unordered_multiset&& table) - { - return static_cast(base_type::operator=(std::move(table))); - } -#endif //!__TBB_IMPLICIT_MOVE_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 - -using interface5::concurrent_unordered_set; -using interface5::concurrent_unordered_multiset; - -} // namespace tbb - -#endif// __TBB_concurrent_unordered_set_H diff --git a/lib/3rdParty/tbb/include/tbb/concurrent_vector.h b/lib/3rdParty/tbb/include/tbb/concurrent_vector.h deleted file mode 100644 index 370129ef..00000000 --- a/lib/3rdParty/tbb/include/tbb/concurrent_vector.h +++ /dev/null @@ -1,1374 +0,0 @@ -/* - 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_concurrent_vector_H -#define __TBB_concurrent_vector_H - -#include "tbb_stddef.h" -#include "tbb_exception.h" -#include "atomic.h" -#include "cache_aligned_allocator.h" -#include "blocked_range.h" -#include "tbb_machine.h" -#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 - #pragma warning (push) - #pragma warning (disable: 4530) -#endif - -#include -#include - -#if !TBB_USE_EXCEPTIONS && _MSC_VER - #pragma warning (pop) -#endif - -#if _MSC_VER==1500 && !__INTEL_COMPILER - // VS2008/VC9 seems to have an issue; limits pull in math.h - #pragma warning( push ) - #pragma warning( disable: 4985 ) -#endif -#include /* std::numeric_limits */ -#if _MSC_VER==1500 && !__INTEL_COMPILER - #pragma warning( pop ) -#endif - -#if __TBB_INITIALIZER_LISTS_PRESENT - #include -#endif - -#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) - // Workaround for overzealous compiler warnings in /Wp64 mode - #pragma warning (push) -#if defined(_Wp64) - #pragma warning (disable: 4267) -#endif - #pragma warning (disable: 4127) //warning C4127: conditional expression is constant -#endif - -namespace tbb { - -template > -class concurrent_vector; - -//! @cond INTERNAL -namespace internal { - - template - class vector_iterator; - - //! Bad allocation marker - static void *const vector_allocation_error_flag = reinterpret_cast(size_t(63)); - - //! Exception helper function - template - void handle_unconstructed_elements(T* array, size_t n_of_elements){ - std::memset( array, 0, n_of_elements * sizeof( T ) ); - } - - //! Base class of concurrent vector implementation. - /** @ingroup containers */ - class concurrent_vector_base_v3 { - protected: - - // Basic types declarations - typedef size_t segment_index_t; - typedef size_t size_type; - - // Using enumerations due to Mac linking problems of static const variables - enum { - // Size constants - default_initial_segments = 1, // 2 initial items - //! Number of slots for segment pointers inside the class - pointers_per_short_table = 3, // to fit into 8 words of entire structure - pointers_per_long_table = sizeof(segment_index_t) * 8 // one segment per bit - }; - - struct segment_not_used {}; - struct segment_allocated {}; - struct segment_allocation_failed {}; - - class segment_t; - class segment_value_t { - void* array; - private: - //TODO: More elegant way to grant access to selected functions _only_? - friend class segment_t; - explicit segment_value_t(void* an_array):array(an_array) {} - public: - friend bool operator==(segment_value_t const& lhs, segment_not_used ) { return lhs.array == 0;} - friend bool operator==(segment_value_t const& lhs, segment_allocated) { return lhs.array > internal::vector_allocation_error_flag;} - friend bool operator==(segment_value_t const& lhs, segment_allocation_failed) { return lhs.array == internal::vector_allocation_error_flag;} - template - friend bool operator!=(segment_value_t const& lhs, argument_type arg) { return ! (lhs == arg);} - - template - T* pointer() const { return static_cast(const_cast(array)); } - }; - - friend void enforce_segment_allocated(segment_value_t const& s, internal::exception_id exception = eid_bad_last_alloc){ - if(s != segment_allocated()){ - internal::throw_exception(exception); - } - } - - // Segment pointer. - class segment_t { - atomic array; - public: - segment_t(){ store(segment_not_used());} - //Copy ctor and assignment operator are defined to ease using of stl algorithms. - //These algorithms usually not a synchronization point, so, semantic is - //intentionally relaxed here. - segment_t(segment_t const& rhs ){ array.store(rhs.array.load());} - - void swap(segment_t & rhs ){ - tbb::internal::swap(array, rhs.array); - } - - segment_t& operator=(segment_t const& rhs ){ - array.store(rhs.array.load()); - return *this; - } - - template - segment_value_t load() const { return segment_value_t(array.load());} - - template - void store(segment_not_used) { - array.store(0); - } - - template - void store(segment_allocation_failed) { - __TBB_ASSERT(load() != segment_allocated(),"transition from \"allocated\" to \"allocation failed\" state looks non-logical"); - array.store(internal::vector_allocation_error_flag); - } - - template - void store(void* allocated_segment_pointer) __TBB_NOEXCEPT(true) { - __TBB_ASSERT(segment_value_t(allocated_segment_pointer) == segment_allocated(), - "other overloads of store should be used for marking segment as not_used or allocation_failed" ); - array.store(allocated_segment_pointer); - } - -#if TBB_USE_ASSERT - ~segment_t() { - __TBB_ASSERT(load() != segment_allocated(), "should have been freed by clear" ); - } -#endif /* TBB_USE_ASSERT */ - }; - friend void swap(segment_t & , segment_t & ) __TBB_NOEXCEPT(true); - - // Data fields - - //! allocator function pointer - void* (*vector_allocator_ptr)(concurrent_vector_base_v3 &, size_t); - - //! count of segments in the first block - atomic my_first_block; - - //! Requested size of vector - atomic my_early_size; - - //! Pointer to the segments table - atomic my_segment; - - //! embedded storage of segment pointers - segment_t my_storage[pointers_per_short_table]; - - // Methods - - concurrent_vector_base_v3() { - //Here the semantic is intentionally relaxed. - //The reason this is next: - //Object that is in middle of construction (i.e. its constructor is not yet finished) - //cannot be used concurrently until the construction is finished. - //Thus to flag other threads that construction is finished, some synchronization with - //acquire-release semantic should be done by the (external) code that uses the vector. - //So, no need to do the synchronization inside the vector. - - my_early_size.store(0); - my_first_block.store(0); // here is not default_initial_segments - my_segment.store(my_storage); - } - - __TBB_EXPORTED_METHOD ~concurrent_vector_base_v3(); - - //these helpers methods use the fact that segments are allocated so - //that every segment size is a (increasing) power of 2. - //with one exception 0 segment has size of 2 as well segment 1; - //e.g. size of segment with index of 3 is 2^3=8; - static segment_index_t segment_index_of( size_type index ) { - return segment_index_t( __TBB_Log2( index|1 ) ); - } - - static segment_index_t segment_base( segment_index_t k ) { - return (segment_index_t(1)< - friend class vector_iterator; - - }; - - inline void swap(concurrent_vector_base_v3::segment_t & lhs, concurrent_vector_base_v3::segment_t & rhs) __TBB_NOEXCEPT(true) { - lhs.swap(rhs); - } - - typedef concurrent_vector_base_v3 concurrent_vector_base; - - //! Meets requirements of a forward iterator for STL and a Value for a blocked_range.*/ - /** Value is either the T or const T type of the container. - @ingroup containers */ - template - class vector_iterator - { - //! concurrent_vector over which we are iterating. - Container* my_vector; - - //! Index into the vector - size_t my_index; - - //! Caches my_vector->internal_subscript(my_index) - /** NULL if cached value is not available */ - mutable Value* my_item; - - template - friend vector_iterator operator+( ptrdiff_t offset, const vector_iterator& v ); - - template - friend bool operator==( const vector_iterator& i, const vector_iterator& j ); - - template - friend bool operator<( const vector_iterator& i, const vector_iterator& j ); - - template - friend ptrdiff_t operator-( const vector_iterator& i, const vector_iterator& j ); - - template - friend class internal::vector_iterator; - -#if !__TBB_TEMPLATE_FRIENDS_BROKEN - template - friend class tbb::concurrent_vector; -#else -public: -#endif - - vector_iterator( const Container& vector, size_t index, void *ptr = 0 ) : - my_vector(const_cast(&vector)), - my_index(index), - my_item(static_cast(ptr)) - {} - - public: - //! Default constructor - vector_iterator() : my_vector(NULL), my_index(~size_t(0)), my_item(NULL) {} - - vector_iterator( const vector_iterator& other ) : - my_vector(other.my_vector), - my_index(other.my_index), - my_item(other.my_item) - {} - - vector_iterator operator+( ptrdiff_t offset ) const { - return vector_iterator( *my_vector, my_index+offset ); - } - vector_iterator &operator+=( ptrdiff_t offset ) { - my_index+=offset; - my_item = NULL; - return *this; - } - vector_iterator operator-( ptrdiff_t offset ) const { - return vector_iterator( *my_vector, my_index-offset ); - } - vector_iterator &operator-=( ptrdiff_t offset ) { - my_index-=offset; - my_item = NULL; - return *this; - } - Value& operator*() const { - Value* item = my_item; - if( !item ) { - item = my_item = &my_vector->internal_subscript(my_index); - } - __TBB_ASSERT( item==&my_vector->internal_subscript(my_index), "corrupt cache" ); - return *item; - } - Value& operator[]( ptrdiff_t k ) const { - return my_vector->internal_subscript(my_index+k); - } - Value* operator->() const {return &operator*();} - - //! Pre increment - vector_iterator& operator++() { - size_t element_index = ++my_index; - if( my_item ) { - //TODO: consider using of knowledge about "first_block optimization" here as well? - if( concurrent_vector_base::is_first_element_in_segment(element_index)) { - //if the iterator crosses a segment boundary, the pointer become invalid - //as possibly next segment is in another memory location - my_item= NULL; - } else { - ++my_item; - } - } - return *this; - } - - //! Pre decrement - vector_iterator& operator--() { - __TBB_ASSERT( my_index>0, "operator--() applied to iterator already at beginning of concurrent_vector" ); - size_t element_index = my_index--; - if( my_item ) { - if(concurrent_vector_base::is_first_element_in_segment(element_index)) { - //if the iterator crosses a segment boundary, the pointer become invalid - //as possibly next segment is in another memory location - my_item= NULL; - } else { - --my_item; - } - } - return *this; - } - - //! Post increment - vector_iterator operator++(int) { - vector_iterator result = *this; - operator++(); - return result; - } - - //! Post decrement - vector_iterator operator--(int) { - vector_iterator result = *this; - operator--(); - return result; - } - - // STL support - - typedef ptrdiff_t difference_type; - typedef Value value_type; - typedef Value* pointer; - typedef Value& reference; - typedef std::random_access_iterator_tag iterator_category; - }; - - template - vector_iterator operator+( ptrdiff_t offset, const vector_iterator& v ) { - return vector_iterator( *v.my_vector, v.my_index+offset ); - } - - template - bool operator==( const vector_iterator& i, const vector_iterator& j ) { - return i.my_index==j.my_index && i.my_vector == j.my_vector; - } - - template - bool operator!=( const vector_iterator& i, const vector_iterator& j ) { - return !(i==j); - } - - template - bool operator<( const vector_iterator& i, const vector_iterator& j ) { - return i.my_index - bool operator>( const vector_iterator& i, const vector_iterator& j ) { - return j - bool operator>=( const vector_iterator& i, const vector_iterator& j ) { - return !(i - bool operator<=( const vector_iterator& i, const vector_iterator& j ) { - return !(j - ptrdiff_t operator-( const vector_iterator& i, const vector_iterator& j ) { - return ptrdiff_t(i.my_index)-ptrdiff_t(j.my_index); - } - - template - class allocator_base { - public: - typedef typename A::template - rebind::other allocator_type; - allocator_type my_allocator; - - allocator_base(const allocator_type &a = allocator_type() ) : my_allocator(a) {} - - }; - -} // namespace internal -//! @endcond - -//! Concurrent vector container -/** concurrent_vector is a container having the following main properties: - - It provides random indexed access to its elements. The index of the first element is 0. - - It ensures safe concurrent growing its size (different threads can safely append new elements). - - Adding new elements does not invalidate existing iterators and does not change indices of existing items. - -@par Compatibility - The class meets all Container Requirements and Reversible Container Requirements from - C++ Standard (See ISO/IEC 14882:2003(E), clause 23.1). But it doesn't meet - Sequence Requirements due to absence of insert() and erase() methods. - -@par Exception Safety - Methods working with memory allocation and/or new elements construction can throw an - exception if allocator fails to allocate memory or element's default constructor throws one. - Concurrent vector's element of type T must conform to the following requirements: - - Throwing an exception is forbidden for destructor of T. - - Default constructor of T must not throw an exception OR its non-virtual destructor must safely work when its object memory is zero-initialized. - . - Otherwise, the program's behavior is undefined. -@par - If an exception happens inside growth or assignment operation, an instance of the vector becomes invalid unless it is stated otherwise in the method documentation. - Invalid state means: - - There are no guarantees that all items were initialized by a constructor. The rest of items is zero-filled, including item where exception happens. - - An invalid vector instance cannot be repaired; it is unable to grow anymore. - - Size and capacity reported by the vector are incorrect, and calculated as if the failed operation were successful. - - Attempt to access not allocated elements using operator[] or iterators results in access violation or segmentation fault exception, and in case of using at() method a C++ exception is thrown. - . - If a concurrent grow operation successfully completes, all the elements it has added to the vector will remain valid and accessible even if one of subsequent grow operations fails. - -@par Fragmentation - Unlike an STL vector, a concurrent_vector does not move existing elements if it needs - to allocate more memory. The container is divided into a series of contiguous arrays of - elements. The first reservation, growth, or assignment operation determines the size of - the first array. Using small number of elements as initial size incurs fragmentation that - may increase element access time. Internal layout can be optimized by method compact() that - merges several smaller arrays into one solid. - -@par Changes since TBB 2.1 - - Fixed guarantees of concurrent_vector::size() and grow_to_at_least() methods to assure elements are allocated. - - Methods end()/rbegin()/back() are partly thread-safe since they use size() to get the end of vector - - Added resize() methods (not thread-safe) - - Added cbegin/cend/crbegin/crend methods - - Changed return type of methods grow* and push_back to iterator - -@par Changes since TBB 2.0 - - Implemented exception-safety guarantees - - Added template argument for allocator - - Added allocator argument in constructors - - Faster index calculation - - First growth call specifies a number of segments to be merged in the first allocation. - - Fixed memory blow up for swarm of vector's instances of small size - - Added grow_by(size_type n, const_reference t) growth using copying constructor to init new items. - - Added STL-like constructors. - - Added operators ==, < and derivatives - - Added at() method, approved for using after an exception was thrown inside the vector - - Added get_allocator() method. - - Added assign() methods - - Added compact() method to defragment first segments - - Added swap() method - - range() defaults on grainsize = 1 supporting auto grainsize algorithms. - - @ingroup containers */ -template -class concurrent_vector: protected internal::allocator_base, - private internal::concurrent_vector_base { -private: - template - class generic_range_type: public blocked_range { - public: - typedef T value_type; - typedef T& reference; - typedef const T& const_reference; - typedef I iterator; - typedef ptrdiff_t difference_type; - generic_range_type( I begin_, I end_, size_t grainsize_ = 1) : blocked_range(begin_,end_,grainsize_) {} - template - generic_range_type( const generic_range_type& r) : blocked_range(r.begin(),r.end(),r.grainsize()) {} - generic_range_type( generic_range_type& r, split ) : blocked_range(r,split()) {} - }; - - template - friend class internal::vector_iterator; - -public: - //------------------------------------------------------------------------ - // STL compatible types - //------------------------------------------------------------------------ - typedef internal::concurrent_vector_base_v3::size_type size_type; - typedef typename internal::allocator_base::allocator_type allocator_type; - - typedef T value_type; - typedef ptrdiff_t difference_type; - typedef T& reference; - typedef const T& const_reference; - typedef T *pointer; - typedef const T *const_pointer; - - typedef internal::vector_iterator iterator; - typedef internal::vector_iterator const_iterator; - -#if !defined(_MSC_VER) || _CPPLIB_VER>=300 - // Assume ISO standard definition of std::reverse_iterator - typedef std::reverse_iterator reverse_iterator; - typedef std::reverse_iterator const_reverse_iterator; -#else - // Use non-standard std::reverse_iterator - typedef std::reverse_iterator reverse_iterator; - typedef std::reverse_iterator const_reverse_iterator; -#endif /* defined(_MSC_VER) && (_MSC_VER<1300) */ - - //------------------------------------------------------------------------ - // Parallel algorithm support - //------------------------------------------------------------------------ - typedef generic_range_type range_type; - typedef generic_range_type const_range_type; - - //------------------------------------------------------------------------ - // STL compatible constructors & destructors - //------------------------------------------------------------------------ - - //! Construct empty vector. - explicit concurrent_vector(const allocator_type &a = allocator_type()) - : internal::allocator_base(a), internal::concurrent_vector_base() - { - vector_allocator_ptr = &internal_allocator; - } - - //Constructors are not required to have synchronization - //(for more details see comment in the concurrent_vector_base constructor). -#if __TBB_INITIALIZER_LISTS_PRESENT - //! Constructor from initializer_list - concurrent_vector(std::initializer_list init_list, const allocator_type &a = allocator_type()) - : internal::allocator_base(a), internal::concurrent_vector_base() - { - vector_allocator_ptr = &internal_allocator; - __TBB_TRY { - internal_assign_iterators(init_list.begin(), init_list.end()); - } __TBB_CATCH(...) { - segment_t *table = my_segment.load();; - internal_free_segments( table, internal_clear(&destroy_array), my_first_block.load()); - __TBB_RETHROW(); - } - - } -#endif //# __TBB_INITIALIZER_LISTS_PRESENT - - //! Copying constructor - concurrent_vector( const concurrent_vector& vector, const allocator_type& a = allocator_type() ) - : internal::allocator_base(a), internal::concurrent_vector_base() - { - vector_allocator_ptr = &internal_allocator; - __TBB_TRY { - internal_copy(vector, sizeof(T), ©_array); - } __TBB_CATCH(...) { - segment_t *table = my_segment.load(); - internal_free_segments( table, internal_clear(&destroy_array), my_first_block.load()); - __TBB_RETHROW(); - } - } - -#if __TBB_CPP11_RVALUE_REF_PRESENT - //! Move constructor - //TODO add __TBB_NOEXCEPT(true) and static_assert(std::has_nothrow_move_constructor::value) - concurrent_vector( concurrent_vector&& source) - : internal::allocator_base(std::move(source)), internal::concurrent_vector_base() - { - vector_allocator_ptr = &internal_allocator; - concurrent_vector_base_v3::internal_swap(source); - } - - concurrent_vector( concurrent_vector&& source, const allocator_type& a) - : internal::allocator_base(a), internal::concurrent_vector_base() - { - vector_allocator_ptr = &internal_allocator; - //C++ standard requires instances of an allocator being compared for equality, - //which means that memory allocated by one instance is possible to deallocate with the other one. - if (a == source.my_allocator) { - concurrent_vector_base_v3::internal_swap(source); - } else { - __TBB_TRY { - internal_copy(source, sizeof(T), &move_array); - } __TBB_CATCH(...) { - segment_t *table = my_segment.load(); - internal_free_segments( table, internal_clear(&destroy_array), my_first_block.load()); - __TBB_RETHROW(); - } - } - } - -#endif - - //! Copying constructor for vector with different allocator type - template - concurrent_vector( const concurrent_vector& vector, const allocator_type& a = allocator_type() ) - : internal::allocator_base(a), internal::concurrent_vector_base() - { - vector_allocator_ptr = &internal_allocator; - __TBB_TRY { - internal_copy(vector.internal_vector_base(), sizeof(T), ©_array); - } __TBB_CATCH(...) { - segment_t *table = my_segment.load(); - internal_free_segments( table, internal_clear(&destroy_array), my_first_block.load() ); - __TBB_RETHROW(); - } - } - - //! Construction with initial size specified by argument n - explicit concurrent_vector(size_type n) - { - vector_allocator_ptr = &internal_allocator; - __TBB_TRY { - internal_resize( n, sizeof(T), max_size(), NULL, &destroy_array, &initialize_array ); - } __TBB_CATCH(...) { - segment_t *table = my_segment.load(); - internal_free_segments( table, internal_clear(&destroy_array), my_first_block.load() ); - __TBB_RETHROW(); - } - } - - //! Construction with initial size specified by argument n, initialization by copying of t, and given allocator instance - concurrent_vector(size_type n, const_reference t, const allocator_type& a = allocator_type()) - : internal::allocator_base(a) - { - vector_allocator_ptr = &internal_allocator; - __TBB_TRY { - internal_resize( n, sizeof(T), max_size(), static_cast(&t), &destroy_array, &initialize_array_by ); - } __TBB_CATCH(...) { - segment_t *table = my_segment.load(); - internal_free_segments( table, internal_clear(&destroy_array), my_first_block.load() ); - __TBB_RETHROW(); - } - } - - //! Construction with copying iteration range and given allocator instance - template - concurrent_vector(I first, I last, const allocator_type &a = allocator_type()) - : internal::allocator_base(a) - { - vector_allocator_ptr = &internal_allocator; - __TBB_TRY { - internal_assign_range(first, last, static_cast::is_integer> *>(0) ); - } __TBB_CATCH(...) { - segment_t *table = my_segment.load(); - internal_free_segments( table, internal_clear(&destroy_array), my_first_block.load() ); - __TBB_RETHROW(); - } - } - - //! Assignment - concurrent_vector& operator=( const concurrent_vector& vector ) { - if( this != &vector ) - internal_assign(vector, sizeof(T), &destroy_array, &assign_array, ©_array); - return *this; - } - -#if __TBB_CPP11_RVALUE_REF_PRESENT - //TODO: add __TBB_NOEXCEPT() - //! Move assignment - concurrent_vector& operator=( concurrent_vector&& other ) { - __TBB_ASSERT(this != &other, "Move assignment to itself is prohibited "); - typedef typename tbb::internal::allocator_traits::propagate_on_container_move_assignment pocma_t; - if(pocma_t::value || this->my_allocator == other.my_allocator) { - concurrent_vector trash (std::move(*this)); - internal_swap(other); - if (pocma_t::value) { - this->my_allocator = std::move(other.my_allocator); - } - } else { - internal_assign(other, sizeof(T), &destroy_array, &move_assign_array, &move_array); - } - return *this; - } -#endif - //TODO: add an template assignment operator? (i.e. with different element type) - - //! Assignment for vector with different allocator type - template - concurrent_vector& operator=( const concurrent_vector& vector ) { - if( static_cast( this ) != static_cast( &vector ) ) - internal_assign(vector.internal_vector_base(), - sizeof(T), &destroy_array, &assign_array, ©_array); - return *this; - } - -#if __TBB_INITIALIZER_LISTS_PRESENT - //! Assignment for initializer_list - concurrent_vector& operator=( std::initializer_list init_list ) { - internal_clear(&destroy_array); - internal_assign_iterators(init_list.begin(), init_list.end()); - return *this; - } -#endif //#if __TBB_INITIALIZER_LISTS_PRESENT - - //------------------------------------------------------------------------ - // Concurrent operations - //------------------------------------------------------------------------ - //! Grow by "delta" elements. - /** Returns iterator pointing to the first new element. */ - iterator grow_by( size_type delta ) { - return iterator(*this, delta ? internal_grow_by( delta, sizeof(T), &initialize_array, NULL ) : my_early_size.load()); - } - - //! Grow by "delta" elements using copying constructor. - /** Returns iterator pointing to the first new element. */ - iterator grow_by( size_type delta, const_reference t ) { - return iterator(*this, delta ? internal_grow_by( delta, sizeof(T), &initialize_array_by, static_cast(&t) ) : my_early_size.load()); - } - - /** Returns iterator pointing to the first new element. */ - template - iterator grow_by( I first, I last ) { - typename std::iterator_traits::difference_type delta = std::distance(first, last); - __TBB_ASSERT( delta >= 0, NULL); - - return iterator(*this, delta ? internal_grow_by(delta, sizeof(T), ©_range, static_cast(&first)) : my_early_size.load()); - } - -#if __TBB_INITIALIZER_LISTS_PRESENT - /** Returns iterator pointing to the first new element. */ - iterator grow_by( std::initializer_list init_list ) { - return grow_by( init_list.begin(), init_list.end() ); - } -#endif //#if __TBB_INITIALIZER_LISTS_PRESENT - - //! Append minimal sequence of elements such that size()>=n. - /** The new elements are default constructed. Blocks until all elements in range [0..n) are allocated. - May return while other elements are being constructed by other threads. - Returns iterator that points to beginning of appended sequence. - If no elements were appended, returns iterator pointing to nth element. */ - iterator grow_to_at_least( size_type n ) { - size_type m=0; - if( n ) { - m = internal_grow_to_at_least_with_result( n, sizeof(T), &initialize_array, NULL ); - if( m>n ) m=n; - } - return iterator(*this, m); - }; - - /** Analogous to grow_to_at_least( size_type n ) with exception that the new - elements are initialized by copying of t instead of default construction. */ - iterator grow_to_at_least( size_type n, const_reference t ) { - size_type m=0; - if( n ) { - m = internal_grow_to_at_least_with_result( n, sizeof(T), &initialize_array_by, &t); - if( m>n ) m=n; - } - return iterator(*this, m); - }; - - //! Push item - /** Returns iterator pointing to the new element. */ - iterator push_back( const_reference item ) - { - push_back_helper prolog(*this); - new(prolog.internal_push_back_result()) T(item); - return prolog.return_iterator_and_dismiss(); - } - -#if __TBB_CPP11_RVALUE_REF_PRESENT - //! Push item, move-aware - /** Returns iterator pointing to the new element. */ - iterator push_back( T&& item ) - { - push_back_helper prolog(*this); - new(prolog.internal_push_back_result()) T(std::move(item)); - return prolog.return_iterator_and_dismiss(); - } -#if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT - //! Push item, create item "in place" with provided arguments - /** Returns iterator pointing to the new element. */ - template - iterator emplace_back( Args&&... args ) - { - push_back_helper prolog(*this); - new(prolog.internal_push_back_result()) T(std::forward(args)...); - return prolog.return_iterator_and_dismiss(); - } -#endif //__TBB_CPP11_VARIADIC_TEMPLATES_PRESENT -#endif //__TBB_CPP11_RVALUE_REF_PRESENT - //! Get reference to element at given index. - /** This method is thread-safe for concurrent reads, and also while growing the vector, - as long as the calling thread has checked that index < size(). */ - reference operator[]( size_type index ) { - return internal_subscript(index); - } - - //! Get const reference to element at given index. - const_reference operator[]( size_type index ) const { - return internal_subscript(index); - } - - //! Get reference to element at given index. Throws exceptions on errors. - reference at( size_type index ) { - return internal_subscript_with_exceptions(index); - } - - //! Get const reference to element at given index. Throws exceptions on errors. - const_reference at( size_type index ) const { - return internal_subscript_with_exceptions(index); - } - - //! Get range for iterating with parallel algorithms - range_type range( size_t grainsize = 1 ) { - return range_type( begin(), end(), grainsize ); - } - - //! Get const range for iterating with parallel algorithms - const_range_type range( size_t grainsize = 1 ) const { - return const_range_type( begin(), end(), grainsize ); - } - - //------------------------------------------------------------------------ - // Capacity - //------------------------------------------------------------------------ - //! Return size of vector. It may include elements under construction - size_type size() const { - size_type sz = my_early_size, cp = internal_capacity(); - return cp < sz ? cp : sz; - } - - //! Return false if vector is not empty or has elements under construction at least. - bool empty() const {return !my_early_size;} - - //! Maximum size to which array can grow without allocating more memory. Concurrent allocations are not included in the value. - size_type capacity() const {return internal_capacity();} - - //! Allocate enough space to grow to size n without having to allocate more memory later. - /** Like most of the methods provided for STL compatibility, this method is *not* thread safe. - The capacity afterwards may be bigger than the requested reservation. */ - void reserve( size_type n ) { - if( n ) - internal_reserve(n, sizeof(T), max_size()); - } - - //! Resize the vector. Not thread-safe. - void resize( size_type n ) { - internal_resize( n, sizeof(T), max_size(), NULL, &destroy_array, &initialize_array ); - } - - //! Resize the vector, copy t for new elements. Not thread-safe. - void resize( size_type n, const_reference t ) { - internal_resize( n, sizeof(T), max_size(), static_cast(&t), &destroy_array, &initialize_array_by ); - } - - //! Optimize memory usage and fragmentation. - void shrink_to_fit(); - - //! Upper bound on argument to reserve. - size_type max_size() const {return (~size_type(0))/sizeof(T);} - - //------------------------------------------------------------------------ - // STL support - //------------------------------------------------------------------------ - - //! start iterator - iterator begin() {return iterator(*this,0);} - //! end iterator - iterator end() {return iterator(*this,size());} - //! start const iterator - const_iterator begin() const {return const_iterator(*this,0);} - //! end const iterator - const_iterator end() const {return const_iterator(*this,size());} - //! start const iterator - const_iterator cbegin() const {return const_iterator(*this,0);} - //! end const iterator - const_iterator cend() const {return const_iterator(*this,size());} - //! reverse start iterator - reverse_iterator rbegin() {return reverse_iterator(end());} - //! reverse end iterator - reverse_iterator rend() {return reverse_iterator(begin());} - //! reverse start const iterator - const_reverse_iterator rbegin() const {return const_reverse_iterator(end());} - //! reverse end const iterator - const_reverse_iterator rend() const {return const_reverse_iterator(begin());} - //! reverse start const iterator - const_reverse_iterator crbegin() const {return const_reverse_iterator(end());} - //! reverse end const iterator - const_reverse_iterator crend() const {return const_reverse_iterator(begin());} - //! the first item - reference front() { - __TBB_ASSERT( size()>0, NULL); - const segment_value_t& segment_value = my_segment[0].template load(); - return (segment_value.template pointer())[0]; - } - //! the first item const - const_reference front() const { - __TBB_ASSERT( size()>0, NULL); - const segment_value_t& segment_value = my_segment[0].template load(); - return (segment_value.template pointer())[0]; - } - //! the last item - reference back() { - __TBB_ASSERT( size()>0, NULL); - return internal_subscript( size()-1 ); - } - //! the last item const - const_reference back() const { - __TBB_ASSERT( size()>0, NULL); - return internal_subscript( size()-1 ); - } - //! return allocator object - allocator_type get_allocator() const { return this->my_allocator; } - - //! assign n items by copying t item - void assign(size_type n, const_reference t) { - clear(); - internal_resize( n, sizeof(T), max_size(), static_cast(&t), &destroy_array, &initialize_array_by ); - } - - //! assign range [first, last) - template - void assign(I first, I last) { - clear(); internal_assign_range( first, last, static_cast::is_integer> *>(0) ); - } - -#if __TBB_INITIALIZER_LISTS_PRESENT - //! assigns an initializer list - void assign(std::initializer_list init_list) { - clear(); internal_assign_iterators( init_list.begin(), init_list.end()); - } -#endif //# __TBB_INITIALIZER_LISTS_PRESENT - - //! swap two instances - void swap(concurrent_vector &vector) { - using std::swap; - if( this != &vector ) { - concurrent_vector_base_v3::internal_swap(static_cast(vector)); - swap(this->my_allocator, vector.my_allocator); - } - } - - //! Clear container while keeping memory allocated. - /** To free up the memory, use in conjunction with method compact(). Not thread safe **/ - void clear() { - internal_clear(&destroy_array); - } - - //! Clear and destroy vector. - ~concurrent_vector() { - segment_t *table = my_segment.load(); - internal_free_segments( table, internal_clear(&destroy_array), my_first_block.load() ); - // base class destructor call should be then - } - - const internal::concurrent_vector_base_v3 &internal_vector_base() const { return *this; } -private: - //! Allocate k items - static void *internal_allocator(internal::concurrent_vector_base_v3 &vb, size_t k) { - return static_cast&>(vb).my_allocator.allocate(k); - } - //! Free k segments from table - void internal_free_segments(segment_t table[], segment_index_t k, segment_index_t first_block); - - //! Get reference to element at given index. - T& internal_subscript( size_type index ) const; - - //! Get reference to element at given index with errors checks - T& internal_subscript_with_exceptions( size_type index ) const; - - //! assign n items by copying t - void internal_assign_n(size_type n, const_pointer p) { - internal_resize( n, sizeof(T), max_size(), static_cast(p), &destroy_array, p? &initialize_array_by : &initialize_array ); - } - - //! helper class - template class is_integer_tag; - - //! assign integer items by copying when arguments are treated as iterators. See C++ Standard 2003 23.1.1p9 - template - void internal_assign_range(I first, I last, is_integer_tag *) { - internal_assign_n(static_cast(first), &static_cast(last)); - } - //! inline proxy assign by iterators - template - void internal_assign_range(I first, I last, is_integer_tag *) { - internal_assign_iterators(first, last); - } - //! assign by iterators - template - void internal_assign_iterators(I first, I last); - - //these functions are marked __TBB_EXPORTED_FUNC as they are called from within the library - - //! Construct n instances of T, starting at "begin". - static void __TBB_EXPORTED_FUNC initialize_array( void* begin, const void*, size_type n ); - - //! Copy-construct n instances of T, starting at "begin". - static void __TBB_EXPORTED_FUNC initialize_array_by( void* begin, const void* src, size_type n ); - - //! Copy-construct n instances of T by copying single element pointed to by src, starting at "dst". - static void __TBB_EXPORTED_FUNC copy_array( void* dst, const void* src, size_type n ); - -#if __TBB_MOVE_IF_NOEXCEPT_PRESENT - //! Either opy or move-construct n instances of T, starting at "dst" by copying according element of src array. - static void __TBB_EXPORTED_FUNC move_array_if_noexcept( void* dst, const void* src, size_type n ); -#endif //__TBB_MOVE_IF_NO_EXCEPT_PRESENT - -#if __TBB_CPP11_RVALUE_REF_PRESENT - //! Move-construct n instances of T, starting at "dst" by copying according element of src array. - static void __TBB_EXPORTED_FUNC move_array( void* dst, const void* src, size_type n ); - - //! Move-assign (using operator=) n instances of T, starting at "dst" by assigning according element of src array. - static void __TBB_EXPORTED_FUNC move_assign_array( void* dst, const void* src, size_type n ); -#endif - //! Copy-construct n instances of T, starting at "dst" by iterator range of [p_type_erased_iterator, p_type_erased_iterator+n). - template - static void __TBB_EXPORTED_FUNC copy_range( void* dst, const void* p_type_erased_iterator, size_type n ); - - //! Assign (using operator=) n instances of T, starting at "dst" by assigning according element of src array. - static void __TBB_EXPORTED_FUNC assign_array( void* dst, const void* src, size_type n ); - - //! Destroy n instances of T, starting at "begin". - static void __TBB_EXPORTED_FUNC destroy_array( void* begin, size_type n ); - - //! Exception-aware helper class for filling a segment by exception-danger operators of user class - class internal_loop_guide : internal::no_copy { - public: - const pointer array; - const size_type n; - size_type i; - - static const T* as_const_pointer(const void *ptr) { return static_cast(ptr); } - static T* as_pointer(const void *src) { return static_cast(const_cast(src)); } - - internal_loop_guide(size_type ntrials, void *ptr) - : array(as_pointer(ptr)), n(ntrials), i(0) {} - void init() { for(; i < n; ++i) new( &array[i] ) T(); } - void init(const void *src) { for(; i < n; ++i) new( &array[i] ) T(*as_const_pointer(src)); } - void copy(const void *src) { for(; i < n; ++i) new( &array[i] ) T(as_const_pointer(src)[i]); } - void assign(const void *src) { for(; i < n; ++i) array[i] = as_const_pointer(src)[i]; } -#if __TBB_CPP11_RVALUE_REF_PRESENT - void move_assign(const void *src) { for(; i < n; ++i) array[i] = std::move(as_pointer(src)[i]); } - void move_construct(const void *src) { for(; i < n; ++i) new( &array[i] ) T( std::move(as_pointer(src)[i]) ); } -#endif -#if __TBB_MOVE_IF_NOEXCEPT_PRESENT - void move_construct_if_noexcept(const void *src) { for(; i < n; ++i) new( &array[i] ) T( std::move_if_noexcept(as_pointer(src)[i]) ); } -#endif //__TBB_MOVE_IF_NOEXCEPT_PRESENT - - //TODO: rename to construct_range - template void iterate(I &src) { for(; i < n; ++i, ++src) new( &array[i] ) T( *src ); } - ~internal_loop_guide() { - if(i < n) {// if an exception was raised, fill the rest of items with zeros - internal::handle_unconstructed_elements(array+i, n-i); - } - } - }; - - struct push_back_helper : internal::no_copy{ - struct element_construction_guard : internal::no_copy{ - pointer element; - - element_construction_guard(pointer an_element) : element (an_element){} - void dismiss(){ element = NULL; } - ~element_construction_guard(){ - if (element){ - internal::handle_unconstructed_elements(element, 1); - } - } - }; - - concurrent_vector & v; - size_type k; - element_construction_guard g; - - push_back_helper(concurrent_vector & vector) : - v(vector), - g (static_cast(v.internal_push_back(sizeof(T),k))) - {} - - pointer internal_push_back_result(){ return g.element;} - iterator return_iterator_and_dismiss(){ - pointer ptr = g.element; - g.dismiss(); - return iterator(v, k, ptr); - } - }; -}; - -#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) -#pragma warning (push) -#pragma warning (disable: 4701) // potentially uninitialized local variable "old" -#endif -template -void concurrent_vector::shrink_to_fit() { - internal_segments_table old; - __TBB_TRY { - internal_array_op2 copy_or_move_array = -#if __TBB_MOVE_IF_NOEXCEPT_PRESENT - &move_array_if_noexcept -#else - ©_array -#endif - ; - if( internal_compact( sizeof(T), &old, &destroy_array, copy_or_move_array ) ) - internal_free_segments( old.table, pointers_per_long_table, old.first_block ); // free joined and unnecessary segments - } __TBB_CATCH(...) { - if( old.first_block ) // free segment allocated for compacting. Only for support of exceptions in ctor of user T[ype] - internal_free_segments( old.table, 1, old.first_block ); - __TBB_RETHROW(); - } -} -#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) -#pragma warning (pop) -#endif // warning 4701 is back - -template -void concurrent_vector::internal_free_segments(segment_t table[], segment_index_t k, segment_index_t first_block) { - // Free the arrays - while( k > first_block ) { - --k; - segment_value_t segment_value = table[k].load(); - table[k].store(segment_not_used()); - if( segment_value == segment_allocated() ) // check for correct segment pointer - this->my_allocator.deallocate( (segment_value.pointer()), segment_size(k) ); - } - segment_value_t segment_value = table[0].load(); - if( segment_value == segment_allocated() ) { - __TBB_ASSERT( first_block > 0, NULL ); - while(k > 0) table[--k].store(segment_not_used()); - this->my_allocator.deallocate( (segment_value.pointer()), segment_size(first_block) ); - } -} - -template -T& concurrent_vector::internal_subscript( size_type index ) const { - //TODO: unify both versions of internal_subscript - __TBB_ASSERT( index < my_early_size, "index out of bounds" ); - size_type j = index; - segment_index_t k = segment_base_index_of( j ); - __TBB_ASSERT( my_segment.load() != my_storage || k < pointers_per_short_table, "index is being allocated" ); - //no need in load with acquire (load) since thread works in own space or gets - //the information about added elements via some form of external synchronization - //TODO: why not make a load of my_segment relaxed as well ? - //TODO: add an assertion that my_segment[k] is properly aligned to please ITT - segment_value_t segment_value = my_segment[k].template load(); - __TBB_ASSERT( segment_value != segment_allocation_failed(), "the instance is broken by bad allocation. Use at() instead" ); - __TBB_ASSERT( segment_value != segment_not_used(), "index is being allocated" ); - return (( segment_value.pointer()))[j]; -} - -template -T& concurrent_vector::internal_subscript_with_exceptions( size_type index ) const { - if( index >= my_early_size ) - internal::throw_exception(internal::eid_out_of_range); // throw std::out_of_range - size_type j = index; - segment_index_t k = segment_base_index_of( j ); - //TODO: refactor this condition into separate helper function, e.g. fits_into_small_table - if( my_segment.load() == my_storage && k >= pointers_per_short_table ) - internal::throw_exception(internal::eid_segment_range_error); // throw std::range_error - // no need in load with acquire (load) since thread works in own space or gets - //the information about added elements via some form of external synchronization - //TODO: why not make a load of my_segment relaxed as well ? - //TODO: add an assertion that my_segment[k] is properly aligned to please ITT - segment_value_t segment_value = my_segment[k].template load(); - enforce_segment_allocated(segment_value, internal::eid_index_range_error); - return (segment_value.pointer())[j]; -} - -template template -void concurrent_vector::internal_assign_iterators(I first, I last) { - __TBB_ASSERT(my_early_size == 0, NULL); - size_type n = std::distance(first, last); - if( !n ) return; - internal_reserve(n, sizeof(T), max_size()); - my_early_size = n; - segment_index_t k = 0; - //TODO: unify segment iteration code with concurrent_base_v3::helper - size_type sz = segment_size( my_first_block ); - while( sz < n ) { - internal_loop_guide loop(sz, my_segment[k].template load().template pointer()); - loop.iterate(first); - n -= sz; - if( !k ) k = my_first_block; - else { ++k; sz <<= 1; } - } - internal_loop_guide loop(n, my_segment[k].template load().template pointer()); - loop.iterate(first); -} - -template -void concurrent_vector::initialize_array( void* begin, const void *, size_type n ) { - internal_loop_guide loop(n, begin); loop.init(); -} - -template -void concurrent_vector::initialize_array_by( void* begin, const void *src, size_type n ) { - internal_loop_guide loop(n, begin); loop.init(src); -} - -template -void concurrent_vector::copy_array( void* dst, const void* src, size_type n ) { - internal_loop_guide loop(n, dst); loop.copy(src); -} - -#if __TBB_CPP11_RVALUE_REF_PRESENT -template -void concurrent_vector::move_array( void* dst, const void* src, size_type n ) { - internal_loop_guide loop(n, dst); loop.move_construct(src); -} -template -void concurrent_vector::move_assign_array( void* dst, const void* src, size_type n ) { - internal_loop_guide loop(n, dst); loop.move_assign(src); -} -#endif - -#if __TBB_MOVE_IF_NOEXCEPT_PRESENT -template -void concurrent_vector::move_array_if_noexcept( void* dst, const void* src, size_type n ) { - internal_loop_guide loop(n, dst); loop.move_construct_if_noexcept(src); -} -#endif //__TBB_MOVE_IF_NOEXCEPT_PRESENT - -template -template -void concurrent_vector::copy_range( void* dst, const void* p_type_erased_iterator, size_type n ){ - I & iterator ((*const_cast(static_cast(p_type_erased_iterator)))); - internal_loop_guide loop(n, dst); loop.iterate(iterator); -} - -template -void concurrent_vector::assign_array( void* dst, const void* src, size_type n ) { - internal_loop_guide loop(n, dst); loop.assign(src); -} - -#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) - // Workaround for overzealous compiler warning - #pragma warning (push) - #pragma warning (disable: 4189) -#endif -template -void concurrent_vector::destroy_array( void* begin, size_type n ) { - T* array = static_cast(begin); - for( size_type j=n; j>0; --j ) - array[j-1].~T(); // destructors are supposed to not throw any exceptions -} -#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) - #pragma warning (pop) -#endif // warning 4189 is back - -// concurrent_vector's template functions -template -inline bool operator==(const concurrent_vector &a, const concurrent_vector &b) { - //TODO: call size() only once per vector (in operator==) - // Simply: return a.size() == b.size() && std::equal(a.begin(), a.end(), b.begin()); - if(a.size() != b.size()) return false; - typename concurrent_vector::const_iterator i(a.begin()); - typename concurrent_vector::const_iterator j(b.begin()); - for(; i != a.end(); ++i, ++j) - if( !(*i == *j) ) return false; - return true; -} - -template -inline bool operator!=(const concurrent_vector &a, const concurrent_vector &b) -{ return !(a == b); } - -template -inline bool operator<(const concurrent_vector &a, const concurrent_vector &b) -{ return (std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end())); } - -template -inline bool operator>(const concurrent_vector &a, const concurrent_vector &b) -{ return b < a; } - -template -inline bool operator<=(const concurrent_vector &a, const concurrent_vector &b) -{ return !(b < a); } - -template -inline bool operator>=(const concurrent_vector &a, const concurrent_vector &b) -{ return !(a < b); } - -template -inline void swap(concurrent_vector &a, concurrent_vector &b) -{ a.swap( b ); } - -} // namespace tbb - -#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) - #pragma warning (pop) -#endif // warning 4267,4127 are back - -#endif /* __TBB_concurrent_vector_H */ diff --git a/lib/3rdParty/tbb/include/tbb/critical_section.h b/lib/3rdParty/tbb/include/tbb/critical_section.h deleted file mode 100644 index 324b3e13..00000000 --- a/lib/3rdParty/tbb/include/tbb/critical_section.h +++ /dev/null @@ -1,133 +0,0 @@ -/* - 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_CRITICAL_SECTION_H_ -#define _TBB_CRITICAL_SECTION_H_ - -#if _WIN32||_WIN64 -#include "machine/windows_api.h" -#else -#include -#include -#endif // _WIN32||WIN64 - -#include "tbb_stddef.h" -#include "tbb_thread.h" -#include "tbb_exception.h" - -#include "tbb_profiling.h" - -namespace tbb { - - namespace internal { -class critical_section_v4 : internal::no_copy { -#if _WIN32||_WIN64 - CRITICAL_SECTION my_impl; -#else - pthread_mutex_t my_impl; -#endif - tbb_thread::id my_tid; -public: - - void __TBB_EXPORTED_METHOD internal_construct(); - - critical_section_v4() { -#if _WIN32||_WIN64 - InitializeCriticalSectionEx( &my_impl, 4000, 0 ); -#else - pthread_mutex_init(&my_impl, NULL); -#endif - internal_construct(); - } - - ~critical_section_v4() { - __TBB_ASSERT(my_tid == tbb_thread::id(), "Destroying a still-held critical section"); -#if _WIN32||_WIN64 - DeleteCriticalSection(&my_impl); -#else - pthread_mutex_destroy(&my_impl); -#endif - } - - class scoped_lock : internal::no_copy { - private: - critical_section_v4 &my_crit; - public: - scoped_lock( critical_section_v4& lock_me) :my_crit(lock_me) { - my_crit.lock(); - } - - ~scoped_lock() { - my_crit.unlock(); - } - }; - - void lock() { - tbb_thread::id local_tid = this_tbb_thread::get_id(); - if(local_tid == my_tid) throw_exception( eid_improper_lock ); -#if _WIN32||_WIN64 - EnterCriticalSection( &my_impl ); -#else - int rval = pthread_mutex_lock(&my_impl); - __TBB_ASSERT_EX(!rval, "critical_section::lock: pthread_mutex_lock failed"); -#endif - __TBB_ASSERT(my_tid == tbb_thread::id(), NULL); - my_tid = local_tid; - } - - bool try_lock() { - bool gotlock; - tbb_thread::id local_tid = this_tbb_thread::get_id(); - if(local_tid == my_tid) return false; -#if _WIN32||_WIN64 - gotlock = TryEnterCriticalSection( &my_impl ) != 0; -#else - int rval = pthread_mutex_trylock(&my_impl); - // valid returns are 0 (locked) and [EBUSY] - __TBB_ASSERT(rval == 0 || rval == EBUSY, "critical_section::trylock: pthread_mutex_trylock failed"); - gotlock = rval == 0; -#endif - if(gotlock) { - my_tid = local_tid; - } - return gotlock; - } - - void unlock() { - __TBB_ASSERT(this_tbb_thread::get_id() == my_tid, "thread unlocking critical_section is not thread that locked it"); - my_tid = tbb_thread::id(); -#if _WIN32||_WIN64 - LeaveCriticalSection( &my_impl ); -#else - int rval = pthread_mutex_unlock(&my_impl); - __TBB_ASSERT_EX(!rval, "critical_section::unlock: pthread_mutex_unlock failed"); -#endif - } - - static const bool is_rw_mutex = false; - static const bool is_recursive_mutex = false; - static const bool is_fair_mutex = true; -}; // critical_section_v4 -} // namespace internal -typedef internal::critical_section_v4 critical_section; - -__TBB_DEFINE_PROFILING_SET_NAME(critical_section) -} // namespace tbb -#endif // _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 deleted file mode 100644 index f31f533b..00000000 --- a/lib/3rdParty/tbb/include/tbb/enumerable_thread_specific.h +++ /dev/null @@ -1,1137 +0,0 @@ -/* - 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_enumerable_thread_specific_H -#define __TBB_enumerable_thread_specific_H - -#include "atomic.h" -#include "concurrent_vector.h" -#include "tbb_thread.h" -#include "tbb_allocator.h" -#include "cache_aligned_allocator.h" -#include "aligned_space.h" -#include "internal/_template_helpers.h" -#include "internal/_tbb_hash_compare_impl.h" -#include "tbb_profiling.h" -#include // for memcpy - -#if _WIN32||_WIN64 -#include "machine/windows_api.h" -#else -#include -#endif - -#define __TBB_ETS_USE_CPP11 \ - (__TBB_CPP11_RVALUE_REF_PRESENT && __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT \ - && __TBB_CPP11_DECLTYPE_PRESENT && __TBB_CPP11_LAMBDAS_PRESENT) - -namespace tbb { - -//! enum for selecting between single key and key-per-instance versions -enum ets_key_usage_type { ets_key_per_instance, ets_no_key }; - -namespace interface6 { - - // Forward declaration to use in internal classes - template - class enumerable_thread_specific; - - //! @cond - namespace internal { - - using namespace tbb::internal; - - template - class ets_base: tbb::internal::no_copy { - protected: - typedef tbb_thread::id key_type; -#if __TBB_PROTECTED_NESTED_CLASS_BROKEN - public: -#endif - struct slot; - - struct array { - array* next; - size_t lg_size; - 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); - } - }; - struct slot { - key_type key; - void* ptr; - bool empty() const {return key == key_type();} - bool match( key_type k ) const {return key == k;} - bool claim( key_type k ) { - // TODO: maybe claim ptr, because key_type is not guaranteed to fit into word size - return atomic_compare_and_swap(key, k, key_type()) == key_type(); - } - }; -#if __TBB_PROTECTED_NESTED_CLASS_BROKEN - protected: -#endif - - //! Root of linked list of arrays of decreasing size. - /** NULL if and only if my_count==0. - Each array in the list is half the size of its predecessor. */ - atomic my_root; - atomic my_count; - 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 - array* allocate( size_t lg_size ) { - size_t n = size_t(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 = size_t(1)<<(a->lg_size); - free_array( (void *)a, size_t(sizeof(array)+n*sizeof(slot)) ); - } - - ets_base() {my_root=NULL; my_count=0;} - virtual ~ets_base(); // g++ complains if this is not virtual - void* table_lookup( bool& exists ); - void table_clear(); - // The following functions are not used in concurrent context, - // so we don't need synchronization and ITT annotations there. - void table_elementwise_copy( const ets_base& other, - void*(*add_element)(ets_base&, void*) ) { - __TBB_ASSERT(!my_root,NULL); - __TBB_ASSERT(!my_count,NULL); - if( !other.my_root ) return; - array* root = my_root = allocate(other.my_root->lg_size); - root->next = NULL; - my_count = other.my_count; - size_t mask = root->mask(); - for( array* r=other.my_root; r; r=r->next ) { - for( size_t i=0; isize(); ++i ) { - slot& s1 = r->at(i); - if( !s1.empty() ) { - for( size_t j = root->start(tbb::tbb_hash()(s1.key)); ; j=(j+1)&mask ) { - slot& s2 = root->at(j); - if( s2.empty() ) { - s2.ptr = add_element(*this, s1.ptr); - s2.key = s1.key; - break; - } - else if( s2.match(s1.key) ) - break; - } - } - } - } - } - void table_swap( ets_base& other ) { - __TBB_ASSERT(this!=&other, "Don't swap an instance with itself"); - tbb::internal::swap(my_root, other.my_root); - tbb::internal::swap(my_count, other.my_count); - } - }; - - template - ets_base::~ets_base() { - __TBB_ASSERT(!my_root, NULL); - } - - template - void ets_base::table_clear() { - while( array* r = my_root ) { - my_root = r->next; - free(r); - } - my_count = 0; - } - - template - void* ets_base::table_lookup( bool& exists ) { - const key_type k = tbb::this_tbb_thread::get_id(); - - __TBB_ASSERT(k != key_type(),NULL); - void* found; - size_t h = tbb::tbb_hash()(k); - for( array* r=my_root; r; r=r->next ) { - call_itt_notify(acquired,r); - size_t mask=r->mask(); - for(size_t i = r->start(h); ;i=(i+1)&mask) { - slot& s = r->at(i); - if( s.empty() ) break; - if( s.match(k) ) { - if( r==my_root ) { - // Success at top level - exists = true; - return s.ptr; - } else { - // Success at some other level. Need to insert at top level. - exists = true; - found = s.ptr; - goto insert; - } - } - } - } - // Key does not yet exist. The density of slots in the table does not exceed 0.5, - // for if this will occur a new table is allocated with double the current table - // size, which is swapped in as the new root table. So an empty slot is guaranteed. - exists = false; - found = create_local(); - { - size_t c = ++my_count; - array* r = my_root; - call_itt_notify(acquired,r); - if( !r || c>r->size()/2 ) { - size_t s = r ? r->lg_size : 2; - while( c>size_t(1)<<(s-1) ) ++s; - array* a = allocate(s); - for(;;) { - a->next = r; - call_itt_notify(releasing,a); - array* new_r = my_root.compare_and_swap(a,r); - if( new_r==r ) break; - call_itt_notify(acquired, new_r); - if( new_r->lg_size>=s ) { - // Another thread inserted an equal or bigger array, so our array is superfluous. - free(a); - break; - } - r = new_r; - } - } - } - insert: - // Whether a slot has been found in an older table, or if it has been inserted at this level, - // it has already been accounted for in the total. Guaranteed to be room for it, and it is - // not present, so search for empty slot and use it. - array* ir = my_root; - call_itt_notify(acquired, ir); - size_t mask = ir->mask(); - for(size_t i = ir->start(h);;i=(i+1)&mask) { - slot& s = ir->at(i); - if( s.empty() ) { - if( s.claim(k) ) { - s.ptr = found; - return found; - } - } - } - } - - //! Specialization that exploits native TLS - template <> - class ets_base: protected ets_base { - typedef ets_base super; -#if _WIN32||_WIN64 -#if __TBB_WIN8UI_SUPPORT - typedef DWORD tls_key_t; - void create_key() { my_key = FlsAlloc(NULL); } - void destroy_key() { FlsFree(my_key); } - void set_tls(void * value) { FlsSetValue(my_key, (LPVOID)value); } - void* get_tls() { return (void *)FlsGetValue(my_key); } -#else - typedef DWORD tls_key_t; - void create_key() { my_key = TlsAlloc(); } - void destroy_key() { TlsFree(my_key); } - void set_tls(void * value) { TlsSetValue(my_key, (LPVOID)value); } - void* get_tls() { return (void *)TlsGetValue(my_key); } -#endif -#else - typedef pthread_key_t tls_key_t; - void create_key() { pthread_key_create(&my_key, NULL); } - void destroy_key() { pthread_key_delete(my_key); } - void set_tls( void * value ) const { pthread_setspecific(my_key, value); } - void* get_tls() const { return pthread_getspecific(my_key); } -#endif - tls_key_t my_key; - 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();} - void* table_lookup( bool& exists ) { - void* found = get_tls(); - if( found ) { - exists=true; - } else { - found = super::table_lookup(exists); - set_tls(found); - } - return found; - } - void table_clear() { - destroy_key(); - create_key(); - super::table_clear(); - } - void table_swap( ets_base& other ) { - using std::swap; - __TBB_ASSERT(this!=&other, "Don't swap an instance with itself"); - swap(my_key, other.my_key); - super::table_swap(other); - } - }; - - //! Random access iterator for traversing the thread local copies. - template< typename Container, typename Value > - class enumerable_thread_specific_iterator -#if defined(_WIN64) && defined(_MSC_VER) - // Ensure that Microsoft's internal template function _Val_type works correctly. - : public std::iterator -#endif /* defined(_WIN64) && defined(_MSC_VER) */ - { - //! current position in the concurrent_vector - - Container *my_container; - typename Container::size_type my_index; - mutable Value *my_value; - - template - friend enumerable_thread_specific_iterator - operator+( ptrdiff_t offset, const enumerable_thread_specific_iterator& v ); - - template - friend bool operator==( const enumerable_thread_specific_iterator& i, - const enumerable_thread_specific_iterator& j ); - - template - friend bool operator<( const enumerable_thread_specific_iterator& i, - const enumerable_thread_specific_iterator& j ); - - template - friend ptrdiff_t operator-( const enumerable_thread_specific_iterator& i, - const enumerable_thread_specific_iterator& j ); - - template - friend class enumerable_thread_specific_iterator; - - public: - - enumerable_thread_specific_iterator( const Container &container, typename Container::size_type index ) : - my_container(&const_cast(container)), my_index(index), my_value(NULL) {} - - //! Default constructor - enumerable_thread_specific_iterator() : my_container(NULL), my_index(0), my_value(NULL) {} - - template - enumerable_thread_specific_iterator( const enumerable_thread_specific_iterator& other ) : - my_container( other.my_container ), my_index( other.my_index), my_value( const_cast(other.my_value) ) {} - - enumerable_thread_specific_iterator operator+( ptrdiff_t offset ) const { - return enumerable_thread_specific_iterator(*my_container, my_index + offset); - } - - enumerable_thread_specific_iterator &operator+=( ptrdiff_t offset ) { - my_index += offset; - my_value = NULL; - return *this; - } - - enumerable_thread_specific_iterator operator-( ptrdiff_t offset ) const { - return enumerable_thread_specific_iterator( *my_container, my_index-offset ); - } - - enumerable_thread_specific_iterator &operator-=( ptrdiff_t offset ) { - my_index -= offset; - my_value = NULL; - return *this; - } - - Value& operator*() const { - Value* value = my_value; - if( !value ) { - value = my_value = (*my_container)[my_index].value(); - } - __TBB_ASSERT( value==(*my_container)[my_index].value(), "corrupt cache" ); - return *value; - } - - Value& operator[]( ptrdiff_t k ) const { - return (*my_container)[my_index + k].value; - } - - Value* operator->() const {return &operator*();} - - enumerable_thread_specific_iterator& operator++() { - ++my_index; - my_value = NULL; - return *this; - } - - enumerable_thread_specific_iterator& operator--() { - --my_index; - my_value = NULL; - return *this; - } - - //! Post increment - enumerable_thread_specific_iterator operator++(int) { - enumerable_thread_specific_iterator result = *this; - ++my_index; - my_value = NULL; - return result; - } - - //! Post decrement - enumerable_thread_specific_iterator operator--(int) { - enumerable_thread_specific_iterator result = *this; - --my_index; - my_value = NULL; - return result; - } - - // STL support - typedef ptrdiff_t difference_type; - typedef Value value_type; - typedef Value* pointer; - typedef Value& reference; - typedef std::random_access_iterator_tag iterator_category; - }; - - template - enumerable_thread_specific_iterator - operator+( ptrdiff_t offset, const enumerable_thread_specific_iterator& v ) { - return enumerable_thread_specific_iterator( v.my_container, v.my_index + offset ); - } - - template - bool operator==( const enumerable_thread_specific_iterator& i, - const enumerable_thread_specific_iterator& j ) { - return i.my_index==j.my_index && i.my_container == j.my_container; - } - - template - bool operator!=( const enumerable_thread_specific_iterator& i, - const enumerable_thread_specific_iterator& j ) { - return !(i==j); - } - - template - bool operator<( const enumerable_thread_specific_iterator& i, - const enumerable_thread_specific_iterator& j ) { - return i.my_index - bool operator>( const enumerable_thread_specific_iterator& i, - const enumerable_thread_specific_iterator& j ) { - return j - bool operator>=( const enumerable_thread_specific_iterator& i, - const enumerable_thread_specific_iterator& j ) { - return !(i - bool operator<=( const enumerable_thread_specific_iterator& i, - const enumerable_thread_specific_iterator& j ) { - return !(j - ptrdiff_t operator-( const enumerable_thread_specific_iterator& i, - const enumerable_thread_specific_iterator& j ) { - return i.my_index-j.my_index; - } - - template - class segmented_iterator -#if defined(_WIN64) && defined(_MSC_VER) - : public std::iterator -#endif - { - template - friend bool operator==(const segmented_iterator& i, const segmented_iterator& j); - - template - friend bool operator!=(const segmented_iterator& i, const segmented_iterator& j); - - template - friend class segmented_iterator; - - public: - - segmented_iterator() {my_segcont = NULL;} - - segmented_iterator( const SegmentedContainer& _segmented_container ) : - my_segcont(const_cast(&_segmented_container)), - outer_iter(my_segcont->end()) { } - - ~segmented_iterator() {} - - typedef typename SegmentedContainer::iterator outer_iterator; - typedef typename SegmentedContainer::value_type InnerContainer; - typedef typename InnerContainer::iterator inner_iterator; - - // STL support - typedef ptrdiff_t difference_type; - typedef Value value_type; - typedef typename SegmentedContainer::size_type size_type; - typedef Value* pointer; - typedef Value& reference; - typedef std::input_iterator_tag iterator_category; - - // Copy Constructor - template - segmented_iterator(const segmented_iterator& other) : - my_segcont(other.my_segcont), - outer_iter(other.outer_iter), - // can we assign a default-constructed iterator to inner if we're at the end? - inner_iter(other.inner_iter) - {} - - // assignment - template - segmented_iterator& operator=( const segmented_iterator& other) { - if(this != &other) { - my_segcont = other.my_segcont; - outer_iter = other.outer_iter; - if(outer_iter != my_segcont->end()) inner_iter = other.inner_iter; - } - return *this; - } - - // allow assignment of outer iterator to segmented iterator. Once it is - // assigned, move forward until a non-empty inner container is found or - // the end of the outer container is reached. - segmented_iterator& operator=(const outer_iterator& new_outer_iter) { - __TBB_ASSERT(my_segcont != NULL, NULL); - // check that this iterator points to something inside the segmented container - for(outer_iter = new_outer_iter ;outer_iter!=my_segcont->end(); ++outer_iter) { - if( !outer_iter->empty() ) { - inner_iter = outer_iter->begin(); - break; - } - } - return *this; - } - - // pre-increment - segmented_iterator& operator++() { - advance_me(); - return *this; - } - - // post-increment - segmented_iterator operator++(int) { - segmented_iterator tmp = *this; - operator++(); - return tmp; - } - - bool operator==(const outer_iterator& other_outer) const { - __TBB_ASSERT(my_segcont != NULL, NULL); - return (outer_iter == other_outer && - (outer_iter == my_segcont->end() || inner_iter == outer_iter->begin())); - } - - bool operator!=(const outer_iterator& other_outer) const { - return !operator==(other_outer); - - } - - // (i)* RHS - reference operator*() const { - __TBB_ASSERT(my_segcont != NULL, NULL); - __TBB_ASSERT(outer_iter != my_segcont->end(), "Dereferencing a pointer at end of container"); - __TBB_ASSERT(inner_iter != outer_iter->end(), NULL); // should never happen - return *inner_iter; - } - - // i-> - pointer operator->() const { return &operator*();} - - private: - SegmentedContainer* my_segcont; - outer_iterator outer_iter; - inner_iterator inner_iter; - - void advance_me() { - __TBB_ASSERT(my_segcont != NULL, NULL); - __TBB_ASSERT(outer_iter != my_segcont->end(), NULL); // not true if there are no inner containers - __TBB_ASSERT(inner_iter != outer_iter->end(), NULL); // not true if the inner containers are all empty. - ++inner_iter; - while(inner_iter == outer_iter->end() && ++outer_iter != my_segcont->end()) { - inner_iter = outer_iter->begin(); - } - } - }; // segmented_iterator - - template - bool operator==( const segmented_iterator& i, - const segmented_iterator& j ) { - if(i.my_segcont != j.my_segcont) return false; - if(i.my_segcont == NULL) return true; - if(i.outer_iter != j.outer_iter) return false; - if(i.outer_iter == i.my_segcont->end()) return true; - return i.inner_iter == j.inner_iter; - } - - // != - template - bool operator!=( const segmented_iterator& i, - const segmented_iterator& j ) { - return !(i==j); - } - - template - struct construct_by_default: tbb::internal::no_assign { - void construct(void*where) {new(where) T();} // C++ note: the () in T() ensure zero initialization. - construct_by_default( int ) {} - }; - - template - struct construct_by_exemplar: tbb::internal::no_assign { - const T exemplar; - void construct(void*where) {new(where) T(exemplar);} - construct_by_exemplar( const T& t ) : exemplar(t) {} -#if __TBB_ETS_USE_CPP11 - construct_by_exemplar( T&& t ) : exemplar(std::move(t)) {} -#endif - }; - - template - struct construct_by_finit: tbb::internal::no_assign { - Finit f; - void construct(void* where) {new(where) T(f());} - construct_by_finit( const Finit& f_ ) : f(f_) {} -#if __TBB_ETS_USE_CPP11 - construct_by_finit( Finit&& f_ ) : f(std::move(f_)) {} -#endif - }; - -#if __TBB_ETS_USE_CPP11 - template - struct construct_by_args: tbb::internal::no_assign { - internal::stored_pack pack; - void construct(void* where) { - internal::call( [where](const typename strip

    ::type&... args ){ - new(where) T(args...); - }, pack ); - } - construct_by_args( P&& ... args ) : pack(std::forward

    (args)...) {} - }; -#endif - - // storage for initialization function pointer - // TODO: consider removing the template parameter T here and in callback_leaf - template - class callback_base { - public: - // Clone *this - virtual callback_base* clone() const = 0; - // Destruct and free *this - virtual void destroy() = 0; - // Need virtual destructor to satisfy GCC compiler warning - virtual ~callback_base() { } - // Construct T at where - virtual void construct(void* where) = 0; - }; - - template - class callback_leaf: public callback_base, Constructor { -#if __TBB_ETS_USE_CPP11 - template callback_leaf( P&& ... params ) : Constructor(std::forward

    (params)...) {} -#else - template callback_leaf( const X& x ) : Constructor(x) {} -#endif - // TODO: make the construction/destruction consistent (use allocator.construct/destroy) - typedef typename tbb::tbb_allocator my_allocator_type; - - callback_base* clone() const __TBB_override { - return make(*this); - } - - void destroy() __TBB_override { - my_allocator_type().destroy(this); - my_allocator_type().deallocate(this,1); - } - - void construct(void* where) __TBB_override { - Constructor::construct(where); - } - public: -#if __TBB_ETS_USE_CPP11 - template - static callback_base* make( P&& ... params ) { - void* where = my_allocator_type().allocate(1); - return new(where) callback_leaf( std::forward

    (params)... ); - } -#else - template - static callback_base* make( const X& x ) { - void* where = my_allocator_type().allocate(1); - return new(where) callback_leaf(x); - } -#endif - }; - - //! Template for recording construction of objects in table - /** All maintenance of the space will be done explicitly on push_back, - and all thread local copies must be destroyed before the concurrent - vector is deleted. - - The flag is_built is initialized to false. When the local is - successfully-constructed, set the flag to true or call value_committed(). - If the constructor throws, the flag will be false. - */ - template - struct ets_element { - tbb::aligned_space my_space; - bool is_built; - ets_element() { is_built = false; } // not currently-built - U* value() { return my_space.begin(); } - U* value_committed() { is_built = true; return my_space.begin(); } - ~ets_element() { - if(is_built) { - my_space.begin()->~U(); - is_built = false; - } - } - }; - - // A predicate that can be used for a compile-time compatibility check of ETS instances - // Ideally, it should have been declared inside the ETS class, but unfortunately - // in that case VS2013 does not enable the variadic constructor. - template struct is_compatible_ets { static const bool value = false; }; - template - struct is_compatible_ets< T, enumerable_thread_specific > { static const bool value = internal::is_same_type::value; }; - -#if __TBB_ETS_USE_CPP11 - // A predicate that checks whether, for a variable 'foo' of type T, foo() is a valid expression - template - class is_callable_no_args { - private: - typedef char yes[1]; - typedef char no [2]; - - template static yes& decide( decltype(declval()())* ); - template static no& decide(...); - public: - static const bool value = (sizeof(decide(NULL)) == sizeof(yes)); - }; -#endif - - } // namespace internal - //! @endcond - - //! The enumerable_thread_specific container - /** enumerable_thread_specific has the following properties: - - thread-local copies are lazily created, with default, exemplar or function initialization. - - thread-local copies do not move (during lifetime, and excepting clear()) so the address of a copy is invariant. - - the contained objects need not have operator=() defined if combine is not used. - - enumerable_thread_specific containers may be copy-constructed or assigned. - - thread-local copies can be managed by hash-table, or can be accessed via TLS storage for speed. - - outside of parallel contexts, the contents of all thread-local copies are accessible by iterator or using combine or combine_each methods - - @par Segmented iterator - When the thread-local objects are containers with input_iterators defined, a segmented iterator may - be used to iterate over all the elements of all thread-local copies. - - @par combine and combine_each - - Both methods are defined for enumerable_thread_specific. - - combine() requires the type T have operator=() defined. - - neither method modifies the contents of the object (though there is no guarantee that the applied methods do not modify the object.) - - Both are evaluated in serial context (the methods are assumed to be non-benign.) - - @ingroup containers */ - template , - ets_key_usage_type ETS_key_type=ets_no_key > - class enumerable_thread_specific: internal::ets_base { - - template friend class enumerable_thread_specific; - - typedef internal::padded< internal::ets_element > padded_element; - - //! A generic range, used to create range objects from the iterators - template - class generic_range_type: public blocked_range { - public: - typedef T value_type; - typedef T& reference; - typedef const T& const_reference; - typedef I iterator; - typedef ptrdiff_t difference_type; - generic_range_type( I begin_, I end_, size_t grainsize_ = 1) : blocked_range(begin_,end_,grainsize_) {} - template - generic_range_type( const generic_range_type& r) : blocked_range(r.begin(),r.end(),r.grainsize()) {} - generic_range_type( generic_range_type& r, split ) : blocked_range(r,split()) {} - }; - - typedef typename Allocator::template rebind< padded_element >::other padded_allocator_type; - typedef tbb::concurrent_vector< padded_element, padded_allocator_type > internal_collection_type; - - internal::callback_base *my_construct_callback; - - internal_collection_type my_locals; - - // TODO: consider unifying the callback mechanism for all create_local* methods below - // (likely non-compatible and requires interface version increase) - void* create_local() __TBB_override { - padded_element& lref = *my_locals.grow_by(1); - my_construct_callback->construct(lref.value()); - return lref.value_committed(); - } - - static void* create_local_by_copy( internal::ets_base& base, void* p ) { - enumerable_thread_specific& ets = static_cast(base); - padded_element& lref = *ets.my_locals.grow_by(1); - new(lref.value()) T(*static_cast(p)); - return lref.value_committed(); - } - -#if __TBB_ETS_USE_CPP11 - static void* create_local_by_move( internal::ets_base& base, void* p ) { - enumerable_thread_specific& ets = static_cast(base); - padded_element& lref = *ets.my_locals.grow_by(1); - new(lref.value()) T(std::move(*static_cast(p))); - return lref.value_committed(); - } -#endif - - typedef typename Allocator::template rebind< uintptr_t >::other array_allocator_type; - - // _size is in bytes - 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); - } - - 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); - } - - public: - - //! Basic types - typedef Allocator allocator_type; - typedef T value_type; - typedef T& reference; - typedef const T& const_reference; - typedef T* pointer; - typedef const T* const_pointer; - typedef typename internal_collection_type::size_type size_type; - typedef typename internal_collection_type::difference_type difference_type; - - // Iterator types - typedef typename internal::enumerable_thread_specific_iterator< internal_collection_type, value_type > iterator; - typedef typename internal::enumerable_thread_specific_iterator< internal_collection_type, const value_type > const_iterator; - - // Parallel range types - typedef generic_range_type< iterator > range_type; - typedef generic_range_type< const_iterator > const_range_type; - - //! Default constructor. Each local instance of T is default constructed. - enumerable_thread_specific() : my_construct_callback( - internal::callback_leaf >::make(/*dummy argument*/0) - ){} - - //! Constructor with initializer functor. Each local instance of T is constructed by T(finit()). - template ::type>::value>::type -#endif - > - 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. - explicit enumerable_thread_specific( const T& exemplar ) : my_construct_callback( - internal::callback_leaf >::make( exemplar ) - ){} - -#if __TBB_ETS_USE_CPP11 - explicit enumerable_thread_specific( T&& exemplar ) : my_construct_callback( - internal::callback_leaf >::make( std::move(exemplar) ) - ){} - - //! Variadic constructor with initializer arguments. Each local instance of T is constructed by T(args...) - template ::type>::value - && !internal::is_compatible_ets::type>::value - && !internal::is_same_type::type>::value - >::type> - enumerable_thread_specific( P1&& arg1, P&& ... args ) : my_construct_callback( - internal::callback_leaf >::make( std::forward(arg1), std::forward

    (args)... ) - ){} -#endif - - //! Destructor - ~enumerable_thread_specific() { - if(my_construct_callback) my_construct_callback->destroy(); - // Deallocate the hash table before overridden free_array() becomes inaccessible - this->internal::ets_base::table_clear(); - } - - //! returns reference to local, discarding exists - reference local() { - bool exists; - return local(exists); - } - - //! Returns reference to calling thread's local copy, creating one if necessary - reference local(bool& exists) { - void* ptr = this->table_lookup(exists); - return *(T*)ptr; - } - - //! Get the number of local copies - size_type size() const { return my_locals.size(); } - - //! true if there have been no local copies created - bool empty() const { return my_locals.empty(); } - - //! begin iterator - iterator begin() { return iterator( my_locals, 0 ); } - //! end iterator - iterator end() { return iterator(my_locals, my_locals.size() ); } - - //! begin const iterator - const_iterator begin() const { return const_iterator(my_locals, 0); } - - //! end const iterator - const_iterator end() const { return const_iterator(my_locals, my_locals.size()); } - - //! Get range for parallel algorithms - range_type range( size_t grainsize=1 ) { return range_type( begin(), end(), grainsize ); } - - //! Get const range for parallel algorithms - const_range_type range( size_t grainsize=1 ) const { return const_range_type( begin(), end(), grainsize ); } - - //! Destroys local copies - void clear() { - my_locals.clear(); - this->table_clear(); - // callback is not destroyed - } - - private: - - template - void internal_copy(const enumerable_thread_specific& other) { -#if __TBB_ETS_USE_CPP11 && TBB_USE_ASSERT - // this tests is_compatible_ets - __TBB_STATIC_ASSERT( (internal::is_compatible_ets::type>::value), "is_compatible_ets fails" ); -#endif - // Initialize my_construct_callback first, so that it is valid even if rest of this routine throws an exception. - my_construct_callback = other.my_construct_callback->clone(); - __TBB_ASSERT(my_locals.size()==0,NULL); - my_locals.reserve(other.size()); - this->table_elementwise_copy( other, create_local_by_copy ); - } - - void internal_swap(enumerable_thread_specific& other) { - using std::swap; - __TBB_ASSERT( this!=&other, NULL ); - swap(my_construct_callback, other.my_construct_callback); - // concurrent_vector::swap() preserves storage space, - // so addresses to the vector kept in ETS hash table remain valid. - swap(my_locals, other.my_locals); - this->internal::ets_base::table_swap(other); - } - -#if __TBB_ETS_USE_CPP11 - template - void internal_move(enumerable_thread_specific&& other) { -#if TBB_USE_ASSERT - // this tests is_compatible_ets - __TBB_STATIC_ASSERT( (internal::is_compatible_ets::type>::value), "is_compatible_ets fails" ); -#endif - my_construct_callback = other.my_construct_callback; - other.my_construct_callback = NULL; - __TBB_ASSERT(my_locals.size()==0,NULL); - my_locals.reserve(other.size()); - this->table_elementwise_copy( other, create_local_by_move ); - } -#endif - - public: - - enumerable_thread_specific( const enumerable_thread_specific& other ) - : internal::ets_base() /* prevents GCC warnings with -Wextra */ - { - internal_copy(other); - } - - template - enumerable_thread_specific( const enumerable_thread_specific& other ) - { - internal_copy(other); - } - -#if __TBB_ETS_USE_CPP11 - enumerable_thread_specific( enumerable_thread_specific&& other ) : my_construct_callback() - { - internal_swap(other); - } - - template - enumerable_thread_specific( enumerable_thread_specific&& other ) : my_construct_callback() - { - internal_move(std::move(other)); - } -#endif - - enumerable_thread_specific& operator=( const enumerable_thread_specific& other ) - { - if( this != &other ) { - this->clear(); - my_construct_callback->destroy(); - internal_copy( other ); - } - return *this; - } - - template - enumerable_thread_specific& operator=( const enumerable_thread_specific& other ) - { - __TBB_ASSERT( static_cast(this)!=static_cast(&other), NULL ); // Objects of different types - this->clear(); - my_construct_callback->destroy(); - internal_copy(other); - return *this; - } - -#if __TBB_ETS_USE_CPP11 - enumerable_thread_specific& operator=( enumerable_thread_specific&& other ) - { - if( this != &other ) - internal_swap(other); - return *this; - } - - template - enumerable_thread_specific& operator=( enumerable_thread_specific&& other ) - { - __TBB_ASSERT( static_cast(this)!=static_cast(&other), NULL ); // Objects of different types - this->clear(); - my_construct_callback->destroy(); - internal_move(std::move(other)); - return *this; - } -#endif - - // combine_func_t has signature T(T,T) or T(const T&, const T&) - template - T combine(combine_func_t f_combine) { - if(begin() == end()) { - internal::ets_element location; - my_construct_callback->construct(location.value()); - return *location.value_committed(); - } - const_iterator ci = begin(); - T my_result = *ci; - while(++ci != end()) - my_result = f_combine( my_result, *ci ); - return my_result; - } - - // combine_func_t takes T by value or by [const] reference, and returns nothing - template - void combine_each(combine_func_t f_combine) { - for(iterator ci = begin(); ci != end(); ++ci) { - f_combine( *ci ); - } - } - - }; // enumerable_thread_specific - - template< typename Container > - class flattened2d { - - // This intermediate typedef is to address issues with VC7.1 compilers - typedef typename Container::value_type conval_type; - - public: - - //! Basic types - typedef typename conval_type::size_type size_type; - typedef typename conval_type::difference_type difference_type; - typedef typename conval_type::allocator_type allocator_type; - typedef typename conval_type::value_type value_type; - typedef typename conval_type::reference reference; - typedef typename conval_type::const_reference const_reference; - typedef typename conval_type::pointer pointer; - typedef typename conval_type::const_pointer const_pointer; - - typedef typename internal::segmented_iterator iterator; - typedef typename internal::segmented_iterator const_iterator; - - 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) { } - - 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; } - iterator end() { return iterator(*my_container) = my_end; } - const_iterator begin() const { return const_iterator(*my_container) = my_begin; } - const_iterator end() const { return const_iterator(*my_container) = my_end; } - - size_type size() const { - size_type tot_size = 0; - for(typename Container::const_iterator i = my_begin; i != my_end; ++i) { - tot_size += i->size(); - } - return tot_size; - } - - private: - - Container *my_container; - typename Container::const_iterator my_begin; - typename Container::const_iterator my_end; - - }; - - template - flattened2d flatten2d(const Container &c, const typename Container::const_iterator b, const typename Container::const_iterator e) { - return flattened2d(c, b, e); - } - - template - flattened2d flatten2d(const Container &c) { - return flattened2d(c); - } - -} // interface6 - -namespace internal { -using interface6::internal::segmented_iterator; -} - -using interface6::enumerable_thread_specific; -using interface6::flattened2d; -using interface6::flatten2d; - -} // namespace tbb - -#endif diff --git a/lib/3rdParty/tbb/include/tbb/flow_graph.h b/lib/3rdParty/tbb/include/tbb/flow_graph.h deleted file mode 100644 index 7b03c0e2..00000000 --- a/lib/3rdParty/tbb/include/tbb/flow_graph.h +++ /dev/null @@ -1,4075 +0,0 @@ -/* - 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_H -#define __TBB_flow_graph_H - -#include "tbb_stddef.h" -#include "atomic.h" -#include "spin_mutex.h" -#include "null_mutex.h" -#include "spin_rw_mutex.h" -#include "null_rw_mutex.h" -#include "task.h" -#include "cache_aligned_allocator.h" -#include "tbb_exception.h" -#include "internal/_template_helpers.h" -#include "internal/_aggregator_impl.h" -#include "tbb_profiling.h" -#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 -#define FLOW_SPAWN(a) tbb::task::spawn((a)) -#endif - -// use the VC10 or gcc version of tuple if it is available. -#if __TBB_CPP11_TUPLE_PRESENT - #include -namespace tbb { - namespace flow { - using std::tuple; - using std::tuple_size; - using std::tuple_element; - using std::get; - } -} -#else - #include "compat/tuple" -#endif - -#include -#include - -/** @file - \brief The graph related classes and functions - - There are some applications that best express dependencies as messages - passed between nodes in a graph. These messages may contain data or - simply act as signals that a predecessors has completed. The graph - class and its associated node classes can be used to express such - applications. -*/ - -namespace tbb { -namespace flow { - -//! An enumeration the provides the two most common concurrency levels: unlimited and serial -enum concurrency { unlimited = 0, serial = 1 }; - -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; - template class predecessor_cache; - template class reservable_predecessor_cache; -} - -//A generic null type -struct null_type {}; - -//! An empty class used for messages that mean "I'm done" -class continue_msg {}; - -template< typename T > class sender; -template< typename T > class receiver; -class continue_receiver; - -template< typename T > class limiter_node; // needed for resetting decrementer -template< typename R, typename B > class run_and_put_task; - -// flags to modify the behavior of the graph reset(). Can be combined. -enum reset_flags { - rf_reset_protocol = 0, - rf_reset_bodies = 1<<0, // delete the current node body, reset to a copy of the initial node body. - rf_clear_edges = 1<<1 // delete edges -}; - -#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. -namespace internal { -template -class edge_container { - -public: - typedef std::list > edge_list_type; - - void add_edge( C &s) { - built_edges.push_back( &s ); - } - - void delete_edge( C &s) { - for ( typename edge_list_type::iterator i = built_edges.begin(); i != built_edges.end(); ++i ) { - if ( *i == &s ) { - (void)built_edges.erase(i); - return; // only remove one predecessor per request - } - } - } - - void copy_edges( edge_list_type &v) { - v = built_edges; - } - - size_t edge_count() { - return (size_t)(built_edges.size()); - } - - void clear() { - built_edges.clear(); - } - - // 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 ); - -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 > { -public: - - //! The input type - typedef continue_msg input_type; - - //! The predecessor type for this node - typedef receiver::predecessor_type predecessor_type; - - //! Constructor - explicit continue_receiver( int number_of_predecessors = 0 ) { - my_predecessor_count = my_initial_predecessor_count = number_of_predecessors; - my_current_count = 0; - } - - //! Copy constructor - continue_receiver( const continue_receiver& src ) : receiver() { - my_predecessor_count = my_initial_predecessor_count = src.my_initial_predecessor_count; - my_current_count = 0; - } - - //! Increments the trigger threshold - bool register_predecessor( predecessor_type & ) __TBB_override { - spin_mutex::scoped_lock l(my_mutex); - ++my_predecessor_count; - return true; - } - - //! Decrements the trigger threshold - /** 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. */ - bool remove_predecessor( predecessor_type & ) __TBB_override { - spin_mutex::scoped_lock l(my_mutex); - --my_predecessor_count; - return true; - } - -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - typedef internal::edge_container built_predecessors_type; - typedef built_predecessors_type::edge_list_type predecessor_list_type; - built_predecessors_type &built_predecessors() __TBB_override { return my_built_predecessors; } - - void internal_add_built_predecessor( predecessor_type &s) __TBB_override { - spin_mutex::scoped_lock l(my_mutex); - my_built_predecessors.add_edge( s ); - } - - void internal_delete_built_predecessor( predecessor_type &s) __TBB_override { - spin_mutex::scoped_lock l(my_mutex); - my_built_predecessors.delete_edge(s); - } - - void copy_predecessors( predecessor_list_type &v) __TBB_override { - spin_mutex::scoped_lock l(my_mutex); - my_built_predecessors.copy_edges(v); - } - - size_t predecessor_count() __TBB_override { - spin_mutex::scoped_lock l(my_mutex); - return my_built_predecessors.edge_count(); - } - -#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; - // execute body is supposed to be too small to create a task for. - task *try_put_task( const input_type & ) __TBB_override { - { - spin_mutex::scoped_lock l(my_mutex); - if ( ++my_current_count < my_predecessor_count ) - return SUCCESSFULLY_ENQUEUED; - else - my_current_count = 0; - } - task * res = execute(); - return res? res : SUCCESSFULLY_ENQUEUED; - } - -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - // continue_receiver must contain its own built_predecessors because it does - // not have a node_cache. - built_predecessors_type my_built_predecessors; -#endif - spin_mutex my_mutex; - int my_predecessor_count; - int my_current_count; - int my_initial_predecessor_count; - // the friend declaration in the base class did not eliminate the "protected class" - // error in gcc 4.1.2 - template friend class limiter_node; - - void reset_receiver( reset_flags f ) __TBB_override { - my_current_count = 0; - if (f & rf_clear_edges) { -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - my_built_predecessors.clear(); -#endif - my_predecessor_count = my_initial_predecessor_count; - } - } - - //! Does whatever should happen when the threshold is reached - /** This should be very fast or else spawn a task. This is - called while the sender is blocked in the try_put(). */ - virtual task * execute() = 0; - template friend class internal::successor_cache; - bool is_continue_receiver() __TBB_override { return true; } - -}; // class continue_receiver -} // interface9 - -#if __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING - template - K key_from_message( const T &t ) { - return t.key(); - } -#endif /* __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING */ - - using interface9::sender; - using interface9::receiver; - using interface9::continue_receiver; -} // flow -} // tbb - -#include "internal/_flow_graph_trace_impl.h" -#include "internal/_tbb_hash_compare_impl.h" - -namespace tbb { -namespace flow { -namespace interface9 { - -#include "internal/_flow_graph_impl.h" -#include "internal/_flow_graph_types_impl.h" -using namespace internal::graph_policy_namespace; - -class graph; -class graph_node; - -template -class graph_iterator { - friend class graph; - friend class graph_node; -public: - typedef size_t size_type; - typedef GraphNodeType value_type; - typedef GraphNodeType* pointer; - typedef GraphNodeType& reference; - typedef const GraphNodeType& const_reference; - typedef std::forward_iterator_tag iterator_category; - - //! Default constructor - graph_iterator() : my_graph(NULL), current_node(NULL) {} - - //! Copy constructor - graph_iterator(const graph_iterator& other) : - my_graph(other.my_graph), current_node(other.current_node) - {} - - //! Assignment - graph_iterator& operator=(const graph_iterator& other) { - if (this != &other) { - my_graph = other.my_graph; - current_node = other.current_node; - } - return *this; - } - - //! Dereference - reference operator*() const; - - //! Dereference - pointer operator->() const; - - //! Equality - bool operator==(const graph_iterator& other) const { - return ((my_graph == other.my_graph) && (current_node == other.current_node)); - } - - //! Inequality - bool operator!=(const graph_iterator& other) const { return !(operator==(other)); } - - //! Pre-increment - graph_iterator& operator++() { - internal_forward(); - return *this; - } - - //! Post-increment - graph_iterator operator++(int) { - graph_iterator result = *this; - operator++(); - return result; - } - -private: - // the graph over which we are iterating - GraphContainerType *my_graph; - // pointer into my_graph's my_nodes list - pointer current_node; - - //! Private initializing constructor for begin() and end() iterators - graph_iterator(GraphContainerType *g, bool begin); - void internal_forward(); -}; // class graph_iterator - -//! The graph class -/** This class serves as a handle to the graph */ -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() __TBB_override { - my_body(); - return NULL; - } - private: - Body my_body; - }; - - template< typename Receiver, typename Body > - class run_and_put_task : public task { - public: - run_and_put_task( Receiver &r, Body& body ) : my_receiver(r), my_body(body) {} - task *execute() __TBB_override { - task *res = my_receiver.try_put_task( my_body() ); - if (res == SUCCESSFULLY_ENQUEUED) res = NULL; - return res; - } - private: - Receiver &my_receiver; - Body my_body; - }; - typedef std::list task_list_type; - - class wait_functor { - task* graph_root_task; - public: - wait_functor( task* t ) : graph_root_task(t) {} - void operator()() const { graph_root_task->wait_for_all(); } - }; - - void prepare_task_arena( bool reinit = false ) { - if (reinit) { - __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(), "task arena is not active"); - } - -public: - //! Constructs a graph with isolated task_group_context - graph() : my_nodes(NULL), my_nodes_last(NULL), my_task_arena(NULL) { - prepare_task_arena(); - own_context = true; - cancelled = false; - caught_exception = false; - my_context = new task_group_context(); - my_root_task = ( new ( task::allocate_root(*my_context) ) empty_task ); - my_root_task->set_ref_count(1); - tbb::internal::fgt_graph( this ); - my_is_active = true; - } - - //! 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), my_task_arena(NULL) { - prepare_task_arena(); - own_context = false; - my_root_task = ( new ( task::allocate_root(*my_context) ) empty_task ); - my_root_task->set_ref_count(1); - tbb::internal::fgt_graph( this ); - my_is_active = true; - } - - //! Destroys the graph. - /** Calls wait_for_all, then destroys the root task and context. */ - ~graph() { - wait_for_all(); - my_root_task->set_ref_count(0); - task::destroy( *my_root_task ); - if (own_context) delete my_context; - delete my_task_arena; - } - -#if TBB_PREVIEW_FLOW_GRAPH_TRACE - void set_name( const char *name ) { - tbb::internal::fgt_graph_desc( this, name ); - } -#endif - - //! Used to register that an external entity may still interact with the graph. - /** The graph will not return from wait_for_all until a matching number of decrement_wait_count calls - is made. */ - void increment_wait_count() { - if (my_root_task) - my_root_task->increment_ref_count(); - } - - //! Deregisters an external entity that may have interacted with the graph. - /** The graph will not return from wait_for_all until all the number of decrement_wait_count calls - matches the number of increment_wait_count calls. */ - void decrement_wait_count() { - if (my_root_task) - 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. */ - template< typename Receiver, typename Body > - void run( Receiver &r, Body body ) { - if(is_active()) { - FLOW_SPAWN( (* new ( task::allocate_additional_child_of( *root_task() ) ) - run_and_put_task< Receiver, Body >( r, body )) ); - } - } - - //! Spawns a task that runs a function object - /** 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. */ - template< typename Body > - void run( Body body ) { - if(is_active()) { - FLOW_SPAWN( * new ( task::allocate_additional_child_of( *root_task() ) ) run_task< Body >( body ) ); - } - } - - //! Wait until graph is idle and decrement_wait_count calls equals increment_wait_count calls. - /** The waiting thread will go off and steal work while it is block in the wait_for_all. */ - void wait_for_all() { - cancelled = false; - caught_exception = false; - if (my_root_task) { -#if TBB_USE_EXCEPTIONS - try { -#endif - my_task_arena->execute(wait_functor(my_root_task)); - cancelled = my_context->is_group_execution_cancelled(); -#if TBB_USE_EXCEPTIONS - } - catch(...) { - my_root_task->set_ref_count(1); - my_context->reset(); - caught_exception = true; - cancelled = true; - throw; - } -#endif - // TODO: the "if" condition below is just a work-around to support the concurrent wait - // 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() - my_root_task->set_ref_count(1); - } - } - } - - //! Returns the root task of the graph - task * root_task() { - return my_root_task; - } - - void set_active(bool a = true) { - my_is_active = a; - } - - bool is_active() { - return my_is_active; - } - - void add_task_to_reset_list(task *tp) { - my_reset_task_list.push_back(tp); - } - - // ITERATORS - template - friend class graph_iterator; - - // Graph iterator typedefs - typedef graph_iterator iterator; - typedef graph_iterator const_iterator; - - // Graph iterator constructors - //! start iterator - iterator begin() { return iterator(this, true); } - //! end iterator - iterator end() { return iterator(this, false); } - //! start const iterator - const_iterator begin() const { return const_iterator(this, true); } - //! end const iterator - const_iterator end() const { return const_iterator(this, false); } - //! start const iterator - const_iterator cbegin() const { return const_iterator(this, true); } - //! end const iterator - const_iterator cend() const { return const_iterator(this, false); } - - //! return status of graph execution - bool is_cancelled() { return cancelled; } - bool exception_thrown() { return caught_exception; } - - // thread-unsafe state reset. - void reset(reset_flags f = rf_reset_protocol); - -private: - task *my_root_task; - task_group_context *my_context; - bool own_context; - bool cancelled; - bool caught_exception; - bool my_is_active; - task_list_type my_reset_task_list; - - graph_node *my_nodes, *my_nodes_last; - - spin_mutex nodelist_mutex; - void register_node(graph_node *n); - void remove_node(graph_node *n); - - template < typename Input, typename Output, typename Policy, typename Allocator > - friend class async_node; - task_arena* my_task_arena; -}; // class graph - -template -graph_iterator::graph_iterator(C *g, bool begin) : my_graph(g), current_node(NULL) -{ - if (begin) current_node = my_graph->my_nodes; - //else it is an end iterator by default -} - -template -typename graph_iterator::reference graph_iterator::operator*() const { - __TBB_ASSERT(current_node, "graph_iterator at end"); - return *operator->(); -} - -template -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_copy { - friend class graph; - template - friend class graph_iterator; -protected: - graph& my_graph; - graph_node *next, *prev; -public: - explicit graph_node(graph& g) : my_graph(g) { - my_graph.register_node(this); - } - virtual ~graph_node() { - my_graph.remove_node(this); - } - -#if TBB_PREVIEW_FLOW_GRAPH_TRACE - virtual void set_name( const char *name ) = 0; -#endif - -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - virtual void extract( ) = 0; -#endif - -protected: - // performs the reset on an individual node. - virtual void reset_node(reset_flags f=rf_reset_protocol) = 0; -}; // class graph_node - -inline void graph::register_node(graph_node *n) { - n->next = NULL; - { - spin_mutex::scoped_lock lock(nodelist_mutex); - n->prev = my_nodes_last; - if (my_nodes_last) my_nodes_last->next = n; - my_nodes_last = n; - if (!my_nodes) my_nodes = n; - } -} - -inline void graph::remove_node(graph_node *n) { - { - spin_mutex::scoped_lock lock(nodelist_mutex); - __TBB_ASSERT(my_nodes && my_nodes_last, "graph::remove_node: Error: no registered nodes"); - if (n->prev) n->prev->next = n->next; - if (n->next) n->next->prev = n->prev; - if (my_nodes_last == n) my_nodes_last = n->prev; - if (my_nodes == n) my_nodes = n->next; - } - n->prev = n->next = NULL; -} - -inline void graph::reset( reset_flags f ) { - // reset context - set_active(false); - if(my_context) my_context->reset(); - cancelled = false; - caught_exception = false; - // reset all the nodes comprising the graph - for(iterator ii = begin(); ii != end(); ++ii) { - graph_node *my_p = &(*ii); - my_p->reset_node(f); - } - // 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 ); - 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) { - FLOW_SPAWN(*(*rti)); - } - 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 > { -public: - //! The type of the output message, which is complete - typedef Output output_type; - - //! The type of successors of this node - typedef typename sender::successor_type successor_type; - - //Source node has no input type - typedef null_type input_type; - -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - typedef typename sender::built_successors_type built_successors_type; - typedef typename sender::successor_list_type successor_list_type; -#endif - - //! Constructor for a node with a successor - template< typename Body > - source_node( graph &g, Body body, bool is_active = true ) - : graph_node(g), my_active(is_active), init_my_active(is_active), - my_body( new internal::source_body_leaf< output_type, Body>(body) ), - my_init_body( new internal::source_body_leaf< output_type, Body>(body) ), - my_reserved(false), my_has_cached_item(false) - { - my_successors.set_owner(this); - tbb::internal::fgt_node_with_body( tbb::internal::FLOW_SOURCE_NODE, &this->my_graph, - static_cast *>(this), this->my_body ); - } - - //! Copy constructor - source_node( const source_node& src ) : - graph_node(src.my_graph), sender(), - my_active(src.init_my_active), - init_my_active(src.init_my_active), my_body( src.my_init_body->clone() ), my_init_body(src.my_init_body->clone() ), - my_reserved(false), my_has_cached_item(false) - { - my_successors.set_owner(this); - tbb::internal::fgt_node_with_body( tbb::internal::FLOW_SOURCE_NODE, &this->my_graph, - static_cast *>(this), this->my_body ); - } - - //! The destructor - ~source_node() { delete my_body; delete my_init_body; } - -#if TBB_PREVIEW_FLOW_GRAPH_TRACE - void set_name( const char *name ) __TBB_override { - tbb::internal::fgt_node_desc( this, name ); - } -#endif - - //! Add a new successor to this node - bool register_successor( successor_type &r ) __TBB_override { - spin_mutex::scoped_lock lock(my_mutex); - my_successors.register_successor(r); - if ( my_active ) - spawn_put(); - return true; - } - - //! Removes a successor from this node - bool remove_successor( successor_type &r ) __TBB_override { - spin_mutex::scoped_lock lock(my_mutex); - my_successors.remove_successor(r); - return true; - } - -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - - built_successors_type &built_successors() __TBB_override { return my_successors.built_successors(); } - - void internal_add_built_successor( successor_type &r) __TBB_override { - spin_mutex::scoped_lock lock(my_mutex); - my_successors.internal_add_built_successor(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); - } - - size_t successor_count() __TBB_override { - spin_mutex::scoped_lock lock(my_mutex); - return my_successors.successor_count(); - } - - 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 - bool try_get( output_type &v ) __TBB_override { - spin_mutex::scoped_lock lock(my_mutex); - if ( my_reserved ) - return false; - - if ( my_has_cached_item ) { - v = my_cached_item; - my_has_cached_item = false; - return true; - } - // we've been asked to provide an item, but we have none. enqueue a task to - // provide one. - spawn_put(); - return false; - } - - //! Reserves an item. - bool try_reserve( output_type &v ) __TBB_override { - spin_mutex::scoped_lock lock(my_mutex); - if ( my_reserved ) { - return false; - } - - if ( my_has_cached_item ) { - v = my_cached_item; - my_reserved = true; - return true; - } else { - return false; - } - } - - //! Release a reserved item. - /** true = item has been released and so remains in sender, dest must request or reserve future items */ - 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; - if(!my_successors.empty()) - spawn_put(); - return true; - } - - //! Consumes a reserved item - 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; - my_has_cached_item = false; - if ( !my_successors.empty() ) { - spawn_put(); - } - return true; - } - - //! Activates a node that was created in the inactive state - void activate() { - spin_mutex::scoped_lock lock(my_mutex); - my_active = true; - if ( !my_successors.empty() ) - spawn_put(); - } - - template - Body copy_function_object() { - internal::source_body &body_ref = *this->my_body; - return dynamic_cast< internal::source_body_leaf & >(body_ref).get_body(); - } - -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - 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; - if(my_has_cached_item) my_has_cached_item = false; - } -#endif - -protected: - - //! resets the source_node to its initial state - void reset_node( reset_flags f) __TBB_override { - my_active = init_my_active; - my_reserved =false; - if(my_has_cached_item) { - my_has_cached_item = false; - } - if(f & rf_clear_edges) my_successors.clear(); - if(f & rf_reset_bodies) { - internal::source_body *tmp = my_init_body->clone(); - delete my_body; - my_body = tmp; - } - if(my_active) - this->my_graph.add_task_to_reset_list(create_put_task()); - } - -private: - spin_mutex my_mutex; - bool my_active; - bool init_my_active; - internal::source_body *my_body; - internal::source_body *my_init_body; - internal::broadcast_cache< output_type > my_successors; - bool my_reserved; - bool my_has_cached_item; - output_type my_cached_item; - - // used by apply_body_bypass, can invoke body of node. - bool try_reserve_apply_body(output_type &v) { - spin_mutex::scoped_lock lock(my_mutex); - if ( my_reserved ) { - return false; - } - if ( !my_has_cached_item ) { - tbb::internal::fgt_begin_body( my_body ); - bool r = (*my_body)(my_cached_item); - tbb::internal::fgt_end_body( my_body ); - if (r) { - my_has_cached_item = true; - } - } - if ( my_has_cached_item ) { - v = my_cached_item; - my_reserved = true; - return true; - } else { - return false; - } - } - - // when resetting, and if the source_node was created with my_active == true, then - // when we reset the node we must store a task to run the node, and spawn it only - // after the reset is complete and is_active() is again true. This is why we don't - // test for is_active() here. - task* create_put_task() { - return ( new ( task::allocate_additional_child_of( *(this->my_graph.root_task()) ) ) - internal:: source_task_bypass < source_node< output_type > >( *this ) ); - } - - //! Spawns a task that applies the body - void spawn_put( ) { - if(this->my_graph.is_active()) { - FLOW_SPAWN( *create_put_task()); - } - } - - friend class internal::source_task_bypass< source_node< output_type > >; - //! Applies the body. Returning SUCCESSFULLY_ENQUEUED okay; forward_task_bypass will handle it. - task * apply_body_bypass( ) { - output_type v; - if ( !try_reserve_apply_body(v) ) - return NULL; - - task *last_task = my_successors.try_put_task(v); - if ( last_task ) - try_consume(); - else - try_release(); - return last_task; - } -}; // class source_node - -template -struct allocate_buffer { - static const bool value = false; -}; - -template<> -struct allocate_buffer { - static const bool value = true; -}; - -//! Implements a function node that supports Input -> Output -template < typename Input, typename Output = continue_msg, typename Policy = queueing, typename Allocator=cache_aligned_allocator > -class function_node : public graph_node, public internal::function_input, public internal::function_output { -public: - typedef Input input_type; - typedef Output output_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; -#endif - using fInput_type::my_predecessors; - - //! Constructor - // input_queue_type is allocated here, but destroyed in the function_input_base. - // TODO: pass the graph_buffer_policy to the function_input_base so it can all - // be done in one place. This would be an interface-breaking change. - template< typename Body > - 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->my_graph, - static_cast *>(this), static_cast *>(this), this->my_body ); - } - - //! Copy constructor - function_node( const function_node& src ) : - 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->my_graph, - static_cast *>(this), static_cast *>(this), this->my_body ); - } - -#if TBB_PREVIEW_FLOW_GRAPH_TRACE - void set_name( const char *name ) __TBB_override { - tbb::internal::fgt_node_desc( this, name ); - } -#endif - -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - void extract( ) __TBB_override { - my_predecessors.built_predecessors().receiver_extract(*this); - successors().built_successors().sender_extract(*this); - } -#endif - -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; - using fInput_type::try_put_task; - - internal::broadcast_cache &successors () __TBB_override { return fOutput_type::my_successors; } - - void reset_node(reset_flags f) __TBB_override { - fInput_type::reset_function_input(f); - // TODO: use clear() instead. - if(f & rf_clear_edges) { - successors().clear(); - my_predecessors.clear(); - } - __TBB_ASSERT(!(f & rf_clear_edges) || successors().empty(), "function_node successors not empty"); - __TBB_ASSERT(this->my_predecessors.empty(), "function_node predecessors not empty"); - } - -}; // 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 > -class multifunction_node : - public graph_node, - public internal::multifunction_input - < - Input, - typename internal::wrap_tuple_elements< - tbb::flow::tuple_size::value, // #elements in tuple - internal::multifunction_output, // wrap this around each element - Output // the tuple providing the types - >::type, - Allocator - > { -protected: - static const int N = tbb::flow::tuple_size::value; -public: - typedef Input input_type; - typedef null_type output_type; - typedef typename internal::wrap_tuple_elements::type output_ports_type; - typedef internal::multifunction_input fInput_type; - typedef internal::function_input_queue input_queue_type; -private: - typedef typename internal::multifunction_input base_type; - using fInput_type::my_predecessors; -public: - template - 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->my_graph, static_cast *>(this), - this->output_ports(), this->my_body ); - } - - multifunction_node( const multifunction_node &other) : - 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->my_graph, static_cast *>(this), - this->output_ports(), this->my_body ); - } - -#if TBB_PREVIEW_FLOW_GRAPH_TRACE - 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( ) __TBB_override { - my_predecessors.built_predecessors().receiver_extract(*this); - base_type::extract(); - } -#endif - // all the guts are in multifunction_input... -protected: - 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 it does not reject inputs. -template > -class split_node : public graph_node, public receiver { - static const int N = tbb::flow::tuple_size::value; - typedef receiver base_type; -public: - typedef TupleType input_type; - typedef Allocator allocator_type; -#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 - - 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 - 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 { -public: - typedef continue_msg input_type; - typedef Output output_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 - continue_node( graph &g, Body body ) : - graph_node(g), internal::continue_input( g, body ) { - tbb::internal::fgt_node_with_body( tbb::internal::FLOW_CONTINUE_NODE, &this->my_graph, - static_cast *>(this), - static_cast *>(this), this->my_body ); - } - - - //! Constructor for executable node with continue_msg -> Output - template - continue_node( graph &g, int number_of_predecessors, Body body ) : - graph_node(g), internal::continue_input( g, number_of_predecessors, body ) { - tbb::internal::fgt_node_with_body( tbb::internal::FLOW_CONTINUE_NODE, &this->my_graph, - static_cast *>(this), - static_cast *>(this), this->my_body ); - } - - //! Copy constructor - continue_node( const continue_node& 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), - static_cast *>(this), this->my_body ); - } - -#if TBB_PREVIEW_FLOW_GRAPH_TRACE - void set_name( const char *name ) __TBB_override { - tbb::internal::fgt_node_desc( this, name ); - } -#endif - -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - void extract() __TBB_override { - fInput_type::my_built_predecessors.receiver_extract(*this); - successors().built_successors().sender_extract(*this); - } -#endif - -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; - using fInput_type::try_put_task; - internal::broadcast_cache &successors () __TBB_override { return fOutput_type::my_successors; } - - 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 { -public: - typedef T input_type; - typedef T output_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 - - 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) ); - } - - // Copy constructor; doesn't take anything from src; default won't work - overwrite_node( const overwrite_node& src ) : - graph_node(src.my_graph), receiver(), sender(), 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) ); - } - - ~overwrite_node() {} - -#if TBB_PREVIEW_FLOW_GRAPH_TRACE - void set_name( const char *name ) __TBB_override { - tbb::internal::fgt_node_desc( this, name ); - } -#endif - - 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. - if ( s.try_put( my_buffer ) || !s.register_predecessor( *this ) ) { - // We add the successor: it accepted our put or it rejected it but won't let us become a predecessor - my_successors.register_successor( s ); - } else { - // We don't add the successor: it rejected our put and we became its predecessor instead - return false; - } - } else { - // No valid value yet, just add as successor - my_successors.register_successor( s ); - } - return true; - } - - 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 - built_predecessors_type &built_predecessors() __TBB_override { return my_built_predecessors; } - built_successors_type &built_successors() __TBB_override { return my_successors.built_successors(); } - - void internal_add_built_successor( successor_type &s) __TBB_override { - spin_mutex::scoped_lock l( my_mutex ); - my_successors.internal_add_built_successor(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); - } - - size_t successor_count() __TBB_override { - spin_mutex::scoped_lock l( my_mutex ); - return my_successors.successor_count(); - } - - void copy_successors(successor_list_type &v) __TBB_override { - spin_mutex::scoped_lock l( my_mutex ); - my_successors.copy_successors(v); - } - - void internal_add_built_predecessor( predecessor_type &p) __TBB_override { - spin_mutex::scoped_lock l( my_mutex ); - my_built_predecessors.add_edge(p); - } - - void internal_delete_built_predecessor( predecessor_type &p) __TBB_override { - spin_mutex::scoped_lock l( my_mutex ); - my_built_predecessors.delete_edge(p); - } - - size_t predecessor_count() __TBB_override { - spin_mutex::scoped_lock l( my_mutex ); - return my_built_predecessors.edge_count(); - } - - void copy_predecessors(predecessor_list_type &v) __TBB_override { - spin_mutex::scoped_lock l( my_mutex ); - my_built_predecessors.copy_edges(v); - } - - void extract() __TBB_override { - my_buffer_is_valid = false; - built_successors().sender_extract(*this); - built_predecessors().receiver_extract(*this); - } - -#endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */ - - bool try_get( input_type &v ) __TBB_override { - spin_mutex::scoped_lock l( my_mutex ); - if ( my_buffer_is_valid ) { - v = my_buffer; - return true; - } - return false; - } - - bool is_valid() { - spin_mutex::scoped_lock l( my_mutex ); - return my_buffer_is_valid; - } - - void clear() { - spin_mutex::scoped_lock l( my_mutex ); - my_buffer_is_valid = false; - } - -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 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); - if (!rtask) rtask = SUCCESSFULLY_ENQUEUED; - return rtask; - } - - spin_mutex my_mutex; - internal::broadcast_cache< input_type, null_rw_mutex > my_successors; -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - internal::edge_container my_built_predecessors; -#endif - input_type my_buffer; - bool my_buffer_is_valid; - void reset_receiver(reset_flags /*f*/) __TBB_override {} - - void reset_node( reset_flags f) __TBB_override { - my_buffer_is_valid = false; - if (f&rf_clear_edges) { - my_successors.clear(); - } - } -}; // overwrite_node - -template< typename T > -class write_once_node : public overwrite_node { -public: - typedef T input_type; - typedef T output_type; - typedef typename receiver::predecessor_type predecessor_type; - typedef typename sender::successor_type successor_type; - - //! Constructor - 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) ); - } - - //! Copy constructor: call base class copy constructor - write_once_node( const write_once_node& src ) : overwrite_node(src) { - tbb::internal::fgt_node( tbb::internal::FLOW_WRITE_ONCE_NODE, &(this->my_graph), - static_cast *>(this), - static_cast *>(this) ); - } - -#if TBB_PREVIEW_FLOW_GRAPH_TRACE - void set_name( const char *name ) __TBB_override { - tbb::internal::fgt_node_desc( this, name ); - } -#endif - -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 ) __TBB_override { - spin_mutex::scoped_lock l( this->my_mutex ); - 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 { -public: - typedef T input_type; - typedef T output_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; -#endif -private: - internal::broadcast_cache my_successors; -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - internal::edge_container my_built_predecessors; - spin_mutex pred_mutex; // serialize accesses on edge_container -#endif -public: - - 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) ); - } - - // Copy constructor - broadcast_node( const broadcast_node& src ) : - graph_node(src.my_graph), receiver(), sender() - { - my_successors.set_owner( this ); - tbb::internal::fgt_node( tbb::internal::FLOW_BROADCAST_NODE, &this->my_graph, - static_cast *>(this), static_cast *>(this) ); - } - -#if TBB_PREVIEW_FLOW_GRAPH_TRACE - void set_name( const char *name ) __TBB_override { - tbb::internal::fgt_node_desc( this, name ); - } -#endif - - //! Adds a successor - bool register_successor( successor_type &r ) __TBB_override { - my_successors.register_successor( r ); - return true; - } - - //! Removes s as a successor - bool remove_successor( successor_type &r ) __TBB_override { - my_successors.remove_successor( r ); - return true; - } - -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - typedef typename sender::built_successors_type built_successors_type; - - built_successors_type &built_successors() __TBB_override { return my_successors.built_successors(); } - - void internal_add_built_successor(successor_type &r) __TBB_override { - my_successors.internal_add_built_successor(r); - } - - void internal_delete_built_successor(successor_type &r) __TBB_override { - my_successors.internal_delete_built_successor(r); - } - - size_t successor_count() __TBB_override { - return my_successors.successor_count(); - } - - void copy_successors(successor_list_type &v) __TBB_override { - my_successors.copy_successors(v); - } - - typedef typename receiver::built_predecessors_type built_predecessors_type; - - built_predecessors_type &built_predecessors() __TBB_override { return my_built_predecessors; } - - void internal_add_built_predecessor( predecessor_type &p) __TBB_override { - spin_mutex::scoped_lock l(pred_mutex); - my_built_predecessors.add_edge(p); - } - - void internal_delete_built_predecessor( predecessor_type &p) __TBB_override { - spin_mutex::scoped_lock l(pred_mutex); - my_built_predecessors.delete_edge(p); - } - - size_t predecessor_count() __TBB_override { - spin_mutex::scoped_lock l(pred_mutex); - return my_built_predecessors.edge_count(); - } - - void copy_predecessors(predecessor_list_type &v) __TBB_override { - spin_mutex::scoped_lock l(pred_mutex); - my_built_predecessors.copy_edges(v); - } - - void extract() __TBB_override { - my_built_predecessors.receiver_extract(*this); - my_successors.built_successors().sender_extract(*this); - } -#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; - //! build a task to run the successor if possible. Default is old behavior. - 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; - } - - void reset_receiver(reset_flags /*f*/) __TBB_override {} - - void reset_node(reset_flags f) __TBB_override { - if (f&rf_clear_edges) { - my_successors.clear(); -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - my_built_predecessors.clear(); -#endif - } - __TBB_ASSERT(!(f & rf_clear_edges) || my_successors.empty(), "Error resetting broadcast_node"); - } -}; // broadcast_node - -//! Forwards messages in arbitrary order -template > -class buffer_node : public graph_node, public internal::reservable_item_buffer, public receiver, public sender { -public: - typedef T input_type; - typedef T output_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; - typedef typename sender::successor_list_type successor_list_type; -#endif -protected: - typedef size_t size_type; - internal::round_robin_cache< T, null_rw_mutex > my_successors; - -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - internal::edge_container my_built_predecessors; -#endif - - friend class internal::forward_task_bypass< buffer_node< T, A > >; - - enum op_type {reg_succ, rem_succ, req_item, res_item, rel_res, con_res, put_item, try_fwd_task -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - , add_blt_succ, del_blt_succ, - add_blt_pred, del_blt_pred, - blt_succ_cnt, blt_pred_cnt, - blt_succ_cpy, blt_pred_cpy // create vector copies of preds and succs -#endif - }; - - // implements the aggregator_operation concept - class buffer_operation : public internal::aggregated_operation< buffer_operation > { - public: - char type; -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - task * ltask; - union { - input_type *elem; - successor_type *r; - predecessor_type *p; - size_t cnt_val; - successor_list_type *svec; - predecessor_list_type *pvec; - }; -#else - T *elem; - task * ltask; - successor_type *r; -#endif - buffer_operation(const T& e, op_type t) : type(char(t)) - -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - , ltask(NULL), elem(const_cast(&e)) -#else - , elem(const_cast(&e)) , ltask(NULL) -#endif - {} - buffer_operation(op_type t) : type(char(t)), ltask(NULL) {} - }; - - bool forwarder_busy; - typedef internal::aggregating_functor handler_type; - friend class internal::aggregating_functor; - 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; - 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 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: try_forwarding = internal_push(tmp); break; - case try_fwd_task: internal_forward_task(tmp); break; -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - // edge recording - case add_blt_succ: internal_add_built_succ(tmp); break; - case del_blt_succ: internal_del_built_succ(tmp); break; - case add_blt_pred: internal_add_built_pred(tmp); break; - case del_blt_pred: internal_del_built_pred(tmp); break; - case blt_succ_cnt: internal_succ_cnt(tmp); break; - case blt_pred_cnt: internal_pred_cnt(tmp); break; - case blt_succ_cpy: internal_copy_succs(tmp); break; - case blt_pred_cpy: internal_copy_preds(tmp); break; -#endif - } - } - - derived->order(); - - if (try_forwarding && !forwarder_busy) { - if(this->my_graph.is_active()) { - 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 *z = tmp->ltask; - tmp->ltask = combine_tasks(z, new_task); // in case the op generated a task - } - } - } // handle_operations - - inline task *grab_forwarding_task( buffer_operation &op_data) { - return op_data.ltask; - } - - inline bool enqueue_forwarding_task(buffer_operation &op_data) { - task *ft = grab_forwarding_task(op_data); - if(ft) { - FLOW_SPAWN(*ft); - return true; - } - return false; - } - - //! This is executed by an enqueued task, the "forwarder" - virtual task *forward_task() { - buffer_operation op_data(try_fwd_task); - task *last_task = NULL; - do { - 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 ==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, internal::SUCCEEDED); - } - - //! Remove successor - virtual void internal_rem_succ(buffer_operation *op) { - my_successors.remove_successor(*(op->r)); - __TBB_store_with_release(op->status, internal::SUCCEEDED); - } - -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - typedef typename sender::built_successors_type built_successors_type; - - 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, 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, internal::SUCCEEDED); - } - - typedef typename receiver::built_predecessors_type built_predecessors_type; - - 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, internal::SUCCEEDED); - } - - virtual void internal_del_built_pred(buffer_operation *op) { - my_built_predecessors.delete_edge(*(op->p)); - __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, internal::SUCCEEDED); - } - - virtual void internal_pred_cnt(buffer_operation *op) { - op->cnt_val = my_built_predecessors.edge_count(); - __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, internal::SUCCEEDED); - } - - virtual void internal_copy_preds(buffer_operation *op) { - my_built_predecessors.copy_edges(*(op->pvec)); - __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) { - 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; - } - // Try forwarding, giving each successor a chance - task * last_task = NULL; - size_type counter = my_successors.size(); - 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, internal::SUCCEEDED); - } - else { - __TBB_store_with_release(op->status, internal::FAILED); - forwarder_busy = false; - } - } - - virtual bool internal_push(buffer_operation *op) { - this->push_back(*(op->elem)); - __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, internal::SUCCEEDED); - } - else { - __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, internal::SUCCEEDED); - } - else { - __TBB_store_with_release(op->status, internal::FAILED); - } - } - - virtual void internal_consume(buffer_operation *op) { - this->consume_front(); - __TBB_store_with_release(op->status, internal::SUCCEEDED); - } - - virtual void internal_release(buffer_operation *op) { - this->release_front(); - __TBB_store_with_release(op->status, internal::SUCCEEDED); - } - -public: - //! Constructor - 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)); - tbb::internal::fgt_node( tbb::internal::FLOW_BUFFER_NODE, &this->my_graph, - static_cast *>(this), static_cast *>(this) ); - } - - //! Copy constructor - buffer_node( const buffer_node& src ) : graph_node(src.my_graph), - internal::reservable_item_buffer(), receiver(), sender() { - forwarder_busy = false; - my_successors.set_owner(this); - my_aggregator.initialize_handler(handler_type(this)); - tbb::internal::fgt_node( tbb::internal::FLOW_BUFFER_NODE, &this->my_graph, - static_cast *>(this), static_cast *>(this) ); - } - -#if TBB_PREVIEW_FLOW_GRAPH_TRACE - void set_name( const char *name ) __TBB_override { - tbb::internal::fgt_node_desc( this, name ); - } -#endif - - // - // message sender implementation - // - - //! Adds a new successor. - /** Adds successor r to the list of successors; may forward tasks. */ - bool register_successor( successor_type &r ) __TBB_override { - buffer_operation op_data(reg_succ); - op_data.r = &r; - my_aggregator.execute(&op_data); - (void)enqueue_forwarding_task(op_data); - return true; - } - -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - 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); - } - - 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); - } - - 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); - } - - 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); - } - - size_t predecessor_count() __TBB_override { - buffer_operation op_data(blt_pred_cnt); - my_aggregator.execute(&op_data); - return op_data.cnt_val; - } - - size_t successor_count() __TBB_override { - buffer_operation op_data(blt_succ_cnt); - my_aggregator.execute(&op_data); - return op_data.cnt_val; - } - - 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); - } - - 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); - } - -#endif - - //! 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. */ - bool remove_successor( successor_type &r ) __TBB_override { - r.remove_predecessor(*this); - buffer_operation op_data(rem_succ); - op_data.r = &r; - my_aggregator.execute(&op_data); - // even though this operation does not cause a forward, if we are the handler, and - // a forward is scheduled, we may be the first to reach this point after the aggregator, - // and so should check for the task. - (void)enqueue_forwarding_task(op_data); - return true; - } - - //! Request an item from the buffer_node - /** true = v contains the returned item
    - false = no item has been returned */ - 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==internal::SUCCEEDED); - } - - //! Reserves an item. - /** false = no item can be reserved
    - true = an item is reserved */ - 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==internal::SUCCEEDED); - } - - //! Release a reserved item. - /** true = item has been released and so remains in sender */ - bool try_release() __TBB_override { - buffer_operation op_data(rel_res); - my_aggregator.execute(&op_data); - (void)enqueue_forwarding_task(op_data); - return true; - } - - //! Consumes a reserved item. - /** true = item is removed from sender and reservation removed */ - bool try_consume() __TBB_override { - buffer_operation op_data(con_res); - my_aggregator.execute(&op_data); - (void)enqueue_forwarding_task(op_data); - return true; - } - -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; - //! receive an item, return a task *if possible - 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 ==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 ==internal::SUCCEEDED) { - ft = SUCCESSFULLY_ENQUEUED; - } - return ft; - } - - void reset_receiver(reset_flags /*f*/) __TBB_override { } - -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES -public: - void extract() __TBB_override { - my_built_predecessors.receiver_extract(*this); - my_successors.built_successors().sender_extract(*this); - } -#endif - -protected: - void reset_node( reset_flags f) __TBB_override { - internal::reservable_item_buffer::reset(); - // TODO: just clear structures - if (f&rf_clear_edges) { - my_successors.clear(); -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - my_built_predecessors.clear(); -#endif - } - forwarder_busy = false; - } -}; // buffer_node - -//! Forwards messages in FIFO order -template > -class queue_node : public buffer_node { -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; - -private: - template friend class buffer_node; - - 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(); - } - } - -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, internal::FAILED); - } - else { - this->pop_front(*(op->elem)); - __TBB_store_with_release(op->status, internal::SUCCEEDED); - } - } - 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, internal::FAILED); - } - else { - this->reserve_front(*(op->elem)); - __TBB_store_with_release(op->status, internal::SUCCEEDED); - } - } - void internal_consume(queue_operation *op) __TBB_override { - this->consume_front(); - __TBB_store_with_release(op->status, internal::SUCCEEDED); - } - -public: - typedef T input_type; - typedef T output_type; - typedef typename receiver::predecessor_type predecessor_type; - typedef typename sender::successor_type successor_type; - - //! Constructor - 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) ); - } - - //! Copy constructor - queue_node( const queue_node& src) : base_type(src) { - tbb::internal::fgt_node( tbb::internal::FLOW_QUEUE_NODE, &(this->my_graph), - static_cast *>(this), - static_cast *>(this) ); - } - -#if TBB_PREVIEW_FLOW_GRAPH_TRACE - void set_name( const char *name ) __TBB_override { - tbb::internal::fgt_node_desc( this, name ); - } -#endif - -protected: - void reset_node( reset_flags f) __TBB_override { - base_type::reset_node(f); - } -}; // queue_node - -//! Forwards messages in sequence order -template< typename T, typename A=cache_aligned_allocator > -class sequencer_node : public queue_node { - internal::function_body< T, size_t > *my_sequencer; - // my_sequencer should be a benign function and must be callable - // from a parallel context. Does this mean it needn't be reset? -public: - typedef T input_type; - typedef T output_type; - typedef typename receiver::predecessor_type predecessor_type; - typedef typename sender::successor_type successor_type; - - //! Constructor - template< typename Sequencer > - sequencer_node( graph &g, const Sequencer& s ) : queue_node(g), - my_sequencer(new internal::function_body_leaf< T, size_t, Sequencer>(s) ) { - tbb::internal::fgt_node( tbb::internal::FLOW_SEQUENCER_NODE, &(this->my_graph), - static_cast *>(this), - static_cast *>(this) ); - } - - //! Copy constructor - sequencer_node( const sequencer_node& src ) : queue_node(src), - my_sequencer( src.my_sequencer->clone() ) { - tbb::internal::fgt_node( tbb::internal::FLOW_SEQUENCER_NODE, &(this->my_graph), - static_cast *>(this), - static_cast *>(this) ); - } - - //! Destructor - ~sequencer_node() { delete my_sequencer; } - -#if TBB_PREVIEW_FLOW_GRAPH_TRACE - void set_name( const char *name ) __TBB_override { - tbb::internal::fgt_node_desc( this, name ); - } -#endif - -protected: - typedef typename buffer_node::size_type size_type; - typedef typename buffer_node::buffer_operation sequencer_operation; - -private: - 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) { - // have already emitted a message with this tag - __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()) { - this->grow_my_array(this->size(new_tail)); - } - this->my_tail = new_tail; - - 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 - -//! Forwards messages in priority order -template< typename T, typename Compare = std::less, typename A=cache_aligned_allocator > -class priority_queue_node : public buffer_node { -public: - typedef T input_type; - typedef T output_type; - typedef buffer_node base_type; - typedef priority_queue_node class_type; - typedef typename receiver::predecessor_type predecessor_type; - typedef typename sender::successor_type successor_type; - - //! Constructor - 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) ); - } - - //! Copy constructor - priority_queue_node( const priority_queue_node &src ) : buffer_node(src), mark(0) { - tbb::internal::fgt_node( tbb::internal::FLOW_PRIORITY_QUEUE_NODE, &(this->my_graph), - static_cast *>(this), - static_cast *>(this) ); - } - -#if TBB_PREVIEW_FLOW_GRAPH_TRACE - void set_name( const char *name ) __TBB_override { - tbb::internal::fgt_node_desc( this, name ); - } -#endif - -protected: - - void reset_node( reset_flags f) __TBB_override { - mark = 0; - base_type::reset_node(f); - } - - typedef typename buffer_node::size_type size_type; - typedef typename buffer_node::item_type item_type; - typedef typename buffer_node::buffer_operation prio_operation; - - //! Tries to forward valid items to successors - void internal_forward_task(prio_operation *op) __TBB_override { - this->internal_forward_task_impl(op, this); - } - - 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, internal::SUCCEEDED); - return true; - } - - 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, internal::FAILED); - return; - } - - *(op->elem) = prio(); - __TBB_store_with_release(op->status, internal::SUCCEEDED); - prio_pop(); - - } - - // pops the highest-priority item, saves copy - void internal_reserve(prio_operation *op) __TBB_override { - if (this->my_reserved == true || this->my_tail == 0) { - __TBB_store_with_release(op->status, internal::FAILED); - return; - } - this->my_reserved = true; - *(op->elem) = prio(); - reserved_item = *(op->elem); - __TBB_store_with_release(op->status, internal::SUCCEEDED); - prio_pop(); - } - - void internal_consume(prio_operation *op) __TBB_override { - __TBB_store_with_release(op->status, internal::SUCCEEDED); - this->my_reserved = false; - reserved_item = input_type(); - } - - 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; - - input_type reserved_item; - - // in case a reheap has not been done after a push, check if the mark item is higher than the 0'th item - bool prio_use_tail() { - __TBB_ASSERT(mark <= this->my_tail, "mark outside bounds before test"); - return mark < this->my_tail && compare(this->get_my_item(0), this->get_my_item(this->my_tail - 1)); - } - - // prio_push: checks that the item will fit, expand array if necessary, put at end - void prio_push(const T &src) { - if ( this->my_tail >= this->my_array_size ) - this->grow_my_array( this->my_tail + 1 ); - (void) this->place_item(this->my_tail, src); - ++(this->my_tail); - __TBB_ASSERT(mark < this->my_tail, "mark outside bounds after push"); - } - - // prio_pop: deletes highest priority item from the array, and if it is item - // 0, move last item to 0 and reheap. If end of array, just destroy and decrement tail - // and mark. Assumes the array has already been tested for emptiness; no failure. - void prio_pop() { - if (prio_use_tail()) { - // there are newly pushed elements; last one higher than top - // copy the data - this->destroy_item(this->my_tail-1); - --(this->my_tail); - __TBB_ASSERT(mark <= this->my_tail, "mark outside bounds after pop"); - return; - } - this->destroy_item(0); - if(this->my_tail > 1) { - // push the last element down heap - __TBB_ASSERT(this->my_item_valid(this->my_tail - 1), NULL); - this->move_item(0,this->my_tail - 1); - } - --(this->my_tail); - if(mark > this->my_tail) --mark; - if (this->my_tail > 1) // don't reheap for heap of size 1 - reheap(); - __TBB_ASSERT(mark <= this->my_tail, "mark outside bounds after pop"); - } - - const T& prio() { - return this->get_my_item(prio_use_tail() ? this->my_tail-1 : 0); - } - - // turn array into heap - void heapify() { - if(this->my_tail == 0) { - mark = 0; - return; - } - if (!mark) mark = 1; - for (; markmy_tail; ++mark) { // for each unheaped element - size_type cur_pos = mark; - input_type to_place; - this->fetch_item(mark,to_place); - do { // push to_place up the heap - size_type parent = (cur_pos-1)>>1; - if (!compare(this->get_my_item(parent), to_place)) - break; - this->move_item(cur_pos, parent); - cur_pos = parent; - } while( cur_pos ); - (void) this->place_item(cur_pos, to_place); - } - } - - // otherwise heapified array with new root element; rearrange to heap - void reheap() { - size_type cur_pos=0, child=1; - while (child < mark) { - size_type target = child; - if (child+1get_my_item(child), - this->get_my_item(child+1))) - ++target; - // target now has the higher priority child - if (compare(this->get_my_item(target), - this->get_my_item(cur_pos))) - break; - // swap - this->swap_items(cur_pos, target); - cur_pos = target; - child = (cur_pos<<1)+1; - } - } -}; // priority_queue_node - -//! Forwards messages only if the threshold has not been reached -/** This node forwards items until its threshold is reached. - It contains no buffering. If the downstream node rejects, the - message is dropped. */ -template< typename T > -class limiter_node : public graph_node, public receiver< T >, public sender< T > { -public: - typedef T input_type; - typedef T output_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; - size_t my_count; //number of successful puts - size_t my_tries; //number of active put attempts - internal::reservable_predecessor_cache< T, spin_mutex > my_predecessors; - spin_mutex my_mutex; - internal::broadcast_cache< T > my_successors; - int init_decrement_predecessors; - - friend class internal::forward_task_bypass< limiter_node >; - - // Let decrementer call decrement_counter() - friend class internal::decrementer< limiter_node >; - - bool check_conditions() { // always called under lock - return ( my_count + my_tries < my_threshold && !my_predecessors.empty() && !my_successors.empty() ); - } - - // only returns a valid task pointer or NULL, never SUCCESSFULLY_ENQUEUED - task *forward_task() { - input_type v; - task *rval = NULL; - bool reserved = false; - { - spin_mutex::scoped_lock lock(my_mutex); - if ( check_conditions() ) - ++my_tries; - else - return NULL; - } - - //SUCCESS - // 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; - if ( (rval = my_successors.try_put_task(v)) != NULL ){ - { - spin_mutex::scoped_lock lock(my_mutex); - ++my_count; - --my_tries; - my_predecessors.try_consume(); - if ( check_conditions() ) { - if ( this->my_graph.is_active() ) { - task *rtask = new ( task::allocate_additional_child_of( *(this->my_graph.root_task()) ) ) - internal::forward_task_bypass< limiter_node >( *this ); - FLOW_SPAWN (*rtask); - } - } - } - return rval; - } - } - //FAILURE - //if we can't reserve, we decrement the tries - //if we can reserve but can't put, we decrement the tries and release the reservation - { - spin_mutex::scoped_lock lock(my_mutex); - --my_tries; - if (reserved) my_predecessors.try_release(); - if ( check_conditions() ) { - if ( this->my_graph.is_active() ) { - task *rtask = new ( task::allocate_additional_child_of( *(this->my_graph.root_task()) ) ) - internal::forward_task_bypass< limiter_node >( *this ); - __TBB_ASSERT(!rval, "Have two tasks to handle"); - return rtask; - } - } - return rval; - } - } - - void forward() { - __TBB_ASSERT(false, "Should never be called"); - return; - } - - task * decrement_counter() { - { - spin_mutex::scoped_lock lock(my_mutex); - if(my_count) --my_count; - } - return forward_task(); - } - -public: - //! The internal receiver< continue_msg > that decrements the count - internal::decrementer< limiter_node > decrement; - - //! Constructor - limiter_node(graph &g, size_t threshold, int num_decrement_predecessors=0) : - graph_node(g), my_threshold(threshold), my_count(0), my_tries(0), - init_decrement_predecessors(num_decrement_predecessors), - decrement(num_decrement_predecessors) - { - my_predecessors.set_owner(this); - my_successors.set_owner(this); - decrement.set_owner(this); - tbb::internal::fgt_node( tbb::internal::FLOW_LIMITER_NODE, &this->my_graph, - static_cast *>(this), static_cast *>(&decrement), - static_cast *>(this) ); - } - - //! Copy constructor - limiter_node( const limiter_node& src ) : - graph_node(src.my_graph), receiver(), sender(), - my_threshold(src.my_threshold), my_count(0), my_tries(0), - init_decrement_predecessors(src.init_decrement_predecessors), - decrement(src.init_decrement_predecessors) - { - my_predecessors.set_owner(this); - my_successors.set_owner(this); - decrement.set_owner(this); - tbb::internal::fgt_node( tbb::internal::FLOW_LIMITER_NODE, &this->my_graph, - static_cast *>(this), static_cast *>(&decrement), - static_cast *>(this) ); - } - -#if TBB_PREVIEW_FLOW_GRAPH_TRACE - void set_name( const char *name ) __TBB_override { - tbb::internal::fgt_node_desc( this, name ); - } -#endif - - //! Replace the current successor with this new successor - 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); - //spawn a forward task if this is the only successor - if ( was_empty && !my_predecessors.empty() && my_count + my_tries < my_threshold ) { - if ( this->my_graph.is_active() ) { - FLOW_SPAWN( (* new ( task::allocate_additional_child_of( *(this->my_graph.root_task()) ) ) - internal::forward_task_bypass < limiter_node >( *this ) ) ); - } - } - return true; - } - - //! Removes a successor from this node - /** r.remove_predecessor(*this) is also called. */ - 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 - built_successors_type &built_successors() __TBB_override { return my_successors.built_successors(); } - built_predecessors_type &built_predecessors() __TBB_override { return my_predecessors.built_predecessors(); } - - void internal_add_built_successor(successor_type &src) __TBB_override { - my_successors.internal_add_built_successor(src); - } - - void internal_delete_built_successor(successor_type &src) __TBB_override { - my_successors.internal_delete_built_successor(src); - } - - size_t successor_count() __TBB_override { return my_successors.successor_count(); } - - void copy_successors(successor_list_type &v) __TBB_override { - my_successors.copy_successors(v); - } - - void internal_add_built_predecessor(predecessor_type &src) __TBB_override { - my_predecessors.internal_add_built_predecessor(src); - } - - void internal_delete_built_predecessor(predecessor_type &src) __TBB_override { - my_predecessors.internal_delete_built_predecessor(src); - } - - size_t predecessor_count() __TBB_override { return my_predecessors.predecessor_count(); } - - void copy_predecessors(predecessor_list_type &v) __TBB_override { - my_predecessors.copy_predecessors(v); - } - - void extract() __TBB_override { - my_count = 0; - my_successors.built_successors().sender_extract(*this); - my_predecessors.built_predecessors().receiver_extract(*this); - decrement.built_predecessors().receiver_extract(decrement); - } -#endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */ - - //! Adds src to the list of cached predecessors. - 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() ) { - FLOW_SPAWN( (* new ( task::allocate_additional_child_of( *(this->my_graph.root_task()) ) ) - internal::forward_task_bypass < limiter_node >( *this ) ) ); - } - return true; - } - - //! Removes src from the list of cached predecessors. - bool remove_predecessor( predecessor_type &src ) __TBB_override { - my_predecessors.remove( src ); - return true; - } - -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; - //! Puts an item to this receiver - task *try_put_task( const T &t ) __TBB_override { - { - spin_mutex::scoped_lock lock(my_mutex); - if ( my_count + my_tries >= my_threshold ) - return NULL; - else - ++my_tries; - } - - task * rtask = my_successors.try_put_task(t); - - if ( !rtask ) { // try_put_task failed. - spin_mutex::scoped_lock lock(my_mutex); - --my_tries; - if ( check_conditions() && this->my_graph.is_active() ) { - rtask = new ( task::allocate_additional_child_of( *(this->my_graph.root_task()) ) ) - internal::forward_task_bypass< limiter_node >( *this ); - } - } - else { - spin_mutex::scoped_lock lock(my_mutex); - ++my_count; - --my_tries; - } - return rtask; - } - - void reset_receiver(reset_flags /*f*/) __TBB_override { - __TBB_ASSERT(false,NULL); // should never be called - } - - void reset_node( reset_flags f) __TBB_override { - my_count = 0; - if(f & rf_clear_edges) { - my_predecessors.clear(); - my_successors.clear(); - } - else - { - my_predecessors.reset( ); - } - decrement.reset_receiver(f); - } -}; // limiter_node - -#include "internal/_flow_graph_join_impl.h" - -using internal::reserving_port; -using internal::queueing_port; -using internal::key_matching_port; -using internal::input_port; -using internal::tag_value; - -template class join_node; - -template -class join_node: public internal::unfolded_join_node::value, reserving_port, OutputTuple, reserving> { -private: - static const int N = tbb::flow::tuple_size::value; - typedef typename internal::unfolded_join_node unfolded_type; -public: - typedef OutputTuple output_type; - typedef typename unfolded_type::input_ports_type input_ports_type; - 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) ); - } - join_node(const join_node &other) : unfolded_type(other) { - tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_JOIN_NODE_RESERVING, &this->my_graph, - this->input_ports(), static_cast< sender< output_type > *>(this) ); - } - -#if TBB_PREVIEW_FLOW_GRAPH_TRACE - void set_name( const char *name ) __TBB_override { - tbb::internal::fgt_node_desc( this, name ); - } -#endif - -}; - -template -class join_node: public internal::unfolded_join_node::value, queueing_port, OutputTuple, queueing> { -private: - static const int N = tbb::flow::tuple_size::value; - typedef typename internal::unfolded_join_node unfolded_type; -public: - typedef OutputTuple output_type; - typedef typename unfolded_type::input_ports_type input_ports_type; - 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) ); - } - join_node(const join_node &other) : unfolded_type(other) { - tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_JOIN_NODE_QUEUEING, &this->my_graph, - this->input_ports(), static_cast< sender< output_type > *>(this) ); - } - -#if TBB_PREVIEW_FLOW_GRAPH_TRACE - void set_name( const char *name ) __TBB_override { - tbb::internal::fgt_node_desc( this, name ); - } -#endif - -}; - -// template for key_matching join_node -// tag_matching join_node is a specialization of key_matching, and is source-compatible. -template -class join_node > : public internal::unfolded_join_node::value, - key_matching_port, OutputTuple, key_matching > { -private: - static const int N = tbb::flow::tuple_size::value; - typedef typename internal::unfolded_join_node > unfolded_type; -public: - typedef OutputTuple output_type; - typedef typename unfolded_type::input_ports_type input_ports_type; - -#if __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING - join_node(graph &g) : unfolded_type(g) {} -#endif /* __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING */ - - template - join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1) : unfolded_type(g, b0, b1) { - tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph, - this->input_ports(), static_cast< sender< output_type > *>(this) ); - } - template - join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2) : unfolded_type(g, b0, b1, b2) { - tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph, - this->input_ports(), static_cast< sender< output_type > *>(this) ); - } - template - join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2, __TBB_B3 b3) : unfolded_type(g, b0, b1, b2, b3) { - tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph, - this->input_ports(), static_cast< sender< output_type > *>(this) ); - } - template - join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2, __TBB_B3 b3, __TBB_B4 b4) : - unfolded_type(g, b0, b1, b2, b3, b4) { - tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph, - this->input_ports(), static_cast< sender< output_type > *>(this) ); - } -#if __TBB_VARIADIC_MAX >= 6 - template - join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2, __TBB_B3 b3, __TBB_B4 b4, __TBB_B5 b5) : - unfolded_type(g, b0, b1, b2, b3, b4, b5) { - tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph, - this->input_ports(), static_cast< sender< output_type > *>(this) ); - } -#endif -#if __TBB_VARIADIC_MAX >= 7 - template - join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2, __TBB_B3 b3, __TBB_B4 b4, __TBB_B5 b5, __TBB_B6 b6) : - unfolded_type(g, b0, b1, b2, b3, b4, b5, b6) { - tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph, - this->input_ports(), static_cast< sender< output_type > *>(this) ); - } -#endif -#if __TBB_VARIADIC_MAX >= 8 - template - join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2, __TBB_B3 b3, __TBB_B4 b4, __TBB_B5 b5, __TBB_B6 b6, - __TBB_B7 b7) : unfolded_type(g, b0, b1, b2, b3, b4, b5, b6, b7) { - tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph, - this->input_ports(), static_cast< sender< output_type > *>(this) ); - } -#endif -#if __TBB_VARIADIC_MAX >= 9 - template - join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2, __TBB_B3 b3, __TBB_B4 b4, __TBB_B5 b5, __TBB_B6 b6, - __TBB_B7 b7, __TBB_B8 b8) : unfolded_type(g, b0, b1, b2, b3, b4, b5, b6, b7, b8) { - tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph, - this->input_ports(), static_cast< sender< output_type > *>(this) ); - } -#endif -#if __TBB_VARIADIC_MAX >= 10 - template - join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2, __TBB_B3 b3, __TBB_B4 b4, __TBB_B5 b5, __TBB_B6 b6, - __TBB_B7 b7, __TBB_B8 b8, __TBB_B9 b9) : unfolded_type(g, b0, b1, b2, b3, b4, b5, b6, b7, b8, b9) { - tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph, - this->input_ports(), static_cast< sender< output_type > *>(this) ); - } -#endif - join_node(const join_node &other) : unfolded_type(other) { - tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph, - this->input_ports(), static_cast< sender< output_type > *>(this) ); - } - -#if TBB_PREVIEW_FLOW_GRAPH_TRACE - void set_name( const char *name ) __TBB_override { - tbb::internal::fgt_node_desc( this, name ); - } -#endif - -}; - -// indexer node -#include "internal/_flow_graph_indexer_impl.h" - -// TODO: Implement interface with variadic template or tuple -template class indexer_node; - -//indexer node specializations -template -class indexer_node : public internal::unfolded_indexer_node > { -private: - static const int N = 1; -public: - typedef tuple InputTuple; - typedef typename internal::tagged_msg output_type; - typedef typename internal::unfolded_indexer_node unfolded_type; - indexer_node(graph& g) : unfolded_type(g) { - tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_INDEXER_NODE, &this->my_graph, - this->input_ports(), static_cast< sender< output_type > *>(this) ); - } - // Copy constructor - indexer_node( const indexer_node& other ) : unfolded_type(other) { - tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_INDEXER_NODE, &this->my_graph, - this->input_ports(), static_cast< sender< output_type > *>(this) ); - } - -#if TBB_PREVIEW_FLOW_GRAPH_TRACE - void set_name( const char *name ) { - tbb::internal::fgt_node_desc( this, name ); - } -#endif -}; - -template -class indexer_node : public internal::unfolded_indexer_node > { -private: - static const int N = 2; -public: - typedef tuple InputTuple; - typedef typename internal::tagged_msg output_type; - typedef typename internal::unfolded_indexer_node unfolded_type; - indexer_node(graph& g) : unfolded_type(g) { - tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_INDEXER_NODE, &this->my_graph, - this->input_ports(), static_cast< sender< output_type > *>(this) ); - } - // Copy constructor - indexer_node( const indexer_node& other ) : unfolded_type(other) { - tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_INDEXER_NODE, &this->my_graph, - this->input_ports(), static_cast< sender< output_type > *>(this) ); - } - -#if TBB_PREVIEW_FLOW_GRAPH_TRACE - void set_name( const char *name ) { - tbb::internal::fgt_node_desc( this, name ); - } -#endif -}; - -template -class indexer_node : public internal::unfolded_indexer_node > { -private: - static const int N = 3; -public: - typedef tuple InputTuple; - typedef typename internal::tagged_msg output_type; - typedef typename internal::unfolded_indexer_node unfolded_type; - indexer_node(graph& g) : unfolded_type(g) { - tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_INDEXER_NODE, &this->my_graph, - this->input_ports(), static_cast< sender< output_type > *>(this) ); - } - // Copy constructor - indexer_node( const indexer_node& other ) : unfolded_type(other) { - tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_INDEXER_NODE, &this->my_graph, - this->input_ports(), static_cast< sender< output_type > *>(this) ); - } - -#if TBB_PREVIEW_FLOW_GRAPH_TRACE - void set_name( const char *name ) { - tbb::internal::fgt_node_desc( this, name ); - } -#endif -}; - -template -class indexer_node : public internal::unfolded_indexer_node > { -private: - static const int N = 4; -public: - typedef tuple InputTuple; - typedef typename internal::tagged_msg output_type; - typedef typename internal::unfolded_indexer_node unfolded_type; - indexer_node(graph& g) : unfolded_type(g) { - tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_INDEXER_NODE, &this->my_graph, - this->input_ports(), static_cast< sender< output_type > *>(this) ); - } - // Copy constructor - indexer_node( const indexer_node& other ) : unfolded_type(other) { - tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_INDEXER_NODE, &this->my_graph, - this->input_ports(), static_cast< sender< output_type > *>(this) ); - } - -#if TBB_PREVIEW_FLOW_GRAPH_TRACE - void set_name( const char *name ) __TBB_override { - tbb::internal::fgt_node_desc( this, name ); - } -#endif -}; - -template -class indexer_node : public internal::unfolded_indexer_node > { -private: - static const int N = 5; -public: - typedef tuple InputTuple; - typedef typename internal::tagged_msg output_type; - typedef typename internal::unfolded_indexer_node unfolded_type; - indexer_node(graph& g) : unfolded_type(g) { - tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_INDEXER_NODE, &this->my_graph, - this->input_ports(), static_cast< sender< output_type > *>(this) ); - } - // Copy constructor - indexer_node( const indexer_node& other ) : unfolded_type(other) { - tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_INDEXER_NODE, &this->my_graph, - this->input_ports(), static_cast< sender< output_type > *>(this) ); - } - -#if TBB_PREVIEW_FLOW_GRAPH_TRACE - void set_name( const char *name ) __TBB_override { - tbb::internal::fgt_node_desc( this, name ); - } -#endif -}; - -#if __TBB_VARIADIC_MAX >= 6 -template -class indexer_node : public internal::unfolded_indexer_node > { -private: - static const int N = 6; -public: - typedef tuple InputTuple; - typedef typename internal::tagged_msg output_type; - typedef typename internal::unfolded_indexer_node unfolded_type; - indexer_node(graph& g) : unfolded_type(g) { - tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_INDEXER_NODE, &this->my_graph, - this->input_ports(), static_cast< sender< output_type > *>(this) ); - } - // Copy constructor - indexer_node( const indexer_node& other ) : unfolded_type(other) { - tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_INDEXER_NODE, &this->my_graph, - this->input_ports(), static_cast< sender< output_type > *>(this) ); - } - -#if TBB_PREVIEW_FLOW_GRAPH_TRACE - void set_name( const char *name ) __TBB_override { - tbb::internal::fgt_node_desc( this, name ); - } -#endif -}; -#endif //variadic max 6 - -#if __TBB_VARIADIC_MAX >= 7 -template -class indexer_node : public internal::unfolded_indexer_node > { -private: - static const int N = 7; -public: - typedef tuple InputTuple; - typedef typename internal::tagged_msg output_type; - typedef typename internal::unfolded_indexer_node unfolded_type; - indexer_node(graph& g) : unfolded_type(g) { - tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_INDEXER_NODE, &this->my_graph, - this->input_ports(), static_cast< sender< output_type > *>(this) ); - } - // Copy constructor - indexer_node( const indexer_node& other ) : unfolded_type(other) { - tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_INDEXER_NODE, &this->my_graph, - this->input_ports(), static_cast< sender< output_type > *>(this) ); - } - -#if TBB_PREVIEW_FLOW_GRAPH_TRACE - void set_name( const char *name ) __TBB_override { - tbb::internal::fgt_node_desc( this, name ); - } -#endif -}; -#endif //variadic max 7 - -#if __TBB_VARIADIC_MAX >= 8 -template -class indexer_node : public internal::unfolded_indexer_node > { -private: - static const int N = 8; -public: - typedef tuple InputTuple; - typedef typename internal::tagged_msg output_type; - typedef typename internal::unfolded_indexer_node unfolded_type; - indexer_node(graph& g) : unfolded_type(g) { - tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_INDEXER_NODE, &this->my_graph, - this->input_ports(), static_cast< sender< output_type > *>(this) ); - } - // Copy constructor - indexer_node( const indexer_node& other ) : unfolded_type(other) { - tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_INDEXER_NODE, &this->my_graph, - this->input_ports(), static_cast< sender< output_type > *>(this) ); - } - -#if TBB_PREVIEW_FLOW_GRAPH_TRACE - void set_name( const char *name ) __TBB_override { - tbb::internal::fgt_node_desc( this, name ); - } -#endif -}; -#endif //variadic max 8 - -#if __TBB_VARIADIC_MAX >= 9 -template -class indexer_node : public internal::unfolded_indexer_node > { -private: - static const int N = 9; -public: - typedef tuple InputTuple; - typedef typename internal::tagged_msg output_type; - typedef typename internal::unfolded_indexer_node unfolded_type; - indexer_node(graph& g) : unfolded_type(g) { - tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_INDEXER_NODE, &this->my_graph, - this->input_ports(), static_cast< sender< output_type > *>(this) ); - } - // Copy constructor - indexer_node( const indexer_node& other ) : unfolded_type(other) { - tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_INDEXER_NODE, &this->my_graph, - this->input_ports(), static_cast< sender< output_type > *>(this) ); - } - -#if TBB_PREVIEW_FLOW_GRAPH_TRACE - void set_name( const char *name ) __TBB_override { - tbb::internal::fgt_node_desc( this, name ); - } -#endif -}; -#endif //variadic max 9 - -#if __TBB_VARIADIC_MAX >= 10 -template -class indexer_node/*default*/ : public internal::unfolded_indexer_node > { -private: - static const int N = 10; -public: - typedef tuple InputTuple; - typedef typename internal::tagged_msg output_type; - typedef typename internal::unfolded_indexer_node unfolded_type; - indexer_node(graph& g) : unfolded_type(g) { - tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_INDEXER_NODE, &this->my_graph, - this->input_ports(), static_cast< sender< output_type > *>(this) ); - } - // Copy constructor - indexer_node( const indexer_node& other ) : unfolded_type(other) { - tbb::internal::fgt_multiinput_node( tbb::internal::FLOW_INDEXER_NODE, &this->my_graph, - this->input_ports(), static_cast< sender< output_type > *>(this) ); - } - -#if TBB_PREVIEW_FLOW_GRAPH_TRACE - void set_name( const char *name ) __TBB_override { - tbb::internal::fgt_node_desc( this, name ); - } -#endif -}; -#endif //variadic max 10 - -#if __TBB_PREVIEW_ASYNC_MSG -inline void internal_make_edge( internal::untyped_sender &p, internal::untyped_receiver &s ) { -#else -template< typename T > -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); -#endif - p.register_successor( 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, - typename = typename T::output_ports_type, typename = typename V::input_ports_type > -inline void make_edge( T& output, V& input) { - make_edge(get<0>(output.output_ports()), get<0>(input.input_ports())); -} - -//Makes an edge from port 0 of a multi-output predecessor to a receiver. -template< typename T, typename R, - typename = typename T::output_ports_type > -inline void make_edge( T& output, receiver& input) { - make_edge(get<0>(output.output_ports()), input); -} - -//Makes an edge from a sender to port 0 of a multi-input successor. -template< typename S, typename V, - typename = typename V::input_ports_type > -inline void make_edge( sender& output, V& input) { - make_edge(output, get<0>(input.input_ports())); -} -#endif - -#if __TBB_PREVIEW_ASYNC_MSG -inline void internal_remove_edge( internal::untyped_sender &p, internal::untyped_receiver &s ) { -#else -template< typename T > -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? - p.internal_delete_built_successor(s); - s.internal_delete_built_predecessor(p); -#endif - 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, - typename = typename T::output_ports_type, typename = typename V::input_ports_type > -inline void remove_edge( T& output, V& input) { - remove_edge(get<0>(output.output_ports()), get<0>(input.input_ports())); -} - -//Removes an edge between port 0 of a multi-output predecessor and a receiver. -template< typename T, typename R, - typename = typename T::output_ports_type > -inline void remove_edge( T& output, receiver& input) { - remove_edge(get<0>(output.output_ports()), input); -} -//Removes an edge between a sender and port 0 of a multi-input successor. -template< typename S, typename V, - typename = typename V::input_ports_type > -inline void remove_edge( sender& output, V& input) { - remove_edge(output, get<0>(input.input_ports())); -} -#endif - -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES -template -template< typename S > -void internal::edge_container::sender_extract( S &s ) { - edge_list_type e = built_edges; - for ( typename edge_list_type::iterator i = e.begin(); i != e.end(); ++i ) { - remove_edge(s, **i); - } -} - -template -template< typename R > -void internal::edge_container::receiver_extract( R &r ) { - edge_list_type e = built_edges; - for ( typename edge_list_type::iterator i = e.begin(); i != e.end(); ++i ) { - remove_edge(**i, r); - } -} -#endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */ - -//! Returns a copy of the body from a function or continue node -template< typename Body, typename Node > -Body copy_body( Node &n ) { - return n.template copy_function_object(); -} - -#if __TBB_FLOW_GRAPH_CPP11_FEATURES - -//composite_node -template< typename InputTuple, typename OutputTuple > class composite_node; - -template< typename... InputTypes, typename... OutputTypes> -class composite_node , tbb::flow::tuple > : public graph_node{ - -public: - typedef tbb::flow::tuple< receiver&... > input_ports_type; - typedef tbb::flow::tuple< sender&... > output_ports_type; - -private: -#if TBB_PREVIEW_FLOW_GRAPH_TRACE - const char *my_type_name; -#endif - input_ports_type *my_input_ports; - output_ports_type *my_output_ports; - - static const size_t NUM_INPUTS = sizeof...(InputTypes); - static const size_t NUM_OUTPUTS = sizeof...(OutputTypes); - -protected: - void reset_node(reset_flags) __TBB_override {} - -public: -#if TBB_PREVIEW_FLOW_GRAPH_TRACE - composite_node( graph &g, const char *type_name = "composite_node") : graph_node(g), my_type_name(type_name), my_input_ports(NULL), my_output_ports(NULL) { - tbb::internal::itt_make_task_group( tbb::internal::ITT_DOMAIN_FLOW, this, tbb::internal::FLOW_NODE, &g, tbb::internal::FLOW_GRAPH, tbb::internal::FLOW_COMPOSITE_NODE ); - tbb::internal::fgt_multiinput_multioutput_node_desc( this, my_type_name ); - } -#else - composite_node( graph &g) : graph_node(g), my_input_ports(NULL), my_output_ports(NULL) {} -#endif - - template - void set_external_ports(T1&& input_ports_tuple, T2&& output_ports_tuple) { - __TBB_STATIC_ASSERT(NUM_INPUTS == tbb::flow::tuple_size::value, "number of arguments does not match number of input ports"); - __TBB_STATIC_ASSERT(NUM_OUTPUTS == tbb::flow::tuple_size::value, "number of arguments does not match number of output ports"); - my_input_ports = new input_ports_type(std::forward(input_ports_tuple)); - my_output_ports = new output_ports_type(std::forward(output_ports_tuple)); - -#if TBB_PREVIEW_FLOW_GRAPH_TRACE - tbb::internal::fgt_internal_input_helper::register_port( this, input_ports_tuple); - tbb::internal::fgt_internal_output_helper::register_port( this, output_ports_tuple); -#endif - } - -#if TBB_PREVIEW_FLOW_GRAPH_TRACE - template< typename... NodeTypes > - void add_visible_nodes(const NodeTypes&... n) { internal::add_nodes_impl(this, true, n...); } - - template< typename... NodeTypes > - void add_nodes(const NodeTypes&... n) { internal::add_nodes_impl(this, false, n...); } -#else - template void add_nodes(Nodes&...) { } - template void add_visible_nodes(Nodes&...) { } -#endif - -#if TBB_PREVIEW_FLOW_GRAPH_TRACE - void set_name( const char *name ) __TBB_override { - tbb::internal::fgt_multiinput_multioutput_node_desc( this, name ); - } -#endif - - input_ports_type input_ports() { - __TBB_ASSERT(my_input_ports, "input ports not set, call set_external_ports to set input ports"); - return *my_input_ports; - } - - output_ports_type output_ports() { - __TBB_ASSERT(my_output_ports, "output ports not set, call set_external_ports to set output ports"); - return *my_output_ports; - } - - virtual ~composite_node() { - if(my_input_ports) delete my_input_ports; - if(my_output_ports) delete my_output_ports; - } - -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - void extract() __TBB_override { - __TBB_ASSERT(false, "Current composite_node implementation does not support extract"); - } -#endif -}; // class composite_node - -//composite_node with only input ports -template< typename... InputTypes> -class composite_node , tbb::flow::tuple<> > : public graph_node { -public: - typedef tbb::flow::tuple< receiver&... > input_ports_type; - -private: -#if TBB_PREVIEW_FLOW_GRAPH_TRACE - const char *my_type_name; -#endif - input_ports_type *my_input_ports; - static const size_t NUM_INPUTS = sizeof...(InputTypes); - -protected: - void reset_node(reset_flags) __TBB_override {} - -public: -#if TBB_PREVIEW_FLOW_GRAPH_TRACE - composite_node( graph &g, const char *type_name = "composite_node") : graph_node(g), my_type_name(type_name), my_input_ports(NULL) { - tbb::internal::itt_make_task_group( tbb::internal::ITT_DOMAIN_FLOW, this, tbb::internal::FLOW_NODE, &g, tbb::internal::FLOW_GRAPH, tbb::internal::FLOW_COMPOSITE_NODE ); - tbb::internal::fgt_multiinput_multioutput_node_desc( this, my_type_name ); - } -#else - composite_node( graph &g) : graph_node(g), my_input_ports(NULL) {} -#endif - - template - void set_external_ports(T&& input_ports_tuple) { - __TBB_STATIC_ASSERT(NUM_INPUTS == tbb::flow::tuple_size::value, "number of arguments does not match number of input ports"); - - my_input_ports = new input_ports_type(std::forward(input_ports_tuple)); - -#if TBB_PREVIEW_FLOW_GRAPH_TRACE - tbb::internal::fgt_internal_input_helper::register_port( this, std::forward(input_ports_tuple)); -#endif - } - -#if TBB_PREVIEW_FLOW_GRAPH_TRACE - template< typename... NodeTypes > - void add_visible_nodes(const NodeTypes&... n) { internal::add_nodes_impl(this, true, n...); } - - template< typename... NodeTypes > - void add_nodes( const NodeTypes&... n) { internal::add_nodes_impl(this, false, n...); } -#else - template void add_nodes(Nodes&...) {} - template void add_visible_nodes(Nodes&...) {} -#endif - -#if TBB_PREVIEW_FLOW_GRAPH_TRACE - void set_name( const char *name ) __TBB_override { - tbb::internal::fgt_multiinput_multioutput_node_desc( this, name ); - } -#endif - - input_ports_type input_ports() { - __TBB_ASSERT(my_input_ports, "input ports not set, call set_external_ports to set input ports"); - return *my_input_ports; - } - - virtual ~composite_node() { - if(my_input_ports) delete my_input_ports; - } - -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - void extract() __TBB_override { - __TBB_ASSERT(false, "Current composite_node implementation does not support extract"); - } -#endif - -}; // class composite_node - -//composite_nodes with only output_ports -template -class composite_node , tbb::flow::tuple > : public graph_node { -public: - typedef tbb::flow::tuple< sender&... > output_ports_type; - -private: -#if TBB_PREVIEW_FLOW_GRAPH_TRACE - const char *my_type_name; -#endif - output_ports_type *my_output_ports; - static const size_t NUM_OUTPUTS = sizeof...(OutputTypes); - -protected: - void reset_node(reset_flags) __TBB_override {} - -public: -#if TBB_PREVIEW_FLOW_GRAPH_TRACE - composite_node( graph &g, const char *type_name = "composite_node") : graph_node(g), my_type_name(type_name), my_output_ports(NULL) { - tbb::internal::itt_make_task_group( tbb::internal::ITT_DOMAIN_FLOW, this, tbb::internal::FLOW_NODE, &g, tbb::internal::FLOW_GRAPH, tbb::internal::FLOW_COMPOSITE_NODE ); - tbb::internal::fgt_multiinput_multioutput_node_desc( this, my_type_name ); - } -#else - composite_node( graph &g) : graph_node(g), my_output_ports(NULL) {} -#endif - - template - void set_external_ports(T&& output_ports_tuple) { - __TBB_STATIC_ASSERT(NUM_OUTPUTS == tbb::flow::tuple_size::value, "number of arguments does not match number of output ports"); - - my_output_ports = new output_ports_type(std::forward(output_ports_tuple)); - -#if TBB_PREVIEW_FLOW_GRAPH_TRACE - tbb::internal::fgt_internal_output_helper::register_port( this, std::forward(output_ports_tuple)); -#endif - } - -#if TBB_PREVIEW_FLOW_GRAPH_TRACE - template - void add_visible_nodes(const NodeTypes&... n) { internal::add_nodes_impl(this, true, n...); } - - template - void add_nodes(const NodeTypes&... n) { internal::add_nodes_impl(this, false, n...); } -#else - template void add_nodes(Nodes&...) {} - template void add_visible_nodes(Nodes&...) {} -#endif - -#if TBB_PREVIEW_FLOW_GRAPH_TRACE - void set_name( const char *name ) __TBB_override { - tbb::internal::fgt_multiinput_multioutput_node_desc( this, name ); - } -#endif - - output_ports_type output_ports() { - __TBB_ASSERT(my_output_ports, "output ports not set, call set_external_ports to set output ports"); - return *my_output_ports; - } - - virtual ~composite_node() { - if(my_output_ports) delete my_output_ports; - } - -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - void extract() __TBB_override { - __TBB_ASSERT(false, "Current composite_node implementation does not support extract"); - } -#endif - -}; // class composite_node - -#endif // __TBB_FLOW_GRAPH_CPP11_FEATURES - -namespace internal { - -template -class async_body_base: tbb::internal::no_assign { -public: - typedef Gateway gateway_type; - - async_body_base(gateway_type *gateway): my_gateway(gateway) { } - void set_gateway(gateway_type *gateway) { - my_gateway = gateway; - } - -protected: - gateway_type *my_gateway; -}; - -template -class async_body: public async_body_base { -public: - typedef async_body_base base_type; - typedef Gateway gateway_type; - - async_body(const Body &body, gateway_type *gateway) - : base_type(gateway), my_body(body) { } - - void operator()( const Input &v, Ports & ) { - my_body(v, *this->my_gateway); - } - - Body get_body() { return my_body; } - -private: - Body my_body; -}; - -} - -//! 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 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 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; - const Output *value; - bool result; - try_put_functor(output_port_type &p, const Output &v) : port(&p), value(&v), result(false) { } - void operator()() { - result = port->try_put(*value); - } - }; - - 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, &my_gateway) ), my_gateway(self()) { - tbb::internal::fgt_multioutput_node<1>( tbb::internal::FLOW_ASYNC_NODE, - &this->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() ); - } - - gateway_type& gateway() { - return my_gateway; - } - -#if TBB_PREVIEW_FLOW_GRAPH_TRACE - void set_name( const char *name ) __TBB_override { - tbb::internal::fgt_node_desc( this, name ); - } -#endif - - // Define sender< Output > - - //! Add a new successor to this node - bool register_successor( successor_type &r ) __TBB_override { - return internal::output_port<0>(*this).register_successor(r); - } - - //! Removes a successor from this node - 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; - mfn_body_type &body_ref = *this->my_body; - async_body_type ab = *static_cast(dynamic_cast< internal::multifunction_body_leaf & >(body_ref).get_body_ptr()); - return ab.get_body(); - } - -#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; - built_successors_type &built_successors() __TBB_override { - return internal::output_port<0>(*this).built_successors(); - } - - void internal_add_built_successor( successor_type &r ) __TBB_override { - internal::output_port<0>(*this).internal_add_built_successor(r); - } - - void internal_delete_built_successor( successor_type &r ) __TBB_override { - internal::output_port<0>(*this).internal_delete_built_successor(r); - } - - void copy_successors( successor_list_type &l ) __TBB_override { - internal::output_port<0>(*this).copy_successors(l); - } - - size_t successor_count() __TBB_override { - return internal::output_port<0>(*this).successor_count(); - } -#endif - -protected: - - void reset_node( reset_flags f) __TBB_override { - base_type::reset_node(f); - } -}; - -#if __TBB_PREVIEW_STREAMING_NODE -#include "internal/_flow_graph_streaming_node.h" -#endif // __TBB_PREVIEW_STREAMING_NODE - -} // interface9 - - using interface9::reset_flags; - using interface9::rf_reset_protocol; - using interface9::rf_reset_bodies; - using interface9::rf_clear_edges; - - using interface9::graph; - using interface9::graph_node; - using interface9::continue_msg; - - 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 interface9::composite_node; -#endif - 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 - -#undef __TBB_PFG_RESET_ARG -#undef __TBB_COMMA - -#endif // __TBB_flow_graph_H diff --git a/lib/3rdParty/tbb/include/tbb/flow_graph_abstractions.h b/lib/3rdParty/tbb/include/tbb/flow_graph_abstractions.h deleted file mode 100644 index f6eb3fb3..00000000 --- a/lib/3rdParty/tbb/include/tbb/flow_graph_abstractions.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - 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 deleted file mode 100644 index 0a98a775..00000000 --- a/lib/3rdParty/tbb/include/tbb/flow_graph_opencl_node.h +++ /dev/null @@ -1,1537 +0,0 @@ -/* - 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_opencl_node_H -#define __TBB_flow_graph_opencl_node_H - -#include "tbb/tbb_config.h" -#if __TBB_PREVIEW_OPENCL_NODE - -#include "flow_graph.h" - -#include -#include -#include -#include -#include -#include -#include - -#ifdef __APPLE__ -#include -#else -#include -#endif - -namespace tbb { -namespace flow { - -namespace interface9 { - -class opencl_foundation; -class opencl_device_list; - -template -class opencl_buffer_impl; - -template -class opencl_program; - -class default_opencl_factory; - -class opencl_graph : public graph { -public: - //! Constructs a graph with isolated task_group_context - opencl_graph() : my_opencl_foundation( NULL ) {} - //! Constructs a graph with an user context - explicit opencl_graph( task_group_context& context ) : graph( context ), my_opencl_foundation( NULL ) {} - //! Destroys a graph - ~opencl_graph(); - //! Available devices - const opencl_device_list& available_devices(); - default_opencl_factory& opencl_factory(); -protected: - opencl_foundation *my_opencl_foundation; - opencl_foundation &get_opencl_foundation(); - - template - friend class opencl_buffer; - template - friend class opencl_image2d; - template - friend class opencl_node; - template - friend class opencl_factory; -}; - -template -class opencl_factory; - -template -class dependency_msg; - - -inline void enforce_cl_retcode( cl_int err, std::string msg ) { - if ( err != CL_SUCCESS ) { - std::cerr << msg << "; error code: " << err << std::endl; - throw msg; - } -} - -template -T event_info( cl_event e, cl_event_info i ) { - T res; - enforce_cl_retcode( clGetEventInfo( e, i, sizeof( res ), &res, NULL ), "Failed to get OpenCL event information" ); - return res; -} - -template -T device_info( cl_device_id d, cl_device_info i ) { - T res; - enforce_cl_retcode( clGetDeviceInfo( d, i, sizeof( res ), &res, NULL ), "Failed to get OpenCL device information" ); - return res; -} -template <> -std::string device_info( cl_device_id d, cl_device_info i ) { - size_t required; - enforce_cl_retcode( clGetDeviceInfo( d, i, 0, NULL, &required ), "Failed to get OpenCL device information" ); - - char *buff = (char*)alloca( required ); - enforce_cl_retcode( clGetDeviceInfo( d, i, required, buff, NULL ), "Failed to get OpenCL device information" ); - - return buff; -} -template -T platform_info( cl_platform_id p, cl_platform_info i ) { - T res; - enforce_cl_retcode( clGetPlatformInfo( p, i, sizeof( res ), &res, NULL ), "Failed to get OpenCL platform information" ); - return res; -} -template <> -std::string platform_info( cl_platform_id p, cl_platform_info i ) { - size_t required; - enforce_cl_retcode( clGetPlatformInfo( p, i, 0, NULL, &required ), "Failed to get OpenCL platform information" ); - - char *buff = (char*)alloca( required ); - enforce_cl_retcode( clGetPlatformInfo( p, i, required, buff, NULL ), "Failed to get OpenCL platform information" ); - - return buff; -} - - -class opencl_device { -public: - typedef size_t device_id_type; - enum : device_id_type { - unknown = device_id_type( -2 ), - host = device_id_type( -1 ) - }; - - opencl_device() : my_device_id( unknown ) {} - - opencl_device( cl_device_id cl_d_id, device_id_type device_id ) : my_device_id( device_id ), my_cl_device_id( cl_d_id ) {} - - std::string platform_profile() const { - return platform_info( platform(), CL_PLATFORM_PROFILE ); - } - std::string platform_version() const { - return platform_info( platform(), CL_PLATFORM_VERSION ); - } - std::string platform_name() const { - return platform_info( platform(), CL_PLATFORM_NAME ); - } - std::string platform_vendor() const { - return platform_info( platform(), CL_PLATFORM_VENDOR ); - } - std::string platform_extensions() const { - return platform_info( platform(), CL_PLATFORM_EXTENSIONS ); - } - - template - void info( cl_device_info i, T &t ) const { - t = device_info( my_cl_device_id, i ); - } - std::string version() const { - // The version string format: OpenCL - return device_info( my_cl_device_id, CL_DEVICE_VERSION ); - } - int major_version() const { - int major; - std::sscanf( version().c_str(), "OpenCL %d", &major ); - return major; - } - int minor_version() const { - int major, minor; - std::sscanf( version().c_str(), "OpenCL %d.%d", &major, &minor ); - return minor; - } - bool out_of_order_exec_mode_on_host_present() const { -#if CL_VERSION_2_0 - if ( major_version() >= 2 ) - return (device_info( my_cl_device_id, CL_DEVICE_QUEUE_ON_HOST_PROPERTIES ) & CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE) != 0; - else -#endif /* CL_VERSION_2_0 */ - return (device_info( my_cl_device_id, CL_DEVICE_QUEUE_PROPERTIES ) & CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE) != 0; - } - bool out_of_order_exec_mode_on_device_present() const { -#if CL_VERSION_2_0 - if ( major_version() >= 2 ) - return (device_info( my_cl_device_id, CL_DEVICE_QUEUE_ON_DEVICE_PROPERTIES ) & CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE) != 0; - else -#endif /* CL_VERSION_2_0 */ - return false; - } - std::array max_work_item_sizes() const { - return device_info>( my_cl_device_id, CL_DEVICE_MAX_WORK_ITEM_SIZES ); - } - size_t max_work_group_size() const { - return device_info( my_cl_device_id, CL_DEVICE_MAX_WORK_GROUP_SIZE ); - } - bool built_in_kernel_available( const std::string& k ) const { - const std::string semi = ";"; - // Added semicolumns to force an exact match (to avoid a partial match, e.g. "add" is partly matched with "madd"). - return (semi + built_in_kernels() + semi).find( semi + k + semi ) != std::string::npos; - } - std::string built_in_kernels() const { - return device_info( my_cl_device_id, CL_DEVICE_BUILT_IN_KERNELS ); - } - std::string name() const { - return device_info( my_cl_device_id, CL_DEVICE_NAME ); - } - cl_bool available() const { - return device_info( my_cl_device_id, CL_DEVICE_AVAILABLE ); - } - cl_bool compiler_available() const { - return device_info( my_cl_device_id, CL_DEVICE_COMPILER_AVAILABLE ); - } - cl_bool linker_available() const { - return device_info( my_cl_device_id, CL_DEVICE_LINKER_AVAILABLE ); - } - bool extension_available( const std::string &ext ) const { - const std::string space = " "; - // Added space to force an exact match (to avoid a partial match, e.g. "ext" is partly matched with "ext2"). - return (space + extensions() + space).find( space + ext + space ) != std::string::npos; - } - std::string extensions() const { - return device_info( my_cl_device_id, CL_DEVICE_EXTENSIONS ); - } - - cl_device_type type() const { - return device_info( my_cl_device_id, CL_DEVICE_TYPE ); - } - - std::string vendor() const { - return device_info( my_cl_device_id, CL_DEVICE_VENDOR ); - } - - cl_uint address_bits() const { - return device_info( my_cl_device_id, CL_DEVICE_ADDRESS_BITS ); - } - - cl_device_id device_id() const { - return my_cl_device_id; - } - - cl_command_queue command_queue() const { - return my_cl_command_queue; - } - - void set_command_queue( cl_command_queue cmd_queue ) { - my_cl_command_queue = cmd_queue; - } - -private: - opencl_device( cl_device_id d_id ) : my_device_id( unknown ), my_cl_device_id( d_id ) {} - - cl_platform_id platform() const { - return device_info( my_cl_device_id, CL_DEVICE_PLATFORM ); - } - - device_id_type my_device_id; - cl_device_id my_cl_device_id; - cl_command_queue my_cl_command_queue; - - friend bool operator==(opencl_device d1, opencl_device d2) { return d1.my_cl_device_id == d2.my_cl_device_id; } - - template - friend class opencl_factory; - template - friend class opencl_memory; - template - friend class opencl_program; - friend class opencl_foundation; - -#if TBB_USE_ASSERT - template - friend class opencl_buffer; -#endif -}; - -class opencl_device_list { - typedef std::vector container_type; -public: - typedef container_type::iterator iterator; - typedef container_type::const_iterator const_iterator; - typedef container_type::size_type size_type; - - opencl_device_list() {} - opencl_device_list( std::initializer_list il ) : my_container( il ) {} - - 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(); } - const_iterator end() const { return my_container.end(); } - const_iterator cbegin() const { return my_container.cbegin(); } - const_iterator cend() const { return my_container.cend(); } -private: - container_type my_container; -}; - -class callback_base : tbb::internal::no_copy { -public: - virtual void call() = 0; - virtual ~callback_base() {} -}; - -template -class callback : public callback_base { - graph &my_graph; - Callback my_callback; - T my_data; -public: - callback( graph &g, Callback c, const T& t ) : my_graph( g ), my_callback( c ), my_data( t ) { - // Extend the graph lifetime until the callback completion. - my_graph.increment_wait_count(); - } - ~callback() { - // Release the reference to the graph. - my_graph.decrement_wait_count(); - } - void call() __TBB_override { - my_callback( my_data ); - } -}; - -template -class dependency_msg : public async_msg { -public: - typedef T value_type; - - 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" ); - enforce_cl_retcode( clReleaseEvent( my_event ), "Failed to release an event" ); - my_is_event = false; - } - return my_data; - } - - const T& data( bool wait = true ) const { - if ( my_is_event && wait ) { - enforce_cl_retcode( clWaitForEvents( 1, &my_event ), "Failed to wait for an event" ); - enforce_cl_retcode( clReleaseEvent( my_event ), "Failed to release an event" ); - my_is_event = false; - } - return my_data; - } - - 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 ) : 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; - } - - ~dependency_msg() { - if ( my_is_event ) - enforce_cl_retcode( clReleaseEvent( my_event ), "Failed to release an event" ); - } - - cl_event const * get_event() const { return my_is_event ? &my_event : NULL; } - void set_event( cl_event e ) const { - if ( my_is_event ) { - cl_command_queue cq = event_info( my_event, CL_EVENT_COMMAND_QUEUE ); - if ( cq != event_info( e, CL_EVENT_COMMAND_QUEUE ) ) - enforce_cl_retcode( clFlush( cq ), "Failed to flush an OpenCL command queue" ); - enforce_cl_retcode( clReleaseEvent( my_event ), "Failed to release an event" ); - } - my_is_event = true; - my_event = e; - clRetainEvent( my_event ); - } - - void set_graph( graph &g ) { - my_graph = &g; - } - - void clear_event() const { - if ( my_is_event ) { - enforce_cl_retcode( clFlush( event_info( my_event, CL_EVENT_COMMAND_QUEUE ) ), "Failed to flush an OpenCL command queue" ); - enforce_cl_retcode( clReleaseEvent( my_event ), "Failed to release an event" ); - } - my_is_event = false; - } - - template - void register_callback( Callback c ) const { - __TBB_ASSERT( my_is_event, "The OpenCL event is not set" ); - __TBB_ASSERT( my_graph, "The graph is not set" ); - enforce_cl_retcode( clSetEventCallback( my_event, CL_COMPLETE, register_callback_func, new callback( *my_graph, c, my_data ) ), "Failed to set an OpenCL callback" ); - } - - 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 ); - __TBB_ASSERT( event_command_exec_status == CL_COMPLETE, NULL ); - __TBB_ASSERT( data, NULL ); - callback_base *c = static_cast(data); - c->call(); - delete c; - } - - T my_data; - 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 -K key_from_message( const dependency_msg &dmsg ) { - using tbb::flow::key_from_message; - const T &t = dmsg.data( false ); - __TBB_STATIC_ASSERT( true, "" ); - return key_from_message( t ); -} - -template -class opencl_memory { -public: - opencl_memory() {} - opencl_memory( Factory &f ) : my_host_ptr( NULL ), my_factory( &f ), my_sending_event_present( false ) { - my_curr_device_id = my_factory->devices().begin()->my_device_id; - } - - ~opencl_memory() { - if ( my_sending_event_present ) enforce_cl_retcode( clReleaseEvent( my_sending_event ), "Failed to release an event for the OpenCL buffer" ); - enforce_cl_retcode( clReleaseMemObject( my_cl_mem ), "Failed to release an memory object" ); - } - - cl_mem get_cl_mem() const { - return my_cl_mem; - } - - void* get_host_ptr() { - if ( !my_host_ptr ) { - dependency_msg d = receive( NULL ); - d.data(); - __TBB_ASSERT( d.data() == my_host_ptr, NULL ); - } - return my_host_ptr; - } - - Factory *factory() const { return my_factory; } - - dependency_msg send( opencl_device d, const cl_event *e ); - dependency_msg receive( const cl_event *e ); - virtual void map_memory( opencl_device, dependency_msg & ) = 0; -protected: - cl_mem my_cl_mem; - tbb::atomic my_curr_device_id; - void* my_host_ptr; - Factory *my_factory; - - tbb::spin_mutex my_sending_lock; - bool my_sending_event_present; - cl_event my_sending_event; -}; - -template -class opencl_buffer_impl : public opencl_memory { - size_t my_size; -public: - opencl_buffer_impl( size_t size, Factory& f ) : opencl_memory( f ), my_size( size ) { - cl_int err; - this->my_cl_mem = clCreateBuffer( this->my_factory->context(), CL_MEM_ALLOC_HOST_PTR, size, NULL, &err ); - enforce_cl_retcode( err, "Failed to create an OpenCL buffer" ); - } - - // The constructor for subbuffers. - opencl_buffer_impl( cl_mem m, size_t index, size_t size, Factory& f ) : opencl_memory( f ), my_size( size ) { - cl_int err; - cl_buffer_region region = { index, size }; - this->my_cl_mem = clCreateSubBuffer( m, 0, CL_BUFFER_CREATE_TYPE_REGION, ®ion, &err ); - enforce_cl_retcode( err, "Failed to create an OpenCL subbuffer" ); - } - - size_t size() const { - return my_size; - } - - void map_memory( opencl_device device, dependency_msg &dmsg ) __TBB_override { - this->my_factory->enque_map_buffer( device, *this, dmsg ); - } - -#if TBB_USE_ASSERT - template - friend class opencl_buffer; -#endif -}; - -enum access_type { - read_write, - write_only, - read_only -}; - -template -class opencl_subbuffer; - -template -class opencl_buffer { -public: - typedef cl_mem native_object_type; - typedef opencl_buffer memory_object_type; - typedef Factory opencl_factory_type; - - template using iterator = T*; - - template - iterator
    access() const { - T* ptr = (T*)my_impl->get_host_ptr(); - __TBB_ASSERT( ptr, NULL ); - return iterator( ptr ); - } - - T* data() const { return &access()[0]; } - - template - iterator begin() const { return access(); } - - template - iterator end() const { return access()+my_impl->size()/sizeof(T); } - - size_t size() const { return my_impl->size()/sizeof(T); } - - T& operator[] ( ptrdiff_t k ) { return begin()[k]; } - - opencl_buffer() {} - opencl_buffer( opencl_graph &g, size_t size ); - opencl_buffer( Factory &f, size_t size ) : my_impl( std::make_shared( size*sizeof(T), f ) ) {} - - cl_mem native_object() const { - return my_impl->get_cl_mem(); - } - - const opencl_buffer& memory_object() const { - return *this; - } - - void send( opencl_device device, dependency_msg &dependency ) const { - __TBB_ASSERT( dependency.data( /*wait = */false ) == *this, NULL ); - dependency_msg d = my_impl->send( device, dependency.get_event() ); - const cl_event *e = d.get_event(); - if ( e ) dependency.set_event( *e ); - else dependency.clear_event(); - } - void receive( const dependency_msg &dependency ) const { - __TBB_ASSERT( dependency.data( /*wait = */false ) == *this, NULL ); - dependency_msg d = my_impl->receive( dependency.get_event() ); - const cl_event *e = d.get_event(); - if ( e ) dependency.set_event( *e ); - else dependency.clear_event(); - } - - opencl_subbuffer subbuffer( size_t index, size_t size ) const; -private: - // The constructor for subbuffers. - opencl_buffer( Factory &f, cl_mem m, size_t index, size_t size ) : my_impl( std::make_shared( m, index*sizeof(T), size*sizeof(T), f ) ) {} - - typedef opencl_buffer_impl impl_type; - - std::shared_ptr my_impl; - - friend bool operator==(const opencl_buffer &lhs, const opencl_buffer &rhs) { - return lhs.my_impl == rhs.my_impl; - } - - template - friend class opencl_factory; - template - friend class opencl_subbuffer; -}; - -template -class opencl_subbuffer : public opencl_buffer { - opencl_buffer my_owner; -public: - opencl_subbuffer() {} - opencl_subbuffer( const opencl_buffer &owner, size_t index, size_t size ) : - opencl_buffer( *owner.my_impl->factory(), owner.native_object(), index, size ), my_owner( owner ) {} -}; - -template -opencl_subbuffer opencl_buffer::subbuffer( size_t index, size_t size ) const { - return opencl_subbuffer( *this, index, size ); -} - - -#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 ( 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" ); - } - } - - bool init( const opencl_device_list &device_list ) { - tbb::spin_mutex::scoped_lock lock( my_devices_mutex ); - if ( !my_devices.size() ) { - my_devices = device_list; - return true; - } - return false; - } - - -private: - template - void enque_map_buffer( opencl_device device, opencl_buffer_impl &buffer, dependency_msg& dmsg ) { - cl_event const* e1 = dmsg.get_event(); - cl_event e2; - cl_int err; - void *ptr = clEnqueueMapBuffer( device.my_cl_command_queue, buffer.get_cl_mem(), false, CL_MAP_READ | CL_MAP_WRITE, 0, buffer.size(), - e1 == NULL ? 0 : 1, e1, &e2, &err ); - enforce_cl_retcode( err, "Failed to map a buffer" ); - dmsg.data( false ) = ptr; - dmsg.set_event( e2 ); - enforce_cl_retcode( clReleaseEvent( e2 ), "Failed to release an event" ); - } - - - template - void enque_unmap_buffer( opencl_device device, opencl_memory &memory, dependency_msg& dmsg ) { - cl_event const* e1 = dmsg.get_event(); - cl_event e2; - enforce_cl_retcode( - clEnqueueUnmapMemObject( device.my_cl_command_queue, memory.get_cl_mem(), memory.get_host_ptr(), e1 == NULL ? 0 : 1, e1, &e2 ), - "Failed to unmap a buffer" ); - dmsg.set_event( e2 ); - enforce_cl_retcode( clReleaseEvent( e2 ), "Failed to release an event" ); - } - - // --------- 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, - g_offset.data(), g_size.data(), l_size[0] ? l_size.data() : NULL, num_events, num_events ? event_list : NULL, &event ), - "Failed to enqueue a kernel" ); - return event; - } - - // ------------------------------------------- // - 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" ); - } - - const opencl_device_list& devices() { - std::call_once( my_once_flag, &opencl_factory::init_once, this ); - 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. - if ( d1 != opencl_device::host && d2 != opencl_device::host ) - return true; - return d1 == d2; - } -private: - opencl_factory( const opencl_factory& ); - opencl_factory& operator=(const opencl_factory&); - - cl_context context() { - std::call_once( my_once_flag, &opencl_factory::init_once, this ); - return my_cl_context; - } - - void init_once(); - - std::once_flag my_once_flag; - opencl_device_list my_devices; - cl_context my_cl_context; - opencl_graph &my_graph; - - tbb::spin_mutex my_devices_mutex; - - template - friend class opencl_program; - template - friend class opencl_buffer_impl; - template - friend class opencl_memory; -}; - -template -dependency_msg opencl_memory::receive( const cl_event *e ) { - dependency_msg d = e ? dependency_msg( my_host_ptr, *e ) : dependency_msg( my_host_ptr ); - // Concurrent receives are prohibited so we do not worry about synchronization. - if ( my_curr_device_id.load() != opencl_device::host ) { - map_memory( *my_factory->devices().begin(), d ); - my_curr_device_id.store( opencl_device::host ); - my_host_ptr = d.data( false ); - } - // Release the sending event - if ( my_sending_event_present ) { - enforce_cl_retcode( clReleaseEvent( my_sending_event ), "Failed to release an event" ); - my_sending_event_present = false; - } - return d; -} - -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::spin_mutex::scoped_lock lock( my_sending_lock ); - if ( !my_factory->is_same_context( my_curr_device_id.load(), device_id ) ) { - __TBB_ASSERT( my_host_ptr, "The buffer has not been mapped" ); - dependency_msg d( my_host_ptr ); - my_factory->enque_unmap_buffer( device, *this, d ); - my_sending_event = *d.get_event(); - my_sending_event_present = true; - enforce_cl_retcode( clRetainEvent( my_sending_event ), "Failed to retain an event" ); - my_host_ptr = NULL; - my_curr_device_id.store(device_id); - } - } - __TBB_ASSERT( my_sending_event_present, NULL ); - } - - // !e means that buffer has come from the host - if ( !e && my_sending_event_present ) e = &my_sending_event; - - __TBB_ASSERT( !my_host_ptr, "The buffer has not been unmapped" ); - return e ? dependency_msg( NULL, *e ) : dependency_msg( NULL ); -} - -struct default_opencl_factory_device_filter { - opencl_device_list operator()( const opencl_device_list &devices ) { - opencl_device_list dl; - dl.add( *devices.begin() ); - return dl; - } -}; - -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& ); - default_opencl_factory& operator=(const default_opencl_factory&); -}; - -class opencl_foundation : tbb::internal::no_assign { - struct default_device_selector_type { - 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() { - cl_uint num_platforms; - 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"); - - cl_uint num_devices; - std::vector::iterator platforms_it = platforms.begin(); - cl_uint num_all_devices = 0; - 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 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 (auto d = devices.begin(); d != devices.end(); ++d) { - my_devices.add(opencl_device((*d))); - } - } - - default_opencl_factory &get_default_opencl_factory() { - return my_default_opencl_factory; - } - - const opencl_device_list &get_all_devices() { - return my_devices; - } - - default_device_selector_type get_default_device_selector() { return my_default_device_selector; } - -private: - default_opencl_factory my_default_opencl_factory; - opencl_device_list my_devices; - - const default_device_selector_type my_default_device_selector; -}; - -opencl_foundation &opencl_graph::get_opencl_foundation() { - opencl_foundation* INITIALIZATION = (opencl_foundation*)1; - if ( my_opencl_foundation <= INITIALIZATION ) { - if ( tbb::internal::as_atomic( my_opencl_foundation ).compare_and_swap( INITIALIZATION, NULL ) == 0 ) { - my_opencl_foundation = new opencl_foundation( *this ); - } - else { - tbb::internal::spin_wait_while_eq( my_opencl_foundation, INITIALIZATION ); - } - } - - __TBB_ASSERT( my_opencl_foundation > INITIALIZATION, "opencl_foundation is not initialized"); - return *my_opencl_foundation; -} - -opencl_graph::~opencl_graph() { - if ( my_opencl_foundation ) - delete my_opencl_foundation; -} - -template -void opencl_factory::init_once() { - { - tbb::spin_mutex::scoped_lock lock( my_devices_mutex ); - if ( !my_devices.size() ) - my_devices = DeviceFilter()(my_graph.get_opencl_foundation().get_all_devices()); - } - - enforce_cl_retcode( my_devices.size() ? CL_SUCCESS : CL_INVALID_DEVICE, "No devices in the device list" ); - cl_platform_id platform_id = my_devices.begin()->platform(); - for ( opencl_device_list::iterator it = ++my_devices.begin(); it != my_devices.end(); ++it ) - 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 (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; - cl_context ctx = clCreateContext( context_properties, - (cl_uint)cl_device_ids.size(), - cl_device_ids.data(), - NULL, NULL, &err ); - enforce_cl_retcode( err, "Failed to create context" ); - my_cl_context = ctx; - - size_t device_counter = 0; - 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() ) { - 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 ); - } else { - cl_queue_properties props[] = { 0 }; - 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; - // Suppress "declared deprecated" warning for the next line. -#if __TBB_GCC_WARNING_SUPPRESSION_PRESENT -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" -#endif -#if _MSC_VER || __INTEL_COMPILER -#pragma warning( push ) -#if __INTEL_COMPILER -#pragma warning (disable: 1478) -#else -#pragma warning (disable: 4996) -#endif -#endif - cq = clCreateCommandQueue( ctx, (*d).my_cl_device_id, props, &err2 ); -#if _MSC_VER || __INTEL_COMPILER -#pragma warning( pop ) -#endif -#if __TBB_GCC_WARNING_SUPPRESSION_PRESENT -#pragma GCC diagnostic pop -#endif - } - enforce_cl_retcode( err2, "Failed to create command queue" ); - (*d).my_cl_command_queue = cq; - } -} - -const opencl_device_list &opencl_graph::available_devices() { - return get_opencl_foundation().get_all_devices(); -} - -default_opencl_factory &opencl_graph::opencl_factory() { - return get_opencl_foundation().get_default_opencl_factory(); -} - -template -opencl_buffer::opencl_buffer( opencl_graph &g, size_t size ) : my_impl( std::make_shared( size*sizeof(T), g.get_opencl_foundation().get_default_opencl_factory() ) ) {} - - -enum class opencl_program_type { - SOURCE, - PRECOMPILED, - SPIR -}; - -template -class opencl_program : tbb::internal::no_assign { -public: - typedef typename Factory::kernel_type kernel_type; - - 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( 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_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 ); - return kernel; - } - - class file_reader { - public: - file_reader( const std::string& filepath ) { - std::ifstream file_descriptor( filepath, std::ifstream::binary ); - if ( !file_descriptor.is_open() ) { - std::string str = std::string( "Could not open file: " ) + filepath; - std::cerr << str << std::endl; - throw str; - } - file_descriptor.seekg( 0, file_descriptor.end ); - size_t length = size_t( file_descriptor.tellg() ); - file_descriptor.seekg( 0, file_descriptor.beg ); - my_content.resize( length ); - char* begin = &*my_content.begin(); - file_descriptor.read( begin, length ); - file_descriptor.close(); - } - const char* content() { return &*my_content.cbegin(); } - size_t length() { return my_content.length(); } - private: - std::string my_content; - }; - - class opencl_program_builder { - public: - typedef void (CL_CALLBACK *cl_callback_type)(cl_program, void*); - opencl_program_builder( Factory& f, const std::string& name, cl_program program, - cl_uint num_devices, cl_device_id* device_list, - const char* options, cl_callback_type callback, - void* user_data ) { - cl_int err = clBuildProgram( program, num_devices, device_list, options, - callback, user_data ); - if( err == CL_SUCCESS ) - return; - std::string str = std::string( "Failed to build program: " ) + name; - if ( err == CL_BUILD_PROGRAM_FAILURE ) { - const opencl_device_list &devices = f.devices(); - 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, - &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, - output.size(), output.data(), NULL ); - enforce_cl_retcode( query_err, "Failed to get build output" ); - std::cerr << output.data() << std::endl; - } else { - std::cerr << "No build log available" << std::endl; - } - } - } - enforce_cl_retcode( err, str ); - } - }; - - class opencl_device_filter { - public: - template - opencl_device_filter( cl_uint& num_devices, cl_device_id* device_list, - Filter filter, const char* message ) { - for ( cl_uint i = 0; i < num_devices; ++i ) - if ( filter(device_list[i]) ) { - device_list[i--] = device_list[--num_devices]; - } - if ( !num_devices ) - enforce_cl_retcode( CL_DEVICE_NOT_AVAILABLE, message ); - } - }; - - void init( const std::string& ) const { - cl_uint num_devices; - 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( 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 ) { - case opencl_program_type::SOURCE: { - file_reader fr( my_arg_str ); - const char *s[] = { fr.content() }; - const size_t l[] = { fr.length() }; - cl_int 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, - []( const opencl_device& d ) -> bool { - return !d.compiler_available() || !d.linker_available(); - }, "No one device supports building program from sources" ); - opencl_program_builder( - my_factory, my_arg_str, my_cl_program, num_devices, device_list, - options, /*callback*/ NULL, /*user data*/NULL ); - break; - } - case opencl_program_type::SPIR: - options = "-x spir"; - case opencl_program_type::PRECOMPILED: { - file_reader fr( my_arg_str ); - std::vector s( - num_devices, reinterpret_cast(fr.content()) ); - std::vector l( num_devices, fr.length() ); - std::vector bin_statuses( num_devices, -1 ); - cl_int err; - 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 (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( - my_factory, my_arg_str, my_cl_program, num_devices, device_list, - options, /*callback*/ NULL, /*user data*/NULL ); - break; - } - default: - __TBB_ASSERT( false, "Unsupported program type" ); - } - } - - 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_factory; - - template - friend class opencl_factory::kernel; -}; - -template -class opencl_node; - -template -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 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: - 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() ) - {} - - template - opencl_node( opencl_graph &g, const kernel_type& kernel, DeviceSelector d ) - : base_type( g, kernel, d, g.get_opencl_foundation().get_default_opencl_factory() ) - {} -}; - -template -class opencl_node< tuple > : public opencl_node < tuple, queueing, default_opencl_factory > { - typedef opencl_node < tuple, queueing, default_opencl_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() ) - {} - - template - 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 interface9 - -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 -#endif /* __TBB_PREVIEW_OPENCL_NODE */ - -#endif // __TBB_flow_graph_opencl_node_H diff --git a/lib/3rdParty/tbb/include/tbb/gfx_factory.h b/lib/3rdParty/tbb/include/tbb/gfx_factory.h deleted file mode 100644 index 76ca3559..00000000 --- a/lib/3rdParty/tbb/include/tbb/gfx_factory.h +++ /dev/null @@ -1,359 +0,0 @@ -/* - 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 deleted file mode 100644 index fe742020..00000000 --- a/lib/3rdParty/tbb/include/tbb/global_control.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - 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_global_control_H -#define __TBB_global_control_H - -#if !TBB_PREVIEW_GLOBAL_CONTROL && !__TBB_BUILD -#error Set TBB_PREVIEW_GLOBAL_CONTROL before including global_control.h -#endif - -#include "tbb_stddef.h" - -namespace tbb { -namespace interface9 { - -class global_control { -public: - enum parameter { - max_allowed_parallelism, - thread_stack_size, - parameter_max // insert new parameters above this point - }; - - global_control(parameter p, size_t value) : - my_value(value), my_next(NULL), my_param(p) { - __TBB_ASSERT(my_param < parameter_max, "Invalid parameter"); -#if __TBB_WIN8UI_SUPPORT - // For Windows Store* apps it's impossible to set stack size - if (p==thread_stack_size) - return; -#elif __TBB_x86_64 && (_WIN32 || _WIN64) - if (p==thread_stack_size) - __TBB_ASSERT_RELEASE((unsigned)value == value, "Stack size is limited to unsigned int range"); -#endif - if (my_param==max_allowed_parallelism) - __TBB_ASSERT_RELEASE(my_value>0, "max_allowed_parallelism cannot be 0."); - internal_create(); - } - - ~global_control() { - __TBB_ASSERT(my_param < parameter_max, "Invalid parameter. Probably the object was corrupted."); -#if __TBB_WIN8UI_SUPPORT - // For Windows Store* apps it's impossible to set stack size - if (my_param==thread_stack_size) - return; -#endif - internal_destroy(); - } - - static size_t active_value(parameter p) { - __TBB_ASSERT(p < parameter_max, "Invalid parameter"); - return active_value((int)p); - } -private: - size_t my_value; - global_control *my_next; - parameter my_param; - - void __TBB_EXPORTED_METHOD internal_create(); - void __TBB_EXPORTED_METHOD internal_destroy(); - static size_t __TBB_EXPORTED_FUNC active_value(int param); -}; -} // namespace interface9 - -using interface9::global_control; - -} // tbb - -#endif // __TBB_global_control_H diff --git a/lib/3rdParty/tbb/include/tbb/index.html b/lib/3rdParty/tbb/include/tbb/index.html deleted file mode 100644 index 2eddd450..00000000 --- a/lib/3rdParty/tbb/include/tbb/index.html +++ /dev/null @@ -1,29 +0,0 @@ - - - -

    Overview

    -Include files for Intel® Threading Building Blocks classes and functions. - -
    Click here to see all files in the directory. - -

    Directories

    -
    -
    compat -
    Include files for source level compatibility with other frameworks. -
    internal -
    Include files with implementation details; not for direct use. -
    machine -
    Include files for low-level architecture specific functionality; not for direct use. -
    - -
    -Up to parent directory -

    -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. -

    -* Other names and brands may be claimed as the property of others. - - diff --git a/lib/3rdParty/tbb/include/tbb/internal/_aggregator_impl.h b/lib/3rdParty/tbb/include/tbb/internal/_aggregator_impl.h deleted file mode 100644 index 40bbd491..00000000 --- a/lib/3rdParty/tbb/include/tbb/internal/_aggregator_impl.h +++ /dev/null @@ -1,184 +0,0 @@ -/* - 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__aggregator_impl_H -#define __TBB__aggregator_impl_H - -#include "../atomic.h" -#if !__TBBMALLOC_BUILD -#include "../tbb_profiling.h" -#endif - -namespace tbb { -namespace interface6 { -namespace internal { - -using namespace tbb::internal; - -//! aggregated_operation base class -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) {} -}; - -//! Aggregator base class -/** An aggregator for collecting operations coming from multiple sources and executing - them serially on a single thread. operation_type must be derived from - aggregated_operation. The parameter handler_type is a functor that will be passed the - list of operations and is expected to handle each operation appropriately, setting the - status of each operation to non-zero.*/ -template < typename operation_type > -class aggregator_generic { -public: - aggregator_generic() : handler_busy(false) { pending_operations = NULL; } - - //! 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 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; - - // ITT note: &(op->status) tag is used to cover accesses to this op node. This - // thread has created the operation, and now releases it so that the handler - // thread may handle the associated operation w/o triggering a race condition; - // 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. - do { - // 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); - if (!res) { // first in the list; handle the operations. - // ITT note: &pending_operations tag covers access to the handler_busy flag, - // which this waiting handler thread will try to set before entering - // handle_operations. - call_itt_notify(acquired, &pending_operations); - start_handle_operations(handle_operations); - // The operation with 'short' life time can already be destroyed. - if (long_life_time) - __TBB_ASSERT(op->status, NULL); - } - // not first; wait for op to be ready. - else if (!status) { // operation is blocking here. - __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); - } - } - - private: - //! An atomically updated list (aka mailbox) of pending operations - atomic pending_operations; - //! Controls thread access to handle_operations - uintptr_t handler_busy; - - //! Trigger the handling of operations when the handler is free - template < typename handler_type > - void start_handle_operations( handler_type &handle_operations ) { - operation_type *op_list; - - // ITT note: &handler_busy tag covers access to pending_operations as it is passed - // between active and waiting handlers. Below, the waiting handler waits until - // the active handler releases, and the waiting handler acquires &handler_busy as - // it becomes the active_handler. The release point is at the end of this - // function, when all operations in pending_operations have been handled by the - // owner of this aggregator. - call_itt_notify(prepare, &handler_busy); - // get the handler_busy: - // only one thread can possibly spin here at a time - spin_wait_until_eq(handler_busy, uintptr_t(0)); - call_itt_notify(acquired, &handler_busy); - // acquire fence not necessary here due to causality rule and surrounding atomics - __TBB_store_with_release(handler_busy, uintptr_t(1)); - - // ITT note: &pending_operations tag covers access to the handler_busy flag - // itself. Capturing the state of the pending_operations signifies that - // handler_busy has been set and a new active handler will now process that list's - // operations. - call_itt_notify(releasing, &pending_operations); - // grab pending_operations - op_list = pending_operations.fetch_and_store(NULL); - - // handle all the operations - handle_operations(op_list); - - // release the handler - itt_store_word_with_release(handler_busy, uintptr_t(0)); - } -}; - -template < typename handler_type, typename operation_type > -class aggregator : public aggregator_generic { - handler_type handle_operations; -public: - aggregator() {} - explicit aggregator(handler_type h) : handle_operations(h) {} - - void initialize_handler(handler_type h) { handle_operations = h; } - - void execute(operation_type *op) { - aggregator_generic::execute(op, handle_operations); - } -}; - -// the most-compatible friend declaration (vs, gcc, icc) is -// template friend class aggregating_functor; -template -class aggregating_functor { - aggregating_class *fi; -public: - aggregating_functor() {} - aggregating_functor(aggregating_class *fi_) : fi(fi_) {} - void operator()(operation_list* op_list) { fi->handle_operations(op_list); } -}; - -} // namespace internal -} // namespace interface6 - -namespace internal { - using interface6::internal::aggregated_operation; - using interface6::internal::aggregator_generic; - using interface6::internal::aggregator; - using interface6::internal::aggregating_functor; -} // namespace internal - -} // namespace tbb - -#endif // __TBB__aggregator_impl_H diff --git a/lib/3rdParty/tbb/include/tbb/internal/_concurrent_queue_impl.h b/lib/3rdParty/tbb/include/tbb/internal/_concurrent_queue_impl.h deleted file mode 100644 index a99a68f6..00000000 --- a/lib/3rdParty/tbb/include/tbb/internal/_concurrent_queue_impl.h +++ /dev/null @@ -1,1086 +0,0 @@ -/* - 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__concurrent_queue_impl_H -#define __TBB__concurrent_queue_impl_H - -#ifndef __TBB_concurrent_queue_H -#error Do not #include this internal file directly; use public TBB headers instead. -#endif - -#include "../tbb_stddef.h" -#include "../tbb_machine.h" -#include "../atomic.h" -#include "../spin_mutex.h" -#include "../cache_aligned_allocator.h" -#include "../tbb_exception.h" -#include "../tbb_profiling.h" -#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 - #pragma warning (push) - #pragma warning (disable: 4530) -#endif - -#include - -#if !TBB_USE_EXCEPTIONS && _MSC_VER - #pragma warning (pop) -#endif - -namespace tbb { - -#if !__TBB_TEMPLATE_FRIENDS_BROKEN - -// forward declaration -namespace strict_ppl { -template class concurrent_queue; -} - -template class concurrent_bounded_queue; - -#endif - -//! For internal use only. -namespace strict_ppl { - -//! @cond INTERNAL -namespace internal { - -using namespace tbb::internal; - -typedef size_t ticket; - -template class micro_queue ; -template class micro_queue_pop_finalizer ; -template class concurrent_queue_base_v3; -template struct concurrent_queue_rep; - -//! parts of concurrent_queue_rep that do not have references to micro_queue -/** - * For internal use only. - */ -struct concurrent_queue_rep_base : no_copy { - template friend class micro_queue; - template friend class concurrent_queue_base_v3; - -protected: - //! Approximately n_queue/golden ratio - static const size_t phi = 3; - -public: - // must be power of 2 - static const size_t n_queue = 8; - - //! Prefix on a page - struct page { - page* next; - uintptr_t mask; - }; - - atomic head_counter; - char pad1[NFS_MaxLineSize-sizeof(atomic)]; - atomic tail_counter; - char pad2[NFS_MaxLineSize-sizeof(atomic)]; - - //! Always a power of 2 - size_t items_per_page; - - //! Size of an item - size_t item_size; - - //! number of invalid entries in the queue - atomic n_invalid_entries; - - char pad3[NFS_MaxLineSize-sizeof(size_t)-sizeof(size_t)-sizeof(atomic)]; -} ; - -inline bool is_valid_page(const concurrent_queue_rep_base::page* p) { - return uintptr_t(p)>1; -} - -//! Abstract class to define interface for page allocation/deallocation -/** - * For internal use only. - */ -class concurrent_queue_page_allocator -{ - template friend class micro_queue ; - template friend class micro_queue_pop_finalizer ; -protected: - virtual ~concurrent_queue_page_allocator() {} -private: - virtual concurrent_queue_rep_base::page* allocate_page() = 0; - virtual void deallocate_page( concurrent_queue_rep_base::page* p ) = 0; -} ; - -#if _MSC_VER && !defined(__INTEL_COMPILER) -// unary minus operator applied to unsigned type, result still unsigned -#pragma warning( push ) -#pragma warning( disable: 4146 ) -#endif - -//! A queue using simple locking. -/** For efficiency, this class has no constructor. - The caller is expected to zero-initialize it. */ -template -class micro_queue : no_copy { -public: - typedef void (*item_constructor_t)(T* location, const void* src); -private: - typedef concurrent_queue_rep_base::page page; - - //! Class used to ensure exception-safety of method "pop" - class destroyer: no_copy { - T& my_value; - public: - destroyer( T& value ) : my_value(value) {} - ~destroyer() {my_value.~T();} - }; - - void copy_item( page& dst, size_t dindex, const void* src, item_constructor_t construct_item ) { - construct_item( &get_ref(dst, dindex), src ); - } - - void copy_item( page& dst, size_t dindex, const page& src, size_t sindex, - item_constructor_t construct_item ) - { - T& src_item = get_ref( const_cast(src), sindex ); - construct_item( &get_ref(dst, dindex), static_cast(&src_item) ); - } - - void assign_and_destroy_item( void* dst, page& src, size_t index ) { - T& from = get_ref(src,index); - destroyer d(from); - *static_cast(dst) = tbb::internal::move( from ); - } - - void spin_wait_until_my_turn( atomic& counter, ticket k, concurrent_queue_rep_base& rb ) const ; - -public: - friend class micro_queue_pop_finalizer; - - struct padded_page: page { - //! Not defined anywhere - exists to quiet warnings. - padded_page(); - //! Not defined anywhere - exists to quiet warnings. - void operator=( const padded_page& ); - //! Must be last field. - T last; - }; - - static T& get_ref( page& p, size_t index ) { - return (&static_cast(static_cast(&p))->last)[index]; - } - - atomic head_page; - atomic head_counter; - - atomic tail_page; - atomic tail_counter; - - spin_mutex page_mutex; - - void push( const void* item, ticket k, concurrent_queue_base_v3& base, - item_constructor_t construct_item ) ; - - bool pop( void* dst, ticket k, concurrent_queue_base_v3& base ) ; - - micro_queue& assign( const micro_queue& src, concurrent_queue_base_v3& base, - item_constructor_t construct_item ) ; - - page* make_copy( concurrent_queue_base_v3& base, const page* src_page, size_t begin_in_page, - size_t end_in_page, ticket& g_index, item_constructor_t construct_item ) ; - - void invalidate_page_and_rethrow( ticket k ) ; -}; - -template -void micro_queue::spin_wait_until_my_turn( atomic& counter, ticket k, concurrent_queue_rep_base& rb ) const { - for( atomic_backoff b(true);;b.pause() ) { - ticket c = counter; - if( c==k ) return; - else if( c&1 ) { - ++rb.n_invalid_entries; - throw_exception( eid_bad_last_alloc ); - } - } -} - -template -void micro_queue::push( const void* item, ticket k, concurrent_queue_base_v3& base, - item_constructor_t construct_item ) -{ - k &= -concurrent_queue_rep_base::n_queue; - page* p = NULL; - size_t index = modulo_power_of_two( k/concurrent_queue_rep_base::n_queue, base.my_rep->items_per_page); - if( !index ) { - __TBB_TRY { - concurrent_queue_page_allocator& pa = base; - p = pa.allocate_page(); - } __TBB_CATCH (...) { - ++base.my_rep->n_invalid_entries; - invalidate_page_and_rethrow( k ); - } - p->mask = 0; - p->next = NULL; - } - - if( tail_counter != k ) spin_wait_until_my_turn( tail_counter, k, *base.my_rep ); - call_itt_notify(acquired, &tail_counter); - - if( p ) { - spin_mutex::scoped_lock lock( page_mutex ); - page* q = tail_page; - if( is_valid_page(q) ) - q->next = p; - else - head_page = p; - tail_page = p; - } else { - p = tail_page; - } - - __TBB_TRY { - copy_item( *p, index, item, construct_item ); - // If no exception was thrown, mark item as present. - itt_hide_store_word(p->mask, p->mask | uintptr_t(1)<n_invalid_entries; - call_itt_notify(releasing, &tail_counter); - tail_counter += concurrent_queue_rep_base::n_queue; - __TBB_RETHROW(); - } -} - -template -bool micro_queue::pop( void* dst, ticket k, concurrent_queue_base_v3& base ) { - k &= -concurrent_queue_rep_base::n_queue; - if( head_counter!=k ) spin_wait_until_eq( head_counter, k ); - 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 ); - 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)<n_invalid_entries; - } - } - return success; -} - -template -micro_queue& micro_queue::assign( const micro_queue& src, concurrent_queue_base_v3& base, - item_constructor_t construct_item ) -{ - head_counter = src.head_counter; - tail_counter = src.tail_counter; - - const page* srcp = src.head_page; - if( is_valid_page(srcp) ) { - ticket g_index = head_counter; - __TBB_TRY { - size_t n_items = (tail_counter-head_counter)/concurrent_queue_rep_base::n_queue; - size_t index = modulo_power_of_two( head_counter/concurrent_queue_rep_base::n_queue, base.my_rep->items_per_page ); - size_t end_in_first_page = (index+n_itemsitems_per_page)?(index+n_items):base.my_rep->items_per_page; - - head_page = make_copy( base, srcp, index, end_in_first_page, g_index, construct_item ); - page* cur_page = head_page; - - if( srcp != src.tail_page ) { - for( srcp = srcp->next; srcp!=src.tail_page; srcp=srcp->next ) { - cur_page->next = make_copy( base, srcp, 0, base.my_rep->items_per_page, g_index, construct_item ); - cur_page = cur_page->next; - } - - __TBB_ASSERT( srcp==src.tail_page, NULL ); - size_t last_index = modulo_power_of_two( tail_counter/concurrent_queue_rep_base::n_queue, base.my_rep->items_per_page ); - if( last_index==0 ) last_index = base.my_rep->items_per_page; - - cur_page->next = make_copy( base, srcp, 0, last_index, g_index, construct_item ); - cur_page = cur_page->next; - } - tail_page = cur_page; - } __TBB_CATCH (...) { - invalidate_page_and_rethrow( g_index ); - } - } else { - head_page = tail_page = NULL; - } - return *this; -} - -template -void micro_queue::invalidate_page_and_rethrow( ticket k ) { - // Append an invalid page at address 1 so that no more pushes are allowed. - page* invalid_page = (page*)uintptr_t(1); - { - spin_mutex::scoped_lock lock( page_mutex ); - itt_store_word_with_release(tail_counter, k+concurrent_queue_rep_base::n_queue+1); - page* q = tail_page; - if( is_valid_page(q) ) - q->next = invalid_page; - else - head_page = invalid_page; - tail_page = invalid_page; - } - __TBB_RETHROW(); -} - -template -concurrent_queue_rep_base::page* micro_queue::make_copy( concurrent_queue_base_v3& base, - const concurrent_queue_rep_base::page* src_page, size_t begin_in_page, size_t end_in_page, - ticket& g_index, item_constructor_t construct_item ) -{ - concurrent_queue_page_allocator& pa = base; - page* new_page = pa.allocate_page(); - new_page->next = NULL; - new_page->mask = src_page->mask; - for( ; begin_in_page!=end_in_page; ++begin_in_page, ++g_index ) - if( new_page->mask & uintptr_t(1)< -class micro_queue_pop_finalizer: no_copy { - typedef concurrent_queue_rep_base::page page; - ticket my_ticket; - micro_queue& my_queue; - page* my_page; - concurrent_queue_page_allocator& allocator; -public: - micro_queue_pop_finalizer( micro_queue& queue, concurrent_queue_base_v3& b, ticket k, page* p ) : - my_ticket(k), my_queue(queue), my_page(p), allocator(b) - {} - ~micro_queue_pop_finalizer() ; -}; - -template -micro_queue_pop_finalizer::~micro_queue_pop_finalizer() { - page* p = my_page; - if( is_valid_page(p) ) { - spin_mutex::scoped_lock lock( my_queue.page_mutex ); - page* q = p->next; - my_queue.head_page = q; - if( !is_valid_page(q) ) { - my_queue.tail_page = NULL; - } - } - itt_store_word_with_release(my_queue.head_counter, my_ticket); - if( is_valid_page(p) ) { - allocator.deallocate_page( p ); - } -} - -#if _MSC_VER && !defined(__INTEL_COMPILER) -#pragma warning( pop ) -#endif // warning 4146 is back - -template class concurrent_queue_iterator_rep ; -template class concurrent_queue_iterator_base_v3; - -//! representation of concurrent_queue_base -/** - * the class inherits from concurrent_queue_rep_base and defines an array of micro_queue's - */ -template -struct concurrent_queue_rep : public concurrent_queue_rep_base { - micro_queue array[n_queue]; - - //! Map ticket to an array index - static size_t index( ticket k ) { - return k*phi%n_queue; - } - - micro_queue& choose( ticket k ) { - // The formula here approximates LRU in a cache-oblivious way. - return array[index(k)]; - } -}; - -//! base class of concurrent_queue -/** - * The class implements the interface defined by concurrent_queue_page_allocator - * and has a pointer to an instance of concurrent_queue_rep. - */ -template -class concurrent_queue_base_v3: public concurrent_queue_page_allocator { -private: - //! Internal representation - concurrent_queue_rep* my_rep; - - friend struct concurrent_queue_rep; - friend class micro_queue; - friend class concurrent_queue_iterator_rep; - friend class concurrent_queue_iterator_base_v3; - -protected: - typedef typename concurrent_queue_rep::page page; - -private: - typedef typename micro_queue::padded_page padded_page; - typedef typename micro_queue::item_constructor_t item_constructor_t; - - 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 )); - } - - 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 ); - } - - //! custom allocator - virtual void *allocate_block( size_t n ) = 0; - - //! custom de-allocator - virtual void deallocate_block( void *p, size_t n ) = 0; - -protected: - 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; iarray[i].tail_page==NULL, "pages were not freed properly" ); -#endif /* TBB_USE_ASSERT */ - cache_aligned_allocator >().deallocate(my_rep,1); - } - - //! Enqueue item at tail of queue - void internal_push( const void* src, item_constructor_t construct_item ) { - concurrent_queue_rep& r = *my_rep; - ticket k = r.tail_counter++; - r.choose(k).push( src, k, *this, construct_item ); - } - - //! Attempt to dequeue item from queue. - /** NULL if there was no item to dequeue. */ - bool internal_try_pop( void* dst ) ; - - //! Get size of queue; result may be invalid if queue is modified concurrently - size_t internal_size() const ; - - //! check if the queue is empty; thread safe - bool internal_empty() const ; - - //! free any remaining pages - /* note that the name may be misleading, but it remains so due to a historical accident. */ - void internal_finish_clear() ; - - //! Obsolete - void internal_throw_exception() const { - throw_exception( eid_bad_alloc ); - } - - //! copy or move internal representation - void assign( const concurrent_queue_base_v3& src, item_constructor_t construct_item ) ; - -#if __TBB_CPP11_RVALUE_REF_PRESENT - //! swap internal representation - void internal_swap( concurrent_queue_base_v3& src ) { - std::swap( my_rep, src.my_rep ); - } -#endif /* __TBB_CPP11_RVALUE_REF_PRESENT */ -}; - -template -concurrent_queue_base_v3::concurrent_queue_base_v3() { - const size_t item_size = sizeof(T); - my_rep = cache_aligned_allocator >().allocate(1); - __TBB_ASSERT( (size_t)my_rep % NFS_GetLineSize()==0, "alignment error" ); - __TBB_ASSERT( (size_t)&my_rep->head_counter % NFS_GetLineSize()==0, "alignment error" ); - __TBB_ASSERT( (size_t)&my_rep->tail_counter % NFS_GetLineSize()==0, "alignment error" ); - __TBB_ASSERT( (size_t)&my_rep->array % NFS_GetLineSize()==0, "alignment error" ); - memset(my_rep,0,sizeof(concurrent_queue_rep)); - my_rep->item_size = item_size; - my_rep->items_per_page = item_size<= 8 ? 32 : - item_size<= 16 ? 16 : - item_size<= 32 ? 8 : - item_size<= 64 ? 4 : - item_size<=128 ? 2 : - 1; -} - -template -bool concurrent_queue_base_v3::internal_try_pop( void* dst ) { - concurrent_queue_rep& r = *my_rep; - ticket k; - do { - k = r.head_counter; - for(;;) { - if( (ptrdiff_t)(r.tail_counter-k)<=0 ) { - // Queue is empty - return false; - } - // Queue had item with ticket k when we looked. Attempt to get that item. - ticket tk=k; -#if defined(_MSC_VER) && defined(_Wp64) - #pragma warning (push) - #pragma warning (disable: 4267) -#endif - k = r.head_counter.compare_and_swap( tk+1, tk ); -#if defined(_MSC_VER) && defined(_Wp64) - #pragma warning (pop) -#endif - if( k==tk ) - break; - // Another thread snatched the item, retry. - } - } while( !r.choose( k ).pop( dst, k, *this ) ); - return true; -} - -template -size_t concurrent_queue_base_v3::internal_size() const { - concurrent_queue_rep& r = *my_rep; - __TBB_ASSERT( sizeof(ptrdiff_t)<=sizeof(size_t), NULL ); - ticket hc = r.head_counter; - size_t nie = r.n_invalid_entries; - ticket tc = r.tail_counter; - __TBB_ASSERT( hc!=tc || !nie, NULL ); - ptrdiff_t sz = tc-hc-nie; - return sz<0 ? 0 : size_t(sz); -} - -template -bool concurrent_queue_base_v3::internal_empty() const { - concurrent_queue_rep& r = *my_rep; - ticket tc = r.tail_counter; - ticket hc = r.head_counter; - // if tc!=r.tail_counter, the queue was not empty at some point between the two reads. - return tc==r.tail_counter && tc==hc+r.n_invalid_entries ; -} - -template -void concurrent_queue_base_v3::internal_finish_clear() { - concurrent_queue_rep& r = *my_rep; - size_t nq = r.n_queue; - for( size_t i=0; i -void concurrent_queue_base_v3::assign( const concurrent_queue_base_v3& src, - item_constructor_t construct_item ) -{ - concurrent_queue_rep& r = *my_rep; - r.items_per_page = src.my_rep->items_per_page; - - // copy concurrent_queue_rep data - r.head_counter = src.my_rep->head_counter; - r.tail_counter = src.my_rep->tail_counter; - r.n_invalid_entries = src.my_rep->n_invalid_entries; - - // copy or move micro_queues - for( size_t i = 0; i < r.n_queue; ++i ) - r.array[i].assign( src.my_rep->array[i], *this, construct_item); - - __TBB_ASSERT( r.head_counter==src.my_rep->head_counter && r.tail_counter==src.my_rep->tail_counter, - "the source concurrent queue should not be concurrently modified." ); -} - -template class concurrent_queue_iterator; - -template -class concurrent_queue_iterator_rep: no_assign { - typedef typename micro_queue::padded_page padded_page; -public: - ticket head_counter; - const concurrent_queue_base_v3& my_queue; - typename concurrent_queue_base_v3::page* array[concurrent_queue_rep::n_queue]; - concurrent_queue_iterator_rep( const concurrent_queue_base_v3& queue ) : - head_counter(queue.my_rep->head_counter), - my_queue(queue) - { - for( size_t k=0; k::n_queue; ++k ) - array[k] = queue.my_rep->array[k].head_page; - } - - //! Set item to point to kth element. Return true if at end of queue or item is marked valid; false otherwise. - bool get_item( T*& item, size_t k ) ; -}; - -template -bool concurrent_queue_iterator_rep::get_item( T*& item, size_t k ) { - if( k==my_queue.my_rep->tail_counter ) { - item = NULL; - return true; - } else { - typename concurrent_queue_base_v3::page* p = array[concurrent_queue_rep::index(k)]; - __TBB_ASSERT(p,NULL); - size_t i = modulo_power_of_two( k/concurrent_queue_rep::n_queue, my_queue.my_rep->items_per_page ); - item = µ_queue::get_ref(*p,i); - return (p->mask & uintptr_t(1)< -class concurrent_queue_iterator_base_v3 : no_assign { - //! Represents concurrent_queue over which we are iterating. - /** NULL if one past last element in queue. */ - concurrent_queue_iterator_rep* my_rep; - - template - friend bool operator==( const concurrent_queue_iterator& i, const concurrent_queue_iterator& j ); - - template - friend bool operator!=( const concurrent_queue_iterator& i, const concurrent_queue_iterator& j ); -protected: - //! Pointer to current item - Value* my_item; - - //! Default constructor - concurrent_queue_iterator_base_v3() : my_rep(NULL), my_item(NULL) { -#if __TBB_GCC_OPTIMIZER_ORDERING_BROKEN - __TBB_compiler_fence(); -#endif - } - - //! Copy constructor - concurrent_queue_iterator_base_v3( const concurrent_queue_iterator_base_v3& i ) - : no_assign(), my_rep(NULL), my_item(NULL) { - assign(i); - } - - //! Construct iterator pointing to head of queue. - concurrent_queue_iterator_base_v3( const concurrent_queue_base_v3& queue ) ; - - //! Assignment - void assign( const concurrent_queue_iterator_base_v3& other ) ; - - //! Advance iterator one step towards tail of queue. - void advance() ; - - //! Destructor - ~concurrent_queue_iterator_base_v3() { - cache_aligned_allocator >().deallocate(my_rep, 1); - my_rep = NULL; - } -}; - -template -concurrent_queue_iterator_base_v3::concurrent_queue_iterator_base_v3( const concurrent_queue_base_v3& queue ) { - my_rep = cache_aligned_allocator >().allocate(1); - new( my_rep ) concurrent_queue_iterator_rep(queue); - size_t k = my_rep->head_counter; - if( !my_rep->get_item(my_item, k) ) advance(); -} - -template -void concurrent_queue_iterator_base_v3::assign( const concurrent_queue_iterator_base_v3& other ) { - if( my_rep!=other.my_rep ) { - if( my_rep ) { - cache_aligned_allocator >().deallocate(my_rep, 1); - my_rep = NULL; - } - if( other.my_rep ) { - my_rep = cache_aligned_allocator >().allocate(1); - new( my_rep ) concurrent_queue_iterator_rep( *other.my_rep ); - } - } - my_item = other.my_item; -} - -template -void concurrent_queue_iterator_base_v3::advance() { - __TBB_ASSERT( my_item, "attempt to increment iterator past end of queue" ); - size_t k = my_rep->head_counter; - const concurrent_queue_base_v3& queue = my_rep->my_queue; -#if TBB_USE_ASSERT - Value* tmp; - my_rep->get_item(tmp,k); - __TBB_ASSERT( my_item==tmp, NULL ); -#endif /* TBB_USE_ASSERT */ - size_t i = modulo_power_of_two( k/concurrent_queue_rep::n_queue, queue.my_rep->items_per_page ); - if( i==queue.my_rep->items_per_page-1 ) { - typename concurrent_queue_base_v3::page*& root = my_rep->array[concurrent_queue_rep::index(k)]; - root = root->next; - } - // advance k - my_rep->head_counter = ++k; - if( !my_rep->get_item(my_item, k) ) advance(); -} - -//! Similar to C++0x std::remove_cv -/** "tbb_" prefix added to avoid overload confusion with C++0x implementations. */ -template struct tbb_remove_cv {typedef T type;}; -template struct tbb_remove_cv {typedef T type;}; -template struct tbb_remove_cv {typedef T type;}; -template struct tbb_remove_cv {typedef T type;}; - -//! Meets requirements of a forward iterator for STL. -/** Value is either the T or const T type of the container. - @ingroup containers */ -template -class concurrent_queue_iterator: public concurrent_queue_iterator_base_v3::type>, - public std::iterator { -#if !__TBB_TEMPLATE_FRIENDS_BROKEN - template - friend class ::tbb::strict_ppl::concurrent_queue; -#else -public: -#endif - //! Construct iterator pointing to head of queue. - explicit concurrent_queue_iterator( const concurrent_queue_base_v3::type>& queue ) : - concurrent_queue_iterator_base_v3::type>(queue) - { - } - -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) - {} - - //! Iterator assignment - concurrent_queue_iterator& operator=( const concurrent_queue_iterator& other ) { - this->assign(other); - return *this; - } - - //! Reference to current item - Value& operator*() const { - return *static_cast(this->my_item); - } - - Value* operator->() const {return &operator*();} - - //! Advance to next item in queue - concurrent_queue_iterator& operator++() { - this->advance(); - return *this; - } - - //! Post increment - Value* operator++(int) { - Value* result = &operator*(); - operator++(); - return result; - } -}; // concurrent_queue_iterator - - -template -bool operator==( const concurrent_queue_iterator& i, const concurrent_queue_iterator& j ) { - return i.my_item==j.my_item; -} - -template -bool operator!=( const concurrent_queue_iterator& i, const concurrent_queue_iterator& j ) { - return i.my_item!=j.my_item; -} - -} // namespace internal - -//! @endcond - -} // namespace strict_ppl - -//! @cond INTERNAL -namespace internal { - -class concurrent_queue_rep; -class concurrent_queue_iterator_rep; -class concurrent_queue_iterator_base_v3; -template class concurrent_queue_iterator; - -//! For internal use only. -/** Type-independent portion of concurrent_queue. - @ingroup containers */ -class concurrent_queue_base_v3: no_copy { -private: - //! Internal representation - concurrent_queue_rep* my_rep; - - friend class concurrent_queue_rep; - friend struct micro_queue; - friend class micro_queue_pop_finalizer; - friend class concurrent_queue_iterator_rep; - friend class concurrent_queue_iterator_base_v3; -protected: - //! Prefix on a page - struct page { - page* next; - uintptr_t mask; - }; - - //! Capacity of the queue - ptrdiff_t my_capacity; - - //! Always a power of 2 - size_t items_per_page; - - //! Size of an item - size_t item_size; - - enum copy_specifics { copy, move }; - -#if __TBB_PROTECTED_NESTED_CLASS_BROKEN -public: -#endif - template - struct padded_page: page { - //! Not defined anywhere - exists to quiet warnings. - padded_page(); - //! Not defined anywhere - exists to quiet warnings. - void operator=( const padded_page& ); - //! Must be last field. - T last; - }; - -private: - virtual void copy_item( page& dst, size_t index, const void* src ) = 0; - virtual void assign_and_destroy_item( void* dst, page& src, size_t index ) = 0; -protected: - __TBB_EXPORTED_METHOD concurrent_queue_base_v3( size_t item_size ); - virtual __TBB_EXPORTED_METHOD ~concurrent_queue_base_v3(); - - //! Enqueue item at tail of queue using copy operation - void __TBB_EXPORTED_METHOD internal_push( const void* src ); - - //! Dequeue item from head of queue - void __TBB_EXPORTED_METHOD internal_pop( void* dst ); - - //! Abort all pending queue operations - void __TBB_EXPORTED_METHOD internal_abort(); - - //! Attempt to enqueue item onto queue using copy operation - bool __TBB_EXPORTED_METHOD internal_push_if_not_full( const void* src ); - - //! Attempt to dequeue item from queue. - /** NULL if there was no item to dequeue. */ - bool __TBB_EXPORTED_METHOD internal_pop_if_present( void* dst ); - - //! Get size of queue - ptrdiff_t __TBB_EXPORTED_METHOD internal_size() const; - - //! Check if the queue is emtpy - bool __TBB_EXPORTED_METHOD internal_empty() const; - - //! Set the queue capacity - void __TBB_EXPORTED_METHOD internal_set_capacity( ptrdiff_t capacity, size_t element_size ); - - //! custom allocator - virtual page *allocate_page() = 0; - - //! custom de-allocator - virtual void deallocate_page( page *p ) = 0; - - //! free any remaining pages - /* note that the name may be misleading, but it remains so due to a historical accident. */ - void __TBB_EXPORTED_METHOD internal_finish_clear() ; - - //! throw an exception - void __TBB_EXPORTED_METHOD internal_throw_exception() const; - - //! copy internal representation - void __TBB_EXPORTED_METHOD assign( const concurrent_queue_base_v3& src ) ; - -#if __TBB_CPP11_RVALUE_REF_PRESENT - //! swap queues - void internal_swap( concurrent_queue_base_v3& src ) { - std::swap( my_capacity, src.my_capacity ); - std::swap( items_per_page, src.items_per_page ); - std::swap( item_size, src.item_size ); - std::swap( my_rep, src.my_rep ); - } -#endif /* __TBB_CPP11_RVALUE_REF_PRESENT */ - - //! Enqueues item at tail of queue using specified operation (copy or move) - void internal_insert_item( const void* src, copy_specifics op_type ); - - //! Attempts to enqueue at tail of queue using specified operation (copy or move) - bool internal_insert_if_not_full( const void* src, copy_specifics op_type ); - - //! Assigns one queue to another using specified operation (copy or move) - void internal_assign( const concurrent_queue_base_v3& src, copy_specifics op_type ); -private: - virtual void copy_page_item( page& dst, size_t dindex, const page& src, size_t sindex ) = 0; -}; - -//! For internal use only. -/** Backward compatible modification of concurrent_queue_base_v3 - @ingroup containers */ -class concurrent_queue_base_v8: public concurrent_queue_base_v3 { -protected: - concurrent_queue_base_v8( size_t item_sz ) : concurrent_queue_base_v3( item_sz ) {} - - //! move items - void __TBB_EXPORTED_METHOD move_content( concurrent_queue_base_v8& src ) ; - - //! Attempt to enqueue item onto queue using move operation - bool __TBB_EXPORTED_METHOD internal_push_move_if_not_full( const void* src ); - - //! Enqueue item at tail of queue using move operation - void __TBB_EXPORTED_METHOD internal_push_move( const void* src ); -private: - friend struct micro_queue; - virtual void move_page_item( page& dst, size_t dindex, const page& src, size_t sindex ) = 0; - virtual void move_item( page& dst, size_t index, const void* src ) = 0; -}; - -//! Type-independent portion of concurrent_queue_iterator. -/** @ingroup containers */ -class concurrent_queue_iterator_base_v3 { - //! concurrent_queue over which we are iterating. - /** NULL if one past last element in queue. */ - concurrent_queue_iterator_rep* my_rep; - - template - friend bool operator==( const concurrent_queue_iterator& i, const concurrent_queue_iterator& j ); - - template - friend bool operator!=( const concurrent_queue_iterator& i, const concurrent_queue_iterator& j ); - - void initialize( const concurrent_queue_base_v3& queue, size_t offset_of_data ); -protected: - //! Pointer to current item - void* my_item; - - //! Default constructor - concurrent_queue_iterator_base_v3() : my_rep(NULL), my_item(NULL) {} - - //! Copy constructor - concurrent_queue_iterator_base_v3( const concurrent_queue_iterator_base_v3& i ) : my_rep(NULL), my_item(NULL) { - assign(i); - } - - //! Obsolete entry point for constructing iterator pointing to head of queue. - /** Does not work correctly for SSE types. */ - __TBB_EXPORTED_METHOD concurrent_queue_iterator_base_v3( const concurrent_queue_base_v3& queue ); - - //! Construct iterator pointing to head of queue. - __TBB_EXPORTED_METHOD concurrent_queue_iterator_base_v3( const concurrent_queue_base_v3& queue, size_t offset_of_data ); - - //! Assignment - void __TBB_EXPORTED_METHOD assign( const concurrent_queue_iterator_base_v3& i ); - - //! Advance iterator one step towards tail of queue. - void __TBB_EXPORTED_METHOD advance(); - - //! Destructor - __TBB_EXPORTED_METHOD ~concurrent_queue_iterator_base_v3(); -}; - -typedef concurrent_queue_iterator_base_v3 concurrent_queue_iterator_base; - -//! Meets requirements of a forward iterator for STL. -/** Value is either the T or const T type of the container. - @ingroup containers */ -template -class concurrent_queue_iterator: public concurrent_queue_iterator_base, - public std::iterator { - -#if !__TBB_TEMPLATE_FRIENDS_BROKEN - template - friend class ::tbb::concurrent_bounded_queue; -#else -public: -#endif - - //! Construct iterator pointing to head of 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)) - { - } - -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(other) - {} - - //! Iterator assignment - concurrent_queue_iterator& operator=( const concurrent_queue_iterator& other ) { - assign(other); - return *this; - } - - //! Reference to current item - Value& operator*() const { - return *static_cast(my_item); - } - - Value* operator->() const {return &operator*();} - - //! Advance to next item in queue - concurrent_queue_iterator& operator++() { - advance(); - return *this; - } - - //! Post increment - Value* operator++(int) { - Value* result = &operator*(); - operator++(); - return result; - } -}; // concurrent_queue_iterator - - -template -bool operator==( const concurrent_queue_iterator& i, const concurrent_queue_iterator& j ) { - return i.my_item==j.my_item; -} - -template -bool operator!=( const concurrent_queue_iterator& i, const concurrent_queue_iterator& j ) { - return i.my_item!=j.my_item; -} - -} // namespace internal; - -//! @endcond - -} // namespace tbb - -#endif /* __TBB__concurrent_queue_impl_H */ diff --git a/lib/3rdParty/tbb/include/tbb/internal/_concurrent_unordered_impl.h b/lib/3rdParty/tbb/include/tbb/internal/_concurrent_unordered_impl.h deleted file mode 100644 index b34bc16f..00000000 --- a/lib/3rdParty/tbb/include/tbb/internal/_concurrent_unordered_impl.h +++ /dev/null @@ -1,1528 +0,0 @@ -/* - 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. - - - - -*/ - -/* Container implementations in this header are based on PPL implementations - provided by Microsoft. */ - -#ifndef __TBB__concurrent_unordered_impl_H -#define __TBB__concurrent_unordered_impl_H -#if !defined(__TBB_concurrent_unordered_map_H) && !defined(__TBB_concurrent_unordered_set_H) && !defined(__TBB_concurrent_hash_map_H) -#error Do not #include this internal file directly; use public TBB headers instead. -#endif - -#include "../tbb_stddef.h" - -#if !TBB_USE_EXCEPTIONS && _MSC_VER - // Suppress "C++ exception handler used, but unwind semantics are not enabled" warning in STL headers - #pragma warning (push) - #pragma warning (disable: 4530) -#endif - -#include -#include // Need std::pair -#include // Need std::equal_to (in ../concurrent_unordered_*.h) -#include // For tbb_hasher -#include // Need std::memset -#include __TBB_STD_SWAP_HEADER - -#if !TBB_USE_EXCEPTIONS && _MSC_VER - #pragma warning (pop) -#endif - -#include "../atomic.h" -#include "../tbb_exception.h" -#include "../tbb_allocator.h" - -#if __TBB_INITIALIZER_LISTS_PRESENT - #include -#endif - -#include "_tbb_hash_compare_impl.h" - -namespace tbb { -namespace interface5 { -//! @cond INTERNAL -namespace internal { - -template -class split_ordered_list; -template -class concurrent_unordered_base; - -// Forward list iterators (without skipping dummy elements) -template -class flist_iterator : public std::iterator -{ - template - friend class split_ordered_list; - template - friend class concurrent_unordered_base; - template - friend class flist_iterator; - - typedef typename Solist::nodeptr_t nodeptr_t; -public: - typedef typename Solist::value_type value_type; - typedef typename Solist::difference_type difference_type; - typedef typename Solist::pointer pointer; - typedef typename Solist::reference reference; - - flist_iterator() : my_node_ptr(0) {} - flist_iterator( const flist_iterator &other ) - : my_node_ptr(other.my_node_ptr) {} - - reference operator*() const { return my_node_ptr->my_element; } - pointer operator->() const { return &**this; } - - flist_iterator& operator++() { - my_node_ptr = my_node_ptr->my_next; - return *this; - } - - flist_iterator operator++(int) { - flist_iterator tmp = *this; - ++*this; - return tmp; - } - -protected: - flist_iterator(nodeptr_t pnode) : my_node_ptr(pnode) {} - nodeptr_t get_node_ptr() const { return my_node_ptr; } - - nodeptr_t my_node_ptr; - - template - friend bool operator==( const flist_iterator &i, const flist_iterator &j ); - template - friend bool operator!=( const flist_iterator& i, const flist_iterator& j ); -}; - -template -bool operator==( const flist_iterator &i, const flist_iterator &j ) { - return i.my_node_ptr == j.my_node_ptr; -} -template -bool operator!=( const flist_iterator& i, const flist_iterator& j ) { - return i.my_node_ptr != j.my_node_ptr; -} - -// Split-order list iterators, needed to skip dummy elements -template -class solist_iterator : public flist_iterator -{ - typedef flist_iterator base_type; - typedef typename Solist::nodeptr_t nodeptr_t; - using base_type::get_node_ptr; - template - friend class split_ordered_list; - template - friend class solist_iterator; - template - friend bool operator==( const solist_iterator &i, const solist_iterator &j ); - template - friend bool operator!=( const solist_iterator& i, const solist_iterator& j ); - - const Solist *my_list_ptr; - solist_iterator(nodeptr_t pnode, const Solist *plist) : base_type(pnode), my_list_ptr(plist) {} - -public: - typedef typename Solist::value_type value_type; - typedef typename Solist::difference_type difference_type; - typedef typename Solist::pointer pointer; - typedef typename Solist::reference reference; - - solist_iterator() {} - solist_iterator(const solist_iterator &other ) - : base_type(other), my_list_ptr(other.my_list_ptr) {} - - reference operator*() const { - return this->base_type::operator*(); - } - - pointer operator->() const { - return (&**this); - } - - solist_iterator& operator++() { - do ++(*(base_type *)this); - while (get_node_ptr() != NULL && get_node_ptr()->is_dummy()); - - return (*this); - } - - solist_iterator operator++(int) { - solist_iterator tmp = *this; - do ++*this; - while (get_node_ptr() != NULL && get_node_ptr()->is_dummy()); - - return (tmp); - } -}; - -template -bool operator==( const solist_iterator &i, const solist_iterator &j ) { - return i.my_node_ptr == j.my_node_ptr && i.my_list_ptr == j.my_list_ptr; -} -template -bool operator!=( const solist_iterator& i, const solist_iterator& j ) { - return i.my_node_ptr != j.my_node_ptr || i.my_list_ptr != j.my_list_ptr; -} - -// Forward type and class definitions -typedef size_t sokey_t; - - -// Forward list in which elements are sorted in a split-order -template -class split_ordered_list -{ -public: - typedef split_ordered_list self_type; - typedef typename Allocator::template rebind::other allocator_type; - struct node; - typedef node *nodeptr_t; - - typedef typename allocator_type::size_type size_type; - typedef typename allocator_type::difference_type difference_type; - typedef typename allocator_type::pointer pointer; - typedef typename allocator_type::const_pointer const_pointer; - typedef typename allocator_type::reference reference; - typedef typename allocator_type::const_reference const_reference; - typedef typename allocator_type::value_type value_type; - - typedef solist_iterator const_iterator; - typedef solist_iterator iterator; - typedef flist_iterator raw_const_iterator; - typedef flist_iterator raw_iterator; - - // Node that holds the element in a split-ordered list - struct node : tbb::internal::no_assign - { - private: - // for compilers that try to generate default constructors though they are not needed. - node(); // VS 2008, 2010, 2012 - public: - // Initialize the node with the given order key - void init(sokey_t order_key) { - my_order_key = order_key; - my_next = NULL; - } - - // Return the order key (needed for hashing) - sokey_t get_order_key() const { // TODO: remove - return my_order_key; - } - - // Inserts the new element in the list in an atomic fashion - nodeptr_t atomic_set_next(nodeptr_t new_node, nodeptr_t current_node) - { - // Try to change the next pointer on the current element to a new element, only if it still points to the cached next - nodeptr_t exchange_node = tbb::internal::as_atomic(my_next).compare_and_swap(new_node, current_node); - - if (exchange_node == current_node) // TODO: why this branch? - { - // Operation succeeded, return the new node - return new_node; - } - else - { - // Operation failed, return the "interfering" node - return exchange_node; - } - } - - // Checks if this element in the list is a dummy, order enforcing node. Dummy nodes are used by buckets - // in the hash table to quickly index into the right subsection of the split-ordered list. - bool is_dummy() const { - return (my_order_key & 0x1) == 0; - } - - - nodeptr_t my_next; // Next element in the list - value_type my_element; // Element storage - sokey_t my_order_key; // Order key for this element - }; - - // Allocate a new node with the given order key; used to allocate dummy nodes - nodeptr_t create_node(sokey_t order_key) { - nodeptr_t pnode = my_node_allocator.allocate(1); - pnode->init(order_key); - return (pnode); - } - - // 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, - /*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 - __TBB_TRY { - new(static_cast(&pnode->my_element)) T(tbb::internal::forward(t)); - pnode->init(order_key); - } __TBB_CATCH(...) { - my_node_allocator.deallocate(pnode, 1); - __TBB_RETHROW(); - } - - 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){ - nodeptr_t pnode = my_node_allocator.allocate(1); - - //TODO: use RAII scoped guard instead of explicit catch - __TBB_TRY { - new(static_cast(&pnode->my_element)) T(__TBB_PACK_EXPANSION(tbb::internal::forward(args))); - } __TBB_CATCH(...) { - my_node_allocator.deallocate(pnode, 1); - __TBB_RETHROW(); - } - - return (pnode); - } - - split_ordered_list(allocator_type a = allocator_type()) - : my_node_allocator(a), my_element_count(0) - { - // Immediately allocate a dummy node with order key of 0. This node - // will always be the head of the list. - my_head = create_node(sokey_t(0)); - } - - ~split_ordered_list() - { - // Clear the list - clear(); - - // Remove the head element which is not cleared by clear() - nodeptr_t pnode = my_head; - my_head = NULL; - - __TBB_ASSERT(pnode != NULL && pnode->my_next == NULL, "Invalid head list node"); - - destroy_node(pnode); - } - - // Common forward list functions - - allocator_type get_allocator() const { - return (my_node_allocator); - } - - void clear() { - nodeptr_t pnext; - nodeptr_t pnode = my_head; - - __TBB_ASSERT(my_head != NULL, "Invalid head list node"); - pnext = pnode->my_next; - pnode->my_next = NULL; - pnode = pnext; - - while (pnode != NULL) - { - pnext = pnode->my_next; - destroy_node(pnode); - pnode = pnext; - } - - my_element_count = 0; - } - - // Returns a first non-dummy element in the SOL - iterator begin() { - return first_real_iterator(raw_begin()); - } - - // Returns a first non-dummy element in the SOL - const_iterator begin() const { - return first_real_iterator(raw_begin()); - } - - iterator end() { - return (iterator(0, this)); - } - - const_iterator end() const { - return (const_iterator(0, this)); - } - - const_iterator cbegin() const { - return (((const self_type *)this)->begin()); - } - - const_iterator cend() const { - return (((const self_type *)this)->end()); - } - - // Checks if the number of elements (non-dummy) is 0 - bool empty() const { - return (my_element_count == 0); - } - - // Returns the number of non-dummy elements in the list - size_type size() const { - return my_element_count; - } - - // Returns the maximum size of the list, determined by the allocator - size_type max_size() const { - return my_node_allocator.max_size(); - } - - // Swaps 'this' list with the passed in one - void swap(self_type& other) - { - if (this == &other) - { - // Nothing to do - return; - } - - std::swap(my_element_count, other.my_element_count); - std::swap(my_head, other.my_head); - } - - // Split-order list functions - - // Returns a first element in the SOL, which is always a dummy - raw_iterator raw_begin() { - return raw_iterator(my_head); - } - - // Returns a first element in the SOL, which is always a dummy - raw_const_iterator raw_begin() const { - return raw_const_iterator(my_head); - } - - raw_iterator raw_end() { - return raw_iterator(0); - } - - raw_const_iterator raw_end() const { - return raw_const_iterator(0); - } - - static sokey_t get_order_key(const raw_const_iterator& it) { - return it.get_node_ptr()->get_order_key(); - } - - static sokey_t get_safe_order_key(const raw_const_iterator& it) { - if( !it.get_node_ptr() ) return ~sokey_t(0); - return it.get_node_ptr()->get_order_key(); - } - - // Returns a public iterator version of the internal iterator. Public iterator must not - // be a dummy private iterator. - iterator get_iterator(raw_iterator it) { - __TBB_ASSERT(it.get_node_ptr() == NULL || !it.get_node_ptr()->is_dummy(), "Invalid user node (dummy)"); - return iterator(it.get_node_ptr(), this); - } - - // Returns a public iterator version of the internal iterator. Public iterator must not - // be a dummy private iterator. - const_iterator get_iterator(raw_const_iterator it) const { - __TBB_ASSERT(it.get_node_ptr() == NULL || !it.get_node_ptr()->is_dummy(), "Invalid user node (dummy)"); - return const_iterator(it.get_node_ptr(), this); - } - - // Returns a non-const version of the raw_iterator - raw_iterator get_iterator(raw_const_iterator it) { - return raw_iterator(it.get_node_ptr()); - } - - // Returns a non-const version of the iterator - static iterator get_iterator(const_iterator it) { - return iterator(it.my_node_ptr, it.my_list_ptr); - } - - // Returns a public iterator version of a first non-dummy internal iterator at or after - // the passed in internal iterator. - iterator first_real_iterator(raw_iterator it) - { - // Skip all dummy, internal only iterators - while (it != raw_end() && it.get_node_ptr()->is_dummy()) - ++it; - - return iterator(it.get_node_ptr(), this); - } - - // Returns a public iterator version of a first non-dummy internal iterator at or after - // the passed in internal iterator. - const_iterator first_real_iterator(raw_const_iterator it) const - { - // Skip all dummy, internal only iterators - while (it != raw_end() && it.get_node_ptr()->is_dummy()) - ++it; - - return const_iterator(it.get_node_ptr(), this); - } - - // Erase an element using the allocator - void destroy_node(nodeptr_t pnode) { - if (!pnode->is_dummy()) my_node_allocator.destroy(pnode); - my_node_allocator.deallocate(pnode, 1); - } - - // Try to insert a new element in the list. - // If insert fails, return the node that was inserted instead. - static nodeptr_t try_insert_atomic(nodeptr_t previous, nodeptr_t new_node, nodeptr_t current_node) { - new_node->my_next = current_node; - return previous->atomic_set_next(new_node, current_node); - } - - // Insert a new element between passed in iterators - std::pair try_insert(raw_iterator it, raw_iterator next, nodeptr_t pnode, size_type *new_count) - { - nodeptr_t inserted_node = try_insert_atomic(it.get_node_ptr(), pnode, next.get_node_ptr()); - - if (inserted_node == pnode) - { - // If the insert succeeded, check that the order is correct and increment the element count - check_range(it, next); - *new_count = tbb::internal::as_atomic(my_element_count).fetch_and_increment(); - return std::pair(iterator(pnode, this), true); - } - else - { - return std::pair(end(), false); - } - } - - // Insert a new dummy element, starting search at a parent dummy element - raw_iterator insert_dummy(raw_iterator it, sokey_t order_key) - { - raw_iterator last = raw_end(); - raw_iterator where = it; - - __TBB_ASSERT(where != last, "Invalid head node"); - - ++where; - - // Create a dummy element up front, even though it may be discarded (due to concurrent insertion) - nodeptr_t dummy_node = create_node(order_key); - - for (;;) - { - __TBB_ASSERT(it != last, "Invalid head list node"); - - // If the head iterator is at the end of the list, or past the point where this dummy - // node needs to be inserted, then try to insert it. - if (where == last || get_order_key(where) > order_key) - { - __TBB_ASSERT(get_order_key(it) < order_key, "Invalid node order in the list"); - - // Try to insert it in the right place - nodeptr_t inserted_node = try_insert_atomic(it.get_node_ptr(), dummy_node, where.get_node_ptr()); - - if (inserted_node == dummy_node) - { - // Insertion succeeded, check the list for order violations - check_range(it, where); - return raw_iterator(dummy_node); - } - else - { - // Insertion failed: either dummy node was inserted by another thread, or - // a real element was inserted at exactly the same place as dummy node. - // 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; - continue; - } - } - else if (get_order_key(where) == order_key) - { - // Another dummy node with the same value found, discard the new one. - destroy_node(dummy_node); - return where; - } - - // Move the iterator forward - it = where; - ++where; - } - - } - - // This erase function can handle both real and dummy nodes - void erase_node(raw_iterator previous, raw_const_iterator& where) - { - nodeptr_t pnode = (where++).get_node_ptr(); - nodeptr_t prevnode = previous.get_node_ptr(); - __TBB_ASSERT(prevnode->my_next == pnode, "Erase must take consecutive iterators"); - prevnode->my_next = pnode->my_next; - - destroy_node(pnode); - } - - // Erase the element (previous node needs to be passed because this is a forward only list) - iterator erase_node(raw_iterator previous, const_iterator where) - { - raw_const_iterator it = where; - erase_node(previous, it); - my_element_count--; - - return get_iterator(first_real_iterator(it)); - } - - // Move all elements from the passed in split-ordered list to this one - void move_all(self_type& source) - { - raw_const_iterator first = source.raw_begin(); - raw_const_iterator last = source.raw_end(); - - if (first == last) - return; - - nodeptr_t previous_node = my_head; - raw_const_iterator begin_iterator = first++; - - // Move all elements one by one, including dummy ones - for (raw_const_iterator it = first; it != last;) - { - nodeptr_t pnode = it.get_node_ptr(); - - nodeptr_t dummy_node = pnode->is_dummy() ? create_node(pnode->get_order_key()) : create_node(pnode->get_order_key(), pnode->my_element); - previous_node = try_insert_atomic(previous_node, dummy_node, NULL); - __TBB_ASSERT(previous_node != NULL, "Insertion must succeed"); - raw_const_iterator where = it++; - source.erase_node(get_iterator(begin_iterator), where); - } - check_range(); - } - - -private: - //Need to setup private fields of split_ordered_list in move constructor and assignment of concurrent_unordered_base - template - friend class concurrent_unordered_base; - - // Check the list for order violations - void check_range( raw_iterator first, raw_iterator last ) - { -#if TBB_USE_ASSERT - for (raw_iterator it = first; it != last; ++it) - { - raw_iterator next = it; - ++next; - - __TBB_ASSERT(next == raw_end() || get_order_key(next) >= get_order_key(it), "!!! List order inconsistency !!!"); - } -#else - tbb::internal::suppress_unused_warning(first, last); -#endif - } - void check_range() - { -#if TBB_USE_ASSERT - check_range( raw_begin(), raw_end() ); -#endif - } - - typename allocator_type::template rebind::other my_node_allocator; // allocator object for nodes - size_type my_element_count; // Total item count, not counting dummy nodes - nodeptr_t my_head; // pointer to head node -}; - -#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) -#pragma warning(push) -#pragma warning(disable: 4127) // warning C4127: conditional expression is constant -#endif - -template -class concurrent_unordered_base : public Traits -{ -protected: - // Type definitions - typedef concurrent_unordered_base self_type; - typedef typename Traits::value_type value_type; - typedef typename Traits::key_type key_type; - typedef typename Traits::hash_compare hash_compare; - typedef typename Traits::allocator_type allocator_type; - typedef typename hash_compare::hasher hasher; - typedef typename hash_compare::key_equal key_equal; - typedef typename allocator_type::pointer pointer; - typedef typename allocator_type::const_pointer const_pointer; - typedef typename allocator_type::reference reference; - typedef typename allocator_type::const_reference const_reference; - typedef typename allocator_type::size_type size_type; - typedef typename allocator_type::difference_type difference_type; - typedef split_ordered_list solist_t; - typedef typename solist_t::nodeptr_t nodeptr_t; - // Iterators that walk the entire split-order list, including dummy nodes - typedef typename solist_t::raw_iterator raw_iterator; - typedef typename solist_t::raw_const_iterator raw_const_iterator; - typedef typename solist_t::iterator iterator; // TODO: restore const iterator for unordered_sets - typedef typename solist_t::const_iterator const_iterator; - typedef iterator local_iterator; - typedef const_iterator const_local_iterator; - using Traits::my_hash_compare; - using Traits::get_key; - using Traits::allow_multimapping; - - static const size_type initial_bucket_number = 8; // Initial number of buckets -private: - typedef std::pair pairii_t; - typedef std::pair paircc_t; - - static size_type const pointers_per_table = sizeof(size_type) * 8; // One bucket segment per bit - static const size_type initial_bucket_load = 4; // Initial maximum number of elements per bucket - - struct call_internal_clear_on_exit{ - concurrent_unordered_base* my_instance; - call_internal_clear_on_exit(concurrent_unordered_base* instance) : my_instance(instance) {} - void dismiss(){ my_instance = NULL;} - ~call_internal_clear_on_exit(){ - if (my_instance){ - my_instance->internal_clear(); - } - } - }; -protected: - // Constructors/Destructors - concurrent_unordered_base(size_type n_of_buckets = initial_bucket_number, - const hash_compare& hc = hash_compare(), const allocator_type& a = allocator_type()) - : Traits(hc), my_solist(a), - my_allocator(a), my_maximum_bucket_size((float) initial_bucket_load) - { - if( n_of_buckets == 0) ++n_of_buckets; - my_number_of_buckets = size_type(1)<<__TBB_Log2((uintptr_t)n_of_buckets*2-1); // round up to power of 2 - internal_init(); - } - - concurrent_unordered_base(const concurrent_unordered_base& right, const allocator_type& a) - : Traits(right.my_hash_compare), my_solist(a), my_allocator(a) - { - internal_init(); - internal_copy(right); - } - - concurrent_unordered_base(const concurrent_unordered_base& right) - : Traits(right.my_hash_compare), my_solist(right.get_allocator()), my_allocator(right.get_allocator()) - { - //FIXME:exception safety seems to be broken here - internal_init(); - internal_copy(right); - } - -#if __TBB_CPP11_RVALUE_REF_PRESENT - concurrent_unordered_base(concurrent_unordered_base&& right) - : Traits(right.my_hash_compare), my_solist(right.get_allocator()), my_allocator(right.get_allocator()) - { - internal_init(); - swap(right); - } - - concurrent_unordered_base(concurrent_unordered_base&& right, const allocator_type& a) - : Traits(right.my_hash_compare), my_solist(a), my_allocator(a) - { - call_internal_clear_on_exit clear_buckets_on_exception(this); - - internal_init(); - if (a == right.get_allocator()){ - this->swap(right); - }else{ - my_maximum_bucket_size = right.my_maximum_bucket_size; - my_number_of_buckets = right.my_number_of_buckets; - my_solist.my_element_count = right.my_solist.my_element_count; - - if (! right.my_solist.empty()){ - nodeptr_t previous_node = my_solist.my_head; - - // Move all elements one by one, including dummy ones - for (raw_const_iterator it = ++(right.my_solist.raw_begin()), last = right.my_solist.raw_end(); it != last; ++it) - { - const nodeptr_t pnode = it.get_node_ptr(); - nodeptr_t node; - if (pnode->is_dummy()) { - node = my_solist.create_node(pnode->get_order_key()); - size_type bucket = __TBB_ReverseBits(pnode->get_order_key()) % my_number_of_buckets; - set_bucket(bucket, node); - }else{ - node = my_solist.create_node(pnode->get_order_key(), std::move(pnode->my_element)); - } - - previous_node = my_solist.try_insert_atomic(previous_node, node, NULL); - __TBB_ASSERT(previous_node != NULL, "Insertion of node failed. Concurrent inserts in constructor ?"); - } - my_solist.check_range(); - } - } - - clear_buckets_on_exception.dismiss(); - } - -#endif // __TBB_CPP11_RVALUE_REF_PRESENT - - concurrent_unordered_base& operator=(const concurrent_unordered_base& right) { - if (this != &right) - internal_copy(right); - return (*this); - } - -#if __TBB_CPP11_RVALUE_REF_PRESENT - concurrent_unordered_base& operator=(concurrent_unordered_base&& other) - { - if(this != &other){ - typedef typename tbb::internal::allocator_traits::propagate_on_container_move_assignment pocma_t; - if(pocma_t::value || this->my_allocator == other.my_allocator) { - concurrent_unordered_base trash (std::move(*this)); - swap(other); - if (pocma_t::value) { - using std::swap; - //TODO: swapping allocators here may be a problem, replace with single direction moving - swap(this->my_solist.my_node_allocator, other.my_solist.my_node_allocator); - swap(this->my_allocator, other.my_allocator); - } - } else { - concurrent_unordered_base moved_copy(std::move(other),this->my_allocator); - this->swap(moved_copy); - } - } - return *this; - } - -#endif // __TBB_CPP11_RVALUE_REF_PRESENT - -#if __TBB_INITIALIZER_LISTS_PRESENT - //! assignment operator from initializer_list - concurrent_unordered_base& operator=(std::initializer_list il) - { - this->clear(); - this->insert(il.begin(),il.end()); - return (*this); - } -#endif // __TBB_INITIALIZER_LISTS_PRESENT - - - ~concurrent_unordered_base() { - // Delete all node segments - internal_clear(); - } - -public: - allocator_type get_allocator() const { - return my_solist.get_allocator(); - } - - // Size and capacity function - bool empty() const { - return my_solist.empty(); - } - - size_type size() const { - return my_solist.size(); - } - - size_type max_size() const { - return my_solist.max_size(); - } - - // Iterators - iterator begin() { - return my_solist.begin(); - } - - const_iterator begin() const { - return my_solist.begin(); - } - - iterator end() { - return my_solist.end(); - } - - const_iterator end() const { - return my_solist.end(); - } - - const_iterator cbegin() const { - return my_solist.cbegin(); - } - - const_iterator cend() const { - return my_solist.cend(); - } - - // Parallel traversal support - class const_range_type : tbb::internal::no_assign { - const concurrent_unordered_base &my_table; - raw_const_iterator my_begin_node; - raw_const_iterator my_end_node; - mutable raw_const_iterator my_midpoint_node; - public: - //! Type for size of a range - typedef typename concurrent_unordered_base::size_type size_type; - typedef typename concurrent_unordered_base::value_type value_type; - typedef typename concurrent_unordered_base::reference reference; - typedef typename concurrent_unordered_base::difference_type difference_type; - typedef typename concurrent_unordered_base::const_iterator iterator; - - //! True if range is empty. - bool empty() const {return my_begin_node == my_end_node;} - - //! True if range can be partitioned into two subranges. - bool is_divisible() const { - return my_midpoint_node != my_end_node; - } - //! Split range. - const_range_type( const_range_type &r, split ) : - my_table(r.my_table), my_end_node(r.my_end_node) - { - r.my_end_node = my_begin_node = r.my_midpoint_node; - __TBB_ASSERT( !empty(), "Splitting despite the range is not divisible" ); - __TBB_ASSERT( !r.empty(), "Splitting despite the range is not divisible" ); - set_midpoint(); - r.set_midpoint(); - } - //! Init range with container and grainsize specified - const_range_type( const concurrent_unordered_base &a_table ) : - my_table(a_table), my_begin_node(a_table.my_solist.begin()), - my_end_node(a_table.my_solist.end()) - { - set_midpoint(); - } - iterator begin() const { return my_table.my_solist.get_iterator(my_begin_node); } - iterator end() const { return my_table.my_solist.get_iterator(my_end_node); } - //! The grain size for this range. - size_type grainsize() const { return 1; } - - //! Set my_midpoint_node to point approximately half way between my_begin_node and my_end_node. - void set_midpoint() const { - if( my_begin_node == my_end_node ) // not divisible - my_midpoint_node = my_end_node; - else { - sokey_t begin_key = solist_t::get_safe_order_key(my_begin_node); - sokey_t end_key = solist_t::get_safe_order_key(my_end_node); - size_t mid_bucket = __TBB_ReverseBits( begin_key + (end_key-begin_key)/2 ) % my_table.my_number_of_buckets; - while ( !my_table.is_initialized(mid_bucket) ) mid_bucket = my_table.get_parent(mid_bucket); - if(__TBB_ReverseBits(mid_bucket) > begin_key) { - // found a dummy_node between begin and end - my_midpoint_node = my_table.my_solist.first_real_iterator(my_table.get_bucket( mid_bucket )); - } - else { - // didn't find a dummy node between begin and end. - my_midpoint_node = my_end_node; - } -#if TBB_USE_ASSERT - { - sokey_t mid_key = solist_t::get_safe_order_key(my_midpoint_node); - __TBB_ASSERT( begin_key < mid_key, "my_begin_node is after my_midpoint_node" ); - __TBB_ASSERT( mid_key <= end_key, "my_midpoint_node is after my_end_node" ); - } -#endif // TBB_USE_ASSERT - } - } - }; - - class range_type : public const_range_type { - public: - typedef typename concurrent_unordered_base::iterator iterator; - //! Split range. - range_type( range_type &r, split ) : const_range_type( r, split() ) {} - //! Init range with container and grainsize specified - range_type( const concurrent_unordered_base &a_table ) : const_range_type(a_table) {} - - iterator begin() const { return solist_t::get_iterator( const_range_type::begin() ); } - iterator end() const { return solist_t::get_iterator( const_range_type::end() ); } - }; - - range_type range() { - return range_type( *this ); - } - - const_range_type range() const { - return const_range_type( *this ); - } - - // Modifiers - std::pair insert(const value_type& value) { - return internal_insert(value); - } - - iterator insert(const_iterator, const value_type& value) { - // Ignore hint - return insert(value).first; - } - -#if __TBB_CPP11_RVALUE_REF_PRESENT - std::pair insert(value_type&& value) { - return internal_insert(std::move(value)); - } - - iterator insert(const_iterator, value_type&& value) { - // Ignore hint - return insert(std::move(value)).first; - } - -#if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT - template - std::pair emplace(Args&&... args) { - nodeptr_t pnode = my_solist.create_node_v(tbb::internal::forward(args)...); - const sokey_t hashed_element_key = (sokey_t) my_hash_compare(get_key(pnode->my_element)); - const sokey_t order_key = split_order_key_regular(hashed_element_key); - pnode->init(order_key); - - return internal_insert(pnode->my_element, pnode); - } - - template - iterator emplace_hint(const_iterator, Args&&... args) { - // Ignore hint - return emplace(tbb::internal::forward(args)...).first; - } - -#endif // __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT -#endif // __TBB_CPP11_RVALUE_REF_PRESENT - - template - void insert(Iterator first, Iterator last) { - for (Iterator it = first; it != last; ++it) - insert(*it); - } - -#if __TBB_INITIALIZER_LISTS_PRESENT - //! Insert initializer list - void insert(std::initializer_list il) { - insert(il.begin(), il.end()); - } -#endif - - iterator unsafe_erase(const_iterator where) { - return internal_erase(where); - } - - iterator unsafe_erase(const_iterator first, const_iterator last) { - while (first != last) - unsafe_erase(first++); - return my_solist.get_iterator(first); - } - - size_type unsafe_erase(const key_type& key) { - pairii_t where = equal_range(key); - size_type item_count = internal_distance(where.first, where.second); - unsafe_erase(where.first, where.second); - return item_count; - } - - void swap(concurrent_unordered_base& right) { - if (this != &right) { - std::swap(my_hash_compare, right.my_hash_compare); // TODO: check what ADL meant here - my_solist.swap(right.my_solist); - internal_swap_buckets(right); - std::swap(my_number_of_buckets, right.my_number_of_buckets); - std::swap(my_maximum_bucket_size, right.my_maximum_bucket_size); - } - } - - // Observers - hasher hash_function() const { - return my_hash_compare.my_hash_object; - } - - key_equal key_eq() const { - return my_hash_compare.my_key_compare_object; - } - - void clear() { - // Clear list - my_solist.clear(); - - // Clear buckets - internal_clear(); - - // Initialize bucket 0 - __TBB_ASSERT(my_buckets[0] == NULL, NULL); - raw_iterator dummy_node = my_solist.raw_begin(); - set_bucket(0, dummy_node); - } - - // Lookup - iterator find(const key_type& key) { - return internal_find(key); - } - - const_iterator find(const key_type& key) const { - return const_cast(this)->internal_find(key); - } - - size_type count(const key_type& key) const { - if(allow_multimapping) { - paircc_t answer = equal_range(key); - size_type item_count = internal_distance(answer.first, answer.second); - return item_count; - } else { - return const_cast(this)->internal_find(key) == end()?0:1; - } - } - - std::pair equal_range(const key_type& key) { - return internal_equal_range(key); - } - - std::pair equal_range(const key_type& key) const { - return const_cast(this)->internal_equal_range(key); - } - - // Bucket interface - for debugging - size_type unsafe_bucket_count() const { - return my_number_of_buckets; - } - - size_type unsafe_max_bucket_count() const { - return segment_size(pointers_per_table-1); - } - - size_type unsafe_bucket_size(size_type bucket) { - size_type item_count = 0; - if (is_initialized(bucket)) { - raw_iterator it = get_bucket(bucket); - ++it; - for (; it != my_solist.raw_end() && !it.get_node_ptr()->is_dummy(); ++it) - ++item_count; - } - return item_count; - } - - size_type unsafe_bucket(const key_type& key) const { - sokey_t order_key = (sokey_t) my_hash_compare(key); - size_type bucket = order_key % my_number_of_buckets; - return bucket; - } - - // If the bucket is initialized, return a first non-dummy element in it - local_iterator unsafe_begin(size_type bucket) { - if (!is_initialized(bucket)) - return end(); - - raw_iterator it = get_bucket(bucket); - return my_solist.first_real_iterator(it); - } - - // If the bucket is initialized, return a first non-dummy element in it - const_local_iterator unsafe_begin(size_type bucket) const - { - if (!is_initialized(bucket)) - return end(); - - raw_const_iterator it = get_bucket(bucket); - return my_solist.first_real_iterator(it); - } - - // @REVIEW: Takes O(n) - // Returns the iterator after the last non-dummy element in the bucket - local_iterator unsafe_end(size_type bucket) - { - if (!is_initialized(bucket)) - return end(); - - raw_iterator it = get_bucket(bucket); - - // Find the end of the bucket, denoted by the dummy element - do ++it; - while(it != my_solist.raw_end() && !it.get_node_ptr()->is_dummy()); - - // Return the first real element past the end of the bucket - return my_solist.first_real_iterator(it); - } - - // @REVIEW: Takes O(n) - // Returns the iterator after the last non-dummy element in the bucket - const_local_iterator unsafe_end(size_type bucket) const - { - if (!is_initialized(bucket)) - return end(); - - raw_const_iterator it = get_bucket(bucket); - - // Find the end of the bucket, denoted by the dummy element - do ++it; - while(it != my_solist.raw_end() && !it.get_node_ptr()->is_dummy()); - - // Return the first real element past the end of the bucket - return my_solist.first_real_iterator(it); - } - - const_local_iterator unsafe_cbegin(size_type bucket) const { - return ((const self_type *) this)->unsafe_begin(bucket); - } - - const_local_iterator unsafe_cend(size_type bucket) const { - return ((const self_type *) this)->unsafe_end(bucket); - } - - // Hash policy - float load_factor() const { - return (float) size() / (float) unsafe_bucket_count(); - } - - float max_load_factor() const { - return my_maximum_bucket_size; - } - - void max_load_factor(float newmax) { - if (newmax != newmax || newmax < 0) - tbb::internal::throw_exception(tbb::internal::eid_invalid_load_factor); - my_maximum_bucket_size = newmax; - } - - // This function is a noop, because the underlying split-ordered list - // is already sorted, so an increase in the bucket number will be - // reflected next time this bucket is touched. - void rehash(size_type buckets) { - size_type current_buckets = my_number_of_buckets; - if (current_buckets >= buckets) - return; - my_number_of_buckets = size_type(1)<<__TBB_Log2((uintptr_t)buckets*2-1); // round up to power of 2 - } - -private: - - // Initialize the hash and keep the first bucket open - void internal_init() { - // Allocate an array of segment pointers - memset(my_buckets, 0, pointers_per_table * sizeof(void *)); - - // Initialize bucket 0 - raw_iterator dummy_node = my_solist.raw_begin(); - set_bucket(0, dummy_node); - } - - void internal_clear() { - for (size_type index = 0; index < pointers_per_table; ++index) { - if (my_buckets[index] != NULL) { - size_type sz = segment_size(index); - for (size_type index2 = 0; index2 < sz; ++index2) - my_allocator.destroy(&my_buckets[index][index2]); - my_allocator.deallocate(my_buckets[index], sz); - my_buckets[index] = 0; - } - } - } - - void internal_copy(const self_type& right) { - clear(); - - my_maximum_bucket_size = right.my_maximum_bucket_size; - my_number_of_buckets = right.my_number_of_buckets; - - __TBB_TRY { - insert(right.begin(), right.end()); - my_hash_compare = right.my_hash_compare; - } __TBB_CATCH(...) { - my_solist.clear(); - __TBB_RETHROW(); - } - } - - void internal_swap_buckets(concurrent_unordered_base& right) - { - // Swap all node segments - for (size_type index = 0; index < pointers_per_table; ++index) - { - raw_iterator * iterator_pointer = my_buckets[index]; - my_buckets[index] = right.my_buckets[index]; - right.my_buckets[index] = iterator_pointer; - } - } - - //TODO: why not use std::distance? - // Hash APIs - static size_type internal_distance(const_iterator first, const_iterator last) - { - size_type num = 0; - - for (const_iterator it = first; it != last; ++it) - ++num; - - return num; - } - - // Insert an element in the hash given its value - template - std::pair internal_insert(__TBB_FORWARDING_REF(ValueType) value, nodeptr_t pnode = NULL) - { - const key_type *pkey = &get_key(value); - sokey_t hash_key = (sokey_t) my_hash_compare(*pkey); - size_type new_count = 0; - sokey_t order_key = split_order_key_regular(hash_key); - raw_iterator previous = prepare_bucket(hash_key); - raw_iterator last = my_solist.raw_end(); - __TBB_ASSERT(previous != last, "Invalid head node"); - - // First node is a dummy node - 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), *pkey))) // TODO: fix negation - { - 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 'previous' and 'where' - std::pair result = my_solist.try_insert(previous, where, pnode, &new_count); - - if (result.second) - { - // Insertion succeeded, adjust the table size, if needed - adjust_table_size(new_count, my_number_of_buckets); - return result; - } - else - { - // Insertion failed: either the same node was inserted by another thread, or - // another element was inserted at exactly the same place as this node. - // 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 = previous; - continue; - } - } - else if (!allow_multimapping && solist_t::get_order_key(where) == order_key && - !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 - previous = where; - } - } - - // Find the element in the split-ordered list - iterator internal_find(const key_type& 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 = prepare_bucket(hash_key); it != last; ++it) - { - if (solist_t::get_order_key(it) > order_key) - { - // If the order key is smaller than the current order key, the element - // is not in the hash. - return end(); - } - else if (solist_t::get_order_key(it) == order_key) - { - // 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)) // TODO: fix negation - return my_solist.get_iterator(it); - } - } - - return end(); - } - - // Erase an element from the list. This is not a concurrency safe function. - iterator internal_erase(const_iterator it) - { - 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(); - __TBB_ASSERT(previous != last, "Invalid head node"); - - // First node is a dummy node - 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); - } - } - - // Return the [begin, end) pair of iterators with the same key values. - // This operation makes sense only if mapping is many-to-one. - pairii_t internal_equal_range(const key_type& 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 = 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)) // TODO: fix negation; also below - { - iterator first = my_solist.get_iterator(it); - iterator last = first; - do ++last; while( allow_multimapping && last != end() && !my_hash_compare(get_key(*last), key) ); - return pairii_t(first, last); - } - } - - return pairii_t(end(), end()); - } - - // Bucket APIs - void init_bucket(size_type bucket) - { - // Bucket 0 has no parent. - __TBB_ASSERT( bucket != 0, "The first bucket must always be initialized"); - - size_type parent_bucket = get_parent(bucket); - - // All parent_bucket buckets have to be initialized before this bucket is - if (!is_initialized(parent_bucket)) - init_bucket(parent_bucket); - - raw_iterator parent = get_bucket(parent_bucket); - - // Create a dummy first node in this bucket - raw_iterator dummy_node = my_solist.insert_dummy(parent, split_order_key_dummy(bucket)); - set_bucket(bucket, dummy_node); - } - - void adjust_table_size(size_type total_elements, size_type current_size) - { - // Grow the table by a factor of 2 if possible and needed - if ( ((float) total_elements / (float) current_size) > my_maximum_bucket_size ) - { - // Double the size of the hash only if size has not changed in between loads - my_number_of_buckets.compare_and_swap(2u*current_size, current_size); - //Simple "my_number_of_buckets.compare_and_swap( current_size<<1, current_size );" does not work for VC8 - //due to overzealous compiler warnings in /Wp64 mode - } - } - - size_type get_parent(size_type bucket) const - { - // Unsets bucket's most significant turned-on bit - size_type msb = __TBB_Log2((uintptr_t)bucket); - return bucket & ~(size_type(1) << msb); - } - - - // Dynamic sized array (segments) - //! @return segment index of given index in the array - static size_type segment_index_of( size_type index ) { - return size_type( __TBB_Log2( uintptr_t(index|1) ) ); - } - - //! @return the first array index of given segment - static size_type segment_base( size_type k ) { - return (size_type(1)< my_number_of_buckets; // Current table size - solist_t my_solist; // List where all the elements are kept - typename allocator_type::template rebind::other my_allocator; // Allocator object for segments - float my_maximum_bucket_size; // Maximum size of the bucket - atomic my_buckets[pointers_per_table]; // The segment table -}; -#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) -#pragma warning(pop) // warning 4127 is back -#endif - -} // namespace internal -//! @endcond -} // namespace interface5 -} // namespace tbb -#endif // __TBB__concurrent_unordered_impl_H 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 deleted file mode 100644 index 7d2c3aef..00000000 --- a/lib/3rdParty/tbb/include/tbb/internal/_flow_graph_async_msg_impl.h +++ /dev/null @@ -1,221 +0,0 @@ -/* - 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 deleted file mode 100644 index 92278caf..00000000 --- a/lib/3rdParty/tbb/include/tbb/internal/_flow_graph_impl.h +++ /dev/null @@ -1,839 +0,0 @@ -/* - 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_impl_H -#define __TBB__flow_graph_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) - -namespace internal { - - typedef tbb::internal::uint64_t tag_value; - - using tbb::internal::strip; - - namespace graph_policy_namespace { - - struct rejecting { }; - struct reserving { }; - struct queueing { }; - - // K == type of field used for key-matching. Each tag-matching port will be provided - // functor that, given an object accepted by the port, will return the - /// field of type K being used for matching. - template::type > > - struct key_matching { - typedef K key_type; - typedef typename strip::type base_key_type; - typedef KHash hash_compare_type; - }; - - // old tag_matching join's new specifier - typedef key_matching tag_matching; - } - -// -------------- function_body containers ---------------------- - - //! A functor that takes no input and generates a value of type Output - template< typename Output > - class source_body : tbb::internal::no_assign { - public: - virtual ~source_body() {} - virtual bool operator()(Output &output) = 0; - virtual source_body* clone() = 0; - }; - - //! The leaf for source_body - template< typename Output, typename Body> - class source_body_leaf : public source_body { - public: - source_body_leaf( const Body &_body ) : body(_body) { } - 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; } - private: - Body body; - }; - - //! A functor that takes an Input and generates an Output - template< typename Input, typename Output > - class function_body : tbb::internal::no_assign { - public: - virtual ~function_body() {} - virtual Output operator()(const Input &input) = 0; - virtual function_body* clone() = 0; - }; - - //! the leaf for function_body - template - class function_body_leaf : public function_body< Input, Output > { - public: - function_body_leaf( const B &_body ) : body(_body) { } - Output operator()(const Input &i) __TBB_override { return body(i); } - B get_body() { return body; } - function_body_leaf* clone() __TBB_override { - return new function_body_leaf< Input, Output, B >(body); - } - private: - B body; - }; - - //! the leaf for function_body specialized for Input and output of continue_msg - template - 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 ) __TBB_override { - body(i); - return i; - } - B get_body() { return body; } - function_body_leaf* clone() __TBB_override { - return new function_body_leaf< continue_msg, continue_msg, B >(body); - } - private: - B body; - }; - - //! the leaf for function_body specialized for Output of continue_msg - template - 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) __TBB_override { - body(i); - return continue_msg(); - } - B get_body() { return body; } - function_body_leaf* clone() __TBB_override { - return new function_body_leaf< Input, continue_msg, B >(body); - } - private: - B body; - }; - - //! the leaf for function_body specialized for Input of continue_msg - template - 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) __TBB_override { - return body(i); - } - B get_body() { return body; } - function_body_leaf* clone() __TBB_override { - return new function_body_leaf< continue_msg, Output, B >(body); - } - private: - B body; - }; - - //! function_body that takes an Input and a set of output ports - template - class multifunction_body : tbb::internal::no_assign { - public: - virtual ~multifunction_body () {} - virtual void operator()(const Input &/* input*/, OutputSet &/*oset*/) = 0; - virtual multifunction_body* clone() = 0; - virtual void* get_body_ptr() = 0; - }; - - //! leaf for multifunction. OutputSet can be a std::tuple or a vector. - template - class multifunction_body_leaf : public multifunction_body { - public: - multifunction_body_leaf(const B &_body) : body(_body) { } - void operator()(const Input &input, OutputSet &oset) __TBB_override { - body(input, oset); // body may explicitly put() to one or more of oset. - } - void* get_body_ptr() __TBB_override { return &body; } - multifunction_body_leaf* clone() __TBB_override { - return new multifunction_body_leaf(body); - } - - private: - B body; - }; - -// ------ function bodies for hash_buffers and key-matching joins. - -template -class type_to_key_function_body : tbb::internal::no_assign { - public: - virtual ~type_to_key_function_body() {} - virtual Output operator()(const Input &input) = 0; // returns an Output - virtual type_to_key_function_body* clone() = 0; -}; - -// specialization for ref output -template -class type_to_key_function_body : tbb::internal::no_assign { - public: - virtual ~type_to_key_function_body() {} - virtual const Output & operator()(const Input &input) = 0; // returns a const Output& - virtual type_to_key_function_body* clone() = 0; -}; - -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) { } - Output operator()(const Input &i) __TBB_override { return body(i); } - B get_body() { return body; } - type_to_key_function_body_leaf* clone() __TBB_override { - return new type_to_key_function_body_leaf< Input, Output, B>(body); - } -private: - B body; -}; - -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) { } - const Output& operator()(const Input &i) __TBB_override { - return body(i); - } - B get_body() { return body; } - type_to_key_function_body_leaf* clone() __TBB_override { - return new type_to_key_function_body_leaf< Input, Output&, B>(body); - } -private: - B body; -}; - -// --------------------------- end of function_body containers ------------------------ - -// --------------------------- node task bodies --------------------------------------- - - //! A task that calls a node's forward_task function - template< typename NodeType > - class forward_task_bypass : public task { - - NodeType &my_node; - - public: - - forward_task_bypass( NodeType &n ) : my_node(n) {} - - task *execute() __TBB_override { - task * new_task = my_node.forward_task(); - if (new_task == SUCCESSFULLY_ENQUEUED) new_task = NULL; - return new_task; - } - }; - - //! A task that calls a node's apply_body_bypass function, passing in an input of type Input - // return the task* unless it is SUCCESSFULLY_ENQUEUED, in which case return NULL - template< typename NodeType, typename Input > - class apply_body_task_bypass : public task { - - NodeType &my_node; - Input my_input; - - public: - - apply_body_task_bypass( NodeType &n, const Input &i ) : my_node(n), my_input(i) {} - - 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; - } - }; - - //! A task that calls a node's apply_body_bypass function with no input - template< typename NodeType > - class source_task_bypass : public task { - - NodeType &my_node; - - public: - - source_task_bypass( NodeType &n ) : my_node(n) {} - - task *execute() __TBB_override { - task *new_task = my_node.apply_body_bypass( ); - if(new_task == SUCCESSFULLY_ENQUEUED) return NULL; - return new_task; - } - }; - -// ------------------------ end of node task bodies ----------------------------------- - - //! An empty functor that takes an Input and returns a default constructed Output - template< typename Input, typename Output > - struct empty_body { - Output operator()( const Input & ) const { return Output(); } - }; - - //! A node_cache maintains a std::queue of elements of type T. Each operation is protected by a lock. - template< typename T, typename M=spin_mutex > - class node_cache { - public: - - typedef size_t size_type; - - bool empty() { - typename mutex_type::scoped_lock lock( my_mutex ); - return internal_empty(); - } - - void add( T &n ) { - typename mutex_type::scoped_lock lock( my_mutex ); - internal_push(n); - } - - void remove( T &n ) { - typename mutex_type::scoped_lock lock( my_mutex ); - for ( size_t i = internal_size(); i != 0; --i ) { - T &s = internal_pop(); - if ( &s == &n ) return; // only remove one predecessor per request - internal_push(s); - } - } - - void clear() { - while( !my_q.empty()) (void)my_q.pop(); -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - my_built_predecessors.clear(); -#endif - } - -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - typedef edge_container built_predecessors_type; - built_predecessors_type &built_predecessors() { return my_built_predecessors; } - - typedef typename edge_container::edge_list_type predecessor_list_type; - void internal_add_built_predecessor( T &n ) { - typename mutex_type::scoped_lock lock( my_mutex ); - my_built_predecessors.add_edge(n); - } - - void internal_delete_built_predecessor( T &n ) { - typename mutex_type::scoped_lock lock( my_mutex ); - my_built_predecessors.delete_edge(n); - } - - void copy_predecessors( predecessor_list_type &v) { - typename mutex_type::scoped_lock lock( my_mutex ); - my_built_predecessors.copy_edges(v); - } - - size_t predecessor_count() { - typename mutex_type::scoped_lock lock(my_mutex); - return (size_t)(my_built_predecessors.edge_count()); - } -#endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */ - - protected: - - typedef M mutex_type; - mutex_type my_mutex; - std::queue< T * > my_q; -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - built_predecessors_type my_built_predecessors; -#endif - - // Assumes lock is held - inline bool internal_empty( ) { - return my_q.empty(); - } - - // Assumes lock is held - inline size_type internal_size( ) { - return my_q.size(); - } - - // Assumes lock is held - inline void internal_push( T &n ) { - my_q.push(&n); - } - - // Assumes lock is held - inline T &internal_pop() { - T *v = my_q.front(); - my_q.pop(); - return *v; - } - - }; - - //! 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 ) { } - - void set_owner( successor_type *owner ) { my_owner = owner; } - - bool get_item( output_type &v ) { - - bool msg = false; - - do { - predecessor_type *src; - { - typename mutex_type::scoped_lock lock(this->my_mutex); - if ( this->internal_empty() ) { - break; - } - src = &this->internal_pop(); - } - - // Try to get from this sender - msg = src->try_get( v ); - - if (msg == false) { - // Relinquish ownership of the edge - if (my_owner) - src->register_successor( *my_owner ); - } else { - // Retain ownership of the edge - this->add(*src); - } - } while ( msg == false ); - return msg; - } - - // If we are removing arcs (rf_clear_edges), call clear() rather than reset(). - void reset() { - if (my_owner) { - for(;;) { - predecessor_type *src; - { - if (this->internal_empty()) break; - src = &this->internal_pop(); - } - src->register_successor( *my_owner ); - } - } - } - - protected: - -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - 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) { } - - bool - try_reserve( output_type &v ) { - bool msg = false; - - do { - { - typename mutex_type::scoped_lock lock(this->my_mutex); - if ( reserved_src || this->internal_empty() ) - return false; - - reserved_src = &this->internal_pop(); - } - - // Try to get from this sender - msg = reserved_src->try_reserve( v ); - - if (msg == false) { - typename mutex_type::scoped_lock lock(this->my_mutex); - // Relinquish ownership of the edge - reserved_src->register_successor( *this->my_owner ); - reserved_src = NULL; - } else { - // Retain ownership of the edge - this->add( *reserved_src ); - } - } while ( msg == false ); - - return msg; - } - - bool - try_release( ) { - reserved_src->try_release( ); - reserved_src = NULL; - return true; - } - - bool - try_consume( ) { - reserved_src->try_consume( ); - reserved_src = NULL; - return true; - } - - void reset( ) { - reserved_src = NULL; - predecessor_cache::reset( ); - } - - void clear() { - reserved_src = NULL; - predecessor_cache::clear(); - } - - private: - predecessor_type *reserved_src; - }; - - - //! 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: - - 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; - - owner_type *my_owner; - - public: -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - typedef typename edge_container::edge_list_type successor_list_type; - - edge_container &built_successors() { return my_built_successors; } - - void internal_add_built_successor( successor_type &r) { - typename mutex_type::scoped_lock l(my_mutex, true); - my_built_successors.add_edge( r ); - } - - void internal_delete_built_successor( successor_type &r) { - typename mutex_type::scoped_lock l(my_mutex, true); - my_built_successors.delete_edge(r); - } - - void copy_successors( successor_list_type &v) { - typename mutex_type::scoped_lock l(my_mutex, false); - my_built_successors.copy_edges(v); - } - - size_t successor_count() { - typename mutex_type::scoped_lock l(my_mutex,false); - return my_built_successors.edge_count(); - } - -#endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */ - - successor_cache( ) : my_owner(NULL) {} - - void set_owner( owner_type *owner ) { my_owner = owner; } - - virtual ~successor_cache() {} - - void register_successor( successor_type &r ) { - typename mutex_type::scoped_lock l(my_mutex, true); - my_successors.push_back( &r ); - } - - void remove_successor( successor_type &r ) { - typename mutex_type::scoped_lock l(my_mutex, true); - for ( typename successors_type::iterator i = my_successors.begin(); - i != my_successors.end(); ++i ) { - if ( *i == & r ) { - my_successors.erase(i); - break; - } - } - } - - bool empty() { - typename mutex_type::scoped_lock l(my_mutex, false); - return my_successors.empty(); - } - - void clear() { - my_successors.clear(); -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - my_built_successors.clear(); -#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 - template<> - class successor_cache< continue_msg > : tbb::internal::no_copy { - protected: - - 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 - edge_container my_built_successors; - typedef edge_container::edge_list_type successor_list_type; -#endif - - sender *my_owner; - - public: - -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - - edge_container &built_successors() { return my_built_successors; } - - void internal_add_built_successor( successor_type &r) { - mutex_type::scoped_lock l(my_mutex, true); - my_built_successors.add_edge( r ); - } - - void internal_delete_built_successor( successor_type &r) { - mutex_type::scoped_lock l(my_mutex, true); - my_built_successors.delete_edge(r); - } - - void copy_successors( successor_list_type &v) { - mutex_type::scoped_lock l(my_mutex, false); - my_built_successors.copy_edges(v); - } - - size_t successor_count() { - mutex_type::scoped_lock l(my_mutex,false); - return my_built_successors.edge_count(); - } - -#endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */ - - successor_cache( ) : my_owner(NULL) {} - - void set_owner( sender *owner ) { my_owner = owner; } - - virtual ~successor_cache() {} - - void register_successor( successor_type &r ) { - mutex_type::scoped_lock l(my_mutex, true); - my_successors.push_back( &r ); - if ( my_owner && r.is_continue_receiver() ) { - r.register_predecessor( *my_owner ); - } - } - - void remove_successor( successor_type &r ) { - mutex_type::scoped_lock l(my_mutex, true); - for ( successors_type::iterator i = my_successors.begin(); - i != my_successors.end(); ++i ) { - if ( *i == & r ) { - // TODO: Check if we need to test for continue_receiver before - // removing from r. - if ( my_owner ) - r.remove_predecessor( *my_owner ); - my_successors.erase(i); - break; - } - } - } - - bool empty() { - mutex_type::scoped_lock l(my_mutex, false); - return my_successors.empty(); - } - - void clear() { - my_successors.clear(); -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - my_built_successors.clear(); -#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; - typedef typename successor_cache::successors_type successors_type; - - public: - - broadcast_cache( ) {} - - // as above, but call try_put_task instead, and return the last task we received (if any) -#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); - typename successors_type::iterator i = this->my_successors.begin(); - while ( i != this->my_successors.end() ) { - task *new_task = (*i)->try_put_task(t); - last_task = combine_tasks(last_task, new_task); // enqueue if necessary - if(new_task) { - ++i; - } - else { // failed - if ( (*i)->register_predecessor(*this->my_owner) ) { - if (!upgraded) { - l.upgrade_to_writer(); - upgraded = true; - } - i = this->my_successors.erase(i); - } else { - ++i; - } - } - } - return last_task; - } - - }; - - //! 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; - typedef M mutex_type; - typedef typename successor_cache::successors_type successors_type; - - public: - - round_robin_cache( ) {} - - size_type size() { - typename mutex_type::scoped_lock l(this->my_mutex, false); - return this->my_successors.size(); - } - -#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(); - while ( i != this->my_successors.end() ) { - task *new_task = (*i)->try_put_task(t); - if ( new_task ) { - return new_task; - } else { - if ( (*i)->register_predecessor(*this->my_owner) ) { - if (!upgraded) { - l.upgrade_to_writer(); - upgraded = true; - } - i = this->my_successors.erase(i); - } - else { - ++i; - } - } - } - return NULL; - } - }; - - template - class decrementer : public continue_receiver, tbb::internal::no_copy { - - T *my_node; - - task *execute() __TBB_override { - return my_node->decrement_counter(); - } - - public: - - typedef continue_msg input_type; - typedef continue_msg output_type; - decrementer( int number_of_predecessors = 0 ) : continue_receiver( number_of_predecessors ) { } - void set_owner( T *node ) { my_node = node; } - }; - -} - -#endif // __TBB__flow_graph_impl_H - 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 deleted file mode 100644 index 1fc6690c..00000000 --- a/lib/3rdParty/tbb/include/tbb/internal/_flow_graph_indexer_impl.h +++ /dev/null @@ -1,478 +0,0 @@ -/* - 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_indexer_impl_H -#define __TBB__flow_graph_indexer_impl_H - -#ifndef __TBB_flow_graph_H -#error Do not #include this internal file directly; use public TBB headers instead. -#endif - -#include "_flow_graph_types_impl.h" - -namespace internal { - - // Output of the indexer_node is a tbb::flow::tagged_msg, and will be of - // the form tagged_msg - // where the value of tag will indicate which result was put to the - // successor. - - template - task* do_try_put(const T &v, void *p) { - typename IndexerNodeBaseType::output_type o(K, v); - return reinterpret_cast(p)->try_put_task(&o); - } - - template - struct indexer_helper { - template - static inline void set_indexer_node_pointer(PortTuple &my_input, IndexerNodeBaseType *p) { - typedef typename tuple_element::type T; - task *(*indexer_node_put_task)(const T&, void *) = do_try_put; - tbb::flow::get(my_input).set_up(p, indexer_node_put_task); - indexer_helper::template set_indexer_node_pointer(my_input, p); - } - template - static inline void reset_inputs(InputTuple &my_input, reset_flags f) { - indexer_helper::reset_inputs(my_input, f); - tbb::flow::get(my_input).reset_receiver(f); - } -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - template - static inline void extract(InputTuple &my_input) { - indexer_helper::extract(my_input); - tbb::flow::get(my_input).extract_receiver(); - } -#endif - }; - - template - struct indexer_helper { - template - static inline void set_indexer_node_pointer(PortTuple &my_input, IndexerNodeBaseType *p) { - typedef typename tuple_element<0, TupleTypes>::type T; - task *(*indexer_node_put_task)(const T&, void *) = do_try_put; - tbb::flow::get<0>(my_input).set_up(p, indexer_node_put_task); - } - template - static inline void reset_inputs(InputTuple &my_input, reset_flags f) { - tbb::flow::get<0>(my_input).reset_receiver(f); - } -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - template - static inline void extract(InputTuple &my_input) { - tbb::flow::get<0>(my_input).extract_receiver(); - } -#endif - }; - - template - class indexer_input_port : public receiver { - private: - void* my_indexer_ptr; - typedef task* (* forward_function_ptr)(T const &, void* ); - forward_function_ptr my_try_put_task; -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - spin_mutex my_pred_mutex; - typedef typename receiver::built_predecessors_type built_predecessors_type; - built_predecessors_type my_built_predecessors; -#endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */ - public: -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - indexer_input_port() : my_pred_mutex() {} - indexer_input_port( const indexer_input_port & /*other*/ ) : receiver(), my_pred_mutex() { - } -#endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */ - void set_up(void *p, forward_function_ptr f) { - my_indexer_ptr = p; - my_try_put_task = f; - } -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - typedef typename receiver::predecessor_list_type predecessor_list_type; - typedef typename receiver::predecessor_type predecessor_type; - - built_predecessors_type &built_predecessors() __TBB_override { return my_built_predecessors; } - - size_t predecessor_count() __TBB_override { - spin_mutex::scoped_lock l(my_pred_mutex); - return my_built_predecessors.edge_count(); - } - void internal_add_built_predecessor(predecessor_type &p) __TBB_override { - spin_mutex::scoped_lock l(my_pred_mutex); - my_built_predecessors.add_edge(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); - } - void copy_predecessors( predecessor_list_type &v) __TBB_override { - spin_mutex::scoped_lock l(my_pred_mutex); - 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) __TBB_override { - return my_try_put_task(v, my_indexer_ptr); - } - - public: -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - void reset_receiver(reset_flags f) __TBB_override { if(f&rf_clear_edges) my_built_predecessors.clear(); } -#else - void reset_receiver(reset_flags /*f*/) __TBB_override { } -#endif - -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - void extract_receiver() { my_built_predecessors.receiver_extract(*this); } -#endif - }; - - template - class indexer_node_FE { - public: - static const int N = tbb::flow::tuple_size::value; - typedef OutputType output_type; - typedef InputTuple input_type; - - // Some versions of Intel C++ compiler fail to generate an implicit constructor for the class which has std::tuple as a member. - indexer_node_FE() : my_inputs() {} - - input_type &input_ports() { return my_inputs; } - protected: - input_type my_inputs; - }; - - //! indexer_node_base - template - class indexer_node_base : public graph_node, public indexer_node_FE, - public sender { - protected: - using graph_node::my_graph; - public: - static const size_t N = tbb::flow::tuple_size::value; - typedef OutputType output_type; - typedef StructTypes tuple_types; - 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; - typedef typename sender::successor_list_type successor_list_type; -#endif - - private: - // ----------- Aggregator ------------ - enum op_type { reg_succ, rem_succ, try__put_task -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - , add_blt_succ, del_blt_succ, - blt_succ_cnt, blt_succ_cpy -#endif - }; - typedef indexer_node_base class_type; - - class indexer_node_base_operation : public aggregated_operation { - public: - char type; - union { - output_type const *my_arg; - successor_type *my_succ; - task *bypass_t; -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - size_t cnt_val; - successor_list_type *succv; -#endif - }; - indexer_node_base_operation(const output_type* e, op_type t) : - type(char(t)), my_arg(e) {} - indexer_node_base_operation(const successor_type &s, op_type t) : type(char(t)), - my_succ(const_cast(&s)) {} - indexer_node_base_operation(op_type t) : type(char(t)) {} - }; - - typedef internal::aggregating_functor handler_type; - friend class internal::aggregating_functor; - aggregator my_aggregator; - - void handle_operations(indexer_node_base_operation* op_list) { - indexer_node_base_operation *current; - while(op_list) { - current = op_list; - op_list = op_list->next; - switch(current->type) { - - case reg_succ: - my_successors.register_successor(*(current->my_succ)); - __TBB_store_with_release(current->status, SUCCEEDED); - break; - - case rem_succ: - my_successors.remove_successor(*(current->my_succ)); - __TBB_store_with_release(current->status, SUCCEEDED); - break; - case try__put_task: { - current->bypass_t = my_successors.try_put_task(*(current->my_arg)); - __TBB_store_with_release(current->status, SUCCEEDED); // return of try_put_task actual return value - } - break; -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - case add_blt_succ: - my_successors.internal_add_built_successor(*(current->my_succ)); - __TBB_store_with_release(current->status, SUCCEEDED); - break; - case del_blt_succ: - my_successors.internal_delete_built_successor(*(current->my_succ)); - __TBB_store_with_release(current->status, SUCCEEDED); - break; - case blt_succ_cnt: - current->cnt_val = my_successors.successor_count(); - __TBB_store_with_release(current->status, SUCCEEDED); - break; - case blt_succ_cpy: - my_successors.copy_successors(*(current->succv)); - __TBB_store_with_release(current->status, SUCCEEDED); - break; -#endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */ - } - } - } - // ---------- end aggregator ----------- - public: - indexer_node_base(graph& g) : graph_node(g), input_ports_type() { - indexer_helper::set_indexer_node_pointer(this->my_inputs, this); - my_successors.set_owner(this); - my_aggregator.initialize_handler(handler_type(this)); - } - - indexer_node_base(const indexer_node_base& other) : graph_node(other.my_graph), input_ports_type(), sender() { - indexer_helper::set_indexer_node_pointer(this->my_inputs, this); - my_successors.set_owner(this); - my_aggregator.initialize_handler(handler_type(this)); - } - - 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) __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) { // 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; - } - -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - - built_successors_type &built_successors() __TBB_override { return my_successors.built_successors(); } - - 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) __TBB_override { - indexer_node_base_operation op_data(r, del_blt_succ); - my_aggregator.execute(&op_data); - } - - 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) __TBB_override { - indexer_node_base_operation op_data(blt_succ_cpy); - op_data.succv = &v; - my_aggregator.execute(&op_data); - } - void extract() __TBB_override { - my_successors.built_successors().sender_extract(*this); - indexer_helper::extract(this->my_inputs); - } -#endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */ - protected: - void reset_node(reset_flags f) __TBB_override { - if(f & rf_clear_edges) { - my_successors.clear(); - indexer_helper::reset_inputs(this->my_inputs,f); - } - } - - private: - broadcast_cache my_successors; - }; //indexer_node_base - - - template struct input_types; - - template - struct input_types<1, InputTuple> { - typedef typename tuple_element<0, InputTuple>::type first_type; - typedef typename internal::tagged_msg type; - }; - - template - struct input_types<2, InputTuple> { - typedef typename tuple_element<0, InputTuple>::type first_type; - typedef typename tuple_element<1, InputTuple>::type second_type; - typedef typename internal::tagged_msg type; - }; - - template - struct input_types<3, InputTuple> { - typedef typename tuple_element<0, InputTuple>::type first_type; - typedef typename tuple_element<1, InputTuple>::type second_type; - typedef typename tuple_element<2, InputTuple>::type third_type; - typedef typename internal::tagged_msg type; - }; - - template - struct input_types<4, InputTuple> { - typedef typename tuple_element<0, InputTuple>::type first_type; - typedef typename tuple_element<1, InputTuple>::type second_type; - typedef typename tuple_element<2, InputTuple>::type third_type; - typedef typename tuple_element<3, InputTuple>::type fourth_type; - typedef typename internal::tagged_msg type; - }; - - template - struct input_types<5, InputTuple> { - typedef typename tuple_element<0, InputTuple>::type first_type; - typedef typename tuple_element<1, InputTuple>::type second_type; - typedef typename tuple_element<2, InputTuple>::type third_type; - typedef typename tuple_element<3, InputTuple>::type fourth_type; - typedef typename tuple_element<4, InputTuple>::type fifth_type; - typedef typename internal::tagged_msg type; - }; - - template - struct input_types<6, InputTuple> { - typedef typename tuple_element<0, InputTuple>::type first_type; - typedef typename tuple_element<1, InputTuple>::type second_type; - typedef typename tuple_element<2, InputTuple>::type third_type; - typedef typename tuple_element<3, InputTuple>::type fourth_type; - typedef typename tuple_element<4, InputTuple>::type fifth_type; - typedef typename tuple_element<5, InputTuple>::type sixth_type; - typedef typename internal::tagged_msg type; - }; - - template - struct input_types<7, InputTuple> { - typedef typename tuple_element<0, InputTuple>::type first_type; - typedef typename tuple_element<1, InputTuple>::type second_type; - typedef typename tuple_element<2, InputTuple>::type third_type; - typedef typename tuple_element<3, InputTuple>::type fourth_type; - typedef typename tuple_element<4, InputTuple>::type fifth_type; - typedef typename tuple_element<5, InputTuple>::type sixth_type; - typedef typename tuple_element<6, InputTuple>::type seventh_type; - typedef typename internal::tagged_msg type; - }; - - - template - struct input_types<8, InputTuple> { - typedef typename tuple_element<0, InputTuple>::type first_type; - typedef typename tuple_element<1, InputTuple>::type second_type; - typedef typename tuple_element<2, InputTuple>::type third_type; - typedef typename tuple_element<3, InputTuple>::type fourth_type; - typedef typename tuple_element<4, InputTuple>::type fifth_type; - typedef typename tuple_element<5, InputTuple>::type sixth_type; - typedef typename tuple_element<6, InputTuple>::type seventh_type; - typedef typename tuple_element<7, InputTuple>::type eighth_type; - typedef typename internal::tagged_msg type; - }; - - - template - struct input_types<9, InputTuple> { - typedef typename tuple_element<0, InputTuple>::type first_type; - typedef typename tuple_element<1, InputTuple>::type second_type; - typedef typename tuple_element<2, InputTuple>::type third_type; - typedef typename tuple_element<3, InputTuple>::type fourth_type; - typedef typename tuple_element<4, InputTuple>::type fifth_type; - typedef typename tuple_element<5, InputTuple>::type sixth_type; - typedef typename tuple_element<6, InputTuple>::type seventh_type; - typedef typename tuple_element<7, InputTuple>::type eighth_type; - typedef typename tuple_element<8, InputTuple>::type nineth_type; - typedef typename internal::tagged_msg type; - }; - - template - struct input_types<10, InputTuple> { - typedef typename tuple_element<0, InputTuple>::type first_type; - typedef typename tuple_element<1, InputTuple>::type second_type; - typedef typename tuple_element<2, InputTuple>::type third_type; - typedef typename tuple_element<3, InputTuple>::type fourth_type; - typedef typename tuple_element<4, InputTuple>::type fifth_type; - typedef typename tuple_element<5, InputTuple>::type sixth_type; - typedef typename tuple_element<6, InputTuple>::type seventh_type; - typedef typename tuple_element<7, InputTuple>::type eighth_type; - typedef typename tuple_element<8, InputTuple>::type nineth_type; - typedef typename tuple_element<9, InputTuple>::type tenth_type; - typedef typename internal::tagged_msg type; - }; - - // type generators - template - struct indexer_types : public input_types::value, OutputTuple> { - static const int N = tbb::flow::tuple_size::value; - typedef typename input_types::type output_type; - typedef typename wrap_tuple_elements::type input_ports_type; - typedef internal::indexer_node_FE indexer_FE_type; - typedef internal::indexer_node_base indexer_base_type; - }; - - template - class unfolded_indexer_node : public indexer_types::indexer_base_type { - public: - typedef typename indexer_types::input_ports_type input_ports_type; - typedef OutputTuple tuple_types; - typedef typename indexer_types::output_type output_type; - private: - typedef typename indexer_types::indexer_base_type base_type; - public: - unfolded_indexer_node(graph& g) : base_type(g) {} - unfolded_indexer_node(const unfolded_indexer_node &other) : base_type(other) {} - }; - -} /* namespace internal */ - -#endif /* __TBB__flow_graph_indexer_impl_H */ 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 deleted file mode 100644 index 85d2686d..00000000 --- a/lib/3rdParty/tbb/include/tbb/internal/_flow_graph_item_buffer_impl.h +++ /dev/null @@ -1,288 +0,0 @@ -/* - 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_item_buffer_impl_H -#define __TBB__flow_graph_item_buffer_impl_H - -#ifndef __TBB_flow_graph_H -#error Do not #include this internal file directly; use public TBB headers instead. -#endif - -#include "tbb/internal/_flow_graph_types_impl.h" // for aligned_pair - -// in namespace tbb::flow::interfaceX (included in _flow_graph_node_impl.h) - - //! Expandable buffer of items. The possible operations are push, pop, - //* tests for empty and so forth. No mutual exclusion is built in. - //* objects are constructed into and explicitly-destroyed. get_my_item gives - // a read-only reference to the item in the buffer. set_my_item may be called - // with either an empty or occupied slot. - - using internal::aligned_pair; - using internal::alignment_of; - -namespace internal { - - template > - class item_buffer { - public: - typedef T item_type; - enum buffer_item_state { no_item=0, has_item=1, reserved_item=2 }; - protected: - typedef size_t size_type; - typedef typename aligned_pair::type buffer_item_type; - typedef typename A::template rebind::other allocator_type; - - buffer_item_type *my_array; - size_type my_array_size; - static const size_type initial_buffer_size = 4; - size_type my_head; - size_type 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); - __TBB_ASSERT(!(size_type(&(my_array[i&(my_array_size-1)].first))%alignment_of::value), NULL); - return my_array[i & (my_array_size - 1) ]; - } - - 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 { - __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; - } - - // may be called with an empty slot or a slot that has already been constructed into. - void set_my_item(size_t i, const item_type &o) { - if(item(i).second != no_item) { - destroy_item(i); - } - new(&(item(i).first)) item_type(o); - item(i).second = has_item; - } - - // destructively-fetch an object from the buffer - void fetch_item(size_t i, item_type &o) { - __TBB_ASSERT(my_item_valid(i), "Trying to fetch an empty slot"); - o = get_my_item(i); // could have std::move assign semantics - destroy_item(i); - } - - // move an existing item from one slot to another. The moved-to slot must be unoccupied, - // the moved-from slot must exist and not be reserved. The after, from will be empty, - // to will be occupied but not reserved - void move_item(size_t to, size_t from) { - __TBB_ASSERT(!my_item_valid(to), "Trying to move to a non-empty slot"); - __TBB_ASSERT(my_item_valid(from), "Trying to move from an empty slot"); - set_my_item(to, get_my_item(from)); // could have std::move semantics - destroy_item(from); - - } - - // put an item in an empty slot. Return true if successful, else false - bool place_item(size_t here, const item_type &me) { -#if !TBB_DEPRECATED_SEQUENCER_DUPLICATES - if(my_item_valid(here)) return false; -#endif - set_my_item(here, me); - return true; - } - - // could be implemented with std::move semantics - void swap_items(size_t i, size_t j) { - __TBB_ASSERT(my_item_valid(i) && my_item_valid(j), "attempt to swap invalid item(s)"); - item_type temp = get_my_item(i); - set_my_item(i, get_my_item(j)); - set_my_item(j, temp); - } - - void destroy_item(size_type i) { - __TBB_ASSERT(my_item_valid(i), "destruction of invalid item"); - (tbb::internal::punned_cast(&(item(i).first)))->~item_type(); - item(i).second = no_item; - } - - // returns the front element - const item_type& front() const - { - __TBB_ASSERT(my_item_valid(my_head), "attempt to fetch head non-item"); - return get_my_item(my_head); - } - - // 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. - void reserve_item(size_type i) { __TBB_ASSERT(my_item_valid(i) && !my_item_reserved(i), "item cannot be reserved"); item(i).second = reserved_item; } - void release_item(size_type i) { __TBB_ASSERT(my_item_reserved(i), "item is not reserved"); item(i).second = has_item; } - - void destroy_front() { destroy_item(my_head); ++my_head; } - void destroy_back() { destroy_item(my_tail-1); --my_tail; } - - // we have to be able to test against a new tail value without changing my_tail - // grow_array doesn't work if we change my_tail when the old array is too small - size_type size(size_t new_tail = 0) { return (new_tail ? new_tail : my_tail) - my_head; } - size_type capacity() { return my_array_size; } - // sequencer_node does not use this method, so we don't - // need a version that passes in the new_tail value. - bool buffer_full() { return size() >= capacity(); } - - //! Grows the internal array. - void grow_my_array( size_t minimum_size ) { - // test that we haven't made the structure inconsistent. - __TBB_ASSERT(capacity() >= my_tail - my_head, "total items exceed capacity"); - size_type new_size = my_array_size ? 2*my_array_size : initial_buffer_size; - while( new_sizeback(); - destroy_back(); - return true; - } - - bool pop_front(item_type &v) { - if(!my_item_valid(my_head)) { - return false; - } - v = this->front(); - destroy_front(); - return true; - } - - // This is used both for reset and for grow_my_array. In the case of grow_my_array - // we want to retain the values of the head and tail. - void clean_up_buffer(bool reset_pointers) { - if (my_array) { - for( size_type i=my_head; i > - class reservable_item_buffer : public item_buffer { - protected: - using item_buffer::my_item_valid; - using item_buffer::my_head; - - public: - reservable_item_buffer() : item_buffer(), my_reserved(false) {} - void reset() {my_reserved = false; item_buffer::reset(); } - protected: - - bool reserve_front(T &v) { - if(my_reserved || !my_item_valid(this->my_head)) return false; - my_reserved = true; - // reserving the head - v = this->front(); - this->reserve_item(this->my_head); - return true; - } - - void consume_front() { - __TBB_ASSERT(my_reserved, "Attempt to consume a non-reserved item"); - this->destroy_front(); - my_reserved = false; - } - - void release_front() { - __TBB_ASSERT(my_reserved, "Attempt to release a non-reserved item"); - this->release_item(this->my_head); - my_reserved = false; - } - - bool my_reserved; - }; - -} // namespace internal - -#endif // __TBB__flow_graph_item_buffer_impl_H 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 deleted file mode 100644 index 4999bef7..00000000 --- a/lib/3rdParty/tbb/include/tbb/internal/_flow_graph_join_impl.h +++ /dev/null @@ -1,1991 +0,0 @@ -/* - 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_join_impl_H -#define __TBB__flow_graph_join_impl_H - -#ifndef __TBB_flow_graph_H -#error Do not #include this internal file directly; use public TBB headers instead. -#endif - -namespace internal { - - struct forwarding_base { - forwarding_base(graph &g) : graph_pointer(&g) {} - virtual ~forwarding_base() {} - // decrement_port_count may create a forwarding task. If we cannot handle the task - // ourselves, ask decrement_port_count to deal with it. - virtual task * decrement_port_count(bool handle_task) = 0; - virtual void increment_port_count() = 0; - // moved here so input ports can queue tasks - graph* graph_pointer; - }; - - // specialization that lets us keep a copy of the current_key for building results. - // KeyType can be a reference type. - template - struct matching_forwarding_base :public forwarding_base { - typedef typename tbb::internal::strip::type current_key_type; - matching_forwarding_base(graph &g) : forwarding_base(g) { } - virtual task * increment_key_count(current_key_type const & /*t*/, bool /*handle_task*/) = 0; // {return NULL;} - current_key_type current_key; // so ports can refer to FE's desired items - }; - - template< int N > - struct join_helper { - - template< typename TupleType, typename PortType > - static inline void set_join_node_pointer(TupleType &my_input, PortType *port) { - tbb::flow::get( my_input ).set_join_node_pointer(port); - join_helper::set_join_node_pointer( my_input, port ); - } - template< typename TupleType > - static inline void consume_reservations( TupleType &my_input ) { - tbb::flow::get( my_input ).consume(); - join_helper::consume_reservations( my_input ); - } - - template< typename TupleType > - static inline void release_my_reservation( TupleType &my_input ) { - tbb::flow::get( my_input ).release(); - } - - template - static inline void release_reservations( TupleType &my_input) { - join_helper::release_reservations(my_input); - release_my_reservation(my_input); - } - - template< typename InputTuple, typename OutputTuple > - static inline bool reserve( InputTuple &my_input, OutputTuple &out) { - if ( !tbb::flow::get( my_input ).reserve( tbb::flow::get( out ) ) ) return false; - if ( !join_helper::reserve( my_input, out ) ) { - release_my_reservation( my_input ); - return false; - } - return true; - } - - template - static inline bool get_my_item( InputTuple &my_input, OutputTuple &out) { - bool res = tbb::flow::get(my_input).get_item(tbb::flow::get(out) ); // may fail - return join_helper::get_my_item(my_input, out) && res; // do get on other inputs before returning - } - - template - static inline bool get_items(InputTuple &my_input, OutputTuple &out) { - return get_my_item(my_input, out); - } - - template - static inline void reset_my_port(InputTuple &my_input) { - join_helper::reset_my_port(my_input); - tbb::flow::get(my_input).reset_port(); - } - - template - static inline void reset_ports(InputTuple& my_input) { - reset_my_port(my_input); - } - - template - static inline void set_key_functors(InputTuple &my_input, KeyFuncTuple &my_key_funcs) { - tbb::flow::get(my_input).set_my_key_func(tbb::flow::get(my_key_funcs)); - tbb::flow::get(my_key_funcs) = NULL; - join_helper::set_key_functors(my_input, my_key_funcs); - } - - template< typename KeyFuncTuple> - static inline void copy_key_functors(KeyFuncTuple &my_inputs, KeyFuncTuple &other_inputs) { - if(tbb::flow::get(other_inputs).get_my_key_func()) { - tbb::flow::get(my_inputs).set_my_key_func(tbb::flow::get(other_inputs).get_my_key_func()->clone()); - } - join_helper::copy_key_functors(my_inputs, other_inputs); - } - - template - static inline void reset_inputs(InputTuple &my_input, reset_flags f) { - join_helper::reset_inputs(my_input, f); - tbb::flow::get(my_input).reset_receiver(f); - } - -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - template - static inline void extract_inputs(InputTuple &my_input) { - join_helper::extract_inputs(my_input); - tbb::flow::get(my_input).extract_receiver(); - } -#endif - }; // join_helper - - template< > - struct join_helper<1> { - - template< typename TupleType, typename PortType > - static inline void set_join_node_pointer(TupleType &my_input, PortType *port) { - tbb::flow::get<0>( my_input ).set_join_node_pointer(port); - } - - template< typename TupleType > - static inline void consume_reservations( TupleType &my_input ) { - tbb::flow::get<0>( my_input ).consume(); - } - - template< typename TupleType > - static inline void release_my_reservation( TupleType &my_input ) { - tbb::flow::get<0>( my_input ).release(); - } - - template - static inline void release_reservations( TupleType &my_input) { - release_my_reservation(my_input); - } - - template< typename InputTuple, typename OutputTuple > - static inline bool reserve( InputTuple &my_input, OutputTuple &out) { - return tbb::flow::get<0>( my_input ).reserve( tbb::flow::get<0>( out ) ); - } - - template - static inline bool get_my_item( InputTuple &my_input, OutputTuple &out) { - return tbb::flow::get<0>(my_input).get_item(tbb::flow::get<0>(out)); - } - - template - static inline bool get_items(InputTuple &my_input, OutputTuple &out) { - return get_my_item(my_input, out); - } - - template - static inline void reset_my_port(InputTuple &my_input) { - tbb::flow::get<0>(my_input).reset_port(); - } - - template - static inline void reset_ports(InputTuple& my_input) { - reset_my_port(my_input); - } - - template - static inline void set_key_functors(InputTuple &my_input, KeyFuncTuple &my_key_funcs) { - tbb::flow::get<0>(my_input).set_my_key_func(tbb::flow::get<0>(my_key_funcs)); - tbb::flow::get<0>(my_key_funcs) = NULL; - } - - template< typename KeyFuncTuple> - static inline void copy_key_functors(KeyFuncTuple &my_inputs, KeyFuncTuple &other_inputs) { - if(tbb::flow::get<0>(other_inputs).get_my_key_func()) { - tbb::flow::get<0>(my_inputs).set_my_key_func(tbb::flow::get<0>(other_inputs).get_my_key_func()->clone()); - } - } - template - static inline void reset_inputs(InputTuple &my_input, reset_flags f) { - tbb::flow::get<0>(my_input).reset_receiver(f); - } - -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - template - static inline void extract_inputs(InputTuple &my_input) { - tbb::flow::get<0>(my_input).extract_receiver(); - } -#endif - }; // join_helper<1> - - //! The two-phase join port - template< typename T > - class reserving_port : public receiver { - public: - typedef T input_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; -#endif - private: - // ----------- Aggregator ------------ - enum op_type { reg_pred, rem_pred, res_item, rel_res, con_res -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - , add_blt_pred, del_blt_pred, blt_pred_cnt, blt_pred_cpy -#endif - }; - enum op_stat {WAIT=0, SUCCEEDED, FAILED}; - typedef reserving_port class_type; - - class reserving_port_operation : public aggregated_operation { - public: - char type; - union { - T *my_arg; - predecessor_type *my_pred; -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - size_t cnt_val; - predecessor_list_type *plist; -#endif - }; - reserving_port_operation(const T& e, op_type t) : - type(char(t)), my_arg(const_cast(&e)) {} - reserving_port_operation(const predecessor_type &s, op_type t) : type(char(t)), - my_pred(const_cast(&s)) {} - reserving_port_operation(op_type t) : type(char(t)) {} - }; - - typedef internal::aggregating_functor handler_type; - friend class internal::aggregating_functor; - aggregator my_aggregator; - - void handle_operations(reserving_port_operation* op_list) { - reserving_port_operation *current; - bool no_predecessors; - while(op_list) { - current = op_list; - op_list = op_list->next; - switch(current->type) { - case reg_pred: - no_predecessors = my_predecessors.empty(); - my_predecessors.add(*(current->my_pred)); - if ( no_predecessors ) { - (void) my_join->decrement_port_count(true); // may try to forward - } - __TBB_store_with_release(current->status, SUCCEEDED); - break; - case rem_pred: - my_predecessors.remove(*(current->my_pred)); - if(my_predecessors.empty()) my_join->increment_port_count(); - __TBB_store_with_release(current->status, SUCCEEDED); - break; - case res_item: - if ( reserved ) { - __TBB_store_with_release(current->status, FAILED); - } - else if ( my_predecessors.try_reserve( *(current->my_arg) ) ) { - reserved = true; - __TBB_store_with_release(current->status, SUCCEEDED); - } else { - if ( my_predecessors.empty() ) { - my_join->increment_port_count(); - } - __TBB_store_with_release(current->status, FAILED); - } - break; - case rel_res: - reserved = false; - my_predecessors.try_release( ); - __TBB_store_with_release(current->status, SUCCEEDED); - break; - case con_res: - reserved = false; - my_predecessors.try_consume( ); - __TBB_store_with_release(current->status, SUCCEEDED); - break; -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - case add_blt_pred: - my_predecessors.internal_add_built_predecessor(*(current->my_pred)); - __TBB_store_with_release(current->status, SUCCEEDED); - break; - case del_blt_pred: - my_predecessors.internal_delete_built_predecessor(*(current->my_pred)); - __TBB_store_with_release(current->status, SUCCEEDED); - break; - case blt_pred_cnt: - current->cnt_val = my_predecessors.predecessor_count(); - __TBB_store_with_release(current->status, SUCCEEDED); - break; - case blt_pred_cpy: - my_predecessors.copy_predecessors(*(current->plist)); - __TBB_store_with_release(current->status, SUCCEEDED); - break; -#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 & ) __TBB_override { - return NULL; - } - - public: - - //! Constructor - reserving_port() : reserved(false) { - my_join = NULL; - my_predecessors.set_owner( this ); - my_aggregator.initialize_handler(handler_type(this)); - } - - // copy constructor - reserving_port(const reserving_port& /* other */) : receiver() { - reserved = false; - my_join = NULL; - my_predecessors.set_owner( this ); - my_aggregator.initialize_handler(handler_type(this)); - } - - void set_join_node_pointer(forwarding_base *join) { - my_join = join; - } - - //! Add a predecessor - 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( predecessor_type &src ) __TBB_override { - reserving_port_operation op_data(src, rem_pred); - my_aggregator.execute(&op_data); - return op_data.status == SUCCEEDED; - } - - //! Reserve an item from the port - bool reserve( T &v ) { - reserving_port_operation op_data(v, res_item); - my_aggregator.execute(&op_data); - return op_data.status == SUCCEEDED; - } - - //! Release the port - void release( ) { - reserving_port_operation op_data(rel_res); - my_aggregator.execute(&op_data); - } - - //! Complete use of the port - void consume( ) { - reserving_port_operation op_data(con_res); - my_aggregator.execute(&op_data); - } - -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - 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); - } - - void internal_delete_built_predecessor(predecessor_type &src) __TBB_override { - reserving_port_operation op_data(src, del_blt_pred); - my_aggregator.execute(&op_data); - } - - size_t predecessor_count() __TBB_override { - reserving_port_operation op_data(blt_pred_cnt); - my_aggregator.execute(&op_data); - return op_data.cnt_val; - } - - 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); - } - - void extract_receiver() { - my_predecessors.built_predecessors().receiver_extract(*this); - } - -#endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */ - - void reset_receiver( reset_flags f) __TBB_override { - if(f & rf_clear_edges) my_predecessors.clear(); - else - my_predecessors.reset(); - reserved = false; - __TBB_ASSERT(!(f&rf_clear_edges) || my_predecessors.empty(), "port edges not removed"); - } - - private: - forwarding_base *my_join; - reservable_predecessor_cache< T, null_mutex > my_predecessors; - bool reserved; - }; // reserving_port - - //! queueing join_port - template - class queueing_port : public receiver, public item_buffer { - public: - typedef T input_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; - typedef typename receiver::predecessor_list_type predecessor_list_type; -#endif - - // ----------- Aggregator ------------ - private: - enum op_type { get__item, res_port, try__put_task -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - , add_blt_pred, del_blt_pred, blt_pred_cnt, blt_pred_cpy -#endif - }; - enum op_stat {WAIT=0, SUCCEEDED, FAILED}; - - class queueing_port_operation : public aggregated_operation { - public: - char type; - T my_val; - T *my_arg; -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - predecessor_type *pred; - size_t cnt_val; - predecessor_list_type *plist; -#endif - task * bypass_t; - // constructor for value parameter - queueing_port_operation(const T& e, op_type t) : - type(char(t)), my_val(e) - , bypass_t(NULL) - {} - // constructor for pointer parameter - queueing_port_operation(const T* p, op_type t) : - type(char(t)), my_arg(const_cast(p)) - , bypass_t(NULL) - {} - // constructor with no parameter - queueing_port_operation(op_type t) : type(char(t)) - , bypass_t(NULL) - {} - }; - - typedef internal::aggregating_functor handler_type; - friend class internal::aggregating_functor; - aggregator my_aggregator; - - void handle_operations(queueing_port_operation* op_list) { - queueing_port_operation *current; - bool was_empty; - while(op_list) { - current = op_list; - op_list = op_list->next; - switch(current->type) { - case try__put_task: { - task *rtask = NULL; - was_empty = this->buffer_empty(); - this->push_back(current->my_val); - if (was_empty) rtask = my_join->decrement_port_count(false); - else - rtask = SUCCESSFULLY_ENQUEUED; - current->bypass_t = rtask; - __TBB_store_with_release(current->status, SUCCEEDED); - } - break; - case get__item: - if(!this->buffer_empty()) { - *(current->my_arg) = this->front(); - __TBB_store_with_release(current->status, SUCCEEDED); - } - else { - __TBB_store_with_release(current->status, FAILED); - } - break; - case res_port: - __TBB_ASSERT(this->my_item_valid(this->my_head), "No item to reset"); - this->destroy_front(); - if(this->my_item_valid(this->my_head)) { - (void)my_join->decrement_port_count(true); - } - __TBB_store_with_release(current->status, SUCCEEDED); - break; -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - case add_blt_pred: - my_built_predecessors.add_edge(*(current->pred)); - __TBB_store_with_release(current->status, SUCCEEDED); - break; - case del_blt_pred: - my_built_predecessors.delete_edge(*(current->pred)); - __TBB_store_with_release(current->status, SUCCEEDED); - break; - case blt_pred_cnt: - current->cnt_val = my_built_predecessors.edge_count(); - __TBB_store_with_release(current->status, SUCCEEDED); - break; - case blt_pred_cpy: - my_built_predecessors.copy_edges(*(current->plist)); - __TBB_store_with_release(current->status, SUCCEEDED); - break; -#endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */ - } - } - } - // ------------ End Aggregator --------------- - - 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) __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"); - if(!op_data.bypass_t) return SUCCESSFULLY_ENQUEUED; - return op_data.bypass_t; - } - - public: - - //! Constructor - queueing_port() : item_buffer() { - my_join = NULL; - my_aggregator.initialize_handler(handler_type(this)); - } - - //! copy constructor - queueing_port(const queueing_port& /* other */) : receiver(), item_buffer() { - my_join = NULL; - my_aggregator.initialize_handler(handler_type(this)); - } - - //! record parent for tallying available items - void set_join_node_pointer(forwarding_base *join) { - my_join = join; - } - - bool get_item( T &v ) { - queueing_port_operation op_data(&v, get__item); - my_aggregator.execute(&op_data); - return op_data.status == SUCCEEDED; - } - - // reset_port is called when item is accepted by successor, but - // is initiated by join_node. - void reset_port() { - queueing_port_operation op_data(res_port); - my_aggregator.execute(&op_data); - return; - } - -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - built_predecessors_type &built_predecessors() __TBB_override { return my_built_predecessors; } - - 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); - } - - 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); - } - - size_t predecessor_count() __TBB_override { - queueing_port_operation op_data(blt_pred_cnt); - my_aggregator.execute(&op_data); - return op_data.cnt_val; - } - - 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); - } - - void extract_receiver() { - item_buffer::reset(); - my_built_predecessors.receiver_extract(*this); - } -#endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */ - - void reset_receiver(reset_flags f) __TBB_override { - tbb::internal::suppress_unused_warning(f); - item_buffer::reset(); -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - if (f & rf_clear_edges) - my_built_predecessors.clear(); -#endif - } - - private: - forwarding_base *my_join; -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - edge_container my_built_predecessors; -#endif - }; // queueing_port - -#include "_flow_graph_tagged_buffer_impl.h" - - template - struct count_element { - K my_key; - size_t my_value; - }; - - // method to access the key in the counting table - // the ref has already been removed from K - template< typename K > - struct key_to_count_functor { - typedef count_element table_item_type; - const K& operator()(const table_item_type& v) { return v.my_key; } - }; - - // the ports can have only one template parameter. We wrap the types needed in - // a traits type - template< class TraitsType > - class key_matching_port : - public receiver, - public hash_buffer< typename TraitsType::K, typename TraitsType::T, typename TraitsType::TtoK, - typename TraitsType::KHash > { - public: - typedef TraitsType traits; - typedef key_matching_port class_type; - typedef typename TraitsType::T input_type; - typedef typename TraitsType::K key_type; - typedef typename tbb::internal::strip::type noref_key_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; -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - typedef typename receiver::built_predecessors_type built_predecessors_type; - typedef typename receiver::predecessor_list_type predecessor_list_type; -#endif - private: -// ----------- Aggregator ------------ - private: - enum op_type { try__put, get__item, res_port -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - , add_blt_pred, del_blt_pred, blt_pred_cnt, blt_pred_cpy -#endif - }; - enum op_stat {WAIT=0, SUCCEEDED, FAILED}; - - class key_matching_port_operation : public aggregated_operation { - public: - char type; - input_type my_val; - input_type *my_arg; -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - predecessor_type *pred; - size_t cnt_val; - predecessor_list_type *plist; -#endif - // constructor for value parameter - key_matching_port_operation(const input_type& e, op_type t) : - type(char(t)), my_val(e) {} - // constructor for pointer parameter - key_matching_port_operation(const input_type* p, op_type t) : - type(char(t)), my_arg(const_cast(p)) {} - // constructor with no parameter - key_matching_port_operation(op_type t) : type(char(t)) {} - }; - - typedef internal::aggregating_functor handler_type; - friend class internal::aggregating_functor; - aggregator my_aggregator; - - void handle_operations(key_matching_port_operation* op_list) { - key_matching_port_operation *current; - while(op_list) { - current = op_list; - op_list = op_list->next; - switch(current->type) { - case try__put: { - bool was_inserted = this->insert_with_key(current->my_val); - // return failure if a duplicate insertion occurs - __TBB_store_with_release(current->status, was_inserted ? SUCCEEDED : FAILED); - } - break; - case get__item: - // use current_key from FE for item - if(!this->find_with_key(my_join->current_key, *(current->my_arg))) { - __TBB_ASSERT(false, "Failed to find item corresponding to current_key."); - } - __TBB_store_with_release(current->status, SUCCEEDED); - break; - case res_port: - // use current_key from FE for item - this->delete_with_key(my_join->current_key); - __TBB_store_with_release(current->status, SUCCEEDED); - break; -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - case add_blt_pred: - my_built_predecessors.add_edge(*(current->pred)); - __TBB_store_with_release(current->status, SUCCEEDED); - break; - case del_blt_pred: - my_built_predecessors.delete_edge(*(current->pred)); - __TBB_store_with_release(current->status, SUCCEEDED); - break; - case blt_pred_cnt: - current->cnt_val = my_built_predecessors.edge_count(); - __TBB_store_with_release(current->status, SUCCEEDED); - break; - case blt_pred_cpy: - my_built_predecessors.copy_edges(*(current->plist)); - __TBB_store_with_release(current->status, SUCCEEDED); - break; -#endif - } - } - } -// ------------ End Aggregator --------------- - 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 input_type& v) __TBB_override { - key_matching_port_operation op_data(v, try__put); - task *rtask = NULL; - my_aggregator.execute(&op_data); - if(op_data.status == SUCCEEDED) { - rtask = my_join->increment_key_count((*(this->get_key_func()))(v), false); // may spawn - // rtask has to reflect the return status of the try_put - if(!rtask) rtask = SUCCESSFULLY_ENQUEUED; - } - return rtask; - } - - public: - - key_matching_port() : receiver(), buffer_type() { - my_join = NULL; - my_aggregator.initialize_handler(handler_type(this)); - } - - // copy constructor - key_matching_port(const key_matching_port& /*other*/) : receiver(), buffer_type() { - my_join = NULL; - my_aggregator.initialize_handler(handler_type(this)); - } - - ~key_matching_port() { } - - void set_join_node_pointer(forwarding_base *join) { - my_join = dynamic_cast*>(join); - } - - void set_my_key_func(type_to_key_func_type *f) { this->set_key_func(f); } - - type_to_key_func_type* get_my_key_func() { return this->get_key_func(); } - - bool get_item( input_type &v ) { - // aggregator uses current_key from FE for Key - key_matching_port_operation op_data(&v, get__item); - my_aggregator.execute(&op_data); - return op_data.status == SUCCEEDED; - } - -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - built_predecessors_type &built_predecessors() __TBB_override { return my_built_predecessors; } - - 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); - } - - 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); - } - - 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; - } - - 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); - } -#endif - - // reset_port is called when item is accepted by successor, but - // is initiated by join_node. - void reset_port() { - key_matching_port_operation op_data(res_port); - my_aggregator.execute(&op_data); - return; - } - -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - void extract_receiver() { - buffer_type::reset(); - my_built_predecessors.receiver_extract(*this); - } -#endif - void reset_receiver(reset_flags f ) __TBB_override { - tbb::internal::suppress_unused_warning(f); - buffer_type::reset(); -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - if (f & rf_clear_edges) - my_built_predecessors.clear(); -#endif - } - - private: - // my_join forwarding base used to count number of inputs that - // received key. - matching_forwarding_base *my_join; -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - edge_container my_built_predecessors; -#endif - }; // key_matching_port - - using namespace graph_policy_namespace; - - template - class join_node_base; - - //! join_node_FE : implements input port policy - template - class join_node_FE; - - template - class join_node_FE : public forwarding_base { - public: - static const int N = tbb::flow::tuple_size::value; - typedef OutputTuple output_type; - typedef InputTuple input_type; - typedef join_node_base base_node_type; // for forwarding - - join_node_FE(graph &g) : forwarding_base(g), my_node(NULL) { - ports_with_no_inputs = N; - join_helper::set_join_node_pointer(my_inputs, this); - } - - join_node_FE(const join_node_FE& other) : forwarding_base(*(other.forwarding_base::graph_pointer)), my_node(NULL) { - ports_with_no_inputs = N; - join_helper::set_join_node_pointer(my_inputs, this); - } - - void set_my_node(base_node_type *new_my_node) { my_node = new_my_node; } - - 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) __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()) ) ) - forward_task_bypass(*my_node); - if(!handle_task) return rtask; - FLOW_SPAWN(*rtask); - } - } - return NULL; - } - - input_type &input_ports() { return my_inputs; } - - protected: - - void reset( reset_flags f) { - // called outside of parallel contexts - ports_with_no_inputs = N; - join_helper::reset_inputs(my_inputs, f); - } - -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - void extract( ) { - // called outside of parallel contexts - ports_with_no_inputs = N; - join_helper::extract_inputs(my_inputs); - } -#endif - - // all methods on input ports should be called under mutual exclusion from join_node_base. - - bool tuple_build_may_succeed() { - return !ports_with_no_inputs; - } - - bool try_to_make_tuple(output_type &out) { - if(ports_with_no_inputs) return false; - return join_helper::reserve(my_inputs, out); - } - - void tuple_accepted() { - join_helper::consume_reservations(my_inputs); - } - void tuple_rejected() { - join_helper::release_reservations(my_inputs); - } - - input_type my_inputs; - base_node_type *my_node; - atomic ports_with_no_inputs; - }; // join_node_FE - - template - class join_node_FE : public forwarding_base { - public: - static const int N = tbb::flow::tuple_size::value; - typedef OutputTuple output_type; - typedef InputTuple input_type; - typedef join_node_base base_node_type; // for forwarding - - join_node_FE(graph &g) : forwarding_base(g), my_node(NULL) { - ports_with_no_items = N; - join_helper::set_join_node_pointer(my_inputs, this); - } - - join_node_FE(const join_node_FE& other) : forwarding_base(*(other.forwarding_base::graph_pointer)), my_node(NULL) { - ports_with_no_items = N; - join_helper::set_join_node_pointer(my_inputs, this); - } - - // needed for forwarding - void set_my_node(base_node_type *new_my_node) { my_node = new_my_node; } - - void reset_port_count() { - ports_with_no_items = N; - } - - // if all input_ports have items, spawn forward to try and consume tuples - task * decrement_port_count(bool handle_task) __TBB_override - { - if(ports_with_no_items.fetch_and_decrement() == 1) { - if(this->graph_pointer->is_active()) { - task *rtask = new ( task::allocate_additional_child_of( *(this->graph_pointer->root_task()) ) ) - forward_task_bypass (*my_node); - if(!handle_task) return rtask; - FLOW_SPAWN( *rtask); - } - } - return NULL; - } - - void increment_port_count() __TBB_override { __TBB_ASSERT(false, NULL); } // should never be called - - input_type &input_ports() { return my_inputs; } - - protected: - - void reset( reset_flags f) { - reset_port_count(); - join_helper::reset_inputs(my_inputs, f ); - } - -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - void extract() { - reset_port_count(); - join_helper::extract_inputs(my_inputs); - } -#endif - // all methods on input ports should be called under mutual exclusion from join_node_base. - - bool tuple_build_may_succeed() { - return !ports_with_no_items; - } - - bool try_to_make_tuple(output_type &out) { - if(ports_with_no_items) return false; - return join_helper::get_items(my_inputs, out); - } - - void tuple_accepted() { - reset_port_count(); - join_helper::reset_ports(my_inputs); - } - void tuple_rejected() { - // nothing to do. - } - - input_type my_inputs; - base_node_type *my_node; - atomic ports_with_no_items; - }; // join_node_FE - - // key_matching join front-end. - template - class join_node_FE, InputTuple, OutputTuple> : public matching_forwarding_base, - // buffer of key value counts - public hash_buffer< // typedefed below to key_to_count_buffer_type - typename tbb::internal::strip::type&, // force ref type on K - count_element::type>, - internal::type_to_key_function_body< - count_element::type>, - typename tbb::internal::strip::type& >, - KHash >, - // buffer of output items - public item_buffer { - public: - static const int N = tbb::flow::tuple_size::value; - typedef OutputTuple output_type; - typedef InputTuple input_type; - typedef K key_type; - typedef typename tbb::internal::strip::type unref_key_type; - typedef KHash key_hash_compare; - // must use K without ref. - typedef count_element count_element_type; - // method that lets us refer to the key of this type. - typedef key_to_count_functor key_to_count_func; - typedef internal::type_to_key_function_body< count_element_type, unref_key_type&> TtoK_function_body_type; - typedef internal::type_to_key_function_body_leaf TtoK_function_body_leaf_type; - // this is the type of the special table that keeps track of the number of discrete - // elements corresponding to each key that we've seen. - typedef hash_buffer< unref_key_type&, count_element_type, TtoK_function_body_type, key_hash_compare > - key_to_count_buffer_type; - typedef item_buffer output_buffer_type; - typedef join_node_base, InputTuple, OutputTuple> base_node_type; // for forwarding - typedef matching_forwarding_base forwarding_base_type; - -// ----------- Aggregator ------------ - // the aggregator is only needed to serialize the access to the hash table. - // and the output_buffer_type base class - private: - enum op_type { res_count, inc_count, may_succeed, try_make }; - enum op_stat {WAIT=0, SUCCEEDED, FAILED}; - typedef join_node_FE, InputTuple, OutputTuple> class_type; - - class key_matching_FE_operation : public aggregated_operation { - public: - char type; - unref_key_type my_val; - output_type* my_output; - task *bypass_t; - bool enqueue_task; - // constructor for value parameter - key_matching_FE_operation(const unref_key_type& e , bool q_task , op_type t) : type(char(t)), my_val(e), - my_output(NULL), bypass_t(NULL), enqueue_task(q_task) {} - key_matching_FE_operation(output_type *p, op_type t) : type(char(t)), my_output(p), bypass_t(NULL), - enqueue_task(true) {} - // constructor with no parameter - key_matching_FE_operation(op_type t) : type(char(t)), my_output(NULL), bypass_t(NULL), enqueue_task(true) {} - }; - - typedef internal::aggregating_functor handler_type; - friend class internal::aggregating_functor; - aggregator my_aggregator; - - // called from aggregator, so serialized - // returns a task pointer if the a task would have been enqueued but we asked that - // it be returned. Otherwise returns NULL. - task * fill_output_buffer(unref_key_type &t, bool should_enqueue, bool handle_task) { - output_type l_out; - task *rtask = NULL; - bool do_fwd = should_enqueue && this->buffer_empty() && this->graph_pointer->is_active(); - this->current_key = t; - this->delete_with_key(this->current_key); // remove the key - if(join_helper::get_items(my_inputs, l_out)) { // <== call back - this->push_back(l_out); - if(do_fwd) { // we enqueue if receiving an item from predecessor, not if successor asks for item - rtask = new ( task::allocate_additional_child_of( *(this->graph_pointer->root_task()) ) ) - forward_task_bypass(*my_node); - if(handle_task) { - FLOW_SPAWN(*rtask); - rtask = NULL; - } - do_fwd = false; - } - // retire the input values - join_helper::reset_ports(my_inputs); // <== call back - } - else { - __TBB_ASSERT(false, "should have had something to push"); - } - return rtask; - } - - void handle_operations(key_matching_FE_operation* op_list) { - key_matching_FE_operation *current; - while(op_list) { - current = op_list; - op_list = op_list->next; - switch(current->type) { - case res_count: // called from BE - { - this->destroy_front(); - __TBB_store_with_release(current->status, SUCCEEDED); - } - break; - case inc_count: { // called from input ports - count_element_type *p = 0; - unref_key_type &t = current->my_val; - bool do_enqueue = current->enqueue_task; - if(!(this->find_ref_with_key(t,p))) { - count_element_type ev; - ev.my_key = t; - ev.my_value = 0; - this->insert_with_key(ev); - if(!(this->find_ref_with_key(t,p))) { - __TBB_ASSERT(false, "should find key after inserting it"); - } - } - if(++(p->my_value) == size_t(N)) { - task *rtask = fill_output_buffer(t, true, do_enqueue); - __TBB_ASSERT(!rtask || !do_enqueue, "task should not be returned"); - current->bypass_t = rtask; - } - } - __TBB_store_with_release(current->status, SUCCEEDED); - break; - case may_succeed: // called from BE - __TBB_store_with_release(current->status, this->buffer_empty() ? FAILED : SUCCEEDED); - break; - case try_make: // called from BE - if(this->buffer_empty()) { - __TBB_store_with_release(current->status, FAILED); - } - else { - *(current->my_output) = this->front(); - __TBB_store_with_release(current->status, SUCCEEDED); - } - break; - } - } - } -// ------------ End Aggregator --------------- - - public: - template - join_node_FE(graph &g, FunctionTuple &TtoK_funcs) : forwarding_base_type(g), my_node(NULL) { - join_helper::set_join_node_pointer(my_inputs, this); - join_helper::set_key_functors(my_inputs, TtoK_funcs); - my_aggregator.initialize_handler(handler_type(this)); - TtoK_function_body_type *cfb = new TtoK_function_body_leaf_type(key_to_count_func()); - this->set_key_func(cfb); - } - - join_node_FE(const join_node_FE& other) : forwarding_base_type(*(other.forwarding_base_type::graph_pointer)), key_to_count_buffer_type(), - output_buffer_type() { - my_node = NULL; - join_helper::set_join_node_pointer(my_inputs, this); - join_helper::copy_key_functors(my_inputs, const_cast(other.my_inputs)); - my_aggregator.initialize_handler(handler_type(this)); - TtoK_function_body_type *cfb = new TtoK_function_body_leaf_type(key_to_count_func()); - this->set_key_func(cfb); - } - - // needed for forwarding - void set_my_node(base_node_type *new_my_node) { my_node = new_my_node; } - - void reset_port_count() { // called from BE - key_matching_FE_operation op_data(res_count); - my_aggregator.execute(&op_data); - return; - } - - // if all input_ports have items, spawn forward to try and consume tuples - // return a task if we are asked and did create one. - 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; - } - - task *decrement_port_count(bool /*handle_task*/) __TBB_override { __TBB_ASSERT(false, NULL); return NULL; } - - void increment_port_count() __TBB_override { __TBB_ASSERT(false, NULL); } // should never be called - - input_type &input_ports() { return my_inputs; } - - protected: - - void reset( reset_flags f ) { - // called outside of parallel contexts - join_helper::reset_inputs(my_inputs, f); - - key_to_count_buffer_type::reset(); - output_buffer_type::reset(); - } - -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - void extract() { - // called outside of parallel contexts - join_helper::extract_inputs(my_inputs); - key_to_count_buffer_type::reset(); // have to reset the tag counts - output_buffer_type::reset(); // also the queue of outputs - // my_node->current_tag = NO_TAG; - } -#endif - // all methods on input ports should be called under mutual exclusion from join_node_base. - - bool tuple_build_may_succeed() { // called from back-end - key_matching_FE_operation op_data(may_succeed); - my_aggregator.execute(&op_data); - return op_data.status == SUCCEEDED; - } - - // cannot lock while calling back to input_ports. current_key will only be set - // and reset under the aggregator, so it will remain consistent. - bool try_to_make_tuple(output_type &out) { - key_matching_FE_operation op_data(&out,try_make); - my_aggregator.execute(&op_data); - return op_data.status == SUCCEEDED; - } - - void tuple_accepted() { - reset_port_count(); // reset current_key after ports reset. - } - - void tuple_rejected() { - // nothing to do. - } - - input_type my_inputs; // input ports - base_node_type *my_node; - }; // join_node_FE, InputTuple, OutputTuple> - - //! join_node_base - template - class join_node_base : public graph_node, public join_node_FE, - public sender { - protected: - using graph_node::my_graph; - public: - typedef OutputTuple output_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; - using input_ports_type::tuple_accepted; - using input_ports_type::tuple_rejected; -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - typedef typename sender::built_successors_type built_successors_type; - typedef typename sender::successor_list_type successor_list_type; -#endif - - private: - // ----------- Aggregator ------------ - enum op_type { reg_succ, rem_succ, try__get, do_fwrd, do_fwrd_bypass -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - , add_blt_succ, del_blt_succ, blt_succ_cnt, blt_succ_cpy -#endif - }; - enum op_stat {WAIT=0, SUCCEEDED, FAILED}; - typedef join_node_base class_type; - - class join_node_base_operation : public aggregated_operation { - public: - char type; - union { - output_type *my_arg; - successor_type *my_succ; -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - size_t cnt_val; - successor_list_type *slist; -#endif - }; - task *bypass_t; - join_node_base_operation(const output_type& e, op_type t) : type(char(t)), - my_arg(const_cast(&e)), bypass_t(NULL) {} - join_node_base_operation(const successor_type &s, op_type t) : type(char(t)), - my_succ(const_cast(&s)), bypass_t(NULL) {} - join_node_base_operation(op_type t) : type(char(t)), bypass_t(NULL) {} - }; - - typedef internal::aggregating_functor handler_type; - friend class internal::aggregating_functor; - bool forwarder_busy; - aggregator my_aggregator; - - void handle_operations(join_node_base_operation* op_list) { - join_node_base_operation *current; - while(op_list) { - current = op_list; - op_list = op_list->next; - switch(current->type) { - case reg_succ: { - my_successors.register_successor(*(current->my_succ)); - if(tuple_build_may_succeed() && !forwarder_busy && this->graph_node::my_graph.is_active()) { - task *rtask = new ( task::allocate_additional_child_of(*(this->graph_node::my_graph.root_task())) ) - forward_task_bypass - >(*this); - FLOW_SPAWN(*rtask); - forwarder_busy = true; - } - __TBB_store_with_release(current->status, SUCCEEDED); - } - break; - case rem_succ: - my_successors.remove_successor(*(current->my_succ)); - __TBB_store_with_release(current->status, SUCCEEDED); - break; - case try__get: - if(tuple_build_may_succeed()) { - if(try_to_make_tuple(*(current->my_arg))) { - tuple_accepted(); - __TBB_store_with_release(current->status, SUCCEEDED); - } - else __TBB_store_with_release(current->status, FAILED); - } - else __TBB_store_with_release(current->status, FAILED); - break; - case do_fwrd_bypass: { - bool build_succeeded; - task *last_task = NULL; - output_type out; - if(tuple_build_may_succeed()) { // checks output queue of FE - do { - build_succeeded = try_to_make_tuple(out); // fetch front_end of queue - if(build_succeeded) { - task *new_task = my_successors.try_put_task(out); - last_task = combine_tasks(last_task, new_task); - if(new_task) { - tuple_accepted(); - } - else { - tuple_rejected(); - build_succeeded = false; - } - } - } while(build_succeeded); - } - current->bypass_t = last_task; - __TBB_store_with_release(current->status, SUCCEEDED); - forwarder_busy = false; - } - break; -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - case add_blt_succ: - my_successors.internal_add_built_successor(*(current->my_succ)); - __TBB_store_with_release(current->status, SUCCEEDED); - break; - case del_blt_succ: - my_successors.internal_delete_built_successor(*(current->my_succ)); - __TBB_store_with_release(current->status, SUCCEEDED); - break; - case blt_succ_cnt: - current->cnt_val = my_successors.successor_count(); - __TBB_store_with_release(current->status, SUCCEEDED); - break; - case blt_succ_cpy: - my_successors.copy_successors(*(current->slist)); - __TBB_store_with_release(current->status, SUCCEEDED); - break; -#endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */ - } - } - } - // ---------- end aggregator ----------- - public: - join_node_base(graph &g) : graph_node(g), input_ports_type(g), forwarder_busy(false) { - my_successors.set_owner(this); - input_ports_type::set_my_node(this); - my_aggregator.initialize_handler(handler_type(this)); - } - - join_node_base(const join_node_base& other) : - graph_node(other.graph_node::my_graph), input_ports_type(other), - sender(), forwarder_busy(false), my_successors() { - my_successors.set_owner(this); - input_ports_type::set_my_node(this); - my_aggregator.initialize_handler(handler_type(this)); - } - - template - join_node_base(graph &g, FunctionTuple f) : graph_node(g), input_ports_type(g, f), forwarder_busy(false) { - my_successors.set_owner(this); - input_ports_type::set_my_node(this); - my_aggregator.initialize_handler(handler_type(this)); - } - - 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) __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) __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 - built_successors_type &built_successors() __TBB_override { return my_successors.built_successors(); } - - 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); - } - - 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); - } - - 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; - } - - 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); - } -#endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */ - -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - void extract() __TBB_override { - input_ports_type::extract(); - my_successors.built_successors().sender_extract(*this); - } -#endif - - protected: - - void reset_node(reset_flags f) __TBB_override { - input_ports_type::reset(f); - if(f & rf_clear_edges) my_successors.clear(); - } - - private: - broadcast_cache my_successors; - - friend class forward_task_bypass< join_node_base >; - task *forward_task() { - join_node_base_operation op_data(do_fwrd_bypass); - my_aggregator.execute(&op_data); - return op_data.bypass_t; - } - - }; // join_node_base - - // join base class type generator - template class PT, typename OutputTuple, typename JP> - struct join_base { - typedef typename internal::join_node_base::type, OutputTuple> type; - }; - - template - struct join_base > { - typedef key_matching key_traits_type; - typedef K key_type; - typedef KHash key_hash_compare; - typedef typename internal::join_node_base< key_traits_type, - // ports type - typename wrap_key_tuple_elements::type, - OutputTuple > type; - }; - - //! unfolded_join_node : passes input_ports_type to join_node_base. We build the input port type - // using tuple_element. The class PT is the port type (reserving_port, queueing_port, key_matching_port) - // and should match the typename. - - template class PT, typename OutputTuple, typename JP> - class unfolded_join_node : public join_base::type { - public: - typedef typename wrap_tuple_elements::type input_ports_type; - typedef OutputTuple output_type; - private: - typedef join_node_base base_type; - public: - unfolded_join_node(graph &g) : base_type(g) {} - unfolded_join_node(const unfolded_join_node &other) : base_type(other) {} - }; - -#if __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING - template - struct key_from_message_body { - K operator()(const T& t) const { - using tbb::flow::key_from_message; - return key_from_message(t); - } - }; - // Adds const to reference type - template - struct key_from_message_body { - const K& operator()(const T& t) const { - using tbb::flow::key_from_message; - return key_from_message(t); - } - }; -#endif /* __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING */ - // key_matching unfolded_join_node. This must be a separate specialization because the constructors - // differ. - - template - class unfolded_join_node<2,key_matching_port,OutputTuple,key_matching > : public - join_base<2,key_matching_port,OutputTuple,key_matching >::type { - typedef typename tbb::flow::tuple_element<0, OutputTuple>::type T0; - typedef typename tbb::flow::tuple_element<1, OutputTuple>::type T1; - public: - typedef typename wrap_key_tuple_elements<2,key_matching_port,key_matching,OutputTuple>::type input_ports_type; - typedef OutputTuple output_type; - private: - typedef join_node_base, input_ports_type, output_type > base_type; - typedef typename internal::type_to_key_function_body *f0_p; - typedef typename internal::type_to_key_function_body *f1_p; - typedef typename tbb::flow::tuple< f0_p, f1_p > func_initializer_type; - public: -#if __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING - unfolded_join_node(graph &g) : base_type(g, - func_initializer_type( - new internal::type_to_key_function_body_leaf >(key_from_message_body()), - new internal::type_to_key_function_body_leaf >(key_from_message_body()) - ) ) { - } -#endif /* __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING */ - template - unfolded_join_node(graph &g, Body0 body0, Body1 body1) : base_type(g, - func_initializer_type( - new internal::type_to_key_function_body_leaf(body0), - new internal::type_to_key_function_body_leaf(body1) - ) ) { - __TBB_STATIC_ASSERT(tbb::flow::tuple_size::value == 2, "wrong number of body initializers"); - } - unfolded_join_node(const unfolded_join_node &other) : base_type(other) {} - }; - - template - class unfolded_join_node<3,key_matching_port,OutputTuple,key_matching > : public - join_base<3,key_matching_port,OutputTuple,key_matching >::type { - typedef typename tbb::flow::tuple_element<0, OutputTuple>::type T0; - typedef typename tbb::flow::tuple_element<1, OutputTuple>::type T1; - typedef typename tbb::flow::tuple_element<2, OutputTuple>::type T2; - public: - typedef typename wrap_key_tuple_elements<3,key_matching_port,key_matching,OutputTuple>::type input_ports_type; - typedef OutputTuple output_type; - private: - typedef join_node_base, input_ports_type, output_type > base_type; - typedef typename internal::type_to_key_function_body *f0_p; - typedef typename internal::type_to_key_function_body *f1_p; - typedef typename internal::type_to_key_function_body *f2_p; - typedef typename tbb::flow::tuple< f0_p, f1_p, f2_p > func_initializer_type; - public: -#if __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING - unfolded_join_node(graph &g) : base_type(g, - func_initializer_type( - new internal::type_to_key_function_body_leaf >(key_from_message_body()), - new internal::type_to_key_function_body_leaf >(key_from_message_body()), - new internal::type_to_key_function_body_leaf >(key_from_message_body()) - ) ) { - } -#endif /* __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING */ - template - unfolded_join_node(graph &g, Body0 body0, Body1 body1, Body2 body2) : base_type(g, - func_initializer_type( - new internal::type_to_key_function_body_leaf(body0), - new internal::type_to_key_function_body_leaf(body1), - new internal::type_to_key_function_body_leaf(body2) - ) ) { - __TBB_STATIC_ASSERT(tbb::flow::tuple_size::value == 3, "wrong number of body initializers"); - } - unfolded_join_node(const unfolded_join_node &other) : base_type(other) {} - }; - - template - class unfolded_join_node<4,key_matching_port,OutputTuple,key_matching > : public - join_base<4,key_matching_port,OutputTuple,key_matching >::type { - typedef typename tbb::flow::tuple_element<0, OutputTuple>::type T0; - typedef typename tbb::flow::tuple_element<1, OutputTuple>::type T1; - typedef typename tbb::flow::tuple_element<2, OutputTuple>::type T2; - typedef typename tbb::flow::tuple_element<3, OutputTuple>::type T3; - public: - typedef typename wrap_key_tuple_elements<4,key_matching_port,key_matching,OutputTuple>::type input_ports_type; - typedef OutputTuple output_type; - private: - typedef join_node_base, input_ports_type, output_type > base_type; - typedef typename internal::type_to_key_function_body *f0_p; - typedef typename internal::type_to_key_function_body *f1_p; - typedef typename internal::type_to_key_function_body *f2_p; - typedef typename internal::type_to_key_function_body *f3_p; - typedef typename tbb::flow::tuple< f0_p, f1_p, f2_p, f3_p > func_initializer_type; - public: -#if __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING - unfolded_join_node(graph &g) : base_type(g, - func_initializer_type( - new internal::type_to_key_function_body_leaf >(key_from_message_body()), - new internal::type_to_key_function_body_leaf >(key_from_message_body()), - new internal::type_to_key_function_body_leaf >(key_from_message_body()), - new internal::type_to_key_function_body_leaf >(key_from_message_body()) - ) ) { - } -#endif /* __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING */ - template - unfolded_join_node(graph &g, Body0 body0, Body1 body1, Body2 body2, Body3 body3) : base_type(g, - func_initializer_type( - new internal::type_to_key_function_body_leaf(body0), - new internal::type_to_key_function_body_leaf(body1), - new internal::type_to_key_function_body_leaf(body2), - new internal::type_to_key_function_body_leaf(body3) - ) ) { - __TBB_STATIC_ASSERT(tbb::flow::tuple_size::value == 4, "wrong number of body initializers"); - } - unfolded_join_node(const unfolded_join_node &other) : base_type(other) {} - }; - - template - class unfolded_join_node<5,key_matching_port,OutputTuple,key_matching > : public - join_base<5,key_matching_port,OutputTuple,key_matching >::type { - typedef typename tbb::flow::tuple_element<0, OutputTuple>::type T0; - typedef typename tbb::flow::tuple_element<1, OutputTuple>::type T1; - typedef typename tbb::flow::tuple_element<2, OutputTuple>::type T2; - typedef typename tbb::flow::tuple_element<3, OutputTuple>::type T3; - typedef typename tbb::flow::tuple_element<4, OutputTuple>::type T4; - public: - typedef typename wrap_key_tuple_elements<5,key_matching_port,key_matching,OutputTuple>::type input_ports_type; - typedef OutputTuple output_type; - private: - typedef join_node_base , input_ports_type, output_type > base_type; - typedef typename internal::type_to_key_function_body *f0_p; - typedef typename internal::type_to_key_function_body *f1_p; - typedef typename internal::type_to_key_function_body *f2_p; - typedef typename internal::type_to_key_function_body *f3_p; - typedef typename internal::type_to_key_function_body *f4_p; - typedef typename tbb::flow::tuple< f0_p, f1_p, f2_p, f3_p, f4_p > func_initializer_type; - public: -#if __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING - unfolded_join_node(graph &g) : base_type(g, - func_initializer_type( - new internal::type_to_key_function_body_leaf >(key_from_message_body()), - new internal::type_to_key_function_body_leaf >(key_from_message_body()), - new internal::type_to_key_function_body_leaf >(key_from_message_body()), - new internal::type_to_key_function_body_leaf >(key_from_message_body()), - new internal::type_to_key_function_body_leaf >(key_from_message_body()) - ) ) { - } -#endif /* __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING */ - template - unfolded_join_node(graph &g, Body0 body0, Body1 body1, Body2 body2, Body3 body3, Body4 body4) : base_type(g, - func_initializer_type( - new internal::type_to_key_function_body_leaf(body0), - new internal::type_to_key_function_body_leaf(body1), - new internal::type_to_key_function_body_leaf(body2), - new internal::type_to_key_function_body_leaf(body3), - new internal::type_to_key_function_body_leaf(body4) - ) ) { - __TBB_STATIC_ASSERT(tbb::flow::tuple_size::value == 5, "wrong number of body initializers"); - } - unfolded_join_node(const unfolded_join_node &other) : base_type(other) {} - }; - -#if __TBB_VARIADIC_MAX >= 6 - template - class unfolded_join_node<6,key_matching_port,OutputTuple,key_matching > : public - join_base<6,key_matching_port,OutputTuple,key_matching >::type { - typedef typename tbb::flow::tuple_element<0, OutputTuple>::type T0; - typedef typename tbb::flow::tuple_element<1, OutputTuple>::type T1; - typedef typename tbb::flow::tuple_element<2, OutputTuple>::type T2; - typedef typename tbb::flow::tuple_element<3, OutputTuple>::type T3; - typedef typename tbb::flow::tuple_element<4, OutputTuple>::type T4; - typedef typename tbb::flow::tuple_element<5, OutputTuple>::type T5; - public: - typedef typename wrap_key_tuple_elements<6,key_matching_port,key_matching,OutputTuple>::type input_ports_type; - typedef OutputTuple output_type; - private: - typedef join_node_base , input_ports_type, output_type > base_type; - typedef typename internal::type_to_key_function_body *f0_p; - typedef typename internal::type_to_key_function_body *f1_p; - typedef typename internal::type_to_key_function_body *f2_p; - typedef typename internal::type_to_key_function_body *f3_p; - typedef typename internal::type_to_key_function_body *f4_p; - typedef typename internal::type_to_key_function_body *f5_p; - typedef typename tbb::flow::tuple< f0_p, f1_p, f2_p, f3_p, f4_p, f5_p > func_initializer_type; - public: -#if __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING - unfolded_join_node(graph &g) : base_type(g, - func_initializer_type( - new internal::type_to_key_function_body_leaf >(key_from_message_body()), - new internal::type_to_key_function_body_leaf >(key_from_message_body()), - new internal::type_to_key_function_body_leaf >(key_from_message_body()), - new internal::type_to_key_function_body_leaf >(key_from_message_body()), - new internal::type_to_key_function_body_leaf >(key_from_message_body()), - new internal::type_to_key_function_body_leaf >(key_from_message_body()) - ) ) { - } -#endif /* __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING */ - template - unfolded_join_node(graph &g, Body0 body0, Body1 body1, Body2 body2, Body3 body3, Body4 body4, Body5 body5) - : base_type(g, func_initializer_type( - new internal::type_to_key_function_body_leaf(body0), - new internal::type_to_key_function_body_leaf(body1), - new internal::type_to_key_function_body_leaf(body2), - new internal::type_to_key_function_body_leaf(body3), - new internal::type_to_key_function_body_leaf(body4), - new internal::type_to_key_function_body_leaf(body5) - ) ) { - __TBB_STATIC_ASSERT(tbb::flow::tuple_size::value == 6, "wrong number of body initializers"); - } - unfolded_join_node(const unfolded_join_node &other) : base_type(other) {} - }; -#endif - -#if __TBB_VARIADIC_MAX >= 7 - template - class unfolded_join_node<7,key_matching_port,OutputTuple,key_matching > : public - join_base<7,key_matching_port,OutputTuple,key_matching >::type { - typedef typename tbb::flow::tuple_element<0, OutputTuple>::type T0; - typedef typename tbb::flow::tuple_element<1, OutputTuple>::type T1; - typedef typename tbb::flow::tuple_element<2, OutputTuple>::type T2; - typedef typename tbb::flow::tuple_element<3, OutputTuple>::type T3; - typedef typename tbb::flow::tuple_element<4, OutputTuple>::type T4; - typedef typename tbb::flow::tuple_element<5, OutputTuple>::type T5; - typedef typename tbb::flow::tuple_element<6, OutputTuple>::type T6; - public: - typedef typename wrap_key_tuple_elements<7,key_matching_port,key_matching,OutputTuple>::type input_ports_type; - typedef OutputTuple output_type; - private: - typedef join_node_base , input_ports_type, output_type > base_type; - typedef typename internal::type_to_key_function_body *f0_p; - typedef typename internal::type_to_key_function_body *f1_p; - typedef typename internal::type_to_key_function_body *f2_p; - typedef typename internal::type_to_key_function_body *f3_p; - typedef typename internal::type_to_key_function_body *f4_p; - typedef typename internal::type_to_key_function_body *f5_p; - typedef typename internal::type_to_key_function_body *f6_p; - typedef typename tbb::flow::tuple< f0_p, f1_p, f2_p, f3_p, f4_p, f5_p, f6_p > func_initializer_type; - public: -#if __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING - unfolded_join_node(graph &g) : base_type(g, - func_initializer_type( - new internal::type_to_key_function_body_leaf >(key_from_message_body()), - new internal::type_to_key_function_body_leaf >(key_from_message_body()), - new internal::type_to_key_function_body_leaf >(key_from_message_body()), - new internal::type_to_key_function_body_leaf >(key_from_message_body()), - new internal::type_to_key_function_body_leaf >(key_from_message_body()), - new internal::type_to_key_function_body_leaf >(key_from_message_body()), - new internal::type_to_key_function_body_leaf >(key_from_message_body()) - ) ) { - } -#endif /* __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING */ - template - unfolded_join_node(graph &g, Body0 body0, Body1 body1, Body2 body2, Body3 body3, Body4 body4, - Body5 body5, Body6 body6) : base_type(g, func_initializer_type( - new internal::type_to_key_function_body_leaf(body0), - new internal::type_to_key_function_body_leaf(body1), - new internal::type_to_key_function_body_leaf(body2), - new internal::type_to_key_function_body_leaf(body3), - new internal::type_to_key_function_body_leaf(body4), - new internal::type_to_key_function_body_leaf(body5), - new internal::type_to_key_function_body_leaf(body6) - ) ) { - __TBB_STATIC_ASSERT(tbb::flow::tuple_size::value == 7, "wrong number of body initializers"); - } - unfolded_join_node(const unfolded_join_node &other) : base_type(other) {} - }; -#endif - -#if __TBB_VARIADIC_MAX >= 8 - template - class unfolded_join_node<8,key_matching_port,OutputTuple,key_matching > : public - join_base<8,key_matching_port,OutputTuple,key_matching >::type { - typedef typename tbb::flow::tuple_element<0, OutputTuple>::type T0; - typedef typename tbb::flow::tuple_element<1, OutputTuple>::type T1; - typedef typename tbb::flow::tuple_element<2, OutputTuple>::type T2; - typedef typename tbb::flow::tuple_element<3, OutputTuple>::type T3; - typedef typename tbb::flow::tuple_element<4, OutputTuple>::type T4; - typedef typename tbb::flow::tuple_element<5, OutputTuple>::type T5; - typedef typename tbb::flow::tuple_element<6, OutputTuple>::type T6; - typedef typename tbb::flow::tuple_element<7, OutputTuple>::type T7; - public: - typedef typename wrap_key_tuple_elements<8,key_matching_port,key_matching,OutputTuple>::type input_ports_type; - typedef OutputTuple output_type; - private: - typedef join_node_base , input_ports_type, output_type > base_type; - typedef typename internal::type_to_key_function_body *f0_p; - typedef typename internal::type_to_key_function_body *f1_p; - typedef typename internal::type_to_key_function_body *f2_p; - typedef typename internal::type_to_key_function_body *f3_p; - typedef typename internal::type_to_key_function_body *f4_p; - typedef typename internal::type_to_key_function_body *f5_p; - typedef typename internal::type_to_key_function_body *f6_p; - typedef typename internal::type_to_key_function_body *f7_p; - typedef typename tbb::flow::tuple< f0_p, f1_p, f2_p, f3_p, f4_p, f5_p, f6_p, f7_p > func_initializer_type; - public: -#if __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING - unfolded_join_node(graph &g) : base_type(g, - func_initializer_type( - new internal::type_to_key_function_body_leaf >(key_from_message_body()), - new internal::type_to_key_function_body_leaf >(key_from_message_body()), - new internal::type_to_key_function_body_leaf >(key_from_message_body()), - new internal::type_to_key_function_body_leaf >(key_from_message_body()), - new internal::type_to_key_function_body_leaf >(key_from_message_body()), - new internal::type_to_key_function_body_leaf >(key_from_message_body()), - new internal::type_to_key_function_body_leaf >(key_from_message_body()), - new internal::type_to_key_function_body_leaf >(key_from_message_body()) - ) ) { - } -#endif /* __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING */ - template - unfolded_join_node(graph &g, Body0 body0, Body1 body1, Body2 body2, Body3 body3, Body4 body4, - Body5 body5, Body6 body6, Body7 body7) : base_type(g, func_initializer_type( - new internal::type_to_key_function_body_leaf(body0), - new internal::type_to_key_function_body_leaf(body1), - new internal::type_to_key_function_body_leaf(body2), - new internal::type_to_key_function_body_leaf(body3), - new internal::type_to_key_function_body_leaf(body4), - new internal::type_to_key_function_body_leaf(body5), - new internal::type_to_key_function_body_leaf(body6), - new internal::type_to_key_function_body_leaf(body7) - ) ) { - __TBB_STATIC_ASSERT(tbb::flow::tuple_size::value == 8, "wrong number of body initializers"); - } - unfolded_join_node(const unfolded_join_node &other) : base_type(other) {} - }; -#endif - -#if __TBB_VARIADIC_MAX >= 9 - template - class unfolded_join_node<9,key_matching_port,OutputTuple,key_matching > : public - join_base<9,key_matching_port,OutputTuple,key_matching >::type { - typedef typename tbb::flow::tuple_element<0, OutputTuple>::type T0; - typedef typename tbb::flow::tuple_element<1, OutputTuple>::type T1; - typedef typename tbb::flow::tuple_element<2, OutputTuple>::type T2; - typedef typename tbb::flow::tuple_element<3, OutputTuple>::type T3; - typedef typename tbb::flow::tuple_element<4, OutputTuple>::type T4; - typedef typename tbb::flow::tuple_element<5, OutputTuple>::type T5; - typedef typename tbb::flow::tuple_element<6, OutputTuple>::type T6; - typedef typename tbb::flow::tuple_element<7, OutputTuple>::type T7; - typedef typename tbb::flow::tuple_element<8, OutputTuple>::type T8; - public: - typedef typename wrap_key_tuple_elements<9,key_matching_port,key_matching,OutputTuple>::type input_ports_type; - typedef OutputTuple output_type; - private: - typedef join_node_base , input_ports_type, output_type > base_type; - typedef typename internal::type_to_key_function_body *f0_p; - typedef typename internal::type_to_key_function_body *f1_p; - typedef typename internal::type_to_key_function_body *f2_p; - typedef typename internal::type_to_key_function_body *f3_p; - typedef typename internal::type_to_key_function_body *f4_p; - typedef typename internal::type_to_key_function_body *f5_p; - typedef typename internal::type_to_key_function_body *f6_p; - typedef typename internal::type_to_key_function_body *f7_p; - typedef typename internal::type_to_key_function_body *f8_p; - typedef typename tbb::flow::tuple< f0_p, f1_p, f2_p, f3_p, f4_p, f5_p, f6_p, f7_p, f8_p > func_initializer_type; - public: -#if __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING - unfolded_join_node(graph &g) : base_type(g, - func_initializer_type( - new internal::type_to_key_function_body_leaf >(key_from_message_body()), - new internal::type_to_key_function_body_leaf >(key_from_message_body()), - new internal::type_to_key_function_body_leaf >(key_from_message_body()), - new internal::type_to_key_function_body_leaf >(key_from_message_body()), - new internal::type_to_key_function_body_leaf >(key_from_message_body()), - new internal::type_to_key_function_body_leaf >(key_from_message_body()), - new internal::type_to_key_function_body_leaf >(key_from_message_body()), - new internal::type_to_key_function_body_leaf >(key_from_message_body()), - new internal::type_to_key_function_body_leaf >(key_from_message_body()) - ) ) { - } -#endif /* __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING */ - template - unfolded_join_node(graph &g, Body0 body0, Body1 body1, Body2 body2, Body3 body3, Body4 body4, - Body5 body5, Body6 body6, Body7 body7, Body8 body8) : base_type(g, func_initializer_type( - new internal::type_to_key_function_body_leaf(body0), - new internal::type_to_key_function_body_leaf(body1), - new internal::type_to_key_function_body_leaf(body2), - new internal::type_to_key_function_body_leaf(body3), - new internal::type_to_key_function_body_leaf(body4), - new internal::type_to_key_function_body_leaf(body5), - new internal::type_to_key_function_body_leaf(body6), - new internal::type_to_key_function_body_leaf(body7), - new internal::type_to_key_function_body_leaf(body8) - ) ) { - __TBB_STATIC_ASSERT(tbb::flow::tuple_size::value == 9, "wrong number of body initializers"); - } - unfolded_join_node(const unfolded_join_node &other) : base_type(other) {} - }; -#endif - -#if __TBB_VARIADIC_MAX >= 10 - template - class unfolded_join_node<10,key_matching_port,OutputTuple,key_matching > : public - join_base<10,key_matching_port,OutputTuple,key_matching >::type { - typedef typename tbb::flow::tuple_element<0, OutputTuple>::type T0; - typedef typename tbb::flow::tuple_element<1, OutputTuple>::type T1; - typedef typename tbb::flow::tuple_element<2, OutputTuple>::type T2; - typedef typename tbb::flow::tuple_element<3, OutputTuple>::type T3; - typedef typename tbb::flow::tuple_element<4, OutputTuple>::type T4; - typedef typename tbb::flow::tuple_element<5, OutputTuple>::type T5; - typedef typename tbb::flow::tuple_element<6, OutputTuple>::type T6; - typedef typename tbb::flow::tuple_element<7, OutputTuple>::type T7; - typedef typename tbb::flow::tuple_element<8, OutputTuple>::type T8; - typedef typename tbb::flow::tuple_element<9, OutputTuple>::type T9; - public: - typedef typename wrap_key_tuple_elements<10,key_matching_port,key_matching,OutputTuple>::type input_ports_type; - typedef OutputTuple output_type; - private: - typedef join_node_base , input_ports_type, output_type > base_type; - typedef typename internal::type_to_key_function_body *f0_p; - typedef typename internal::type_to_key_function_body *f1_p; - typedef typename internal::type_to_key_function_body *f2_p; - typedef typename internal::type_to_key_function_body *f3_p; - typedef typename internal::type_to_key_function_body *f4_p; - typedef typename internal::type_to_key_function_body *f5_p; - typedef typename internal::type_to_key_function_body *f6_p; - typedef typename internal::type_to_key_function_body *f7_p; - typedef typename internal::type_to_key_function_body *f8_p; - typedef typename internal::type_to_key_function_body *f9_p; - typedef typename tbb::flow::tuple< f0_p, f1_p, f2_p, f3_p, f4_p, f5_p, f6_p, f7_p, f8_p, f9_p > func_initializer_type; - public: -#if __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING - unfolded_join_node(graph &g) : base_type(g, - func_initializer_type( - new internal::type_to_key_function_body_leaf >(key_from_message_body()), - new internal::type_to_key_function_body_leaf >(key_from_message_body()), - new internal::type_to_key_function_body_leaf >(key_from_message_body()), - new internal::type_to_key_function_body_leaf >(key_from_message_body()), - new internal::type_to_key_function_body_leaf >(key_from_message_body()), - new internal::type_to_key_function_body_leaf >(key_from_message_body()), - new internal::type_to_key_function_body_leaf >(key_from_message_body()), - new internal::type_to_key_function_body_leaf >(key_from_message_body()), - new internal::type_to_key_function_body_leaf >(key_from_message_body()), - new internal::type_to_key_function_body_leaf >(key_from_message_body()) - ) ) { - } -#endif /* __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING */ - template - unfolded_join_node(graph &g, Body0 body0, Body1 body1, Body2 body2, Body3 body3, Body4 body4, - Body5 body5, Body6 body6, Body7 body7, Body8 body8, Body9 body9) : base_type(g, func_initializer_type( - new internal::type_to_key_function_body_leaf(body0), - new internal::type_to_key_function_body_leaf(body1), - new internal::type_to_key_function_body_leaf(body2), - new internal::type_to_key_function_body_leaf(body3), - new internal::type_to_key_function_body_leaf(body4), - new internal::type_to_key_function_body_leaf(body5), - new internal::type_to_key_function_body_leaf(body6), - new internal::type_to_key_function_body_leaf(body7), - new internal::type_to_key_function_body_leaf(body8), - new internal::type_to_key_function_body_leaf(body9) - ) ) { - __TBB_STATIC_ASSERT(tbb::flow::tuple_size::value == 10, "wrong number of body initializers"); - } - unfolded_join_node(const unfolded_join_node &other) : base_type(other) {} - }; -#endif - - //! templated function to refer to input ports of the join node - template - typename tbb::flow::tuple_element::type &input_port(JNT &jn) { - return tbb::flow::get(jn.input_ports()); - } - -} -#endif // __TBB__flow_graph_join_impl_H - 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 deleted file mode 100644 index eeff72bc..00000000 --- a/lib/3rdParty/tbb/include/tbb/internal/_flow_graph_node_impl.h +++ /dev/null @@ -1,798 +0,0 @@ -/* - 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_node_impl_H -#define __TBB__flow_graph_node_impl_H - -#ifndef __TBB_flow_graph_H -#error Do not #include this internal file directly; use public TBB headers instead. -#endif - -#include "_flow_graph_item_buffer_impl.h" - -//! @cond INTERNAL -namespace internal { - - using tbb::internal::aggregated_operation; - using tbb::internal::aggregating_functor; - using tbb::internal::aggregator; - - 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 ); - } - }; - - //! Input and scheduling for a function node that takes a type Input as input - // The only up-ref is apply_body_impl, which should implement the function - // 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_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, - blt_pred_cnt, blt_pred_cpy // create vector copies of preds and succs -#endif - }; - typedef function_input_base class_type; - - public: - - //! The input type of this receiver - typedef Input input_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; - -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - typedef typename predecessor_cache_type::built_predecessors_type built_predecessors_type; - typedef typename receiver::predecessor_list_type predecessor_list_type; -#endif - - //! Constructor for function_input_base - function_input_base( graph &g, size_t max_concurrency, input_queue_type *q = NULL) - : 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)); - } - - //! Copy constructor - function_input_base( const function_input_base& src, input_queue_type *q = NULL) : - receiver(), tbb::internal::no_assign(), - 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); - my_aggregator.initialize_handler(handler_type(this)); - } - - //! Destructor - // The queue is allocated by the constructor for {multi}function_node. - // TODO: pass the graph_buffer_policy to the base so it can allocate the queue instead. - // This would be an interface-breaking change. - virtual ~function_input_base() { - if ( my_queue ) delete my_queue; - } - - //! Put to the node, returning a task if available - 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 == internal::SUCCEEDED) { - return op_data.bypass_t; - } - return NULL; - } - } - - //! Adds src to the list of cached predecessors. - bool register_predecessor( predecessor_type &src ) __TBB_override { - operation_type op_data(reg_pred); - op_data.r = &src; - my_aggregator.execute(&op_data); - return true; - } - - //! Removes src from the list of cached predecessors. - bool remove_predecessor( predecessor_type &src ) __TBB_override { - operation_type op_data(rem_pred); - op_data.r = &src; - my_aggregator.execute(&op_data); - return true; - } - -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - //! Adds to list of predecessors added by make_edge - 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) - 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); - } - - size_t predecessor_count() __TBB_override { - operation_type op_data(blt_pred_cnt); - my_aggregator.execute(&op_data); - return op_data.cnt_val; - } - - 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); - } - - built_predecessors_type &built_predecessors() __TBB_override { - return my_predecessors.built_predecessors(); - } -#endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */ - - protected: - - void reset_function_input_base( reset_flags f) { - my_concurrency = 0; - if(my_queue) { - my_queue->reset(); - } - reset_receiver(f); - forwarder_busy = false; - } - - graph* my_graph_ptr; - const size_t my_max_concurrency; - size_t my_concurrency; - input_queue_type *my_queue; - predecessor_cache my_predecessors; - - void reset_receiver( reset_flags f) __TBB_override { - if( f & rf_clear_edges) my_predecessors.clear(); - else - my_predecessors.reset(); - __TBB_ASSERT(!(f & rf_clear_edges) || my_predecessors.empty(), "function_input_base reset failed"); - } - - private: - - friend class apply_body_task_bypass< class_type, input_type >; - friend class forward_task_bypass< class_type >; - - class operation_type : public aggregated_operation< operation_type > { - public: - char type; - union { - input_type *elem; - predecessor_type *r; -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - size_t cnt_val; - predecessor_list_type *predv; -#endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */ - }; - tbb::task *bypass_t; - operation_type(const input_type& e, op_type t) : - type(char(t)), elem(const_cast(&e)) {} - operation_type(op_type t) : type(char(t)), r(NULL) {} - }; - - bool forwarder_busy; - typedef internal::aggregating_functor handler_type; - 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) { - tmp = op_list; - op_list = op_list->next; - switch (tmp->type) { - case reg_pred: - my_predecessors.add(*(tmp->r)); - __TBB_store_with_release(tmp->status, SUCCEEDED); - if (!forwarder_busy) { - forwarder_busy = true; - spawn_forward_task(); - } - break; - case rem_pred: - my_predecessors.remove(*(tmp->r)); - __TBB_store_with_release(tmp->status, SUCCEEDED); - break; - case app_body: - __TBB_ASSERT(my_max_concurrency != 0, NULL); - --my_concurrency; - __TBB_store_with_release(tmp->status, SUCCEEDED); - if (my_concurrencybypass_t = NULL; - __TBB_ASSERT(my_max_concurrency != 0, NULL); - --my_concurrency; - if(my_concurrencybypass_t = create_and_spawn_task(/*spawn=*/false); - - __TBB_store_with_release(tmp->status, SUCCEEDED); - } - break; - case tryput_bypass: internal_try_put_task(tmp); break; - case try_fwd: internal_forward(tmp); break; -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - case add_blt_pred: { - my_predecessors.internal_add_built_predecessor(*(tmp->r)); - __TBB_store_with_release(tmp->status, SUCCEEDED); - } - break; - case del_blt_pred: - my_predecessors.internal_delete_built_predecessor(*(tmp->r)); - __TBB_store_with_release(tmp->status, SUCCEEDED); - break; - case blt_pred_cnt: - tmp->cnt_val = my_predecessors.predecessor_count(); - __TBB_store_with_release(tmp->status, SUCCEEDED); - break; - case blt_pred_cpy: - my_predecessors.copy_predecessors( *(tmp->predv) ); - __TBB_store_with_release(tmp->status, SUCCEEDED); - break; -#endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */ - } - } - } - - //! Put to the node, but return the task instead of enqueueing it - void internal_try_put_task(operation_type *op) { - __TBB_ASSERT(my_max_concurrency != 0, NULL); - if (my_concurrency < my_max_concurrency) { - ++my_concurrency; - task * new_task = create_body_task(*(op->elem)); - op->bypass_t = new_task; - __TBB_store_with_release(op->status, SUCCEEDED); - } else if ( my_queue && my_queue->push(*(op->elem)) ) { - op->bypass_t = SUCCESSFULLY_ENQUEUED; - __TBB_store_with_release(op->status, SUCCEEDED); - } else { - op->bypass_t = NULL; - __TBB_store_with_release(op->status, FAILED); - } - } - - //! Tries to spawn bodies if available and if concurrency allows - void internal_forward(operation_type *op) { - op->bypass_t = NULL; - 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); - } - } - - //! Applies the body to the provided input - // then decides if more work is available - task * apply_body_bypass( input_type &i ) { - task * new_task = static_cast(this)->apply_body_impl_bypass(i); - if ( my_max_concurrency != 0 ) { - operation_type op_data(app_body_bypass); // tries to pop an item or get_item, enqueues another apply_body - my_aggregator.execute(&op_data); - tbb::task *ttask = op_data.bypass_t; - new_task = combine_tasks(new_task, ttask); - } - return new_task; - } - - //! allocates a task to apply a body - inline task * create_body_task( const input_type &input ) { - - 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; - } - - //! This is executed by an enqueued task, the "forwarder" - task *forward_task() { - operation_type op_data(try_fwd); - task *rval = NULL; - do { - op_data.status = WAIT; - my_aggregator.execute(&op_data); - if(op_data.status == SUCCEEDED) { - tbb::task *ttask = op_data.bypass_t; - rval = combine_tasks(rval, ttask); - } - } while (op_data.status == SUCCEEDED); - return rval; - } - - inline task *create_forward_task() { - return (my_graph_ptr->is_active()) ? - new(task::allocate_additional_child_of(*(my_graph_ptr->root_task()))) forward_task_bypass< class_type >(*this) : - NULL; - } - - //! Spawns a task that calls forward() - inline void spawn_forward_task() { - task* tp = create_forward_task(); - if(tp) { - FLOW_SPAWN(*tp); - } - } - }; // function_input_base - - //! Implements methods for a function node that takes a type Input as input and sends - // a type Output to its successors. - template< typename Input, typename Output, typename A> - class function_input : public function_input_base > { - public: - typedef Input input_type; - typedef Output output_type; - typedef function_body function_body_type; - typedef function_input my_class; - typedef function_input_base base_type; - typedef function_input_queue input_queue_type; - - // constructor - template - function_input( graph &g, size_t max_concurrency, Body& body, input_queue_type *q = NULL ) : - base_type(g, max_concurrency, q), - my_body( new internal::function_body_leaf< input_type, output_type, Body>(body) ), - my_init_body( new internal::function_body_leaf< input_type, output_type, Body>(body) ) { - } - - //! Copy constructor - function_input( const function_input& src, input_queue_type *q = NULL ) : - base_type(src, q), - my_body( src.my_init_body->clone() ), - my_init_body(src.my_init_body->clone() ) { - } - - ~function_input() { - delete my_body; - delete my_init_body; - } - - template< typename Body > - Body copy_function_object() { - function_body_type &body_ref = *this->my_body; - return dynamic_cast< internal::function_body_leaf & >(body_ref).get_body(); - } - - task * apply_body_impl_bypass( const input_type &i) { -#if TBB_PREVIEW_FLOW_GRAPH_TRACE - // There is an extra copied needed to capture the - // body execution without the try_put - tbb::internal::fgt_begin_body( my_body ); - output_type v = (*my_body)(i); - tbb::internal::fgt_end_body( my_body ); - task * new_task = successors().try_put_task( v ); -#else - task * new_task = successors().try_put_task( (*my_body)(i) ); -#endif - return new_task; - } - - protected: - - void reset_function_input(reset_flags f) { - base_type::reset_function_input_base(f); - if(f & rf_reset_bodies) { - function_body_type *tmp = my_init_body->clone(); - delete my_body; - my_body = tmp; - } - } - - function_body_type *my_body; - function_body_type *my_init_body; - virtual broadcast_cache &successors() = 0; - - }; // function_input - - - // helper templates to clear the successor edges of the output ports of an multifunction_node - template struct clear_element { - template static void clear_this(P &p) { - (void)tbb::flow::get(p).successors().clear(); - clear_element::clear_this(p); - } - template static bool this_empty(P &p) { - if(tbb::flow::get(p).successors().empty()) - return clear_element::this_empty(p); - return false; - } - }; - - template<> struct clear_element<1> { - template static void clear_this(P &p) { - (void)tbb::flow::get<0>(p).successors().clear(); - } - template static bool this_empty(P &p) { - return tbb::flow::get<0>(p).successors().empty(); - } - }; - -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - // helper templates to extract the output ports of an multifunction_node from graph - template struct extract_element { - template static void extract_this(P &p) { - (void)tbb::flow::get(p).successors().built_successors().sender_extract(tbb::flow::get(p)); - extract_element::extract_this(p); - } - }; - - template<> struct extract_element<1> { - template static void extract_this(P &p) { - (void)tbb::flow::get<0>(p).successors().built_successors().sender_extract(tbb::flow::get<0>(p)); - } - }; -#endif - - //! Implements methods for a function node that takes a type Input as input - // and has a tuple of output ports specified. - template< typename Input, typename OutputPortSet, typename A> - class multifunction_input : public function_input_base > { - public: - static const int N = tbb::flow::tuple_size::value; - typedef Input input_type; - typedef OutputPortSet output_ports_type; - typedef multifunction_body multifunction_body_type; - typedef multifunction_input my_class; - typedef function_input_base base_type; - typedef function_input_queue input_queue_type; - - // constructor - template - multifunction_input( - graph &g, - size_t max_concurrency, - Body& body, - input_queue_type *q = NULL ) : - base_type(g, max_concurrency, q), - my_body( new internal::multifunction_body_leaf(body) ), - my_init_body( new internal::multifunction_body_leaf(body) ) { - } - - //! Copy constructor - multifunction_input( const multifunction_input& src, input_queue_type *q = NULL ) : - base_type(src, q), - my_body( src.my_init_body->clone() ), - my_init_body(src.my_init_body->clone() ) { - } - - ~multifunction_input() { - delete my_body; - delete my_init_body; - } - - template< typename Body > - Body copy_function_object() { - multifunction_body_type &body_ref = *this->my_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 - // the task we were successful. - task * apply_body_impl_bypass( const input_type &i) { - tbb::internal::fgt_begin_body( my_body ); - (*my_body)(i, my_output_ports); - tbb::internal::fgt_end_body( my_body ); - task * new_task = SUCCESSFULLY_ENQUEUED; - return new_task; - } - - output_ports_type &output_ports(){ return my_output_ports; } - - protected: -#if TBB_PREVIEW_FLOW_GRAPH_FEATURES - void extract() { - extract_element::extract_this(my_output_ports); - } -#endif - - 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) { - multifunction_body_type *tmp = my_init_body->clone(); - delete my_body; - my_body = tmp; - } - __TBB_ASSERT(!(f & rf_clear_edges) || clear_element::this_empty(my_output_ports), "multifunction_node reset failed"); - } - - multifunction_body_type *my_body; - multifunction_body_type *my_init_body; - output_ports_type my_output_ports; - - }; // multifunction_input - - // template to refer to an output port of a multifunction_node - template - typename tbb::flow::tuple_element::type &output_port(MOP &op) { - return tbb::flow::get(op.output_ports()); - } - -// helper structs for split_node - template - struct emit_element { - template - static void emit_this(const T &t, P &p) { - (void)tbb::flow::get(p).try_put(tbb::flow::get(t)); - emit_element::emit_this(t,p); - } - }; - - template<> - struct emit_element<1> { - template - static void emit_this(const T &t, P &p) { - (void)tbb::flow::get<0>(p).try_put(tbb::flow::get<0>(t)); - } - }; - - //! Implements methods for an executable node that takes continue_msg as input - template< typename Output > - class continue_input : public continue_receiver { - public: - - //! The input type of this receiver - typedef continue_msg input_type; - - //! The output type of this receiver - typedef Output output_type; - typedef function_body function_body_type; - - template< typename Body > - continue_input( graph &g, Body& body ) - : my_graph_ptr(&g), - my_body( new internal::function_body_leaf< input_type, output_type, Body>(body) ), - my_init_body( new internal::function_body_leaf< input_type, output_type, Body>(body) ) { } - - template< typename Body > - continue_input( graph &g, int number_of_predecessors, Body& body ) - : continue_receiver( number_of_predecessors ), my_graph_ptr(&g), - my_body( new internal::function_body_leaf< input_type, output_type, Body>(body) ), - my_init_body( new internal::function_body_leaf< input_type, output_type, Body>(body) ) - { } - - continue_input( const continue_input& src ) : continue_receiver(src), - my_graph_ptr(src.my_graph_ptr), - my_body( src.my_init_body->clone() ), - my_init_body( src.my_init_body->clone() ) {} - - ~continue_input() { - delete my_body; - delete my_init_body; - } - - template< typename Body > - Body copy_function_object() { - function_body_type &body_ref = *my_body; - return dynamic_cast< internal::function_body_leaf & >(body_ref).get_body(); - } - - 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(); - delete my_body; - my_body = tmp; - } - } - - protected: - - graph* my_graph_ptr; - function_body_type *my_body; - function_body_type *my_init_body; - - virtual broadcast_cache &successors() = 0; - - friend class apply_body_task_bypass< continue_input< Output >, continue_msg >; - - //! Applies the body to the provided input - task *apply_body_bypass( input_type ) { -#if TBB_PREVIEW_FLOW_GRAPH_TRACE - // There is an extra copied needed to capture the - // body execution without the try_put - tbb::internal::fgt_begin_body( my_body ); - output_type v = (*my_body)( continue_msg() ); - tbb::internal::fgt_end_body( my_body ); - return successors().try_put_task( v ); -#else - return successors().try_put_task( (*my_body)( continue_msg() ) ); -#endif - } - - //! Spawns a task that applies the body - 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() ) : - NULL; - } - - }; // continue_input - - //! Implements methods for both executable and function nodes that puts Output to its successors - template< typename Output > - class function_output : public sender { - public: - - template friend struct clear_element; - typedef Output output_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; - typedef typename sender::successor_list_type successor_list_type; -#endif - - function_output() { my_successors.set_owner(this); } - function_output(const function_output & /*other*/) : sender() { - my_successors.set_owner(this); - } - - //! Adds a new successor to this node - bool register_successor( successor_type &r ) __TBB_override { - successors().register_successor( r ); - return true; - } - - //! Removes a successor from this node - 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() __TBB_override { return successors().built_successors(); } - - - void internal_add_built_successor( successor_type &r) __TBB_override { - successors().internal_add_built_successor( r ); - } - - void internal_delete_built_successor( successor_type &r) __TBB_override { - successors().internal_delete_built_successor( r ); - } - - size_t successor_count() __TBB_override { - return successors().successor_count(); - } - - void copy_successors( successor_list_type &v) __TBB_override { - successors().copy_successors(v); - } -#endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */ - - // for multifunction_node. The function_body that implements - // the node will have an input and an output tuple of ports. To put - // an item to a successor, the body should - // - // get(output_ports).try_put(output_value); - // - // 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) { // not a virtual method in this class - return my_successors.try_put_task(i); - } - - broadcast_cache_type &successors() { return my_successors; } - protected: - broadcast_cache_type my_successors; - - }; // function_output - - template< typename Output > - class multifunction_output : public function_output { - public: - typedef Output output_type; - typedef function_output base_type; - using base_type::my_successors; - - multifunction_output() : base_type() {my_successors.set_owner(this);} - multifunction_output( const multifunction_output &/*other*/) : base_type() { my_successors.set_owner(this); } - - bool try_put(const output_type &i) { - task *res = my_successors.try_put_task(i); - if(!res) return false; - if(res != SUCCESSFULLY_ENQUEUED) FLOW_SPAWN(*res); - return true; - } - }; // multifunction_output - -//composite_node -#if TBB_PREVIEW_FLOW_GRAPH_TRACE && __TBB_FLOW_GRAPH_CPP11_FEATURES - template - void add_nodes_impl(CompositeType*, bool) {} - - template< typename CompositeType, typename NodeType1, typename... NodeTypes > - void add_nodes_impl(CompositeType *c_node, bool visible, const NodeType1& n1, const NodeTypes&... n) { - void *addr = const_cast(&n1); - - if(visible) - tbb::internal::itt_relation_add( tbb::internal::ITT_DOMAIN_FLOW, c_node, tbb::internal::FLOW_NODE, tbb::internal::__itt_relation_is_parent_of, addr, tbb::internal::FLOW_NODE ); - else - tbb::internal::itt_relation_add( tbb::internal::ITT_DOMAIN_FLOW, addr, tbb::internal::FLOW_NODE, tbb::internal::__itt_relation_is_child_of, c_node, tbb::internal::FLOW_NODE ); - add_nodes_impl(c_node, visible, n...); - } -#endif - -} // internal - -#endif // __TBB__flow_graph_node_impl_H 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 deleted file mode 100644 index 493f76e8..00000000 --- a/lib/3rdParty/tbb/include/tbb/internal/_flow_graph_streaming_node.h +++ /dev/null @@ -1,745 +0,0 @@ -/* - 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 deleted file mode 100644 index 46755fe0..00000000 --- a/lib/3rdParty/tbb/include/tbb/internal/_flow_graph_tagged_buffer_impl.h +++ /dev/null @@ -1,253 +0,0 @@ -/* - 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. - - - - -*/ - -// a hash table buffer that can expand, and can support as many deletions as -// additions, list-based, with elements of list held in array (for destruction -// management), multiplicative hashing (like ets). No synchronization built-in. -// - -#ifndef __TBB__flow_graph_hash_buffer_impl_H -#define __TBB__flow_graph_hash_buffer_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::internal - -// elements in the table are a simple list; we need pointer to next element to -// traverse the chain -template -struct buffer_element_type { - // the second parameter below is void * because we can't forward-declare the type - // itself, so we just reinterpret_cast below. - typedef typename aligned_pair::type type; -}; - -template - < - typename Key, // type of key within ValueType - typename ValueType, - typename ValueToKey, // abstract method that returns "const Key" or "const Key&" given ValueType - typename HashCompare, // has hash and equal - typename Allocator=tbb::cache_aligned_allocator< typename aligned_pair::type > - > -class hash_buffer : public HashCompare { -public: - static const size_t INITIAL_SIZE = 8; // initial size of the hash pointer table - typedef ValueType value_type; - typedef typename buffer_element_type< value_type >::type element_type; - typedef value_type *pointer_type; - typedef element_type *list_array_type; // array we manage manually - typedef list_array_type *pointer_array_type; - typedef typename Allocator::template rebind::other pointer_array_allocator_type; - typedef typename Allocator::template rebind::other elements_array_allocator; - typedef typename tbb::internal::strip::type Knoref; - -private: - ValueToKey *my_key; - size_t my_size; - size_t nelements; - pointer_array_type pointer_array; // pointer_array[my_size] - list_array_type elements_array; // elements_array[my_size / 2] - element_type* free_list; - - size_t mask() { return my_size - 1; } - - void set_up_free_list( element_type **p_free_list, list_array_type la, size_t sz) { - for(size_t i=0; i < sz - 1; ++i ) { // construct free list - la[i].second = &(la[i+1]); - } - la[sz-1].second = NULL; - *p_free_list = (element_type *)&(la[0]); - } - - // cleanup for exceptions - struct DoCleanup { - pointer_array_type *my_pa; - list_array_type *my_elements; - size_t my_size; - - DoCleanup(pointer_array_type &pa, list_array_type &my_els, size_t sz) : - my_pa(&pa), my_elements(&my_els), my_size(sz) { } - ~DoCleanup() { - if(my_pa) { - size_t dont_care = 0; - internal_free_buffer(*my_pa, *my_elements, my_size, dont_care); - } - } - }; - - // exception-safety requires we do all the potentially-throwing operations first - void grow_array() { - size_t new_size = my_size*2; - size_t new_nelements = nelements; // internal_free_buffer zeroes this - list_array_type new_elements_array = NULL; - pointer_array_type new_pointer_array = NULL; - list_array_type new_free_list = NULL; - { - DoCleanup my_cleanup(new_pointer_array, new_elements_array, new_size); - new_elements_array = elements_array_allocator().allocate(my_size); - new_pointer_array = pointer_array_allocator_type().allocate(new_size); - for(size_t i=0; i < new_size; ++i) new_pointer_array[i] = NULL; - set_up_free_list(&new_free_list, new_elements_array, my_size ); - - for(size_t i=0; i < my_size; ++i) { - for( element_type* op = pointer_array[i]; op; op = (element_type *)(op->second)) { - value_type *ov = reinterpret_cast(&(op->first)); - // could have std::move semantics - internal_insert_with_key(new_pointer_array, new_size, new_free_list, *ov); - } - } - my_cleanup.my_pa = NULL; - my_cleanup.my_elements = NULL; - } - - internal_free_buffer(pointer_array, elements_array, my_size, nelements); - free_list = new_free_list; - pointer_array = new_pointer_array; - elements_array = new_elements_array; - my_size = new_size; - nelements = new_nelements; - } - - // v should have perfect forwarding if std::move implemented. - // we use this method to move elements in grow_array, so can't use class fields - void internal_insert_with_key( element_type **p_pointer_array, size_t p_sz, list_array_type &p_free_list, - const value_type &v) { - size_t l_mask = p_sz-1; - __TBB_ASSERT(my_key, "Error: value-to-key functor not provided"); - size_t h = this->hash((*my_key)(v)) & l_mask; - __TBB_ASSERT(p_free_list, "Error: free list not set up."); - element_type* my_elem = p_free_list; p_free_list = (element_type *)(p_free_list->second); - (void) new(&(my_elem->first)) value_type(v); - my_elem->second = p_pointer_array[h]; - p_pointer_array[h] = my_elem; - } - - void internal_initialize_buffer() { - pointer_array = pointer_array_allocator_type().allocate(my_size); - for(size_t i = 0; i < my_size; ++i) pointer_array[i] = NULL; - elements_array = elements_array_allocator().allocate(my_size / 2); - set_up_free_list(&free_list, elements_array, my_size / 2); - } - - // made static so an enclosed class can use to properly dispose of the internals - static void internal_free_buffer( pointer_array_type &pa, list_array_type &el, size_t &sz, size_t &ne ) { - if(pa) { - for(size_t i = 0; i < sz; ++i ) { - element_type *p_next; - for( element_type *p = pa[i]; p; p = p_next) { - p_next = (element_type *)p->second; - internal::punned_cast(&(p->first))->~value_type(); - } - } - pointer_array_allocator_type().deallocate(pa, sz); - pa = NULL; - } - // Separate test (if allocation of pa throws, el may be allocated. - // but no elements will be constructed.) - if(el) { - elements_array_allocator().deallocate(el, sz / 2); - el = NULL; - } - sz = INITIAL_SIZE; - ne = 0; - } - -public: - hash_buffer() : my_key(NULL), my_size(INITIAL_SIZE), nelements(0) { - internal_initialize_buffer(); - } - - ~hash_buffer() { - internal_free_buffer(pointer_array, elements_array, my_size, nelements); - if(my_key) delete my_key; - } - - void reset() { - internal_free_buffer(pointer_array, elements_array, my_size, nelements); - internal_initialize_buffer(); - } - - // Take ownership of func object allocated with new. - // This method is only used internally, so can't be misused by user. - void set_key_func(ValueToKey *vtk) { my_key = vtk; } - // pointer is used to clone() - ValueToKey* get_key_func() { return my_key; } - - bool insert_with_key(const value_type &v) { - pointer_type p = NULL; - __TBB_ASSERT(my_key, "Error: value-to-key functor not provided"); - if(find_ref_with_key((*my_key)(v), p)) { - p->~value_type(); - (void) new(p) value_type(v); // copy-construct into the space - return false; - } - ++nelements; - if(nelements*2 > my_size) grow_array(); - internal_insert_with_key(pointer_array, my_size, free_list, v); - return true; - } - - // returns true and sets v to array element if found, else returns false. - bool find_ref_with_key(const Knoref& k, pointer_type &v) { - size_t i = this->hash(k) & mask(); - for(element_type* p = pointer_array[i]; p; p = (element_type *)(p->second)) { - pointer_type pv = reinterpret_cast(&(p->first)); - __TBB_ASSERT(my_key, "Error: value-to-key functor not provided"); - if(this->equal((*my_key)(*pv), k)) { - v = pv; - return true; - } - } - return false; - } - - bool find_with_key( const Knoref& k, value_type &v) { - value_type *p; - if(find_ref_with_key(k, p)) { - v = *p; - return true; - } - else - return false; - } - - void delete_with_key(const Knoref& k) { - size_t h = this->hash(k) & mask(); - element_type* prev = NULL; - for(element_type* p = pointer_array[h]; p; prev = p, p = (element_type *)(p->second)) { - value_type *vp = reinterpret_cast(&(p->first)); - __TBB_ASSERT(my_key, "Error: value-to-key functor not provided"); - if(this->equal((*my_key)(*vp), k)) { - vp->~value_type(); - if(prev) prev->second = p->second; - else pointer_array[h] = (element_type *)(p->second); - p->second = free_list; - free_list = p; - --nelements; - return; - } - } - __TBB_ASSERT(false, "key not found for delete"); - } -}; -#endif // __TBB__flow_graph_hash_buffer_impl_H 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 deleted file mode 100644 index b798888d..00000000 --- a/lib/3rdParty/tbb/include/tbb/internal/_flow_graph_trace_impl.h +++ /dev/null @@ -1,238 +0,0 @@ -/* - 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 _FGT_GRAPH_TRACE_IMPL_H -#define _FGT_GRAPH_TRACE_IMPL_H - -#include "../tbb_profiling.h" - -namespace tbb { - namespace internal { - -#if TBB_PREVIEW_FLOW_GRAPH_TRACE - -static inline void fgt_internal_create_input_port( void *node, void *p, string_index name_index ) { - itt_make_task_group( ITT_DOMAIN_FLOW, p, FLOW_INPUT_PORT, node, FLOW_NODE, name_index ); -} - -static inline void fgt_internal_create_output_port( void *node, void *p, string_index name_index ) { - itt_make_task_group( ITT_DOMAIN_FLOW, p, FLOW_OUTPUT_PORT, node, FLOW_NODE, name_index ); -} - -template -void register_input_port(void *node, tbb::flow::receiver* port, string_index name_index) { - //TODO: Make fgt_internal_create_input_port a function template? - fgt_internal_create_input_port( node, port, name_index); -} - -template < typename PortsTuple, int N > -struct fgt_internal_input_helper { - static void register_port( void *node, PortsTuple &ports ) { - register_input_port( node, &(tbb::flow::get(ports)), static_cast(FLOW_INPUT_PORT_0 + N - 1) ); - fgt_internal_input_helper::register_port( node, ports ); - } -}; - -template < typename PortsTuple > -struct fgt_internal_input_helper { - static void register_port( void *node, PortsTuple &ports ) { - register_input_port( node, &(tbb::flow::get<0>(ports)), FLOW_INPUT_PORT_0 ); - } -}; - -template -void register_output_port(void *node, tbb::flow::sender* port, string_index name_index) { - //TODO: Make fgt_internal_create_output_port a function template? - fgt_internal_create_output_port( node, static_cast(port), name_index); -} - -template < typename PortsTuple, int N > -struct fgt_internal_output_helper { - static void register_port( void *node, PortsTuple &ports ) { - register_output_port( node, &(tbb::flow::get(ports)), static_cast(FLOW_OUTPUT_PORT_0 + N - 1) ); - fgt_internal_output_helper::register_port( node, ports ); - } -}; - -template < typename PortsTuple > -struct fgt_internal_output_helper { - static void register_port( void *node, PortsTuple &ports ) { - register_output_port( node, &(tbb::flow::get<0>(ports)), FLOW_OUTPUT_PORT_0 ); - } -}; - -template< typename NodeType > -void fgt_multioutput_node_desc( const NodeType *node, const char *desc ) { - void *addr = (void *)( static_cast< tbb::flow::receiver< typename NodeType::input_type > * >(const_cast< NodeType *>(node)) ); - itt_metadata_str_add( ITT_DOMAIN_FLOW, addr, FLOW_NODE, FLOW_OBJECT_NAME, desc ); -} - -template< typename NodeType > -void fgt_multiinput_multioutput_node_desc( const NodeType *node, const char *desc ) { - void *addr = const_cast(node); - itt_metadata_str_add( ITT_DOMAIN_FLOW, addr, FLOW_NODE, FLOW_OBJECT_NAME, desc ); -} - -template< typename NodeType > -static inline void fgt_node_desc( const NodeType *node, const char *desc ) { - void *addr = (void *)( static_cast< tbb::flow::sender< typename NodeType::output_type > * >(const_cast< NodeType *>(node)) ); - itt_metadata_str_add( ITT_DOMAIN_FLOW, addr, FLOW_NODE, FLOW_OBJECT_NAME, desc ); -} - -static inline void fgt_graph_desc( void *g, const char *desc ) { - itt_metadata_str_add( ITT_DOMAIN_FLOW, g, FLOW_GRAPH, FLOW_OBJECT_NAME, desc ); -} - -static inline void fgt_body( void *node, void *body ) { - itt_relation_add( ITT_DOMAIN_FLOW, body, FLOW_BODY, __itt_relation_is_child_of, node, FLOW_NODE ); -} - -template< int N, typename PortsTuple > -static inline void fgt_multioutput_node( string_index t, void *g, void *input_port, PortsTuple &ports ) { - itt_make_task_group( ITT_DOMAIN_FLOW, input_port, FLOW_NODE, g, FLOW_GRAPH, t ); - fgt_internal_create_input_port( input_port, input_port, FLOW_INPUT_PORT_0 ); - fgt_internal_output_helper::register_port( input_port, ports ); -} - -template< int N, typename PortsTuple > -static inline void fgt_multioutput_node_with_body( string_index t, void *g, void *input_port, PortsTuple &ports, void *body ) { - itt_make_task_group( ITT_DOMAIN_FLOW, input_port, FLOW_NODE, g, FLOW_GRAPH, t ); - fgt_internal_create_input_port( input_port, input_port, FLOW_INPUT_PORT_0 ); - fgt_internal_output_helper::register_port( input_port, ports ); - fgt_body( input_port, body ); -} - -template< int N, typename PortsTuple > -static inline void fgt_multiinput_node( string_index t, void *g, PortsTuple &ports, void *output_port) { - itt_make_task_group( ITT_DOMAIN_FLOW, output_port, FLOW_NODE, g, FLOW_GRAPH, t ); - fgt_internal_create_output_port( output_port, output_port, FLOW_OUTPUT_PORT_0 ); - fgt_internal_input_helper::register_port( output_port, ports ); -} - -static inline void fgt_node( string_index t, void *g, void *output_port ) { - itt_make_task_group( ITT_DOMAIN_FLOW, output_port, FLOW_NODE, g, FLOW_GRAPH, t ); - fgt_internal_create_output_port( output_port, output_port, FLOW_OUTPUT_PORT_0 ); -} - -static inline void fgt_node_with_body( string_index t, void *g, void *output_port, void *body ) { - itt_make_task_group( ITT_DOMAIN_FLOW, output_port, FLOW_NODE, g, FLOW_GRAPH, t ); - fgt_internal_create_output_port( output_port, output_port, FLOW_OUTPUT_PORT_0 ); - fgt_body( output_port, body ); -} - - -static inline void fgt_node( string_index t, void *g, void *input_port, void *output_port ) { - fgt_node( t, g, output_port ); - fgt_internal_create_input_port( output_port, input_port, FLOW_INPUT_PORT_0 ); -} - -static inline void fgt_node_with_body( string_index t, void *g, void *input_port, void *output_port, void *body ) { - fgt_node_with_body( t, g, output_port, body ); - fgt_internal_create_input_port( output_port, input_port, FLOW_INPUT_PORT_0 ); -} - - -static inline void fgt_node( string_index t, void *g, void *input_port, void *decrement_port, void *output_port ) { - fgt_node( t, g, input_port, output_port ); - fgt_internal_create_input_port( output_port, decrement_port, FLOW_INPUT_PORT_1 ); -} - -static inline void fgt_make_edge( void *output_port, void *input_port ) { - itt_relation_add( ITT_DOMAIN_FLOW, output_port, FLOW_OUTPUT_PORT, __itt_relation_is_predecessor_to, input_port, FLOW_INPUT_PORT); -} - -static inline void fgt_remove_edge( void *output_port, void *input_port ) { - itt_relation_add( ITT_DOMAIN_FLOW, output_port, FLOW_OUTPUT_PORT, __itt_relation_is_sibling_of, input_port, FLOW_INPUT_PORT); -} - -static inline void fgt_graph( void *g ) { - itt_make_task_group( ITT_DOMAIN_FLOW, g, FLOW_GRAPH, NULL, FLOW_NULL, FLOW_GRAPH ); -} - -static inline void fgt_begin_body( void *body ) { - itt_task_begin( ITT_DOMAIN_FLOW, body, FLOW_BODY, NULL, FLOW_NULL, FLOW_BODY ); -} - -static inline void fgt_end_body( void * ) { - itt_task_end( ITT_DOMAIN_FLOW ); -} - -static inline void fgt_async_try_put_begin( void *node, void *port ) { - itt_task_begin( ITT_DOMAIN_FLOW, port, FLOW_OUTPUT_PORT, node, FLOW_NODE, FLOW_OUTPUT_PORT ); -} - -static inline void fgt_async_try_put_end( void *, void * ) { - itt_task_end( ITT_DOMAIN_FLOW ); -} - -static inline void fgt_async_reserve( void *node, void *graph ) { - itt_region_begin( ITT_DOMAIN_FLOW, node, FLOW_NODE, graph, FLOW_GRAPH, FLOW_NULL ); -} - -static inline void fgt_async_commit( void *node, void *graph ) { - itt_region_end( ITT_DOMAIN_FLOW, node, FLOW_NODE ); -} - -#else // TBB_PREVIEW_FLOW_GRAPH_TRACE - -static inline void fgt_graph( void * /*g*/ ) { } - -template< typename NodeType > -static inline void fgt_multioutput_node_desc( const NodeType * /*node*/, const char * /*desc*/ ) { } - -template< typename NodeType > -static inline void fgt_node_desc( const NodeType * /*node*/, const char * /*desc*/ ) { } - -static inline void fgt_graph_desc( void * /*g*/, const char * /*desc*/ ) { } - -static inline void fgt_body( void * /*node*/, void * /*body*/ ) { } - -template< int N, typename PortsTuple > -static inline void fgt_multioutput_node( string_index /*t*/, void * /*g*/, void * /*input_port*/, PortsTuple & /*ports*/ ) { } - -template< int N, typename PortsTuple > -static inline void fgt_multioutput_node_with_body( string_index /*t*/, void * /*g*/, void * /*input_port*/, PortsTuple & /*ports*/, void * /*body*/ ) { } - -template< int N, typename PortsTuple > -static inline void fgt_multiinput_node( string_index /*t*/, void * /*g*/, PortsTuple & /*ports*/, void * /*output_port*/ ) { } - -static inline void fgt_node( string_index /*t*/, void * /*g*/, void * /*output_port*/ ) { } -static inline void fgt_node( string_index /*t*/, void * /*g*/, void * /*input_port*/, void * /*output_port*/ ) { } -static inline void fgt_node( string_index /*t*/, void * /*g*/, void * /*input_port*/, void * /*decrement_port*/, void * /*output_port*/ ) { } - -static inline void fgt_node_with_body( string_index /*t*/, void * /*g*/, void * /*output_port*/, void * /*body*/ ) { } -static inline void fgt_node_with_body( string_index /*t*/, void * /*g*/, void * /*input_port*/, void * /*output_port*/, void * /*body*/ ) { } - -static inline void fgt_make_edge( void * /*output_port*/, void * /*input_port*/ ) { } -static inline void fgt_remove_edge( void * /*output_port*/, void * /*input_port*/ ) { } - -static inline void fgt_begin_body( void * /*body*/ ) { } -static inline void fgt_end_body( void * /*body*/) { } -static inline void fgt_async_try_put_begin( void * /*node*/, void * /*port*/ ) { } -static inline void fgt_async_try_put_end( void * /*node*/ , void * /*port*/ ) { } -static inline void fgt_async_reserve( void * /*node*/, void * /*graph*/ ) { } -static inline void fgt_async_commit( void * /*node*/, void * /*graph*/ ) { } - -#endif // TBB_PREVIEW_FLOW_GRAPH_TRACE - - } // namespace internal -} // namespace tbb - -#endif 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 deleted file mode 100644 index 73b5f547..00000000 --- a/lib/3rdParty/tbb/include/tbb/internal/_flow_graph_types_impl.h +++ /dev/null @@ -1,713 +0,0 @@ -/* - 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_types_impl_H -#define __TBB__flow_graph_types_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 - -namespace internal { - - // the change to key_matching (adding a K and KHash template parameter, making it a class) - // means we have to pass this data to the key_matching_port. All the ports have only one - // template parameter, so we have to wrap the following types in a trait: - // - // . K == key_type - // . KHash == hash and compare for Key - // . TtoK == function_body that given an object of T, returns its K - // . T == type accepted by port, and stored in the hash table - // - // The port will have an additional parameter on node construction, which is a function_body - // that accepts a const T& and returns a K which is the field in T which is its K. - template - struct KeyTrait { - typedef Kp K; - typedef Tp T; - typedef internal::type_to_key_function_body TtoK; - typedef KHashp KHash; - }; - -// wrap each element of a tuple in a template, and make a tuple of the result. - template class PT, typename TypeTuple> - struct wrap_tuple_elements; - - // A wrapper that generates the traits needed for each port of a key-matching join, - // and the type of the tuple of input ports. - template class PT, typename KeyTraits, typename TypeTuple> - struct wrap_key_tuple_elements; - - template class PT, typename TypeTuple> - struct wrap_tuple_elements<1, PT, TypeTuple> { - typedef typename tbb::flow::tuple< - PT::type> > - type; - }; - - template class PT, typename KeyTraits, typename TypeTuple> - struct wrap_key_tuple_elements<1, PT, KeyTraits, TypeTuple > { - typedef typename KeyTraits::key_type K; - typedef typename KeyTraits::hash_compare_type KHash; - typedef KeyTrait::type> KeyTrait0; - typedef typename tbb::flow::tuple< PT > type; - }; - - template class PT, typename TypeTuple> - struct wrap_tuple_elements<2, PT, TypeTuple> { - typedef typename tbb::flow::tuple< - PT::type>, - PT::type> > - type; - }; - - template class PT, typename KeyTraits, typename TypeTuple> - struct wrap_key_tuple_elements<2, PT, KeyTraits, TypeTuple> { - typedef typename KeyTraits::key_type K; - typedef typename KeyTraits::hash_compare_type KHash; - typedef KeyTrait::type> KeyTrait0; - typedef KeyTrait::type> KeyTrait1; - typedef typename tbb::flow::tuple< PT, PT > type; - }; - - template class PT, typename TypeTuple> - struct wrap_tuple_elements<3, PT, TypeTuple> { - typedef typename tbb::flow::tuple< - PT::type>, - PT::type>, - PT::type> > - type; - }; - - template class PT, typename KeyTraits, typename TypeTuple> - struct wrap_key_tuple_elements<3, PT, KeyTraits, TypeTuple> { - typedef typename KeyTraits::key_type K; - typedef typename KeyTraits::hash_compare_type KHash; - typedef KeyTrait::type> KeyTrait0; - typedef KeyTrait::type> KeyTrait1; - typedef KeyTrait::type> KeyTrait2; - typedef typename tbb::flow::tuple< PT, PT, PT > type; - }; - - template class PT, typename TypeTuple> - struct wrap_tuple_elements<4, PT, TypeTuple> { - typedef typename tbb::flow::tuple< - PT::type>, - PT::type>, - PT::type>, - PT::type> > - type; - }; - - template class PT, typename KeyTraits, typename TypeTuple> - struct wrap_key_tuple_elements<4, PT, KeyTraits, TypeTuple> { - typedef typename KeyTraits::key_type K; - typedef typename KeyTraits::hash_compare_type KHash; - typedef KeyTrait::type> KeyTrait0; - typedef KeyTrait::type> KeyTrait1; - typedef KeyTrait::type> KeyTrait2; - typedef KeyTrait::type> KeyTrait3; - typedef typename tbb::flow::tuple< PT, PT, PT, - PT > type; - }; - - template class PT, typename TypeTuple> - struct wrap_tuple_elements<5, PT, TypeTuple> { - typedef typename tbb::flow::tuple< - PT::type>, - PT::type>, - PT::type>, - PT::type>, - PT::type> > - type; - }; - - template class PT, typename KeyTraits, typename TypeTuple> - struct wrap_key_tuple_elements<5, PT, KeyTraits, TypeTuple> { - typedef typename KeyTraits::key_type K; - typedef typename KeyTraits::hash_compare_type KHash; - typedef KeyTrait::type> KeyTrait0; - typedef KeyTrait::type> KeyTrait1; - typedef KeyTrait::type> KeyTrait2; - typedef KeyTrait::type> KeyTrait3; - typedef KeyTrait::type> KeyTrait4; - typedef typename tbb::flow::tuple< PT, PT, PT, - PT, PT > type; - }; - -#if __TBB_VARIADIC_MAX >= 6 - template class PT, typename TypeTuple> - struct wrap_tuple_elements<6, PT, TypeTuple> { - typedef typename tbb::flow::tuple< - PT::type>, - PT::type>, - PT::type>, - PT::type>, - PT::type>, - PT::type> > - type; - }; - - template class PT, typename KeyTraits, typename TypeTuple> - struct wrap_key_tuple_elements<6, PT, KeyTraits, TypeTuple> { - typedef typename KeyTraits::key_type K; - typedef typename KeyTraits::hash_compare_type KHash; - typedef KeyTrait::type> KeyTrait0; - typedef KeyTrait::type> KeyTrait1; - typedef KeyTrait::type> KeyTrait2; - typedef KeyTrait::type> KeyTrait3; - typedef KeyTrait::type> KeyTrait4; - typedef KeyTrait::type> KeyTrait5; - typedef typename tbb::flow::tuple< PT, PT, PT, PT, - PT, PT > type; - }; -#endif - -#if __TBB_VARIADIC_MAX >= 7 - template class PT, typename TypeTuple> - struct wrap_tuple_elements<7, PT, TypeTuple> { - typedef typename tbb::flow::tuple< - PT::type>, - PT::type>, - PT::type>, - PT::type>, - PT::type>, - PT::type>, - PT::type> > - type; - }; - - template class PT, typename KeyTraits, typename TypeTuple> - struct wrap_key_tuple_elements<7, PT, KeyTraits, TypeTuple> { - typedef typename KeyTraits::key_type K; - typedef typename KeyTraits::hash_compare_type KHash; - typedef KeyTrait::type> KeyTrait0; - typedef KeyTrait::type> KeyTrait1; - typedef KeyTrait::type> KeyTrait2; - typedef KeyTrait::type> KeyTrait3; - typedef KeyTrait::type> KeyTrait4; - typedef KeyTrait::type> KeyTrait5; - typedef KeyTrait::type> KeyTrait6; - typedef typename tbb::flow::tuple< PT, PT, PT, PT, - PT, PT, PT > type; - }; -#endif - -#if __TBB_VARIADIC_MAX >= 8 - template class PT, typename TypeTuple> - struct wrap_tuple_elements<8, PT, TypeTuple> { - typedef typename tbb::flow::tuple< - PT::type>, - PT::type>, - PT::type>, - PT::type>, - PT::type>, - PT::type>, - PT::type>, - PT::type> > - type; - }; - - template class PT, typename KeyTraits, typename TypeTuple> - struct wrap_key_tuple_elements<8, PT, KeyTraits, TypeTuple> { - typedef typename KeyTraits::key_type K; - typedef typename KeyTraits::hash_compare_type KHash; - typedef KeyTrait::type> KeyTrait0; - typedef KeyTrait::type> KeyTrait1; - typedef KeyTrait::type> KeyTrait2; - typedef KeyTrait::type> KeyTrait3; - typedef KeyTrait::type> KeyTrait4; - typedef KeyTrait::type> KeyTrait5; - typedef KeyTrait::type> KeyTrait6; - typedef KeyTrait::type> KeyTrait7; - typedef typename tbb::flow::tuple< PT, PT, PT, PT, - PT, PT, PT, PT > type; - }; -#endif - -#if __TBB_VARIADIC_MAX >= 9 - template class PT, typename TypeTuple> - struct wrap_tuple_elements<9, PT, TypeTuple> { - typedef typename tbb::flow::tuple< - PT::type>, - PT::type>, - PT::type>, - PT::type>, - PT::type>, - PT::type>, - PT::type>, - PT::type>, - PT::type> > - type; - }; - - template class PT, typename KeyTraits, typename TypeTuple> - struct wrap_key_tuple_elements<9, PT, KeyTraits, TypeTuple> { - typedef typename KeyTraits::key_type K; - typedef typename KeyTraits::hash_compare_type KHash; - typedef KeyTrait::type> KeyTrait0; - typedef KeyTrait::type> KeyTrait1; - typedef KeyTrait::type> KeyTrait2; - typedef KeyTrait::type> KeyTrait3; - typedef KeyTrait::type> KeyTrait4; - typedef KeyTrait::type> KeyTrait5; - typedef KeyTrait::type> KeyTrait6; - typedef KeyTrait::type> KeyTrait7; - typedef KeyTrait::type> KeyTrait8; - typedef typename tbb::flow::tuple< PT, PT, PT, PT, - PT, PT, PT, PT, PT > type; - }; -#endif - -#if __TBB_VARIADIC_MAX >= 10 - template class PT, typename TypeTuple> - struct wrap_tuple_elements<10, PT, TypeTuple> { - typedef typename tbb::flow::tuple< - PT::type>, - PT::type>, - PT::type>, - PT::type>, - PT::type>, - PT::type>, - PT::type>, - PT::type>, - PT::type>, - PT::type> > - type; - }; - - template class PT, typename KeyTraits, typename TypeTuple> - struct wrap_key_tuple_elements<10, PT, KeyTraits, TypeTuple> { - typedef typename KeyTraits::key_type K; - typedef typename KeyTraits::hash_compare_type KHash; - typedef KeyTrait::type> KeyTrait0; - typedef KeyTrait::type> KeyTrait1; - typedef KeyTrait::type> KeyTrait2; - typedef KeyTrait::type> KeyTrait3; - typedef KeyTrait::type> KeyTrait4; - typedef KeyTrait::type> KeyTrait5; - typedef KeyTrait::type> KeyTrait6; - typedef KeyTrait::type> KeyTrait7; - typedef KeyTrait::type> KeyTrait8; - typedef KeyTrait::type> KeyTrait9; - typedef typename tbb::flow::tuple< PT, PT, PT, PT, - PT, PT, PT, PT, PT, - PT > type; - }; -#endif - -#if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT - template< int... S > class sequence {}; - - template< int N, int... S > - struct make_sequence : make_sequence < N - 1, N - 1, S... > {}; - - template< int... S > - struct make_sequence < 0, S... > { - typedef sequence type; - }; -#endif /* __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT */ - -#if __TBB_INITIALIZER_LISTS_PRESENT - // Until C++14 std::initializer_list does not guarantee life time of contained objects. - template - class initializer_list_wrapper { - public: - typedef T value_type; - typedef const T& reference; - typedef const T& const_reference; - typedef size_t size_type; - - typedef T* iterator; - typedef const T* const_iterator; - - initializer_list_wrapper( std::initializer_list il ) __TBB_NOEXCEPT( true ) : my_begin( static_cast(malloc( il.size()*sizeof( T ) )) ) { - iterator dst = my_begin; - for ( typename std::initializer_list::const_iterator src = il.begin(); src != il.end(); ++src ) - new (dst++) T( *src ); - my_end = dst; - } - - initializer_list_wrapper( const initializer_list_wrapper& ilw ) __TBB_NOEXCEPT( true ) : my_begin( static_cast(malloc( ilw.size()*sizeof( T ) )) ) { - iterator dst = my_begin; - for ( typename std::initializer_list::const_iterator src = ilw.begin(); src != ilw.end(); ++src ) - new (dst++) T( *src ); - my_end = dst; - } - -#if __TBB_CPP11_RVALUE_REF_PRESENT - initializer_list_wrapper( initializer_list_wrapper&& ilw ) __TBB_NOEXCEPT( true ) : my_begin( ilw.my_begin ), my_end( ilw.my_end ) { - ilw.my_begin = ilw.my_end = NULL; - } -#endif /* __TBB_CPP11_RVALUE_REF_PRESENT */ - - ~initializer_list_wrapper() { - if ( my_begin ) - free( my_begin ); - } - - const_iterator begin() const __TBB_NOEXCEPT(true) { return my_begin; } - const_iterator end() const __TBB_NOEXCEPT(true) { return my_end; } - size_t size() const __TBB_NOEXCEPT(true) { return (size_t)(my_end - my_begin); } - - private: - iterator my_begin; - iterator my_end; - }; -#endif /* __TBB_INITIALIZER_LISTS_PRESENT */ - -//! type mimicking std::pair but with trailing fill to ensure each element of an array -//* will have the correct alignment - template - struct type_plus_align { - char first[sizeof(T1)]; - T2 second; - char fill1[REM]; - }; - - template - struct type_plus_align { - char first[sizeof(T1)]; - T2 second; - }; - - template struct alignment_of { - typedef struct { char t; U padded; } test_alignment; - static const size_t value = sizeof(test_alignment) - sizeof(U); - }; - - // T1, T2 are actual types stored. The space defined for T1 in the type returned - // is a char array of the correct size. Type T2 should be trivially-constructible, - // T1 must be explicitly managed. - template - struct aligned_pair { - static const size_t t1_align = alignment_of::value; - static const size_t t2_align = alignment_of::value; - typedef type_plus_align just_pair; - static const size_t max_align = t1_align < t2_align ? t2_align : t1_align; - static const size_t extra_bytes = sizeof(just_pair) % max_align; - static const size_t remainder = extra_bytes ? max_align - extra_bytes : 0; - public: - typedef type_plus_align type; - }; // aligned_pair - -// support for variant type -// type we use when we're not storing a value -struct default_constructed { }; - -// type which contains another type, tests for what type is contained, and references to it. -// internal::Wrapper -// void CopyTo( void *newSpace) : builds a Wrapper copy of itself in newSpace - -// struct to allow us to copy and test the type of objects -struct WrapperBase { - virtual ~WrapperBase() {} - virtual void CopyTo(void* /*newSpace*/) const { } -}; - -// Wrapper contains a T, with the ability to test what T is. The Wrapper can be -// constructed from a T, can be copy-constructed from another Wrapper, and can be -// examined via value(), but not modified. -template -struct Wrapper: public WrapperBase { - typedef T value_type; - typedef T* pointer_type; -private: - T value_space; -public: - const value_type &value() const { return value_space; } - -private: - Wrapper(); - - // on exception will ensure the Wrapper will contain only a trivially-constructed object - struct _unwind_space { - pointer_type space; - _unwind_space(pointer_type p) : space(p) {} - ~_unwind_space() { - if(space) (void) new (space) Wrapper(default_constructed()); - } - }; -public: - explicit Wrapper( const T& other ) : value_space(other) { } - explicit Wrapper(const Wrapper& other) : value_space(other.value_space) { } - - void CopyTo(void* newSpace) const __TBB_override { - _unwind_space guard((pointer_type)newSpace); - (void) new(newSpace) Wrapper(value_space); - guard.space = NULL; - } - ~Wrapper() { } -}; - -// specialization for array objects -template -struct Wrapper : public WrapperBase { - typedef T value_type; - typedef T* pointer_type; - // space must be untyped. - typedef T ArrayType[N]; -private: - // The space is not of type T[N] because when copy-constructing, it would be - // default-initialized and then copied to in some fashion, resulting in two - // constructions and one destruction per element. If the type is char[ ], we - // placement new into each element, resulting in one construction per element. - static const size_t space_size = sizeof(ArrayType) / sizeof(char); - char value_space[space_size]; - - - // on exception will ensure the already-built objects will be destructed - // (the value_space is a char array, so it is already trivially-destructible.) - struct _unwind_class { - pointer_type space; - int already_built; - _unwind_class(pointer_type p) : space(p), already_built(0) {} - ~_unwind_class() { - if(space) { - for(size_t i = already_built; i > 0 ; --i ) space[i-1].~value_type(); - (void) new(space) Wrapper(default_constructed()); - } - } - }; -public: - const ArrayType &value() const { - char *vp = const_cast(value_space); - return reinterpret_cast(*vp); - } - -private: - Wrapper(); -public: - // have to explicitly construct because other decays to a const value_type* - explicit Wrapper(const ArrayType& other) { - _unwind_class guard((pointer_type)value_space); - pointer_type vp = reinterpret_cast(&value_space); - for(size_t i = 0; i < N; ++i ) { - (void) new(vp++) value_type(other[i]); - ++(guard.already_built); - } - guard.space = NULL; - } - explicit Wrapper(const Wrapper& other) : WrapperBase() { - // we have to do the heavy lifting to copy contents - _unwind_class guard((pointer_type)value_space); - pointer_type dp = reinterpret_cast(value_space); - pointer_type sp = reinterpret_cast(const_cast(other.value_space)); - for(size_t i = 0; i < N; ++i, ++dp, ++sp) { - (void) new(dp) value_type(*sp); - ++(guard.already_built); - } - guard.space = NULL; - } - - void CopyTo(void* newSpace) const __TBB_override { - (void) new(newSpace) Wrapper(*this); // exceptions handled in copy constructor - } - - ~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(); - } -}; - -// given a tuple, return the type of the element that has the maximum alignment requirement. -// Given a tuple and that type, return the number of elements of the object with the max -// alignment requirement that is at least as big as the largest object in the tuple. - -template struct pick_one; -template struct pick_one { typedef T1 type; }; -template struct pick_one { typedef T2 type; }; - -template< template class Selector, typename T1, typename T2 > -struct pick_max { - typedef typename pick_one< (Selector::value > Selector::value), T1, T2 >::type type; -}; - -template struct size_of { static const int value = sizeof(T); }; - -template< size_t N, class Tuple, template class Selector > struct pick_tuple_max { - typedef typename pick_tuple_max::type LeftMaxType; - typedef typename tbb::flow::tuple_element::type ThisType; - typedef typename pick_max::type type; -}; - -template< class Tuple, template class Selector > struct pick_tuple_max<0, Tuple, Selector> { - typedef typename tbb::flow::tuple_element<0, Tuple>::type type; -}; - -// is the specified type included in a tuple? -template -struct is_element_of { - typedef typename tbb::flow::tuple_element::type T_i; - static const bool value = tbb::internal::is_same_type::value || is_element_of::value; -}; - -template -struct is_element_of { - typedef typename tbb::flow::tuple_element<0, Tuple>::type T_i; - static const bool value = tbb::internal::is_same_type::value; -}; - -// allow the construction of types that are listed tuple. If a disallowed type -// construction is written, a method involving this type is created. The -// type has no definition, so a syntax error is generated. -template struct ERROR_Type_Not_allowed_In_Tagged_Msg_Not_Member_Of_Tuple; - -template struct do_if; -template -struct do_if { - static void construct(void *mySpace, const T& x) { - (void) new(mySpace) Wrapper(x); - } -}; -template -struct do_if { - static void construct(void * /*mySpace*/, const T& x) { - // This method is instantiated when the type T does not match any of the - // element types in the Tuple in variant. - ERROR_Type_Not_allowed_In_Tagged_Msg_Not_Member_Of_Tuple::bad_type(x); - } -}; - -// Tuple tells us the allowed types that variant can hold. It determines the alignment of the space in -// Wrapper, and how big Wrapper is. -// -// the object can only be tested for type, and a read-only reference can be fetched by cast_to(). - -using tbb::internal::punned_cast; -struct tagged_null_type {}; -template -class tagged_msg { - typedef tbb::flow::tuple= 6 - , T5 - #endif - #if __TBB_VARIADIC_MAX >= 7 - , T6 - #endif - #if __TBB_VARIADIC_MAX >= 8 - , T7 - #endif - #if __TBB_VARIADIC_MAX >= 9 - , T8 - #endif - #if __TBB_VARIADIC_MAX >= 10 - , T9 - #endif - > Tuple; - -private: - class variant { - static const size_t N = tbb::flow::tuple_size::value; - typedef typename pick_tuple_max::type AlignType; - typedef typename pick_tuple_max::type MaxSizeType; - static const size_t MaxNBytes = (sizeof(Wrapper)+sizeof(AlignType)-1); - static const size_t MaxNElements = MaxNBytes/sizeof(AlignType); - typedef typename tbb::aligned_space SpaceType; - SpaceType my_space; - static const size_t MaxSize = sizeof(SpaceType); - - public: - variant() { (void) new(&my_space) Wrapper(default_constructed()); } - - template - variant( const T& x ) { - do_if::value>::construct(&my_space,x); - } - - variant(const variant& other) { - const WrapperBase * h = punned_cast(&(other.my_space)); - h->CopyTo(&my_space); - } - - // assignment must destroy and re-create the Wrapper type, as there is no way - // to create a Wrapper-to-Wrapper assign even if we find they agree in type. - void operator=( const variant& rhs ) { - if(&rhs != this) { - WrapperBase *h = punned_cast(&my_space); - h->~WrapperBase(); - const WrapperBase *ch = punned_cast(&(rhs.my_space)); - ch->CopyTo(&my_space); - } - } - - template - const U& variant_cast_to() const { - const Wrapper *h = dynamic_cast*>(punned_cast(&my_space)); - if(!h) { - tbb::internal::throw_exception(tbb::internal::eid_bad_tagged_msg_cast); - } - return h->value(); - } - template - bool variant_is_a() const { return dynamic_cast*>(punned_cast(&my_space)) != NULL; } - - bool variant_is_default_constructed() const {return variant_is_a();} - - ~variant() { - WrapperBase *h = punned_cast(&my_space); - h->~WrapperBase(); - } - }; //class variant - - TagType my_tag; - variant my_msg; - -public: - tagged_msg(): my_tag(TagType(~0)), my_msg(){} - - template - tagged_msg(T const &index, R const &value) : my_tag(index), my_msg(value) {} - - #if __TBB_CONST_REF_TO_ARRAY_TEMPLATE_PARAM_BROKEN - template - tagged_msg(T const &index, R (&value)[N]) : my_tag(index), my_msg(value) {} - #endif - - void set_tag(TagType const &index) {my_tag = index;} - TagType tag() const {return my_tag;} - - template - const V& cast_to() const {return my_msg.template variant_cast_to();} - - template - bool is_a() const {return my_msg.template variant_is_a();} - - bool is_default_constructed() const {return my_msg.variant_is_default_constructed();} -}; //class tagged_msg - -// template to simplify cast and test for tagged_msg in template contexts -template -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 deleted file mode 100644 index 6c1d9b59..00000000 --- a/lib/3rdParty/tbb/include/tbb/internal/_mutex_padding.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - 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_mutex_padding_H -#define __TBB_mutex_padding_H - -// wrapper for padding mutexes to be alone on a cache line, without requiring they be allocated -// from a pool. Because we allow them to be defined anywhere they must be two cache lines in size. - - -namespace tbb { -namespace interface7 { -namespace internal { - -static const size_t cache_line_size = 64; - -// Pad a mutex to occupy a number of full cache lines sufficient to avoid false sharing -// with other data; space overhead is up to 2*cache_line_size-1. -template class padded_mutex; - -template -class padded_mutex : tbb::internal::mutex_copy_deprecated_and_disabled { - typedef long pad_type; - pad_type my_pad[((sizeof(Mutex)+cache_line_size-1)/cache_line_size+1)*cache_line_size/sizeof(pad_type)]; - - Mutex *impl() { return (Mutex *)((uintptr_t(this)|(cache_line_size-1))+1);} - -public: - static const bool is_rw_mutex = Mutex::is_rw_mutex; - static const bool is_recursive_mutex = Mutex::is_recursive_mutex; - static const bool is_fair_mutex = Mutex::is_fair_mutex; - - padded_mutex() { new(impl()) Mutex(); } - ~padded_mutex() { impl()->~Mutex(); } - - //! Represents acquisition of a mutex. - class scoped_lock : tbb::internal::no_copy { - typename Mutex::scoped_lock my_scoped_lock; - public: - scoped_lock() : my_scoped_lock() {} - scoped_lock( padded_mutex& m ) : my_scoped_lock(*m.impl()) { } - ~scoped_lock() { } - - void acquire( padded_mutex& m ) { my_scoped_lock.acquire(*m.impl()); } - bool try_acquire( padded_mutex& m ) { return my_scoped_lock.try_acquire(*m.impl()); } - void release() { my_scoped_lock.release(); } - }; -}; - -template -class padded_mutex : tbb::internal::mutex_copy_deprecated_and_disabled { - typedef long pad_type; - pad_type my_pad[((sizeof(Mutex)+cache_line_size-1)/cache_line_size+1)*cache_line_size/sizeof(pad_type)]; - - Mutex *impl() { return (Mutex *)((uintptr_t(this)|(cache_line_size-1))+1);} - -public: - static const bool is_rw_mutex = Mutex::is_rw_mutex; - static const bool is_recursive_mutex = Mutex::is_recursive_mutex; - static const bool is_fair_mutex = Mutex::is_fair_mutex; - - padded_mutex() { new(impl()) Mutex(); } - ~padded_mutex() { impl()->~Mutex(); } - - //! Represents acquisition of a mutex. - class scoped_lock : tbb::internal::no_copy { - typename Mutex::scoped_lock my_scoped_lock; - public: - scoped_lock() : my_scoped_lock() {} - scoped_lock( padded_mutex& m, bool write = true ) : my_scoped_lock(*m.impl(),write) { } - ~scoped_lock() { } - - void acquire( padded_mutex& m, bool write = true ) { my_scoped_lock.acquire(*m.impl(),write); } - bool try_acquire( padded_mutex& m, bool write = true ) { return my_scoped_lock.try_acquire(*m.impl(),write); } - bool upgrade_to_writer() { return my_scoped_lock.upgrade_to_writer(); } - bool downgrade_to_reader() { return my_scoped_lock.downgrade_to_reader(); } - void release() { my_scoped_lock.release(); } - }; -}; - -} // namespace internal -} // namespace interface7 -} // namespace tbb - -#endif /* __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 deleted file mode 100644 index 5ebc42e8..00000000 --- a/lib/3rdParty/tbb/include/tbb/internal/_range_iterator.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - 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_range_iterator_H -#define __TBB_range_iterator_H - -#include "../tbb_stddef.h" - -#if __TBB_CPP11_STD_BEGIN_END_PRESENT && __TBB_CPP11_AUTO_PRESENT && __TBB_CPP11_DECLTYPE_PRESENT - #include -#endif - -namespace tbb { - // iterators to first and last elements of container - namespace internal { - -#if __TBB_CPP11_STD_BEGIN_END_PRESENT && __TBB_CPP11_AUTO_PRESENT && __TBB_CPP11_DECLTYPE_PRESENT - using std::begin; - using std::end; - template - auto first(Container& c)-> decltype(begin(c)) {return begin(c);} - - template - auto first(const Container& c)-> decltype(begin(c)) {return begin(c);} - - template - auto last(Container& c)-> decltype(begin(c)) {return end(c);} - - template - auto last(const Container& c)-> decltype(begin(c)) {return end(c);} -#else - template - typename Container::iterator first(Container& c) {return c.begin();} - - template - typename Container::const_iterator first(const Container& c) {return c.begin();} - - template - typename Container::iterator last(Container& c) {return c.end();} - - template - typename Container::const_iterator last(const Container& c) {return c.end();} -#endif - - template - T* first(T (&arr) [size]) {return arr;} - - template - T* last(T (&arr) [size]) {return arr + size;} - } //namespace internal -} //namespace tbb - -#endif // __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 deleted file mode 100644 index 6381e2dc..00000000 --- a/lib/3rdParty/tbb/include/tbb/internal/_tbb_hash_compare_impl.h +++ /dev/null @@ -1,109 +0,0 @@ -/* - 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. - - - - -*/ - -// must be included outside namespaces. -#ifndef __TBB_tbb_hash_compare_impl_H -#define __TBB_tbb_hash_compare_impl_H - -#include - -namespace tbb { -namespace interface5 { -namespace internal { - -// Template class for hash compare -template -class hash_compare -{ -public: - typedef Hasher hasher; - typedef Key_equality key_equal; - - hash_compare() {} - - hash_compare(Hasher a_hasher) : my_hash_object(a_hasher) {} - - hash_compare(Hasher a_hasher, Key_equality a_keyeq) : my_hash_object(a_hasher), my_key_compare_object(a_keyeq) {} - - size_t operator()(const Key& key) const { - return ((size_t)my_hash_object(key)); - } - - bool operator()(const Key& key1, const Key& key2) const { - // TODO: get rid of the result invertion - return (!my_key_compare_object(key1, key2)); - } - - Hasher my_hash_object; // The hash object - Key_equality my_key_compare_object; // The equality comparator object -}; - -//! Hash multiplier -static const size_t hash_multiplier = tbb::internal::select_size_t_constant<2654435769U, 11400714819323198485ULL>::value; - -} // namespace internal - -//! Hasher functions -template -inline size_t tbb_hasher( const T& t ) { - return static_cast( t ) * internal::hash_multiplier; -} -template -inline size_t tbb_hasher( P* ptr ) { - size_t const h = reinterpret_cast( ptr ); - return (h >> 3) ^ h; -} -template -inline size_t tbb_hasher( const std::basic_string& s ) { - size_t h = 0; - for( const E* c = s.c_str(); *c; ++c ) - h = static_cast(*c) ^ (h * internal::hash_multiplier); - return h; -} -template -inline size_t tbb_hasher( const std::pair& p ) { - return tbb_hasher(p.first) ^ tbb_hasher(p.second); -} - -} // namespace interface5 -using interface5::tbb_hasher; - -// Template class for hash compare -template -class tbb_hash -{ -public: - tbb_hash() {} - - size_t operator()(const Key& key) const - { - return tbb_hasher(key); - } -}; - -//! hash_compare that is default argument for concurrent_hash_map -template -struct tbb_hash_compare { - static size_t hash( const Key& a ) { return tbb_hasher(a); } - static bool equal( const Key& a, const Key& b ) { return a == b; } -}; - -} // namespace tbb -#endif /* __TBB_tbb_hash_compare_impl_H */ diff --git a/lib/3rdParty/tbb/include/tbb/internal/_tbb_strings.h b/lib/3rdParty/tbb/include/tbb/internal/_tbb_strings.h deleted file mode 100644 index 1aa532f3..00000000 --- a/lib/3rdParty/tbb/include/tbb/internal/_tbb_strings.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - 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. - - - - -*/ - -TBB_STRING_RESOURCE(FLOW_BROADCAST_NODE, "broadcast_node") -TBB_STRING_RESOURCE(FLOW_BUFFER_NODE, "buffer_node") -TBB_STRING_RESOURCE(FLOW_CONTINUE_NODE, "continue_node") -TBB_STRING_RESOURCE(FLOW_FUNCTION_NODE, "function_node") -TBB_STRING_RESOURCE(FLOW_JOIN_NODE_QUEUEING, "join_node (queueing)") -TBB_STRING_RESOURCE(FLOW_JOIN_NODE_RESERVING, "join_node (reserving)") -TBB_STRING_RESOURCE(FLOW_JOIN_NODE_TAG_MATCHING, "join_node (tag_matching)") -TBB_STRING_RESOURCE(FLOW_LIMITER_NODE, "limiter_node") -TBB_STRING_RESOURCE(FLOW_MULTIFUNCTION_NODE, "multifunction_node") -TBB_STRING_RESOURCE(FLOW_OR_NODE, "or_node") //no longer in use, kept for backward compatibility -TBB_STRING_RESOURCE(FLOW_OVERWRITE_NODE, "overwrite_node") -TBB_STRING_RESOURCE(FLOW_PRIORITY_QUEUE_NODE, "priority_queue_node") -TBB_STRING_RESOURCE(FLOW_QUEUE_NODE, "queue_node") -TBB_STRING_RESOURCE(FLOW_SEQUENCER_NODE, "sequencer_node") -TBB_STRING_RESOURCE(FLOW_SOURCE_NODE, "source_node") -TBB_STRING_RESOURCE(FLOW_SPLIT_NODE, "split_node") -TBB_STRING_RESOURCE(FLOW_WRITE_ONCE_NODE, "write_once_node") -TBB_STRING_RESOURCE(FLOW_BODY, "body") -TBB_STRING_RESOURCE(FLOW_GRAPH, "graph") -TBB_STRING_RESOURCE(FLOW_NODE, "node") -TBB_STRING_RESOURCE(FLOW_INPUT_PORT, "input_port") -TBB_STRING_RESOURCE(FLOW_INPUT_PORT_0, "input_port_0") -TBB_STRING_RESOURCE(FLOW_INPUT_PORT_1, "input_port_1") -TBB_STRING_RESOURCE(FLOW_INPUT_PORT_2, "input_port_2") -TBB_STRING_RESOURCE(FLOW_INPUT_PORT_3, "input_port_3") -TBB_STRING_RESOURCE(FLOW_INPUT_PORT_4, "input_port_4") -TBB_STRING_RESOURCE(FLOW_INPUT_PORT_5, "input_port_5") -TBB_STRING_RESOURCE(FLOW_INPUT_PORT_6, "input_port_6") -TBB_STRING_RESOURCE(FLOW_INPUT_PORT_7, "input_port_7") -TBB_STRING_RESOURCE(FLOW_INPUT_PORT_8, "input_port_8") -TBB_STRING_RESOURCE(FLOW_INPUT_PORT_9, "input_port_9") -TBB_STRING_RESOURCE(FLOW_OUTPUT_PORT, "output_port") -TBB_STRING_RESOURCE(FLOW_OUTPUT_PORT_0, "output_port_0") -TBB_STRING_RESOURCE(FLOW_OUTPUT_PORT_1, "output_port_1") -TBB_STRING_RESOURCE(FLOW_OUTPUT_PORT_2, "output_port_2") -TBB_STRING_RESOURCE(FLOW_OUTPUT_PORT_3, "output_port_3") -TBB_STRING_RESOURCE(FLOW_OUTPUT_PORT_4, "output_port_4") -TBB_STRING_RESOURCE(FLOW_OUTPUT_PORT_5, "output_port_5") -TBB_STRING_RESOURCE(FLOW_OUTPUT_PORT_6, "output_port_6") -TBB_STRING_RESOURCE(FLOW_OUTPUT_PORT_7, "output_port_7") -TBB_STRING_RESOURCE(FLOW_OUTPUT_PORT_8, "output_port_8") -TBB_STRING_RESOURCE(FLOW_OUTPUT_PORT_9, "output_port_9") -TBB_STRING_RESOURCE(FLOW_OBJECT_NAME, "object_name") -TBB_STRING_RESOURCE(FLOW_NULL, "null") -TBB_STRING_RESOURCE(FLOW_INDEXER_NODE, "indexer_node") -TBB_STRING_RESOURCE(FLOW_COMPOSITE_NODE, "composite_node") -TBB_STRING_RESOURCE(FLOW_ASYNC_NODE, "async_node") diff --git a/lib/3rdParty/tbb/include/tbb/internal/_tbb_windef.h b/lib/3rdParty/tbb/include/tbb/internal/_tbb_windef.h deleted file mode 100644 index e798dee4..00000000 --- a/lib/3rdParty/tbb/include/tbb/internal/_tbb_windef.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - 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_tbb_windef_H -#error Do not #include this internal file directly; use public TBB headers instead. -#endif /* __TBB_tbb_windef_H */ - -// Check that the target Windows version has all API calls requried for TBB. -// Do not increase the version in condition beyond 0x0500 without prior discussion! -#if defined(_WIN32_WINNT) && _WIN32_WINNT<0x0501 -#error TBB is unable to run on old Windows versions; _WIN32_WINNT must be 0x0501 or greater. -#endif - -#if !defined(_MT) -#error TBB requires linkage with multithreaded C/C++ runtime library. \ - Choose multithreaded DLL runtime in project settings, or use /MD[d] compiler switch. -#endif - -// Workaround for the problem with MVSC headers failing to define namespace std -namespace std { - using ::size_t; using ::ptrdiff_t; -} - -#define __TBB_STRING_AUX(x) #x -#define __TBB_STRING(x) __TBB_STRING_AUX(x) - -// Default setting of TBB_USE_DEBUG -#ifdef TBB_USE_DEBUG -# if TBB_USE_DEBUG -# if !defined(_DEBUG) -# pragma message(__FILE__ "(" __TBB_STRING(__LINE__) ") : Warning: Recommend using /MDd if compiling with TBB_USE_DEBUG!=0") -# endif -# else -# if defined(_DEBUG) -# pragma message(__FILE__ "(" __TBB_STRING(__LINE__) ") : Warning: Recommend using /MD if compiling with TBB_USE_DEBUG==0") -# endif -# endif -#endif - -#if (__TBB_BUILD || __TBBMALLOC_BUILD) && !defined(__TBB_NO_IMPLICIT_LINKAGE) -#define __TBB_NO_IMPLICIT_LINKAGE 1 -#endif - -#if _MSC_VER - #if !__TBB_NO_IMPLICIT_LINKAGE - #ifdef __TBB_LIB_NAME - #pragma comment(lib, __TBB_STRING(__TBB_LIB_NAME)) - #else - #ifdef _DEBUG - #pragma comment(lib, "tbb_debug.lib") - #else - #pragma comment(lib, "tbb.lib") - #endif - #endif - #endif -#endif diff --git a/lib/3rdParty/tbb/include/tbb/internal/_template_helpers.h b/lib/3rdParty/tbb/include/tbb/internal/_template_helpers.h deleted file mode 100644 index 1e0abbe8..00000000 --- a/lib/3rdParty/tbb/include/tbb/internal/_template_helpers.h +++ /dev/null @@ -1,158 +0,0 @@ -/* - 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_template_helpers_H -#define __TBB_template_helpers_H - -#include -#include - -namespace tbb { namespace internal { - -//! Enables one or the other code branches -template struct enable_if {}; -template struct enable_if { typedef T type; }; - -//! Strips its template type argument from cv- and ref-qualifiers -template struct strip { typedef T type; }; -template struct strip { typedef T type; }; -template struct strip { typedef T type; }; -template struct strip { typedef T type; }; -template struct strip { typedef T type; }; -template struct strip { typedef T type; }; -template struct strip { typedef T type; }; -template struct strip { typedef T type; }; -//! Specialization for function pointers -template struct strip { typedef T(*type)(); }; -#if __TBB_CPP11_RVALUE_REF_PRESENT -template struct strip { typedef T type; }; -template struct strip { typedef T type; }; -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; }; - -//! Detects whether two given types are the same -template struct is_same_type { static const bool value = false; }; -template struct is_same_type { static const bool value = true; }; - -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 -template< typename... Types > -struct stored_pack; - -template<> -struct stored_pack<> -{ - typedef stored_pack<> pack_type; - stored_pack() {} - - // Friend front-end functions - template< typename F, typename Pack > friend void call( F&& f, Pack&& p ); - template< typename Ret, typename F, typename Pack > friend Ret call_and_return( F&& f, Pack&& p ); - -protected: - // Ideally, ref-qualified non-static methods would be used, - // but that would greatly reduce the set of compilers where it works. - template< typename Ret, typename F, typename... Preceding > - static Ret call( F&& f, const pack_type& /*pack*/, Preceding&&... params ) { - return std::forward(f)( std::forward(params)... ); - } - template< typename Ret, typename F, typename... Preceding > - static Ret call( F&& f, pack_type&& /*pack*/, Preceding&&... params ) { - return std::forward(f)( std::forward(params)... ); - } -}; - -template< typename T, typename... Types > -struct stored_pack : stored_pack -{ - typedef stored_pack pack_type; - typedef stored_pack pack_remainder; - // Since lifetime of original values is out of control, copies should be made. - // Thus references should be stripped away from the deduced type. - typename strip::type leftmost_value; - - // Here rvalue references act in the same way as forwarding references, - // as long as class template parameters were deduced via forwarding references. - stored_pack( T&& t, Types&&... types ) - : pack_remainder(std::forward(types)...), leftmost_value(std::forward(t)) {} - - // Friend front-end functions - template< typename F, typename Pack > friend void call( F&& f, Pack&& p ); - 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( - std::forward(f), static_cast(pack), - std::forward(params)... , pack.leftmost_value - ); - } - 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)... , std::move(pack.leftmost_value) - ); - } -}; - -//! Calls the given function with arguments taken from a stored_pack -template< typename F, typename Pack > -void call( F&& f, Pack&& p ) { - strip::type::template call( std::forward(f), std::forward(p) ); -} - -template< typename Ret, typename F, typename Pack > -Ret call_and_return( F&& f, Pack&& p ) { - return strip::type::template call( std::forward(f), std::forward(p) ); -} - -template< typename... Types > -stored_pack save_pack( Types&&... types ) { - return stored_pack( std::forward(types)... ); -} - -#endif /* __TBB_CPP11_RVALUE_REF_PRESENT && __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT */ -} } // namespace internal, namespace tbb - -#endif /* __TBB_template_helpers_H */ 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 deleted file mode 100644 index ef5f9223..00000000 --- a/lib/3rdParty/tbb/include/tbb/internal/_x86_eliding_mutex_impl.h +++ /dev/null @@ -1,148 +0,0 @@ -/* - 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__x86_eliding_mutex_impl_H -#define __TBB__x86_eliding_mutex_impl_H - -#ifndef __TBB_spin_mutex_H -#error Do not #include this internal file directly; use public TBB headers instead. -#endif - -#if ( __TBB_x86_32 || __TBB_x86_64 ) - -namespace tbb { -namespace interface7 { -namespace internal { - -template -class padded_mutex; - -//! An eliding lock that occupies a single byte. -/** A x86_eliding_mutex is an HLE-enabled spin mutex. It is recommended to - put the mutex on a cache line that is not shared by the data it protects. - It should be used for locking short critical sections where the lock is - contended but the data it protects are not. If zero-initialized, the - mutex is considered unheld. - @ingroup synchronization */ -class x86_eliding_mutex : tbb::internal::mutex_copy_deprecated_and_disabled { - //! 0 if lock is released, 1 if lock is acquired. - __TBB_atomic_flag flag; - - friend class padded_mutex; - -public: - //! Construct unacquired lock. - /** Equivalent to zero-initialization of *this. */ - x86_eliding_mutex() : flag(0) {} - -// bug in gcc 3.x.x causes syntax error in spite of the friend declaration above. -// Make the scoped_lock public in that case. -#if __TBB_USE_X86_ELIDING_MUTEX || __TBB_GCC_VERSION < 40000 -#else - // by default we will not provide the scoped_lock interface. The user - // should use the padded version of the mutex. scoped_lock is used in - // padded_mutex template. -private: -#endif - // scoped_lock in padded_mutex<> is the interface to use. - //! Represents acquisition of a mutex. - class scoped_lock : tbb::internal::no_copy { - private: - //! Points to currently held mutex, or NULL if no lock is held. - x86_eliding_mutex* my_mutex; - - public: - //! Construct without acquiring a mutex. - scoped_lock() : my_mutex(NULL) {} - - //! Construct and acquire lock on a mutex. - scoped_lock( x86_eliding_mutex& m ) : my_mutex(NULL) { acquire(m); } - - //! Acquire lock. - void acquire( x86_eliding_mutex& m ) { - __TBB_ASSERT( !my_mutex, "already holding a lock" ); - - my_mutex=&m; - my_mutex->lock(); - } - - //! Try acquiring lock (non-blocking) - /** Return true if lock acquired; false otherwise. */ - bool try_acquire( x86_eliding_mutex& m ) { - __TBB_ASSERT( !my_mutex, "already holding a lock" ); - - bool result = m.try_lock(); - if( result ) { - my_mutex = &m; - } - return result; - } - - //! Release lock - void release() { - __TBB_ASSERT( my_mutex, "release on scoped_lock that is not holding a lock" ); - - my_mutex->unlock(); - my_mutex = NULL; - } - - //! Destroy lock. If holding a lock, releases the lock first. - ~scoped_lock() { - if( my_mutex ) { - release(); - } - } - }; -#if __TBB_USE_X86_ELIDING_MUTEX || __TBB_GCC_VERSION < 40000 -#else -public: -#endif /* __TBB_USE_X86_ELIDING_MUTEX */ - - // Mutex traits - static const bool is_rw_mutex = false; - static const bool is_recursive_mutex = false; - static const bool is_fair_mutex = false; - - // ISO C++0x compatibility methods - - //! Acquire lock - void lock() { - __TBB_LockByteElided(flag); - } - - //! Try acquiring lock (non-blocking) - /** Return true if lock acquired; false otherwise. */ - bool try_lock() { - return __TBB_TryLockByteElided(flag); - } - - //! Release lock - void unlock() { - __TBB_UnlockByteElided( flag ); - } -}; // end of x86_eliding_mutex - -} // namespace internal -} // namespace interface7 -} // namespace tbb - -#endif /* ( __TBB_x86_32 || __TBB_x86_64 ) */ - -#endif /* __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 deleted file mode 100644 index b08c2331..00000000 --- a/lib/3rdParty/tbb/include/tbb/internal/_x86_rtm_rw_mutex_impl.h +++ /dev/null @@ -1,225 +0,0 @@ -/* - 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__x86_rtm_rw_mutex_impl_H -#define __TBB__x86_rtm_rw_mutex_impl_H - -#ifndef __TBB_spin_rw_mutex_H -#error Do not #include this internal file directly; use public TBB headers instead. -#endif - -#if __TBB_TSX_AVAILABLE - -#include "../tbb_stddef.h" -#include "../tbb_machine.h" -#include "../tbb_profiling.h" -#include "../spin_rw_mutex.h" - -namespace tbb { -namespace interface8 { -namespace internal { - -enum RTM_type { - RTM_not_in_mutex, - RTM_transacting_reader, - RTM_transacting_writer, - RTM_real_reader, - RTM_real_writer -}; - -static const unsigned long speculation_granularity = 64; - -//! Fast, unfair, spinning speculation-enabled reader-writer lock with backoff and -// writer-preference -/** @ingroup synchronization */ -class x86_rtm_rw_mutex: private spin_rw_mutex { -#if __TBB_USE_X86_RTM_RW_MUTEX || __TBB_GCC_VERSION < 40000 -// bug in gcc 3.x.x causes syntax error in spite of the friend declaration below. -// Make the scoped_lock public in that case. -public: -#else -private: -#endif - friend class interface7::internal::padded_mutex; - class scoped_lock; // should be private - friend class scoped_lock; -private: - //! @cond INTERNAL - - //! Internal construct unacquired mutex. - void __TBB_EXPORTED_METHOD internal_construct(); - - //! Internal acquire write lock. - // only_speculate == true if we're doing a try_lock, else false. - void __TBB_EXPORTED_METHOD internal_acquire_writer(x86_rtm_rw_mutex::scoped_lock&, bool only_speculate=false); - - //! Internal acquire read lock. - // only_speculate == true if we're doing a try_lock, else false. - void __TBB_EXPORTED_METHOD internal_acquire_reader(x86_rtm_rw_mutex::scoped_lock&, bool only_speculate=false); - - //! Internal upgrade reader to become a writer. - bool __TBB_EXPORTED_METHOD internal_upgrade( x86_rtm_rw_mutex::scoped_lock& ); - - //! Out of line code for downgrading a writer to a reader. - bool __TBB_EXPORTED_METHOD internal_downgrade( x86_rtm_rw_mutex::scoped_lock& ); - - //! Internal try_acquire write lock. - bool __TBB_EXPORTED_METHOD internal_try_acquire_writer( x86_rtm_rw_mutex::scoped_lock& ); - - //! Internal release lock. - void __TBB_EXPORTED_METHOD internal_release( x86_rtm_rw_mutex::scoped_lock& ); - - static x86_rtm_rw_mutex* internal_get_mutex( const spin_rw_mutex::scoped_lock& lock ) - { - return static_cast( lock.internal_get_mutex() ); - } - static void internal_set_mutex( spin_rw_mutex::scoped_lock& lock, spin_rw_mutex* mtx ) - { - lock.internal_set_mutex( mtx ); - } - //! @endcond -public: - //! Construct unacquired mutex. - x86_rtm_rw_mutex() { - w_flag = false; -#if TBB_USE_THREADING_TOOLS - internal_construct(); -#endif - } - -#if TBB_USE_ASSERT - //! Empty destructor. - ~x86_rtm_rw_mutex() {} -#endif /* TBB_USE_ASSERT */ - - // Mutex traits - static const bool is_rw_mutex = true; - static const bool is_recursive_mutex = false; - static const bool is_fair_mutex = false; - -#if __TBB_USE_X86_RTM_RW_MUTEX || __TBB_GCC_VERSION < 40000 -#else - // by default we will not provide the scoped_lock interface. The user - // should use the padded version of the mutex. scoped_lock is used in - // padded_mutex template. -private: -#endif - //! The scoped locking pattern - /** It helps to avoid the common problem of forgetting to release lock. - It also nicely provides the "node" for queuing locks. */ - // Speculation-enabled scoped lock for spin_rw_mutex - // The idea is to be able to reuse the acquire/release methods of spin_rw_mutex - // and its scoped lock wherever possible. The only way to use a speculative lock is to use - // a scoped_lock. (because transaction_state must be local) - - class scoped_lock : tbb::internal::no_copy { - friend class x86_rtm_rw_mutex; - spin_rw_mutex::scoped_lock my_scoped_lock; - - RTM_type transaction_state; - - public: - //! Construct lock that has not acquired a mutex. - /** Equivalent to zero-initialization of *this. */ - scoped_lock() : my_scoped_lock(), transaction_state(RTM_not_in_mutex) { - } - - //! Acquire lock on given mutex. - scoped_lock( x86_rtm_rw_mutex& m, bool write = true ) : my_scoped_lock(), - transaction_state(RTM_not_in_mutex) { - acquire(m, write); - } - - //! Release lock (if lock is held). - ~scoped_lock() { - if(transaction_state != RTM_not_in_mutex) release(); - } - - //! Acquire lock on given mutex. - void acquire( x86_rtm_rw_mutex& m, bool write = true ) { - if( write ) m.internal_acquire_writer(*this); - else m.internal_acquire_reader(*this); - } - - //! Release lock - void release() { - x86_rtm_rw_mutex* mutex = x86_rtm_rw_mutex::internal_get_mutex(my_scoped_lock); - __TBB_ASSERT( mutex, "lock is not acquired" ); - __TBB_ASSERT( transaction_state!=RTM_not_in_mutex, "lock is not acquired" ); - return mutex->internal_release(*this); - } - - //! Upgrade reader to become a writer. - /** Returns whether the upgrade happened without releasing and re-acquiring the lock */ - bool upgrade_to_writer() { - x86_rtm_rw_mutex* mutex = x86_rtm_rw_mutex::internal_get_mutex(my_scoped_lock); - __TBB_ASSERT( mutex, "lock is not acquired" ); - __TBB_ASSERT( transaction_state==RTM_transacting_reader || transaction_state==RTM_real_reader, "Invalid state for upgrade" ); - return mutex->internal_upgrade(*this); - } - - //! Downgrade writer to become a reader. - /** Returns whether the downgrade happened without releasing and re-acquiring the lock */ - bool downgrade_to_reader() { - x86_rtm_rw_mutex* mutex = x86_rtm_rw_mutex::internal_get_mutex(my_scoped_lock); - __TBB_ASSERT( mutex, "lock is not acquired" ); - __TBB_ASSERT( transaction_state==RTM_transacting_writer || transaction_state==RTM_real_writer, "Invalid state for downgrade" ); - return mutex->internal_downgrade(*this); - } - - //! Attempt to acquire mutex. - /** returns true if successful. */ - bool try_acquire( x86_rtm_rw_mutex& m, bool write = true ) { -#if TBB_USE_ASSERT - x86_rtm_rw_mutex* mutex = x86_rtm_rw_mutex::internal_get_mutex(my_scoped_lock); - __TBB_ASSERT( !mutex, "lock is already acquired" ); -#endif - // have to assign m to our mutex. - // cannot set the mutex, because try_acquire in spin_rw_mutex depends on it being NULL. - if(write) return m.internal_try_acquire_writer(*this); - // speculatively acquire the lock. If this fails, do try_acquire on the spin_rw_mutex. - m.internal_acquire_reader(*this, /*only_speculate=*/true); - if(transaction_state == RTM_transacting_reader) return true; - if( my_scoped_lock.try_acquire(m, false)) { - transaction_state = RTM_real_reader; - return true; - } - return false; - } - - }; // class x86_rtm_rw_mutex::scoped_lock - - // ISO C++0x compatibility methods not provided because we cannot maintain - // state about whether a thread is in a transaction. - -private: - char pad[speculation_granularity-sizeof(spin_rw_mutex)]; // padding - - // If true, writer holds the spin_rw_mutex. - tbb::atomic w_flag; // want this on a separate cache line - -}; // x86_rtm_rw_mutex - -} // namespace internal -} // namespace interface8 -} // namespace tbb - -#endif /* __TBB_TSX_AVAILABLE */ -#endif /* __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 deleted file mode 100644 index 642c14fe..00000000 --- a/lib/3rdParty/tbb/include/tbb/machine/gcc_armv7.h +++ /dev/null @@ -1,217 +0,0 @@ -/* - 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. - - - - -*/ - -/* - Platform isolation layer for the ARMv7-a architecture. -*/ - -#ifndef __TBB_machine_H -#error Do not include this file directly; include tbb_machine.h instead -#endif - -//TODO: is ARMv7 is the only version ever to support? -#if !(__ARM_ARCH_7A__) -#error compilation requires an ARMv7-a architecture. -#endif - -#include -#include - -#define __TBB_WORDSIZE 4 - -// Traditionally ARM is little-endian. -// Note that, since only the layout of aligned 32-bit words is of interest, -// any apparent PDP-endianness of 32-bit words at half-word alignment or -// any little-endian ordering of big-endian 32-bit words in 64-bit quantities -// may be disregarded for this setting. -#if __BIG_ENDIAN__ || (defined(__BYTE_ORDER__) && __BYTE_ORDER__==__ORDER_BIG_ENDIAN__) - #define __TBB_ENDIANNESS __TBB_ENDIAN_BIG -#elif __LITTLE_ENDIAN__ || (defined(__BYTE_ORDER__) && __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__) - #define __TBB_ENDIANNESS __TBB_ENDIAN_LITTLE -#elif defined(__BYTE_ORDER__) - #define __TBB_ENDIANNESS __TBB_ENDIAN_UNSUPPORTED -#else - #define __TBB_ENDIANNESS __TBB_ENDIAN_DETECT -#endif - - -#define __TBB_compiler_fence() __asm__ __volatile__("": : :"memory") -#define __TBB_full_memory_fence() __asm__ __volatile__("dmb ish": : :"memory") -#define __TBB_control_consistency_helper() __TBB_full_memory_fence() -#define __TBB_acquire_consistency_helper() __TBB_full_memory_fence() -#define __TBB_release_consistency_helper() __TBB_full_memory_fence() - -//-------------------------------------------------- -// Compare and swap -//-------------------------------------------------- - -/** - * Atomic CAS for 32 bit values, if *ptr==comparand, then *ptr=value, returns *ptr - * @param ptr pointer to value in memory to be swapped with value if *ptr==comparand - * @param value value to assign *ptr to if *ptr==comparand - * @param comparand value to compare with *ptr - * @return value originally in memory at ptr, regardless of success -*/ -static inline int32_t __TBB_machine_cmpswp4(volatile void *ptr, int32_t value, int32_t comparand ) -{ - int32_t oldval, res; - - __TBB_full_memory_fence(); - - do { - __asm__ __volatile__( - "ldrex %1, [%3]\n" - "mov %0, #0\n" - "cmp %1, %4\n" - "it eq\n" - "strexeq %0, %5, [%3]\n" - : "=&r" (res), "=&r" (oldval), "+Qo" (*(volatile int32_t*)ptr) - : "r" ((volatile int32_t *)ptr), "Ir" (comparand), "r" (value) - : "cc"); - } while (res); - - __TBB_full_memory_fence(); - - return oldval; -} - -/** - * Atomic CAS for 64 bit values, if *ptr==comparand, then *ptr=value, returns *ptr - * @param ptr pointer to value in memory to be swapped with value if *ptr==comparand - * @param value value to assign *ptr to if *ptr==comparand - * @param comparand value to compare with *ptr - * @return value originally in memory at ptr, regardless of success - */ -static inline int64_t __TBB_machine_cmpswp8(volatile void *ptr, int64_t value, int64_t comparand ) -{ - int64_t oldval; - int32_t res; - - __TBB_full_memory_fence(); - - do { - __asm__ __volatile__( - "mov %0, #0\n" - "ldrexd %1, %H1, [%3]\n" - "cmp %1, %4\n" - "it eq\n" - "cmpeq %H1, %H4\n" - "it eq\n" - "strexdeq %0, %5, %H5, [%3]" - : "=&r" (res), "=&r" (oldval), "+Qo" (*(volatile int64_t*)ptr) - : "r" ((volatile int64_t *)ptr), "r" (comparand), "r" (value) - : "cc"); - } while (res); - - __TBB_full_memory_fence(); - - return oldval; -} - -static inline int32_t __TBB_machine_fetchadd4(volatile void* ptr, int32_t addend) -{ - unsigned long tmp; - int32_t result, tmp2; - - __TBB_full_memory_fence(); - - __asm__ __volatile__( -"1: ldrex %0, [%4]\n" -" add %3, %0, %5\n" -" strex %1, %3, [%4]\n" -" cmp %1, #0\n" -" bne 1b\n" - : "=&r" (result), "=&r" (tmp), "+Qo" (*(volatile int32_t*)ptr), "=&r"(tmp2) - : "r" ((volatile int32_t *)ptr), "Ir" (addend) - : "cc"); - - __TBB_full_memory_fence(); - - return result; -} - -static inline int64_t __TBB_machine_fetchadd8(volatile void *ptr, int64_t addend) -{ - unsigned long tmp; - int64_t result, tmp2; - - __TBB_full_memory_fence(); - - __asm__ __volatile__( -"1: ldrexd %0, %H0, [%4]\n" -" adds %3, %0, %5\n" -" adc %H3, %H0, %H5\n" -" strexd %1, %3, %H3, [%4]\n" -" cmp %1, #0\n" -" bne 1b" - : "=&r" (result), "=&r" (tmp), "+Qo" (*(volatile int64_t*)ptr), "=&r"(tmp2) - : "r" ((volatile int64_t *)ptr), "r" (addend) - : "cc"); - - - __TBB_full_memory_fence(); - - return result; -} - -inline void __TBB_machine_pause (int32_t delay ) -{ - while(delay>0) - { - __TBB_compiler_fence(); - delay--; - } -} - -namespace tbb { -namespace internal { - template - struct machine_load_store_relaxed { - static inline T load ( const volatile T& location ) { - const T value = location; - - /* - * An extra memory barrier is required for errata #761319 - * Please see http://infocenter.arm.com/help/topic/com.arm.doc.uan0004a - */ - __TBB_acquire_consistency_helper(); - return value; - } - - static inline void store ( volatile T& location, T value ) { - location = value; - } - }; -}} // namespaces internal, tbb - -// Machine specific atomic operations - -#define __TBB_CompareAndSwap4(P,V,C) __TBB_machine_cmpswp4(P,V,C) -#define __TBB_CompareAndSwap8(P,V,C) __TBB_machine_cmpswp8(P,V,C) -#define __TBB_Pause(V) __TBB_machine_pause(V) - -// Use generics for some things -#define __TBB_USE_GENERIC_PART_WORD_CAS 1 -#define __TBB_USE_GENERIC_PART_WORD_FETCH_ADD 1 -#define __TBB_USE_GENERIC_PART_WORD_FETCH_STORE 1 -#define __TBB_USE_GENERIC_FETCH_STORE 1 -#define __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE 1 -#define __TBB_USE_GENERIC_DWORD_LOAD_STORE 1 -#define __TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE 1 diff --git a/lib/3rdParty/tbb/include/tbb/machine/gcc_generic.h b/lib/3rdParty/tbb/include/tbb/machine/gcc_generic.h deleted file mode 100644 index 5fc2a901..00000000 --- a/lib/3rdParty/tbb/include/tbb/machine/gcc_generic.h +++ /dev/null @@ -1,184 +0,0 @@ -/* - 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. - - - - -*/ - -#if !defined(__TBB_machine_H) || defined(__TBB_machine_gcc_generic_H) -#error Do not #include this internal file directly; use public TBB headers instead. -#endif - -#define __TBB_machine_gcc_generic_H - -#include -#include - -#define __TBB_WORDSIZE __SIZEOF_POINTER__ - -#if __TBB_GCC_64BIT_ATOMIC_BUILTINS_BROKEN - #define __TBB_64BIT_ATOMICS 0 -#endif - -/** FPU control setting not available for non-Intel architectures on Android **/ -#if __ANDROID__ && __TBB_generic_arch - #define __TBB_CPU_CTL_ENV_PRESENT 0 -#endif - -// __BYTE_ORDER__ is used in accordance with http://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html, -// but __BIG_ENDIAN__ or __LITTLE_ENDIAN__ may be more commonly found instead. -#if __BIG_ENDIAN__ || (defined(__BYTE_ORDER__) && __BYTE_ORDER__==__ORDER_BIG_ENDIAN__) - #define __TBB_ENDIANNESS __TBB_ENDIAN_BIG -#elif __LITTLE_ENDIAN__ || (defined(__BYTE_ORDER__) && __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__) - #define __TBB_ENDIANNESS __TBB_ENDIAN_LITTLE -#elif defined(__BYTE_ORDER__) - #define __TBB_ENDIANNESS __TBB_ENDIAN_UNSUPPORTED -#else - #define __TBB_ENDIANNESS __TBB_ENDIAN_DETECT -#endif - -#if __TBB_GCC_VERSION < 40700 -// Use __sync_* builtins - -/** As this generic implementation has absolutely no information about underlying - hardware, its performance most likely will be sub-optimal because of full memory - fence usages where a more lightweight synchronization means (or none at all) - could suffice. Thus if you use this header to enable TBB on a new platform, - consider forking it and relaxing below helpers as appropriate. **/ -#define __TBB_acquire_consistency_helper() __sync_synchronize() -#define __TBB_release_consistency_helper() __sync_synchronize() -#define __TBB_full_memory_fence() __sync_synchronize() -#define __TBB_control_consistency_helper() __sync_synchronize() - -#define __TBB_MACHINE_DEFINE_ATOMICS(S,T) \ -inline T __TBB_machine_cmpswp##S( volatile void *ptr, T value, T comparand ) { \ - return __sync_val_compare_and_swap(reinterpret_cast(ptr),comparand,value); \ -} \ -inline T __TBB_machine_fetchadd##S( volatile void *ptr, T value ) { \ - return __sync_fetch_and_add(reinterpret_cast(ptr),value); \ -} - -#define __TBB_USE_GENERIC_FETCH_STORE 1 - -#else -// __TBB_GCC_VERSION >= 40700; use __atomic_* builtins available since gcc 4.7 - -#define __TBB_compiler_fence() __asm__ __volatile__("": : :"memory") -// Acquire and release fence intrinsics in GCC might miss compiler fence. -// Adding it at both sides of an intrinsic, as we do not know what reordering can be made. -#define __TBB_acquire_consistency_helper() __TBB_compiler_fence(); __atomic_thread_fence(__ATOMIC_ACQUIRE); __TBB_compiler_fence() -#define __TBB_release_consistency_helper() __TBB_compiler_fence(); __atomic_thread_fence(__ATOMIC_RELEASE); __TBB_compiler_fence() -#define __TBB_full_memory_fence() __atomic_thread_fence(__ATOMIC_SEQ_CST) -#define __TBB_control_consistency_helper() __TBB_acquire_consistency_helper() - -#define __TBB_MACHINE_DEFINE_ATOMICS(S,T) \ -inline T __TBB_machine_cmpswp##S( volatile void *ptr, T value, T comparand ) { \ - (void)__atomic_compare_exchange_n(reinterpret_cast(ptr), &comparand, value, \ - false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); \ - return comparand; \ -} \ -inline T __TBB_machine_fetchadd##S( volatile void *ptr, T value ) { \ - return __atomic_fetch_add(reinterpret_cast(ptr), value, __ATOMIC_SEQ_CST); \ -} \ -inline T __TBB_machine_fetchstore##S( volatile void *ptr, T value ) { \ - return __atomic_exchange_n(reinterpret_cast(ptr), value, __ATOMIC_SEQ_CST); \ -} - -#endif // __TBB_GCC_VERSION < 40700 - -__TBB_MACHINE_DEFINE_ATOMICS(1,int8_t) -__TBB_MACHINE_DEFINE_ATOMICS(2,int16_t) -__TBB_MACHINE_DEFINE_ATOMICS(4,int32_t) -__TBB_MACHINE_DEFINE_ATOMICS(8,int64_t) - -#undef __TBB_MACHINE_DEFINE_ATOMICS - -namespace tbb{ namespace internal { namespace gcc_builtins { - inline int clz(unsigned int x){ return __builtin_clz(x);}; - inline int clz(unsigned long int x){ return __builtin_clzl(x);}; - inline int clz(unsigned long long int x){ return __builtin_clzll(x);}; -}}} -//gcc __builtin_clz builtin count _number_ of leading zeroes -static inline intptr_t __TBB_machine_lg( uintptr_t x ) { - return sizeof(x)*8 - tbb::internal::gcc_builtins::clz(x) -1 ; -} - - -typedef unsigned char __TBB_Flag; -typedef __TBB_atomic __TBB_Flag __TBB_atomic_flag; - -#if __TBB_GCC_VERSION < 40700 -// Use __sync_* builtins - -static inline void __TBB_machine_or( volatile void *ptr, uintptr_t addend ) { - __sync_fetch_and_or(reinterpret_cast(ptr),addend); -} - -static inline void __TBB_machine_and( volatile void *ptr, uintptr_t addend ) { - __sync_fetch_and_and(reinterpret_cast(ptr),addend); -} - -inline bool __TBB_machine_try_lock_byte( __TBB_atomic_flag &flag ) { - return __sync_lock_test_and_set(&flag,1)==0; -} - -inline void __TBB_machine_unlock_byte( __TBB_atomic_flag &flag ) { - __sync_lock_release(&flag); -} - -#else -// __TBB_GCC_VERSION >= 40700; use __atomic_* builtins available since gcc 4.7 - -static inline void __TBB_machine_or( volatile void *ptr, uintptr_t addend ) { - __atomic_fetch_or(reinterpret_cast(ptr),addend,__ATOMIC_SEQ_CST); -} - -static inline void __TBB_machine_and( volatile void *ptr, uintptr_t addend ) { - __atomic_fetch_and(reinterpret_cast(ptr),addend,__ATOMIC_SEQ_CST); -} - -inline bool __TBB_machine_try_lock_byte( __TBB_atomic_flag &flag ) { - return !__atomic_test_and_set(&flag,__ATOMIC_ACQUIRE); -} - -inline void __TBB_machine_unlock_byte( __TBB_atomic_flag &flag ) { - __atomic_clear(&flag,__ATOMIC_RELEASE); -} - -#endif // __TBB_GCC_VERSION < 40700 - -// Machine specific atomic operations -#define __TBB_AtomicOR(P,V) __TBB_machine_or(P,V) -#define __TBB_AtomicAND(P,V) __TBB_machine_and(P,V) - -#define __TBB_TryLockByte __TBB_machine_try_lock_byte -#define __TBB_UnlockByte __TBB_machine_unlock_byte - -// Definition of other functions -#define __TBB_Log2(V) __TBB_machine_lg(V) - -// TODO: implement with __atomic_* builtins where available -#define __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE 1 -#define __TBB_USE_GENERIC_RELAXED_LOAD_STORE 1 -#define __TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE 1 - -#if __TBB_WORDSIZE==4 - #define __TBB_USE_GENERIC_DWORD_LOAD_STORE 1 -#endif - -#if __TBB_x86_32 || __TBB_x86_64 -#include "gcc_itsx.h" -#endif diff --git a/lib/3rdParty/tbb/include/tbb/machine/gcc_ia32_common.h b/lib/3rdParty/tbb/include/tbb/machine/gcc_ia32_common.h deleted file mode 100644 index f5efc375..00000000 --- a/lib/3rdParty/tbb/include/tbb/machine/gcc_ia32_common.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - 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_machine_gcc_ia32_common_H -#define __TBB_machine_gcc_ia32_common_H - -//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 -template -static inline intptr_t __TBB_machine_lg( T x ) { - __TBB_ASSERT(x>0, "The logarithm of a non-positive value is undefined."); - uintptr_t j, i = x; - __asm__("bsr %1,%0" : "=r"(j) : "r"(i)); - return j; -} -#define __TBB_Log2(V) __TBB_machine_lg(V) - -#ifndef __TBB_Pause -//TODO: check if raising a ratio of pause instructions to loop control instructions -//(via e.g. loop unrolling) gives any benefit for HT. E.g, the current implementation -//does about 2 CPU-consuming instructions for every pause instruction. Perhaps for -//high pause counts it should use an unrolled loop to raise the ratio, and thus free -//up more integer cycles for the other hyperthread. On the other hand, if the loop is -//unrolled too far, it won't fit in the core's loop cache, and thus take away -//instruction decode slots from the other hyperthread. - -//TODO: check if use of gcc __builtin_ia32_pause intrinsic gives a "some how" better performing code -static inline void __TBB_machine_pause( int32_t delay ) { - for (int32_t i = 0; i < delay; i++) { - __asm__ __volatile__("pause;"); - } - return; -} -#define __TBB_Pause(V) __TBB_machine_pause(V) -#endif /* !__TBB_Pause */ - -namespace tbb { namespace internal { typedef uint64_t machine_tsc_t; } } -static inline tbb::internal::machine_tsc_t __TBB_machine_time_stamp() { -#if __INTEL_COMPILER - return _rdtsc(); -#else - tbb::internal::uint32_t hi, lo; - __asm__ __volatile__("rdtsc" : "=d"(hi), "=a"(lo)); - return (tbb::internal::machine_tsc_t( hi ) << 32) | lo; -#endif -} -#define __TBB_time_stamp() __TBB_machine_time_stamp() - -// API to retrieve/update FPU control setting -#ifndef __TBB_CPU_CTL_ENV_PRESENT -#define __TBB_CPU_CTL_ENV_PRESENT 1 -namespace tbb { -namespace internal { -class cpu_ctl_env { -private: - int mxcsr; - short x87cw; - static const int MXCSR_CONTROL_MASK = ~0x3f; /* all except last six status bits */ -public: - bool operator!=( const cpu_ctl_env& ctl ) const { return mxcsr != ctl.mxcsr || x87cw != ctl.x87cw; } - void get_env() { - #if __TBB_ICC_12_0_INL_ASM_FSTCW_BROKEN - cpu_ctl_env loc_ctl; - __asm__ __volatile__ ( - "stmxcsr %0\n\t" - "fstcw %1" - : "=m"(loc_ctl.mxcsr), "=m"(loc_ctl.x87cw) - ); - *this = loc_ctl; - #else - __asm__ __volatile__ ( - "stmxcsr %0\n\t" - "fstcw %1" - : "=m"(mxcsr), "=m"(x87cw) - ); - #endif - mxcsr &= MXCSR_CONTROL_MASK; - } - void set_env() const { - __asm__ __volatile__ ( - "ldmxcsr %0\n\t" - "fldcw %1" - : : "m"(mxcsr), "m"(x87cw) - ); - } -}; -} // namespace internal -} // namespace tbb -#endif /* !__TBB_CPU_CTL_ENV_PRESENT */ - -#include "gcc_itsx.h" - -#endif /* __TBB_machine_gcc_ia32_common_H */ diff --git a/lib/3rdParty/tbb/include/tbb/machine/gcc_itsx.h b/lib/3rdParty/tbb/include/tbb/machine/gcc_itsx.h deleted file mode 100644 index caa35441..00000000 --- a/lib/3rdParty/tbb/include/tbb/machine/gcc_itsx.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - 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. - - - - -*/ - -#if !defined(__TBB_machine_H) || defined(__TBB_machine_gcc_itsx_H) -#error Do not #include this internal file directly; use public TBB headers instead. -#endif - -#define __TBB_machine_gcc_itsx_H - -#define __TBB_OP_XACQUIRE 0xF2 -#define __TBB_OP_XRELEASE 0xF3 -#define __TBB_OP_LOCK 0xF0 - -#define __TBB_STRINGIZE_INTERNAL(arg) #arg -#define __TBB_STRINGIZE(arg) __TBB_STRINGIZE_INTERNAL(arg) - -#ifdef __TBB_x86_64 -#define __TBB_r_out "=r" -#else -#define __TBB_r_out "=q" -#endif - -inline static uint8_t __TBB_machine_try_lock_elided( volatile uint8_t* lk ) -{ - uint8_t value = 1; - __asm__ volatile (".byte " __TBB_STRINGIZE(__TBB_OP_XACQUIRE)"; lock; xchgb %0, %1;" - : __TBB_r_out(value), "=m"(*lk) : "0"(value), "m"(*lk) : "memory" ); - return uint8_t(value^1); -} - -inline static void __TBB_machine_try_lock_elided_cancel() -{ - // 'pause' instruction aborts HLE/RTM transactions - __asm__ volatile ("pause\n" : : : "memory" ); -} - -inline static void __TBB_machine_unlock_elided( volatile uint8_t* lk ) -{ - __asm__ volatile (".byte " __TBB_STRINGIZE(__TBB_OP_XRELEASE)"; movb $0, %0" - : "=m"(*lk) : "m"(*lk) : "memory" ); -} - -#if __TBB_TSX_INTRINSICS_PRESENT -#include - -#define __TBB_machine_is_in_transaction _xtest -#define __TBB_machine_begin_transaction _xbegin -#define __TBB_machine_end_transaction _xend -#define __TBB_machine_transaction_conflict_abort() _xabort(0xff) - -#else - -/*! - * Check if the instruction is executed in a transaction or not - */ -inline static bool __TBB_machine_is_in_transaction() -{ - int8_t res = 0; -#if __TBB_x86_32 - __asm__ volatile (".byte 0x0F; .byte 0x01; .byte 0xD6;\n" - "setz %0" : "=q"(res) : : "memory" ); -#else - __asm__ volatile (".byte 0x0F; .byte 0x01; .byte 0xD6;\n" - "setz %0" : "=r"(res) : : "memory" ); -#endif - return res==0; -} - -/*! - * Enter speculative execution mode. - * @return -1 on success - * abort cause ( or 0 ) on abort - */ -inline static uint32_t __TBB_machine_begin_transaction() -{ - uint32_t res = ~uint32_t(0); // success value - __asm__ volatile ("1: .byte 0xC7; .byte 0xF8;\n" // XBEGIN - " .long 2f-1b-6\n" // 2f-1b == difference in addresses of start - // of XBEGIN and the MOVL - // 2f - 1b - 6 == that difference minus the size of the - // XBEGIN instruction. This is the abort offset to - // 2: below. - " jmp 3f\n" // success (leave -1 in res) - "2: movl %%eax,%0\n" // store failure code in res - "3:" - :"=r"(res):"0"(res):"memory","%eax"); - return res; -} - -/*! - * Attempt to commit/end transaction - */ -inline static void __TBB_machine_end_transaction() -{ - __asm__ volatile (".byte 0x0F; .byte 0x01; .byte 0xD5" :::"memory"); // XEND -} - -/* - * aborts with code 0xFF (lock already held) - */ -inline static void __TBB_machine_transaction_conflict_abort() -{ - __asm__ volatile (".byte 0xC6; .byte 0xF8; .byte 0xFF" :::"memory"); -} - -#endif /* __TBB_TSX_INTRINSICS_PRESENT */ diff --git a/lib/3rdParty/tbb/include/tbb/machine/ibm_aix51.h b/lib/3rdParty/tbb/include/tbb/machine/ibm_aix51.h deleted file mode 100644 index a905b4e1..00000000 --- a/lib/3rdParty/tbb/include/tbb/machine/ibm_aix51.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - 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. - - - - -*/ - -// TODO: revise by comparing with mac_ppc.h - -#if !defined(__TBB_machine_H) || defined(__TBB_machine_ibm_aix51_H) -#error Do not #include this internal file directly; use public TBB headers instead. -#endif - -#define __TBB_machine_ibm_aix51_H - -#define __TBB_WORDSIZE 8 -#define __TBB_ENDIANNESS __TBB_ENDIAN_BIG // assumption based on operating system - -#include -#include -#include - -extern "C" { -int32_t __TBB_machine_cas_32 (volatile void* ptr, int32_t value, int32_t comparand); -int64_t __TBB_machine_cas_64 (volatile void* ptr, int64_t value, int64_t comparand); -void __TBB_machine_flush (); -void __TBB_machine_lwsync (); -void __TBB_machine_isync (); -} - -// Mapping of old entry point names retained for the sake of backward binary compatibility -#define __TBB_machine_cmpswp4 __TBB_machine_cas_32 -#define __TBB_machine_cmpswp8 __TBB_machine_cas_64 - -#define __TBB_Yield() sched_yield() - -#define __TBB_USE_GENERIC_PART_WORD_CAS 1 -#define __TBB_USE_GENERIC_FETCH_ADD 1 -#define __TBB_USE_GENERIC_FETCH_STORE 1 -#define __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE 1 -#define __TBB_USE_GENERIC_RELAXED_LOAD_STORE 1 -#define __TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE 1 - -#if __GNUC__ - #define __TBB_control_consistency_helper() __asm__ __volatile__( "isync": : :"memory") - #define __TBB_acquire_consistency_helper() __asm__ __volatile__("lwsync": : :"memory") - #define __TBB_release_consistency_helper() __asm__ __volatile__("lwsync": : :"memory") - #define __TBB_full_memory_fence() __asm__ __volatile__( "sync": : :"memory") -#else - // IBM C++ Compiler does not support inline assembly - // TODO: Since XL 9.0 or earlier GCC syntax is supported. Replace with more - // lightweight implementation (like in mac_ppc.h) - #define __TBB_control_consistency_helper() __TBB_machine_isync () - #define __TBB_acquire_consistency_helper() __TBB_machine_lwsync () - #define __TBB_release_consistency_helper() __TBB_machine_lwsync () - #define __TBB_full_memory_fence() __TBB_machine_flush () -#endif diff --git a/lib/3rdParty/tbb/include/tbb/machine/icc_generic.h b/lib/3rdParty/tbb/include/tbb/machine/icc_generic.h deleted file mode 100644 index 04863000..00000000 --- a/lib/3rdParty/tbb/include/tbb/machine/icc_generic.h +++ /dev/null @@ -1,262 +0,0 @@ -/* - 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. - - - - -*/ - -#if !defined(__TBB_machine_H) || defined(__TBB_machine_icc_generic_H) -#error Do not #include this internal file directly; use public TBB headers instead. -#endif - -#if ! __TBB_ICC_BUILTIN_ATOMICS_PRESENT - #error "Intel C++ Compiler of at least 12.0 version is needed to use ICC intrinsics port" -#endif - -#define __TBB_machine_icc_generic_H - -//ICC mimics the "native" target compiler -#if _MSC_VER - #include "msvc_ia32_common.h" -#else - #include "gcc_ia32_common.h" -#endif - -//TODO: Make __TBB_WORDSIZE macro optional for ICC intrinsics port. -//As compiler intrinsics are used for all the operations it is possible to do. - -#if __TBB_x86_32 - #define __TBB_WORDSIZE 4 -#else - #define __TBB_WORDSIZE 8 -#endif -#define __TBB_ENDIANNESS __TBB_ENDIAN_LITTLE - -//__TBB_compiler_fence() defined just in case, as it seems not to be used on its own anywhere else -#ifndef __TBB_compiler_fence -#if _MSC_VER - //TODO: any way to use same intrinsics on windows and linux? - #pragma intrinsic(_ReadWriteBarrier) - #define __TBB_compiler_fence() _ReadWriteBarrier() -#else - #define __TBB_compiler_fence() __asm__ __volatile__("": : :"memory") -#endif -#endif - -#ifndef __TBB_full_memory_fence -#if _MSC_VER - //TODO: any way to use same intrinsics on windows and linux? - #pragma intrinsic(_mm_mfence) - #define __TBB_full_memory_fence() _mm_mfence() -#else - #define __TBB_full_memory_fence() __asm__ __volatile__("mfence": : :"memory") -#endif -#endif - -#ifndef __TBB_control_consistency_helper -#define __TBB_control_consistency_helper() __TBB_compiler_fence() -#endif - -namespace tbb { namespace internal { -//TODO: is there any way to reuse definition of memory_order enum from ICC instead of copy paste. -//however it seems unlikely that ICC will silently change exact enum values, as they are defined -//in the ISO exactly like this. -//TODO: add test that exact values of the enum are same as in the ISO C++11 -typedef enum memory_order { - memory_order_relaxed, memory_order_consume, memory_order_acquire, - memory_order_release, memory_order_acq_rel, memory_order_seq_cst -} memory_order; - -namespace icc_intrinsics_port { - template - T convert_argument(T value){ - return value; - } - //The overload below is needed to have explicit conversion of pointer to void* in argument list. - //compiler bug? - //TODO: add according broken macro and recheck with ICC 13.0 if the overload is still needed - template - void* convert_argument(T* value){ - return (void*)value; - } -} -//TODO: code below is a bit repetitive, consider simplifying it -template -struct machine_load_store { - static T load_with_acquire ( const volatile T& location ) { - return __atomic_load_explicit(&location, memory_order_acquire); - } - static void store_with_release ( volatile T &location, T value ) { - __atomic_store_explicit(&location, icc_intrinsics_port::convert_argument(value), memory_order_release); - } -}; - -template -struct machine_load_store_relaxed { - static inline T load ( const T& location ) { - return __atomic_load_explicit(&location, memory_order_relaxed); - } - static inline void store ( T& location, T value ) { - __atomic_store_explicit(&location, icc_intrinsics_port::convert_argument(value), memory_order_relaxed); - } -}; - -template -struct machine_load_store_seq_cst { - static T load ( const volatile T& location ) { - return __atomic_load_explicit(&location, memory_order_seq_cst); - } - - static void store ( volatile T &location, T value ) { - __atomic_store_explicit(&location, value, memory_order_seq_cst); - } -}; - -}} // namespace tbb::internal - -namespace tbb{ namespace internal { namespace icc_intrinsics_port{ - typedef enum memory_order_map { - relaxed = memory_order_relaxed, - acquire = memory_order_acquire, - release = memory_order_release, - full_fence= memory_order_seq_cst - } memory_order_map; -}}}// namespace tbb::internal - -#define __TBB_MACHINE_DEFINE_ATOMICS(S,T,M) \ -inline T __TBB_machine_cmpswp##S##M( volatile void *ptr, T value, T comparand ) { \ - __atomic_compare_exchange_strong_explicit( \ - (T*)ptr \ - ,&comparand \ - ,value \ - , tbb::internal::icc_intrinsics_port::M \ - , tbb::internal::icc_intrinsics_port::M); \ - return comparand; \ -} \ - \ -inline T __TBB_machine_fetchstore##S##M(volatile void *ptr, T value) { \ - return __atomic_exchange_explicit((T*)ptr, value, tbb::internal::icc_intrinsics_port::M); \ -} \ - \ -inline T __TBB_machine_fetchadd##S##M(volatile void *ptr, T value) { \ - return __atomic_fetch_add_explicit((T*)ptr, value, tbb::internal::icc_intrinsics_port::M); \ -} \ - -__TBB_MACHINE_DEFINE_ATOMICS(1,tbb::internal::int8_t, full_fence) -__TBB_MACHINE_DEFINE_ATOMICS(1,tbb::internal::int8_t, acquire) -__TBB_MACHINE_DEFINE_ATOMICS(1,tbb::internal::int8_t, release) -__TBB_MACHINE_DEFINE_ATOMICS(1,tbb::internal::int8_t, relaxed) - -__TBB_MACHINE_DEFINE_ATOMICS(2,tbb::internal::int16_t, full_fence) -__TBB_MACHINE_DEFINE_ATOMICS(2,tbb::internal::int16_t, acquire) -__TBB_MACHINE_DEFINE_ATOMICS(2,tbb::internal::int16_t, release) -__TBB_MACHINE_DEFINE_ATOMICS(2,tbb::internal::int16_t, relaxed) - -__TBB_MACHINE_DEFINE_ATOMICS(4,tbb::internal::int32_t, full_fence) -__TBB_MACHINE_DEFINE_ATOMICS(4,tbb::internal::int32_t, acquire) -__TBB_MACHINE_DEFINE_ATOMICS(4,tbb::internal::int32_t, release) -__TBB_MACHINE_DEFINE_ATOMICS(4,tbb::internal::int32_t, relaxed) - -__TBB_MACHINE_DEFINE_ATOMICS(8,tbb::internal::int64_t, full_fence) -__TBB_MACHINE_DEFINE_ATOMICS(8,tbb::internal::int64_t, acquire) -__TBB_MACHINE_DEFINE_ATOMICS(8,tbb::internal::int64_t, release) -__TBB_MACHINE_DEFINE_ATOMICS(8,tbb::internal::int64_t, relaxed) - - -#undef __TBB_MACHINE_DEFINE_ATOMICS - -#define __TBB_USE_FENCED_ATOMICS 1 - -namespace tbb { namespace internal { -#if __TBB_FORCE_64BIT_ALIGNMENT_BROKEN -__TBB_MACHINE_DEFINE_LOAD8_GENERIC_FENCED(full_fence) -__TBB_MACHINE_DEFINE_STORE8_GENERIC_FENCED(full_fence) - -__TBB_MACHINE_DEFINE_LOAD8_GENERIC_FENCED(acquire) -__TBB_MACHINE_DEFINE_STORE8_GENERIC_FENCED(release) - -__TBB_MACHINE_DEFINE_LOAD8_GENERIC_FENCED(relaxed) -__TBB_MACHINE_DEFINE_STORE8_GENERIC_FENCED(relaxed) - -template -struct machine_load_store { - static T load_with_acquire ( const volatile T& location ) { - if( tbb::internal::is_aligned(&location,8)) { - return __atomic_load_explicit(&location, memory_order_acquire); - } else { - return __TBB_machine_generic_load8acquire(&location); - } - } - static void store_with_release ( volatile T &location, T value ) { - if( tbb::internal::is_aligned(&location,8)) { - __atomic_store_explicit(&location, icc_intrinsics_port::convert_argument(value), memory_order_release); - } else { - return __TBB_machine_generic_store8release(&location,value); - } - } -}; - -template -struct machine_load_store_relaxed { - static T load( const volatile T& location ) { - if( tbb::internal::is_aligned(&location,8)) { - return __atomic_load_explicit(&location, memory_order_relaxed); - } else { - return __TBB_machine_generic_load8relaxed(&location); - } - } - static void store( volatile T &location, T value ) { - if( tbb::internal::is_aligned(&location,8)) { - __atomic_store_explicit(&location, icc_intrinsics_port::convert_argument(value), memory_order_relaxed); - } else { - return __TBB_machine_generic_store8relaxed(&location,value); - } - } -}; - -template -struct machine_load_store_seq_cst { - static T load ( const volatile T& location ) { - if( tbb::internal::is_aligned(&location,8)) { - return __atomic_load_explicit(&location, memory_order_seq_cst); - } else { - return __TBB_machine_generic_load8full_fence(&location); - } - - } - - static void store ( volatile T &location, T value ) { - if( tbb::internal::is_aligned(&location,8)) { - __atomic_store_explicit(&location, value, memory_order_seq_cst); - } else { - return __TBB_machine_generic_store8full_fence(&location,value); - } - - } -}; - -#endif -}} // namespace tbb::internal -template -inline void __TBB_machine_OR( T *operand, T addend ) { - __atomic_fetch_or_explicit(operand, addend, tbb::internal::memory_order_seq_cst); -} - -template -inline void __TBB_machine_AND( T *operand, T addend ) { - __atomic_fetch_and_explicit(operand, addend, tbb::internal::memory_order_seq_cst); -} - diff --git a/lib/3rdParty/tbb/include/tbb/machine/linux_common.h b/lib/3rdParty/tbb/include/tbb/machine/linux_common.h deleted file mode 100644 index 4d2d355b..00000000 --- a/lib/3rdParty/tbb/include/tbb/machine/linux_common.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - 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_machine_H -#error Do not #include this internal file directly; use public TBB headers instead. -#endif - -#include -#define __TBB_Yield() sched_yield() - -#include -/* Futex definitions */ -#include - -#if defined(SYS_futex) - -#define __TBB_USE_FUTEX 1 -#include -#include -// Unfortunately, some versions of Linux do not have a header that defines FUTEX_WAIT and FUTEX_WAKE. - -#ifdef FUTEX_WAIT -#define __TBB_FUTEX_WAIT FUTEX_WAIT -#else -#define __TBB_FUTEX_WAIT 0 -#endif - -#ifdef FUTEX_WAKE -#define __TBB_FUTEX_WAKE FUTEX_WAKE -#else -#define __TBB_FUTEX_WAKE 1 -#endif - -#ifndef __TBB_ASSERT -#error machine specific headers must be included after tbb_stddef.h -#endif - -namespace tbb { - -namespace internal { - -inline int futex_wait( void *futex, int comparand ) { - int r = syscall( SYS_futex,futex,__TBB_FUTEX_WAIT,comparand,NULL,NULL,0 ); -#if TBB_USE_ASSERT - int e = errno; - __TBB_ASSERT( r==0||r==EWOULDBLOCK||(r==-1&&(e==EAGAIN||e==EINTR)), "futex_wait failed." ); -#endif /* TBB_USE_ASSERT */ - return r; -} - -inline int futex_wakeup_one( void *futex ) { - int r = ::syscall( SYS_futex,futex,__TBB_FUTEX_WAKE,1,NULL,NULL,0 ); - __TBB_ASSERT( r==0||r==1, "futex_wakeup_one: more than one thread woken up?" ); - return r; -} - -inline int futex_wakeup_all( void *futex ) { - int r = ::syscall( SYS_futex,futex,__TBB_FUTEX_WAKE,INT_MAX,NULL,NULL,0 ); - __TBB_ASSERT( r>=0, "futex_wakeup_all: error in waking up threads" ); - return r; -} - -} /* namespace internal */ - -} /* namespace tbb */ - -#endif /* SYS_futex */ diff --git a/lib/3rdParty/tbb/include/tbb/machine/linux_ia32.h b/lib/3rdParty/tbb/include/tbb/machine/linux_ia32.h deleted file mode 100644 index 932d343d..00000000 --- a/lib/3rdParty/tbb/include/tbb/machine/linux_ia32.h +++ /dev/null @@ -1,232 +0,0 @@ -/* - 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. - - - - -*/ - -#if !defined(__TBB_machine_H) || defined(__TBB_machine_linux_ia32_H) -#error Do not #include this internal file directly; use public TBB headers instead. -#endif - -#define __TBB_machine_linux_ia32_H - -#include -#include "gcc_ia32_common.h" - -#define __TBB_WORDSIZE 4 -#define __TBB_ENDIANNESS __TBB_ENDIAN_LITTLE - -#define __TBB_compiler_fence() __asm__ __volatile__("": : :"memory") -#define __TBB_control_consistency_helper() __TBB_compiler_fence() -#define __TBB_acquire_consistency_helper() __TBB_compiler_fence() -#define __TBB_release_consistency_helper() __TBB_compiler_fence() -#define __TBB_full_memory_fence() __asm__ __volatile__("mfence": : :"memory") - -#if __TBB_ICC_ASM_VOLATILE_BROKEN -#define __TBB_VOLATILE -#else -#define __TBB_VOLATILE volatile -#endif - -#define __TBB_MACHINE_DEFINE_ATOMICS(S,T,X,R) \ -static inline T __TBB_machine_cmpswp##S (volatile void *ptr, T value, T comparand ) \ -{ \ - T result; \ - \ - __asm__ __volatile__("lock\ncmpxchg" X " %2,%1" \ - : "=a"(result), "=m"(*(__TBB_VOLATILE T*)ptr) \ - : "q"(value), "0"(comparand), "m"(*(__TBB_VOLATILE T*)ptr) \ - : "memory"); \ - return result; \ -} \ - \ -static inline T __TBB_machine_fetchadd##S(volatile void *ptr, T addend) \ -{ \ - T result; \ - __asm__ __volatile__("lock\nxadd" X " %0,%1" \ - : R (result), "=m"(*(__TBB_VOLATILE T*)ptr) \ - : "0"(addend), "m"(*(__TBB_VOLATILE T*)ptr) \ - : "memory"); \ - return result; \ -} \ - \ -static inline T __TBB_machine_fetchstore##S(volatile void *ptr, T value) \ -{ \ - T result; \ - __asm__ __volatile__("lock\nxchg" X " %0,%1" \ - : R (result), "=m"(*(__TBB_VOLATILE T*)ptr) \ - : "0"(value), "m"(*(__TBB_VOLATILE T*)ptr) \ - : "memory"); \ - return result; \ -} \ - -__TBB_MACHINE_DEFINE_ATOMICS(1,int8_t,"","=q") -__TBB_MACHINE_DEFINE_ATOMICS(2,int16_t,"","=r") -__TBB_MACHINE_DEFINE_ATOMICS(4,int32_t,"l","=r") - -#if __INTEL_COMPILER -#pragma warning( push ) -// reference to EBX in a function requiring stack alignment -#pragma warning( disable: 998 ) -#endif - -#if __TBB_GCC_CAS8_BUILTIN_INLINING_BROKEN -#define __TBB_IA32_CAS8_NOINLINE __attribute__ ((noinline)) -#else -#define __TBB_IA32_CAS8_NOINLINE -#endif - -static inline __TBB_IA32_CAS8_NOINLINE int64_t __TBB_machine_cmpswp8 (volatile void *ptr, int64_t value, int64_t comparand ) { -//TODO: remove the extra part of condition once __TBB_GCC_BUILTIN_ATOMICS_PRESENT is lowered to gcc version 4.1.2 -#if (__TBB_GCC_BUILTIN_ATOMICS_PRESENT || (__TBB_GCC_VERSION >= 40102)) && !__TBB_GCC_64BIT_ATOMIC_BUILTINS_BROKEN - return __sync_val_compare_and_swap( reinterpret_cast(ptr), comparand, value ); -#else /* !__TBB_GCC_BUILTIN_ATOMICS_PRESENT */ - //TODO: look like ICC 13.0 has some issues with this code, investigate it more deeply - int64_t result; - union { - int64_t i64; - int32_t i32[2]; - }; - i64 = value; -#if __PIC__ - /* compiling position-independent code */ - // EBX register preserved for compliance with position-independent code rules on IA32 - int32_t tmp; - __asm__ __volatile__ ( - "movl %%ebx,%2\n\t" - "movl %5,%%ebx\n\t" -#if __GNUC__==3 - "lock\n\t cmpxchg8b %1\n\t" -#else - "lock\n\t cmpxchg8b (%3)\n\t" -#endif - "movl %2,%%ebx" - : "=A"(result) - , "=m"(*(__TBB_VOLATILE int64_t *)ptr) - , "=m"(tmp) -#if __GNUC__==3 - : "m"(*(__TBB_VOLATILE int64_t *)ptr) -#else - : "SD"(ptr) -#endif - , "0"(comparand) - , "m"(i32[0]), "c"(i32[1]) - : "memory" -#if __INTEL_COMPILER - ,"ebx" -#endif - ); -#else /* !__PIC__ */ - __asm__ __volatile__ ( - "lock\n\t cmpxchg8b %1\n\t" - : "=A"(result), "=m"(*(__TBB_VOLATILE int64_t *)ptr) - : "m"(*(__TBB_VOLATILE int64_t *)ptr) - , "0"(comparand) - , "b"(i32[0]), "c"(i32[1]) - : "memory" - ); -#endif /* __PIC__ */ - return result; -#endif /* !__TBB_GCC_BUILTIN_ATOMICS_PRESENT */ -} - -#undef __TBB_IA32_CAS8_NOINLINE - -#if __INTEL_COMPILER -#pragma warning( pop ) -#endif // warning 998 is back - -static inline void __TBB_machine_or( volatile void *ptr, uint32_t addend ) { - __asm__ __volatile__("lock\norl %1,%0" : "=m"(*(__TBB_VOLATILE uint32_t *)ptr) : "r"(addend), "m"(*(__TBB_VOLATILE uint32_t *)ptr) : "memory"); -} - -static inline void __TBB_machine_and( volatile void *ptr, uint32_t addend ) { - __asm__ __volatile__("lock\nandl %1,%0" : "=m"(*(__TBB_VOLATILE uint32_t *)ptr) : "r"(addend), "m"(*(__TBB_VOLATILE uint32_t *)ptr) : "memory"); -} - -//TODO: Check if it possible and profitable for IA-32 architecture on (Linux* and Windows*) -//to use of 64-bit load/store via floating point registers together with full fence -//for sequentially consistent load/store, instead of CAS. - -#if __clang__ -#define __TBB_fildq "fildll" -#define __TBB_fistpq "fistpll" -#else -#define __TBB_fildq "fildq" -#define __TBB_fistpq "fistpq" -#endif - -static inline int64_t __TBB_machine_aligned_load8 (const volatile void *ptr) { - __TBB_ASSERT(tbb::internal::is_aligned(ptr,8),"__TBB_machine_aligned_load8 should be used with 8 byte aligned locations only \n"); - int64_t result; - __asm__ __volatile__ ( __TBB_fildq " %1\n\t" - __TBB_fistpq " %0" : "=m"(result) : "m"(*(const __TBB_VOLATILE uint64_t*)ptr) : "memory" ); - return result; -} - -static inline void __TBB_machine_aligned_store8 (volatile void *ptr, int64_t value ) { - __TBB_ASSERT(tbb::internal::is_aligned(ptr,8),"__TBB_machine_aligned_store8 should be used with 8 byte aligned locations only \n"); - // Aligned store - __asm__ __volatile__ ( __TBB_fildq " %1\n\t" - __TBB_fistpq " %0" : "=m"(*(__TBB_VOLATILE int64_t*)ptr) : "m"(value) : "memory" ); -} - -static inline int64_t __TBB_machine_load8 (const volatile void *ptr) { -#if __TBB_FORCE_64BIT_ALIGNMENT_BROKEN - if( tbb::internal::is_aligned(ptr,8)) { -#endif - return __TBB_machine_aligned_load8(ptr); -#if __TBB_FORCE_64BIT_ALIGNMENT_BROKEN - } else { - // Unaligned load - return __TBB_machine_cmpswp8(const_cast(ptr),0,0); - } -#endif -} - -//! Handles misaligned 8-byte store -/** Defined in tbb_misc.cpp */ -extern "C" void __TBB_machine_store8_slow( volatile void *ptr, int64_t value ); -extern "C" void __TBB_machine_store8_slow_perf_warning( volatile void *ptr ); - -static inline void __TBB_machine_store8(volatile void *ptr, int64_t value) { -#if __TBB_FORCE_64BIT_ALIGNMENT_BROKEN - if( tbb::internal::is_aligned(ptr,8)) { -#endif - __TBB_machine_aligned_store8(ptr,value); -#if __TBB_FORCE_64BIT_ALIGNMENT_BROKEN - } else { - // Unaligned store -#if TBB_USE_PERFORMANCE_WARNINGS - __TBB_machine_store8_slow_perf_warning(ptr); -#endif /* TBB_USE_PERFORMANCE_WARNINGS */ - __TBB_machine_store8_slow(ptr,value); - } -#endif -} - -// Machine specific atomic operations -#define __TBB_AtomicOR(P,V) __TBB_machine_or(P,V) -#define __TBB_AtomicAND(P,V) __TBB_machine_and(P,V) - -#define __TBB_USE_GENERIC_DWORD_FETCH_ADD 1 -#define __TBB_USE_GENERIC_DWORD_FETCH_STORE 1 -#define __TBB_USE_FETCHSTORE_AS_FULL_FENCED_STORE 1 -#define __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE 1 -#define __TBB_USE_GENERIC_RELAXED_LOAD_STORE 1 -#define __TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE 1 - diff --git a/lib/3rdParty/tbb/include/tbb/machine/linux_ia64.h b/lib/3rdParty/tbb/include/tbb/machine/linux_ia64.h deleted file mode 100644 index f4772288..00000000 --- a/lib/3rdParty/tbb/include/tbb/machine/linux_ia64.h +++ /dev/null @@ -1,181 +0,0 @@ -/* - 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. - - - - -*/ - -#if !defined(__TBB_machine_H) || defined(__TBB_machine_linux_ia64_H) -#error Do not #include this internal file directly; use public TBB headers instead. -#endif - -#define __TBB_machine_linux_ia64_H - -#include -#include - -#define __TBB_WORDSIZE 8 -#define __TBB_ENDIANNESS __TBB_ENDIAN_LITTLE - -#if __INTEL_COMPILER - #define __TBB_compiler_fence() - #define __TBB_control_consistency_helper() __TBB_compiler_fence() - #define __TBB_acquire_consistency_helper() - #define __TBB_release_consistency_helper() - #define __TBB_full_memory_fence() __mf() -#else - #define __TBB_compiler_fence() __asm__ __volatile__("": : :"memory") - #define __TBB_control_consistency_helper() __TBB_compiler_fence() - // Even though GCC imbues volatile loads with acquire semantics, it sometimes moves - // loads over the acquire fence. The following helpers stop such incorrect code motion. - #define __TBB_acquire_consistency_helper() __TBB_compiler_fence() - #define __TBB_release_consistency_helper() __TBB_compiler_fence() - #define __TBB_full_memory_fence() __asm__ __volatile__("mf": : :"memory") -#endif /* !__INTEL_COMPILER */ - -// Most of the functions will be in a .s file -// TODO: revise dynamic_link, memory pools and etc. if the library dependency is removed. - -extern "C" { - int8_t __TBB_machine_fetchadd1__TBB_full_fence (volatile void *ptr, int8_t addend); - int8_t __TBB_machine_fetchadd1acquire(volatile void *ptr, int8_t addend); - int8_t __TBB_machine_fetchadd1release(volatile void *ptr, int8_t addend); - - int16_t __TBB_machine_fetchadd2__TBB_full_fence (volatile void *ptr, int16_t addend); - int16_t __TBB_machine_fetchadd2acquire(volatile void *ptr, int16_t addend); - int16_t __TBB_machine_fetchadd2release(volatile void *ptr, int16_t addend); - - int32_t __TBB_machine_fetchadd4__TBB_full_fence (volatile void *ptr, int32_t value); - int32_t __TBB_machine_fetchadd4acquire(volatile void *ptr, int32_t addend); - int32_t __TBB_machine_fetchadd4release(volatile void *ptr, int32_t addend); - - int64_t __TBB_machine_fetchadd8__TBB_full_fence (volatile void *ptr, int64_t value); - int64_t __TBB_machine_fetchadd8acquire(volatile void *ptr, int64_t addend); - int64_t __TBB_machine_fetchadd8release(volatile void *ptr, int64_t addend); - - int8_t __TBB_machine_fetchstore1__TBB_full_fence (volatile void *ptr, int8_t value); - int8_t __TBB_machine_fetchstore1acquire(volatile void *ptr, int8_t value); - int8_t __TBB_machine_fetchstore1release(volatile void *ptr, int8_t value); - - int16_t __TBB_machine_fetchstore2__TBB_full_fence (volatile void *ptr, int16_t value); - int16_t __TBB_machine_fetchstore2acquire(volatile void *ptr, int16_t value); - int16_t __TBB_machine_fetchstore2release(volatile void *ptr, int16_t value); - - int32_t __TBB_machine_fetchstore4__TBB_full_fence (volatile void *ptr, int32_t value); - int32_t __TBB_machine_fetchstore4acquire(volatile void *ptr, int32_t value); - int32_t __TBB_machine_fetchstore4release(volatile void *ptr, int32_t value); - - int64_t __TBB_machine_fetchstore8__TBB_full_fence (volatile void *ptr, int64_t value); - int64_t __TBB_machine_fetchstore8acquire(volatile void *ptr, int64_t value); - int64_t __TBB_machine_fetchstore8release(volatile void *ptr, int64_t value); - - int8_t __TBB_machine_cmpswp1__TBB_full_fence (volatile void *ptr, int8_t value, int8_t comparand); - int8_t __TBB_machine_cmpswp1acquire(volatile void *ptr, int8_t value, int8_t comparand); - int8_t __TBB_machine_cmpswp1release(volatile void *ptr, int8_t value, int8_t comparand); - - int16_t __TBB_machine_cmpswp2__TBB_full_fence (volatile void *ptr, int16_t value, int16_t comparand); - int16_t __TBB_machine_cmpswp2acquire(volatile void *ptr, int16_t value, int16_t comparand); - int16_t __TBB_machine_cmpswp2release(volatile void *ptr, int16_t value, int16_t comparand); - - int32_t __TBB_machine_cmpswp4__TBB_full_fence (volatile void *ptr, int32_t value, int32_t comparand); - int32_t __TBB_machine_cmpswp4acquire(volatile void *ptr, int32_t value, int32_t comparand); - int32_t __TBB_machine_cmpswp4release(volatile void *ptr, int32_t value, int32_t comparand); - - int64_t __TBB_machine_cmpswp8__TBB_full_fence (volatile void *ptr, int64_t value, int64_t comparand); - int64_t __TBB_machine_cmpswp8acquire(volatile void *ptr, int64_t value, int64_t comparand); - int64_t __TBB_machine_cmpswp8release(volatile void *ptr, int64_t value, int64_t comparand); - - int64_t __TBB_machine_lg(uint64_t value); - void __TBB_machine_pause(int32_t delay); - bool __TBB_machine_trylockbyte( volatile unsigned char &ptr ); - int64_t __TBB_machine_lockbyte( volatile unsigned char &ptr ); - - //! Retrieves the current RSE backing store pointer. IA64 specific. - void* __TBB_get_bsp(); - - int32_t __TBB_machine_load1_relaxed(const void *ptr); - int32_t __TBB_machine_load2_relaxed(const void *ptr); - int32_t __TBB_machine_load4_relaxed(const void *ptr); - int64_t __TBB_machine_load8_relaxed(const void *ptr); - - void __TBB_machine_store1_relaxed(void *ptr, int32_t value); - void __TBB_machine_store2_relaxed(void *ptr, int32_t value); - void __TBB_machine_store4_relaxed(void *ptr, int32_t value); - void __TBB_machine_store8_relaxed(void *ptr, int64_t value); -} // extern "C" - -// Mapping old entry points to the names corresponding to the new full_fence identifier. -#define __TBB_machine_fetchadd1full_fence __TBB_machine_fetchadd1__TBB_full_fence -#define __TBB_machine_fetchadd2full_fence __TBB_machine_fetchadd2__TBB_full_fence -#define __TBB_machine_fetchadd4full_fence __TBB_machine_fetchadd4__TBB_full_fence -#define __TBB_machine_fetchadd8full_fence __TBB_machine_fetchadd8__TBB_full_fence -#define __TBB_machine_fetchstore1full_fence __TBB_machine_fetchstore1__TBB_full_fence -#define __TBB_machine_fetchstore2full_fence __TBB_machine_fetchstore2__TBB_full_fence -#define __TBB_machine_fetchstore4full_fence __TBB_machine_fetchstore4__TBB_full_fence -#define __TBB_machine_fetchstore8full_fence __TBB_machine_fetchstore8__TBB_full_fence -#define __TBB_machine_cmpswp1full_fence __TBB_machine_cmpswp1__TBB_full_fence -#define __TBB_machine_cmpswp2full_fence __TBB_machine_cmpswp2__TBB_full_fence -#define __TBB_machine_cmpswp4full_fence __TBB_machine_cmpswp4__TBB_full_fence -#define __TBB_machine_cmpswp8full_fence __TBB_machine_cmpswp8__TBB_full_fence - -// Mapping relaxed operations to the entry points implementing them. -/** On IA64 RMW operations implicitly have acquire semantics. Thus one cannot - actually have completely relaxed RMW operation here. **/ -#define __TBB_machine_fetchadd1relaxed __TBB_machine_fetchadd1acquire -#define __TBB_machine_fetchadd2relaxed __TBB_machine_fetchadd2acquire -#define __TBB_machine_fetchadd4relaxed __TBB_machine_fetchadd4acquire -#define __TBB_machine_fetchadd8relaxed __TBB_machine_fetchadd8acquire -#define __TBB_machine_fetchstore1relaxed __TBB_machine_fetchstore1acquire -#define __TBB_machine_fetchstore2relaxed __TBB_machine_fetchstore2acquire -#define __TBB_machine_fetchstore4relaxed __TBB_machine_fetchstore4acquire -#define __TBB_machine_fetchstore8relaxed __TBB_machine_fetchstore8acquire -#define __TBB_machine_cmpswp1relaxed __TBB_machine_cmpswp1acquire -#define __TBB_machine_cmpswp2relaxed __TBB_machine_cmpswp2acquire -#define __TBB_machine_cmpswp4relaxed __TBB_machine_cmpswp4acquire -#define __TBB_machine_cmpswp8relaxed __TBB_machine_cmpswp8acquire - -#define __TBB_MACHINE_DEFINE_ATOMICS(S,V) \ - template \ - struct machine_load_store_relaxed { \ - static inline T load ( const T& location ) { \ - return (T)__TBB_machine_load##S##_relaxed(&location); \ - } \ - static inline void store ( T& location, T value ) { \ - __TBB_machine_store##S##_relaxed(&location, (V)value); \ - } \ - } - -namespace tbb { -namespace internal { - __TBB_MACHINE_DEFINE_ATOMICS(1,int8_t); - __TBB_MACHINE_DEFINE_ATOMICS(2,int16_t); - __TBB_MACHINE_DEFINE_ATOMICS(4,int32_t); - __TBB_MACHINE_DEFINE_ATOMICS(8,int64_t); -}} // namespaces internal, tbb - -#undef __TBB_MACHINE_DEFINE_ATOMICS - -#define __TBB_USE_FENCED_ATOMICS 1 -#define __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE 1 -#define __TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE 1 - -// Definition of Lock functions -#define __TBB_TryLockByte(P) __TBB_machine_trylockbyte(P) -#define __TBB_LockByte(P) __TBB_machine_lockbyte(P) - -// Definition of other utility functions -#define __TBB_Pause(V) __TBB_machine_pause(V) -#define __TBB_Log2(V) __TBB_machine_lg(V) diff --git a/lib/3rdParty/tbb/include/tbb/machine/linux_intel64.h b/lib/3rdParty/tbb/include/tbb/machine/linux_intel64.h deleted file mode 100644 index 02153c2a..00000000 --- a/lib/3rdParty/tbb/include/tbb/machine/linux_intel64.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - 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. - - - - -*/ - -#if !defined(__TBB_machine_H) || defined(__TBB_machine_linux_intel64_H) -#error Do not #include this internal file directly; use public TBB headers instead. -#endif - -#define __TBB_machine_linux_intel64_H - -#include -#include "gcc_ia32_common.h" - -#define __TBB_WORDSIZE 8 -#define __TBB_ENDIANNESS __TBB_ENDIAN_LITTLE - -#define __TBB_compiler_fence() __asm__ __volatile__("": : :"memory") -#define __TBB_control_consistency_helper() __TBB_compiler_fence() -#define __TBB_acquire_consistency_helper() __TBB_compiler_fence() -#define __TBB_release_consistency_helper() __TBB_compiler_fence() - -#ifndef __TBB_full_memory_fence -#define __TBB_full_memory_fence() __asm__ __volatile__("mfence": : :"memory") -#endif - -#define __TBB_MACHINE_DEFINE_ATOMICS(S,T,X) \ -static inline T __TBB_machine_cmpswp##S (volatile void *ptr, T value, T comparand ) \ -{ \ - T result; \ - \ - __asm__ __volatile__("lock\ncmpxchg" X " %2,%1" \ - : "=a"(result), "=m"(*(volatile T*)ptr) \ - : "q"(value), "0"(comparand), "m"(*(volatile T*)ptr) \ - : "memory"); \ - return result; \ -} \ - \ -static inline T __TBB_machine_fetchadd##S(volatile void *ptr, T addend) \ -{ \ - T result; \ - __asm__ __volatile__("lock\nxadd" X " %0,%1" \ - : "=r"(result),"=m"(*(volatile T*)ptr) \ - : "0"(addend), "m"(*(volatile T*)ptr) \ - : "memory"); \ - return result; \ -} \ - \ -static inline T __TBB_machine_fetchstore##S(volatile void *ptr, T value) \ -{ \ - T result; \ - __asm__ __volatile__("lock\nxchg" X " %0,%1" \ - : "=r"(result),"=m"(*(volatile T*)ptr) \ - : "0"(value), "m"(*(volatile T*)ptr) \ - : "memory"); \ - return result; \ -} \ - -__TBB_MACHINE_DEFINE_ATOMICS(1,int8_t,"") -__TBB_MACHINE_DEFINE_ATOMICS(2,int16_t,"") -__TBB_MACHINE_DEFINE_ATOMICS(4,int32_t,"") -__TBB_MACHINE_DEFINE_ATOMICS(8,int64_t,"q") - -#undef __TBB_MACHINE_DEFINE_ATOMICS - -static inline void __TBB_machine_or( volatile void *ptr, uint64_t value ) { - __asm__ __volatile__("lock\norq %1,%0" : "=m"(*(volatile uint64_t*)ptr) : "r"(value), "m"(*(volatile uint64_t*)ptr) : "memory"); -} - -static inline void __TBB_machine_and( volatile void *ptr, uint64_t value ) { - __asm__ __volatile__("lock\nandq %1,%0" : "=m"(*(volatile uint64_t*)ptr) : "r"(value), "m"(*(volatile uint64_t*)ptr) : "memory"); -} - -#define __TBB_AtomicOR(P,V) __TBB_machine_or(P,V) -#define __TBB_AtomicAND(P,V) __TBB_machine_and(P,V) - -#define __TBB_USE_FETCHSTORE_AS_FULL_FENCED_STORE 1 -#define __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE 1 -#define __TBB_USE_GENERIC_RELAXED_LOAD_STORE 1 -#define __TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE 1 - diff --git a/lib/3rdParty/tbb/include/tbb/machine/mac_ppc.h b/lib/3rdParty/tbb/include/tbb/machine/mac_ppc.h deleted file mode 100644 index 13f387b4..00000000 --- a/lib/3rdParty/tbb/include/tbb/machine/mac_ppc.h +++ /dev/null @@ -1,313 +0,0 @@ -/* - 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. - - - - -*/ - -#if !defined(__TBB_machine_H) || defined(__TBB_machine_gcc_power_H) -#error Do not #include this internal file directly; use public TBB headers instead. -#endif - -#define __TBB_machine_gcc_power_H - -#include -#include - -// TODO: rename to gcc_power.h? -// This file is for Power Architecture with compilers supporting GNU inline-assembler syntax (currently GNU g++ and IBM XL). -// Note that XL V9.0 (sometimes?) has trouble dealing with empty input and/or clobber lists, so they should be avoided. - -#if __powerpc64__ || __ppc64__ - // IBM XL documents __powerpc64__ (and __PPC64__). - // Apple documents __ppc64__ (with __ppc__ only on 32-bit). - #define __TBB_WORDSIZE 8 -#else - #define __TBB_WORDSIZE 4 -#endif - -// Traditionally Power Architecture is big-endian. -// Little-endian could be just an address manipulation (compatibility with TBB not verified), -// or normal little-endian (on more recent systems). Embedded PowerPC systems may support -// page-specific endianness, but then one endianness must be hidden from TBB so that it still sees only one. -#if __BIG_ENDIAN__ || (defined(__BYTE_ORDER__) && __BYTE_ORDER__==__ORDER_BIG_ENDIAN__) - #define __TBB_ENDIANNESS __TBB_ENDIAN_BIG -#elif __LITTLE_ENDIAN__ || (defined(__BYTE_ORDER__) && __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__) - #define __TBB_ENDIANNESS __TBB_ENDIAN_LITTLE -#elif defined(__BYTE_ORDER__) - #define __TBB_ENDIANNESS __TBB_ENDIAN_UNSUPPORTED -#else - #define __TBB_ENDIANNESS __TBB_ENDIAN_DETECT -#endif - -// On Power Architecture, (lock-free) 64-bit atomics require 64-bit hardware: -#if __TBB_WORDSIZE==8 - // Do not change the following definition, because TBB itself will use 64-bit atomics in 64-bit builds. - #define __TBB_64BIT_ATOMICS 1 -#elif __bgp__ - // Do not change the following definition, because this is known 32-bit hardware. - #define __TBB_64BIT_ATOMICS 0 -#else - // To enable 64-bit atomics in 32-bit builds, set the value below to 1 instead of 0. - // You must make certain that the program will only use them on actual 64-bit hardware - // (which typically means that the entire program is only executed on such hardware), - // because their implementation involves machine instructions that are illegal elsewhere. - // The setting can be chosen independently per compilation unit, - // which also means that TBB itself does not need to be rebuilt. - // Alternatively (but only for the current architecture and TBB version), - // override the default as a predefined macro when invoking the compiler. - #ifndef __TBB_64BIT_ATOMICS - #define __TBB_64BIT_ATOMICS 0 - #endif -#endif - -inline int32_t __TBB_machine_cmpswp4 (volatile void *ptr, int32_t value, int32_t comparand ) -{ - int32_t result; - - __asm__ __volatile__("sync\n" - "0:\n\t" - "lwarx %[res],0,%[ptr]\n\t" /* load w/ reservation */ - "cmpw %[res],%[cmp]\n\t" /* compare against comparand */ - "bne- 1f\n\t" /* exit if not same */ - "stwcx. %[val],0,%[ptr]\n\t" /* store new value */ - "bne- 0b\n" /* retry if reservation lost */ - "1:\n\t" /* the exit */ - "isync" - : [res]"=&r"(result) - , "+m"(* (int32_t*) ptr) /* redundant with "memory" */ - : [ptr]"r"(ptr) - , [val]"r"(value) - , [cmp]"r"(comparand) - : "memory" /* compiler full fence */ - , "cr0" /* clobbered by cmp and/or stwcx. */ - ); - return result; -} - -#if __TBB_WORDSIZE==8 - -inline int64_t __TBB_machine_cmpswp8 (volatile void *ptr, int64_t value, int64_t comparand ) -{ - int64_t result; - __asm__ __volatile__("sync\n" - "0:\n\t" - "ldarx %[res],0,%[ptr]\n\t" /* load w/ reservation */ - "cmpd %[res],%[cmp]\n\t" /* compare against comparand */ - "bne- 1f\n\t" /* exit if not same */ - "stdcx. %[val],0,%[ptr]\n\t" /* store new value */ - "bne- 0b\n" /* retry if reservation lost */ - "1:\n\t" /* the exit */ - "isync" - : [res]"=&r"(result) - , "+m"(* (int64_t*) ptr) /* redundant with "memory" */ - : [ptr]"r"(ptr) - , [val]"r"(value) - , [cmp]"r"(comparand) - : "memory" /* compiler full fence */ - , "cr0" /* clobbered by cmp and/or stdcx. */ - ); - return result; -} - -#elif __TBB_64BIT_ATOMICS /* && __TBB_WORDSIZE==4 */ - -inline int64_t __TBB_machine_cmpswp8 (volatile void *ptr, int64_t value, int64_t comparand ) -{ - int64_t result; - int64_t value_register, comparand_register, result_register; // dummy variables to allocate registers - __asm__ __volatile__("sync\n\t" - "ld %[val],%[valm]\n\t" - "ld %[cmp],%[cmpm]\n" - "0:\n\t" - "ldarx %[res],0,%[ptr]\n\t" /* load w/ reservation */ - "cmpd %[res],%[cmp]\n\t" /* compare against comparand */ - "bne- 1f\n\t" /* exit if not same */ - "stdcx. %[val],0,%[ptr]\n\t" /* store new value */ - "bne- 0b\n" /* retry if reservation lost */ - "1:\n\t" /* the exit */ - "std %[res],%[resm]\n\t" - "isync" - : [resm]"=m"(result) - , [res] "=&r"( result_register) - , [val] "=&r"( value_register) - , [cmp] "=&r"(comparand_register) - , "+m"(* (int64_t*) ptr) /* redundant with "memory" */ - : [ptr] "r"(ptr) - , [valm]"m"(value) - , [cmpm]"m"(comparand) - : "memory" /* compiler full fence */ - , "cr0" /* clobbered by cmpd and/or stdcx. */ - ); - return result; -} - -#endif /* __TBB_WORDSIZE==4 && __TBB_64BIT_ATOMICS */ - -#define __TBB_MACHINE_DEFINE_LOAD_STORE(S,ldx,stx,cmpx) \ - template \ - struct machine_load_store { \ - static inline T load_with_acquire(const volatile T& location) { \ - T result; \ - __asm__ __volatile__(ldx " %[res],0(%[ptr])\n" \ - "0:\n\t" \ - cmpx " %[res],%[res]\n\t" \ - "bne- 0b\n\t" \ - "isync" \ - : [res]"=r"(result) \ - : [ptr]"b"(&location) /* cannot use register 0 here */ \ - , "m"(location) /* redundant with "memory" */ \ - : "memory" /* compiler acquire fence */ \ - , "cr0" /* clobbered by cmpw/cmpd */); \ - return result; \ - } \ - static inline void store_with_release(volatile T &location, T value) { \ - __asm__ __volatile__("lwsync\n\t" \ - stx " %[val],0(%[ptr])" \ - : "=m"(location) /* redundant with "memory" */ \ - : [ptr]"b"(&location) /* cannot use register 0 here */ \ - , [val]"r"(value) \ - : "memory"/*compiler release fence*/ /*(cr0 not affected)*/); \ - } \ - }; \ - \ - template \ - struct machine_load_store_relaxed { \ - static inline T load (const __TBB_atomic T& location) { \ - T result; \ - __asm__ __volatile__(ldx " %[res],0(%[ptr])" \ - : [res]"=r"(result) \ - : [ptr]"b"(&location) /* cannot use register 0 here */ \ - , "m"(location) \ - ); /*(no compiler fence)*/ /*(cr0 not affected)*/ \ - return result; \ - } \ - static inline void store (__TBB_atomic T &location, T value) { \ - __asm__ __volatile__(stx " %[val],0(%[ptr])" \ - : "=m"(location) \ - : [ptr]"b"(&location) /* cannot use register 0 here */ \ - , [val]"r"(value) \ - ); /*(no compiler fence)*/ /*(cr0 not affected)*/ \ - } \ - }; - -namespace tbb { -namespace internal { - __TBB_MACHINE_DEFINE_LOAD_STORE(1,"lbz","stb","cmpw") - __TBB_MACHINE_DEFINE_LOAD_STORE(2,"lhz","sth","cmpw") - __TBB_MACHINE_DEFINE_LOAD_STORE(4,"lwz","stw","cmpw") - -#if __TBB_WORDSIZE==8 - - __TBB_MACHINE_DEFINE_LOAD_STORE(8,"ld" ,"std","cmpd") - -#elif __TBB_64BIT_ATOMICS /* && __TBB_WORDSIZE==4 */ - - template - struct machine_load_store { - static inline T load_with_acquire(const volatile T& location) { - T result; - T result_register; // dummy variable to allocate a register - __asm__ __volatile__("ld %[res],0(%[ptr])\n\t" - "std %[res],%[resm]\n" - "0:\n\t" - "cmpd %[res],%[res]\n\t" - "bne- 0b\n\t" - "isync" - : [resm]"=m"(result) - , [res]"=&r"(result_register) - : [ptr]"b"(&location) /* cannot use register 0 here */ - , "m"(location) /* redundant with "memory" */ - : "memory" /* compiler acquire fence */ - , "cr0" /* clobbered by cmpd */); - return result; - } - - static inline void store_with_release(volatile T &location, T value) { - T value_register; // dummy variable to allocate a register - __asm__ __volatile__("lwsync\n\t" - "ld %[val],%[valm]\n\t" - "std %[val],0(%[ptr])" - : "=m"(location) /* redundant with "memory" */ - , [val]"=&r"(value_register) - : [ptr]"b"(&location) /* cannot use register 0 here */ - , [valm]"m"(value) - : "memory"/*compiler release fence*/ /*(cr0 not affected)*/); - } - }; - - struct machine_load_store_relaxed { - static inline T load (const volatile T& location) { - T result; - T result_register; // dummy variable to allocate a register - __asm__ __volatile__("ld %[res],0(%[ptr])\n\t" - "std %[res],%[resm]" - : [resm]"=m"(result) - , [res]"=&r"(result_register) - : [ptr]"b"(&location) /* cannot use register 0 here */ - , "m"(location) - ); /*(no compiler fence)*/ /*(cr0 not affected)*/ - return result; - } - - static inline void store (volatile T &location, T value) { - T value_register; // dummy variable to allocate a register - __asm__ __volatile__("ld %[val],%[valm]\n\t" - "std %[val],0(%[ptr])" - : "=m"(location) - , [val]"=&r"(value_register) - : [ptr]"b"(&location) /* cannot use register 0 here */ - , [valm]"m"(value) - ); /*(no compiler fence)*/ /*(cr0 not affected)*/ - } - }; - #define __TBB_machine_load_store_relaxed_8 - -#endif /* __TBB_WORDSIZE==4 && __TBB_64BIT_ATOMICS */ - -}} // namespaces internal, tbb - -#undef __TBB_MACHINE_DEFINE_LOAD_STORE - -#define __TBB_USE_GENERIC_PART_WORD_CAS 1 -#define __TBB_USE_GENERIC_FETCH_ADD 1 -#define __TBB_USE_GENERIC_FETCH_STORE 1 -#define __TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE 1 - -#define __TBB_control_consistency_helper() __asm__ __volatile__("isync": : :"memory") -#define __TBB_full_memory_fence() __asm__ __volatile__( "sync": : :"memory") - -static inline intptr_t __TBB_machine_lg( uintptr_t x ) { - __TBB_ASSERT(x, "__TBB_Log2(0) undefined"); - // cntlzd/cntlzw starts counting at 2^63/2^31 (ignoring any higher-order bits), and does not affect cr0 -#if __TBB_WORDSIZE==8 - __asm__ __volatile__ ("cntlzd %0,%0" : "+r"(x)); - return 63-static_cast(x); -#else - __asm__ __volatile__ ("cntlzw %0,%0" : "+r"(x)); - return 31-static_cast(x); -#endif -} -#define __TBB_Log2(V) __TBB_machine_lg(V) - -// Assumes implicit alignment for any 32-bit value -typedef uint32_t __TBB_Flag; -#define __TBB_Flag __TBB_Flag - -inline bool __TBB_machine_trylockbyte( __TBB_atomic __TBB_Flag &flag ) { - return __TBB_machine_cmpswp4(&flag,1,0)==0; -} -#define __TBB_TryLockByte(P) __TBB_machine_trylockbyte(P) diff --git a/lib/3rdParty/tbb/include/tbb/machine/macos_common.h b/lib/3rdParty/tbb/include/tbb/machine/macos_common.h deleted file mode 100644 index 119ad979..00000000 --- a/lib/3rdParty/tbb/include/tbb/machine/macos_common.h +++ /dev/null @@ -1,133 +0,0 @@ -/* - 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. - - - - -*/ - -#if !defined(__TBB_machine_H) || defined(__TBB_machine_macos_common_H) -#error Do not #include this internal file directly; use public TBB headers instead. -#endif - -#define __TBB_machine_macos_common_H - -#include -#define __TBB_Yield() sched_yield() - -// __TBB_HardwareConcurrency - -#include -#include - -static inline int __TBB_macos_available_cpu() { - int name[2] = {CTL_HW, HW_AVAILCPU}; - int ncpu; - size_t size = sizeof(ncpu); - sysctl( name, 2, &ncpu, &size, NULL, 0 ); - return ncpu; -} - -#define __TBB_HardwareConcurrency() __TBB_macos_available_cpu() - -#ifndef __TBB_full_memory_fence - // TBB has not recognized the architecture (none of the architecture abstraction - // headers was included). - #define __TBB_UnknownArchitecture 1 -#endif - -#if __TBB_UnknownArchitecture -// Implementation of atomic operations based on OS provided primitives -#include - -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 macOS* atomics"); - int64_t* address = (int64_t*)ptr; - while( !OSAtomicCompareAndSwap64Barrier(comparand, value, address) ){ -#if __TBB_WORDSIZE==8 - int64_t snapshot = *address; -#else - int64_t snapshot = OSAtomicAdd64( 0, address ); -#endif - if( snapshot!=comparand ) return snapshot; - } - return comparand; -} - -#define __TBB_machine_cmpswp8 __TBB_machine_cmpswp8_OsX - -#endif /* __TBB_UnknownArchitecture */ - -#if __TBB_UnknownArchitecture - -#ifndef __TBB_WORDSIZE -#define __TBB_WORDSIZE __SIZEOF_POINTER__ -#endif - -#ifdef __TBB_ENDIANNESS - // Already determined based on hardware architecture. -#elif __BIG_ENDIAN__ - #define __TBB_ENDIANNESS __TBB_ENDIAN_BIG -#elif __LITTLE_ENDIAN__ - #define __TBB_ENDIANNESS __TBB_ENDIAN_LITTLE -#else - #define __TBB_ENDIANNESS __TBB_ENDIAN_UNSUPPORTED -#endif - -/** As this generic implementation has absolutely no information about underlying - hardware, its performance most likely will be sub-optimal because of full memory - fence usages where a more lightweight synchronization means (or none at all) - could suffice. Thus if you use this header to enable TBB on a new platform, - consider forking it and relaxing below helpers as appropriate. **/ -#define __TBB_control_consistency_helper() OSMemoryBarrier() -#define __TBB_acquire_consistency_helper() OSMemoryBarrier() -#define __TBB_release_consistency_helper() OSMemoryBarrier() -#define __TBB_full_memory_fence() OSMemoryBarrier() - -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 macOS atomics"); - int32_t* address = (int32_t*)ptr; - while( !OSAtomicCompareAndSwap32Barrier(comparand, value, address) ){ - int32_t snapshot = *address; - if( snapshot!=comparand ) return snapshot; - } - return comparand; -} - -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 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 macOS atomics"); - return OSAtomicAdd64Barrier(addend, (int64_t*)ptr) - addend; -} - -#define __TBB_USE_GENERIC_PART_WORD_CAS 1 -#define __TBB_USE_GENERIC_PART_WORD_FETCH_ADD 1 -#define __TBB_USE_GENERIC_FETCH_STORE 1 -#define __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE 1 -#define __TBB_USE_GENERIC_RELAXED_LOAD_STORE 1 -#if __TBB_WORDSIZE == 4 - #define __TBB_USE_GENERIC_DWORD_LOAD_STORE 1 -#endif -#define __TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE 1 - -#endif /* __TBB_UnknownArchitecture */ diff --git a/lib/3rdParty/tbb/include/tbb/machine/mic_common.h b/lib/3rdParty/tbb/include/tbb/machine/mic_common.h deleted file mode 100644 index 8765d39f..00000000 --- a/lib/3rdParty/tbb/include/tbb/machine/mic_common.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - 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_mic_common_H -#define __TBB_mic_common_H - -#ifndef __TBB_machine_H -#error Do not #include this internal file directly; use public TBB headers instead. -#endif - -#if ! __TBB_DEFINE_MIC - #error mic_common.h should be included only when building for Intel(R) Many Integrated Core Architecture -#endif - -#ifndef __TBB_PREFETCHING -#define __TBB_PREFETCHING 1 -#endif -#if __TBB_PREFETCHING -#include -#define __TBB_cl_prefetch(p) _mm_prefetch((const char*)p, _MM_HINT_T1) -#define __TBB_cl_evict(p) _mm_clevict(p, _MM_HINT_T1) -#endif - -/** Intel(R) Many Integrated Core Architecture does not support mfence and pause instructions **/ -#define __TBB_full_memory_fence() __asm__ __volatile__("lock; addl $0,(%%rsp)":::"memory") -#define __TBB_Pause(x) _mm_delay_32(16*(x)) -#define __TBB_STEALING_PAUSE 1500/16 -#include -#define __TBB_Yield() sched_yield() - -/** Specifics **/ -#define __TBB_STEALING_ABORT_ON_CONTENTION 1 -#define __TBB_YIELD2P 1 -#define __TBB_HOARD_NONLOCAL_TASKS 1 - -#if ! ( __FreeBSD__ || __linux__ ) - #error Intel(R) Many Integrated Core Compiler does not define __FreeBSD__ or __linux__ anymore. Check for the __TBB_XXX_BROKEN defined under __FreeBSD__ or __linux__. -#endif /* ! ( __FreeBSD__ || __linux__ ) */ - -#endif /* __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 deleted file mode 100644 index 40d22020..00000000 --- a/lib/3rdParty/tbb/include/tbb/machine/msvc_armv7.h +++ /dev/null @@ -1,171 +0,0 @@ -/* - 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. - - - - -*/ - -#if !defined(__TBB_machine_H) || defined(__TBB_msvc_armv7_H) -#error Do not #include this internal file directly; use public TBB headers instead. -#endif - -#define __TBB_msvc_armv7_H - -#include -#include - -#define __TBB_WORDSIZE 4 - -#define __TBB_ENDIANNESS __TBB_ENDIAN_UNSUPPORTED - -#if defined(TBB_WIN32_USE_CL_BUILTINS) -// We can test this on _M_IX86 -#pragma intrinsic(_ReadWriteBarrier) -#pragma intrinsic(_mm_mfence) -#define __TBB_compiler_fence() _ReadWriteBarrier() -#define __TBB_full_memory_fence() _mm_mfence() -#define __TBB_control_consistency_helper() __TBB_compiler_fence() -#define __TBB_acquire_consistency_helper() __TBB_compiler_fence() -#define __TBB_release_consistency_helper() __TBB_compiler_fence() -#else -//Now __dmb(_ARM_BARRIER_SY) is used for both compiler and memory fences -//This might be changed later after testing -#define __TBB_compiler_fence() __dmb(_ARM_BARRIER_SY) -#define __TBB_full_memory_fence() __dmb(_ARM_BARRIER_SY) -#define __TBB_control_consistency_helper() __TBB_compiler_fence() -#define __TBB_acquire_consistency_helper() __TBB_full_memory_fence() -#define __TBB_release_consistency_helper() __TBB_full_memory_fence() -#endif - -//-------------------------------------------------- -// Compare and swap -//-------------------------------------------------- - -/** - * Atomic CAS for 32 bit values, if *ptr==comparand, then *ptr=value, returns *ptr - * @param ptr pointer to value in memory to be swapped with value if *ptr==comparand - * @param value value to assign *ptr to if *ptr==comparand - * @param comparand value to compare with *ptr - * @return value originally in memory at ptr, regardless of success -*/ - -#define __TBB_MACHINE_DEFINE_ATOMICS_CMPSWP(S,T,F) \ -inline T __TBB_machine_cmpswp##S( volatile void *ptr, T value, T comparand ) { \ - return _InterlockedCompareExchange##F(reinterpret_cast(ptr),value,comparand); \ -} \ - -#define __TBB_MACHINE_DEFINE_ATOMICS_FETCHADD(S,T,F) \ -inline T __TBB_machine_fetchadd##S( volatile void *ptr, T value ) { \ - return _InterlockedExchangeAdd##F(reinterpret_cast(ptr),value); \ -} \ - -__TBB_MACHINE_DEFINE_ATOMICS_CMPSWP(1,char,8) -__TBB_MACHINE_DEFINE_ATOMICS_CMPSWP(2,short,16) -__TBB_MACHINE_DEFINE_ATOMICS_CMPSWP(4,long,) -__TBB_MACHINE_DEFINE_ATOMICS_CMPSWP(8,__int64,64) -__TBB_MACHINE_DEFINE_ATOMICS_FETCHADD(4,long,) -#if defined(TBB_WIN32_USE_CL_BUILTINS) -// No _InterlockedExchangeAdd64 intrinsic on _M_IX86 -#define __TBB_64BIT_ATOMICS 0 -#else -__TBB_MACHINE_DEFINE_ATOMICS_FETCHADD(8,__int64,64) -#endif - -inline void __TBB_machine_pause (int32_t delay ) -{ - while(delay>0) - { - __TBB_compiler_fence(); - delay--; - } -} - -// API to retrieve/update FPU control setting -#define __TBB_CPU_CTL_ENV_PRESENT 1 - -namespace tbb { -namespace internal { - -template -struct machine_load_store_relaxed { - static inline T load ( const volatile T& location ) { - const T value = location; - - /* - * An extra memory barrier is required for errata #761319 - * Please see http://infocenter.arm.com/help/topic/com.arm.doc.uan0004a - */ - __TBB_acquire_consistency_helper(); - return value; - } - - static inline void store ( volatile T& location, T value ) { - location = value; - } -}; - -class cpu_ctl_env { -private: - unsigned int my_ctl; -public: - bool operator!=( const cpu_ctl_env& ctl ) const { return my_ctl != ctl.my_ctl; } - void get_env() { my_ctl = _control87(0, 0); } - void set_env() const { _control87( my_ctl, ~0U ); } -}; - -} // namespace internal -} // namespaces tbb - -// Machine specific atomic operations -#define __TBB_CompareAndSwap4(P,V,C) __TBB_machine_cmpswp4(P,V,C) -#define __TBB_CompareAndSwap8(P,V,C) __TBB_machine_cmpswp8(P,V,C) -#define __TBB_Pause(V) __TBB_machine_pause(V) - -// Use generics for some things -#define __TBB_USE_FETCHSTORE_AS_FULL_FENCED_STORE 1 -#define __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE 1 -#define __TBB_USE_GENERIC_PART_WORD_FETCH_ADD 1 -#define __TBB_USE_GENERIC_PART_WORD_FETCH_STORE 1 -#define __TBB_USE_GENERIC_FETCH_STORE 1 -#define __TBB_USE_GENERIC_DWORD_LOAD_STORE 1 -#define __TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE 1 - -#if defined(TBB_WIN32_USE_CL_BUILTINS) -#if !__TBB_WIN8UI_SUPPORT -extern "C" __declspec(dllimport) int __stdcall SwitchToThread( void ); -#define __TBB_Yield() SwitchToThread() -#else -#include -#define __TBB_Yield() std::this_thread::yield() -#endif -#else -#define __TBB_Yield() __yield() -#endif - -// Machine specific atomic operations -#define __TBB_AtomicOR(P,V) __TBB_machine_OR(P,V) -#define __TBB_AtomicAND(P,V) __TBB_machine_AND(P,V) - -template -inline void __TBB_machine_OR( T1 *operand, T2 addend ) { - _InterlockedOr((long volatile *)operand, (long)addend); -} - -template -inline void __TBB_machine_AND( T1 *operand, T2 addend ) { - _InterlockedAnd((long volatile *)operand, (long)addend); -} - diff --git a/lib/3rdParty/tbb/include/tbb/machine/msvc_ia32_common.h b/lib/3rdParty/tbb/include/tbb/machine/msvc_ia32_common.h deleted file mode 100644 index 8b4814bc..00000000 --- a/lib/3rdParty/tbb/include/tbb/machine/msvc_ia32_common.h +++ /dev/null @@ -1,280 +0,0 @@ -/* - 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. - - - - -*/ - -#if !defined(__TBB_machine_H) || defined(__TBB_machine_msvc_ia32_common_H) -#error Do not #include this internal file directly; use public TBB headers instead. -#endif - -#define __TBB_machine_msvc_ia32_common_H - -#include - -//TODO: consider moving this macro to tbb_config.h and using where MSVC asm is used -#if !_M_X64 || __INTEL_COMPILER - #define __TBB_X86_MSVC_INLINE_ASM_AVAILABLE 1 -#else - //MSVC in x64 mode does not accept inline assembler - #define __TBB_X86_MSVC_INLINE_ASM_AVAILABLE 0 - #define __TBB_NO_X86_MSVC_INLINE_ASM_MSG "The compiler being used is not supported (outdated?)" -#endif - -#if _M_X64 - #define __TBB_r(reg_name) r##reg_name - #define __TBB_W(name) name##64 - namespace tbb { namespace internal { namespace msvc_intrinsics { - typedef __int64 word; - }}} -#else - #define __TBB_r(reg_name) e##reg_name - #define __TBB_W(name) name - namespace tbb { namespace internal { namespace msvc_intrinsics { - typedef long word; - }}} -#endif - -#if _MSC_VER>=1600 && (!__INTEL_COMPILER || __INTEL_COMPILER>=1310) - // S is the operand size in bytes, B is the suffix for intrinsics for that size - #define __TBB_MACHINE_DEFINE_ATOMICS(S,B,T,U) \ - __pragma(intrinsic( _InterlockedCompareExchange##B )) \ - static inline T __TBB_machine_cmpswp##S ( volatile void * ptr, U value, U comparand ) { \ - return _InterlockedCompareExchange##B ( (T*)ptr, value, comparand ); \ - } \ - __pragma(intrinsic( _InterlockedExchangeAdd##B )) \ - static inline T __TBB_machine_fetchadd##S ( volatile void * ptr, U addend ) { \ - return _InterlockedExchangeAdd##B ( (T*)ptr, addend ); \ - } \ - __pragma(intrinsic( _InterlockedExchange##B )) \ - static inline T __TBB_machine_fetchstore##S ( volatile void * ptr, U value ) { \ - return _InterlockedExchange##B ( (T*)ptr, value ); \ - } - - // Atomic intrinsics for 1, 2, and 4 bytes are available for x86 & x64 - __TBB_MACHINE_DEFINE_ATOMICS(1,8,char,__int8) - __TBB_MACHINE_DEFINE_ATOMICS(2,16,short,__int16) - __TBB_MACHINE_DEFINE_ATOMICS(4,,long,__int32) - - #if __TBB_WORDSIZE==8 - __TBB_MACHINE_DEFINE_ATOMICS(8,64,__int64,__int64) - #endif - - #undef __TBB_MACHINE_DEFINE_ATOMICS - #define __TBB_ATOMIC_PRIMITIVES_DEFINED -#endif /*_MSC_VER>=1600*/ - -#if _MSC_VER>=1300 || __INTEL_COMPILER>=1100 - #pragma intrinsic(_ReadWriteBarrier) - #pragma intrinsic(_mm_mfence) - #define __TBB_compiler_fence() _ReadWriteBarrier() - #define __TBB_full_memory_fence() _mm_mfence() -#elif __TBB_X86_MSVC_INLINE_ASM_AVAILABLE - #define __TBB_compiler_fence() __asm { __asm nop } - #define __TBB_full_memory_fence() __asm { __asm mfence } -#else - #error Unsupported compiler; define __TBB_{control,acquire,release}_consistency_helper to support it -#endif - -#define __TBB_control_consistency_helper() __TBB_compiler_fence() -#define __TBB_acquire_consistency_helper() __TBB_compiler_fence() -#define __TBB_release_consistency_helper() __TBB_compiler_fence() - -#if (_MSC_VER>=1300) || (__INTEL_COMPILER) - #pragma intrinsic(_mm_pause) - namespace tbb { namespace internal { namespace msvc_intrinsics { - static inline void pause (uintptr_t delay ) { - for (;delay>0; --delay ) - _mm_pause(); - } - }}} - #define __TBB_Pause(V) tbb::internal::msvc_intrinsics::pause(V) - #define __TBB_SINGLE_PAUSE _mm_pause() -#else - #if !__TBB_X86_MSVC_INLINE_ASM_AVAILABLE - #error __TBB_NO_X86_MSVC_INLINE_ASM_MSG - #endif - namespace tbb { namespace internal { namespace msvc_inline_asm - static inline void pause (uintptr_t delay ) { - _asm - { - mov __TBB_r(ax), delay - __TBB_L1: - pause - add __TBB_r(ax), -1 - jne __TBB_L1 - } - return; - } - }}} - #define __TBB_Pause(V) tbb::internal::msvc_inline_asm::pause(V) - #define __TBB_SINGLE_PAUSE __asm pause -#endif - -#if (_MSC_VER>=1400 && !__INTEL_COMPILER) || (__INTEL_COMPILER>=1200) -// MSVC did not have this intrinsic prior to VC8. -// ICL 11.1 fails to compile a TBB example if __TBB_Log2 uses the intrinsic. - #pragma intrinsic(__TBB_W(_BitScanReverse)) - namespace tbb { namespace internal { namespace msvc_intrinsics { - static inline uintptr_t lg_bsr( uintptr_t i ){ - unsigned long j; - __TBB_W(_BitScanReverse)( &j, i ); - return j; - } - }}} - #define __TBB_Log2(V) tbb::internal::msvc_intrinsics::lg_bsr(V) -#else - #if !__TBB_X86_MSVC_INLINE_ASM_AVAILABLE - #error __TBB_NO_X86_MSVC_INLINE_ASM_MSG - #endif - namespace tbb { namespace internal { namespace msvc_inline_asm { - static inline uintptr_t lg_bsr( uintptr_t i ){ - uintptr_t j; - __asm - { - bsr __TBB_r(ax), i - mov j, __TBB_r(ax) - } - return j; - } - }}} - #define __TBB_Log2(V) tbb::internal::msvc_inline_asm::lg_bsr(V) -#endif - -#if _MSC_VER>=1400 - #pragma intrinsic(__TBB_W(_InterlockedOr)) - #pragma intrinsic(__TBB_W(_InterlockedAnd)) - namespace tbb { namespace internal { namespace msvc_intrinsics { - static inline void lock_or( volatile void *operand, intptr_t addend ){ - __TBB_W(_InterlockedOr)((volatile word*)operand, addend); - } - static inline void lock_and( volatile void *operand, intptr_t addend ){ - __TBB_W(_InterlockedAnd)((volatile word*)operand, addend); - } - }}} - #define __TBB_AtomicOR(P,V) tbb::internal::msvc_intrinsics::lock_or(P,V) - #define __TBB_AtomicAND(P,V) tbb::internal::msvc_intrinsics::lock_and(P,V) -#else - #if !__TBB_X86_MSVC_INLINE_ASM_AVAILABLE - #error __TBB_NO_X86_MSVC_INLINE_ASM_MSG - #endif - namespace tbb { namespace internal { namespace msvc_inline_asm { - static inline void lock_or( volatile void *operand, __int32 addend ) { - __asm - { - mov eax, addend - mov edx, [operand] - lock or [edx], eax - } - } - static inline void lock_and( volatile void *operand, __int32 addend ) { - __asm - { - mov eax, addend - mov edx, [operand] - lock and [edx], eax - } - } - }}} - #define __TBB_AtomicOR(P,V) tbb::internal::msvc_inline_asm::lock_or(P,V) - #define __TBB_AtomicAND(P,V) tbb::internal::msvc_inline_asm::lock_and(P,V) -#endif - -#pragma intrinsic(__rdtsc) -namespace tbb { namespace internal { typedef uint64_t machine_tsc_t; } } -static inline tbb::internal::machine_tsc_t __TBB_machine_time_stamp() { - return __rdtsc(); -} -#define __TBB_time_stamp() __TBB_machine_time_stamp() - -// API to retrieve/update FPU control setting -#define __TBB_CPU_CTL_ENV_PRESENT 1 - -namespace tbb { namespace internal { class cpu_ctl_env; } } -#if __TBB_X86_MSVC_INLINE_ASM_AVAILABLE - inline void __TBB_get_cpu_ctl_env ( tbb::internal::cpu_ctl_env* ctl ) { - __asm { - __asm mov __TBB_r(ax), ctl - __asm stmxcsr [__TBB_r(ax)] - __asm fstcw [__TBB_r(ax)+4] - } - } - inline void __TBB_set_cpu_ctl_env ( const tbb::internal::cpu_ctl_env* ctl ) { - __asm { - __asm mov __TBB_r(ax), ctl - __asm ldmxcsr [__TBB_r(ax)] - __asm fldcw [__TBB_r(ax)+4] - } - } -#else - extern "C" { - void __TBB_EXPORTED_FUNC __TBB_get_cpu_ctl_env ( tbb::internal::cpu_ctl_env* ); - void __TBB_EXPORTED_FUNC __TBB_set_cpu_ctl_env ( const tbb::internal::cpu_ctl_env* ); - } -#endif - -namespace tbb { -namespace internal { -class cpu_ctl_env { -private: - int mxcsr; - short x87cw; - static const int MXCSR_CONTROL_MASK = ~0x3f; /* all except last six status bits */ -public: - bool operator!=( const cpu_ctl_env& ctl ) const { return mxcsr != ctl.mxcsr || x87cw != ctl.x87cw; } - void get_env() { - __TBB_get_cpu_ctl_env( this ); - mxcsr &= MXCSR_CONTROL_MASK; - } - void set_env() const { __TBB_set_cpu_ctl_env( this ); } -}; -} // namespace internal -} // namespace tbb - -#if !__TBB_WIN8UI_SUPPORT -extern "C" __declspec(dllimport) int __stdcall SwitchToThread( void ); -#define __TBB_Yield() SwitchToThread() -#else -#include -#define __TBB_Yield() std::this_thread::yield() -#endif - -#undef __TBB_r -#undef __TBB_W -#undef __TBB_word - -extern "C" { - __int8 __TBB_EXPORTED_FUNC __TBB_machine_try_lock_elided (volatile void* ptr); - void __TBB_EXPORTED_FUNC __TBB_machine_unlock_elided (volatile void* ptr); - - // 'pause' instruction aborts HLE/RTM transactions - inline static void __TBB_machine_try_lock_elided_cancel() { __TBB_SINGLE_PAUSE; } - -#if __TBB_TSX_INTRINSICS_PRESENT - #define __TBB_machine_is_in_transaction _xtest - #define __TBB_machine_begin_transaction _xbegin - #define __TBB_machine_end_transaction _xend - // The value (0xFF) below comes from the - // Intel(R) 64 and IA-32 Architectures Optimization Reference Manual 12.4.5 lock not free - #define __TBB_machine_transaction_conflict_abort() _xabort(0xFF) -#else - __int8 __TBB_EXPORTED_FUNC __TBB_machine_is_in_transaction(); - unsigned __int32 __TBB_EXPORTED_FUNC __TBB_machine_begin_transaction(); - void __TBB_EXPORTED_FUNC __TBB_machine_end_transaction(); - void __TBB_EXPORTED_FUNC __TBB_machine_transaction_conflict_abort(); -#endif /* __TBB_TSX_INTRINSICS_PRESENT */ -} diff --git a/lib/3rdParty/tbb/include/tbb/machine/sunos_sparc.h b/lib/3rdParty/tbb/include/tbb/machine/sunos_sparc.h deleted file mode 100644 index 9119f402..00000000 --- a/lib/3rdParty/tbb/include/tbb/machine/sunos_sparc.h +++ /dev/null @@ -1,203 +0,0 @@ -/* - 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. - - - - -*/ - - -#if !defined(__TBB_machine_H) || defined(__TBB_machine_sunos_sparc_H) -#error Do not #include this internal file directly; use public TBB headers instead. -#endif - -#define __TBB_machine_sunos_sparc_H - -#include -#include - -#define __TBB_WORDSIZE 8 -// Big endian is assumed for SPARC. -// While hardware may support page-specific bi-endianness, only big endian pages may be exposed to TBB -#define __TBB_ENDIANNESS __TBB_ENDIAN_BIG - -/** To those working on SPARC hardware. Consider relaxing acquire and release - consistency helpers to no-op (as this port covers TSO mode only). **/ -#define __TBB_compiler_fence() __asm__ __volatile__ ("": : :"memory") -#define __TBB_control_consistency_helper() __TBB_compiler_fence() -#define __TBB_acquire_consistency_helper() __TBB_compiler_fence() -#define __TBB_release_consistency_helper() __TBB_compiler_fence() -#define __TBB_full_memory_fence() __asm__ __volatile__("membar #LoadLoad|#LoadStore|#StoreStore|#StoreLoad": : : "memory") - -//-------------------------------------------------- -// Compare and swap -//-------------------------------------------------- - -/** - * Atomic CAS for 32 bit values, if *ptr==comparand, then *ptr=value, returns *ptr - * @param ptr pointer to value in memory to be swapped with value if *ptr==comparand - * @param value value to assign *ptr to if *ptr==comparand - * @param comparand value to compare with *ptr - ( @return value originally in memory at ptr, regardless of success -*/ -static inline int32_t __TBB_machine_cmpswp4(volatile void *ptr, int32_t value, int32_t comparand ){ - int32_t result; - __asm__ __volatile__( - "cas\t[%5],%4,%1" - : "=m"(*(int32_t *)ptr), "=r"(result) - : "m"(*(int32_t *)ptr), "1"(value), "r"(comparand), "r"(ptr) - : "memory"); - return result; -} - -/** - * Atomic CAS for 64 bit values, if *ptr==comparand, then *ptr=value, returns *ptr - * @param ptr pointer to value in memory to be swapped with value if *ptr==comparand - * @param value value to assign *ptr to if *ptr==comparand - * @param comparand value to compare with *ptr - ( @return value originally in memory at ptr, regardless of success - */ -static inline int64_t __TBB_machine_cmpswp8(volatile void *ptr, int64_t value, int64_t comparand ){ - int64_t result; - __asm__ __volatile__( - "casx\t[%5],%4,%1" - : "=m"(*(int64_t *)ptr), "=r"(result) - : "m"(*(int64_t *)ptr), "1"(value), "r"(comparand), "r"(ptr) - : "memory"); - return result; -} - -//--------------------------------------------------- -// Fetch and add -//--------------------------------------------------- - -/** - * Atomic fetch and add for 32 bit values, in this case implemented by continuously checking success of atomicity - * @param ptr pointer to value to add addend to - * @param addened value to add to *ptr - * @return value at ptr before addened was added - */ -static inline int32_t __TBB_machine_fetchadd4(volatile void *ptr, int32_t addend){ - int32_t result; - __asm__ __volatile__ ( - "0:\t add\t %3, %4, %0\n" // do addition - "\t cas\t [%2], %3, %0\n" // cas to store result in memory - "\t cmp\t %3, %0\n" // check if value from memory is original - "\t bne,a,pn\t %%icc, 0b\n" // if not try again - "\t mov %0, %3\n" // use branch delay slot to move new value in memory to be added - : "=&r"(result), "=m"(*(int32_t *)ptr) - : "r"(ptr), "r"(*(int32_t *)ptr), "r"(addend), "m"(*(int32_t *)ptr) - : "ccr", "memory"); - return result; -} - -/** - * Atomic fetch and add for 64 bit values, in this case implemented by continuously checking success of atomicity - * @param ptr pointer to value to add addend to - * @param addened value to add to *ptr - * @return value at ptr before addened was added - */ -static inline int64_t __TBB_machine_fetchadd8(volatile void *ptr, int64_t addend){ - int64_t result; - __asm__ __volatile__ ( - "0:\t add\t %3, %4, %0\n" // do addition - "\t casx\t [%2], %3, %0\n" // cas to store result in memory - "\t cmp\t %3, %0\n" // check if value from memory is original - "\t bne,a,pn\t %%xcc, 0b\n" // if not try again - "\t mov %0, %3\n" // use branch delay slot to move new value in memory to be added - : "=&r"(result), "=m"(*(int64_t *)ptr) - : "r"(ptr), "r"(*(int64_t *)ptr), "r"(addend), "m"(*(int64_t *)ptr) - : "ccr", "memory"); - return result; -} - -//-------------------------------------------------------- -// Logarithm (base two, integer) -//-------------------------------------------------------- - -static inline int64_t __TBB_machine_lg( uint64_t x ) { - __TBB_ASSERT(x, "__TBB_Log2(0) undefined"); - uint64_t count; - // one hot encode - x |= (x >> 1); - x |= (x >> 2); - x |= (x >> 4); - x |= (x >> 8); - x |= (x >> 16); - x |= (x >> 32); - // count 1's - __asm__ ("popc %1, %0" : "=r"(count) : "r"(x) ); - return count-1; -} - -//-------------------------------------------------------- - -static inline void __TBB_machine_or( volatile void *ptr, uint64_t value ) { - __asm__ __volatile__ ( - "0:\t or\t %2, %3, %%g1\n" // do operation - "\t casx\t [%1], %2, %%g1\n" // cas to store result in memory - "\t cmp\t %2, %%g1\n" // check if value from memory is original - "\t bne,a,pn\t %%xcc, 0b\n" // if not try again - "\t mov %%g1, %2\n" // use branch delay slot to move new value in memory to be added - : "=m"(*(int64_t *)ptr) - : "r"(ptr), "r"(*(int64_t *)ptr), "r"(value), "m"(*(int64_t *)ptr) - : "ccr", "g1", "memory"); -} - -static inline void __TBB_machine_and( volatile void *ptr, uint64_t value ) { - __asm__ __volatile__ ( - "0:\t and\t %2, %3, %%g1\n" // do operation - "\t casx\t [%1], %2, %%g1\n" // cas to store result in memory - "\t cmp\t %2, %%g1\n" // check if value from memory is original - "\t bne,a,pn\t %%xcc, 0b\n" // if not try again - "\t mov %%g1, %2\n" // use branch delay slot to move new value in memory to be added - : "=m"(*(int64_t *)ptr) - : "r"(ptr), "r"(*(int64_t *)ptr), "r"(value), "m"(*(int64_t *)ptr) - : "ccr", "g1", "memory"); -} - - -static inline void __TBB_machine_pause( int32_t delay ) { - // do nothing, inlined, doesn't matter -} - -// put 0xff in memory location, return memory value, -// generic trylockbyte puts 0x01, however this is fine -// because all that matters is that 0 is unlocked -static inline bool __TBB_machine_trylockbyte(unsigned char &flag){ - unsigned char result; - __asm__ __volatile__ ( - "ldstub\t [%2], %0\n" - : "=r"(result), "=m"(flag) - : "r"(&flag), "m"(flag) - : "memory"); - return result == 0; -} - -#define __TBB_USE_GENERIC_PART_WORD_CAS 1 -#define __TBB_USE_GENERIC_PART_WORD_FETCH_ADD 1 -#define __TBB_USE_GENERIC_FETCH_STORE 1 -#define __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE 1 -#define __TBB_USE_GENERIC_RELAXED_LOAD_STORE 1 -#define __TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE 1 - -#define __TBB_AtomicOR(P,V) __TBB_machine_or(P,V) -#define __TBB_AtomicAND(P,V) __TBB_machine_and(P,V) - -// Definition of other functions -#define __TBB_Pause(V) __TBB_machine_pause(V) -#define __TBB_Log2(V) __TBB_machine_lg(V) - -#define __TBB_TryLockByte(P) __TBB_machine_trylockbyte(P) diff --git a/lib/3rdParty/tbb/include/tbb/machine/windows_api.h b/lib/3rdParty/tbb/include/tbb/machine/windows_api.h deleted file mode 100644 index d362abc5..00000000 --- a/lib/3rdParty/tbb/include/tbb/machine/windows_api.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - 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_machine_windows_api_H -#define __TBB_machine_windows_api_H - -#if _WIN32 || _WIN64 - -#include - -#if _WIN32_WINNT < 0x0600 -// The following Windows API function is declared explicitly; -// otherwise it fails to compile by VS2005. -#if !defined(WINBASEAPI) || (_WIN32_WINNT < 0x0501 && _MSC_VER == 1400) -#define __TBB_WINBASEAPI extern "C" -#else -#define __TBB_WINBASEAPI WINBASEAPI -#endif -__TBB_WINBASEAPI BOOL WINAPI TryEnterCriticalSection( LPCRITICAL_SECTION ); -__TBB_WINBASEAPI BOOL WINAPI InitializeCriticalSectionAndSpinCount( LPCRITICAL_SECTION, DWORD ); -// Overloading WINBASEAPI macro and using local functions missing in Windows XP/2003 -#define InitializeCriticalSectionEx inlineInitializeCriticalSectionEx -#define CreateSemaphoreEx inlineCreateSemaphoreEx -#define CreateEventEx inlineCreateEventEx -inline BOOL WINAPI inlineInitializeCriticalSectionEx( LPCRITICAL_SECTION lpCriticalSection, DWORD dwSpinCount, DWORD ) -{ - return InitializeCriticalSectionAndSpinCount( lpCriticalSection, dwSpinCount ); -} -inline HANDLE WINAPI inlineCreateSemaphoreEx( LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, LONG lInitialCount, LONG lMaximumCount, LPCTSTR lpName, DWORD, DWORD ) -{ - return CreateSemaphore( lpSemaphoreAttributes, lInitialCount, lMaximumCount, lpName ); -} -inline HANDLE WINAPI inlineCreateEventEx( LPSECURITY_ATTRIBUTES lpEventAttributes, LPCTSTR lpName, DWORD dwFlags, DWORD ) -{ - BOOL manual_reset = dwFlags&0x00000001 ? TRUE : FALSE; // CREATE_EVENT_MANUAL_RESET - BOOL initial_set = dwFlags&0x00000002 ? TRUE : FALSE; // CREATE_EVENT_INITIAL_SET - return CreateEvent( lpEventAttributes, manual_reset, initial_set, lpName ); -} -#endif - -#if defined(RTL_SRWLOCK_INIT) -#ifndef __TBB_USE_SRWLOCK -// TODO: turn it on when bug 1952 will be fixed -#define __TBB_USE_SRWLOCK 0 -#endif -#endif - -#else -#error tbb/machine/windows_api.h should only be used for Windows based platforms -#endif // _WIN32 || _WIN64 - -#endif // __TBB_machine_windows_api_H diff --git a/lib/3rdParty/tbb/include/tbb/machine/windows_ia32.h b/lib/3rdParty/tbb/include/tbb/machine/windows_ia32.h deleted file mode 100644 index 8db0d2b8..00000000 --- a/lib/3rdParty/tbb/include/tbb/machine/windows_ia32.h +++ /dev/null @@ -1,109 +0,0 @@ -/* - 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. - - - - -*/ - -#if !defined(__TBB_machine_H) || defined(__TBB_machine_windows_ia32_H) -#error Do not #include this internal file directly; use public TBB headers instead. -#endif - -#define __TBB_machine_windows_ia32_H - -#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) - // Workaround for overzealous compiler warnings in /Wp64 mode - #pragma warning (push) - #pragma warning (disable: 4244 4267) -#endif - -#include "msvc_ia32_common.h" - -#define __TBB_WORDSIZE 4 -#define __TBB_ENDIANNESS __TBB_ENDIAN_LITTLE - -extern "C" { - __int64 __TBB_EXPORTED_FUNC __TBB_machine_cmpswp8 (volatile void *ptr, __int64 value, __int64 comparand ); - __int64 __TBB_EXPORTED_FUNC __TBB_machine_fetchadd8 (volatile void *ptr, __int64 addend ); - __int64 __TBB_EXPORTED_FUNC __TBB_machine_fetchstore8 (volatile void *ptr, __int64 value ); - void __TBB_EXPORTED_FUNC __TBB_machine_store8 (volatile void *ptr, __int64 value ); - __int64 __TBB_EXPORTED_FUNC __TBB_machine_load8 (const volatile void *ptr); -} - -#ifndef __TBB_ATOMIC_PRIMITIVES_DEFINED - -#define __TBB_MACHINE_DEFINE_ATOMICS(S,T,U,A,C) \ -static inline T __TBB_machine_cmpswp##S ( volatile void * ptr, U value, U comparand ) { \ - T result; \ - volatile T *p = (T *)ptr; \ - __asm \ - { \ - __asm mov edx, p \ - __asm mov C , value \ - __asm mov A , comparand \ - __asm lock cmpxchg [edx], C \ - __asm mov result, A \ - } \ - return result; \ -} \ -\ -static inline T __TBB_machine_fetchadd##S ( volatile void * ptr, U addend ) { \ - T result; \ - volatile T *p = (T *)ptr; \ - __asm \ - { \ - __asm mov edx, p \ - __asm mov A, addend \ - __asm lock xadd [edx], A \ - __asm mov result, A \ - } \ - return result; \ -}\ -\ -static inline T __TBB_machine_fetchstore##S ( volatile void * ptr, U value ) { \ - T result; \ - volatile T *p = (T *)ptr; \ - __asm \ - { \ - __asm mov edx, p \ - __asm mov A, value \ - __asm lock xchg [edx], A \ - __asm mov result, A \ - } \ - return result; \ -} - - -__TBB_MACHINE_DEFINE_ATOMICS(1, __int8, __int8, al, cl) -__TBB_MACHINE_DEFINE_ATOMICS(2, __int16, __int16, ax, cx) -__TBB_MACHINE_DEFINE_ATOMICS(4, ptrdiff_t, ptrdiff_t, eax, ecx) - -#undef __TBB_MACHINE_DEFINE_ATOMICS - -#endif /*__TBB_ATOMIC_PRIMITIVES_DEFINED*/ - -//TODO: Check if it possible and profitable for IA-32 architecture on (Linux and Windows) -//to use of 64-bit load/store via floating point registers together with full fence -//for sequentially consistent load/store, instead of CAS. -#define __TBB_USE_FETCHSTORE_AS_FULL_FENCED_STORE 1 -#define __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE 1 -#define __TBB_USE_GENERIC_RELAXED_LOAD_STORE 1 -#define __TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE 1 - - -#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) - #pragma warning (pop) -#endif // warnings 4244, 4267 are back diff --git a/lib/3rdParty/tbb/include/tbb/machine/windows_intel64.h b/lib/3rdParty/tbb/include/tbb/machine/windows_intel64.h deleted file mode 100644 index 86abd6ad..00000000 --- a/lib/3rdParty/tbb/include/tbb/machine/windows_intel64.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - 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. - - - - -*/ - -#if !defined(__TBB_machine_H) || defined(__TBB_machine_windows_intel64_H) -#error Do not #include this internal file directly; use public TBB headers instead. -#endif - -#define __TBB_machine_windows_intel64_H - -#define __TBB_WORDSIZE 8 -#define __TBB_ENDIANNESS __TBB_ENDIAN_LITTLE - -#include "msvc_ia32_common.h" - -#ifndef __TBB_ATOMIC_PRIMITIVES_DEFINED - -#include -#pragma intrinsic(_InterlockedCompareExchange,_InterlockedExchangeAdd,_InterlockedExchange) -#pragma intrinsic(_InterlockedCompareExchange64,_InterlockedExchangeAdd64,_InterlockedExchange64) - -// ATTENTION: if you ever change argument types in machine-specific primitives, -// please take care of atomic_word<> specializations in tbb/atomic.h -extern "C" { - __int8 __TBB_EXPORTED_FUNC __TBB_machine_cmpswp1 (volatile void *ptr, __int8 value, __int8 comparand ); - __int8 __TBB_EXPORTED_FUNC __TBB_machine_fetchadd1 (volatile void *ptr, __int8 addend ); - __int8 __TBB_EXPORTED_FUNC __TBB_machine_fetchstore1 (volatile void *ptr, __int8 value ); - __int16 __TBB_EXPORTED_FUNC __TBB_machine_cmpswp2 (volatile void *ptr, __int16 value, __int16 comparand ); - __int16 __TBB_EXPORTED_FUNC __TBB_machine_fetchadd2 (volatile void *ptr, __int16 addend ); - __int16 __TBB_EXPORTED_FUNC __TBB_machine_fetchstore2 (volatile void *ptr, __int16 value ); -} - -inline long __TBB_machine_cmpswp4 (volatile void *ptr, __int32 value, __int32 comparand ) { - return _InterlockedCompareExchange( (long*)ptr, value, comparand ); -} -inline long __TBB_machine_fetchadd4 (volatile void *ptr, __int32 addend ) { - return _InterlockedExchangeAdd( (long*)ptr, addend ); -} -inline long __TBB_machine_fetchstore4 (volatile void *ptr, __int32 value ) { - return _InterlockedExchange( (long*)ptr, value ); -} - -inline __int64 __TBB_machine_cmpswp8 (volatile void *ptr, __int64 value, __int64 comparand ) { - return _InterlockedCompareExchange64( (__int64*)ptr, value, comparand ); -} -inline __int64 __TBB_machine_fetchadd8 (volatile void *ptr, __int64 addend ) { - return _InterlockedExchangeAdd64( (__int64*)ptr, addend ); -} -inline __int64 __TBB_machine_fetchstore8 (volatile void *ptr, __int64 value ) { - return _InterlockedExchange64( (__int64*)ptr, value ); -} - -#endif /*__TBB_ATOMIC_PRIMITIVES_DEFINED*/ - -#define __TBB_USE_FETCHSTORE_AS_FULL_FENCED_STORE 1 -#define __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE 1 -#define __TBB_USE_GENERIC_RELAXED_LOAD_STORE 1 -#define __TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE 1 diff --git a/lib/3rdParty/tbb/include/tbb/memory_pool.h b/lib/3rdParty/tbb/include/tbb/memory_pool.h deleted file mode 100644 index b3bba397..00000000 --- a/lib/3rdParty/tbb/include/tbb/memory_pool.h +++ /dev/null @@ -1,279 +0,0 @@ -/* - 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_memory_pool_H -#define __TBB_memory_pool_H - -#if !TBB_PREVIEW_MEMORY_POOL -#error Set TBB_PREVIEW_MEMORY_POOL to include memory_pool.h -#endif -/** @file */ - -#include "scalable_allocator.h" -#include // std::bad_alloc -#include // std::runtime_error, std::invalid_argument -// required in C++03 to construct std::runtime_error and std::invalid_argument -#include -#if __TBB_ALLOCATOR_CONSTRUCT_VARIADIC -#include // std::forward -#endif - -#if __TBB_EXTRA_DEBUG -#define __TBBMALLOC_ASSERT ASSERT -#else -#define __TBBMALLOC_ASSERT(a,b) ((void)0) -#endif - -namespace tbb { -namespace interface6 { -//! @cond INTERNAL -namespace internal { - -//! Base of thread-safe pool allocator for variable-size requests -class pool_base : tbb::internal::no_copy { - // Pool interface is separate from standard allocator classes because it has - // to maintain internal state, no copy or assignment. Move and swap are possible. -public: - //! Reset pool to reuse its memory (free all objects at once) - void recycle() { rml::pool_reset(my_pool); } - - //! The "malloc" analogue to allocate block of memory of size bytes - void *malloc(size_t size) { return rml::pool_malloc(my_pool, size); } - - //! The "free" analogue to discard a previously allocated piece of memory. - void free(void* ptr) { rml::pool_free(my_pool, ptr); } - - //! The "realloc" analogue complementing pool_malloc. - // Enables some low-level optimization possibilities - void *realloc(void* ptr, size_t size) { - return rml::pool_realloc(my_pool, ptr, size); - } - -protected: - //! destroy pool - must be called in a child class - void destroy() { rml::pool_destroy(my_pool); } - - rml::MemoryPool *my_pool; -}; - -} // namespace internal -//! @endcond - -#if _MSC_VER && !defined(__INTEL_COMPILER) - // Workaround for erroneous "unreferenced parameter" warning in method destroy. - #pragma warning (push) - #pragma warning (disable: 4100) -#endif - -//! Meets "allocator" requirements of ISO C++ Standard, Section 20.1.5 -/** @ingroup memory_allocation */ -template -class memory_pool_allocator { -protected: - typedef P pool_type; - pool_type *my_pool; - template - friend class memory_pool_allocator; - template - friend bool operator==( const memory_pool_allocator& a, const memory_pool_allocator& b); - template - friend bool operator!=( const memory_pool_allocator& a, const memory_pool_allocator& b); -public: - typedef typename tbb::internal::allocator_type::value_type value_type; - typedef value_type* pointer; - typedef const value_type* const_pointer; - typedef value_type& reference; - typedef const value_type& const_reference; - typedef size_t size_type; - typedef ptrdiff_t difference_type; - template struct rebind { - typedef memory_pool_allocator other; - }; - - 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) {} - - pointer address(reference x) const { return &x; } - const_pointer address(const_reference x) const { return &x; } - - //! Allocate space for n objects. - pointer allocate( size_type n, const void* /*hint*/ = 0) { - pointer p = static_cast( my_pool->malloc( n*sizeof(value_type) ) ); - if (!p) - tbb::internal::throw_exception(std::bad_alloc()); - return p; - } - //! Free previously allocated block of memory. - void deallocate( pointer p, size_type ) { - my_pool->free(p); - } - //! Largest value for which method allocate might succeed. - size_type max_size() const throw() { - size_type max = static_cast(-1) / sizeof (value_type); - return (max > 0 ? max : 1); - } - //! Copy-construct value at location pointed to by p. -#if __TBB_ALLOCATOR_CONSTRUCT_VARIADIC - template - void construct(U *p, Args&&... args) - { ::new((void *)p) U(std::forward(args)...); } -#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 - - //! Destroy value at location pointed to by p. - void destroy( pointer p ) { p->~value_type(); } - -}; - -#if _MSC_VER && !defined(__INTEL_COMPILER) - #pragma warning (pop) -#endif // warning 4100 is back - -//! Analogous to std::allocator, as defined in ISO C++ Standard, Section 20.4.1 -/** @ingroup memory_allocation */ -template -class memory_pool_allocator { -public: - typedef P pool_type; - typedef void* pointer; - typedef const void* const_pointer; - typedef void value_type; - template struct rebind { - typedef memory_pool_allocator other; - }; - - 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) {} - -protected: - pool_type *my_pool; - template - friend class memory_pool_allocator; - template - friend bool operator==( const memory_pool_allocator& a, const memory_pool_allocator& b); - template - friend bool operator!=( const memory_pool_allocator& a, const memory_pool_allocator& b); -}; - -template -inline bool operator==( const memory_pool_allocator& a, const memory_pool_allocator& b) {return a.my_pool==b.my_pool;} - -template -inline bool operator!=( const memory_pool_allocator& a, const memory_pool_allocator& b) {return a.my_pool!=b.my_pool;} - - -//! Thread-safe growable pool allocator for variable-size requests -template -class memory_pool : public internal::pool_base { - Alloc my_alloc; // TODO: base-class optimization - static void *allocate_request(intptr_t pool_id, size_t & bytes); - static int deallocate_request(intptr_t pool_id, void*, size_t raw_bytes); - -public: - //! construct pool with underlying allocator - explicit memory_pool(const Alloc &src = Alloc()); - - //! destroy pool - ~memory_pool() { destroy(); } // call the callbacks first and destroy my_alloc latter - -}; - -class fixed_pool : public internal::pool_base { - void *my_buffer; - size_t my_size; - inline static void *allocate_request(intptr_t pool_id, size_t & bytes); - -public: - //! construct pool with underlying allocator - inline fixed_pool(void *buf, size_t size); - //! destroy pool - ~fixed_pool() { destroy(); } -}; - -//////////////// Implementation /////////////// - -template -memory_pool::memory_pool(const Alloc &src) : my_alloc(src) { - rml::MemPoolPolicy args(allocate_request, deallocate_request, - sizeof(typename Alloc::value_type)); - rml::MemPoolError res = rml::pool_create_v1(intptr_t(this), &args, &my_pool); - if (res!=rml::POOL_OK) - tbb::internal::throw_exception(std::runtime_error("Can't create pool")); -} -template -void *memory_pool::allocate_request(intptr_t pool_id, size_t & bytes) { - memory_pool &self = *reinterpret_cast*>(pool_id); - const size_t unit_size = sizeof(typename Alloc::value_type); - __TBBMALLOC_ASSERT( 0 == bytes%unit_size, NULL); - void *ptr; - __TBB_TRY { ptr = self.my_alloc.allocate( bytes/unit_size ); } - __TBB_CATCH(...) { return 0; } - return ptr; -} -#if __TBB_MSVC_UNREACHABLE_CODE_IGNORED - // Workaround for erroneous "unreachable code" warning in the template below. - // Specific for VC++ 17-18 compiler - #pragma warning (push) - #pragma warning (disable: 4702) -#endif -template -int memory_pool::deallocate_request(intptr_t pool_id, void* raw_ptr, size_t raw_bytes) { - memory_pool &self = *reinterpret_cast*>(pool_id); - const size_t unit_size = sizeof(typename Alloc::value_type); - __TBBMALLOC_ASSERT( 0 == raw_bytes%unit_size, NULL); - self.my_alloc.deallocate( static_cast(raw_ptr), raw_bytes/unit_size ); - return 0; -} -#if __TBB_MSVC_UNREACHABLE_CODE_IGNORED - #pragma warning (pop) -#endif -inline fixed_pool::fixed_pool(void *buf, size_t size) : my_buffer(buf), my_size(size) { - if (!buf || !size) - // TODO: improve support for mode with exceptions disabled - tbb::internal::throw_exception(std::invalid_argument("Zero in parameter is invalid")); - rml::MemPoolPolicy args(allocate_request, 0, size, /*fixedPool=*/true); - rml::MemPoolError res = rml::pool_create_v1(intptr_t(this), &args, &my_pool); - if (res!=rml::POOL_OK) - tbb::internal::throw_exception(std::runtime_error("Can't create pool")); -} -inline void *fixed_pool::allocate_request(intptr_t pool_id, size_t & bytes) { - fixed_pool &self = *reinterpret_cast(pool_id); - __TBBMALLOC_ASSERT(0 != self.my_size, "The buffer must not be used twice."); - bytes = self.my_size; - self.my_size = 0; // remember that buffer has been used - return self.my_buffer; -} - -} //namespace interface6 -using interface6::memory_pool_allocator; -using interface6::memory_pool; -using interface6::fixed_pool; -} //namespace tbb - -#undef __TBBMALLOC_ASSERT -#endif// __TBB_memory_pool_H diff --git a/lib/3rdParty/tbb/include/tbb/mutex.h b/lib/3rdParty/tbb/include/tbb/mutex.h deleted file mode 100644 index e40b4cd0..00000000 --- a/lib/3rdParty/tbb/include/tbb/mutex.h +++ /dev/null @@ -1,233 +0,0 @@ -/* - 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_mutex_H -#define __TBB_mutex_H - -#if _WIN32||_WIN64 -#include "machine/windows_api.h" -#else -#include -#endif /* _WIN32||_WIN64 */ - -#include -#include "aligned_space.h" -#include "tbb_stddef.h" -#include "tbb_profiling.h" - -namespace tbb { - -//! Wrapper around the platform's native lock. -/** @ingroup synchronization */ -class mutex : internal::mutex_copy_deprecated_and_disabled { -public: - //! Construct unacquired mutex. - mutex() { -#if TBB_USE_ASSERT || TBB_USE_THREADING_TOOLS - internal_construct(); -#else - #if _WIN32||_WIN64 - InitializeCriticalSectionEx(&impl, 4000, 0); - #else - int error_code = pthread_mutex_init(&impl,NULL); - if( error_code ) - tbb::internal::handle_perror(error_code,"mutex: pthread_mutex_init failed"); - #endif /* _WIN32||_WIN64*/ -#endif /* TBB_USE_ASSERT */ - }; - - ~mutex() { -#if TBB_USE_ASSERT - internal_destroy(); -#else - #if _WIN32||_WIN64 - DeleteCriticalSection(&impl); - #else - pthread_mutex_destroy(&impl); - - #endif /* _WIN32||_WIN64 */ -#endif /* TBB_USE_ASSERT */ - }; - - class scoped_lock; - friend class scoped_lock; - - //! The scoped locking pattern - /** It helps to avoid the common problem of forgetting to release lock. - It also nicely provides the "node" for queuing locks. */ - class scoped_lock : internal::no_copy { - public: - //! Construct lock that has not acquired a mutex. - scoped_lock() : my_mutex(NULL) {}; - - //! Acquire lock on given mutex. - scoped_lock( mutex& mutex ) { - acquire( mutex ); - } - - //! Release lock (if lock is held). - ~scoped_lock() { - if( my_mutex ) - release(); - } - - //! Acquire lock on given mutex. - void acquire( mutex& mutex ) { -#if TBB_USE_ASSERT - internal_acquire(mutex); -#else - mutex.lock(); - my_mutex = &mutex; -#endif /* TBB_USE_ASSERT */ - } - - //! Try acquire lock on given mutex. - bool try_acquire( mutex& mutex ) { -#if TBB_USE_ASSERT - return internal_try_acquire (mutex); -#else - bool result = mutex.try_lock(); - if( result ) - my_mutex = &mutex; - return result; -#endif /* TBB_USE_ASSERT */ - } - - //! Release lock - void release() { -#if TBB_USE_ASSERT - internal_release (); -#else - my_mutex->unlock(); - my_mutex = NULL; -#endif /* TBB_USE_ASSERT */ - } - - private: - //! The pointer to the current mutex to work - mutex* my_mutex; - - //! All checks from acquire using mutex.state were moved here - void __TBB_EXPORTED_METHOD internal_acquire( mutex& m ); - - //! All checks from try_acquire using mutex.state were moved here - bool __TBB_EXPORTED_METHOD internal_try_acquire( mutex& m ); - - //! All checks from release using mutex.state were moved here - void __TBB_EXPORTED_METHOD internal_release(); - - friend class mutex; - }; - - // Mutex traits - static const bool is_rw_mutex = false; - static const bool is_recursive_mutex = false; - static const bool is_fair_mutex = false; - - // ISO C++0x compatibility methods - - //! Acquire lock - void lock() { -#if TBB_USE_ASSERT - aligned_space tmp; - new(tmp.begin()) scoped_lock(*this); -#else - #if _WIN32||_WIN64 - EnterCriticalSection(&impl); - #else - int error_code = pthread_mutex_lock(&impl); - if( error_code ) - tbb::internal::handle_perror(error_code,"mutex: pthread_mutex_lock failed"); - #endif /* _WIN32||_WIN64 */ -#endif /* TBB_USE_ASSERT */ - } - - //! Try acquiring lock (non-blocking) - /** Return true if lock acquired; false otherwise. */ - bool try_lock() { -#if TBB_USE_ASSERT - aligned_space tmp; - scoped_lock& s = *tmp.begin(); - s.my_mutex = NULL; - return s.internal_try_acquire(*this); -#else - #if _WIN32||_WIN64 - return TryEnterCriticalSection(&impl)!=0; - #else - return pthread_mutex_trylock(&impl)==0; - #endif /* _WIN32||_WIN64 */ -#endif /* TBB_USE_ASSERT */ - } - - //! Release lock - void unlock() { -#if TBB_USE_ASSERT - aligned_space tmp; - scoped_lock& s = *tmp.begin(); - s.my_mutex = this; - s.internal_release(); -#else - #if _WIN32||_WIN64 - LeaveCriticalSection(&impl); - #else - pthread_mutex_unlock(&impl); - #endif /* _WIN32||_WIN64 */ -#endif /* TBB_USE_ASSERT */ - } - - //! Return native_handle - #if _WIN32||_WIN64 - typedef LPCRITICAL_SECTION native_handle_type; - #else - typedef pthread_mutex_t* native_handle_type; - #endif - native_handle_type native_handle() { return (native_handle_type) &impl; } - - enum state_t { - INITIALIZED=0x1234, - DESTROYED=0x789A, - HELD=0x56CD - }; -private: -#if _WIN32||_WIN64 - CRITICAL_SECTION impl; - enum state_t state; -#else - pthread_mutex_t impl; -#endif /* _WIN32||_WIN64 */ - - //! All checks from mutex constructor using mutex.state were moved here - void __TBB_EXPORTED_METHOD internal_construct(); - - //! All checks from mutex destructor using mutex.state were moved here - void __TBB_EXPORTED_METHOD internal_destroy(); - -#if _WIN32||_WIN64 -public: - //! Set the internal state - void set_state( state_t to ) { state = to; } -#endif -}; - -__TBB_DEFINE_PROFILING_SET_NAME(mutex) - -} // namespace tbb - -#endif /* __TBB_mutex_H */ diff --git a/lib/3rdParty/tbb/include/tbb/null_mutex.h b/lib/3rdParty/tbb/include/tbb/null_mutex.h deleted file mode 100644 index 85c660e3..00000000 --- a/lib/3rdParty/tbb/include/tbb/null_mutex.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - 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_null_mutex_H -#define __TBB_null_mutex_H - -#include "tbb_stddef.h" - -namespace tbb { - -//! A mutex which does nothing -/** A null_mutex does no operation and simulates success. - @ingroup synchronization */ -class null_mutex : internal::mutex_copy_deprecated_and_disabled { -public: - //! Represents acquisition of a mutex. - class scoped_lock : internal::no_copy { - public: - scoped_lock() {} - scoped_lock( null_mutex& ) {} - ~scoped_lock() {} - void acquire( null_mutex& ) {} - bool try_acquire( null_mutex& ) { return true; } - void release() {} - }; - - null_mutex() {} - - // Mutex traits - static const bool is_rw_mutex = false; - static const bool is_recursive_mutex = true; - static const bool is_fair_mutex = true; -}; - -} - -#endif /* __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 deleted file mode 100644 index fa0c8035..00000000 --- a/lib/3rdParty/tbb/include/tbb/null_rw_mutex.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - 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_null_rw_mutex_H -#define __TBB_null_rw_mutex_H - -#include "tbb_stddef.h" - -namespace tbb { - -//! A rw mutex which does nothing -/** A null_rw_mutex is a rw mutex that does nothing and simulates successful operation. - @ingroup synchronization */ -class null_rw_mutex : internal::mutex_copy_deprecated_and_disabled { -public: - //! Represents acquisition of a mutex. - class scoped_lock : internal::no_copy { - public: - scoped_lock() {} - scoped_lock( null_rw_mutex& , bool = true ) {} - ~scoped_lock() {} - void acquire( null_rw_mutex& , bool = true ) {} - bool upgrade_to_writer() { return true; } - bool downgrade_to_reader() { return true; } - bool try_acquire( null_rw_mutex& , bool = true ) { return true; } - void release() {} - }; - - null_rw_mutex() {} - - // Mutex traits - static const bool is_rw_mutex = true; - static const bool is_recursive_mutex = true; - static const bool is_fair_mutex = true; -}; - -} - -#endif /* __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 deleted file mode 100644 index 15275682..00000000 --- a/lib/3rdParty/tbb/include/tbb/parallel_do.h +++ /dev/null @@ -1,551 +0,0 @@ -/* - 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_parallel_do_H -#define __TBB_parallel_do_H - -#include "internal/_range_iterator.h" -#include "internal/_template_helpers.h" -#include "task.h" -#include "aligned_space.h" -#include - -namespace tbb { -namespace interface9 { -//! @cond INTERNAL -namespace internal { - template class parallel_do_feeder_impl; -} // namespace internal -//! @endcond - -//! Class the user supplied algorithm body uses to add new tasks -/** \param Item Work item type **/ - 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 **/ - template - class parallel_do_operator_selector - { - typedef parallel_do_feeder Feeder; - template - 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, __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, __TBB_FORWARDING_REF(A1) arg1, A2& arg2 ) - { - internal_call( obj, tbb::internal::forward(arg1), arg2, &Body::operator() ); - } - }; - - //! For internal use only. - /** Executes one iteration of a do. - @ingroup algorithms */ - template - class do_iteration_task: public task - { - typedef parallel_do_feeder_impl feeder_type; - - Item my_value; - feeder_type& my_feeder; - - do_iteration_task( const Item& value, feeder_type& feeder ) : - my_value(value), my_feeder(feeder) - {} - -#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 - { - parallel_do_operator_selector::call(*my_feeder.my_body, tbb::internal::move(my_value), my_feeder); - return NULL; - } - - template friend class parallel_do_feeder_impl; - }; // class do_iteration_task - - template - class do_iteration_task_iter: public task - { - typedef parallel_do_feeder_impl feeder_type; - - Iterator my_iter; - feeder_type& my_feeder; - - do_iteration_task_iter( const Iterator& iter, feeder_type& feeder ) : - my_iter(iter), my_feeder(feeder) - {} - - task* execute() __TBB_override - { - parallel_do_operator_selector::call(*my_feeder.my_body, *my_iter, my_feeder); - return NULL; - } - - template friend class do_group_task_forward; - template friend class do_group_task_input; - template friend class do_task_iter; - }; // class do_iteration_task_iter - - //! For internal use only. - /** Implements new task adding procedure. - @ingroup algorithms **/ - template - class parallel_do_feeder_impl : public parallel_do_feeder - { -#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(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; - - parallel_do_feeder_impl() - { - my_barrier = new( task::allocate_root() ) empty_task(); - __TBB_ASSERT(my_barrier, "root task allocation failed"); - } - -#if __TBB_TASK_GROUP_CONTEXT - parallel_do_feeder_impl(tbb::task_group_context &context) - { - my_barrier = new( task::allocate_root(context) ) empty_task(); - __TBB_ASSERT(my_barrier, "root task allocation failed"); - } -#endif - - ~parallel_do_feeder_impl() - { - my_barrier->destroy(*my_barrier); - } - }; // class parallel_do_feeder_impl - - - //! For internal use only - /** Unpacks a block of iterations. - @ingroup algorithms */ - - template - class do_group_task_forward: public task - { - static const size_t max_arg_size = 4; - - typedef parallel_do_feeder_impl feeder_type; - - feeder_type& my_feeder; - Iterator my_first; - size_t my_size; - - do_group_task_forward( Iterator first, size_t size, feeder_type& feeder ) - : my_feeder(feeder), my_first(first), my_size(size) - {} - - task* execute() __TBB_override - { - 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_first, my_feeder ); - ++my_first; - if( ++k==my_size ) break; - list.push_back(*t); - } - set_ref_count(int(k+1)); - spawn(list); - spawn_and_wait_for_all(*t); - return NULL; - } - - template friend class do_task_iter; - }; // class do_group_task_forward - - template - class do_group_task_input: public task - { - static const size_t max_arg_size = 4; - - typedef parallel_do_feeder_impl feeder_type; - - feeder_type& my_feeder; - size_t my_size; - aligned_space my_arg; - - do_group_task_input( feeder_type& feeder ) - : my_feeder(feeder), my_size(0) - {} - - task* execute() __TBB_override - { -#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( Item_iterator(my_arg.begin() + k), my_feeder ); - if( ++k==my_size ) break; - list.push_back(*t); - } - set_ref_count(int(k+1)); - spawn(list); - spawn_and_wait_for_all(*t); - return NULL; - } - - ~do_group_task_input(){ - for( size_t k=0; k~Item(); - } - - template friend class do_task_iter; - }; // class do_group_task_input - - //! For internal use only. - /** Gets block of iterations and packages them into a do_group_task. - @ingroup algorithms */ - template - class do_task_iter: public task - { - typedef parallel_do_feeder_impl feeder_type; - - public: - do_task_iter( Iterator first, Iterator last , feeder_type& feeder ) : - my_first(first), my_last(last), my_feeder(feeder) - {} - - private: - Iterator my_first; - Iterator my_last; - feeder_type& my_feeder; - - /* Do not merge run(xxx) and run_xxx() methods. They are separated in order - to make sure that compilers will eliminate unused argument of type xxx - (that is will not put it on stack). The sole purpose of this argument - is overload resolution. - - An alternative could be using template functions, but explicit specialization - of member function templates is not supported for non specialized class - 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. */ - task* execute() __TBB_override - { - typedef typename std::iterator_traits::iterator_category iterator_tag; - return run( (iterator_tag*)NULL ); - } - - /** This is the most restricted variant that operates on input iterators or - iterators with unknown tags (tags not derived from the standard ones). **/ - inline task* run( void* ) { return run_for_input_iterator(); } - - task* run_for_input_iterator() { - typedef do_group_task_input block_type; - - 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) ) { - // 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 ) { - if ( !(my_first == my_last) ) - recycle_to_reexecute(); - break; - } - } - if( k==0 ) { - destroy(t); - return NULL; - } else { - t.my_size = k; - return &t; - } - } - - inline task* run( std::forward_iterator_tag* ) { return run_for_forward_iterator(); } - - task* run_for_forward_iterator() { - typedef do_group_task_forward block_type; - - Iterator first = my_first; - size_t k=0; - while( !(my_first==my_last) ) { - ++my_first; - if( ++k==block_type::max_arg_size ) { - if ( !(my_first==my_last) ) - recycle_to_reexecute(); - break; - } - } - return k==0 ? NULL : new( allocate_additional_child_of(*my_feeder.my_barrier) ) block_type(first, k, my_feeder); - } - - inline task* run( std::random_access_iterator_tag* ) { return run_for_random_access_iterator(); } - - task* run_for_random_access_iterator() { - typedef do_group_task_forward block_type; - typedef do_iteration_task_iter iteration_type; - - size_t k = static_cast(my_last-my_first); - if( k > block_type::max_arg_size ) { - Iterator middle = my_first + k/2; - - empty_task& c = *new( allocate_continuation() ) empty_task; - do_task_iter& b = *new( c.allocate_child() ) do_task_iter(middle, my_last, my_feeder); - recycle_as_child_of(c); - - my_last = middle; - c.set_ref_count(2); - c.spawn(b); - return this; - }else if( k != 0 ) { - task_list list; - task* t; - size_t k1=0; - for(;;) { - t = new( allocate_child() ) iteration_type(my_first, my_feeder); - ++my_first; - if( ++k1==k ) break; - list.push_back(*t); - } - set_ref_count(int(k+1)); - spawn(list); - spawn_and_wait_for_all(*t); - } - return NULL; - } - }; // class do_task_iter - - //! For internal use only. - /** Implements parallel iteration over a range. - @ingroup algorithms */ - template - void run_parallel_do( Iterator first, Iterator last, const Body& body -#if __TBB_TASK_GROUP_CONTEXT - , task_group_context& context -#endif - ) - { - typedef do_task_iter root_iteration_task; -#if __TBB_TASK_GROUP_CONTEXT - parallel_do_feeder_impl feeder(context); -#else - parallel_do_feeder_impl feeder; -#endif - feeder.my_body = &body; - - root_iteration_task &t = *new( feeder.my_barrier->allocate_child() ) root_iteration_task(first, last, feeder); - - feeder.my_barrier->set_ref_count(2); - feeder.my_barrier->spawn_and_wait_for_all(t); - } - - //! For internal use only. - /** Detects types of Body's operator function arguments. - @ingroup algorithms **/ - template - 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 - ) - { - run_parallel_do::type>( first, last, body -#if __TBB_TASK_GROUP_CONTEXT - , context -#endif - ); - } - - //! For internal use only. - /** Detects types of Body's operator function arguments. - @ingroup algorithms **/ - template - 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 - ) - { - run_parallel_do::type>( first, last, body -#if __TBB_TASK_GROUP_CONTEXT - , 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 - B::operator()( - cv_item_type item, - parallel_do_feeder& feeder - ) const - - OR - - B::operator()( cv_item_type& item ) const - \endcode Process item. - May be invoked concurrently for the same \c this but different \c item. - - - \code item_type( const item_type& ) \endcode - Copy a work item. - - \code ~item_type() \endcode Destroy a work item -**/ - -/** \name parallel_do - See also requirements on \ref parallel_do_body_req "parallel_do Body". **/ -//@{ -//! Parallel iteration over a range, with optional addition of more work. -/** @ingroup algorithms */ -template -void parallel_do( Iterator first, Iterator last, const Body& body ) -{ - if ( first == last ) - return; -#if __TBB_TASK_GROUP_CONTEXT - task_group_context context; -#endif - interface9::internal::select_parallel_do( first, last, body, &Body::operator() -#if __TBB_TASK_GROUP_CONTEXT - , context -#endif - ); -} - -template -void parallel_do(Range& rng, const Body& body) { - parallel_do(tbb::internal::first(rng), tbb::internal::last(rng), body); -} - -template -void parallel_do(const Range& rng, const Body& body) { - parallel_do(tbb::internal::first(rng), tbb::internal::last(rng), body); -} - -#if __TBB_TASK_GROUP_CONTEXT -//! Parallel iteration over a range, with optional addition of more work and user-supplied context -/** @ingroup algorithms */ -template -void parallel_do( Iterator first, Iterator last, const Body& body, task_group_context& context ) -{ - if ( first == last ) - return; - interface9::internal::select_parallel_do( first, last, body, &Body::operator(), context ); -} - -template -void parallel_do(Range& rng, const Body& body, task_group_context& context) { - parallel_do(tbb::internal::first(rng), tbb::internal::last(rng), body, context); -} - -template -void parallel_do(const Range& rng, const Body& body, task_group_context& context) { - parallel_do(tbb::internal::first(rng), tbb::internal::last(rng), body, context); -} - -#endif // __TBB_TASK_GROUP_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 deleted file mode 100644 index 2cab6586..00000000 --- a/lib/3rdParty/tbb/include/tbb/parallel_for.h +++ /dev/null @@ -1,407 +0,0 @@ -/* - 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_parallel_for_H -#define __TBB_parallel_for_H - -#include -#include "task.h" -#include "partitioner.h" -#include "blocked_range.h" -#include "tbb_exception.h" - -namespace tbb { - -namespace interface9 { -//! @cond INTERNAL -namespace internal { - - //! allocate right task with new parent - void* allocate_sibling(task* start_for_task, size_t bytes); - - //! Task type used in parallel_for - /** @ingroup algorithms */ - template - class start_for: public task { - Range my_range; - const Body my_body; - typename Partitioner::task_partition_type my_partition; - task* execute() __TBB_override; - - //! Update affinity info, if any. - void note_affinity( affinity_id id ) __TBB_override { - my_partition.note_affinity( id ); - } - - public: - //! Constructor for root task. - start_for( const Range& range, const Body& body, Partitioner& partitioner ) : - my_range(range), - my_body(body), - my_partition(partitioner) - { - } - //! Splitting constructor used to generate children. - /** parent_ becomes left child. Newly constructed object is right child. */ - start_for( start_for& parent_, typename Partitioner::split_type& split_obj) : - my_range(parent_.my_range, split_obj), - my_body(parent_.my_body), - my_partition(parent_.my_partition, split_obj) - { - my_partition.set_affinity(*this); - } - //! Construct right child from the given range as response to the demand. - /** parent_ remains left child. Newly constructed object is right child. */ - start_for( start_for& parent_, const Range& r, depth_t d ) : - my_range(r), - my_body(parent_.my_body), - my_partition(parent_.my_partition, split()) - { - my_partition.set_affinity(*this); - my_partition.align_depth( d ); - } - static void run( const Range& range, const Body& body, Partitioner& partitioner ) { - if( !range.empty() ) { -#if !__TBB_TASK_GROUP_CONTEXT || TBB_JOIN_OUTER_TASK_GROUP - start_for& a = *new(task::allocate_root()) start_for(range,body,partitioner); -#else - // Bound context prevents exceptions from body to affect nesting or sibling algorithms, - // and allows users to handle exceptions safely by wrapping parallel_for in the try-block. - task_group_context context; - start_for& a = *new(task::allocate_root(context)) start_for(range,body,partitioner); -#endif /* __TBB_TASK_GROUP_CONTEXT && !TBB_JOIN_OUTER_TASK_GROUP */ - task::spawn_root_and_wait(a); - } - } -#if __TBB_TASK_GROUP_CONTEXT - static void run( const Range& range, const Body& body, Partitioner& partitioner, task_group_context& context ) { - if( !range.empty() ) { - start_for& a = *new(task::allocate_root(context)) start_for(range,body,partitioner); - task::spawn_root_and_wait(a); - } - } -#endif /* __TBB_TASK_GROUP_CONTEXT */ - //! Run body for range, serves as callback for partitioner - void run_body( Range &r ) { my_body( r ); } - - //! spawn right task, serves as callback for partitioner - void offer_work(typename Partitioner::split_type& split_obj) { - spawn( *new( allocate_sibling(static_cast(this), sizeof(start_for)) ) start_for(*this, split_obj) ); - } - //! spawn right task, serves as callback for partitioner - void offer_work(const Range& r, depth_t d = 0) { - spawn( *new( allocate_sibling(static_cast(this), sizeof(start_for)) ) start_for(*this, r, d) ); - } - }; - - //! allocate right task with new parent - // TODO: 'inline' here is to avoid multiple definition error but for sake of code size this should not be inlined - inline void* allocate_sibling(task* start_for_task, size_t bytes) { - task* parent_ptr = new( start_for_task->allocate_continuation() ) flag_task(); - start_for_task->set_parent(parent_ptr); - parent_ptr->set_ref_count(2); - return &parent_ptr->allocate_child().allocate(bytes); - } - - //! execute task for parallel_for - template - task* start_for::execute() { - my_partition.check_being_stolen( *this ); - my_partition.execute(*this, my_range); - return NULL; - } -} // namespace internal -//! @endcond -} // namespace interfaceX - -//! @cond INTERNAL -namespace internal { - using interface9::internal::start_for; - - //! Calls the function with values from range [begin, end) with a step provided - template - class parallel_for_body : internal::no_assign { - const Function &my_func; - const Index my_begin; - const Index my_step; - public: - parallel_for_body( const Function& _func, Index& _begin, Index& _step ) - : my_func(_func), my_begin(_begin), my_step(_step) {} - - void operator()( const tbb::blocked_range& r ) const { - // A set of local variables to help the compiler with vectorization of the following loop. - Index b = r.begin(); - Index e = r.end(); - Index ms = my_step; - Index k = my_begin + b*ms; - -#if __INTEL_COMPILER -#pragma ivdep -#if __TBB_ASSERT_ON_VECTORIZATION_FAILURE -#pragma vector always assert -#endif -#endif - for ( Index i = b; i < e; ++i, k += ms ) { - my_func( k ); - } - } - }; -} // namespace internal -//! @endcond - -// Requirements on Range concept are documented in blocked_range.h - -/** \page parallel_for_body_req Requirements on parallel_for body - Class \c Body implementing the concept of parallel_for body must define: - - \code Body::Body( const Body& ); \endcode Copy constructor - - \code Body::~Body(); \endcode Destructor - - \code void Body::operator()( Range& r ) const; \endcode Function call operator applying the body to range \c r. -**/ - -/** \name parallel_for - See also requirements on \ref range_req "Range" and \ref parallel_for_body_req "parallel_for Body". **/ -//@{ - -//! Parallel iteration over range with default partitioner. -/** @ingroup algorithms **/ -template -void parallel_for( const Range& range, const Body& body ) { - internal::start_for::run(range,body,__TBB_DEFAULT_PARTITIONER()); -} - -//! Parallel iteration over range with simple partitioner. -/** @ingroup algorithms **/ -template -void parallel_for( const Range& range, const Body& body, const simple_partitioner& partitioner ) { - internal::start_for::run(range,body,partitioner); -} - -//! Parallel iteration over range with auto_partitioner. -/** @ingroup algorithms **/ -template -void parallel_for( const Range& range, const Body& body, const auto_partitioner& partitioner ) { - internal::start_for::run(range,body,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); -} - -//! Parallel iteration over range with affinity_partitioner. -/** @ingroup algorithms **/ -template -void parallel_for( const Range& range, const Body& body, affinity_partitioner& partitioner ) { - internal::start_for::run(range,body,partitioner); -} - -#if __TBB_TASK_GROUP_CONTEXT -//! Parallel iteration over range with default partitioner and user-supplied context. -/** @ingroup algorithms **/ -template -void parallel_for( const Range& range, const Body& body, task_group_context& context ) { - internal::start_for::run(range, body, __TBB_DEFAULT_PARTITIONER(), context); -} - -//! Parallel iteration over range with simple partitioner and user-supplied context. -/** @ingroup algorithms **/ -template -void parallel_for( const Range& range, const Body& body, const simple_partitioner& partitioner, task_group_context& context ) { - internal::start_for::run(range, body, partitioner, context); -} - -//! Parallel iteration over range with auto_partitioner and user-supplied context. -/** @ingroup algorithms **/ -template -void parallel_for( const Range& range, const Body& body, const auto_partitioner& partitioner, task_group_context& context ) { - internal::start_for::run(range, body, partitioner, context); -} - -//! 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); -} - -//! Parallel iteration over range with affinity_partitioner and user-supplied context. -/** @ingroup algorithms **/ -template -void parallel_for( const Range& range, const Body& body, affinity_partitioner& partitioner, task_group_context& context ) { - internal::start_for::run(range,body,partitioner, context); -} -#endif /* __TBB_TASK_GROUP_CONTEXT */ -//@} - -namespace strict_ppl { - -//@{ -//! Implementation of parallel iteration over stepped range of integers with explicit step and partitioner -template -void parallel_for_impl(Index first, Index last, Index step, const Function& f, Partitioner& partitioner) { - if (step <= 0 ) - internal::throw_exception(internal::eid_nonpositive_step); // throws std::invalid_argument - else if (last > first) { - // Above "else" avoids "potential divide by zero" warning on some platforms - Index end = (last - first - Index(1)) / step + Index(1); - tbb::blocked_range range(static_cast(0), end); - internal::parallel_for_body body(f, first, step); - tbb::parallel_for(range, body, partitioner); - } -} - -//! Parallel iteration over a range of integers with a step provided and default partitioner -template -void parallel_for(Index first, Index last, Index step, const Function& f) { - parallel_for_impl(first, last, step, f, auto_partitioner()); -} -//! Parallel iteration over a range of integers with a step provided and simple partitioner -template -void parallel_for(Index first, Index last, Index step, const Function& f, const simple_partitioner& partitioner) { - parallel_for_impl(first, last, step, f, partitioner); -} -//! Parallel iteration over a range of integers with a step provided and auto partitioner -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); -} -//! 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); -} -//! 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) { - parallel_for_impl(first, last, step, f, partitioner); -} - -//! Parallel iteration over a range of integers with a default step value and default partitioner -template -void parallel_for(Index first, Index last, const Function& f) { - parallel_for_impl(first, last, static_cast(1), f, auto_partitioner()); -} -//! Parallel iteration over a range of integers with a default step value and simple partitioner -template -void parallel_for(Index first, Index last, const Function& f, const simple_partitioner& partitioner) { - parallel_for_impl(first, last, static_cast(1), f, partitioner); -} -//! Parallel iteration over a range of integers with a default step value and auto partitioner -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); -} -//! 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); -} -//! 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) { - parallel_for_impl(first, last, static_cast(1), f, partitioner); -} - -#if __TBB_TASK_GROUP_CONTEXT -//! Implementation of parallel iteration over stepped range of integers with explicit step, task group context, and partitioner -template -void parallel_for_impl(Index first, Index last, Index step, const Function& f, Partitioner& partitioner, tbb::task_group_context &context) { - if (step <= 0 ) - internal::throw_exception(internal::eid_nonpositive_step); // throws std::invalid_argument - else if (last > first) { - // Above "else" avoids "potential divide by zero" warning on some platforms - Index end = (last - first - Index(1)) / step + Index(1); - tbb::blocked_range range(static_cast(0), end); - internal::parallel_for_body body(f, first, step); - tbb::parallel_for(range, body, partitioner, context); - } -} - -//! Parallel iteration over a range of integers with explicit step, task group context, and default partitioner -template -void parallel_for(Index first, Index last, Index step, const Function& f, tbb::task_group_context &context) { - parallel_for_impl(first, last, step, f, auto_partitioner(), context); -} -//! Parallel iteration over a range of integers with explicit step, task group context, and simple partitioner - template -void parallel_for(Index first, Index last, Index step, const Function& f, const simple_partitioner& partitioner, tbb::task_group_context &context) { - parallel_for_impl(first, last, step, f, partitioner, context); -} -//! Parallel iteration over a range of integers with explicit step, task group context, and auto partitioner - template -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); -} -//! 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); -} -//! 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) { - parallel_for_impl(first, last, step, f, partitioner, context); -} - - -//! Parallel iteration over a range of integers with a default step value, explicit task group context, and default partitioner -template -void parallel_for(Index first, Index last, const Function& f, tbb::task_group_context &context) { - parallel_for_impl(first, last, static_cast(1), f, auto_partitioner(), context); -} -//! Parallel iteration over a range of integers with a default step value, explicit task group context, and simple partitioner - template -void parallel_for(Index first, Index last, const Function& f, const simple_partitioner& partitioner, tbb::task_group_context &context) { - parallel_for_impl(first, last, static_cast(1), f, partitioner, context); -} -//! Parallel iteration over a range of integers with a default step value, explicit task group context, and auto partitioner - template -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); -} -//! 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); -} -//! 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) { - parallel_for_impl(first, last, static_cast(1), f, partitioner, context); -} - -#endif /* __TBB_TASK_GROUP_CONTEXT */ -//@} - -} // namespace strict_ppl - -using strict_ppl::parallel_for; - -} // namespace tbb - -#if TBB_PREVIEW_SERIAL_SUBSET -#define __TBB_NORMAL_EXECUTION -#include "../serial/tbb/parallel_for.h" -#undef __TBB_NORMAL_EXECUTION -#endif - -#endif /* __TBB_parallel_for_H */ diff --git a/lib/3rdParty/tbb/include/tbb/parallel_for_each.h b/lib/3rdParty/tbb/include/tbb/parallel_for_each.h deleted file mode 100644 index 6c2ec9f0..00000000 --- a/lib/3rdParty/tbb/include/tbb/parallel_for_each.h +++ /dev/null @@ -1,137 +0,0 @@ -/* - 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_parallel_for_each_H -#define __TBB_parallel_for_each_H - -#include "parallel_do.h" -#include "parallel_for.h" - -namespace tbb { - -//! @cond INTERNAL -namespace internal { - // The class calls user function in operator() - template - class parallel_for_each_body_do : internal::no_assign { - const Function &my_func; - public: - parallel_for_each_body_do(const Function &_func) : my_func(_func) {} - - void operator()(typename std::iterator_traits::reference value) const { - my_func(value); - } - }; - - // The class calls user function in operator() - template - class parallel_for_each_body_for : internal::no_assign { - const Function &my_func; - public: - parallel_for_each_body_for(const Function &_func) : my_func(_func) {} - - void operator()(tbb::blocked_range range) const { -#if __INTEL_COMPILER -#pragma ivdep -#endif - for(Iterator it = range.begin(), end = range.end(); it != end; ++it) { - my_func(*it); - } - } - }; - - template - struct parallel_for_each_impl { -#if __TBB_TASK_GROUP_CONTEXT - static void doit(Iterator first, Iterator last, const Function& f, task_group_context &context) { - internal::parallel_for_each_body_do body(f); - tbb::parallel_do(first, last, body, context); - } -#endif - static void doit(Iterator first, Iterator last, const Function& f) { - internal::parallel_for_each_body_do body(f); - tbb::parallel_do(first, last, body); - } - }; - template - struct parallel_for_each_impl { -#if __TBB_TASK_GROUP_CONTEXT - static void doit(Iterator first, Iterator last, const Function& f, task_group_context &context) { - internal::parallel_for_each_body_for body(f); - tbb::parallel_for(tbb::blocked_range(first, last), body, context); - } -#endif - static void doit(Iterator first, Iterator last, const Function& f) { - internal::parallel_for_each_body_for body(f); - tbb::parallel_for(tbb::blocked_range(first, last), body); - } - }; -} // namespace internal -//! @endcond - -/** \name parallel_for_each - **/ -//@{ -//! Calls function f for all items from [first, last) interval using user-supplied context -/** @ingroup algorithms */ -#if __TBB_TASK_GROUP_CONTEXT -template -void parallel_for_each(Iterator first, Iterator last, const Function& f, task_group_context &context) { - internal::parallel_for_each_impl::iterator_category>::doit(first, last, f, context); -} - -//! Calls function f for all items from rng using user-supplied context -/** @ingroup algorithms */ -template -void parallel_for_each(Range& rng, const Function& f, task_group_context& context) { - parallel_for_each(tbb::internal::first(rng), tbb::internal::last(rng), f, context); -} - -//! Calls function f for all items from const rng user-supplied context -/** @ingroup algorithms */ -template -void parallel_for_each(const Range& rng, const Function& f, task_group_context& context) { - parallel_for_each(tbb::internal::first(rng), tbb::internal::last(rng), f, context); -} -#endif /* __TBB_TASK_GROUP_CONTEXT */ - -//! Uses default context -template -void parallel_for_each(Iterator first, Iterator last, const Function& f) { - internal::parallel_for_each_impl::iterator_category>::doit(first, last, f); -} - -//! Uses default context -template -void parallel_for_each(Range& rng, const Function& f) { - parallel_for_each(tbb::internal::first(rng), tbb::internal::last(rng), f); -} - -//! Uses default context -template -void parallel_for_each(const Range& rng, const Function& f) { - parallel_for_each(tbb::internal::first(rng), tbb::internal::last(rng), f); -} - -//@} - -} // namespace - -#endif /* __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 deleted file mode 100644 index 0dd7590e..00000000 --- a/lib/3rdParty/tbb/include/tbb/parallel_invoke.h +++ /dev/null @@ -1,455 +0,0 @@ -/* - 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_parallel_invoke_H -#define __TBB_parallel_invoke_H - -#include "task.h" - -#if __TBB_VARIADIC_PARALLEL_INVOKE - #include // std::forward -#endif - -namespace tbb { - -#if !__TBB_TASK_GROUP_CONTEXT - /** Dummy to avoid cluttering the bulk of the header with enormous amount of ifdefs. **/ - struct task_group_context {}; -#endif /* __TBB_TASK_GROUP_CONTEXT */ - -//! @cond INTERNAL -namespace internal { - // Simple task object, executing user method - template - class function_invoker : public task{ - public: - function_invoker(const function& _function) : my_function(_function) {} - private: - const function &my_function; - task* execute() __TBB_override - { - my_function(); - return NULL; - } - }; - - // The class spawns two or three child tasks - template - class spawner : public task { - private: - const function1& my_func1; - const function2& my_func2; - const function3& my_func3; - bool is_recycled; - - task* execute () __TBB_override { - if(is_recycled){ - return NULL; - }else{ - __TBB_ASSERT(N==2 || N==3, "Number of arguments passed to spawner is wrong"); - set_ref_count(N); - recycle_as_safe_continuation(); - internal::function_invoker* invoker2 = new (allocate_child()) internal::function_invoker(my_func2); - __TBB_ASSERT(invoker2, "Child task allocation failed"); - spawn(*invoker2); - size_t n = N; // To prevent compiler warnings - if (n>2) { - internal::function_invoker* invoker3 = new (allocate_child()) internal::function_invoker(my_func3); - __TBB_ASSERT(invoker3, "Child task allocation failed"); - spawn(*invoker3); - } - my_func1(); - is_recycled = true; - return NULL; - } - } // execute - - public: - spawner(const function1& _func1, const function2& _func2, const function3& _func3) : my_func1(_func1), my_func2(_func2), my_func3(_func3), is_recycled(false) {} - }; - - // Creates and spawns child tasks - class parallel_invoke_helper : public empty_task { - public: - // Dummy functor class - class parallel_invoke_noop { - public: - void operator() () const {} - }; - // Creates a helper object with user-defined number of children expected - parallel_invoke_helper(int number_of_children) - { - set_ref_count(number_of_children + 1); - } - -#if __TBB_VARIADIC_PARALLEL_INVOKE - void add_children() {} - void add_children(tbb::task_group_context&) {} - - template - void add_children(function&& _func) - { - internal::function_invoker* invoker = new (allocate_child()) internal::function_invoker(std::forward(_func)); - __TBB_ASSERT(invoker, "Child task allocation failed"); - spawn(*invoker); - } - - template - void add_children(function&& _func, tbb::task_group_context&) - { - add_children(std::forward(_func)); - } - - // Adds child(ren) task(s) and spawns them - template - void add_children(function1&& _func1, function2&& _func2, function&&... _func) - { - // The third argument is dummy, it is ignored actually. - parallel_invoke_noop noop; - typedef internal::spawner<2, function1, function2, parallel_invoke_noop> spawner_type; - spawner_type & sub_root = *new(allocate_child()) spawner_type(std::forward(_func1), std::forward(_func2), noop); - spawn(sub_root); - add_children(std::forward(_func)...); - } -#else - // Adds child task and spawns it - template - void add_children (const function &_func) - { - internal::function_invoker* invoker = new (allocate_child()) internal::function_invoker(_func); - __TBB_ASSERT(invoker, "Child task allocation failed"); - spawn(*invoker); - } - - // Adds a task with multiple child tasks and spawns it - // two arguments - template - void add_children (const function1& _func1, const function2& _func2) - { - // The third argument is dummy, it is ignored actually. - parallel_invoke_noop noop; - internal::spawner<2, function1, function2, parallel_invoke_noop>& sub_root = *new(allocate_child())internal::spawner<2, function1, function2, parallel_invoke_noop>(_func1, _func2, noop); - spawn(sub_root); - } - // three arguments - template - void add_children (const function1& _func1, const function2& _func2, const function3& _func3) - { - internal::spawner<3, function1, function2, function3>& sub_root = *new(allocate_child())internal::spawner<3, function1, function2, function3>(_func1, _func2, _func3); - spawn(sub_root); - } -#endif // __TBB_VARIADIC_PARALLEL_INVOKE - - // Waits for all child tasks - template - void run_and_finish(const F0& f0) - { - internal::function_invoker* invoker = new (allocate_child()) internal::function_invoker(f0); - __TBB_ASSERT(invoker, "Child task allocation failed"); - spawn_and_wait_for_all(*invoker); - } - }; - // The class destroys root if exception occurred as well as in normal case - class parallel_invoke_cleaner: internal::no_copy { - public: -#if __TBB_TASK_GROUP_CONTEXT - parallel_invoke_cleaner(int number_of_children, tbb::task_group_context& context) - : root(*new(task::allocate_root(context)) internal::parallel_invoke_helper(number_of_children)) -#else - parallel_invoke_cleaner(int number_of_children, tbb::task_group_context&) - : root(*new(task::allocate_root()) internal::parallel_invoke_helper(number_of_children)) -#endif /* !__TBB_TASK_GROUP_CONTEXT */ - {} - - ~parallel_invoke_cleaner(){ - root.destroy(root); - } - internal::parallel_invoke_helper& root; - }; - -#if __TBB_VARIADIC_PARALLEL_INVOKE -// Determine whether the last parameter in a pack is task_group_context - template struct impl_selector; // to workaround a GCC bug - - template struct impl_selector { - typedef typename impl_selector::type type; - }; - - template struct impl_selector { - typedef false_type type; - }; - template<> struct impl_selector { - typedef true_type type; - }; - - // Select task_group_context parameter from the back of a pack - inline task_group_context& get_context( task_group_context& tgc ) { return tgc; } - - template - task_group_context& get_context( T1&& /*ignored*/, T&&... t ) - { return get_context( std::forward(t)... ); } - - // task_group_context is known to be at the back of the parameter pack - template - void parallel_invoke_impl(true_type, F0&& f0, F1&& f1, F&&... f) { - __TBB_STATIC_ASSERT(sizeof...(F)>0, "Variadic parallel_invoke implementation broken?"); - // # of child tasks: f0, f1, and a task for each two elements of the pack except the last - const size_t number_of_children = 2 + sizeof...(F)/2; - parallel_invoke_cleaner cleaner(number_of_children, get_context(std::forward(f)...)); - parallel_invoke_helper& root = cleaner.root; - - root.add_children(std::forward(f)...); - root.add_children(std::forward(f1)); - root.run_and_finish(std::forward(f0)); - } - - // task_group_context is not in the pack, needs to be added - template - void parallel_invoke_impl(false_type, F0&& f0, F1&& f1, F&&... f) { - tbb::task_group_context context; - // Add context to the arguments, and redirect to the other overload - parallel_invoke_impl(true_type(), std::forward(f0), std::forward(f1), std::forward(f)..., context); - } -#endif -} // namespace internal -//! @endcond - -/** \name parallel_invoke - **/ -//@{ -//! Executes a list of tasks in parallel and waits for all tasks to complete. -/** @ingroup algorithms */ - -#if __TBB_VARIADIC_PARALLEL_INVOKE - -// parallel_invoke for two or more arguments via variadic templates -// presence of task_group_context is defined automatically -template -void parallel_invoke(F0&& f0, F1&& f1, F&&... f) { - typedef typename internal::impl_selector::type selector_type; - internal::parallel_invoke_impl(selector_type(), std::forward(f0), std::forward(f1), std::forward(f)...); -} - -#else - -// parallel_invoke with user-defined context -// two arguments -template -void parallel_invoke(const F0& f0, const F1& f1, tbb::task_group_context& context) { - internal::parallel_invoke_cleaner cleaner(2, context); - internal::parallel_invoke_helper& root = cleaner.root; - - root.add_children(f1); - - root.run_and_finish(f0); -} - -// three arguments -template -void parallel_invoke(const F0& f0, const F1& f1, const F2& f2, tbb::task_group_context& context) { - internal::parallel_invoke_cleaner cleaner(3, context); - internal::parallel_invoke_helper& root = cleaner.root; - - root.add_children(f2); - root.add_children(f1); - - root.run_and_finish(f0); -} - -// four arguments -template -void parallel_invoke(const F0& f0, const F1& f1, const F2& f2, const F3& f3, - tbb::task_group_context& context) -{ - internal::parallel_invoke_cleaner cleaner(4, context); - internal::parallel_invoke_helper& root = cleaner.root; - - root.add_children(f3); - root.add_children(f2); - root.add_children(f1); - - root.run_and_finish(f0); -} - -// five arguments -template -void parallel_invoke(const F0& f0, const F1& f1, const F2& f2, const F3& f3, const F4& f4, - tbb::task_group_context& context) -{ - internal::parallel_invoke_cleaner cleaner(3, context); - internal::parallel_invoke_helper& root = cleaner.root; - - root.add_children(f4, f3); - root.add_children(f2, f1); - - root.run_and_finish(f0); -} - -// six arguments -template -void parallel_invoke(const F0& f0, const F1& f1, const F2& f2, const F3& f3, const F4& f4, const F5& f5, - tbb::task_group_context& context) -{ - internal::parallel_invoke_cleaner cleaner(3, context); - internal::parallel_invoke_helper& root = cleaner.root; - - root.add_children(f5, f4, f3); - root.add_children(f2, f1); - - root.run_and_finish(f0); -} - -// seven arguments -template -void parallel_invoke(const F0& f0, const F1& f1, const F2& f2, const F3& f3, const F4& f4, - const F5& f5, const F6& f6, - tbb::task_group_context& context) -{ - internal::parallel_invoke_cleaner cleaner(3, context); - internal::parallel_invoke_helper& root = cleaner.root; - - root.add_children(f6, f5, f4); - root.add_children(f3, f2, f1); - - root.run_and_finish(f0); -} - -// eight arguments -template -void parallel_invoke(const F0& f0, const F1& f1, const F2& f2, const F3& f3, const F4& f4, - const F5& f5, const F6& f6, const F7& f7, - tbb::task_group_context& context) -{ - internal::parallel_invoke_cleaner cleaner(4, context); - internal::parallel_invoke_helper& root = cleaner.root; - - root.add_children(f7, f6, f5); - root.add_children(f4, f3); - root.add_children(f2, f1); - - root.run_and_finish(f0); -} - -// nine arguments -template -void parallel_invoke(const F0& f0, const F1& f1, const F2& f2, const F3& f3, const F4& f4, - const F5& f5, const F6& f6, const F7& f7, const F8& f8, - tbb::task_group_context& context) -{ - internal::parallel_invoke_cleaner cleaner(4, context); - internal::parallel_invoke_helper& root = cleaner.root; - - root.add_children(f8, f7, f6); - root.add_children(f5, f4, f3); - root.add_children(f2, f1); - - root.run_and_finish(f0); -} - -// ten arguments -template -void parallel_invoke(const F0& f0, const F1& f1, const F2& f2, const F3& f3, const F4& f4, - const F5& f5, const F6& f6, const F7& f7, const F8& f8, const F9& f9, - tbb::task_group_context& context) -{ - internal::parallel_invoke_cleaner cleaner(4, context); - internal::parallel_invoke_helper& root = cleaner.root; - - root.add_children(f9, f8, f7); - root.add_children(f6, f5, f4); - root.add_children(f3, f2, f1); - - root.run_and_finish(f0); -} - -// two arguments -template -void parallel_invoke(const F0& f0, const F1& f1) { - task_group_context context; - parallel_invoke(f0, f1, context); -} -// three arguments -template -void parallel_invoke(const F0& f0, const F1& f1, const F2& f2) { - task_group_context context; - parallel_invoke(f0, f1, f2, context); -} -// four arguments -template -void parallel_invoke(const F0& f0, const F1& f1, const F2& f2, const F3& f3) { - task_group_context context; - parallel_invoke(f0, f1, f2, f3, context); -} -// five arguments -template -void parallel_invoke(const F0& f0, const F1& f1, const F2& f2, const F3& f3, const F4& f4) { - task_group_context context; - parallel_invoke(f0, f1, f2, f3, f4, context); -} -// six arguments -template -void parallel_invoke(const F0& f0, const F1& f1, const F2& f2, const F3& f3, const F4& f4, const F5& f5) { - task_group_context context; - parallel_invoke(f0, f1, f2, f3, f4, f5, context); -} -// seven arguments -template -void parallel_invoke(const F0& f0, const F1& f1, const F2& f2, const F3& f3, const F4& f4, - const F5& f5, const F6& f6) -{ - task_group_context context; - parallel_invoke(f0, f1, f2, f3, f4, f5, f6, context); -} -// eight arguments -template -void parallel_invoke(const F0& f0, const F1& f1, const F2& f2, const F3& f3, const F4& f4, - const F5& f5, const F6& f6, const F7& f7) -{ - task_group_context context; - parallel_invoke(f0, f1, f2, f3, f4, f5, f6, f7, context); -} -// nine arguments -template -void parallel_invoke(const F0& f0, const F1& f1, const F2& f2, const F3& f3, const F4& f4, - const F5& f5, const F6& f6, const F7& f7, const F8& f8) -{ - task_group_context context; - parallel_invoke(f0, f1, f2, f3, f4, f5, f6, f7, f8, context); -} -// ten arguments -template -void parallel_invoke(const F0& f0, const F1& f1, const F2& f2, const F3& f3, const F4& f4, - const F5& f5, const F6& f6, const F7& f7, const F8& f8, const F9& f9) -{ - task_group_context context; - parallel_invoke(f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, context); -} -#endif // __TBB_VARIADIC_PARALLEL_INVOKE -//@} - -} // namespace - -#endif /* __TBB_parallel_invoke_H */ diff --git a/lib/3rdParty/tbb/include/tbb/parallel_reduce.h b/lib/3rdParty/tbb/include/tbb/parallel_reduce.h deleted file mode 100644 index 0596ae03..00000000 --- a/lib/3rdParty/tbb/include/tbb/parallel_reduce.h +++ /dev/null @@ -1,569 +0,0 @@ -/* - 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_parallel_reduce_H -#define __TBB_parallel_reduce_H - -#include -#include "task.h" -#include "aligned_space.h" -#include "partitioner.h" -#include "tbb_profiling.h" - -namespace tbb { - -namespace interface9 { -//! @cond INTERNAL -namespace internal { - - using namespace tbb::internal; - - /** Values for reduction_context. */ - enum { - root_task, left_child, right_child - }; - - /** Represented as a char, not enum, for compactness. */ - typedef char reduction_context; - - //! Task type used to combine the partial results of parallel_reduce. - /** @ingroup algorithms */ - template - class finish_reduce: public flag_task { - //! Pointer to body, or NULL if the left child has not yet finished. - bool has_right_zombie; - const reduction_context my_context; - Body* my_body; - aligned_space zombie_space; - finish_reduce( reduction_context context_ ) : - has_right_zombie(false), // TODO: substitute by flag_task::child_stolen? - my_context(context_), - my_body(NULL) - { - } - ~finish_reduce() { - if( has_right_zombie ) - zombie_space.begin()->~Body(); - } - task* execute() __TBB_override { - if( has_right_zombie ) { - // Right child was stolen. - Body* s = zombie_space.begin(); - my_body->join( *s ); - // Body::join() won't be called if canceled. Defer destruction to destructor - } - if( my_context==left_child ) - itt_store_word_with_release( static_cast(parent())->my_body, my_body ); - return NULL; - } - template - friend class start_reduce; - }; - - //! allocate right task with new parent - void allocate_sibling(task* start_reduce_task, task *tasks[], size_t start_bytes, size_t finish_bytes); - - //! Task type used to split the work of parallel_reduce. - /** @ingroup algorithms */ - template - class start_reduce: public task { - typedef finish_reduce finish_type; - Body* my_body; - Range my_range; - typename Partitioner::task_partition_type my_partition; - reduction_context my_context; - task* execute() __TBB_override; - //! Update affinity info, if any - void note_affinity( affinity_id id ) __TBB_override { - my_partition.note_affinity( id ); - } - template - friend class finish_reduce; - -public: - //! Constructor used for root task - start_reduce( const Range& range, Body* body, Partitioner& partitioner ) : - my_body(body), - my_range(range), - my_partition(partitioner), - my_context(root_task) - { - } - //! Splitting constructor used to generate children. - /** parent_ becomes left child. Newly constructed object is right child. */ - start_reduce( start_reduce& parent_, typename Partitioner::split_type& split_obj ) : - my_body(parent_.my_body), - my_range(parent_.my_range, split_obj), - my_partition(parent_.my_partition, split_obj), - my_context(right_child) - { - my_partition.set_affinity(*this); - parent_.my_context = left_child; - } - //! Construct right child from the given range as response to the demand. - /** parent_ remains left child. Newly constructed object is right child. */ - start_reduce( start_reduce& parent_, const Range& r, depth_t d ) : - my_body(parent_.my_body), - my_range(r), - my_partition(parent_.my_partition, split()), - my_context(right_child) - { - my_partition.set_affinity(*this); - my_partition.align_depth( d ); // TODO: move into constructor of partitioner - parent_.my_context = left_child; - } - static void run( const Range& range, Body& body, Partitioner& partitioner ) { - if( !range.empty() ) { -#if !__TBB_TASK_GROUP_CONTEXT || TBB_JOIN_OUTER_TASK_GROUP - task::spawn_root_and_wait( *new(task::allocate_root()) start_reduce(range,&body,partitioner) ); -#else - // Bound context prevents exceptions from body to affect nesting or sibling algorithms, - // and allows users to handle exceptions safely by wrapping parallel_for in the try-block. - task_group_context context; - task::spawn_root_and_wait( *new(task::allocate_root(context)) start_reduce(range,&body,partitioner) ); -#endif /* __TBB_TASK_GROUP_CONTEXT && !TBB_JOIN_OUTER_TASK_GROUP */ - } - } -#if __TBB_TASK_GROUP_CONTEXT - static void run( const Range& range, Body& body, Partitioner& partitioner, task_group_context& context ) { - if( !range.empty() ) - task::spawn_root_and_wait( *new(task::allocate_root(context)) start_reduce(range,&body,partitioner) ); - } -#endif /* __TBB_TASK_GROUP_CONTEXT */ - //! Run body for range - void run_body( Range &r ) { (*my_body)( r ); } - - //! spawn right task, serves as callback for partitioner - // TODO: remove code duplication from 'offer_work' methods - void offer_work(typename Partitioner::split_type& split_obj) { - task *tasks[2]; - allocate_sibling(static_cast(this), tasks, sizeof(start_reduce), sizeof(finish_type)); - new((void*)tasks[0]) finish_type(my_context); - new((void*)tasks[1]) start_reduce(*this, split_obj); - spawn(*tasks[1]); - } - //! spawn right task, serves as callback for partitioner - void offer_work(const Range& r, depth_t d = 0) { - task *tasks[2]; - allocate_sibling(static_cast(this), tasks, sizeof(start_reduce), sizeof(finish_type)); - new((void*)tasks[0]) finish_type(my_context); - new((void*)tasks[1]) start_reduce(*this, r, d); - spawn(*tasks[1]); - } - }; - - //! allocate right task with new parent - // TODO: 'inline' here is to avoid multiple definition error but for sake of code size this should not be inlined - inline void allocate_sibling(task* start_reduce_task, task *tasks[], size_t start_bytes, size_t finish_bytes) { - tasks[0] = &start_reduce_task->allocate_continuation().allocate(finish_bytes); - start_reduce_task->set_parent(tasks[0]); - tasks[0]->set_ref_count(2); - tasks[1] = &tasks[0]->allocate_child().allocate(start_bytes); - } - - template - task* start_reduce::execute() { - my_partition.check_being_stolen( *this ); - if( my_context==right_child ) { - finish_type* parent_ptr = static_cast(parent()); - if( !itt_load_word_with_acquire(parent_ptr->my_body) ) { // TODO: replace by is_stolen_task() or by parent_ptr->ref_count() == 2??? - my_body = new( parent_ptr->zombie_space.begin() ) Body(*my_body,split()); - parent_ptr->has_right_zombie = true; - } - } else __TBB_ASSERT(my_context==root_task,NULL);// because left leaf spawns right leafs without recycling - my_partition.execute(*this, my_range); - if( my_context==left_child ) { - finish_type* parent_ptr = static_cast(parent()); - __TBB_ASSERT(my_body!=parent_ptr->zombie_space.begin(),NULL); - itt_store_word_with_release(parent_ptr->my_body, my_body ); - } - return NULL; - } - - //! Task type used to combine the partial results of parallel_deterministic_reduce. - /** @ingroup algorithms */ - template - class finish_deterministic_reduce: public task { - Body &my_left_body; - Body my_right_body; - - finish_deterministic_reduce( Body &body ) : - my_left_body( body ), - my_right_body( body, split() ) - { - } - task* execute() __TBB_override { - my_left_body.join( my_right_body ); - return NULL; - } - template - friend class start_deterministic_reduce; - }; - - //! Task type used to split the work of parallel_deterministic_reduce. - /** @ingroup algorithms */ - template - class start_deterministic_reduce: public task { - typedef finish_deterministic_reduce finish_type; - Body &my_body; - Range my_range; - task* execute() __TBB_override; - - //! Constructor used for root task - start_deterministic_reduce( const Range& range, Body& body ) : - my_body( body ), - my_range( range ) - { - } - //! Splitting constructor used to generate children. - /** parent_ becomes left child. Newly constructed object is right child. */ - start_deterministic_reduce( start_deterministic_reduce& parent_, finish_type& c ) : - my_body( c.my_right_body ), - my_range( parent_.my_range, split() ) - { - } - -public: - static void run( const Range& range, Body& body ) { - if( !range.empty() ) { -#if !__TBB_TASK_GROUP_CONTEXT || TBB_JOIN_OUTER_TASK_GROUP - task::spawn_root_and_wait( *new(task::allocate_root()) start_deterministic_reduce(range,&body) ); -#else - // Bound context prevents exceptions from body to affect nesting or sibling algorithms, - // and allows users to handle exceptions safely by wrapping parallel_for in the try-block. - task_group_context context; - task::spawn_root_and_wait( *new(task::allocate_root(context)) start_deterministic_reduce(range,body) ); -#endif /* __TBB_TASK_GROUP_CONTEXT && !TBB_JOIN_OUTER_TASK_GROUP */ - } - } -#if __TBB_TASK_GROUP_CONTEXT - static void run( const Range& range, Body& body, task_group_context& context ) { - if( !range.empty() ) - task::spawn_root_and_wait( *new(task::allocate_root(context)) start_deterministic_reduce(range,body) ); - } -#endif /* __TBB_TASK_GROUP_CONTEXT */ - }; - - template - task* start_deterministic_reduce::execute() { - if( !my_range.is_divisible() ) { - my_body( my_range ); - return NULL; - } else { - finish_type& c = *new( allocate_continuation() ) finish_type( my_body ); - recycle_as_child_of(c); - c.set_ref_count(2); - start_deterministic_reduce& b = *new( c.allocate_child() ) start_deterministic_reduce( *this, c ); - task::spawn(b); - return this; - } - } -} // namespace internal -//! @endcond -} //namespace interfaceX - -//! @cond INTERNAL -namespace internal { - using interface9::internal::start_reduce; - using interface9::internal::start_deterministic_reduce; - //! Auxiliary class for parallel_reduce; for internal use only. - /** The adaptor class that implements \ref parallel_reduce_body_req "parallel_reduce Body" - using given \ref parallel_reduce_lambda_req "anonymous function objects". - **/ - /** @ingroup algorithms */ - template - class lambda_reduce_body { - -//FIXME: decide if my_real_body, my_reduction, and identity_element should be copied or referenced -// (might require some performance measurements) - - const Value& identity_element; - const RealBody& my_real_body; - const Reduction& my_reduction; - Value my_value; - lambda_reduce_body& operator= ( const lambda_reduce_body& other ); - public: - lambda_reduce_body( const Value& identity, const RealBody& body, const Reduction& reduction ) - : identity_element(identity) - , my_real_body(body) - , my_reduction(reduction) - , my_value(identity) - { } - lambda_reduce_body( const lambda_reduce_body& other ) - : identity_element(other.identity_element) - , my_real_body(other.my_real_body) - , my_reduction(other.my_reduction) - , my_value(other.my_value) - { } - lambda_reduce_body( lambda_reduce_body& other, tbb::split ) - : identity_element(other.identity_element) - , my_real_body(other.my_real_body) - , my_reduction(other.my_reduction) - , my_value(other.identity_element) - { } - void operator()(Range& range) { - my_value = my_real_body(range, const_cast(my_value)); - } - void join( lambda_reduce_body& rhs ) { - my_value = my_reduction(const_cast(my_value), const_cast(rhs.my_value)); - } - Value result() const { - return my_value; - } - }; - -} // namespace internal -//! @endcond - -// Requirements on Range concept are documented in blocked_range.h - -/** \page parallel_reduce_body_req Requirements on parallel_reduce body - Class \c Body implementing the concept of parallel_reduce body must define: - - \code Body::Body( Body&, split ); \endcode Splitting constructor. - Must be able to run concurrently with operator() and method \c join - - \code Body::~Body(); \endcode Destructor - - \code void Body::operator()( Range& r ); \endcode Function call operator applying body to range \c r - and accumulating the result - - \code void Body::join( Body& b ); \endcode Join results. - The result in \c b should be merged into the result of \c this -**/ - -/** \page parallel_reduce_lambda_req Requirements on parallel_reduce anonymous function objects (lambda functions) - TO BE DOCUMENTED -**/ - -/** \name parallel_reduce - See also requirements on \ref range_req "Range" and \ref parallel_reduce_body_req "parallel_reduce Body". **/ -//@{ - -//! Parallel iteration with reduction and default partitioner. -/** @ingroup algorithms **/ -template -void parallel_reduce( const Range& range, Body& body ) { - internal::start_reduce::run( range, body, __TBB_DEFAULT_PARTITIONER() ); -} - -//! Parallel iteration with reduction and simple_partitioner -/** @ingroup algorithms **/ -template -void parallel_reduce( const Range& range, Body& body, const simple_partitioner& partitioner ) { - internal::start_reduce::run( range, body, partitioner ); -} - -//! Parallel iteration with reduction and auto_partitioner -/** @ingroup algorithms **/ -template -void parallel_reduce( const Range& range, Body& body, const auto_partitioner& partitioner ) { - internal::start_reduce::run( range, body, 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 ); -} - -//! Parallel iteration with reduction and affinity_partitioner -/** @ingroup algorithms **/ -template -void parallel_reduce( const Range& range, Body& body, affinity_partitioner& partitioner ) { - internal::start_reduce::run( range, body, partitioner ); -} - -#if __TBB_TASK_GROUP_CONTEXT -//! Parallel iteration with reduction, simple partitioner and user-supplied context. -/** @ingroup algorithms **/ -template -void parallel_reduce( const Range& range, Body& body, const simple_partitioner& partitioner, task_group_context& context ) { - internal::start_reduce::run( range, body, partitioner, context ); -} - -//! Parallel iteration with reduction, auto_partitioner and user-supplied context -/** @ingroup algorithms **/ -template -void parallel_reduce( const Range& range, Body& body, const auto_partitioner& partitioner, task_group_context& context ) { - internal::start_reduce::run( range, body, partitioner, context ); -} - -//! 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 ); -} - -//! Parallel iteration with reduction, affinity_partitioner and user-supplied context -/** @ingroup algorithms **/ -template -void parallel_reduce( const Range& range, Body& body, affinity_partitioner& partitioner, task_group_context& context ) { - internal::start_reduce::run( range, body, partitioner, context ); -} -#endif /* __TBB_TASK_GROUP_CONTEXT */ - -/** parallel_reduce overloads that work with anonymous function objects - (see also \ref parallel_reduce_lambda_req "requirements on parallel_reduce anonymous function objects"). **/ - -//! Parallel iteration with reduction and default partitioner. -/** @ingroup algorithms **/ -template -Value parallel_reduce( const Range& range, const Value& identity, const RealBody& real_body, const Reduction& reduction ) { - internal::lambda_reduce_body body(identity, real_body, reduction); - internal::start_reduce,const __TBB_DEFAULT_PARTITIONER> - ::run(range, body, __TBB_DEFAULT_PARTITIONER() ); - return body.result(); -} - -//! Parallel iteration with reduction and simple_partitioner. -/** @ingroup algorithms **/ -template -Value parallel_reduce( const Range& range, const Value& identity, const RealBody& real_body, const Reduction& reduction, - const simple_partitioner& partitioner ) { - internal::lambda_reduce_body body(identity, real_body, reduction); - internal::start_reduce,const simple_partitioner> - ::run(range, body, partitioner ); - return body.result(); -} - -//! Parallel iteration with reduction and auto_partitioner -/** @ingroup algorithms **/ -template -Value parallel_reduce( const Range& range, const Value& identity, const RealBody& real_body, const Reduction& reduction, - const auto_partitioner& partitioner ) { - internal::lambda_reduce_body body(identity, real_body, reduction); - internal::start_reduce,const auto_partitioner> - ::run( range, body, partitioner ); - return body.result(); -} - -//! Parallel iteration with reduction and static_partitioner -/** @ingroup algorithms **/ -template -Value parallel_reduce( const Range& range, const Value& identity, const RealBody& real_body, const Reduction& reduction, - const static_partitioner& partitioner ) { - internal::lambda_reduce_body body(identity, real_body, reduction); - internal::start_reduce,const static_partitioner> - ::run( range, body, partitioner ); - return body.result(); -} - -//! Parallel iteration with reduction and affinity_partitioner -/** @ingroup algorithms **/ -template -Value parallel_reduce( const Range& range, const Value& identity, const RealBody& real_body, const Reduction& reduction, - affinity_partitioner& partitioner ) { - internal::lambda_reduce_body body(identity, real_body, reduction); - internal::start_reduce,affinity_partitioner> - ::run( range, body, partitioner ); - return body.result(); -} - -#if __TBB_TASK_GROUP_CONTEXT -//! Parallel iteration with reduction, simple partitioner and user-supplied context. -/** @ingroup algorithms **/ -template -Value parallel_reduce( const Range& range, const Value& identity, const RealBody& real_body, const Reduction& reduction, - const simple_partitioner& partitioner, task_group_context& context ) { - internal::lambda_reduce_body body(identity, real_body, reduction); - internal::start_reduce,const simple_partitioner> - ::run( range, body, partitioner, context ); - return body.result(); -} - -//! Parallel iteration with reduction, auto_partitioner and user-supplied context -/** @ingroup algorithms **/ -template -Value parallel_reduce( const Range& range, const Value& identity, const RealBody& real_body, const Reduction& reduction, - const auto_partitioner& partitioner, task_group_context& context ) { - internal::lambda_reduce_body body(identity, real_body, reduction); - internal::start_reduce,const auto_partitioner> - ::run( range, body, partitioner, context ); - return body.result(); -} - -//! Parallel iteration with reduction, static_partitioner and user-supplied context -/** @ingroup algorithms **/ -template -Value parallel_reduce( const Range& range, const Value& identity, const RealBody& real_body, const Reduction& reduction, - const static_partitioner& partitioner, task_group_context& context ) { - internal::lambda_reduce_body body(identity, real_body, reduction); - internal::start_reduce,const static_partitioner> - ::run( range, body, partitioner, context ); - return body.result(); -} - -//! Parallel iteration with reduction, affinity_partitioner and user-supplied context -/** @ingroup algorithms **/ -template -Value parallel_reduce( const Range& range, const Value& identity, const RealBody& real_body, const Reduction& reduction, - affinity_partitioner& partitioner, task_group_context& context ) { - internal::lambda_reduce_body body(identity, real_body, reduction); - internal::start_reduce,affinity_partitioner> - ::run( range, body, partitioner, context ); - return body.result(); -} -#endif /* __TBB_TASK_GROUP_CONTEXT */ - -//! Parallel iteration with deterministic reduction and default partitioner. -/** @ingroup algorithms **/ -template -void parallel_deterministic_reduce( const Range& range, Body& body ) { - internal::start_deterministic_reduce::run( range, body ); -} - -#if __TBB_TASK_GROUP_CONTEXT -//! Parallel iteration with deterministic reduction, simple partitioner and user-supplied context. -/** @ingroup algorithms **/ -template -void parallel_deterministic_reduce( const Range& range, Body& body, task_group_context& context ) { - internal::start_deterministic_reduce::run( range, body, context ); -} -#endif /* __TBB_TASK_GROUP_CONTEXT */ - -/** parallel_reduce overloads that work with anonymous function objects - (see also \ref parallel_reduce_lambda_req "requirements on parallel_reduce anonymous function objects"). **/ - -//! Parallel iteration with deterministic reduction and default partitioner. -/** @ingroup algorithms **/ -template -Value parallel_deterministic_reduce( const Range& range, const Value& identity, const RealBody& real_body, const Reduction& reduction ) { - internal::lambda_reduce_body body(identity, real_body, reduction); - internal::start_deterministic_reduce > - ::run(range, body); - return body.result(); -} - -#if __TBB_TASK_GROUP_CONTEXT -//! Parallel iteration with deterministic reduction, simple partitioner and user-supplied context. -/** @ingroup algorithms **/ -template -Value parallel_deterministic_reduce( const Range& range, const Value& identity, const RealBody& real_body, const Reduction& reduction, - task_group_context& context ) { - internal::lambda_reduce_body body(identity, real_body, reduction); - internal::start_deterministic_reduce > - ::run( range, body, context ); - return body.result(); -} -#endif /* __TBB_TASK_GROUP_CONTEXT */ -//@} - -} // namespace tbb - -#endif /* __TBB_parallel_reduce_H */ diff --git a/lib/3rdParty/tbb/include/tbb/parallel_scan.h b/lib/3rdParty/tbb/include/tbb/parallel_scan.h deleted file mode 100644 index faf6b316..00000000 --- a/lib/3rdParty/tbb/include/tbb/parallel_scan.h +++ /dev/null @@ -1,348 +0,0 @@ -/* - 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_parallel_scan_H -#define __TBB_parallel_scan_H - -#include "task.h" -#include "aligned_space.h" -#include -#include "partitioner.h" - -namespace tbb { - -//! Used to indicate that the initial scan is being performed. -/** @ingroup algorithms */ -struct pre_scan_tag { - static bool is_final_scan() {return false;} -}; - -//! Used to indicate that the final scan is being performed. -/** @ingroup algorithms */ -struct final_scan_tag { - static bool is_final_scan() {return true;} -}; - -//! @cond INTERNAL -namespace internal { - - //! Performs final scan for a leaf - /** @ingroup algorithms */ - template - class final_sum: public task { - public: - Body my_body; - private: - aligned_space my_range; - //! Where to put result of last subrange, or NULL if not last subrange. - Body* my_stuff_last; - public: - final_sum( Body& body_ ) : - my_body(body_,split()) - { - poison_pointer(my_stuff_last); - } - ~final_sum() { - my_range.begin()->~Range(); - } - void finish_construction( const Range& range_, Body* stuff_last_ ) { - new( my_range.begin() ) Range(range_); - my_stuff_last = stuff_last_; - } - private: - task* execute() __TBB_override { - my_body( *my_range.begin(), final_scan_tag() ); - if( my_stuff_last ) - my_stuff_last->assign(my_body); - return NULL; - } - }; - - //! Split work to be done in the scan. - /** @ingroup algorithms */ - template - class sum_node: public task { - typedef final_sum final_sum_type; - public: - final_sum_type *my_incoming; - final_sum_type *my_body; - Body *my_stuff_last; - private: - final_sum_type *my_left_sum; - sum_node *my_left; - sum_node *my_right; - 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), - my_left_is_final(left_is_final_), - my_range(range_) - { - // Poison fields that will be set by second pass. - poison_pointer(my_body); - poison_pointer(my_incoming); - } - task* create_child( const Range& range_, final_sum_type& f, sum_node* n, final_sum_type* incoming_, Body* stuff_last_ ) { - if( !n ) { - f.recycle_as_child_of( *this ); - f.finish_construction( range_, stuff_last_ ); - return &f; - } else { - n->my_body = &f; - n->my_incoming = incoming_; - n->my_stuff_last = stuff_last_; - return n; - } - } - task* execute() __TBB_override { - if( my_body ) { - if( my_incoming ) - my_left_sum->my_body.reverse_join( my_incoming->my_body ); - recycle_as_continuation(); - sum_node& c = *this; - task* b = c.create_child(Range(my_range,split()),*my_left_sum,my_right,my_left_sum,my_stuff_last); - task* a = my_left_is_final ? NULL : c.create_child(my_range,*my_body,my_left,my_incoming,NULL); - set_ref_count( (a!=NULL)+(b!=NULL) ); - my_body = NULL; - if( a ) spawn(*b); - else a = b; - return a; - } else { - return NULL; - } - } - template - friend class start_scan; - - template - friend class finish_scan; - }; - - //! Combine partial results - /** @ingroup algorithms */ - template - class finish_scan: public task { - typedef sum_node sum_node_type; - typedef final_sum final_sum_type; - final_sum_type** const my_sum; - sum_node_type*& my_return_slot; - public: - final_sum_type* my_right_zombie; - sum_node_type& my_result; - - 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; - if( my_right_zombie && my_sum ) - ((*my_sum)->my_body).reverse_join(my_result.my_left_sum->my_body); - __TBB_ASSERT( !my_return_slot, NULL ); - if( my_right_zombie || my_result.my_right ) { - my_return_slot = &my_result; - } else { - destroy( my_result ); - } - if( my_right_zombie && !my_sum && !my_result.my_right ) { - destroy(*my_right_zombie); - my_right_zombie = NULL; - } - return NULL; - } - - finish_scan( sum_node_type*& return_slot_, final_sum_type** sum_, sum_node_type& result_ ) : - my_sum(sum_), - my_return_slot(return_slot_), - my_right_zombie(NULL), - my_result(result_) - { - __TBB_ASSERT( !my_return_slot, NULL ); - } - }; - - //! Initial task to split the work - /** @ingroup algorithms */ - template - class start_scan: public task { - typedef sum_node sum_node_type; - typedef final_sum final_sum_type; - final_sum_type* my_body; - /** Non-null if caller is requesting total. */ - final_sum_type** my_sum; - sum_node_type** my_return_slot; - /** Null if computing root. */ - sum_node_type* my_parent_sum; - bool my_is_final; - bool my_is_right_child; - Range my_range; - typename Partitioner::partition_type my_partition; - 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), - my_sum(parent_.my_sum), - my_return_slot(&return_slot_), - my_parent_sum(parent_sum_), - my_is_final(parent_.my_is_final), - my_is_right_child(false), - my_range(parent_.my_range,split()), - my_partition(parent_.my_partition,split()) - { - __TBB_ASSERT( !*my_return_slot, NULL ); - } - - start_scan( sum_node_type*& return_slot_, const Range& range_, final_sum_type& body_, const Partitioner& partitioner_) : - my_body(&body_), - my_sum(NULL), - my_return_slot(&return_slot_), - my_parent_sum(NULL), - my_is_final(true), - my_is_right_child(false), - my_range(range_), - my_partition(partitioner_) - { - __TBB_ASSERT( !*my_return_slot, NULL ); - } - - static void run( const Range& range_, Body& body_, const Partitioner& partitioner_ ) { - if( !range_.empty() ) { - typedef internal::start_scan start_pass1_type; - internal::sum_node* root = NULL; - typedef internal::final_sum final_sum_type; - final_sum_type* temp_body = new(task::allocate_root()) final_sum_type( body_ ); - start_pass1_type& pass1 = *new(task::allocate_root()) start_pass1_type( - /*my_return_slot=*/root, - range_, - *temp_body, - partitioner_ ); - temp_body->my_body.reverse_join(body_); - task::spawn_root_and_wait( pass1 ); - if( root ) { - root->my_body = temp_body; - root->my_incoming = NULL; - root->my_stuff_last = &body_; - task::spawn_root_and_wait( *root ); - } else { - body_.assign(temp_body->my_body); - temp_body->finish_construction( range_, NULL ); - temp_body->destroy(*temp_body); - } - } - } - }; - - template - task* start_scan::execute() { - typedef internal::finish_scan finish_pass1_type; - finish_pass1_type* p = my_parent_sum ? static_cast( parent() ) : NULL; - // Inspecting p->result.left_sum would ordinarily be a race condition. - // But we inspect it only if we are not a stolen task, in which case we - // know that task assigning to p->result.left_sum has completed. - bool treat_as_stolen = my_is_right_child && (is_stolen_task() || my_body!=p->my_result.my_left_sum); - if( treat_as_stolen ) { - // Invocation is for right child that has been really stolen or needs to be virtually stolen - p->my_right_zombie = my_body = new( allocate_root() ) final_sum_type(my_body->my_body); - my_is_final = false; - } - task* next_task = NULL; - if( (my_is_right_child && !treat_as_stolen) || !my_range.is_divisible() || my_partition.should_execute_range(*this) ) { - if( my_is_final ) - (my_body->my_body)( my_range, final_scan_tag() ); - else if( my_sum ) - (my_body->my_body)( my_range, pre_scan_tag() ); - if( my_sum ) - *my_sum = my_body; - __TBB_ASSERT( !*my_return_slot, NULL ); - } else { - sum_node_type* result; - if( my_parent_sum ) - result = new(allocate_additional_child_of(*my_parent_sum)) sum_node_type(my_range,/*my_left_is_final=*/my_is_final); - else - result = new(task::allocate_root()) sum_node_type(my_range,/*my_left_is_final=*/my_is_final); - finish_pass1_type& c = *new( allocate_continuation()) finish_pass1_type(*my_return_slot,my_sum,*result); - // Split off right child - start_scan& b = *new( c.allocate_child() ) start_scan( /*my_return_slot=*/result->my_right, *this, result ); - b.my_is_right_child = true; - // Left child is recycling of *this. Must recycle this before spawning b, - // otherwise b might complete and decrement c.ref_count() to zero, which - // would cause c.execute() to run prematurely. - recycle_as_child_of(c); - c.set_ref_count(2); - c.spawn(b); - my_sum = &result->my_left_sum; - my_return_slot = &result->my_left; - my_is_right_child = false; - next_task = this; - my_parent_sum = result; - __TBB_ASSERT( !*my_return_slot, NULL ); - } - return next_task; - } -} // namespace internal -//! @endcond - -// Requirements on Range concept are documented in blocked_range.h - -/** \page parallel_scan_body_req Requirements on parallel_scan body - Class \c Body implementing the concept of parallel_scan body must define: - - \code Body::Body( Body&, split ); \endcode Splitting constructor. - Split \c b so that \c this and \c b can accumulate separately - - \code Body::~Body(); \endcode Destructor - - \code void Body::operator()( const Range& r, pre_scan_tag ); \endcode - Preprocess iterations for range \c r - - \code void Body::operator()( const Range& r, final_scan_tag ); \endcode - Do final processing for iterations of range \c r - - \code void Body::reverse_join( Body& a ); \endcode - Merge preprocessing state of \c a into \c this, where \c a was - created earlier from \c b by b's splitting constructor -**/ - -/** \name parallel_scan - See also requirements on \ref range_req "Range" and \ref parallel_scan_body_req "parallel_scan Body". **/ -//@{ - -//! Parallel prefix with default partitioner -/** @ingroup algorithms **/ -template -void parallel_scan( const Range& range, Body& body ) { - internal::start_scan::run(range,body,__TBB_DEFAULT_PARTITIONER()); -} - -//! Parallel prefix with simple_partitioner -/** @ingroup algorithms **/ -template -void parallel_scan( const Range& range, Body& body, const simple_partitioner& partitioner ) { - internal::start_scan::run(range,body,partitioner); -} - -//! Parallel prefix with auto_partitioner -/** @ingroup algorithms **/ -template -void parallel_scan( const Range& range, Body& body, const auto_partitioner& partitioner ) { - internal::start_scan::run(range,body,partitioner); -} -//@} - -} // namespace tbb - -#endif /* __TBB_parallel_scan_H */ - diff --git a/lib/3rdParty/tbb/include/tbb/parallel_sort.h b/lib/3rdParty/tbb/include/tbb/parallel_sort.h deleted file mode 100644 index 07d3907b..00000000 --- a/lib/3rdParty/tbb/include/tbb/parallel_sort.h +++ /dev/null @@ -1,266 +0,0 @@ -/* - 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_parallel_sort_H -#define __TBB_parallel_sort_H - -#include "parallel_for.h" -#include "blocked_range.h" -#include "internal/_range_iterator.h" -#include -#include -#include - -namespace tbb { - -namespace interface9 { -//! @cond INTERNAL -namespace internal { - -using tbb::internal::no_assign; - -//! Range used in quicksort to split elements into subranges based on a value. -/** The split operation selects a splitter and places all elements less than or equal - to the value in the first range and the remaining elements in the second range. - @ingroup algorithms */ -template -class quick_sort_range: private no_assign { - - inline size_t median_of_three(const RandomAccessIterator &array, size_t l, size_t m, size_t r) const { - return comp(array[l], array[m]) ? ( comp(array[m], array[r]) ? m : ( comp( array[l], array[r]) ? r : l ) ) - : ( comp(array[r], array[m]) ? m : ( comp( array[r], array[l] ) ? r : l ) ); - } - - inline size_t pseudo_median_of_nine( const RandomAccessIterator &array, const quick_sort_range &range ) const { - size_t offset = range.size/8u; - return median_of_three(array, - median_of_three(array, 0, offset, offset*2), - median_of_three(array, offset*3, offset*4, offset*5), - median_of_three(array, offset*6, offset*7, range.size - 1) ); - - } - - size_t split_range( quick_sort_range& range ) { - using std::iter_swap; - RandomAccessIterator array = range.begin; - RandomAccessIterator key0 = range.begin; - size_t m = pseudo_median_of_nine(array, range); - if (m) iter_swap ( array, array+m ); - - size_t i=0; - size_t j=range.size; - // Partition interval [i+1,j-1] with key *key0. - for(;;) { - __TBB_ASSERT( i=grainsize;} - - quick_sort_range( quick_sort_range& range, split ) - : comp(range.comp) - , size(split_range(range)) - // +1 accounts for the pivot element, which is at its correct place - // already and, therefore, is not included into subranges. - , begin(range.begin+range.size+1) {} -}; - -#if __TBB_TASK_GROUP_CONTEXT -//! Body class used to test if elements in a range are presorted -/** @ingroup algorithms */ -template -class quick_sort_pretest_body : no_assign { - const Compare ∁ - -public: - quick_sort_pretest_body(const Compare &_comp) : comp(_comp) {} - - void operator()( const blocked_range& range ) const { - task &my_task = task::self(); - RandomAccessIterator my_end = range.end(); - - int i = 0; - for (RandomAccessIterator k = range.begin(); k != my_end; ++k, ++i) { - if ( i%64 == 0 && my_task.is_cancelled() ) break; - - // The k-1 is never out-of-range because the first chunk starts at begin+serial_cutoff+1 - if ( comp( *(k), *(k-1) ) ) { - my_task.cancel_group_execution(); - break; - } - } - } - -}; -#endif /* __TBB_TASK_GROUP_CONTEXT */ - -//! Body class used to sort elements in a range that is smaller than the grainsize. -/** @ingroup algorithms */ -template -struct quick_sort_body { - void operator()( const quick_sort_range& range ) const { - //SerialQuickSort( range.begin, range.size, range.comp ); - std::sort( range.begin, range.begin + range.size, range.comp ); - } -}; - -//! Wrapper method to initiate the sort by calling parallel_for. -/** @ingroup algorithms */ -template -void parallel_quick_sort( RandomAccessIterator begin, RandomAccessIterator end, const Compare& comp ) { -#if __TBB_TASK_GROUP_CONTEXT - task_group_context my_context; - const int serial_cutoff = 9; - - __TBB_ASSERT( begin + serial_cutoff < end, "min_parallel_size is smaller than serial cutoff?" ); - RandomAccessIterator k = begin; - for ( ; k != begin + serial_cutoff; ++k ) { - if ( comp( *(k+1), *k ) ) { - goto do_parallel_quick_sort; - } - } - - parallel_for( blocked_range(k+1, end), - quick_sort_pretest_body(comp), - auto_partitioner(), - my_context); - - if (my_context.is_group_execution_cancelled()) -do_parallel_quick_sort: -#endif /* __TBB_TASK_GROUP_CONTEXT */ - parallel_for( quick_sort_range(begin, end-begin, comp ), - quick_sort_body(), - auto_partitioner() ); -} - -} // namespace internal -//! @endcond -} // namespace interfaceX - -/** \page parallel_sort_iter_req Requirements on iterators for parallel_sort - Requirements on the iterator type \c It and its value type \c T for \c parallel_sort: - - - \code void iter_swap( It a, It b ) \endcode Swaps the values of the elements the given - iterators \c a and \c b are pointing to. \c It should be a random access iterator. - - - \code bool Compare::operator()( const T& x, const T& y ) \endcode True if x comes before y; -**/ - -/** \name parallel_sort - See also requirements on \ref parallel_sort_iter_req "iterators for parallel_sort". **/ -//@{ - -//! Sorts the data in [begin,end) using the given comparator -/** The compare function object is used for all comparisons between elements during sorting. - The compare object must define a bool operator() function. - @ingroup algorithms **/ -template -void parallel_sort( RandomAccessIterator begin, RandomAccessIterator end, const Compare& comp) { - const int min_parallel_size = 500; - if( end > begin ) { - if (end - begin < min_parallel_size) { - std::sort(begin, end, comp); - } else { - interface9::internal::parallel_quick_sort(begin, end, comp); - } - } -} - -//! Sorts the data in [begin,end) with a default comparator \c std::less -/** @ingroup algorithms **/ -template -inline void parallel_sort( RandomAccessIterator begin, RandomAccessIterator end ) { - parallel_sort( begin, end, std::less< typename std::iterator_traits::value_type >() ); -} - -//! Sorts the data in rng using the given comparator -/** @ingroup algorithms **/ -template -void parallel_sort(Range& rng, const Compare& comp) { - parallel_sort(tbb::internal::first(rng), tbb::internal::last(rng), comp); -} - -//! Sorts the data in const rng using the given comparator -/** @ingroup algorithms **/ -template -void parallel_sort(const Range& rng, const Compare& comp) { - parallel_sort(tbb::internal::first(rng), tbb::internal::last(rng), comp); -} - -//! Sorts the data in rng with a default comparator \c std::less -/** @ingroup algorithms **/ -template -void parallel_sort(Range& rng) { - parallel_sort(tbb::internal::first(rng), tbb::internal::last(rng)); -} - -//! Sorts the data in const rng with a default comparator \c std::less -/** @ingroup algorithms **/ -template -void parallel_sort(const Range& rng) { - parallel_sort(tbb::internal::first(rng), tbb::internal::last(rng)); -} - -//! Sorts the data in the range \c [begin,end) with a default comparator \c std::less -/** @ingroup algorithms **/ -template -inline void parallel_sort( T * begin, T * end ) { - parallel_sort( begin, end, std::less< T >() ); -} -//@} - - -} // namespace tbb - -#endif - diff --git a/lib/3rdParty/tbb/include/tbb/parallel_while.h b/lib/3rdParty/tbb/include/tbb/parallel_while.h deleted file mode 100644 index 2f37a41a..00000000 --- a/lib/3rdParty/tbb/include/tbb/parallel_while.h +++ /dev/null @@ -1,186 +0,0 @@ -/* - 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_parallel_while -#define __TBB_parallel_while - -#include "task.h" -#include - -namespace tbb { - -template -class parallel_while; - -//! @cond INTERNAL -namespace internal { - - template class while_task; - - //! For internal use only. - /** Executes one iteration of a while. - @ingroup algorithms */ - template - class while_iteration_task: public task { - const Body& my_body; - typename Body::argument_type my_value; - task* execute() __TBB_override { - my_body(my_value); - return NULL; - } - while_iteration_task( const typename Body::argument_type& value, const Body& body ) : - my_body(body), my_value(value) - {} - template friend class while_group_task; - friend class tbb::parallel_while; - }; - - //! For internal use only - /** Unpacks a block of iterations. - @ingroup algorithms */ - template - class while_group_task: public task { - static const size_t max_arg_size = 4; - const Body& my_body; - size_t size; - typename Body::argument_type my_arg[max_arg_size]; - while_group_task( const Body& body ) : my_body(body), size(0) {} - task* execute() __TBB_override { - typedef while_iteration_task iteration_type; - __TBB_ASSERT( size>0, NULL ); - task_list list; - task* t; - size_t k=0; - for(;;) { - t = new( allocate_child() ) iteration_type(my_arg[k],my_body); - if( ++k==size ) break; - list.push_back(*t); - } - set_ref_count(int(k+1)); - spawn(list); - spawn_and_wait_for_all(*t); - return NULL; - } - template friend class while_task; - }; - - //! For internal use only. - /** Gets block of iterations from a stream and packages them into a while_group_task. - @ingroup algorithms */ - template - class while_task: public task { - Stream& my_stream; - const Body& my_body; - empty_task& my_barrier; - 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; - while( my_stream.pop_if_present(t.my_arg[k]) ) { - if( ++k==block_type::max_arg_size ) { - // There might be more iterations. - recycle_to_reexecute(); - break; - } - } - if( k==0 ) { - destroy(t); - return NULL; - } else { - t.size = k; - return &t; - } - } - while_task( Stream& stream, const Body& body, empty_task& barrier ) : - my_stream(stream), - my_body(body), - my_barrier(barrier) - {} - friend class tbb::parallel_while; - }; - -} // namespace internal -//! @endcond - -//! Parallel iteration over a stream, with optional addition of more work. -/** The Body b has the requirement: \n - "b(v)" \n - "b.argument_type" \n - where v is an argument_type - @ingroup algorithms */ -template -class parallel_while: internal::no_copy { -public: - //! Construct empty non-running parallel while. - parallel_while() : my_body(NULL), my_barrier(NULL) {} - - //! Destructor cleans up data members before returning. - ~parallel_while() { - if( my_barrier ) { - my_barrier->destroy(*my_barrier); - my_barrier = NULL; - } - } - - //! Type of items - typedef typename Body::argument_type value_type; - - //! Apply body.apply to each item in the stream. - /** A Stream s has the requirements \n - "S::value_type" \n - "s.pop_if_present(value) is convertible to bool */ - template - void run( Stream& stream, const Body& body ); - - //! Add a work item while running. - /** Should be executed only by body.apply or a thread spawned therefrom. */ - void add( const value_type& item ); - -private: - const Body* my_body; - empty_task* my_barrier; -}; - -template -template -void parallel_while::run( Stream& stream, const Body& body ) { - using namespace internal; - empty_task& barrier = *new( task::allocate_root() ) empty_task(); - my_body = &body; - my_barrier = &barrier; - my_barrier->set_ref_count(2); - while_task& w = *new( my_barrier->allocate_child() ) while_task( stream, body, barrier ); - my_barrier->spawn_and_wait_for_all(w); - my_barrier->destroy(*my_barrier); - my_barrier = NULL; - my_body = NULL; -} - -template -void parallel_while::add( const value_type& item ) { - __TBB_ASSERT(my_barrier,"attempt to add to parallel_while that is not running"); - typedef internal::while_iteration_task iteration_type; - iteration_type& i = *new( task::allocate_additional_child_of(*my_barrier) ) iteration_type(item,*my_body); - task::self().spawn( i ); -} - -} // namespace - -#endif /* __TBB_parallel_while */ diff --git a/lib/3rdParty/tbb/include/tbb/partitioner.h b/lib/3rdParty/tbb/include/tbb/partitioner.h deleted file mode 100644 index 96a0b757..00000000 --- a/lib/3rdParty/tbb/include/tbb/partitioner.h +++ /dev/null @@ -1,681 +0,0 @@ -/* - 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_partitioner_H -#define __TBB_partitioner_H - -#ifndef __TBB_INITIAL_CHUNKS -// initial task divisions per thread -#define __TBB_INITIAL_CHUNKS 2 -#endif -#ifndef __TBB_RANGE_POOL_CAPACITY -// maximum number of elements in range pool -#define __TBB_RANGE_POOL_CAPACITY 8 -#endif -#ifndef __TBB_INIT_DEPTH -// initial value for depth of range pool -#define __TBB_INIT_DEPTH 5 -#endif -#ifndef __TBB_DEMAND_DEPTH_ADD -// when imbalance is found range splits this value times more -#define __TBB_DEMAND_DEPTH_ADD 1 -#endif -#ifndef __TBB_STATIC_THRESHOLD -// necessary number of clocks for the work to be distributed among all tasks -#define __TBB_STATIC_THRESHOLD 40000 -#endif -#if __TBB_DEFINE_MIC -#define __TBB_NONUNIFORM_TASK_CREATION 1 -#ifdef __TBB_time_stamp -#define __TBB_USE_MACHINE_TIME_STAMPS 1 -#define __TBB_task_duration() __TBB_STATIC_THRESHOLD -#endif // __TBB_machine_time_stamp -#endif // __TBB_DEFINE_MIC - -#include "task.h" -#include "aligned_space.h" -#include "atomic.h" -#include "internal/_template_helpers.h" - -#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) - // Workaround for overzealous compiler warnings - #pragma warning (push) - #pragma warning (disable: 4244) -#endif - -namespace tbb { - -class auto_partitioner; -class simple_partitioner; -class static_partitioner; -class affinity_partitioner; - -namespace interface9 { - namespace internal { - class affinity_partition_type; - } -} - -namespace internal { //< @cond INTERNAL -size_t __TBB_EXPORTED_FUNC get_initial_auto_partitioner_divisor(); - -//! Defines entry point for affinity partitioner into tbb run-time library. -class affinity_partitioner_base_v3: no_copy { - friend class tbb::affinity_partitioner; - friend class tbb::interface9::internal::affinity_partition_type; - //! Array that remembers affinities of tree positions to affinity_id. - /** NULL if my_size==0. */ - affinity_id* my_array; - //! Number of elements in my_array. - size_t my_size; - //! Zeros the fields. - affinity_partitioner_base_v3() : my_array(NULL), my_size(0) {} - //! Deallocates my_array. - ~affinity_partitioner_base_v3() {resize(0);} - //! Resize my_array. - /** Retains values if resulting size is the same. */ - void __TBB_EXPORTED_METHOD resize( unsigned factor ); -}; - -//! Provides backward-compatible methods for partition objects without affinity. -class partition_type_base { -public: - void set_affinity( task & ) {} - void note_affinity( task::affinity_id ) {} - task* continue_after_execute_range() {return NULL;} - bool decide_whether_to_delay() {return false;} - void spawn_or_delay( bool, task& b ) { - task::spawn(b); - } -}; - -template class start_scan; - -} //< namespace internal @endcond - -namespace serial { -namespace interface9 { -template class start_for; -} -} - -namespace interface9 { -//! @cond INTERNAL -namespace internal { -using namespace tbb::internal; -template class start_for; -template class start_reduce; - -//! Join task node that contains shared flag for stealing feedback -class flag_task: public task { -public: - tbb::atomic my_child_stolen; - flag_task() { my_child_stolen = false; } - 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 - // Threading tools respect lock prefix but report false-positive data-race via plain store - flag.fetch_and_store(true); -#else - flag = true; -#endif //TBB_USE_THREADING_TOOLS - } - static bool is_peer_stolen(task &t) { - return static_cast(t.parent())->my_child_stolen; - } -}; - -//! Depth is a relative depth of recursive division inside a range pool. Relative depth allows -//! infinite absolute depth of the recursion for heavily unbalanced workloads with range represented -//! by a number that cannot fit into machine word. -typedef unsigned char depth_t; - -//! Range pool stores ranges of type T in a circular buffer with MaxCapacity -template -class range_vector { - depth_t my_head; - depth_t my_tail; - depth_t my_size; - depth_t my_depth[MaxCapacity]; // relative depths of stored ranges - tbb::aligned_space my_pool; - -public: - //! initialize via first range in pool - range_vector(const T& elem) : my_head(0), my_tail(0), my_size(1) { - my_depth[0] = 0; - new( static_cast(my_pool.begin()) ) T(elem);//TODO: std::move? - } - ~range_vector() { - while( !empty() ) pop_back(); - } - bool empty() const { return my_size == 0; } - depth_t size() const { return my_size; } - //! Populates range pool via ranges up to max depth or while divisible - //! max_depth starts from 0, e.g. value 2 makes 3 ranges in the pool up to two 1/4 pieces - void split_to_fill(depth_t max_depth) { - while( my_size < MaxCapacity && is_divisible(max_depth) ) { - depth_t prev = my_head; - my_head = (my_head + 1) % MaxCapacity; - new(my_pool.begin()+my_head) T(my_pool.begin()[prev]); // copy TODO: std::move? - my_pool.begin()[prev].~T(); // instead of assignment - new(my_pool.begin()+prev) T(my_pool.begin()[my_head], split()); // do 'inverse' split - my_depth[my_head] = ++my_depth[prev]; - my_size++; - } - } - void pop_back() { - __TBB_ASSERT(my_size > 0, "range_vector::pop_back() with empty size"); - my_pool.begin()[my_head].~T(); - my_size--; - my_head = (my_head + MaxCapacity - 1) % MaxCapacity; - } - void pop_front() { - __TBB_ASSERT(my_size > 0, "range_vector::pop_front() with empty size"); - my_pool.begin()[my_tail].~T(); - my_size--; - my_tail = (my_tail + 1) % MaxCapacity; - } - T& back() { - __TBB_ASSERT(my_size > 0, "range_vector::back() with empty size"); - return my_pool.begin()[my_head]; - } - T& front() { - __TBB_ASSERT(my_size > 0, "range_vector::front() with empty size"); - return my_pool.begin()[my_tail]; - } - //! similarly to front(), returns depth of the first range in the pool - depth_t front_depth() { - __TBB_ASSERT(my_size > 0, "range_vector::front_depth() with empty size"); - return my_depth[my_tail]; - } - depth_t back_depth() { - __TBB_ASSERT(my_size > 0, "range_vector::back_depth() with empty size"); - return my_depth[my_head]; - } - bool is_divisible(depth_t max_depth) { - return back_depth() < max_depth && back().is_divisible(); - } -}; - -//! Provides default methods for partition objects and common algorithm blocks. -template -struct partition_type_base { - typedef split split_type; - // decision makers - void set_affinity( task & ) {} - void note_affinity( task::affinity_id ) {} - bool check_being_stolen(task &) { return false; } // part of old should_execute_range() - bool check_for_demand(task &) { return false; } - bool is_divisible() { return true; } // part of old should_execute_range() - depth_t max_depth() { return 0; } - void align_depth(depth_t) { } - template split_type get_split() { return split(); } - Partition& self() { return *static_cast(this); } // CRTP helper - - template - void work_balance(StartType &start, Range &range) { - start.run_body( range ); // simple partitioner goes always here - } - - template - void execute(StartType &start, Range &range) { - // The algorithm in a few words ([]-denotes calls to decision methods of partitioner): - // [If this task is stolen, adjust depth and divisions if necessary, set flag]. - // If range is divisible { - // Spread the work while [initial divisions left]; - // Create trap task [if necessary]; - // } - // If not divisible or [max depth is reached], execute, else do the range pool part - if ( range.is_divisible() ) { - if ( self().is_divisible() ) { - do { // split until is divisible - typename Partition::split_type split_obj = self().template get_split(); - start.offer_work( split_obj ); - } while ( range.is_divisible() && self().is_divisible() ); - } - } - self().work_balance(start, range); - } -}; - -//! Provides default splitting strategy for partition objects. -template -struct adaptive_mode : partition_type_base { - typedef Partition my_partition; - using partition_type_base::self; // CRTP helper to get access to derived classes - size_t my_divisor; - // For affinity_partitioner, my_divisor indicates the number of affinity array indices the task reserves. - // A task which has only one index must produce the right split without reserved index in order to avoid - // it to be overwritten in note_affinity() of the created (right) task. - // I.e. a task created deeper than the affinity array can remember must not save its affinity (LIFO order) - static const unsigned factor = 1; - adaptive_mode() : my_divisor(tbb::internal::get_initial_auto_partitioner_divisor() / 4 * my_partition::factor) {} - adaptive_mode(adaptive_mode &src, split) : my_divisor(do_split(src, split())) {} - adaptive_mode(adaptive_mode &src, const proportional_split& split_obj) : my_divisor(do_split(src, split_obj)) {} - /*! Override do_split methods in order to specify splitting strategy */ - size_t do_split(adaptive_mode &src, split) { - return src.my_divisor /= 2u; - } - size_t do_split(adaptive_mode &src, const proportional_split& split_obj) { -#if __TBB_ENABLE_RANGE_FEEDBACK - size_t portion = size_t(float(src.my_divisor) * float(split_obj.right()) - / float(split_obj.left() + split_obj.right()) + 0.5f); -#else - size_t portion = split_obj.right() * my_partition::factor; -#endif - portion = (portion + my_partition::factor/2) & (0ul - my_partition::factor); -#if __TBB_ENABLE_RANGE_FEEDBACK - /** Corner case handling */ - if (!portion) - portion = my_partition::factor; - else if (portion == src.my_divisor) - portion = src.my_divisor - my_partition::factor; -#endif - src.my_divisor -= portion; - return portion; - } - bool is_divisible() { // part of old should_execute_range() - return my_divisor > my_partition::factor; - } -}; - -//! Provides default linear indexing of partitioner's sequence -template -struct linear_affinity_mode : adaptive_mode { - using adaptive_mode::my_divisor; - size_t my_head; - using adaptive_mode::self; - linear_affinity_mode() : adaptive_mode(), my_head(0) {} - linear_affinity_mode(linear_affinity_mode &src, split) : adaptive_mode(src, split()) - , my_head(src.my_head + src.my_divisor) {} - linear_affinity_mode(linear_affinity_mode &src, const proportional_split& split_obj) : adaptive_mode(src, split_obj) - , my_head(src.my_head + src.my_divisor) {} - void set_affinity( task &t ) { - if( my_divisor ) - t.set_affinity( affinity_id(my_head) + 1 ); - } -}; - -//! Class determines whether template parameter has static boolean constant -//! 'is_splittable_in_proportion' initialized with value of 'true' or not. -/** If template parameter has such field that has been initialized with non-zero - * value then class field will be set to 'true', otherwise - 'false' - */ -template -class is_splittable_in_proportion { -private: - typedef char yes[1]; - typedef char no [2]; - - template static yes& decide(typename enable_if::type *); - template static no& decide(...); -public: - // equals to 'true' if and only if static const variable 'is_splittable_in_proportion' of template parameter - // initialized with the value of 'true' - static const bool value = (sizeof(decide(0)) == sizeof(yes)); -}; - -//! Provides default methods for non-balancing partition objects. -template -struct unbalancing_partition_type : Mode { - using Mode::self; - unbalancing_partition_type() : Mode() {} - unbalancing_partition_type(unbalancing_partition_type& p, split) : Mode(p, split()) {} - unbalancing_partition_type(unbalancing_partition_type& p, const proportional_split& split_obj) : Mode(p, split_obj) {} -#if _MSC_VER && !defined(__INTEL_COMPILER) - // Suppress "conditional expression is constant" warning. - #pragma warning( push ) - #pragma warning( disable: 4127 ) -#endif - template - proportional_split get_split() { - if (is_splittable_in_proportion::value) { - size_t size = self().my_divisor / Mode::my_partition::factor; -#if __TBB_NONUNIFORM_TASK_CREATION - size_t right = (size + 2) / 3; -#else - size_t right = size / 2; -#endif - size_t left = size - right; - return proportional_split(left, right); - } else { - return proportional_split(1, 1); - } - } -#if _MSC_VER && !defined(__INTEL_COMPILER) - #pragma warning( pop ) -#endif // warning 4127 is back -}; - -/*! Determine work-balance phase implementing splitting & stealing actions */ -template -struct balancing_partition_type : unbalancing_partition_type { - using Mode::self; -#ifdef __TBB_USE_MACHINE_TIME_STAMPS - tbb::internal::machine_tsc_t my_dst_tsc; -#endif - enum { - begin = 0, - run, - pass - } my_delay; - depth_t my_max_depth; - static const unsigned range_pool_size = __TBB_RANGE_POOL_CAPACITY; - balancing_partition_type(): unbalancing_partition_type() -#ifdef __TBB_USE_MACHINE_TIME_STAMPS - , my_dst_tsc(0) -#endif - , my_delay(begin) - , my_max_depth(__TBB_INIT_DEPTH) {} - balancing_partition_type(balancing_partition_type& p, split) - : unbalancing_partition_type(p, split()) -#ifdef __TBB_USE_MACHINE_TIME_STAMPS - , my_dst_tsc(0) -#endif - , my_delay(pass) - , my_max_depth(p.my_max_depth) {} - balancing_partition_type(balancing_partition_type& p, const proportional_split& split_obj) - : unbalancing_partition_type(p, split_obj) -#ifdef __TBB_USE_MACHINE_TIME_STAMPS - , my_dst_tsc(0) -#endif - , my_delay(begin) - , my_max_depth(p.my_max_depth) {} - bool check_being_stolen( task &t) { // part of old should_execute_range() - if( !(self().my_divisor / Mode::my_partition::factor) ) { // if not from the top P tasks of binary tree - self().my_divisor = 1; // TODO: replace by on-stack flag (partition_state's member)? - if( t.is_stolen_task() && t.parent()->ref_count() >= 2 ) { // runs concurrently with the left task -#if __TBB_USE_OPTIONAL_RTTI - // RTTI is available, check whether the cast is valid - __TBB_ASSERT(dynamic_cast(t.parent()), 0); - // correctness of the cast relies on avoiding the root task for which: - // - initial value of my_divisor != 0 (protected by separate assertion) - // - is_stolen_task() always returns false for the root task. -#endif - flag_task::mark_task_stolen(t); - if( !my_max_depth ) my_max_depth++; - my_max_depth += __TBB_DEMAND_DEPTH_ADD; - return true; - } - } - return false; - } - depth_t max_depth() { return my_max_depth; } - void align_depth(depth_t base) { - __TBB_ASSERT(base <= my_max_depth, 0); - my_max_depth -= base; - } - template - void work_balance(StartType &start, Range &range) { - if( !range.is_divisible() || !self().max_depth() ) { - start.run_body( range ); // simple partitioner goes always here - } - else { // do range pool - internal::range_vector range_pool(range); - do { - range_pool.split_to_fill(self().max_depth()); // fill range pool - if( self().check_for_demand( start ) ) { - if( range_pool.size() > 1 ) { - start.offer_work( range_pool.front(), range_pool.front_depth() ); - range_pool.pop_front(); - continue; - } - if( range_pool.is_divisible(self().max_depth()) ) // was not enough depth to fork a task - continue; // note: next split_to_fill() should split range at least once - } - start.run_body( range_pool.back() ); - range_pool.pop_back(); - } while( !range_pool.empty() && !start.is_cancelled() ); - } - } - bool check_for_demand( task &t ) { - if( pass == my_delay ) { - if( self().my_divisor > 1 ) // produce affinitized tasks while they have slot in array - return true; // do not do my_max_depth++ here, but be sure range_pool is splittable once more - else if( self().my_divisor && my_max_depth ) { // make balancing task - self().my_divisor = 0; // once for each task; depth will be decreased in align_depth() - return true; - } - else if( flag_task::is_peer_stolen(t) ) { - my_max_depth += __TBB_DEMAND_DEPTH_ADD; - return true; - } - } else if( begin == my_delay ) { -#ifndef __TBB_USE_MACHINE_TIME_STAMPS - my_delay = pass; -#else - my_dst_tsc = __TBB_time_stamp() + __TBB_task_duration(); - my_delay = run; - } else if( run == my_delay ) { - if( __TBB_time_stamp() < my_dst_tsc ) { - __TBB_ASSERT(my_max_depth > 0, NULL); - my_max_depth--; // increase granularity since tasks seem having too small work - return false; - } - my_delay = pass; - return true; -#endif // __TBB_USE_MACHINE_TIME_STAMPS - } - return false; - } -}; - -class auto_partition_type: public balancing_partition_type > { -public: - auto_partition_type( const auto_partitioner& ) - : balancing_partition_type >() { - my_divisor *= __TBB_INITIAL_CHUNKS; - } - auto_partition_type( auto_partition_type& src, split) - : balancing_partition_type >(src, split()) {} - bool is_divisible() { // part of old should_execute_range() - if( my_divisor > 1 ) return true; - if( my_divisor && my_max_depth ) { // can split the task. TODO: on-stack flag instead - // keep same fragmentation while splitting for the local task pool - my_max_depth--; - my_divisor = 0; // decrease max_depth once per task - return true; - } else return false; - } - bool check_for_demand(task &t) { - if( flag_task::is_peer_stolen(t) ) { - my_max_depth += __TBB_DEMAND_DEPTH_ADD; - return true; - } else return false; - } -}; - -class simple_partition_type: public partition_type_base { -public: - simple_partition_type( const simple_partitioner& ) {} - simple_partition_type( const simple_partition_type&, split ) {} - //! simplified algorithm - template - void execute(StartType &start, Range &range) { - split_type split_obj = split(); // start.offer_work accepts split_type as reference - while( range.is_divisible() ) - start.offer_work( split_obj ); - start.run_body( range ); - } -}; - -class static_partition_type : public unbalancing_partition_type > { -public: - typedef proportional_split split_type; - static_partition_type( const static_partitioner& ) - : unbalancing_partition_type >() {} - static_partition_type( static_partition_type& p, split ) - : unbalancing_partition_type >(p, split()) {} - static_partition_type( static_partition_type& p, const proportional_split& split_obj ) - : unbalancing_partition_type >(p, split_obj) {} -}; - -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 - tbb::internal::affinity_id* my_array; -public: - static const unsigned factor = 1 << factor_power; // number of slots in affinity array per task - typedef proportional_split split_type; - affinity_partition_type( tbb::internal::affinity_partitioner_base_v3& ap ) - : balancing_partition_type >() { - __TBB_ASSERT( (factor&(factor-1))==0, "factor must be power of two" ); - ap.resize(factor); - my_array = ap.my_array; - my_max_depth = factor_power + 1; - __TBB_ASSERT( my_max_depth < __TBB_RANGE_POOL_CAPACITY, 0 ); - } - affinity_partition_type(affinity_partition_type& p, split) - : balancing_partition_type >(p, split()) - , my_array(p.my_array) {} - affinity_partition_type(affinity_partition_type& p, const proportional_split& split_obj) - : balancing_partition_type >(p, split_obj) - , my_array(p.my_array) {} - void set_affinity( task &t ) { - if( my_divisor ) { - if( !my_array[my_head] ) - // TODO: consider new ideas with my_array for both affinity and static partitioner's, then code reuse - t.set_affinity( affinity_id(my_head / factor + 1) ); - else - t.set_affinity( my_array[my_head] ); - } - } - void note_affinity( task::affinity_id id ) { - if( my_divisor ) - my_array[my_head] = id; - } -}; - -//! Backward-compatible partition for auto and affinity partition objects. -class old_auto_partition_type: public tbb::internal::partition_type_base { - size_t num_chunks; - static const size_t VICTIM_CHUNKS = 4; -public: - bool should_execute_range(const task &t) { - if( num_chunks friend class serial::interface9::start_for; - template friend class interface9::internal::start_for; - template friend class interface9::internal::start_reduce; - template friend class internal::start_scan; - // backward compatibility - class partition_type: public internal::partition_type_base { - public: - bool should_execute_range(const task& ) {return false;} - partition_type( const simple_partitioner& ) {} - partition_type( const partition_type&, split ) {} - }; - // new implementation just extends existing interface - typedef interface9::internal::simple_partition_type task_partition_type; - - // TODO: consider to make split_type public - typedef interface9::internal::simple_partition_type::split_type split_type; -}; - -//! An auto partitioner -/** The range is initial divided into several large chunks. - Chunks are further subdivided into smaller pieces if demand detected and they are divisible. - @ingroup algorithms */ -class auto_partitioner { -public: - auto_partitioner() {} - -private: - template friend class serial::interface9::start_for; - template friend class interface9::internal::start_for; - template friend class interface9::internal::start_reduce; - template friend class internal::start_scan; - // backward compatibility - typedef interface9::internal::old_auto_partition_type partition_type; - // new implementation just extends existing interface - typedef interface9::internal::auto_partition_type task_partition_type; - - // TODO: consider to make split_type public - typedef interface9::internal::auto_partition_type::split_type split_type; -}; - -//! A static partitioner -class static_partitioner { -public: - static_partitioner() {} -private: - template friend class serial::interface9::start_for; - template friend class interface9::internal::start_for; - template friend class interface9::internal::start_reduce; - template friend class internal::start_scan; - // backward compatibility - typedef interface9::internal::old_auto_partition_type partition_type; - // new implementation just extends existing interface - typedef interface9::internal::static_partition_type task_partition_type; - - // TODO: consider to make split_type public - typedef interface9::internal::static_partition_type::split_type split_type; -}; - -//! An affinity partitioner -class affinity_partitioner: internal::affinity_partitioner_base_v3 { -public: - affinity_partitioner() {} - -private: - template friend class serial::interface9::start_for; - template friend class interface9::internal::start_for; - template friend class interface9::internal::start_reduce; - template friend class internal::start_scan; - // backward compatibility - for parallel_scan only - typedef interface9::internal::old_auto_partition_type partition_type; - // new implementation just extends existing interface - typedef interface9::internal::affinity_partition_type task_partition_type; - - // TODO: consider to make split_type public - typedef interface9::internal::affinity_partition_type::split_type split_type; -}; - -} // namespace tbb - -#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) - #pragma warning (pop) -#endif // warning 4244 is back -#undef __TBB_INITIAL_CHUNKS -#undef __TBB_RANGE_POOL_CAPACITY -#undef __TBB_INIT_DEPTH -#endif /* __TBB_partitioner_H */ diff --git a/lib/3rdParty/tbb/include/tbb/pipeline.h b/lib/3rdParty/tbb/include/tbb/pipeline.h deleted file mode 100644 index 20a8ec9b..00000000 --- a/lib/3rdParty/tbb/include/tbb/pipeline.h +++ /dev/null @@ -1,665 +0,0 @@ -/* - 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_pipeline_H -#define __TBB_pipeline_H - -#include "atomic.h" -#include "task.h" -#include "tbb_allocator.h" -#include - -#if __TBB_CPP11_TYPE_PROPERTIES_PRESENT || __TBB_TR1_TYPE_PROPERTIES_IN_STD_PRESENT -#include -#endif - -namespace tbb { - -class pipeline; -class filter; - -//! @cond INTERNAL -namespace internal { - -// The argument for PIPELINE_VERSION should be an integer between 2 and 9 -#define __TBB_PIPELINE_VERSION(x) ((unsigned char)(x-2)<<1) - -typedef unsigned long Token; -typedef long tokendiff_t; -class stage_task; -class input_buffer; -class pipeline_root_task; -class pipeline_cleaner; - -} // namespace internal - -namespace interface6 { - template class filter_t; - - namespace internal { - class pipeline_proxy; - } -} - -//! @endcond - -//! A stage in a pipeline. -/** @ingroup algorithms */ -class filter: internal::no_copy { -private: - //! Value used to mark "not in pipeline" - static filter* not_in_pipeline() {return reinterpret_cast(intptr_t(-1));} -protected: - //! The lowest bit 0 is for parallel vs. serial - static const unsigned char filter_is_serial = 0x1; - - //! 4th bit distinguishes ordered vs unordered filters. - /** The bit was not set for parallel filters in TBB 2.1 and earlier, - but is_ordered() function always treats parallel filters as out of order. */ - static const unsigned char filter_is_out_of_order = 0x1<<4; - - //! 5th bit distinguishes thread-bound and regular filters. - static const unsigned char filter_is_bound = 0x1<<5; - - //! 6th bit marks input filters emitting small objects - static const unsigned char filter_may_emit_null = 0x1<<6; - - //! 7th bit defines exception propagation mode expected by the application. - static const unsigned char exact_exception_propagation = -#if TBB_USE_CAPTURED_EXCEPTION - 0x0; -#else - 0x1<<7; -#endif /* TBB_USE_CAPTURED_EXCEPTION */ - - static const unsigned char current_version = __TBB_PIPELINE_VERSION(5); - static const unsigned char version_mask = 0x7<<1; // bits 1-3 are for version -public: - enum mode { - //! processes multiple items in parallel and in no particular order - parallel = current_version | filter_is_out_of_order, - //! processes items one at a time; all such filters process items in the same order - serial_in_order = current_version | filter_is_serial, - //! processes items one at a time and in no particular order - serial_out_of_order = current_version | filter_is_serial | filter_is_out_of_order, - //! @deprecated use serial_in_order instead - serial = serial_in_order - }; -protected: - 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)), - prev_filter_in_pipeline(not_in_pipeline()), - my_pipeline(NULL), - next_segment(NULL) - {} - - 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)), - prev_filter_in_pipeline(not_in_pipeline()), - my_pipeline(NULL), - next_segment(NULL) - {} - - // signal end-of-input for concrete_filters - void __TBB_EXPORTED_METHOD set_end_of_input(); - -public: - //! True if filter is serial. - bool is_serial() const { - return bool( my_filter_mode & filter_is_serial ); - } - - //! True if filter must receive stream in order. - bool is_ordered() const { - return (my_filter_mode & (filter_is_out_of_order|filter_is_serial))==filter_is_serial; - } - - //! True if filter is thread-bound. - bool is_bound() const { - return ( my_filter_mode & filter_is_bound )==filter_is_bound; - } - - //! true if an input filter can emit null - bool object_may_be_null() { - return ( my_filter_mode & filter_may_emit_null ) == filter_may_emit_null; - } - - //! Operate on an item from the input stream, and return item for output stream. - /** Returns NULL if filter is a sink. */ - virtual void* operator()( void* item ) = 0; - - //! Destroy filter. - /** If the filter was added to a pipeline, the pipeline must be destroyed first. */ - virtual __TBB_EXPORTED_METHOD ~filter(); - -#if __TBB_TASK_GROUP_CONTEXT - //! Destroys item if pipeline was cancelled. - /** Required to prevent memory leaks. - Note it can be called concurrently even for serial filters.*/ - virtual void finalize( void* /*item*/ ) {}; -#endif - -private: - //! Pointer to next filter in the pipeline. - filter* next_filter_in_pipeline; - - //! has the filter not yet processed all the tokens it will ever see? - // (pipeline has not yet reached end_of_input or this filter has not yet - // seen the last token produced by input_filter) - bool has_more_work(); - - //! Buffer for incoming tokens, or NULL if not required. - /** The buffer is required if the filter is serial or follows a thread-bound one. */ - internal::input_buffer* my_input_buffer; - - friend class internal::stage_task; - friend class internal::pipeline_root_task; - friend class pipeline; - friend class thread_bound_filter; - - //! Storage for filter mode and dynamically checked implementation version. - const unsigned char my_filter_mode; - - //! Pointer to previous filter in the pipeline. - filter* prev_filter_in_pipeline; - - //! Pointer to the pipeline. - pipeline* my_pipeline; - - //! Pointer to the next "segment" of filters, or NULL if not required. - /** In each segment, the first filter is not thread-bound but follows a thread-bound one. */ - filter* next_segment; -}; - -//! A stage in a pipeline served by a user thread. -/** @ingroup algorithms */ -class thread_bound_filter: public filter { -public: - enum result_type { - // item was processed - success, - // item is currently not available - item_not_available, - // there are no more items to process - end_of_stream - }; -protected: - 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"); - } -public: - //! If a data item is available, invoke operator() on that item. - /** This interface is non-blocking. - Returns 'success' if an item was processed. - Returns 'item_not_available' if no item can be processed now - but more may arrive in the future, or if token limit is reached. - Returns 'end_of_stream' if there are no more items to process. */ - result_type __TBB_EXPORTED_METHOD try_process_item(); - - //! Wait until a data item becomes available, and invoke operator() on that item. - /** This interface is blocking. - Returns 'success' if an item was processed. - Returns 'end_of_stream' if there are no more items to process. - Never returns 'item_not_available', as it blocks until another return condition applies. */ - result_type __TBB_EXPORTED_METHOD process_item(); - -private: - //! Internal routine for item processing - result_type internal_process_item(bool is_blocking); -}; - -//! A processing pipeline that applies filters to items. -/** @ingroup algorithms */ -class pipeline { -public: - //! Construct empty pipeline. - __TBB_EXPORTED_METHOD pipeline(); - - /** Though the current implementation declares the destructor virtual, do not rely on this - detail. The virtualness is deprecated and may disappear in future versions of TBB. */ - virtual __TBB_EXPORTED_METHOD ~pipeline(); - - //! Add filter to end of pipeline. - void __TBB_EXPORTED_METHOD add_filter( filter& filter_ ); - - //! Run the pipeline to completion. - void __TBB_EXPORTED_METHOD run( size_t max_number_of_live_tokens ); - -#if __TBB_TASK_GROUP_CONTEXT - //! Run the pipeline to completion with user-supplied context. - void __TBB_EXPORTED_METHOD run( size_t max_number_of_live_tokens, tbb::task_group_context& context ); -#endif - - //! Remove all filters from the pipeline. - void __TBB_EXPORTED_METHOD clear(); - -private: - friend class internal::stage_task; - friend class internal::pipeline_root_task; - friend class filter; - friend class thread_bound_filter; - friend class internal::pipeline_cleaner; - friend class tbb::interface6::internal::pipeline_proxy; - - //! Pointer to first filter in the pipeline. - filter* filter_list; - - //! Pointer to location where address of next filter to be added should be stored. - filter* filter_end; - - //! task who's reference count is used to determine when all stages are done. - task* end_counter; - - //! Number of idle tokens waiting for input stage. - atomic input_tokens; - - //! Global counter of tokens - atomic token_counter; - - //! False until fetch_input returns NULL. - bool end_of_input; - - //! True if the pipeline contains a thread-bound filter; false otherwise. - bool has_thread_bound_filters; - - //! Remove filter from pipeline. - void remove_filter( filter& filter_ ); - - //! Not used, but retained to satisfy old export files. - void __TBB_EXPORTED_METHOD inject_token( task& self ); - -#if __TBB_TASK_GROUP_CONTEXT - //! Does clean up if pipeline is cancelled or exception occurred - void clear_filters(); -#endif -}; - -//------------------------------------------------------------------------ -// Support for lambda-friendly parallel_pipeline interface -//------------------------------------------------------------------------ - -namespace interface6 { - -namespace internal { - template class concrete_filter; -} - -//! input_filter control to signal end-of-input for parallel_pipeline -class flow_control { - bool is_pipeline_stopped; - flow_control() { is_pipeline_stopped = false; } - template friend class internal::concrete_filter; -public: - void stop() { is_pipeline_stopped = true; } -}; - -//! @cond INTERNAL -namespace internal { - -template struct tbb_large_object {enum { value = sizeof(T) > sizeof(void *) }; }; - -// Obtain type properties in one or another way -#if __TBB_CPP11_TYPE_PROPERTIES_PRESENT -template struct tbb_trivially_copyable { enum { value = std::is_trivially_copyable::value }; }; -#elif __TBB_TR1_TYPE_PROPERTIES_IN_STD_PRESENT -template struct tbb_trivially_copyable { enum { value = std::has_trivial_copy_constructor::value }; }; -#else -// Explicitly list the types we wish to be placed as-is in the pipeline input_buffers. -template struct tbb_trivially_copyable { enum { value = false }; }; -template struct tbb_trivially_copyable { enum { value = true }; }; -template<> struct tbb_trivially_copyable { enum { value = true }; }; -template<> struct tbb_trivially_copyable { enum { value = true }; }; -template<> struct tbb_trivially_copyable { enum { value = !tbb_large_object::value }; }; -template<> struct tbb_trivially_copyable { enum { value = !tbb_large_object::value }; }; -template<> struct tbb_trivially_copyable { enum { value = !tbb_large_object::value }; }; -template<> struct tbb_trivially_copyable { enum { value = !tbb_large_object::value }; }; -template<> struct tbb_trivially_copyable { enum { value = !tbb_large_object::value }; }; -template<> struct tbb_trivially_copyable { enum { value = !tbb_large_object::value }; }; -#endif // Obtaining type properties - -template struct is_large_object {enum { value = tbb_large_object::value || !tbb_trivially_copyable::value }; }; - -template class token_helper; - -// large object helper (uses tbb_allocator) -template -class token_helper { - public: - typedef typename tbb::tbb_allocator allocator; - typedef T* pointer; - typedef T value_type; - static pointer create_token(const value_type & source) { - pointer output_t = allocator().allocate(1); - return new (output_t) T(source); - } - static value_type & token(pointer & t) { return *t;} - static void * cast_to_void_ptr(pointer ref) { return (void *) ref; } - static pointer cast_from_void_ptr(void * ref) { return (pointer)ref; } - static void destroy_token(pointer token) { - allocator().destroy(token); - allocator().deallocate(token,1); - } -}; - -// pointer specialization -template -class token_helper { - public: - typedef T* pointer; - typedef T* value_type; - static pointer create_token(const value_type & source) { return source; } - static value_type & token(pointer & t) { return t;} - static void * cast_to_void_ptr(pointer ref) { return (void *)ref; } - static pointer cast_from_void_ptr(void * ref) { return (pointer)ref; } - static void destroy_token( pointer /*token*/) {} -}; - -// small object specialization (converts void* to the correct type, passes objects directly.) -template -class token_helper { - typedef union { - T actual_value; - void * void_overlay; - } type_to_void_ptr_map; - public: - typedef T pointer; // not really a pointer in this case. - typedef T value_type; - static pointer create_token(const value_type & source) { - return source; } - static value_type & token(pointer & t) { return t;} - static void * cast_to_void_ptr(pointer ref) { - type_to_void_ptr_map mymap; - mymap.void_overlay = NULL; - mymap.actual_value = ref; - return mymap.void_overlay; - } - static pointer cast_from_void_ptr(void * ref) { - type_to_void_ptr_map mymap; - mymap.void_overlay = ref; - return mymap.actual_value; - } - static void destroy_token( pointer /*token*/) {} -}; - -template -class concrete_filter: public tbb::filter { - const Body& my_body; - typedef token_helper::value > t_helper; - typedef typename t_helper::pointer t_pointer; - typedef token_helper::value > u_helper; - typedef typename u_helper::pointer u_pointer; - - 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); - } - - void finalize(void * input) __TBB_override { - t_pointer temp_input = t_helper::cast_from_void_ptr(input); - t_helper::destroy_token(temp_input); - } - -public: - concrete_filter(tbb::filter::mode filter_mode, const Body& body) : filter(filter_mode), my_body(body) {} -}; - -// input -template -class concrete_filter: public filter { - const Body& my_body; - typedef token_helper::value > u_helper; - typedef typename u_helper::pointer u_pointer; - - void* operator()(void*) __TBB_override { - flow_control control; - u_pointer output_u = u_helper::create_token(my_body(control)); - if(control.is_pipeline_stopped) { - u_helper::destroy_token(output_u); - set_end_of_input(); - return NULL; - } - return u_helper::cast_to_void_ptr(output_u); - } - -public: - concrete_filter(tbb::filter::mode filter_mode, const Body& body) : - filter(static_cast(filter_mode | filter_may_emit_null)), - my_body(body) - {} -}; - -template -class concrete_filter: public filter { - const Body& my_body; - typedef token_helper::value > t_helper; - typedef typename t_helper::pointer t_pointer; - - 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; - } - void finalize(void* input) __TBB_override { - t_pointer temp_input = t_helper::cast_from_void_ptr(input); - t_helper::destroy_token(temp_input); - } - -public: - concrete_filter(tbb::filter::mode filter_mode, const Body& body) : filter(filter_mode), my_body(body) {} -}; - -template -class concrete_filter: public filter { - const Body& my_body; - - /** Override privately because it is always called virtually */ - void* operator()(void*) __TBB_override { - flow_control control; - my_body(control); - void* output = control.is_pipeline_stopped ? NULL : (void*)(intptr_t)-1; - return output; - } -public: - concrete_filter(filter::mode filter_mode, const Body& body) : filter(filter_mode), my_body(body) {} -}; - -//! The class that represents an object of the pipeline for parallel_pipeline(). -/** It primarily serves as RAII class that deletes heap-allocated filter instances. */ -class pipeline_proxy { - tbb::pipeline my_pipe; -public: - pipeline_proxy( const filter_t& filter_chain ); - ~pipeline_proxy() { - while( filter* f = my_pipe.filter_list ) - delete f; // filter destructor removes it from the pipeline - } - tbb::pipeline* operator->() { return &my_pipe; } -}; - -//! Abstract base class that represents a node in a parse tree underlying a filter_t. -/** These nodes are always heap-allocated and can be shared by filter_t objects. */ -class filter_node: tbb::internal::no_copy { - /** Count must be atomic because it is hidden state for user, but might be shared by threads. */ - tbb::atomic ref_count; -protected: - filter_node() { - ref_count = 0; -#ifdef __TBB_TEST_FILTER_NODE_COUNT - ++(__TBB_TEST_FILTER_NODE_COUNT); -#endif - } -public: - //! Add concrete_filter to pipeline - virtual void add_to( pipeline& ) = 0; - //! Increment reference count - void add_ref() {++ref_count;} - //! Decrement reference count and delete if it becomes zero. - void remove_ref() { - __TBB_ASSERT(ref_count>0,"ref_count underflow"); - if( --ref_count==0 ) - delete this; - } - virtual ~filter_node() { -#ifdef __TBB_TEST_FILTER_NODE_COUNT - --(__TBB_TEST_FILTER_NODE_COUNT); -#endif - } -}; - -//! Node in parse tree representing result of make_filter. -template -class filter_node_leaf: public filter_node { - const tbb::filter::mode mode; - const Body body; - void add_to( pipeline& p ) __TBB_override { - concrete_filter* f = new concrete_filter(mode,body); - p.add_filter( *f ); - } -public: - filter_node_leaf( tbb::filter::mode m, const Body& b ) : mode(m), body(b) {} -}; - -//! Node in parse tree representing join of two filters. -class filter_node_join: public filter_node { - friend class filter_node; // to suppress GCC 3.2 warnings - filter_node& left; - filter_node& right; - ~filter_node_join() { - left.remove_ref(); - right.remove_ref(); - } - void add_to( pipeline& p ) __TBB_override { - left.add_to(p); - right.add_to(p); - } -public: - filter_node_join( filter_node& x, filter_node& y ) : left(x), right(y) { - left.add_ref(); - right.add_ref(); - } -}; - -} // namespace internal -//! @endcond - -//! Create a filter to participate in parallel_pipeline -template -filter_t make_filter(tbb::filter::mode mode, const Body& body) { - return new internal::filter_node_leaf(mode, body); -} - -template -filter_t operator& (const filter_t& left, const filter_t& right) { - __TBB_ASSERT(left.root,"cannot use default-constructed filter_t as left argument of '&'"); - __TBB_ASSERT(right.root,"cannot use default-constructed filter_t as right argument of '&'"); - return new internal::filter_node_join(*left.root,*right.root); -} - -//! Class representing a chain of type-safe pipeline filters -template -class filter_t { - typedef internal::filter_node filter_node; - filter_node* root; - filter_t( filter_node* root_ ) : root(root_) { - root->add_ref(); - } - friend class internal::pipeline_proxy; - template - friend filter_t make_filter(tbb::filter::mode, const Body& ); - template - friend filter_t operator& (const filter_t& , const filter_t& ); -public: - // TODO: add move-constructors, move-assignment, etc. where C++11 is available. - filter_t() : root(NULL) {} - filter_t( const filter_t& rhs ) : root(rhs.root) { - if( root ) root->add_ref(); - } - template - filter_t( tbb::filter::mode mode, const Body& body ) : - root( new internal::filter_node_leaf(mode, body) ) { - root->add_ref(); - } - - void operator=( const filter_t& rhs ) { - // Order of operations below carefully chosen so that reference counts remain correct - // in unlikely event that remove_ref throws exception. - filter_node* old = root; - root = rhs.root; - if( root ) root->add_ref(); - if( old ) old->remove_ref(); - } - ~filter_t() { - if( root ) root->remove_ref(); - } - void clear() { - // Like operator= with filter_t() on right side. - if( root ) { - filter_node* old = root; - root = NULL; - old->remove_ref(); - } - } -}; - -inline internal::pipeline_proxy::pipeline_proxy( const filter_t& filter_chain ) : my_pipe() { - __TBB_ASSERT( filter_chain.root, "cannot apply parallel_pipeline to default-constructed filter_t" ); - filter_chain.root->add_to(my_pipe); -} - -inline void parallel_pipeline(size_t max_number_of_live_tokens, const filter_t& filter_chain -#if __TBB_TASK_GROUP_CONTEXT - , tbb::task_group_context& context -#endif - ) { - internal::pipeline_proxy pipe(filter_chain); - // tbb::pipeline::run() is called via the proxy - pipe->run(max_number_of_live_tokens -#if __TBB_TASK_GROUP_CONTEXT - , context -#endif - ); -} - -#if __TBB_TASK_GROUP_CONTEXT -inline void parallel_pipeline(size_t max_number_of_live_tokens, const filter_t& filter_chain) { - tbb::task_group_context context; - parallel_pipeline(max_number_of_live_tokens, filter_chain, context); -} -#endif // __TBB_TASK_GROUP_CONTEXT - -} // interface6 - -using interface6::flow_control; -using interface6::filter_t; -using interface6::make_filter; -using interface6::parallel_pipeline; - -} // tbb - -#endif /* __TBB_pipeline_H */ diff --git a/lib/3rdParty/tbb/include/tbb/queuing_mutex.h b/lib/3rdParty/tbb/include/tbb/queuing_mutex.h deleted file mode 100644 index 0fe4b3ea..00000000 --- a/lib/3rdParty/tbb/include/tbb/queuing_mutex.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - 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_queuing_mutex_H -#define __TBB_queuing_mutex_H - -#include "tbb_config.h" - -#if !TBB_USE_EXCEPTIONS && _MSC_VER - // Suppress "C++ exception handler used, but unwind semantics are not enabled" warning in STL headers - #pragma warning (push) - #pragma warning (disable: 4530) -#endif - -#include - -#if !TBB_USE_EXCEPTIONS && _MSC_VER - #pragma warning (pop) -#endif - -#include "atomic.h" -#include "tbb_profiling.h" - -namespace tbb { - -//! Queuing mutex with local-only spinning. -/** @ingroup synchronization */ -class queuing_mutex : internal::mutex_copy_deprecated_and_disabled { -public: - //! Construct unacquired mutex. - queuing_mutex() { - q_tail = NULL; -#if TBB_USE_THREADING_TOOLS - internal_construct(); -#endif - } - - //! The scoped locking pattern - /** It helps to avoid the common problem of forgetting to release lock. - It also nicely provides the "node" for queuing locks. */ - class scoped_lock: internal::no_copy { - //! Initialize fields to mean "no lock held". - void initialize() { - mutex = NULL; -#if TBB_USE_ASSERT - internal::poison_pointer(next); -#endif /* TBB_USE_ASSERT */ - } - - public: - //! Construct lock that has not acquired a mutex. - /** Equivalent to zero-initialization of *this. */ - scoped_lock() {initialize();} - - //! Acquire lock on given mutex. - scoped_lock( queuing_mutex& m ) { - initialize(); - acquire(m); - } - - //! Release lock (if lock is held). - ~scoped_lock() { - if( mutex ) release(); - } - - //! Acquire lock on given mutex. - void __TBB_EXPORTED_METHOD acquire( queuing_mutex& m ); - - //! Acquire lock on given mutex if free (i.e. non-blocking) - bool __TBB_EXPORTED_METHOD try_acquire( queuing_mutex& m ); - - //! Release lock. - void __TBB_EXPORTED_METHOD release(); - - private: - //! The pointer to the mutex owned, or NULL if not holding a mutex. - queuing_mutex* mutex; - - //! The pointer to the next competitor for a mutex - scoped_lock *next; - - //! The local spin-wait variable - /** Inverted (0 - blocked, 1 - acquired the mutex) for the sake of - zero-initialization. Defining it as an entire word instead of - a byte seems to help performance slightly. */ - uintptr_t going; - }; - - void __TBB_EXPORTED_METHOD internal_construct(); - - // Mutex traits - static const bool is_rw_mutex = false; - static const bool is_recursive_mutex = false; - static const bool is_fair_mutex = true; - -private: - //! The last competitor requesting the lock - atomic q_tail; - -}; - -__TBB_DEFINE_PROFILING_SET_NAME(queuing_mutex) - -} // namespace tbb - -#endif /* __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 deleted file mode 100644 index e0224ed5..00000000 --- a/lib/3rdParty/tbb/include/tbb/queuing_rw_mutex.h +++ /dev/null @@ -1,163 +0,0 @@ -/* - 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_queuing_rw_mutex_H -#define __TBB_queuing_rw_mutex_H - -#include "tbb_config.h" - -#if !TBB_USE_EXCEPTIONS && _MSC_VER - // Suppress "C++ exception handler used, but unwind semantics are not enabled" warning in STL headers - #pragma warning (push) - #pragma warning (disable: 4530) -#endif - -#include - -#if !TBB_USE_EXCEPTIONS && _MSC_VER - #pragma warning (pop) -#endif - -#include "atomic.h" -#include "tbb_profiling.h" - -namespace tbb { - -//! Queuing reader-writer mutex with local-only spinning. -/** Adapted from Krieger, Stumm, et al. pseudocode at - http://www.eecg.toronto.edu/parallel/pubs_abs.html#Krieger_etal_ICPP93 - @ingroup synchronization */ -class queuing_rw_mutex : internal::mutex_copy_deprecated_and_disabled { -public: - //! Construct unacquired mutex. - queuing_rw_mutex() { - q_tail = NULL; -#if TBB_USE_THREADING_TOOLS - internal_construct(); -#endif - } - - //! Destructor asserts if the mutex is acquired, i.e. q_tail is non-NULL - ~queuing_rw_mutex() { -#if TBB_USE_ASSERT - __TBB_ASSERT( !q_tail, "destruction of an acquired mutex"); -#endif - } - - //! The scoped locking pattern - /** It helps to avoid the common problem of forgetting to release lock. - It also nicely provides the "node" for queuing locks. */ - class scoped_lock: internal::no_copy { - //! Initialize fields to mean "no lock held". - void initialize() { - my_mutex = NULL; -#if TBB_USE_ASSERT - my_state = 0xFF; // Set to invalid state - internal::poison_pointer(my_next); - internal::poison_pointer(my_prev); -#endif /* TBB_USE_ASSERT */ - } - - public: - //! Construct lock that has not acquired a mutex. - /** Equivalent to zero-initialization of *this. */ - scoped_lock() {initialize();} - - //! Acquire lock on given mutex. - scoped_lock( queuing_rw_mutex& m, bool write=true ) { - initialize(); - acquire(m,write); - } - - //! Release lock (if lock is held). - ~scoped_lock() { - if( my_mutex ) release(); - } - - //! Acquire lock on given mutex. - void acquire( queuing_rw_mutex& m, bool write=true ); - - //! Acquire lock on given mutex if free (i.e. non-blocking) - bool try_acquire( queuing_rw_mutex& m, bool write=true ); - - //! Release lock. - void release(); - - //! Upgrade reader to become a writer. - /** Returns whether the upgrade happened without releasing and re-acquiring the lock */ - bool upgrade_to_writer(); - - //! Downgrade writer to become a reader. - bool downgrade_to_reader(); - - private: - //! The pointer to the mutex owned, or NULL if not holding a mutex. - queuing_rw_mutex* my_mutex; - - //! The pointer to the previous and next competitors for a mutex - scoped_lock *__TBB_atomic my_prev, *__TBB_atomic my_next; - - typedef unsigned char state_t; - - //! State of the request: reader, writer, active reader, other service states - atomic my_state; - - //! The local spin-wait variable - /** Corresponds to "spin" in the pseudocode but inverted for the sake of zero-initialization */ - unsigned char __TBB_atomic my_going; - - //! A tiny internal lock - unsigned char my_internal_lock; - - //! Acquire the internal lock - void acquire_internal_lock(); - - //! Try to acquire the internal lock - /** Returns true if lock was successfully acquired. */ - bool try_acquire_internal_lock(); - - //! Release the internal lock - void release_internal_lock(); - - //! Wait for internal lock to be released - void wait_for_release_of_internal_lock(); - - //! A helper function - void unblock_or_wait_on_internal_lock( uintptr_t ); - }; - - void __TBB_EXPORTED_METHOD internal_construct(); - - // Mutex traits - static const bool is_rw_mutex = true; - static const bool is_recursive_mutex = false; - static const bool is_fair_mutex = true; - -private: - //! The last competitor requesting the lock - atomic q_tail; - -}; - -__TBB_DEFINE_PROFILING_SET_NAME(queuing_rw_mutex) - -} // namespace tbb - -#endif /* __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 deleted file mode 100644 index 353beec5..00000000 --- a/lib/3rdParty/tbb/include/tbb/reader_writer_lock.h +++ /dev/null @@ -1,232 +0,0 @@ -/* - 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_reader_writer_lock_H -#define __TBB_reader_writer_lock_H - -#include "tbb_thread.h" -#include "tbb_allocator.h" -#include "atomic.h" - -namespace tbb { -namespace interface5 { -//! Writer-preference reader-writer lock with local-only spinning on readers. -/** Loosely adapted from Mellor-Crummey and Scott pseudocode at - http://www.cs.rochester.edu/research/synchronization/pseudocode/rw.html#s_wp - @ingroup synchronization */ - class reader_writer_lock : tbb::internal::no_copy { - public: - friend class scoped_lock; - friend class scoped_lock_read; - //! Status type for nodes associated with lock instances - /** waiting_nonblocking: the wait state for nonblocking lock - instances; for writes, these transition straight to active - states; for reads, these are unused. - - waiting: the start and spin state for all lock instances; these will - transition to active state when appropriate. Non-blocking write locks - transition from this state to waiting_nonblocking immediately. - - active: the active state means that the lock instance holds - the lock; it will transition to invalid state during node deletion - - invalid: the end state for all nodes; this is set in the - destructor so if we encounter this state, we are looking at - memory that has already been freed - - The state diagrams below describe the status transitions. - Single arrows indicate that the thread that owns the node is - responsible for the transition; double arrows indicate that - any thread could make the transition. - - State diagram for scoped_lock status: - - waiting ----------> waiting_nonblocking - | _____________/ | - V V V - active -----------------> invalid - - State diagram for scoped_lock_read status: - - waiting - | - V - active ----------------->invalid - - */ - enum status_t { waiting_nonblocking, waiting, active, invalid }; - - //! Constructs a new reader_writer_lock - reader_writer_lock() { - internal_construct(); - } - - //! Destructs a reader_writer_lock object - ~reader_writer_lock() { - internal_destroy(); - } - - //! The scoped lock pattern for write locks - /** Scoped locks help avoid the common problem of forgetting to release the lock. - This type also serves as the node for queuing locks. */ - class scoped_lock : tbb::internal::no_copy { - public: - friend class reader_writer_lock; - - //! Construct with blocking attempt to acquire write lock on the passed-in lock - scoped_lock(reader_writer_lock& lock) { - internal_construct(lock); - } - - //! Destructor, releases the write lock - ~scoped_lock() { - internal_destroy(); - } - - void* operator new(size_t s) { - return tbb::internal::allocate_via_handler_v3(s); - } - void operator delete(void* p) { - tbb::internal::deallocate_via_handler_v3(p); - } - - private: - //! The pointer to the mutex to lock - reader_writer_lock *mutex; - //! The next queued competitor for the mutex - scoped_lock* next; - //! Status flag of the thread associated with this node - atomic status; - - //! Construct scoped_lock that is not holding lock - scoped_lock(); - - void __TBB_EXPORTED_METHOD internal_construct(reader_writer_lock&); - void __TBB_EXPORTED_METHOD internal_destroy(); - }; - - //! The scoped lock pattern for read locks - class scoped_lock_read : tbb::internal::no_copy { - public: - friend class reader_writer_lock; - - //! Construct with blocking attempt to acquire read lock on the passed-in lock - scoped_lock_read(reader_writer_lock& lock) { - internal_construct(lock); - } - - //! Destructor, releases the read lock - ~scoped_lock_read() { - internal_destroy(); - } - - void* operator new(size_t s) { - return tbb::internal::allocate_via_handler_v3(s); - } - void operator delete(void* p) { - tbb::internal::deallocate_via_handler_v3(p); - } - - private: - //! The pointer to the mutex to lock - reader_writer_lock *mutex; - //! The next queued competitor for the mutex - scoped_lock_read *next; - //! Status flag of the thread associated with this node - atomic status; - - //! Construct scoped_lock_read that is not holding lock - scoped_lock_read(); - - void __TBB_EXPORTED_METHOD internal_construct(reader_writer_lock&); - void __TBB_EXPORTED_METHOD internal_destroy(); - }; - - //! Acquires the reader_writer_lock for write. - /** If the lock is currently held in write mode by another - context, the writer will block by spinning on a local - variable. Exceptions thrown: improper_lock The context tries - to acquire a reader_writer_lock that it already has write - ownership of.*/ - void __TBB_EXPORTED_METHOD lock(); - - //! Tries to acquire the reader_writer_lock for write. - /** This function does not block. Return Value: True or false, - depending on whether the lock is acquired or not. If the lock - is already held by this acquiring context, try_lock() returns - false. */ - bool __TBB_EXPORTED_METHOD try_lock(); - - //! Acquires the reader_writer_lock for read. - /** If the lock is currently held by a writer, this reader will - block and wait until the writers are done. Exceptions thrown: - improper_lock The context tries to acquire a - reader_writer_lock that it already has write ownership of. */ - void __TBB_EXPORTED_METHOD lock_read(); - - //! Tries to acquire the reader_writer_lock for read. - /** This function does not block. Return Value: True or false, - depending on whether the lock is acquired or not. */ - bool __TBB_EXPORTED_METHOD try_lock_read(); - - //! Releases the reader_writer_lock - void __TBB_EXPORTED_METHOD unlock(); - - private: - void __TBB_EXPORTED_METHOD internal_construct(); - void __TBB_EXPORTED_METHOD internal_destroy(); - - //! Attempts to acquire write lock - /** If unavailable, spins in blocking case, returns false in non-blocking case. */ - bool start_write(scoped_lock *); - //! Sets writer_head to w and attempts to unblock - void set_next_writer(scoped_lock *w); - //! Relinquishes write lock to next waiting writer or group of readers - void end_write(scoped_lock *); - //! Checks if current thread holds write lock - bool is_current_writer(); - - //! Attempts to acquire read lock - /** If unavailable, spins in blocking case, returns false in non-blocking case. */ - void start_read(scoped_lock_read *); - //! Unblocks pending readers - void unblock_readers(); - //! Relinquishes read lock by decrementing counter; last reader wakes pending writer - void end_read(); - - //! The list of pending readers - atomic reader_head; - //! The list of pending writers - atomic writer_head; - //! The last node in the list of pending writers - atomic writer_tail; - //! Writer that owns the mutex; tbb_thread::id() otherwise. - tbb_thread::id my_current_writer; - //! Status of mutex - atomic rdr_count_and_flags; // used with __TBB_AtomicOR, which assumes uintptr_t -}; - -} // namespace interface5 - -using interface5::reader_writer_lock; - -} // namespace tbb - -#endif /* __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 deleted file mode 100644 index 5a23c097..00000000 --- a/lib/3rdParty/tbb/include/tbb/recursive_mutex.h +++ /dev/null @@ -1,234 +0,0 @@ -/* - 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_recursive_mutex_H -#define __TBB_recursive_mutex_H - -#if _WIN32||_WIN64 -#include "machine/windows_api.h" -#else -#include -#endif /* _WIN32||_WIN64 */ - -#include -#include "aligned_space.h" -#include "tbb_stddef.h" -#include "tbb_profiling.h" - -namespace tbb { -//! Mutex that allows recursive mutex acquisition. -/** Mutex that allows recursive mutex acquisition. - @ingroup synchronization */ -class recursive_mutex : internal::mutex_copy_deprecated_and_disabled { -public: - //! Construct unacquired recursive_mutex. - recursive_mutex() { -#if TBB_USE_ASSERT || TBB_USE_THREADING_TOOLS - internal_construct(); -#else - #if _WIN32||_WIN64 - InitializeCriticalSectionEx(&impl, 4000, 0); - #else - pthread_mutexattr_t mtx_attr; - int error_code = pthread_mutexattr_init( &mtx_attr ); - if( error_code ) - tbb::internal::handle_perror(error_code,"recursive_mutex: pthread_mutexattr_init failed"); - - pthread_mutexattr_settype( &mtx_attr, PTHREAD_MUTEX_RECURSIVE ); - error_code = pthread_mutex_init( &impl, &mtx_attr ); - if( error_code ) - tbb::internal::handle_perror(error_code,"recursive_mutex: pthread_mutex_init failed"); - - pthread_mutexattr_destroy( &mtx_attr ); - #endif /* _WIN32||_WIN64*/ -#endif /* TBB_USE_ASSERT */ - }; - - ~recursive_mutex() { -#if TBB_USE_ASSERT - internal_destroy(); -#else - #if _WIN32||_WIN64 - DeleteCriticalSection(&impl); - #else - pthread_mutex_destroy(&impl); - - #endif /* _WIN32||_WIN64 */ -#endif /* TBB_USE_ASSERT */ - }; - - class scoped_lock; - friend class scoped_lock; - - //! The scoped locking pattern - /** It helps to avoid the common problem of forgetting to release lock. - It also nicely provides the "node" for queuing locks. */ - class scoped_lock: internal::no_copy { - public: - //! Construct lock that has not acquired a recursive_mutex. - scoped_lock() : my_mutex(NULL) {}; - - //! Acquire lock on given mutex. - scoped_lock( recursive_mutex& mutex ) { -#if TBB_USE_ASSERT - my_mutex = &mutex; -#endif /* TBB_USE_ASSERT */ - acquire( mutex ); - } - - //! Release lock (if lock is held). - ~scoped_lock() { - if( my_mutex ) - release(); - } - - //! Acquire lock on given mutex. - void acquire( recursive_mutex& mutex ) { -#if TBB_USE_ASSERT - internal_acquire( mutex ); -#else - my_mutex = &mutex; - mutex.lock(); -#endif /* TBB_USE_ASSERT */ - } - - //! Try acquire lock on given recursive_mutex. - bool try_acquire( recursive_mutex& mutex ) { -#if TBB_USE_ASSERT - return internal_try_acquire( mutex ); -#else - bool result = mutex.try_lock(); - if( result ) - my_mutex = &mutex; - return result; -#endif /* TBB_USE_ASSERT */ - } - - //! Release lock - void release() { -#if TBB_USE_ASSERT - internal_release(); -#else - my_mutex->unlock(); - my_mutex = NULL; -#endif /* TBB_USE_ASSERT */ - } - - private: - //! The pointer to the current recursive_mutex to work - recursive_mutex* my_mutex; - - //! All checks from acquire using mutex.state were moved here - void __TBB_EXPORTED_METHOD internal_acquire( recursive_mutex& m ); - - //! All checks from try_acquire using mutex.state were moved here - bool __TBB_EXPORTED_METHOD internal_try_acquire( recursive_mutex& m ); - - //! All checks from release using mutex.state were moved here - void __TBB_EXPORTED_METHOD internal_release(); - - friend class recursive_mutex; - }; - - // Mutex traits - static const bool is_rw_mutex = false; - static const bool is_recursive_mutex = true; - static const bool is_fair_mutex = false; - - // C++0x compatibility interface - - //! Acquire lock - void lock() { -#if TBB_USE_ASSERT - aligned_space tmp; - new(tmp.begin()) scoped_lock(*this); -#else - #if _WIN32||_WIN64 - EnterCriticalSection(&impl); - #else - int error_code = pthread_mutex_lock(&impl); - if( error_code ) - tbb::internal::handle_perror(error_code,"recursive_mutex: pthread_mutex_lock failed"); - #endif /* _WIN32||_WIN64 */ -#endif /* TBB_USE_ASSERT */ - } - - //! Try acquiring lock (non-blocking) - /** Return true if lock acquired; false otherwise. */ - bool try_lock() { -#if TBB_USE_ASSERT - aligned_space tmp; - return (new(tmp.begin()) scoped_lock)->internal_try_acquire(*this); -#else - #if _WIN32||_WIN64 - return TryEnterCriticalSection(&impl)!=0; - #else - return pthread_mutex_trylock(&impl)==0; - #endif /* _WIN32||_WIN64 */ -#endif /* TBB_USE_ASSERT */ - } - - //! Release lock - void unlock() { -#if TBB_USE_ASSERT - aligned_space tmp; - scoped_lock& s = *tmp.begin(); - s.my_mutex = this; - s.internal_release(); -#else - #if _WIN32||_WIN64 - LeaveCriticalSection(&impl); - #else - pthread_mutex_unlock(&impl); - #endif /* _WIN32||_WIN64 */ -#endif /* TBB_USE_ASSERT */ - } - - //! Return native_handle - #if _WIN32||_WIN64 - typedef LPCRITICAL_SECTION native_handle_type; - #else - typedef pthread_mutex_t* native_handle_type; - #endif - native_handle_type native_handle() { return (native_handle_type) &impl; } - -private: -#if _WIN32||_WIN64 - CRITICAL_SECTION impl; - enum state_t { - INITIALIZED=0x1234, - DESTROYED=0x789A, - } state; -#else - pthread_mutex_t impl; -#endif /* _WIN32||_WIN64 */ - - //! All checks from mutex constructor using mutex.state were moved here - void __TBB_EXPORTED_METHOD internal_construct(); - - //! All checks from mutex destructor using mutex.state were moved here - void __TBB_EXPORTED_METHOD internal_destroy(); -}; - -__TBB_DEFINE_PROFILING_SET_NAME(recursive_mutex) - -} // namespace tbb - -#endif /* __TBB_recursive_mutex_H */ diff --git a/lib/3rdParty/tbb/include/tbb/runtime_loader.h b/lib/3rdParty/tbb/include/tbb/runtime_loader.h deleted file mode 100644 index df284645..00000000 --- a/lib/3rdParty/tbb/include/tbb/runtime_loader.h +++ /dev/null @@ -1,180 +0,0 @@ -/* - 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_runtime_loader_H -#define __TBB_runtime_loader_H - -#if ! TBB_PREVIEW_RUNTIME_LOADER - #error Set TBB_PREVIEW_RUNTIME_LOADER to include runtime_loader.h -#endif - -#include "tbb_stddef.h" -#include - -#if _MSC_VER - #if ! __TBB_NO_IMPLICIT_LINKAGE - #ifdef _DEBUG - #pragma comment( linker, "/nodefaultlib:tbb_debug.lib" ) - #pragma comment( linker, "/defaultlib:tbbproxy_debug.lib" ) - #else - #pragma comment( linker, "/nodefaultlib:tbb.lib" ) - #pragma comment( linker, "/defaultlib:tbbproxy.lib" ) - #endif - #endif -#endif - -namespace tbb { - -namespace interface6 { - -//! Load TBB at runtime. -/*! - -\b Usage: - -In source code: - -\code -#include "tbb/runtime_loader.h" - -char const * path[] = { "/lib/ia32", NULL }; -tbb::runtime_loader loader( path ); - -// Now use TBB. -\endcode - -Link with \c tbbproxy.lib (or \c libtbbproxy.a) instead of \c tbb.lib (\c libtbb.dylib, -\c libtbb.so). - -TBB library will be loaded at runtime from \c /lib/ia32 directory. - -\b Attention: - -All \c runtime_loader objects (in the same module, i.e. exe or dll) share some global state. -The most noticeable piece of global state is loaded TBB library. -There are some implications: - - - Only one TBB library can be loaded per module. - - - If one object has already loaded TBB library, another object will not load TBB. - If the loaded TBB library is suitable for the second object, both will use TBB - cooperatively, otherwise the second object will report an error. - - - \c runtime_loader objects will not work (correctly) in parallel due to absence of - synchronization. - -*/ - -class runtime_loader : tbb::internal::no_copy { - - public: - - //! Error mode constants. - enum error_mode { - em_status, //!< Save status of operation and continue. - em_throw, //!< Throw an exception of tbb::runtime_loader::error_code type. - em_abort //!< Print message to \c stderr and call \c abort(). - }; // error_mode - - //! Error codes. - enum error_code { - ec_ok, //!< No errors. - ec_bad_call, //!< Invalid function call (e. g. load() called when TBB is already loaded). - ec_bad_arg, //!< Invalid argument passed. - ec_bad_lib, //!< Invalid library found (e. g. \c TBB_runtime_version symbol not found). - ec_bad_ver, //!< TBB found but version is not suitable. - ec_no_lib //!< No suitable TBB library found. - }; // error_code - - //! Initialize object but do not load TBB. - runtime_loader( error_mode mode = em_abort ); - - //! Initialize object and load TBB. - /*! - See load() for details. - - If error mode is \c em_status, call status() to check whether TBB was loaded or not. - */ - runtime_loader( - char const * path[], //!< List of directories to search TBB in. - int min_ver = TBB_INTERFACE_VERSION, //!< Minimal suitable version of TBB. - int max_ver = INT_MAX, //!< Maximal suitable version of TBB. - error_mode mode = em_abort //!< Error mode for this object. - ); - - //! Destroy object. - ~runtime_loader(); - - //! Load TBB. - /*! - The method searches the directories specified in \c path[] array for the TBB library. - When the library is found, it is loaded and its version is checked. If the version is - not suitable, the library is unloaded, and the search continues. - - \b Note: - - For security reasons, avoid using relative directory names. For example, never load - TBB from current (\c "."), parent (\c "..") or any other relative directory (like - \c "lib" ). Use only absolute directory names (e. g. "/usr/local/lib"). - - For the same security reasons, avoid using system default directories (\c "") on - Windows. (See http://www.microsoft.com/technet/security/advisory/2269637.mspx for - details.) - - Neglecting these rules may cause your program to execute 3-rd party malicious code. - - \b Errors: - - \c ec_bad_call - TBB already loaded by this object. - - \c ec_bad_arg - \p min_ver and/or \p max_ver negative or zero, - or \p min_ver > \p max_ver. - - \c ec_bad_ver - TBB of unsuitable version already loaded by another object. - - \c ec_no_lib - No suitable library found. - */ - error_code - load( - char const * path[], //!< List of directories to search TBB in. - int min_ver = TBB_INTERFACE_VERSION, //!< Minimal suitable version of TBB. - int max_ver = INT_MAX //!< Maximal suitable version of TBB. - - ); - - - //! Report status. - /*! - If error mode is \c em_status, the function returns status of the last operation. - */ - error_code status(); - - private: - - error_mode const my_mode; - error_code my_status; - bool my_loaded; - -}; // class runtime_loader - -} // namespace interface6 - -using interface6::runtime_loader; - -} // namespace tbb - -#endif /* __TBB_runtime_loader_H */ - diff --git a/lib/3rdParty/tbb/include/tbb/scalable_allocator.h b/lib/3rdParty/tbb/include/tbb/scalable_allocator.h deleted file mode 100644 index c2a81493..00000000 --- a/lib/3rdParty/tbb/include/tbb/scalable_allocator.h +++ /dev/null @@ -1,341 +0,0 @@ -/* - 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_scalable_allocator_H -#define __TBB_scalable_allocator_H -/** @file */ - -#include /* Need ptrdiff_t and size_t from here. */ -#if !_MSC_VER -#include /* Need intptr_t from here. */ -#endif - -#if !defined(__cplusplus) && __ICC==1100 - #pragma warning (push) - #pragma warning (disable: 991) -#endif - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -#if _MSC_VER >= 1400 -#define __TBB_EXPORTED_FUNC __cdecl -#else -#define __TBB_EXPORTED_FUNC -#endif - -/** The "malloc" analogue to allocate block of memory of size bytes. - * @ingroup memory_allocation */ -void * __TBB_EXPORTED_FUNC scalable_malloc (size_t size); - -/** The "free" analogue to discard a previously allocated piece of memory. - @ingroup memory_allocation */ -void __TBB_EXPORTED_FUNC scalable_free (void* ptr); - -/** The "realloc" analogue complementing scalable_malloc. - @ingroup memory_allocation */ -void * __TBB_EXPORTED_FUNC scalable_realloc (void* ptr, size_t size); - -/** The "calloc" analogue complementing scalable_malloc. - @ingroup memory_allocation */ -void * __TBB_EXPORTED_FUNC scalable_calloc (size_t nobj, size_t size); - -/** The "posix_memalign" analogue. - @ingroup memory_allocation */ -int __TBB_EXPORTED_FUNC scalable_posix_memalign (void** memptr, size_t alignment, size_t size); - -/** The "_aligned_malloc" analogue. - @ingroup memory_allocation */ -void * __TBB_EXPORTED_FUNC scalable_aligned_malloc (size_t size, size_t alignment); - -/** The "_aligned_realloc" analogue. - @ingroup memory_allocation */ -void * __TBB_EXPORTED_FUNC scalable_aligned_realloc (void* ptr, size_t size, size_t alignment); - -/** The "_aligned_free" analogue. - @ingroup memory_allocation */ -void __TBB_EXPORTED_FUNC scalable_aligned_free (void* ptr); - -/** The analogue of _msize/malloc_size/malloc_usable_size. - Returns the usable size of a memory block previously allocated by scalable_*, - or 0 (zero) if ptr does not point to such a block. - @ingroup memory_allocation */ -size_t __TBB_EXPORTED_FUNC scalable_msize (void* ptr); - -/* Results for scalable_allocation_* functions */ -typedef enum { - TBBMALLOC_OK, - TBBMALLOC_INVALID_PARAM, - TBBMALLOC_UNSUPPORTED, - TBBMALLOC_NO_MEMORY, - TBBMALLOC_NO_EFFECT -} ScalableAllocationResult; - -/* Setting TBB_MALLOC_USE_HUGE_PAGES environment variable to 1 enables huge pages. - scalable_allocation_mode call has priority over environment variable. */ -typedef enum { - TBBMALLOC_USE_HUGE_PAGES, /* value turns using huge pages on and off */ - /* deprecated, kept for backward compatibility only */ - USE_HUGE_PAGES = TBBMALLOC_USE_HUGE_PAGES, - /* try to limit memory consumption value Bytes, clean internal buffers - if limit is exceeded, but not prevents from requesting memory from OS */ - TBBMALLOC_SET_SOFT_HEAP_LIMIT -} AllocationModeParam; - -/** Set TBB allocator-specific allocation modes. - @ingroup memory_allocation */ -int __TBB_EXPORTED_FUNC scalable_allocation_mode(int param, intptr_t value); - -typedef enum { - /* Clean internal allocator buffers for all threads. - Returns TBBMALLOC_NO_EFFECT if no buffers cleaned, - TBBMALLOC_OK if some memory released from buffers. */ - TBBMALLOC_CLEAN_ALL_BUFFERS, - /* Clean internal allocator buffer for current thread only. - Return values same as for TBBMALLOC_CLEAN_ALL_BUFFERS. */ - TBBMALLOC_CLEAN_THREAD_BUFFERS -} ScalableAllocationCmd; - -/** Call TBB allocator-specific commands. - @ingroup memory_allocation */ -int __TBB_EXPORTED_FUNC scalable_allocation_command(int cmd, void *param); - -#ifdef __cplusplus -} /* extern "C" */ -#endif /* __cplusplus */ - -#ifdef __cplusplus - -//! The namespace rml contains components of low-level memory pool interface. -namespace rml { -class MemoryPool; - -typedef void *(*rawAllocType)(intptr_t pool_id, size_t &bytes); -// returns non-zero in case of error -typedef int (*rawFreeType)(intptr_t pool_id, void* raw_ptr, size_t raw_bytes); - -/* -MemPoolPolicy extension must be compatible with such structure fields layout - -struct MemPoolPolicy { - rawAllocType pAlloc; - rawFreeType pFree; - size_t granularity; // granularity of pAlloc allocations -}; -*/ - -struct MemPoolPolicy { - enum { - TBBMALLOC_POOL_VERSION = 1 - }; - - rawAllocType pAlloc; - rawFreeType pFree; - // granularity of pAlloc allocations. 0 means default used. - size_t granularity; - int version; - // all memory consumed at 1st pAlloc call and never returned, - // no more pAlloc calls after 1st - unsigned fixedPool : 1, - // memory consumed but returned only at pool termination - keepAllMemory : 1, - reserved : 30; - - MemPoolPolicy(rawAllocType pAlloc_, rawFreeType pFree_, - size_t granularity_ = 0, bool fixedPool_ = false, - bool keepAllMemory_ = false) : - pAlloc(pAlloc_), pFree(pFree_), granularity(granularity_), version(TBBMALLOC_POOL_VERSION), - fixedPool(fixedPool_), keepAllMemory(keepAllMemory_), - reserved(0) {} -}; - -// enums have same values as appropriate enums from ScalableAllocationResult -// TODO: use ScalableAllocationResult in pool_create directly -enum MemPoolError { - // pool created successfully - POOL_OK = TBBMALLOC_OK, - // invalid policy parameters found - INVALID_POLICY = TBBMALLOC_INVALID_PARAM, - // requested pool policy is not supported by allocator library - UNSUPPORTED_POLICY = TBBMALLOC_UNSUPPORTED, - // lack of memory during pool creation - NO_MEMORY = TBBMALLOC_NO_MEMORY, - // action takes no effect - NO_EFFECT = TBBMALLOC_NO_EFFECT -}; - -MemPoolError pool_create_v1(intptr_t pool_id, const MemPoolPolicy *policy, - rml::MemoryPool **pool); - -bool pool_destroy(MemoryPool* memPool); -void *pool_malloc(MemoryPool* memPool, size_t size); -void *pool_realloc(MemoryPool* memPool, void *object, size_t size); -void *pool_aligned_malloc(MemoryPool* mPool, size_t size, size_t alignment); -void *pool_aligned_realloc(MemoryPool* mPool, void *ptr, size_t size, size_t alignment); -bool pool_reset(MemoryPool* memPool); -bool pool_free(MemoryPool *memPool, void *object); -MemoryPool *pool_identify(void *object); -} - -#include /* To use new with the placement argument */ - -/* Ensure that including this header does not cause implicit linkage with TBB */ -#ifndef __TBB_NO_IMPLICIT_LINKAGE - #define __TBB_NO_IMPLICIT_LINKAGE 1 - #include "tbb_stddef.h" - #undef __TBB_NO_IMPLICIT_LINKAGE -#else - #include "tbb_stddef.h" -#endif - -#if __TBB_ALLOCATOR_CONSTRUCT_VARIADIC - #include // std::forward -#endif - -namespace tbb { - -#if _MSC_VER && !defined(__INTEL_COMPILER) - // Workaround for erroneous "unreferenced parameter" warning in method destroy. - #pragma warning (push) - #pragma warning (disable: 4100) -#endif - -//! @cond INTERNAL -namespace internal { - -#if TBB_USE_EXCEPTIONS -// forward declaration is for inlining prevention -template __TBB_NOINLINE( void throw_exception(const E &e) ); -#endif - -// keep throw in a separate function to prevent code bloat -template -void throw_exception(const E &e) { - __TBB_THROW(e); -} - -} // namespace internal -//! @endcond - -//! Meets "allocator" requirements of ISO C++ Standard, Section 20.1.5 -/** The members are ordered the same way they are in section 20.4.1 - of the ISO C++ standard. - @ingroup memory_allocation */ -template -class scalable_allocator { -public: - typedef typename internal::allocator_type::value_type value_type; - typedef value_type* pointer; - typedef const value_type* const_pointer; - typedef value_type& reference; - typedef const value_type& const_reference; - typedef size_t size_type; - typedef ptrdiff_t difference_type; - template struct rebind { - typedef scalable_allocator other; - }; - - scalable_allocator() throw() {} - scalable_allocator( const scalable_allocator& ) throw() {} - template scalable_allocator(const scalable_allocator&) throw() {} - - pointer address(reference x) const {return &x;} - const_pointer address(const_reference x) const {return &x;} - - //! Allocate space for n objects. - pointer allocate( size_type n, const void* /*hint*/ =0 ) { - pointer p = static_cast( scalable_malloc( n * sizeof(value_type) ) ); - if (!p) - internal::throw_exception(std::bad_alloc()); - return p; - } - - //! Free previously allocated block of memory - void deallocate( pointer p, size_type ) { - scalable_free( p ); - } - - //! Largest value for which method allocate might succeed. - size_type max_size() const throw() { - size_type absolutemax = static_cast(-1) / sizeof (value_type); - return (absolutemax > 0 ? absolutemax : 1); - } -#if __TBB_ALLOCATOR_CONSTRUCT_VARIADIC - template - void construct(U *p, Args&&... args) - { ::new((void *)p) U(std::forward(args)...); } -#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 */ - void destroy( pointer p ) {p->~value_type();} -}; - -#if _MSC_VER && !defined(__INTEL_COMPILER) - #pragma warning (pop) -#endif /* warning 4100 is back */ - -//! Analogous to std::allocator, as defined in ISO C++ Standard, Section 20.4.1 -/** @ingroup memory_allocation */ -template<> -class scalable_allocator { -public: - typedef void* pointer; - typedef const void* const_pointer; - typedef void value_type; - template struct rebind { - typedef scalable_allocator other; - }; -}; - -template -inline bool operator==( const scalable_allocator&, const scalable_allocator& ) {return true;} - -template -inline bool operator!=( const scalable_allocator&, const scalable_allocator& ) {return false;} - -} // namespace tbb - -#if _MSC_VER - #if (__TBB_BUILD || __TBBMALLOC_BUILD) && !defined(__TBBMALLOC_NO_IMPLICIT_LINKAGE) - #define __TBBMALLOC_NO_IMPLICIT_LINKAGE 1 - #endif - - #if !__TBBMALLOC_NO_IMPLICIT_LINKAGE - #ifdef _DEBUG - #pragma comment(lib, "tbbmalloc_debug.lib") - #else - #pragma comment(lib, "tbbmalloc.lib") - #endif - #endif - - -#endif - -#endif /* __cplusplus */ - -#if !defined(__cplusplus) && __ICC==1100 - #pragma warning (pop) -#endif /* ICC 11.0 warning 991 is back */ - -#endif /* __TBB_scalable_allocator_H */ diff --git a/lib/3rdParty/tbb/include/tbb/spin_mutex.h b/lib/3rdParty/tbb/include/tbb/spin_mutex.h deleted file mode 100644 index 99ef15c2..00000000 --- a/lib/3rdParty/tbb/include/tbb/spin_mutex.h +++ /dev/null @@ -1,212 +0,0 @@ -/* - 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_spin_mutex_H -#define __TBB_spin_mutex_H - -#include -#include -#include "aligned_space.h" -#include "tbb_stddef.h" -#include "tbb_machine.h" -#include "tbb_profiling.h" -#include "internal/_mutex_padding.h" - -namespace tbb { - -//! A lock that occupies a single byte. -/** A spin_mutex is a spin mutex that fits in a single byte. - It should be used only for locking short critical sections - (typically less than 20 instructions) when fairness is not an issue. - If zero-initialized, the mutex is considered unheld. - @ingroup synchronization */ -class spin_mutex : internal::mutex_copy_deprecated_and_disabled { - //! 0 if lock is released, 1 if lock is acquired. - __TBB_atomic_flag flag; - -public: - //! Construct unacquired lock. - /** Equivalent to zero-initialization of *this. */ - spin_mutex() : flag(0) { -#if TBB_USE_THREADING_TOOLS - internal_construct(); -#endif - } - - //! Represents acquisition of a mutex. - class scoped_lock : internal::no_copy { - private: - //! Points to currently held mutex, or NULL if no lock is held. - spin_mutex* my_mutex; - - //! Value to store into spin_mutex::flag to unlock the mutex. - /** This variable is no longer used. Instead, 0 and 1 are used to - represent that the lock is free and acquired, respectively. - We keep the member variable here to ensure backward compatibility */ - __TBB_Flag my_unlock_value; - - //! Like acquire, but with ITT instrumentation. - void __TBB_EXPORTED_METHOD internal_acquire( spin_mutex& m ); - - //! Like try_acquire, but with ITT instrumentation. - bool __TBB_EXPORTED_METHOD internal_try_acquire( spin_mutex& m ); - - //! Like release, but with ITT instrumentation. - void __TBB_EXPORTED_METHOD internal_release(); - - friend class spin_mutex; - - public: - //! Construct without acquiring a mutex. - scoped_lock() : my_mutex(NULL), my_unlock_value(0) {} - - //! Construct and acquire lock on a mutex. - scoped_lock( spin_mutex& m ) : my_unlock_value(0) { - internal::suppress_unused_warning(my_unlock_value); -#if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT - my_mutex=NULL; - internal_acquire(m); -#else - my_mutex=&m; - __TBB_LockByte(m.flag); -#endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT*/ - } - - //! Acquire lock. - void acquire( spin_mutex& m ) { -#if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT - internal_acquire(m); -#else - my_mutex = &m; - __TBB_LockByte(m.flag); -#endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT*/ - } - - //! Try acquiring lock (non-blocking) - /** Return true if lock acquired; false otherwise. */ - bool try_acquire( spin_mutex& m ) { -#if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT - return internal_try_acquire(m); -#else - bool result = __TBB_TryLockByte(m.flag); - if( result ) - my_mutex = &m; - return result; -#endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT*/ - } - - //! Release lock - void release() { -#if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT - internal_release(); -#else - __TBB_UnlockByte(my_mutex->flag); - my_mutex = NULL; -#endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT */ - } - - //! Destroy lock. If holding a lock, releases the lock first. - ~scoped_lock() { - if( my_mutex ) { -#if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT - internal_release(); -#else - __TBB_UnlockByte(my_mutex->flag); -#endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT */ - } - } - }; - - //! Internal constructor with ITT instrumentation. - void __TBB_EXPORTED_METHOD internal_construct(); - - // Mutex traits - static const bool is_rw_mutex = false; - static const bool is_recursive_mutex = false; - static const bool is_fair_mutex = false; - - // ISO C++0x compatibility methods - - //! Acquire lock - void lock() { -#if TBB_USE_THREADING_TOOLS - aligned_space tmp; - new(tmp.begin()) scoped_lock(*this); -#else - __TBB_LockByte(flag); -#endif /* TBB_USE_THREADING_TOOLS*/ - } - - //! Try acquiring lock (non-blocking) - /** Return true if lock acquired; false otherwise. */ - bool try_lock() { -#if TBB_USE_THREADING_TOOLS - aligned_space tmp; - return (new(tmp.begin()) scoped_lock)->internal_try_acquire(*this); -#else - return __TBB_TryLockByte(flag); -#endif /* TBB_USE_THREADING_TOOLS*/ - } - - //! Release lock - void unlock() { -#if TBB_USE_THREADING_TOOLS - aligned_space tmp; - scoped_lock& s = *tmp.begin(); - s.my_mutex = this; - s.internal_release(); -#else - __TBB_UnlockByte(flag); -#endif /* TBB_USE_THREADING_TOOLS */ - } - - friend class scoped_lock; -}; // end of spin_mutex - -__TBB_DEFINE_PROFILING_SET_NAME(spin_mutex) - -} // namespace tbb - -#if ( __TBB_x86_32 || __TBB_x86_64 ) -#include "internal/_x86_eliding_mutex_impl.h" -#endif - -namespace tbb { -//! A cross-platform spin mutex with speculative lock acquisition. -/** On platforms with proper HW support, this lock may speculatively execute - its critical sections, using HW mechanisms to detect real data races and - ensure atomicity of the critical sections. In particular, it uses - Intel(R) Transactional Synchronization Extensions (Intel(R) TSX). - Without such HW support, it behaves like a spin_mutex. - It should be used for locking short critical sections where the lock is - contended but the data it protects are not. If zero-initialized, the - mutex is considered unheld. - @ingroup synchronization */ - -#if ( __TBB_x86_32 || __TBB_x86_64 ) -typedef interface7::internal::padded_mutex speculative_spin_mutex; -#else -typedef interface7::internal::padded_mutex speculative_spin_mutex; -#endif -__TBB_DEFINE_PROFILING_SET_NAME(speculative_spin_mutex) - -} // namespace tbb - -#endif /* __TBB_spin_mutex_H */ diff --git a/lib/3rdParty/tbb/include/tbb/spin_rw_mutex.h b/lib/3rdParty/tbb/include/tbb/spin_rw_mutex.h deleted file mode 100644 index b20f4ebd..00000000 --- a/lib/3rdParty/tbb/include/tbb/spin_rw_mutex.h +++ /dev/null @@ -1,259 +0,0 @@ -/* - 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_spin_rw_mutex_H -#define __TBB_spin_rw_mutex_H - -#include "tbb_stddef.h" -#include "tbb_machine.h" -#include "tbb_profiling.h" -#include "internal/_mutex_padding.h" - -namespace tbb { - -#if __TBB_TSX_AVAILABLE -namespace interface8 { namespace internal { - class x86_rtm_rw_mutex; -}} -#endif - -class spin_rw_mutex_v3; -typedef spin_rw_mutex_v3 spin_rw_mutex; - -//! Fast, unfair, spinning reader-writer lock with backoff and writer-preference -/** @ingroup synchronization */ -class spin_rw_mutex_v3 : internal::mutex_copy_deprecated_and_disabled { - //! @cond INTERNAL - - //! Internal acquire write lock. - bool __TBB_EXPORTED_METHOD internal_acquire_writer(); - - //! Out of line code for releasing a write lock. - /** This code has debug checking and instrumentation for Intel(R) Thread Checker and Intel(R) Thread Profiler. */ - void __TBB_EXPORTED_METHOD internal_release_writer(); - - //! Internal acquire read lock. - void __TBB_EXPORTED_METHOD internal_acquire_reader(); - - //! Internal upgrade reader to become a writer. - bool __TBB_EXPORTED_METHOD internal_upgrade(); - - //! Out of line code for downgrading a writer to a reader. - /** This code has debug checking and instrumentation for Intel(R) Thread Checker and Intel(R) Thread Profiler. */ - void __TBB_EXPORTED_METHOD internal_downgrade(); - - //! Internal release read lock. - void __TBB_EXPORTED_METHOD internal_release_reader(); - - //! Internal try_acquire write lock. - bool __TBB_EXPORTED_METHOD internal_try_acquire_writer(); - - //! Internal try_acquire read lock. - bool __TBB_EXPORTED_METHOD internal_try_acquire_reader(); - - //! @endcond -public: - //! Construct unacquired mutex. - spin_rw_mutex_v3() : state(0) { -#if TBB_USE_THREADING_TOOLS - internal_construct(); -#endif - } - -#if TBB_USE_ASSERT - //! Destructor asserts if the mutex is acquired, i.e. state is zero. - ~spin_rw_mutex_v3() { - __TBB_ASSERT( !state, "destruction of an acquired mutex"); - }; -#endif /* TBB_USE_ASSERT */ - - //! The scoped locking pattern - /** It helps to avoid the common problem of forgetting to release lock. - It also nicely provides the "node" for queuing locks. */ - class scoped_lock : internal::no_copy { -#if __TBB_TSX_AVAILABLE - friend class tbb::interface8::internal::x86_rtm_rw_mutex; - // helper methods for x86_rtm_rw_mutex - spin_rw_mutex *internal_get_mutex() const { return mutex; } - void internal_set_mutex(spin_rw_mutex* m) { mutex = m; } -#endif - public: - //! Construct lock that has not acquired a mutex. - /** Equivalent to zero-initialization of *this. */ - scoped_lock() : mutex(NULL), is_writer(false) {} - - //! Acquire lock on given mutex. - scoped_lock( spin_rw_mutex& m, bool write = true ) : mutex(NULL) { - acquire(m, write); - } - - //! Release lock (if lock is held). - ~scoped_lock() { - if( mutex ) release(); - } - - //! Acquire lock on given mutex. - void acquire( spin_rw_mutex& m, bool write = true ) { - __TBB_ASSERT( !mutex, "holding mutex already" ); - is_writer = write; - mutex = &m; - if( write ) mutex->internal_acquire_writer(); - else mutex->internal_acquire_reader(); - } - - //! Upgrade reader to become a writer. - /** Returns whether the upgrade happened without releasing and re-acquiring the lock */ - bool upgrade_to_writer() { - __TBB_ASSERT( mutex, "lock is not acquired" ); - __TBB_ASSERT( !is_writer, "not a reader" ); - is_writer = true; - return mutex->internal_upgrade(); - } - - //! Release lock. - void release() { - __TBB_ASSERT( mutex, "lock is not acquired" ); - spin_rw_mutex *m = mutex; - mutex = NULL; -#if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT - if( is_writer ) m->internal_release_writer(); - else m->internal_release_reader(); -#else - if( is_writer ) __TBB_AtomicAND( &m->state, READERS ); - else __TBB_FetchAndAddWrelease( &m->state, -(intptr_t)ONE_READER); -#endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT */ - } - - //! Downgrade writer to become a reader. - bool downgrade_to_reader() { - __TBB_ASSERT( mutex, "lock is not acquired" ); - __TBB_ASSERT( is_writer, "not a writer" ); -#if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT - mutex->internal_downgrade(); -#else - __TBB_FetchAndAddW( &mutex->state, ((intptr_t)ONE_READER-WRITER)); -#endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT */ - is_writer = false; - return true; - } - - //! Try acquire lock on given mutex. - bool try_acquire( spin_rw_mutex& m, bool write = true ) { - __TBB_ASSERT( !mutex, "holding mutex already" ); - bool result; - is_writer = write; - result = write? m.internal_try_acquire_writer() - : m.internal_try_acquire_reader(); - if( result ) - mutex = &m; - return result; - } - - protected: - - //! The pointer to the current mutex that is held, or NULL if no mutex is held. - spin_rw_mutex* mutex; - - //! If mutex!=NULL, then is_writer is true if holding a writer lock, false if holding a reader lock. - /** Not defined if not holding a lock. */ - bool is_writer; - }; - - // Mutex traits - static const bool is_rw_mutex = true; - static const bool is_recursive_mutex = false; - static const bool is_fair_mutex = false; - - // ISO C++0x compatibility methods - - //! Acquire writer lock - void lock() {internal_acquire_writer();} - - //! Try acquiring writer lock (non-blocking) - /** Return true if lock acquired; false otherwise. */ - bool try_lock() {return internal_try_acquire_writer();} - - //! Release lock - void unlock() { -#if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT - if( state&WRITER ) internal_release_writer(); - else internal_release_reader(); -#else - if( state&WRITER ) __TBB_AtomicAND( &state, READERS ); - else __TBB_FetchAndAddWrelease( &state, -(intptr_t)ONE_READER); -#endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT */ - } - - // Methods for reader locks that resemble ISO C++0x compatibility methods. - - //! Acquire reader lock - void lock_read() {internal_acquire_reader();} - - //! Try acquiring reader lock (non-blocking) - /** Return true if reader lock acquired; false otherwise. */ - bool try_lock_read() {return internal_try_acquire_reader();} - -protected: - typedef intptr_t state_t; - static const state_t WRITER = 1; - static const state_t WRITER_PENDING = 2; - static const state_t READERS = ~(WRITER | WRITER_PENDING); - static const state_t ONE_READER = 4; - static const state_t BUSY = WRITER | READERS; - //! State of lock - /** Bit 0 = writer is holding lock - Bit 1 = request by a writer to acquire lock (hint to readers to wait) - Bit 2..N = number of readers holding lock */ - state_t state; - -private: - void __TBB_EXPORTED_METHOD internal_construct(); -}; - -__TBB_DEFINE_PROFILING_SET_NAME(spin_rw_mutex) - -} // namespace tbb - -#if __TBB_TSX_AVAILABLE -#include "internal/_x86_rtm_rw_mutex_impl.h" -#endif - -namespace tbb { -namespace interface8 { -//! A cross-platform spin reader/writer mutex with speculative lock acquisition. -/** On platforms with proper HW support, this lock may speculatively execute - its critical sections, using HW mechanisms to detect real data races and - ensure atomicity of the critical sections. In particular, it uses - Intel(R) Transactional Synchronization Extensions (Intel(R) TSX). - Without such HW support, it behaves like a spin_rw_mutex. - It should be used for locking short critical sections where the lock is - contended but the data it protects are not. - @ingroup synchronization */ -#if __TBB_TSX_AVAILABLE -typedef interface7::internal::padded_mutex speculative_spin_rw_mutex; -#else -typedef interface7::internal::padded_mutex speculative_spin_rw_mutex; -#endif -} // namespace interface8 - -using interface8::speculative_spin_rw_mutex; -__TBB_DEFINE_PROFILING_SET_NAME(speculative_spin_rw_mutex) -} // namespace tbb -#endif /* __TBB_spin_rw_mutex_H */ diff --git a/lib/3rdParty/tbb/include/tbb/task.h b/lib/3rdParty/tbb/include/tbb/task.h deleted file mode 100644 index 246684ab..00000000 --- a/lib/3rdParty/tbb/include/tbb/task.h +++ /dev/null @@ -1,1050 +0,0 @@ -/* - 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_task_H -#define __TBB_task_H - -#include "tbb_stddef.h" -#include "tbb_machine.h" -#include "tbb_profiling.h" -#include - -typedef struct ___itt_caller *__itt_caller; - -namespace tbb { - -class task; -class task_list; -class task_group_context; - -// MSVC does not allow taking the address of a member that was defined -// privately in task_base and made public in class task via a using declaration. -#if _MSC_VER || (__GNUC__==3 && __GNUC_MINOR__<3) -#define __TBB_TASK_BASE_ACCESS public -#else -#define __TBB_TASK_BASE_ACCESS private -#endif - -namespace internal { //< @cond INTERNAL - - class allocate_additional_child_of_proxy: no_assign { - //! No longer used, but retained for binary layout compatibility. Always NULL. - task* self; - task& parent; - public: - explicit allocate_additional_child_of_proxy( task& parent_ ) : self(NULL), parent(parent_) {} - task& __TBB_EXPORTED_METHOD allocate( size_t size ) const; - void __TBB_EXPORTED_METHOD free( task& ) const; - }; - - struct cpu_ctl_env_space { int space[sizeof(internal::uint64_t)/sizeof(int)]; }; -} //< namespace internal @endcond - -namespace interface5 { - namespace internal { - //! Base class for methods that became static in TBB 3.0. - /** TBB's evolution caused the "this" argument for several methods to become obsolete. - However, for backwards binary compatibility, the new methods need distinct names, - otherwise the One Definition Rule would be broken. Hence the new methods are - defined in this private base class, and then exposed in class task via - using declarations. */ - class task_base: tbb::internal::no_copy { - __TBB_TASK_BASE_ACCESS: - friend class tbb::task; - - //! Schedule task for execution when a worker becomes available. - static void spawn( task& t ); - - //! Spawn multiple tasks and clear list. - static void spawn( task_list& list ); - - //! Like allocate_child, except that task's parent becomes "t", not this. - /** Typically used in conjunction with schedule_to_reexecute to implement while loops. - Atomically increments the reference count of t.parent() */ - static tbb::internal::allocate_additional_child_of_proxy allocate_additional_child_of( task& t ) { - return tbb::internal::allocate_additional_child_of_proxy(t); - } - - //! Destroy a task. - /** Usually, calling this method is unnecessary, because a task is - implicitly deleted after its execute() method runs. However, - sometimes a task needs to be explicitly deallocated, such as - when a root task is used as the parent in spawn_and_wait_for_all. */ - static void __TBB_EXPORTED_FUNC destroy( task& victim ); - }; - } // internal -} // interface5 - -//! @cond INTERNAL -namespace internal { - - class scheduler: no_copy { - public: - //! For internal use only - virtual void spawn( task& first, task*& next ) = 0; - - //! For internal use only - virtual void wait_for_all( task& parent, task* child ) = 0; - - //! For internal use only - virtual void spawn_root_and_wait( task& first, task*& next ) = 0; - - //! Pure virtual destructor; - // Have to have it just to shut up overzealous compilation warnings - virtual ~scheduler() = 0; - - //! For internal use only - virtual void enqueue( task& t, void* reserved ) = 0; - }; - - //! A reference count - /** Should always be non-negative. A signed type is used so that underflow can be detected. */ - typedef intptr_t reference_count; - - //! An id as used for specifying affinity. - typedef unsigned short affinity_id; - -#if __TBB_TASK_ISOLATION - //! A tag for task isolation. - typedef intptr_t isolation_tag; - const isolation_tag no_isolation = 0; -#endif /* __TBB_TASK_ISOLATION */ - -#if __TBB_TASK_GROUP_CONTEXT - class generic_scheduler; - - struct context_list_node_t { - context_list_node_t *my_prev, - *my_next; - }; - - class allocate_root_with_context_proxy: no_assign { - task_group_context& my_context; - public: - allocate_root_with_context_proxy ( task_group_context& ctx ) : my_context(ctx) {} - task& __TBB_EXPORTED_METHOD allocate( size_t size ) const; - void __TBB_EXPORTED_METHOD free( task& ) const; - }; -#endif /* __TBB_TASK_GROUP_CONTEXT */ - - class allocate_root_proxy: no_assign { - public: - static task& __TBB_EXPORTED_FUNC allocate( size_t size ); - static void __TBB_EXPORTED_FUNC free( task& ); - }; - - class allocate_continuation_proxy: no_assign { - public: - task& __TBB_EXPORTED_METHOD allocate( size_t size ) const; - void __TBB_EXPORTED_METHOD free( task& ) const; - }; - - class allocate_child_proxy: no_assign { - public: - task& __TBB_EXPORTED_METHOD allocate( size_t size ) const; - void __TBB_EXPORTED_METHOD free( task& ) const; - }; - - //! Memory prefix to a task object. - /** This class is internal to the library. - Do not reference it directly, except within the library itself. - Fields are ordered in way that preserves backwards compatibility and yields - good packing on typical 32-bit and 64-bit platforms. New fields should be - added at the beginning for backward compatibility with accesses to the task - prefix inlined into application code. - - In case task prefix size exceeds 32 or 64 bytes on IA32 and Intel64 - architectures correspondingly, consider dynamic setting of task_alignment - and task_prefix_reservation_size based on the maximal operand size supported - by the current CPU. - - @ingroup task_scheduling */ - class task_prefix { - private: - friend class tbb::task; - friend class tbb::interface5::internal::task_base; - friend class tbb::task_list; - friend class internal::scheduler; - friend class internal::allocate_root_proxy; - friend class internal::allocate_child_proxy; - friend class internal::allocate_continuation_proxy; - friend class internal::allocate_additional_child_of_proxy; - -#if __TBB_TASK_ISOLATION - //! The tag used for task isolation. - isolation_tag isolation; -#endif /* __TBB_TASK_ISOLATION */ - -#if __TBB_TASK_GROUP_CONTEXT - //! Shared context that is used to communicate asynchronous state changes - /** Currently it is used to broadcast cancellation requests generated both - by users and as the result of unhandled exceptions in the task::execute() - methods. */ - task_group_context *context; -#endif /* __TBB_TASK_GROUP_CONTEXT */ - - //! The scheduler that allocated the task, or NULL if the task is big. - /** Small tasks are pooled by the scheduler that allocated the task. - If a scheduler needs to free a small task allocated by another scheduler, - it returns the task to that other scheduler. This policy avoids - memory space blowup issues for memory allocators that allocate from - thread-specific pools. */ - scheduler* origin; - -#if __TBB_TASK_PRIORITY - union { -#endif /* __TBB_TASK_PRIORITY */ - //! Obsolete. The scheduler that owns the task. - /** Retained only for the sake of backward binary compatibility. - Still used by inline methods in the task.h header. **/ - scheduler* owner; - -#if __TBB_TASK_PRIORITY - //! Pointer to the next offloaded lower priority task. - /** Used to maintain a list of offloaded tasks inside the scheduler. **/ - task* next_offloaded; - }; -#endif /* __TBB_TASK_PRIORITY */ - - //! The task whose reference count includes me. - /** In the "blocking style" of programming, this field points to the parent task. - In the "continuation-passing style" of programming, this field points to the - continuation of the parent. */ - tbb::task* parent; - - //! Reference count used for synchronization. - /** In the "continuation-passing style" of programming, this field is - the difference of the number of allocated children minus the - number of children that have completed. - In the "blocking style" of programming, this field is one more than the difference. */ - __TBB_atomic reference_count ref_count; - - //! Obsolete. Used to be scheduling depth before TBB 2.2 - /** Retained only for the sake of backward binary compatibility. - Not used by TBB anymore. **/ - int depth; - - //! A task::state_type, stored as a byte for compactness. - /** This state is exposed to users via method task::state(). */ - unsigned char state; - - //! Miscellaneous state that is not directly visible to users, stored as a byte for compactness. - /** 0x0 -> version 1.0 task - 0x1 -> version >=2.1 task - 0x10 -> task was enqueued - 0x20 -> task_proxy - 0x40 -> task has live ref_count - 0x80 -> a stolen task */ - unsigned char extra_state; - - affinity_id affinity; - - //! "next" field for list of task - tbb::task* next; - - //! The task corresponding to this task_prefix. - tbb::task& task() {return *reinterpret_cast(this+1);} - }; - -} // namespace internal -//! @endcond - -#if __TBB_TASK_GROUP_CONTEXT - -#if __TBB_TASK_PRIORITY -namespace internal { - static const int priority_stride_v4 = INT_MAX / 4; -} - -enum priority_t { - priority_normal = internal::priority_stride_v4 * 2, - priority_low = priority_normal - internal::priority_stride_v4, - priority_high = priority_normal + internal::priority_stride_v4 -}; - -#endif /* __TBB_TASK_PRIORITY */ - -#if TBB_USE_CAPTURED_EXCEPTION - class tbb_exception; -#else - namespace internal { - class tbb_exception_ptr; - } -#endif /* !TBB_USE_CAPTURED_EXCEPTION */ - -class task_scheduler_init; -namespace interface7 { class task_arena; } - -//! Used to form groups of tasks -/** @ingroup task_scheduling - The context services explicit cancellation requests from user code, and unhandled - exceptions intercepted during tasks execution. Intercepting an exception results - in generating internal cancellation requests (which is processed in exactly the - same way as external ones). - - The context is associated with one or more root tasks and defines the cancellation - group that includes all the descendants of the corresponding root task(s). Association - is established when a context object is passed as an argument to the task::allocate_root() - method. See task_group_context::task_group_context for more details. - - The context can be bound to another one, and other contexts can be bound to it, - forming a tree-like structure: parent -> this -> children. Arrows here designate - cancellation propagation direction. If a task in a cancellation group is cancelled - all the other tasks in this group and groups bound to it (as children) get cancelled too. - - IMPLEMENTATION NOTE: - When adding new members to task_group_context or changing types of existing ones, - update the size of both padding buffers (_leading_padding and _trailing_padding) - appropriately. See also VERSIONING NOTE at the constructor definition below. **/ -class task_group_context : internal::no_copy { -private: - friend class internal::generic_scheduler; - friend class task_scheduler_init; - friend class interface7::task_arena; - -#if TBB_USE_CAPTURED_EXCEPTION - typedef tbb_exception exception_container_type; -#else - typedef internal::tbb_exception_ptr exception_container_type; -#endif - - enum version_traits_word_layout { - traits_offset = 16, - version_mask = 0xFFFF, - traits_mask = 0xFFFFul << traits_offset - }; - -public: - enum kind_type { - isolated, - bound - }; - - enum traits_type { - exact_exception = 0x0001ul << traits_offset, -#if __TBB_FP_CONTEXT - fp_settings = 0x0002ul << traits_offset, -#endif - concurrent_wait = 0x0004ul << traits_offset, -#if TBB_USE_CAPTURED_EXCEPTION - default_traits = 0 -#else - default_traits = exact_exception -#endif /* !TBB_USE_CAPTURED_EXCEPTION */ - }; - -private: - enum state { - may_have_children = 1, - // the following enumerations must be the last, new 2^x values must go above - next_state_value, low_unused_state_bit = (next_state_value-1)*2 - }; - - union { - //! Flavor of this context: bound or isolated. - // TODO: describe asynchronous use, and whether any memory semantics are needed - __TBB_atomic kind_type my_kind; - uintptr_t _my_kind_aligner; - }; - - //! Pointer to the context of the parent cancellation group. NULL for isolated contexts. - task_group_context *my_parent; - - //! Used to form the thread specific list of contexts without additional memory allocation. - /** A context is included into the list of the current thread when its binding to - its parent happens. Any context can be present in the list of one thread only. **/ - internal::context_list_node_t my_node; - - //! Used to set and maintain stack stitching point for Intel Performance Tools. - __itt_caller itt_caller; - - //! Leading padding protecting accesses to frequently used members from false sharing. - /** Read accesses to the field my_cancellation_requested are on the hot path inside - the scheduler. This padding ensures that this field never shares the same cache - line with a local variable that is frequently written to. **/ - char _leading_padding[internal::NFS_MaxLineSize - - 2 * sizeof(uintptr_t)- sizeof(void*) - sizeof(internal::context_list_node_t) - - sizeof(__itt_caller) -#if __TBB_FP_CONTEXT - - sizeof(internal::cpu_ctl_env_space) -#endif - ]; - -#if __TBB_FP_CONTEXT - //! Space for platform-specific FPU settings. - /** Must only be accessed inside TBB binaries, and never directly in user - code or inline methods. */ - internal::cpu_ctl_env_space my_cpu_ctl_env; -#endif - - //! Specifies whether cancellation was requested for this task group. - uintptr_t my_cancellation_requested; - - //! Version for run-time checks and behavioral traits of the context. - /** Version occupies low 16 bits, and traits (zero or more ORed enumerators - from the traits_type enumerations) take the next 16 bits. - Original (zeroth) version of the context did not support any traits. **/ - uintptr_t my_version_and_traits; - - //! Pointer to the container storing exception being propagated across this task group. - exception_container_type *my_exception; - - //! Scheduler instance that registered this context in its thread specific list. - internal::generic_scheduler *my_owner; - - //! Internal state (combination of state flags, currently only may_have_children). - uintptr_t my_state; - -#if __TBB_TASK_PRIORITY - //! Priority level of the task group (in normalized representation) - intptr_t my_priority; -#endif /* __TBB_TASK_PRIORITY */ - - //! Trailing padding protecting accesses to frequently used members from false sharing - /** \sa _leading_padding **/ - char _trailing_padding[internal::NFS_MaxLineSize - 2 * sizeof(uintptr_t) - 2 * sizeof(void*) -#if __TBB_TASK_PRIORITY - - sizeof(intptr_t) -#endif /* __TBB_TASK_PRIORITY */ - ]; - -public: - //! Default & binding constructor. - /** By default a bound context is created. That is this context will be bound - (as child) to the context of the task calling task::allocate_root(this_context) - method. Cancellation requests passed to the parent context are propagated - to all the contexts bound to it. Similarly priority change is propagated - from the parent context to its children. - - If task_group_context::isolated is used as the argument, then the tasks associated - with this context will never be affected by events in any other context. - - Creating isolated contexts involve much less overhead, but they have limited - utility. Normally when an exception occurs in an algorithm that has nested - ones running, it is desirably to have all the nested algorithms cancelled - as well. Such a behavior requires nested algorithms to use bound contexts. - - There is one good place where using isolated algorithms is beneficial. It is - a master thread. That is if a particular algorithm is invoked directly from - the master thread (not from a TBB task), supplying it with explicitly - created isolated context will result in a faster algorithm startup. - - VERSIONING NOTE: - Implementation(s) of task_group_context constructor(s) cannot be made - entirely out-of-line because the run-time version must be set by the user - code. This will become critically important for binary compatibility, if - we ever have to change the size of the context object. - - Boosting the runtime version will also be necessary if new data fields are - introduced in the currently unused padding areas and these fields are updated - by inline methods. **/ - task_group_context ( kind_type relation_with_parent = bound, - uintptr_t t = default_traits ) - : my_kind(relation_with_parent) - , my_version_and_traits(2 | t) - { - init(); - } - - // Do not introduce standalone unbind method since it will break state propagation assumptions - __TBB_EXPORTED_METHOD ~task_group_context (); - - //! Forcefully reinitializes the context after the task tree it was associated with is completed. - /** Because the method assumes that all the tasks that used to be associated with - this context have already finished, calling it while the context is still - in use somewhere in the task hierarchy leads to undefined behavior. - - IMPORTANT: This method is not thread safe! - - The method does not change the context's parent if it is set. **/ - void __TBB_EXPORTED_METHOD reset (); - - //! Initiates cancellation of all tasks in this cancellation group and its subordinate groups. - /** \return false if cancellation has already been requested, true otherwise. - - Note that canceling never fails. When false is returned, it just means that - another thread (or this one) has already sent cancellation request to this - context or to one of its ancestors (if this context is bound). It is guaranteed - that when this method is concurrently called on the same not yet cancelled - context, true will be returned by one and only one invocation. **/ - bool __TBB_EXPORTED_METHOD cancel_group_execution (); - - //! Returns true if the context received cancellation request. - bool __TBB_EXPORTED_METHOD is_group_execution_cancelled () const; - - //! Records the pending exception, and cancels the task group. - /** May be called only from inside a catch-block. If the context is already - cancelled, does nothing. - The method brings the task group associated with this context exactly into - the state it would be in, if one of its tasks threw the currently pending - exception during its execution. In other words, it emulates the actions - of the scheduler's dispatch loop exception handler. **/ - void __TBB_EXPORTED_METHOD register_pending_exception (); - -#if __TBB_FP_CONTEXT - //! Captures the current FPU control settings to the context. - /** Because the method assumes that all the tasks that used to be associated with - this context have already finished, calling it while the context is still - in use somewhere in the task hierarchy leads to undefined behavior. - - IMPORTANT: This method is not thread safe! - - The method does not change the FPU control settings of the context's parent. **/ - void __TBB_EXPORTED_METHOD capture_fp_settings (); -#endif - -#if __TBB_TASK_PRIORITY - //! Changes priority of the task group - void set_priority ( priority_t ); - - //! Retrieves current priority of the current task group - priority_t priority () const; -#endif /* __TBB_TASK_PRIORITY */ - - //! Returns the context's trait - uintptr_t traits() const { return my_version_and_traits & traits_mask; } - -protected: - //! Out-of-line part of the constructor. - /** Singled out to ensure backward binary compatibility of the future versions. **/ - void __TBB_EXPORTED_METHOD init (); - -private: - friend class task; - friend class internal::allocate_root_with_context_proxy; - - static const kind_type binding_required = bound; - static const kind_type binding_completed = kind_type(bound+1); - static const kind_type detached = kind_type(binding_completed+1); - static const kind_type dying = kind_type(detached+1); - - //! Propagates any state change detected to *this, and as an optimisation possibly also upward along the heritage line. - template - void propagate_task_group_state ( T task_group_context::*mptr_state, task_group_context& src, T new_state ); - - //! Registers this context with the local scheduler and binds it to its parent context - void bind_to ( internal::generic_scheduler *local_sched ); - - //! Registers this context with the local scheduler - void register_with ( internal::generic_scheduler *local_sched ); - -#if __TBB_FP_CONTEXT - //! Copies FPU control setting from another context - // TODO: Consider adding #else stub in order to omit #if sections in other code - void copy_fp_settings( const task_group_context &src ); -#endif /* __TBB_FP_CONTEXT */ -}; // class task_group_context - -#endif /* __TBB_TASK_GROUP_CONTEXT */ - -//! Base class for user-defined tasks. -/** @ingroup task_scheduling */ -class task: __TBB_TASK_BASE_ACCESS interface5::internal::task_base { - - //! Set reference count - void __TBB_EXPORTED_METHOD internal_set_ref_count( int count ); - - //! Decrement reference count and return its new value. - internal::reference_count __TBB_EXPORTED_METHOD internal_decrement_ref_count(); - -protected: - //! Default constructor. - task() {prefix().extra_state=1;} - -public: - //! Destructor. - virtual ~task() {} - - //! Should be overridden by derived classes. - virtual task* execute() = 0; - - //! Enumeration of task states that the scheduler considers. - enum state_type { - //! task is running, and will be destroyed after method execute() completes. - executing, - //! task to be rescheduled. - reexecute, - //! task is in ready pool, or is going to be put there, or was just taken off. - ready, - //! task object is freshly allocated or recycled. - allocated, - //! task object is on free list, or is going to be put there, or was just taken off. - freed, - //! task to be recycled as continuation - recycle -#if __TBB_RECYCLE_TO_ENQUEUE - //! task to be scheduled for starvation-resistant execution - ,to_enqueue -#endif - }; - - //------------------------------------------------------------------------ - // Allocating tasks - //------------------------------------------------------------------------ - - //! Returns proxy for overloaded new that allocates a root task. - static internal::allocate_root_proxy allocate_root() { - return internal::allocate_root_proxy(); - } - -#if __TBB_TASK_GROUP_CONTEXT - //! Returns proxy for overloaded new that allocates a root task associated with user supplied context. - static internal::allocate_root_with_context_proxy allocate_root( task_group_context& ctx ) { - return internal::allocate_root_with_context_proxy(ctx); - } -#endif /* __TBB_TASK_GROUP_CONTEXT */ - - //! Returns proxy for overloaded new that allocates a continuation task of *this. - /** The continuation's parent becomes the parent of *this. */ - internal::allocate_continuation_proxy& allocate_continuation() { - return *reinterpret_cast(this); - } - - //! Returns proxy for overloaded new that allocates a child task of *this. - internal::allocate_child_proxy& allocate_child() { - return *reinterpret_cast(this); - } - - //! Define recommended static form via import from base class. - using task_base::allocate_additional_child_of; - -#if __TBB_DEPRECATED_TASK_INTERFACE - //! Destroy a task. - /** Usually, calling this method is unnecessary, because a task is - implicitly deleted after its execute() method runs. However, - sometimes a task needs to be explicitly deallocated, such as - when a root task is used as the parent in spawn_and_wait_for_all. */ - void __TBB_EXPORTED_METHOD destroy( task& t ); -#else /* !__TBB_DEPRECATED_TASK_INTERFACE */ - //! Define recommended static form via import from base class. - using task_base::destroy; -#endif /* !__TBB_DEPRECATED_TASK_INTERFACE */ - - //------------------------------------------------------------------------ - // Recycling of tasks - //------------------------------------------------------------------------ - - //! Change this to be a continuation of its former self. - /** The caller must guarantee that the task's refcount does not become zero until - after the method execute() returns. Typically, this is done by having - method execute() return a pointer to a child of the task. If the guarantee - cannot be made, use method recycle_as_safe_continuation instead. - - Because of the hazard, this method may be deprecated in the future. */ - void recycle_as_continuation() { - __TBB_ASSERT( prefix().state==executing, "execute not running?" ); - prefix().state = allocated; - } - - //! Recommended to use, safe variant of recycle_as_continuation - /** For safety, it requires additional increment of ref_count. - With no descendants and ref_count of 1, it has the semantics of recycle_to_reexecute. */ - void recycle_as_safe_continuation() { - __TBB_ASSERT( prefix().state==executing, "execute not running?" ); - prefix().state = recycle; - } - - //! Change this to be a child of new_parent. - void recycle_as_child_of( task& new_parent ) { - internal::task_prefix& p = prefix(); - __TBB_ASSERT( prefix().state==executing||prefix().state==allocated, "execute not running, or already recycled" ); - __TBB_ASSERT( prefix().ref_count==0, "no child tasks allowed when recycled as a child" ); - __TBB_ASSERT( p.parent==NULL, "parent must be null" ); - __TBB_ASSERT( new_parent.prefix().state<=recycle, "corrupt parent's state" ); - __TBB_ASSERT( new_parent.prefix().state!=freed, "parent already freed" ); - p.state = allocated; - p.parent = &new_parent; -#if __TBB_TASK_GROUP_CONTEXT - p.context = new_parent.prefix().context; -#endif /* __TBB_TASK_GROUP_CONTEXT */ - } - - //! Schedule this for reexecution after current execute() returns. - /** Made obsolete by recycle_as_safe_continuation; may become deprecated. */ - void recycle_to_reexecute() { - __TBB_ASSERT( prefix().state==executing, "execute not running, or already recycled" ); - __TBB_ASSERT( prefix().ref_count==0, "no child tasks allowed when recycled for reexecution" ); - prefix().state = reexecute; - } - -#if __TBB_RECYCLE_TO_ENQUEUE - //! Schedule this to enqueue after descendant tasks complete. - /** Save enqueue/spawn difference, it has the semantics of recycle_as_safe_continuation. */ - void recycle_to_enqueue() { - __TBB_ASSERT( prefix().state==executing, "execute not running, or already recycled" ); - prefix().state = to_enqueue; - } -#endif /* __TBB_RECYCLE_TO_ENQUEUE */ - - //------------------------------------------------------------------------ - // Spawning and blocking - //------------------------------------------------------------------------ - - //! Set reference count - void set_ref_count( int count ) { -#if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT - internal_set_ref_count(count); -#else - prefix().ref_count = count; -#endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT */ - } - - //! Atomically increment reference count. - /** Has acquire semantics */ - void increment_ref_count() { - __TBB_FetchAndIncrementWacquire( &prefix().ref_count ); - } - - //! Atomically adds to reference count and returns its new value. - /** Has release-acquire semantics */ - int add_ref_count( int count ) { - internal::call_itt_notify( internal::releasing, &prefix().ref_count ); - internal::reference_count k = count+__TBB_FetchAndAddW( &prefix().ref_count, count ); - __TBB_ASSERT( k>=0, "task's reference count underflowed" ); - if( k==0 ) - internal::call_itt_notify( internal::acquired, &prefix().ref_count ); - return int(k); - } - - //! Atomically decrement reference count and returns its new value. - /** Has release semantics. */ - int decrement_ref_count() { -#if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT - return int(internal_decrement_ref_count()); -#else - return int(__TBB_FetchAndDecrementWrelease( &prefix().ref_count ))-1; -#endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT */ - } - - //! Define recommended static forms via import from base class. - using task_base::spawn; - - //! Similar to spawn followed by wait_for_all, but more efficient. - void spawn_and_wait_for_all( task& child ) { - prefix().owner->wait_for_all( *this, &child ); - } - - //! Similar to spawn followed by wait_for_all, but more efficient. - void __TBB_EXPORTED_METHOD spawn_and_wait_for_all( task_list& list ); - - //! Spawn task allocated by allocate_root, wait for it to complete, and deallocate it. - static void spawn_root_and_wait( task& root ) { - root.prefix().owner->spawn_root_and_wait( root, root.prefix().next ); - } - - //! Spawn root tasks on list and wait for all of them to finish. - /** If there are more tasks than worker threads, the tasks are spawned in - order of front to back. */ - static void spawn_root_and_wait( task_list& root_list ); - - //! Wait for reference count to become one, and set reference count to zero. - /** Works on tasks while waiting. */ - void wait_for_all() { - prefix().owner->wait_for_all( *this, NULL ); - } - - //! Enqueue task for starvation-resistant execution. -#if __TBB_TASK_PRIORITY - /** The task will be enqueued on the normal priority level disregarding the - priority of its task group. - - The rationale of such semantics is that priority of an enqueued task is - statically fixed at the moment of its enqueuing, while task group priority - is dynamic. Thus automatic priority inheritance would be generally a subject - to the race, which may result in unexpected behavior. - - Use enqueue() overload with explicit priority value and task::group_priority() - method to implement such priority inheritance when it is really necessary. **/ -#endif /* __TBB_TASK_PRIORITY */ - static void enqueue( task& t ) { - t.prefix().owner->enqueue( t, NULL ); - } - -#if __TBB_TASK_PRIORITY - //! Enqueue task for starvation-resistant execution on the specified priority level. - static void enqueue( task& t, priority_t p ) { - __TBB_ASSERT( p == priority_low || p == priority_normal || p == priority_high, "Invalid priority level value" ); - t.prefix().owner->enqueue( t, (void*)p ); - } -#endif /* __TBB_TASK_PRIORITY */ - - //! The innermost task being executed or destroyed by the current thread at the moment. - static task& __TBB_EXPORTED_FUNC self(); - - //! task on whose behalf this task is working, or NULL if this is a root. - task* parent() const {return prefix().parent;} - - //! sets parent task pointer to specified value - void set_parent(task* p) { -#if __TBB_TASK_GROUP_CONTEXT - __TBB_ASSERT(!p || prefix().context == p->prefix().context, "The tasks must be in the same context"); -#endif - prefix().parent = p; - } - -#if __TBB_TASK_GROUP_CONTEXT - //! This method is deprecated and will be removed in the future. - /** Use method group() instead. **/ - task_group_context* context() {return prefix().context;} - - //! Pointer to the task group descriptor. - task_group_context* group () { return prefix().context; } -#endif /* __TBB_TASK_GROUP_CONTEXT */ - - //! True if task was stolen from the task pool of another thread. - bool is_stolen_task() const { - return (prefix().extra_state & 0x80)!=0; - } - - //------------------------------------------------------------------------ - // Debugging - //------------------------------------------------------------------------ - - //! Current execution state - state_type state() const {return state_type(prefix().state);} - - //! The internal reference count. - int ref_count() const { -#if TBB_USE_ASSERT - internal::reference_count ref_count_ = prefix().ref_count; - __TBB_ASSERT( ref_count_==int(ref_count_), "integer overflow error"); -#endif - return int(prefix().ref_count); - } - - //! Obsolete, and only retained for the sake of backward compatibility. Always returns true. - bool __TBB_EXPORTED_METHOD is_owned_by_current_thread() const; - - //------------------------------------------------------------------------ - // Affinity - //------------------------------------------------------------------------ - - //! An id as used for specifying affinity. - /** Guaranteed to be integral type. Value of 0 means no affinity. */ - typedef internal::affinity_id affinity_id; - - //! Set affinity for this task. - void set_affinity( affinity_id id ) {prefix().affinity = id;} - - //! Current affinity of this task - affinity_id affinity() const {return prefix().affinity;} - - //! Invoked by scheduler to notify task that it ran on unexpected thread. - /** Invoked before method execute() runs, if task is stolen, or task has - affinity but will be executed on another thread. - - The default action does nothing. */ - virtual void __TBB_EXPORTED_METHOD note_affinity( affinity_id id ); - -#if __TBB_TASK_GROUP_CONTEXT - //! Moves this task from its current group into another one. - /** Argument ctx specifies the new group. - - The primary purpose of this method is to associate unique task group context - with a task allocated for subsequent enqueuing. In contrast to spawned tasks - enqueued ones normally outlive the scope where they were created. This makes - traditional usage model where task group context are allocated locally on - the stack inapplicable. Dynamic allocation of context objects is performance - inefficient. Method change_group() allows to make task group context object - a member of the task class, and then associate it with its containing task - object in the latter's constructor. **/ - void __TBB_EXPORTED_METHOD change_group ( task_group_context& ctx ); - - //! Initiates cancellation of all tasks in this cancellation group and its subordinate groups. - /** \return false if cancellation has already been requested, true otherwise. **/ - bool cancel_group_execution () { return prefix().context->cancel_group_execution(); } - - //! Returns true if the context has received cancellation request. - bool is_cancelled () const { return prefix().context->is_group_execution_cancelled(); } -#else - bool is_cancelled () const { return false; } -#endif /* __TBB_TASK_GROUP_CONTEXT */ - -#if __TBB_TASK_PRIORITY - //! Changes priority of the task group this task belongs to. - void set_group_priority ( priority_t p ) { prefix().context->set_priority(p); } - - //! Retrieves current priority of the task group this task belongs to. - priority_t group_priority () const { return prefix().context->priority(); } - -#endif /* __TBB_TASK_PRIORITY */ - -private: - friend class interface5::internal::task_base; - friend class task_list; - friend class internal::scheduler; - friend class internal::allocate_root_proxy; -#if __TBB_TASK_GROUP_CONTEXT - friend class internal::allocate_root_with_context_proxy; -#endif /* __TBB_TASK_GROUP_CONTEXT */ - friend class internal::allocate_continuation_proxy; - friend class internal::allocate_child_proxy; - friend class internal::allocate_additional_child_of_proxy; - - //! Get reference to corresponding task_prefix. - /** Version tag prevents loader on Linux from using the wrong symbol in debug builds. **/ - internal::task_prefix& prefix( internal::version_tag* = NULL ) const { - return reinterpret_cast(const_cast(this))[-1]; - } -}; // class task - -//! task that does nothing. Useful for synchronization. -/** @ingroup task_scheduling */ -class empty_task: public task { - task* execute() __TBB_override { - return NULL; - } -}; - -//! @cond INTERNAL -namespace internal { - template - class function_task : public task { -#if __TBB_ALLOW_MUTABLE_FUNCTORS - F my_func; -#else - const F my_func; -#endif - task* execute() __TBB_override { - my_func(); - return NULL; - } - public: - function_task( const F& f ) : my_func(f) {} - }; -} // namespace internal -//! @endcond - -//! A list of children. -/** Used for method task::spawn_children - @ingroup task_scheduling */ -class task_list: internal::no_copy { -private: - task* first; - task** next_ptr; - friend class task; - friend class interface5::internal::task_base; -public: - //! Construct empty list - task_list() : first(NULL), next_ptr(&first) {} - - //! Destroys the list, but does not destroy the task objects. - ~task_list() {} - - //! True if list if empty; false otherwise. - bool empty() const {return !first;} - - //! Push task onto back of list. - void push_back( task& task ) { - task.prefix().next = NULL; - *next_ptr = &task; - next_ptr = &task.prefix().next; - } -#if __TBB_TODO - // TODO: add this method and implement&document the local execution ordering. See more in generic_scheduler::local_spawn - //! Push task onto front of list (FIFO local execution, like individual spawning in the same order). - void push_front( task& task ) { - if( empty() ) { - push_back(task); - } else { - task.prefix().next = first; - first = &task; - } - } -#endif - //! Pop the front task from the list. - task& pop_front() { - __TBB_ASSERT( !empty(), "attempt to pop item from empty task_list" ); - task* result = first; - first = result->prefix().next; - if( !first ) next_ptr = &first; - return *result; - } - - //! Clear the list - void clear() { - first=NULL; - next_ptr=&first; - } -}; - -inline void interface5::internal::task_base::spawn( task& t ) { - t.prefix().owner->spawn( t, t.prefix().next ); -} - -inline void interface5::internal::task_base::spawn( task_list& list ) { - if( task* t = list.first ) { - t->prefix().owner->spawn( *t, *list.next_ptr ); - list.clear(); - } -} - -inline void task::spawn_root_and_wait( task_list& root_list ) { - if( task* t = root_list.first ) { - t->prefix().owner->spawn_root_and_wait( *t, *root_list.next_ptr ); - root_list.clear(); - } -} - -} // namespace tbb - -inline void *operator new( size_t bytes, const tbb::internal::allocate_root_proxy& ) { - return &tbb::internal::allocate_root_proxy::allocate(bytes); -} - -inline void operator delete( void* task, const tbb::internal::allocate_root_proxy& ) { - tbb::internal::allocate_root_proxy::free( *static_cast(task) ); -} - -#if __TBB_TASK_GROUP_CONTEXT -inline void *operator new( size_t bytes, const tbb::internal::allocate_root_with_context_proxy& p ) { - return &p.allocate(bytes); -} - -inline void operator delete( void* task, const tbb::internal::allocate_root_with_context_proxy& p ) { - p.free( *static_cast(task) ); -} -#endif /* __TBB_TASK_GROUP_CONTEXT */ - -inline void *operator new( size_t bytes, const tbb::internal::allocate_continuation_proxy& p ) { - return &p.allocate(bytes); -} - -inline void operator delete( void* task, const tbb::internal::allocate_continuation_proxy& p ) { - p.free( *static_cast(task) ); -} - -inline void *operator new( size_t bytes, const tbb::internal::allocate_child_proxy& p ) { - return &p.allocate(bytes); -} - -inline void operator delete( void* task, const tbb::internal::allocate_child_proxy& p ) { - p.free( *static_cast(task) ); -} - -inline void *operator new( size_t bytes, const tbb::internal::allocate_additional_child_of_proxy& p ) { - return &p.allocate(bytes); -} - -inline void operator delete( void* task, const tbb::internal::allocate_additional_child_of_proxy& p ) { - p.free( *static_cast(task) ); -} - -#endif /* __TBB_task_H */ diff --git a/lib/3rdParty/tbb/include/tbb/task_arena.h b/lib/3rdParty/tbb/include/tbb/task_arena.h deleted file mode 100644 index f33135b6..00000000 --- a/lib/3rdParty/tbb/include/tbb/task_arena.h +++ /dev/null @@ -1,333 +0,0 @@ -/* - 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_task_arena_H -#define __TBB_task_arena_H - -#include "task.h" -#include "tbb_exception.h" -#if TBB_USE_THREADING_TOOLS -#include "atomic.h" // for as_atomic -#endif - -namespace tbb { - -namespace this_task_arena { - int max_concurrency(); -} // namespace this_task_arena - -//! @cond INTERNAL -namespace internal { - //! Internal to library. Should not be used by clients. - /** @ingroup task_scheduling */ - class arena; - class task_scheduler_observer_v3; -} // namespace internal -//! @endcond - -namespace interface7 { -class task_arena; - -//! @cond INTERNAL -namespace internal { -using namespace tbb::internal; //e.g. function_task from task.h - -class delegate_base : no_assign { -public: - virtual void operator()() const = 0; - virtual ~delegate_base() {} -}; - -template -class delegated_function : public delegate_base { - F &my_func; - void operator()() const __TBB_override { - my_func(); - } -public: - delegated_function ( F& f ) : my_func(f) {} -}; - -class task_arena_base { -protected: - //! NULL if not currently initialized. - internal::arena* my_arena; - -#if __TBB_TASK_GROUP_CONTEXT - //! default context of the arena - task_group_context *my_context; -#endif - - //! Concurrency level for deferred initialization - int my_max_concurrency; - - //! Reserved master slots - unsigned my_master_slots; - - //! Special settings - intptr_t my_version_and_traits; - - enum { - default_flags = 0 -#if __TBB_TASK_GROUP_CONTEXT - | (task_group_context::default_traits & task_group_context::exact_exception) // 0 or 1 << 16 - , exact_exception_flag = task_group_context::exact_exception // used to specify flag for context directly -#endif - }; - - task_arena_base(int max_concurrency, unsigned reserved_for_masters) - : my_arena(0) -#if __TBB_TASK_GROUP_CONTEXT - , my_context(0) -#endif - , my_max_concurrency(max_concurrency) - , my_master_slots(reserved_for_masters) - , my_version_and_traits(default_flags) - {} - - void __TBB_EXPORTED_METHOD internal_initialize(); - void __TBB_EXPORTED_METHOD internal_terminate(); - void __TBB_EXPORTED_METHOD internal_attach(); - void __TBB_EXPORTED_METHOD internal_enqueue( task&, intptr_t ) const; - 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; - 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 - -/** 1-to-1 proxy representation class of scheduler's arena - * Constructors set up settings only, real construction is deferred till the first method invocation - * Destructor only removes one of the references to the inner arena representation. - * Final destruction happens when all the references (and the work) are gone. - */ -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" ); -#if __TBB_TASK_GROUP_CONTEXT - __TBB_ASSERT( my_context, "task_arena initialization is incomplete" ); -#endif -#if TBB_USE_THREADING_TOOLS - // Actual synchronization happens in internal_initialize & internal_attach. - // The race on setting my_initialized is benign, but should be hidden from Intel(R) Inspector - internal::as_atomic(my_initialized).fetch_and_store(true); -#else - my_initialized = true; -#endif - } - -public: - //! Creates task_arena with certain concurrency limits - /** Sets up settings only, real construction is deferred till the first method invocation - * @arg max_concurrency specifies total number of slots in arena where threads work - * @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) - , my_initialized(false) - {} - - //! Copies settings from another task_arena - task_arena(const task_arena &s) // copy settings but not the reference or instance - : task_arena_base(s.my_max_concurrency, s.my_master_slots) - , my_initialized(false) - {} - - //! Tag class used to indicate the "attaching" constructor - struct attach {}; - - //! Creates an instance of task_arena attached to the current arena of the thread - explicit task_arena( attach ) - : task_arena_base(automatic, 1) // use default settings if attach fails - , my_initialized(false) - { - internal_attach(); - if( my_arena ) my_initialized = true; - } - - //! Forces allocation of the resources for the task_arena as specified in constructor arguments - inline void initialize() { - if( !my_initialized ) { - internal_initialize(); - mark_initialized(); - } - } - - //! Overrides concurrency level and forces initialization of internal representation - 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_master_slots = reserved_for_masters; - initialize(); - } - } - - //! Attaches this instance to the current arena of the thread - inline void initialize(attach) { - // 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 ) { - internal_attach(); - if( !my_arena ) internal_initialize(); - mark_initialized(); - } - } - - //! Removes the reference to the internal arena representation. - //! Not thread safe wrt concurrent invocations of other methods. - inline void terminate() { - if( my_initialized ) { - internal_terminate(); - my_initialized = false; - } - } - - //! Removes the reference to the internal arena representation, and destroys the external object. - //! Not thread safe wrt concurrent invocations of other methods. - ~task_arena() { - terminate(); - } - - //! Returns true if the arena is active (initialized); false otherwise. - //! The name was chosen to match a task_scheduler_init method with the same semantics. - bool is_active() const { return my_initialized; } - - //! Enqueues a task into the arena to process a functor, and immediately returns. - //! Does not require the calling thread to join the arena - template - void enqueue( const F& f ) { - initialize(); -#if __TBB_TASK_GROUP_CONTEXT - internal_enqueue( *new( task::allocate_root(*my_context) ) internal::function_task(f), 0 ); -#else - internal_enqueue( *new( task::allocate_root() ) internal::function_task(f), 0 ); -#endif - } - -#if __TBB_TASK_PRIORITY - //! Enqueues a task with priority p into the arena to process a functor f, and immediately returns. - //! Does not require the calling thread to join the arena - template - void enqueue( const F& f, priority_t p ) { - __TBB_ASSERT( p == priority_low || p == priority_normal || p == priority_high, "Invalid priority level value" ); - initialize(); -#if __TBB_TASK_GROUP_CONTEXT - internal_enqueue( *new( task::allocate_root(*my_context) ) internal::function_task(f), (intptr_t)p ); -#else - internal_enqueue( *new( task::allocate_root() ) internal::function_task(f), (intptr_t)p ); -#endif - } -#endif// __TBB_TASK_PRIORITY - - //! Joins the arena and executes a functor, then returns - //! If not possible to join, wraps the functor into a task, enqueues it and waits for task completion - //! Can decrement the arena demand for workers, causing a worker to leave and free a slot to the calling thread - template - void execute(F& f) { - initialize(); - internal::delegated_function d(f); - internal_execute( d ); - } - - //! Joins the arena and executes a functor, then returns - //! If not possible to join, wraps the functor into a task, enqueues it and waits for task completion - //! Can decrement the arena demand for workers, causing a worker to leave and free a slot to the calling thread - template - void execute(const F& f) { - initialize(); - internal::delegated_function d(f); - internal_execute( d ); - } - -#if __TBB_EXTRA_DEBUG - //! Wait for all work in the arena to be completed - //! Even submitted by other application threads - //! Joins arena if/when possible (in the same way as execute()) - void debug_wait_until_empty() { - initialize(); - internal_wait(); - } -#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_H */ diff --git a/lib/3rdParty/tbb/include/tbb/task_group.h b/lib/3rdParty/tbb/include/tbb/task_group.h deleted file mode 100644 index bf6922b9..00000000 --- a/lib/3rdParty/tbb/include/tbb/task_group.h +++ /dev/null @@ -1,223 +0,0 @@ -/* - 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_task_group_H -#define __TBB_task_group_H - -#include "task.h" -#include "tbb_exception.h" - -#if __TBB_TASK_GROUP_CONTEXT - -namespace tbb { - -namespace internal { - template class task_handle_task; -} - -class task_group; -class structured_task_group; - -template -class task_handle : internal::no_assign { - template friend class internal::task_handle_task; - friend class task_group; - friend class structured_task_group; - - static const intptr_t scheduled = 0x1; - - F my_func; - intptr_t my_state; - - void mark_scheduled () { - // The check here is intentionally lax to avoid the impact of interlocked operation - if ( my_state & scheduled ) - internal::throw_exception( internal::eid_invalid_multiple_scheduling ); - my_state |= scheduled; - } -public: - task_handle( const F& f ) : my_func(f), my_state(0) {} - - void operator() () const { my_func(); } -}; - -enum task_group_status { - not_complete, - complete, - canceled -}; - -namespace internal { - -template -class task_handle_task : public task { - task_handle& my_handle; - task* execute() __TBB_override { - my_handle(); - return NULL; - } -public: - task_handle_task( task_handle& h ) : my_handle(h) { h.mark_scheduled(); } -}; - -class task_group_base : internal::no_copy { -protected: - empty_task* my_root; - task_group_context my_context; - - task& owner () { return *my_root; } - - template - task_group_status internal_run_and_wait( F& f ) { - __TBB_TRY { - if ( !my_context.is_group_execution_cancelled() ) - f(); - } __TBB_CATCH( ... ) { - my_context.register_pending_exception(); - } - return wait(); - } - - template - void internal_run( F& f ) { - owner().spawn( *new( owner().allocate_additional_child_of(*my_root) ) Task(f) ); - } - -public: - task_group_base( uintptr_t traits = 0 ) - : my_context(task_group_context::bound, task_group_context::default_traits | traits) - { - my_root = new( task::allocate_root(my_context) ) empty_task; - my_root->set_ref_count(1); - } - - ~task_group_base() __TBB_NOEXCEPT(false) { - if( my_root->ref_count() > 1 ) { - bool stack_unwinding_in_progress = std::uncaught_exception(); - // Always attempt to do proper cleanup to avoid inevitable memory corruption - // in case of missing wait (for the sake of better testability & debuggability) - if ( !is_canceling() ) - cancel(); - __TBB_TRY { - my_root->wait_for_all(); - } __TBB_CATCH (...) { - task::destroy(*my_root); - __TBB_RETHROW(); - } - task::destroy(*my_root); - if ( !stack_unwinding_in_progress ) - internal::throw_exception( internal::eid_missing_wait ); - } - else { - task::destroy(*my_root); - } - } - - template - void run( task_handle& h ) { - internal_run< task_handle, internal::task_handle_task >( h ); - } - - task_group_status wait() { - __TBB_TRY { - my_root->wait_for_all(); - } __TBB_CATCH( ... ) { - my_context.reset(); - __TBB_RETHROW(); - } - if ( my_context.is_group_execution_cancelled() ) { - // TODO: the reset method is not thread-safe. Ensure the correct behavior. - my_context.reset(); - return canceled; - } - return complete; - } - - bool is_canceling() { - return my_context.is_group_execution_cancelled(); - } - - void cancel() { - my_context.cancel_group_execution(); - } -}; // class task_group_base - -} // namespace internal - -class task_group : public internal::task_group_base { -public: - task_group () : task_group_base( task_group_context::concurrent_wait ) {} - -#if __SUNPRO_CC - template - void run( task_handle& h ) { - internal_run< task_handle, internal::task_handle_task >( h ); - } -#else - using task_group_base::run; -#endif - - template - void run( const F& f ) { - internal_run< const F, internal::function_task >( f ); - } - - template - task_group_status run_and_wait( const F& f ) { - return internal_run_and_wait( f ); - } - - template - task_group_status run_and_wait( task_handle& h ) { - h.mark_scheduled(); - return internal_run_and_wait< task_handle >( h ); - } -}; // class task_group - -class structured_task_group : public internal::task_group_base { -public: - template - task_group_status run_and_wait ( task_handle& h ) { - h.mark_scheduled(); - return internal_run_and_wait< task_handle >( h ); - } - - task_group_status wait() { - task_group_status res = task_group_base::wait(); - my_root->set_ref_count(1); - return res; - } -}; // class structured_task_group - -inline -bool is_current_task_group_canceling() { - return task::self().is_cancelled(); -} - -template -task_handle make_task( const F& f ) { - return task_handle( f ); -} - -} // namespace tbb - -#endif /* __TBB_TASK_GROUP_CONTEXT */ - -#endif /* __TBB_task_group_H */ diff --git a/lib/3rdParty/tbb/include/tbb/task_scheduler_init.h b/lib/3rdParty/tbb/include/tbb/task_scheduler_init.h deleted file mode 100644 index 928e7a4e..00000000 --- a/lib/3rdParty/tbb/include/tbb/task_scheduler_init.h +++ /dev/null @@ -1,161 +0,0 @@ -/* - 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_task_scheduler_init_H -#define __TBB_task_scheduler_init_H - -#include "tbb_stddef.h" -#include "limits.h" -#if __TBB_SUPPORTS_WORKERS_WAITING_IN_TERMINATE -#include // nothrow_t -#endif - -namespace tbb { - -typedef std::size_t stack_size_type; - -//! @cond INTERNAL -namespace internal { - //! Internal to library. Should not be used by clients. - /** @ingroup task_scheduling */ - class scheduler; -} // namespace internal -//! @endcond - -//! Class delimiting the scope of task scheduler activity. -/** A thread can construct a task_scheduler_init object and keep it alive - while it uses TBB's tasking subsystem (including parallel algorithms). - - This class allows to customize properties of the TBB task pool to some extent. - For example it can limit concurrency level of parallel work initiated by the - given thread. It also can be used to specify stack size of the TBB worker threads, - though this setting is not effective if the thread pool has already been created. - - If a parallel construct is used without task_scheduler_init object previously - created, the scheduler will be initialized automatically with default settings, - and will persist until this thread exits. Default concurrency level is defined - as described in task_scheduler_init::initialize(). - @ingroup task_scheduling */ -class task_scheduler_init: internal::no_copy { - enum ExceptionPropagationMode { - propagation_mode_exact = 1u, - propagation_mode_captured = 2u, - propagation_mode_mask = propagation_mode_exact | propagation_mode_captured - }; - - /** 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. - static const int automatic = -1; - - //! Argument to initialize() or constructor that causes initialization to be deferred. - static const int deferred = -2; - - //! Ensure that scheduler exists for this thread - /** A value of -1 lets TBB decide on the number of threads, which is usually - maximal hardware concurrency for this process, that is the number of logical - CPUs on the machine (possibly limited by the processor affinity mask of this - process (Windows) or of this thread (Linux, FreeBSD). It is preferable option - for production code because it helps to avoid nasty surprises when several - TBB based components run side-by-side or in a nested fashion inside the same - process. - - The number_of_threads is ignored if any other task_scheduler_inits - currently exist. A thread may construct multiple task_scheduler_inits. - Doing so does no harm because the underlying scheduler is reference counted. */ - void __TBB_EXPORTED_METHOD initialize( int number_of_threads=automatic ); - - //! The overloaded method with stack size parameter - /** Overloading is necessary to preserve ABI compatibility */ - void __TBB_EXPORTED_METHOD initialize( int number_of_threads, stack_size_type thread_stack_size ); - - //! Inverse of method initialize. - void __TBB_EXPORTED_METHOD terminate(); - -#if __TBB_SUPPORTS_WORKERS_WAITING_IN_TERMINATE -#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 - // client manually creates tasks in the master thread and does not use - // explicit task group context object. This is necessary because newer - // TBB binaries with exact propagation enabled by default may be used - // by older clients that expect tbb::captured_exception wrapper. - // All zeros mean old client - no preference. - __TBB_ASSERT( !(thread_stack_size & propagation_mode_mask), "Requested stack size is not aligned" ); -#if TBB_USE_EXCEPTIONS - thread_stack_size |= TBB_USE_CAPTURED_EXCEPTION ? propagation_mode_captured : propagation_mode_exact; -#endif /* TBB_USE_EXCEPTIONS */ - initialize( number_of_threads, thread_stack_size ); - } - - //! Destroy scheduler for this thread if thread has no other live task_scheduler_inits. - ~task_scheduler_init() { - if( my_scheduler ) - terminate(); - internal::poison_pointer( my_scheduler ); - } - //! Returns the number of threads TBB scheduler would create if initialized by default. - /** Result returned by this method does not depend on whether the scheduler - has already been initialized. - - Because tbb 2.0 does not support blocking tasks yet, you may use this method - to boost the number of threads in the tbb's internal pool, if your tasks are - doing I/O operations. The optimal number of additional threads depends on how - much time your tasks spend in the blocked state. - - Before TBB 3.0 U4 this method returned the number of logical CPU in the - system. Currently on Windows, Linux and FreeBSD it returns the number of - logical CPUs available to the current process in accordance with its affinity - mask. - - NOTE: The return value of this method never changes after its first invocation. - This means that changes in the process affinity mask that took place after - this method was first invoked will not affect the number of worker threads - in the TBB worker threads pool. */ - static int __TBB_EXPORTED_FUNC default_num_threads (); - - //! Returns true if scheduler is active (initialized); false otherwise - bool is_active() const { return my_scheduler != NULL; } -}; - -} // namespace tbb - -#endif /* __TBB_task_scheduler_init_H */ diff --git a/lib/3rdParty/tbb/include/tbb/task_scheduler_observer.h b/lib/3rdParty/tbb/include/tbb/task_scheduler_observer.h deleted file mode 100644 index 5586ad4f..00000000 --- a/lib/3rdParty/tbb/include/tbb/task_scheduler_observer.h +++ /dev/null @@ -1,174 +0,0 @@ -/* - 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_task_scheduler_observer_H -#define __TBB_task_scheduler_observer_H - -#include "atomic.h" -#if __TBB_ARENA_OBSERVER || __TBB_SLEEP_PERMISSION -#include "task_arena.h" -#endif - -#if __TBB_SCHEDULER_OBSERVER - -namespace tbb { -namespace interface6 { -class task_scheduler_observer; -} -namespace internal { - -class observer_proxy; -class observer_list; - -class task_scheduler_observer_v3 { - friend class observer_proxy; - friend class observer_list; - friend class interface6::task_scheduler_observer; - - //! Pointer to the proxy holding this observer. - /** Observers are proxied by the scheduler to maintain persistent lists of them. **/ - observer_proxy* my_proxy; - - //! Counter preventing the observer from being destroyed while in use by the scheduler. - /** Valid only when observation is on. **/ - atomic my_busy_count; - -public: - //! Enable or disable observation - /** For local observers the method can be used only when the current thread - has the task scheduler initialized or is attached to an arena. - - Repeated calls with the same state are no-ops. **/ - void __TBB_EXPORTED_METHOD observe( bool state=true ); - - //! Returns true if observation is enabled, false otherwise. - bool is_observing() const {return my_proxy!=NULL;} - - //! Construct observer with observation disabled. - task_scheduler_observer_v3() : my_proxy(NULL) { my_busy_count.store(0); } - - //! Entry notification - /** Invoked from inside observe(true) call and whenever a worker enters the arena - this observer is associated with. 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. - - Obsolete semantics. For global observers it is called by a thread before - the first steal since observation became enabled. **/ - virtual void on_scheduler_entry( bool /*is_worker*/ ) {} - - //! Exit notification - /** Invoked from inside observe(false) call and whenever a worker leaves the - arena this observer is associated with. - - Obsolete semantics. For global observers it is called by a thread before - the first steal since observation became enabled. **/ - virtual void on_scheduler_exit( bool /*is_worker*/ ) {} - - //! Destructor automatically switches observation off if it is enabled. - virtual ~task_scheduler_observer_v3() { if(my_proxy) observe(false);} -}; - -} // namespace internal - -#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; - friend class internal::observer_proxy; - friend class internal::observer_list; - - /** Negative numbers with the largest absolute value to minimize probability - of coincidence in case of a bug in busy count usage. **/ - // TODO: take more high bits for version number - static const intptr_t v6_trait = (intptr_t)((~(uintptr_t)0 >> 1) + 1); - - //! contains task_arena pointer or tag indicating local or global semantics of the observer - intptr_t my_context_tag; - enum { global_tag = 0, implicit_tag = 1 }; - -public: - //! Construct local or global observer in inactive state (observation disabled). - /** For a local observer entry/exit notifications are invoked whenever a worker - thread joins/leaves the arena of the observer's owner thread. 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. **/ - /** TODO: Obsolete. - Global observer semantics is obsolete as it violates master thread isolation - 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. **/ - 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_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. **/ - explicit task_scheduler_observer( task_arena & a) { - my_context_tag = (intptr_t)&a; - } -#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, - otherwise it can lead to concurrent notification callback on partly destroyed object **/ - virtual ~task_scheduler_observer() { if(my_proxy) observe(false); } - - //! Enable or disable observation - /** Warning: concurrent invocations of this method are not safe. - Repeated calls with the same state are no-ops. **/ - void observe( bool state=true ) { - if( state && !my_proxy ) { - __TBB_ASSERT( !my_busy_count, "Inconsistent state of task_scheduler_observer instance"); - my_busy_count.store(v6_trait); - } - internal::task_scheduler_observer_v3::observe(state); - } - -#if __TBB_SLEEP_PERMISSION - //! Return commands for may_sleep() - enum { keep_awake = false, allow_sleep = true }; - - //! The callback can be invoked by a worker thread before it goes to sleep. - /** 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 || __TBB_SLEEP_PERMISSION*/ -typedef tbb::internal::task_scheduler_observer_v3 task_scheduler_observer; -#endif /*__TBB_ARENA_OBSERVER || __TBB_SLEEP_PERMISSION*/ - -} // namespace tbb - -#endif /* __TBB_SCHEDULER_OBSERVER */ - -#endif /* __TBB_task_scheduler_observer_H */ diff --git a/lib/3rdParty/tbb/include/tbb/tbb.h b/lib/3rdParty/tbb/include/tbb/tbb.h deleted file mode 100644 index 5e385ea2..00000000 --- a/lib/3rdParty/tbb/include/tbb/tbb.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - 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_tbb_H -#define __TBB_tbb_H - -/** - This header bulk-includes declarations or definitions of all the functionality - provided by TBB (save for malloc dependent headers). - - If you use only a few TBB constructs, consider including specific headers only. - Any header listed below can be included independently of others. -**/ - -#if TBB_PREVIEW_AGGREGATOR -#include "aggregator.h" -#endif -#include "aligned_space.h" -#include "atomic.h" -#include "blocked_range.h" -#include "blocked_range2d.h" -#include "blocked_range3d.h" -#include "cache_aligned_allocator.h" -#include "combinable.h" -#include "concurrent_hash_map.h" -#if TBB_PREVIEW_CONCURRENT_LRU_CACHE -#include "concurrent_lru_cache.h" -#endif -#include "concurrent_priority_queue.h" -#include "concurrent_queue.h" -#include "concurrent_unordered_map.h" -#include "concurrent_unordered_set.h" -#include "concurrent_vector.h" -#include "critical_section.h" -#include "enumerable_thread_specific.h" -#include "flow_graph.h" -#if TBB_PREVIEW_GLOBAL_CONTROL -#include "global_control.h" -#endif -#include "mutex.h" -#include "null_mutex.h" -#include "null_rw_mutex.h" -#include "parallel_do.h" -#include "parallel_for.h" -#include "parallel_for_each.h" -#include "parallel_invoke.h" -#include "parallel_reduce.h" -#include "parallel_scan.h" -#include "parallel_sort.h" -#include "partitioner.h" -#include "pipeline.h" -#include "queuing_mutex.h" -#include "queuing_rw_mutex.h" -#include "reader_writer_lock.h" -#include "recursive_mutex.h" -#include "spin_mutex.h" -#include "spin_rw_mutex.h" -#include "task.h" -#include "task_arena.h" -#include "task_group.h" -#include "task_scheduler_init.h" -#include "task_scheduler_observer.h" -#include "tbb_allocator.h" -#include "tbb_exception.h" -#include "tbb_thread.h" -#include "tick_count.h" - -#endif /* __TBB_tbb_H */ diff --git a/lib/3rdParty/tbb/include/tbb/tbb_allocator.h b/lib/3rdParty/tbb/include/tbb/tbb_allocator.h deleted file mode 100644 index 6346d866..00000000 --- a/lib/3rdParty/tbb/include/tbb/tbb_allocator.h +++ /dev/null @@ -1,218 +0,0 @@ -/* - 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_tbb_allocator_H -#define __TBB_tbb_allocator_H - -#include "tbb_stddef.h" -#include -#if __TBB_ALLOCATOR_CONSTRUCT_VARIADIC - #include // std::forward -#endif - -#if !TBB_USE_EXCEPTIONS && _MSC_VER - // Suppress "C++ exception handler used, but unwind semantics are not enabled" warning in STL headers - #pragma warning (push) - #pragma warning (disable: 4530) -#endif - -#include - -#if !TBB_USE_EXCEPTIONS && _MSC_VER - #pragma warning (pop) -#endif - -namespace tbb { - -//! @cond INTERNAL -namespace internal { - - //! Deallocates memory using FreeHandler - /** The function uses scalable_free if scalable allocator is available and free if not*/ - void __TBB_EXPORTED_FUNC deallocate_via_handler_v3( void *p ); - - //! Allocates memory using MallocHandler - /** The function uses scalable_malloc if scalable allocator is available and malloc if not*/ - void* __TBB_EXPORTED_FUNC allocate_via_handler_v3( size_t n ); - - //! Returns true if standard malloc/free are used to work with memory. - bool __TBB_EXPORTED_FUNC is_malloc_used_v3(); -} -//! @endcond - -#if _MSC_VER && !defined(__INTEL_COMPILER) - // Workaround for erroneous "unreferenced parameter" warning in method destroy. - #pragma warning (push) - #pragma warning (disable: 4100) -#endif - -//! Meets "allocator" requirements of ISO C++ Standard, Section 20.1.5 -/** The class selects the best memory allocation mechanism available - from scalable_malloc and standard malloc. - The members are ordered the same way they are in section 20.4.1 - of the ISO C++ standard. - @ingroup memory_allocation */ -template -class tbb_allocator { -public: - typedef typename internal::allocator_type::value_type value_type; - typedef value_type* pointer; - typedef const value_type* const_pointer; - typedef value_type& reference; - typedef const value_type& const_reference; - typedef size_t size_type; - typedef ptrdiff_t difference_type; - template struct rebind { - typedef tbb_allocator other; - }; - - //! Specifies current allocator - enum malloc_type { - scalable, - standard - }; - - tbb_allocator() throw() {} - tbb_allocator( const tbb_allocator& ) throw() {} - template tbb_allocator(const tbb_allocator&) throw() {} - - pointer address(reference x) const {return &x;} - const_pointer address(const_reference x) const {return &x;} - - //! Allocate space for n objects. - pointer allocate( size_type n, const void* /*hint*/ = 0) { - return pointer(internal::allocate_via_handler_v3( n * sizeof(value_type) )); - } - - //! Free previously allocated block of memory. - void deallocate( pointer p, size_type ) { - internal::deallocate_via_handler_v3(p); - } - - //! Largest value for which method allocate might succeed. - size_type max_size() const throw() { - size_type max = static_cast(-1) / sizeof (value_type); - return (max > 0 ? max : 1); - } - - //! Copy-construct value at location pointed to by p. -#if __TBB_ALLOCATOR_CONSTRUCT_VARIADIC - template - void construct(U *p, Args&&... args) - { ::new((void *)p) U(std::forward(args)...); } -#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 - - //! Destroy value at location pointed to by p. - void destroy( pointer p ) {p->~value_type();} - - //! Returns current allocator - static malloc_type allocator_type() { - return internal::is_malloc_used_v3() ? standard : scalable; - } -}; - -#if _MSC_VER && !defined(__INTEL_COMPILER) - #pragma warning (pop) -#endif // warning 4100 is back - -//! Analogous to std::allocator, as defined in ISO C++ Standard, Section 20.4.1 -/** @ingroup memory_allocation */ -template<> -class tbb_allocator { -public: - typedef void* pointer; - typedef const void* const_pointer; - typedef void value_type; - template struct rebind { - typedef tbb_allocator other; - }; -}; - -template -inline bool operator==( const tbb_allocator&, const tbb_allocator& ) {return true;} - -template -inline bool operator!=( const tbb_allocator&, const tbb_allocator& ) {return false;} - -//! Meets "allocator" requirements of ISO C++ Standard, Section 20.1.5 -/** The class is an adapter over an actual allocator that fills the allocation - using memset function with template argument C as the value. - The members are ordered the same way they are in section 20.4.1 - of the ISO C++ standard. - @ingroup memory_allocation */ -template class Allocator = tbb_allocator> -class zero_allocator : public Allocator -{ -public: - typedef Allocator base_allocator_type; - typedef typename base_allocator_type::value_type value_type; - typedef typename base_allocator_type::pointer pointer; - typedef typename base_allocator_type::const_pointer const_pointer; - typedef typename base_allocator_type::reference reference; - typedef typename base_allocator_type::const_reference const_reference; - typedef typename base_allocator_type::size_type size_type; - typedef typename base_allocator_type::difference_type difference_type; - template struct rebind { - typedef zero_allocator other; - }; - - zero_allocator() throw() { } - zero_allocator(const zero_allocator &a) throw() : base_allocator_type( a ) { } - template - zero_allocator(const zero_allocator &a) throw() : base_allocator_type( Allocator( a ) ) { } - - pointer allocate(const size_type n, const void *hint = 0 ) { - pointer ptr = base_allocator_type::allocate( n, hint ); - std::memset( ptr, 0, n * sizeof(value_type) ); - return ptr; - } -}; - -//! Analogous to std::allocator, as defined in ISO C++ Standard, Section 20.4.1 -/** @ingroup memory_allocation */ -template class Allocator> -class zero_allocator : public Allocator { -public: - typedef Allocator base_allocator_type; - typedef typename base_allocator_type::value_type value_type; - typedef typename base_allocator_type::pointer pointer; - typedef typename base_allocator_type::const_pointer const_pointer; - template struct rebind { - typedef zero_allocator other; - }; -}; - -template class B1, typename T2, template class B2> -inline bool operator==( const zero_allocator &a, const zero_allocator &b) { - return static_cast< B1 >(a) == static_cast< B2 >(b); -} -template class B1, typename T2, template class B2> -inline bool operator!=( const zero_allocator &a, const zero_allocator &b) { - return static_cast< B1 >(a) != static_cast< B2 >(b); -} - -} // namespace tbb - -#endif /* __TBB_tbb_allocator_H */ diff --git a/lib/3rdParty/tbb/include/tbb/tbb_config.h b/lib/3rdParty/tbb/include/tbb/tbb_config.h deleted file mode 100644 index 25f9f24d..00000000 --- a/lib/3rdParty/tbb/include/tbb/tbb_config.h +++ /dev/null @@ -1,779 +0,0 @@ -/* - 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_tbb_config_H -#define __TBB_tbb_config_H - -/** This header is supposed to contain macro definitions and C style comments only. - The macros defined here are intended to control such aspects of TBB build as - - presence of compiler features - - compilation modes - - feature sets - - known compiler/platform issues -**/ - -/* This macro marks incomplete code or comments describing ideas which are considered for the future. - * See also for plain comment with TODO and FIXME marks for small improvement opportunities. - */ -#define __TBB_TODO 0 - -/*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__ || __ANDROID__) - #include -#endif - -// 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__) -#endif - -/** Target OS is either iOS* or iOS* simulator **/ -#if __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ - #define __TBB_IOS 1 -#endif - -/** Preprocessor symbols to determine HW architecture **/ - -#if _WIN32||_WIN64 -# if defined(_M_X64)||defined(__x86_64__) // the latter for MinGW support -# define __TBB_x86_64 1 -# elif defined(_M_IA64) -# define __TBB_ipf 1 -# elif defined(_M_IX86)||defined(__i386__) // the latter for MinGW support -# define __TBB_x86_32 1 -# else -# define __TBB_generic_arch 1 -# endif -#else /* Assume generic Unix */ -# if !__linux__ && !__APPLE__ -# define __TBB_generic_os 1 -# endif -# if __TBB_IOS -# define __TBB_generic_arch 1 -# elif __x86_64__ -# define __TBB_x86_64 1 -# elif __ia64__ -# define __TBB_ipf 1 -# elif __i386__||__i386 // __i386 is for Sun OS -# define __TBB_x86_32 1 -# else -# define __TBB_generic_arch 1 -# endif -#endif - -#if __MIC__ || __MIC2__ -#define __TBB_DEFINE_MIC 1 -#endif - -#define __TBB_TSX_AVAILABLE ((__TBB_x86_32 || __TBB_x86_64) && !__TBB_DEFINE_MIC) - -/** Presence of compiler features **/ - -#if __INTEL_COMPILER == 9999 && __INTEL_COMPILER_BUILD_DATE == 20110811 -/* Intel(R) Composer XE 2011 Update 6 incorrectly sets __INTEL_COMPILER. Fix it. */ - #undef __INTEL_COMPILER - #define __INTEL_COMPILER 1210 -#endif - -#if __TBB_GCC_VERSION >= 40400 && !defined(__INTEL_COMPILER) - /** warning suppression pragmas available in GCC since 4.4 **/ - #define __TBB_GCC_WARNING_SUPPRESSION_PRESENT 1 -#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 - set __GXX_EXPERIMENTAL_CXX0X__ in c++11 mode. - - Compilers that mimics other compilers (ICC, clang) must be processed before - compilers they mimic (GCC, MSVC). - - TODO: The following conditions should be extended when new compilers/runtimes - support added. - */ - -/** 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 ((_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) ) - /** 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 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__ - #else - #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_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 - #endif - #else - #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) - /** 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_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 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__) && (_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 || __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 - #endif - #if (__has_feature(__cxx_generalized_initializers__) && __has_include()) - #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__)) - /**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 || __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_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) - /** 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_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 - // 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_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_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 -#if __INTEL_COMPILER && __GNUC__ && __TBB_EXCEPTION_PTR_PRESENT && !defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) - #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1 -#endif - -// Work around a bug in MinGW32 -#if __MINGW32__ && __TBB_EXCEPTION_PTR_PRESENT && !defined(_GLIBCXX_ATOMIC_BUILTINS_4) - #define _GLIBCXX_ATOMIC_BUILTINS_4 -#endif - -#if __GNUC__ || __SUNPRO_CC || __IBMCPP__ - /* ICC defines __GNUC__ and so is covered */ - #define __TBB_ATTRIBUTE_ALIGNED_PRESENT 1 -#elif _MSC_VER && (_MSC_VER >= 1300 || __INTEL_COMPILER) - #define __TBB_DECLSPEC_ALIGN_PRESENT 1 -#endif - -/* Actually ICC supports gcc __sync_* intrinsics starting 11.1, - * but 64 bit support for 32 bit target comes in later ones*/ -/* TODO: change the version back to 4.1.2 once macro __TBB_WORD_SIZE become optional */ -/* Assumed that all clang versions have these gcc compatible intrinsics. */ -#if __TBB_GCC_VERSION >= 40306 || __INTEL_COMPILER >= 1200 || __clang__ - /** built-in atomics available in GCC since 4.1.2 **/ - #define __TBB_GCC_BUILTIN_ATOMICS_PRESENT 1 -#endif - -#if __INTEL_COMPILER >= 1200 - /** built-in C++11 style atomics available in ICC since 12.0 **/ - #define __TBB_ICC_BUILTIN_ATOMICS_PRESENT 1 -#endif - -#define __TBB_TSX_INTRINSICS_PRESENT ((__RTM__ || _MSC_VER>=1700 || __INTEL_COMPILER>=1300) && !__TBB_DEFINE_MIC && !__ANDROID__) - -/** 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 -#endif /* TBB_USE_DEBUG */ - -#ifndef TBB_USE_ASSERT -#define TBB_USE_ASSERT TBB_USE_DEBUG -#endif /* TBB_USE_ASSERT */ - -#ifndef TBB_USE_THREADING_TOOLS -#define TBB_USE_THREADING_TOOLS TBB_USE_DEBUG -#endif /* TBB_USE_THREADING_TOOLS */ - -#ifndef TBB_USE_PERFORMANCE_WARNINGS -#ifdef TBB_PERFORMANCE_WARNINGS -#define TBB_USE_PERFORMANCE_WARNINGS TBB_PERFORMANCE_WARNINGS -#else -#define TBB_USE_PERFORMANCE_WARNINGS TBB_USE_DEBUG -#endif /* TBB_PEFORMANCE_WARNINGS */ -#endif /* TBB_USE_PERFORMANCE_WARNINGS */ - -#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) - #define TBB_USE_EXCEPTIONS 0 - #endif -#elif !(__EXCEPTIONS || defined(_CPPUNWIND) || __SUNPRO_CC) - #if TBB_USE_EXCEPTIONS - #error Compilation settings do not support exception handling. Please do not set TBB_USE_EXCEPTIONS macro or set it to 0. - #elif !defined(TBB_USE_EXCEPTIONS) - #define TBB_USE_EXCEPTIONS 0 - #endif -#elif !defined(TBB_USE_EXCEPTIONS) - #define TBB_USE_EXCEPTIONS 1 -#endif - -#if __clang__ && !__INTEL_COMPILER -#define __TBB_USE_OPTIONAL_RTTI __has_feature(cxx_rtti) -#elif defined(_CPPRTTI) -#define __TBB_USE_OPTIONAL_RTTI 1 -#else -#define __TBB_USE_OPTIONAL_RTTI (__GXX_RTTI || __RTTI || __INTEL_RTTI__) -#endif - -#ifndef TBB_IMPLEMENT_CPP0X -/** By default, use C++11 classes if available **/ - #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 (__cplusplus < 201103L || !_LIBCPP_VERSION) - #else - #define TBB_IMPLEMENT_CPP0X (__cplusplus < 201103L || (!__has_include() && !__has_include())) - #endif - #elif __GNUC__ - #define TBB_IMPLEMENT_CPP0X (__TBB_GCC_VERSION < 40400 || !__GXX_EXPERIMENTAL_CXX0X__) - #elif _MSC_VER - #define TBB_IMPLEMENT_CPP0X (_MSC_VER < 1700) - #else - // TODO: Reconsider general approach to be more reliable, e.g. (!(__cplusplus >= 201103L && __ STDC_HOSTED__)) - #define TBB_IMPLEMENT_CPP0X (!__STDCPP_THREADS__) - #endif -#endif /* TBB_IMPLEMENT_CPP0X */ - -/* TBB_USE_CAPTURED_EXCEPTION should be explicitly set to either 0 or 1, as it is used as C++ const */ -#ifndef TBB_USE_CAPTURED_EXCEPTION - /** IA-64 architecture pre-built TBB binaries do not support exception_ptr. **/ - #if __TBB_EXCEPTION_PTR_PRESENT && !defined(__ia64__) - #define TBB_USE_CAPTURED_EXCEPTION 0 - #else - #define TBB_USE_CAPTURED_EXCEPTION 1 - #endif -#else /* defined TBB_USE_CAPTURED_EXCEPTION */ - #if !TBB_USE_CAPTURED_EXCEPTION && !__TBB_EXCEPTION_PTR_PRESENT - #error Current runtime does not support std::exception_ptr. Set TBB_USE_CAPTURED_EXCEPTION and make sure that your code is ready to catch tbb::captured_exception. - #endif -#endif /* defined TBB_USE_CAPTURED_EXCEPTION */ - -/** Check whether the request to use GCC atomics can be satisfied **/ -#if TBB_USE_GCC_BUILTINS && !__TBB_GCC_BUILTIN_ATOMICS_PRESENT - #error "GCC atomic built-ins are not supported." -#endif - -/** Internal TBB features & modes **/ - -/** __TBB_WEAK_SYMBOLS_PRESENT denotes that the system supports the weak symbol mechanism **/ -#ifndef __TBB_WEAK_SYMBOLS_PRESENT -#define __TBB_WEAK_SYMBOLS_PRESENT ( !_WIN32 && !__APPLE__ && !__sun && (__TBB_GCC_VERSION >= 40000 || __INTEL_COMPILER ) ) -#endif - -/** __TBB_DYNAMIC_LOAD_ENABLED describes the system possibility to load shared libraries at run time **/ -#ifndef __TBB_DYNAMIC_LOAD_ENABLED - #define __TBB_DYNAMIC_LOAD_ENABLED 1 -#endif - -/** __TBB_SOURCE_DIRECTLY_INCLUDED is a mode used in whitebox testing when - it's necessary to test internal functions not exported from TBB DLLs -**/ -#if (_WIN32||_WIN64) && (__TBB_SOURCE_DIRECTLY_INCLUDED || TBB_USE_PREVIEW_BINARY) - #define __TBB_NO_IMPLICIT_LINKAGE 1 - #define __TBBMALLOC_NO_IMPLICIT_LINKAGE 1 -#endif - -#ifndef __TBB_COUNT_TASK_NODES - #define __TBB_COUNT_TASK_NODES TBB_USE_ASSERT -#endif - -#ifndef __TBB_TASK_GROUP_CONTEXT - #define __TBB_TASK_GROUP_CONTEXT 1 -#endif /* __TBB_TASK_GROUP_CONTEXT */ - -#ifndef __TBB_SCHEDULER_OBSERVER - #define __TBB_SCHEDULER_OBSERVER 1 -#endif /* __TBB_SCHEDULER_OBSERVER */ - -#ifndef __TBB_FP_CONTEXT - #define __TBB_FP_CONTEXT __TBB_TASK_GROUP_CONTEXT -#endif /* __TBB_FP_CONTEXT */ - -#if __TBB_FP_CONTEXT && !__TBB_TASK_GROUP_CONTEXT - #error __TBB_FP_CONTEXT requires __TBB_TASK_GROUP_CONTEXT to be enabled -#endif - -#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) -#endif /* __TBB_ARENA_OBSERVER */ - -#ifndef __TBB_SLEEP_PERMISSION - #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 -// TBB and unexpectedly bringing in other community preview features, which might change -// the behavior of the application. -#define __TBB_NO_IMPLICIT_LINKAGE 1 -#endif /* TBB_PREVIEW_FLOW_GRAPH_TRACE */ - -#ifndef __TBB_ITT_STRUCTURE_API -#define __TBB_ITT_STRUCTURE_API ( !__TBB_DEFINE_MIC && (__TBB_CPF_BUILD || TBB_PREVIEW_FLOW_GRAPH_TRACE) ) -#endif - -#if TBB_USE_EXCEPTIONS && !__TBB_TASK_GROUP_CONTEXT - #error TBB_USE_EXCEPTIONS requires __TBB_TASK_GROUP_CONTEXT to be enabled -#endif - -#ifndef __TBB_TASK_PRIORITY - #define __TBB_TASK_PRIORITY (__TBB_TASK_GROUP_CONTEXT) -#endif /* __TBB_TASK_PRIORITY */ - -#if __TBB_TASK_PRIORITY && !__TBB_TASK_GROUP_CONTEXT - #error __TBB_TASK_PRIORITY requires __TBB_TASK_GROUP_CONTEXT to be enabled -#endif - -#if TBB_PREVIEW_WAITING_FOR_WORKERS || __TBB_BUILD - #define __TBB_SUPPORTS_WORKERS_WAITING_IN_TERMINATE 1 -#endif - -#ifndef __TBB_ENQUEUE_ENFORCED_CONCURRENCY - #define __TBB_ENQUEUE_ENFORCED_CONCURRENCY 1 -#endif - -#if !defined(__TBB_SURVIVE_THREAD_SWITCH) && \ - (_WIN32 || _WIN64 || __APPLE__ || (__linux__ && !__ANDROID__)) - #define __TBB_SURVIVE_THREAD_SWITCH 1 -#endif /* __TBB_SURVIVE_THREAD_SWITCH */ - -#ifndef __TBB_DEFAULT_PARTITIONER -#if TBB_DEPRECATED -/** Default partitioner for parallel loop templates in TBB 1.0-2.1 */ -#define __TBB_DEFAULT_PARTITIONER tbb::simple_partitioner -#else -/** Default partitioner for parallel loop templates since TBB 2.2 */ -#define __TBB_DEFAULT_PARTITIONER tbb::auto_partitioner -#endif /* TBB_DEPRECATED */ -#endif /* !defined(__TBB_DEFAULT_PARTITIONER */ - -#ifndef __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES -#define __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES 1 -#endif - -#ifndef __TBB_ENABLE_RANGE_FEEDBACK -#define __TBB_ENABLE_RANGE_FEEDBACK 0 -#endif - -#ifdef _VARIADIC_MAX - #define __TBB_VARIADIC_MAX _VARIADIC_MAX -#else - #if _MSC_VER == 1700 - #define __TBB_VARIADIC_MAX 5 // VS11 setting, issue resolved in VS12 - #elif _MSC_VER == 1600 - #define __TBB_VARIADIC_MAX 10 // VS10 setting - #else - #define __TBB_VARIADIC_MAX 15 - #endif -#endif - -/** __TBB_WIN8UI_SUPPORT enables support of New Windows*8 Store Apps and limit a possibility to load - shared libraries at run time only from application container **/ -#if defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_APP - #define __TBB_WIN8UI_SUPPORT 1 -#else - #define __TBB_WIN8UI_SUPPORT 0 -#endif - -/** Macros of the form __TBB_XXX_BROKEN denote known issues that are caused by - the bugs in compilers, standard or OS specific libraries. They should be - removed as soon as the corresponding bugs are fixed or the buggy OS/compiler - versions go out of the support list. -**/ - -#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). **/ - #define __TBB_GCC_64BIT_ATOMIC_BUILTINS_BROKEN 1 -#elif __TBB_x86_32 && __TBB_GCC_VERSION == 40102 && ! __GNUC_RH_RELEASE__ - /** GCC 4.1.2 erroneously emit call to external function for 64 bit sync_ intrinsics. - However these functions are not defined anywhere. It seems that this problem was fixed later on - and RHEL got an updated version of gcc 4.1.2. **/ - #define __TBB_GCC_64BIT_ATOMIC_BUILTINS_BROKEN 1 -#endif - -#if __GNUC__ && __TBB_x86_64 && __INTEL_COMPILER == 1200 - #define __TBB_ICC_12_0_INL_ASM_FSTCW_BROKEN 1 -#endif - -#if _MSC_VER && __INTEL_COMPILER && (__INTEL_COMPILER<1110 || __INTEL_COMPILER==1110 && __INTEL_COMPILER_BUILD_DATE < 20091012) - /** Necessary to avoid ICL error (or warning in non-strict mode): - "exception specification for implicitly declared virtual destructor is - incompatible with that of overridden one". **/ - #define __TBB_DEFAULT_DTOR_THROW_SPEC_BROKEN 1 -#endif - -#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 - -#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 -#endif - -#if (_WIN32||_WIN64) && __INTEL_COMPILER == 1110 - /** 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 - -#if __clang__ || (__GNUC__==3 && __GNUC_MINOR__==3 && !defined(__INTEL_COMPILER)) - /** Bugs with access to nested classes declared in protected area */ - #define __TBB_PROTECTED_NESTED_CLASS_BROKEN 1 -#endif - -#if __MINGW32__ && __TBB_GCC_VERSION < 40200 - /** 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 -#endif - -#if __TBB_GCC_VERSION==40300 && !__INTEL_COMPILER && !__clang__ - /* GCC of this version may rashly ignore control dependencies */ - #define __TBB_GCC_OPTIMIZER_ORDERING_BROKEN 1 -#endif - -#if __FreeBSD__ - /** A bug in FreeBSD 8.0 results in kernel panic when there is contention - on a mutex created with this attribute. **/ - #define __TBB_PRIO_INHERIT_BROKEN 1 - - /** A bug in FreeBSD 8.0 results in test hanging when an exception occurs - during (concurrent?) object construction by means of placement new operator. **/ - #define __TBB_PLACEMENT_NEW_EXCEPTION_SAFETY_BROKEN 1 -#endif /* __FreeBSD__ */ - -#if (__linux__ || __APPLE__) && __i386__ && defined(__INTEL_COMPILER) - /** 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 - -#if !__INTEL_COMPILER && (_MSC_VER || __GNUC__==3 && __GNUC_MINOR__<=2) - /** Bug in GCC 3.2 and MSVC compilers that sometimes return 0 for __alignof(T) - when T has not yet been instantiated. **/ - #define __TBB_ALIGNOF_NOT_INSTANTIATED_TYPES_BROKEN 1 -#endif - -#if __TBB_DEFINE_MIC - /** Main thread and user's thread have different default thread affinity masks. **/ - #define __TBB_MAIN_THREAD_AFFINITY_BROKEN 1 -#endif - -#if __GXX_EXPERIMENTAL_CXX0X__ && !defined(__EXCEPTIONS) && \ - ((!__INTEL_COMPILER && !__clang__ && (__TBB_GCC_VERSION>=40400 && __TBB_GCC_VERSION<40600)) || \ - (__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 -#endif - -#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 -#endif - -#if (__GNUC__==4 && __GNUC_MINOR__==4 ) && !defined(__INTEL_COMPILER) && !defined(__clang__) - /** excessive warnings related to strict aliasing rules in GCC 4.4 **/ - #define __TBB_GCC_STRICT_ALIASING_BROKEN 1 - /* topical remedy: #pragma GCC diagnostic ignored "-Wstrict-aliasing" */ - #if !__TBB_GCC_WARNING_SUPPRESSION_PRESENT - #error Warning suppression is not supported, while should. - #endif -#endif - -/*In a PIC mode some versions of GCC 4.1.2 generate incorrect inlined code for 8 byte __sync_val_compare_and_swap intrinsic */ -#if __TBB_GCC_VERSION == 40102 && __PIC__ && !defined(__INTEL_COMPILER) && !defined(__clang__) - #define __TBB_GCC_CAS8_BUILTIN_INLINING_BROKEN 1 -#endif - -#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 - -#if __GNUC__ && !__INTEL_COMPILER && !__clang__ && __TBB_DEFAULTED_AND_DELETED_FUNC_PRESENT && __TBB_GCC_VERSION < 40700 - #define __TBB_ZERO_INIT_WITH_DEFAULTED_CTOR_BROKEN 1 -#endif - -#if _MSC_VER && _MSC_VER <= 1800 && !__INTEL_COMPILER - // With MSVC, when an array is passed by const reference to a template function, - // constness from the function parameter may get propagated to the template parameter. - #define __TBB_CONST_REF_TO_ARRAY_TEMPLATE_PARAM_BROKEN 1 -#endif - -// 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__) - -#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 -// 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 **/ - -#if defined(_MSC_VER) && _MSC_VER>=1500 && !defined(__INTEL_COMPILER) - // A macro to suppress erroneous or benign "unreachable code" MSVC warning (4702) - #define __TBB_MSVC_UNREACHABLE_CODE_IGNORED 1 -#endif - -#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__ -#include -#define __TBB_USE_DLOPEN_REENTRANCY_WORKAROUND (__ANDROID_API__ < 19) -#endif - -#define __TBB_ALLOCATOR_CONSTRUCT_VARIADIC (__TBB_CPP11_VARIADIC_TEMPLATES_PRESENT && __TBB_CPP11_RVALUE_REF_PRESENT) - -#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_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 deleted file mode 100644 index 1c843309..00000000 --- a/lib/3rdParty/tbb/include/tbb/tbb_exception.h +++ /dev/null @@ -1,371 +0,0 @@ -/* - 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_exception_H -#define __TBB_exception_H - -#include "tbb_stddef.h" - -#if !TBB_USE_EXCEPTIONS && _MSC_VER - // Suppress "C++ exception handler used, but unwind semantics are not enabled" warning in STL headers - #pragma warning (push) - #pragma warning (disable: 4530) -#endif - -#include -#include //required for bad_alloc definition, operators new -#include // required to construct std exception classes - -#if !TBB_USE_EXCEPTIONS && _MSC_VER - #pragma warning (pop) -#endif - -namespace tbb { - -//! Exception for concurrent containers -class bad_last_alloc : public std::bad_alloc { -public: - const char* what() const throw() __TBB_override; -#if __TBB_DEFAULT_DTOR_THROW_SPEC_BROKEN - ~bad_last_alloc() throw() __TBB_override {} -#endif -}; - -//! Exception for PPL locks -class improper_lock : public std::exception { -public: - const char* what() const throw() __TBB_override; -}; - -//! Exception for user-initiated abort -class user_abort : public std::exception { -public: - const char* what() const throw() __TBB_override; -}; - -//! Exception for missing wait on structured_task_group -class missing_wait : public std::exception { -public: - const char* what() const throw() __TBB_override; -}; - -//! Exception for repeated scheduling of the same task_handle -class invalid_multiple_scheduling : public std::exception { -public: - const char* what() const throw() __TBB_override; -}; - -namespace internal { -//! Obsolete -void __TBB_EXPORTED_FUNC throw_bad_last_alloc_exception_v4(); - -enum exception_id { - eid_bad_alloc = 1, - eid_bad_last_alloc, - eid_nonpositive_step, - eid_out_of_range, - eid_segment_range_error, - eid_index_range_error, - eid_missing_wait, - eid_invalid_multiple_scheduling, - eid_improper_lock, - eid_possible_deadlock, - eid_operation_not_permitted, - eid_condvar_wait_failed, - eid_invalid_load_factor, - eid_reserved, // free slot for backward compatibility, can be reused. - eid_invalid_swap, - eid_reservation_length_error, - eid_invalid_key, - eid_user_abort, - eid_reserved1, -#if __TBB_SUPPORTS_WORKERS_WAITING_IN_TERMINATE - // 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_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. - /** When adding new IDs, place them immediately _before_ this comment (that is - _after_ all the existing IDs. NEVER insert new IDs between the existing ones. **/ - eid_max -}; - -//! Gathers all throw operators in one place. -/** Its purpose is to minimize code bloat that can be caused by throw operators - scattered in multiple places, especially in templates. **/ -void __TBB_EXPORTED_FUNC throw_exception_v4 ( exception_id ); - -//! Versionless convenience wrapper for throw_exception_v4() -inline void throw_exception ( exception_id eid ) { throw_exception_v4(eid); } - -} // namespace internal -} // namespace tbb - -#if __TBB_TASK_GROUP_CONTEXT -#include "tbb_allocator.h" -#include //for typeid - -namespace tbb { - -//! Interface to be implemented by all exceptions TBB recognizes and propagates across the threads. -/** If an unhandled exception of the type derived from tbb::tbb_exception is intercepted - by the TBB scheduler in one of the worker threads, it is delivered to and re-thrown in - the root thread. The root thread is the thread that has started the outermost algorithm - or root task sharing the same task_group_context with the guilty algorithm/task (the one - that threw the exception first). - - Note: when documentation mentions workers with respect to exception handling, - masters are implied as well, because they are completely equivalent in this context. - Consequently a root thread can be master or worker thread. - - NOTE: In case of nested algorithms or complex task hierarchies when the nested - levels share (explicitly or by means of implicit inheritance) the task group - context of the outermost level, the exception may be (re-)thrown multiple times - (ultimately - in each worker on each nesting level) before reaching the root - thread at the outermost level. IMPORTANT: if you intercept an exception derived - from this class on a nested level, you must re-throw it in the catch block by means - of the "throw;" operator. - - TBB provides two implementations of this interface: tbb::captured_exception and - template class tbb::movable_exception. See their declarations for more info. **/ -class tbb_exception : public std::exception -{ - /** No operator new is provided because the TBB usage model assumes dynamic - creation of the TBB exception objects only by means of applying move() - operation on an exception thrown out of TBB scheduler. **/ - void* operator new ( size_t ); - -public: -#if __clang__ - // At -O3 or even -O2 optimization level, Clang may fully throw away an empty destructor - // of tbb_exception from destructors of derived classes. As a result, it does not create - // vtable for tbb_exception, which is a required part of TBB binary interface. - // Making the destructor non-empty (with just a semicolon) prevents that optimization. - ~tbb_exception() throw() { /* keep the semicolon! */ ; } -#endif - - //! Creates and returns pointer to the deep copy of this exception object. - /** Move semantics is allowed. **/ - virtual tbb_exception* move () throw() = 0; - - //! Destroys objects created by the move() method. - /** Frees memory and calls destructor for this exception object. - Can and must be used only on objects created by the move method. **/ - virtual void destroy () throw() = 0; - - //! Throws this exception object. - /** Make sure that if you have several levels of derivation from this interface - you implement or override this method on the most derived level. The implementation - is as simple as "throw *this;". Failure to do this will result in exception - of a base class type being thrown. **/ - virtual void throw_self () = 0; - - //! Returns RTTI name of the originally intercepted exception - virtual const char* name() const throw() = 0; - - //! Returns the result of originally intercepted exception's what() method. - 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() - operation on an exception thrown out of TBB scheduler. - - When overriding method move() make sure to override operator delete as well - if memory is allocated not by TBB's scalable allocator. **/ - void operator delete ( void* p ) { - internal::deallocate_via_handler_v3(p); - } -}; - -//! This class is used by TBB to propagate information about unhandled exceptions into the root thread. -/** Exception of this type is thrown by TBB in the root thread (thread that started a parallel - algorithm ) if an unhandled exception was intercepted during the algorithm execution in one - of the workers. - \sa tbb::tbb_exception **/ -class captured_exception : public tbb_exception -{ -public: - captured_exception ( const captured_exception& src ) - : tbb_exception(src), my_dynamic(false) - { - set(src.my_exception_name, src.my_exception_info); - } - - captured_exception ( const char* name_, const char* info ) - : my_dynamic(false) - { - set(name_, info); - } - - __TBB_EXPORTED_METHOD ~captured_exception () throw(); - - captured_exception& operator= ( const captured_exception& src ) { - if ( this != &src ) { - clear(); - set(src.my_exception_name, src.my_exception_info); - } - return *this; - } - - captured_exception* __TBB_EXPORTED_METHOD move () throw() __TBB_override; - - void __TBB_EXPORTED_METHOD destroy () throw() __TBB_override; - - void throw_self () __TBB_override { __TBB_THROW(*this); } - - const char* __TBB_EXPORTED_METHOD name() const throw() __TBB_override; - - 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(); - -private: - //! Used only by method clone(). - captured_exception() {} - - //! Functionally equivalent to {captured_exception e(name,info); return e.clone();} - static captured_exception* allocate ( const char* name, const char* info ); - - bool my_dynamic; - const char* my_exception_name; - const char* my_exception_info; -}; - -//! Template that can be used to implement exception that transfers arbitrary ExceptionData to the root thread -/** Code using TBB can instantiate this template with an arbitrary ExceptionData type - and throw this exception object. Such exceptions are intercepted by the TBB scheduler - and delivered to the root thread (). - \sa tbb::tbb_exception **/ -template -class movable_exception : public tbb_exception -{ - typedef movable_exception self_type; - -public: - movable_exception ( const ExceptionData& data_ ) - : my_exception_data(data_) - , my_dynamic(false) - , my_exception_name( -#if TBB_USE_EXCEPTIONS - typeid(self_type).name() -#else /* !TBB_USE_EXCEPTIONS */ - "movable_exception" -#endif /* !TBB_USE_EXCEPTIONS */ - ) - {} - - movable_exception ( const movable_exception& src ) throw () - : tbb_exception(src) - , my_exception_data(src.my_exception_data) - , my_dynamic(false) - , my_exception_name(src.my_exception_name) - {} - - ~movable_exception () throw() {} - - const movable_exception& operator= ( const movable_exception& src ) { - if ( this != &src ) { - my_exception_data = src.my_exception_data; - my_exception_name = src.my_exception_name; - } - return *this; - } - - ExceptionData& data () throw() { return my_exception_data; } - - const ExceptionData& data () const throw() { return my_exception_data; } - - const char* name () const throw() __TBB_override { return my_exception_name; } - - const char* what () const throw() __TBB_override { return "tbb::movable_exception"; } - - movable_exception* move () throw() __TBB_override { - void* e = internal::allocate_via_handler_v3(sizeof(movable_exception)); - if ( e ) { - ::new (e) movable_exception(*this); - ((movable_exception*)e)->my_dynamic = true; - } - return (movable_exception*)e; - } - 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); - } - } - void throw_self () __TBB_override { __TBB_THROW( *this ); } - -protected: - //! User data - ExceptionData my_exception_data; - -private: - //! Flag specifying whether this object has been dynamically allocated (by the move method) - bool my_dynamic; - - //! RTTI name of this class - /** We rely on the fact that RTTI names are static string constants. **/ - const char* my_exception_name; -}; - -#if !TBB_USE_CAPTURED_EXCEPTION -namespace internal { - -//! Exception container that preserves the exact copy of the original exception -/** This class can be used only when the appropriate runtime support (mandated - by C++0x) is present **/ -class tbb_exception_ptr { - std::exception_ptr my_ptr; - -public: - static tbb_exception_ptr* allocate (); - static tbb_exception_ptr* allocate ( const tbb_exception& tag ); - //! This overload uses move semantics (i.e. it empties src) - static tbb_exception_ptr* allocate ( captured_exception& src ); - - //! Destroys this objects - /** Note that objects of this type can be created only by the allocate() method. **/ - void destroy () throw(); - - //! Throws the contained exception . - void throw_self () { std::rethrow_exception(my_ptr); } - -private: - tbb_exception_ptr ( const std::exception_ptr& src ) : my_ptr(src) {} - tbb_exception_ptr ( const captured_exception& src ) : - #if __TBB_MAKE_EXCEPTION_PTR_PRESENT - my_ptr(std::make_exception_ptr(src)) // the final function name in C++11 - #else - my_ptr(std::copy_exception(src)) // early C++0x drafts name - #endif - {} -}; // class tbb::internal::tbb_exception_ptr - -} // namespace internal -#endif /* !TBB_USE_CAPTURED_EXCEPTION */ - -} // namespace tbb - -#endif /* __TBB_TASK_GROUP_CONTEXT */ - -#endif /* __TBB_exception_H */ diff --git a/lib/3rdParty/tbb/include/tbb/tbb_machine.h b/lib/3rdParty/tbb/include/tbb/tbb_machine.h deleted file mode 100644 index 68d1d5d0..00000000 --- a/lib/3rdParty/tbb/include/tbb/tbb_machine.h +++ /dev/null @@ -1,974 +0,0 @@ -/* - 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_machine_H -#define __TBB_machine_H - -/** This header provides basic platform abstraction layer by hooking up appropriate - architecture/OS/compiler specific headers from the /include/tbb/machine directory. - If a plug-in header does not implement all the required APIs, it must specify - the missing ones by setting one or more of the following macros: - - __TBB_USE_GENERIC_PART_WORD_CAS - __TBB_USE_GENERIC_PART_WORD_FETCH_ADD - __TBB_USE_GENERIC_PART_WORD_FETCH_STORE - __TBB_USE_GENERIC_FETCH_ADD - __TBB_USE_GENERIC_FETCH_STORE - __TBB_USE_GENERIC_DWORD_FETCH_ADD - __TBB_USE_GENERIC_DWORD_FETCH_STORE - __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE - __TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE - __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 - 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 - architecture, and thus should be relied upon only after careful evaluation - or as the last resort. - - Additionally __TBB_64BIT_ATOMICS can be set to 0 on a 32-bit architecture to - indicate that the port is not going to support double word atomics. It may also - be set to 1 explicitly, though normally this is not necessary as tbb_machine.h - will set it automatically. - - __TBB_ENDIANNESS macro can be defined by the implementation as well. - It is used only if __TBB_USE_GENERIC_PART_WORD_CAS is set (or for testing), - and must specify the layout of aligned 16-bit and 32-bit data anywhere within a process - (while the details of unaligned 16-bit or 32-bit data or of 64-bit data are irrelevant). - The layout must be the same at all relevant memory locations within the current process; - in case of page-specific endianness, one endianness must be kept "out of sight". - Possible settings, reflecting hardware and possibly O.S. convention, are: - - __TBB_ENDIAN_BIG for big-endian data, - - __TBB_ENDIAN_LITTLE for little-endian data, - - __TBB_ENDIAN_DETECT for run-time detection iff exactly one of the above, - - __TBB_ENDIAN_UNSUPPORTED to prevent undefined behavior if none of the above. - - Prerequisites for each architecture port - ---------------------------------------- - The following functions and macros have no generic implementation. Therefore they must be - implemented in each machine architecture specific header either as a conventional - function or as a functional macro. - - __TBB_WORDSIZE - This is the size of machine word in bytes, i.e. for 32 bit systems it - should be defined to 4. - - __TBB_Yield() - Signals OS that the current thread is willing to relinquish the remainder - of its time quantum. - - __TBB_full_memory_fence() - Must prevent all memory operations from being reordered across it (both - by hardware and compiler). All such fences must be totally ordered (or - sequentially consistent). - - __TBB_machine_cmpswp4( volatile void *ptr, int32_t value, int32_t comparand ) - Must be provided if __TBB_USE_FENCED_ATOMICS is not set. - - __TBB_machine_cmpswp8( volatile void *ptr, int32_t value, int64_t comparand ) - Must be provided for 64-bit architectures if __TBB_USE_FENCED_ATOMICS is not set, - and for 32-bit architectures if __TBB_64BIT_ATOMICS is set - - __TBB_machine_(...), where - = {cmpswp, fetchadd, fetchstore} - = {1, 2, 4, 8} - = {full_fence, acquire, release, relaxed} - Must be provided if __TBB_USE_FENCED_ATOMICS is set. - - __TBB_control_consistency_helper() - Bridges the memory-semantics gap between architectures providing only - implicit C++0x "consume" semantics (like Power Architecture) and those - also implicitly obeying control dependencies (like IA-64 architecture). - It must be used only in conditional code where the condition is itself - data-dependent, and will then make subsequent code behave as if the - original data dependency were acquired. - It needs only a compiler fence where implied by the architecture - either specifically (like IA-64 architecture) or because generally stronger - "acquire" semantics are enforced (like x86). - It is always valid, though potentially suboptimal, to replace - control with acquire on the load and then remove the helper. - - __TBB_acquire_consistency_helper(), __TBB_release_consistency_helper() - Must be provided if __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE is set. - Enforce acquire and release semantics in generic implementations of fenced - store and load operations. Depending on the particular architecture/compiler - combination they may be a hardware fence, a compiler fence, both or nothing. - **/ - -#include "tbb_stddef.h" - -namespace tbb { -namespace internal { //< @cond INTERNAL - -//////////////////////////////////////////////////////////////////////////////// -// Overridable helpers declarations -// -// A machine/*.h file may choose to define these templates, otherwise it must -// request default implementation by setting appropriate __TBB_USE_GENERIC_XXX macro(s). -// -template -struct machine_load_store; - -template -struct machine_load_store_relaxed; - -template -struct machine_load_store_seq_cst; -// -// End of overridable helpers declarations -//////////////////////////////////////////////////////////////////////////////// - -template struct atomic_selector; - -template<> struct atomic_selector<1> { - typedef int8_t word; - inline static word fetch_store ( volatile void* location, word value ); -}; - -template<> struct atomic_selector<2> { - typedef int16_t word; - inline static word fetch_store ( volatile void* location, word value ); -}; - -template<> struct atomic_selector<4> { -#if _MSC_VER && !_WIN64 - // Work-around that avoids spurious /Wp64 warnings - typedef intptr_t word; -#else - typedef int32_t word; -#endif - inline static word fetch_store ( volatile void* location, word value ); -}; - -template<> struct atomic_selector<8> { - typedef int64_t word; - inline static word fetch_store ( volatile void* location, word value ); -}; - -}} //< namespaces internal @endcond, tbb - -#define __TBB_MACHINE_DEFINE_STORE8_GENERIC_FENCED(M) \ - inline void __TBB_machine_generic_store8##M(volatile void *ptr, int64_t value) { \ - for(;;) { \ - int64_t result = *(volatile int64_t *)ptr; \ - if( __TBB_machine_cmpswp8##M(ptr,value,result)==result ) break; \ - } \ - } \ - -#define __TBB_MACHINE_DEFINE_LOAD8_GENERIC_FENCED(M) \ - inline int64_t __TBB_machine_generic_load8##M(const volatile void *ptr) { \ - /* Comparand and new value may be anything, they only must be equal, and */ \ - /* the value should have a low probability to be actually found in 'location'.*/ \ - const int64_t anyvalue = 2305843009213693951LL; \ - return __TBB_machine_cmpswp8##M(const_cast(ptr),anyvalue,anyvalue); \ - } \ - -// The set of allowed values for __TBB_ENDIANNESS (see above for details) -#define __TBB_ENDIAN_UNSUPPORTED -1 -#define __TBB_ENDIAN_LITTLE 0 -#define __TBB_ENDIAN_BIG 1 -#define __TBB_ENDIAN_DETECT 2 - -#if _WIN32||_WIN64 - -#ifdef _MANAGED -#pragma managed(push, off) -#endif - - #if __MINGW64__ || __MINGW32__ - extern "C" __declspec(dllimport) int __stdcall SwitchToThread( void ); - #define __TBB_Yield() SwitchToThread() - #if (TBB_USE_GCC_BUILTINS && __TBB_GCC_BUILTIN_ATOMICS_PRESENT) - #include "machine/gcc_generic.h" - #elif __MINGW64__ - #include "machine/linux_intel64.h" - #elif __MINGW32__ - #include "machine/linux_ia32.h" - #endif - #elif (TBB_USE_ICC_BUILTINS && __TBB_ICC_BUILTIN_ATOMICS_PRESENT) - #include "machine/icc_generic.h" - #elif defined(_M_IX86) && !defined(__TBB_WIN32_USE_CL_BUILTINS) - #include "machine/windows_ia32.h" - #elif defined(_M_X64) - #include "machine/windows_intel64.h" - #elif defined(_M_ARM) || defined(__TBB_WIN32_USE_CL_BUILTINS) - #include "machine/msvc_armv7.h" - #endif - -#ifdef _MANAGED -#pragma managed(pop) -#endif - -#elif __TBB_DEFINE_MIC - - #include "machine/mic_common.h" - #if (TBB_USE_ICC_BUILTINS && __TBB_ICC_BUILTIN_ATOMICS_PRESENT) - #include "machine/icc_generic.h" - #else - #include "machine/linux_intel64.h" - #endif - -#elif __linux__ || __FreeBSD__ || __NetBSD__ - - #if (TBB_USE_GCC_BUILTINS && __TBB_GCC_BUILTIN_ATOMICS_PRESENT) - #include "machine/gcc_generic.h" - #elif (TBB_USE_ICC_BUILTINS && __TBB_ICC_BUILTIN_ATOMICS_PRESENT) - #include "machine/icc_generic.h" - #elif __i386__ - #include "machine/linux_ia32.h" - #elif __x86_64__ - #include "machine/linux_intel64.h" - #elif __ia64__ - #include "machine/linux_ia64.h" - #elif __powerpc__ - #include "machine/mac_ppc.h" - #elif __ARM_ARCH_7A__ - #include "machine/gcc_armv7.h" - #elif __TBB_GCC_BUILTIN_ATOMICS_PRESENT - #include "machine/gcc_generic.h" - #endif - #include "machine/linux_common.h" - -#elif __APPLE__ - //TODO: TBB_USE_GCC_BUILTINS is not used for Mac, Sun, Aix - #if (TBB_USE_ICC_BUILTINS && __TBB_ICC_BUILTIN_ATOMICS_PRESENT) - #include "machine/icc_generic.h" - #elif __TBB_x86_32 - #include "machine/linux_ia32.h" - #elif __TBB_x86_64 - #include "machine/linux_intel64.h" - #elif __POWERPC__ - #include "machine/mac_ppc.h" - #endif - #include "machine/macos_common.h" - -#elif _AIX - - #include "machine/ibm_aix51.h" - -#elif __sun || __SUNPRO_CC - - #define __asm__ asm - #define __volatile__ volatile - - #if __i386 || __i386__ - #include "machine/linux_ia32.h" - #elif __x86_64__ - #include "machine/linux_intel64.h" - #elif __sparc - #include "machine/sunos_sparc.h" - #endif - #include - - #define __TBB_Yield() sched_yield() - -#endif /* OS selection */ - -#ifndef __TBB_64BIT_ATOMICS - #define __TBB_64BIT_ATOMICS 1 -#endif - -//TODO: replace usage of these functions with usage of tbb::atomic, and then remove them -//TODO: map functions with W suffix to use cast to tbb::atomic and according op, i.e. as_atomic().op() -// Special atomic functions -#if __TBB_USE_FENCED_ATOMICS - #define __TBB_machine_cmpswp1 __TBB_machine_cmpswp1full_fence - #define __TBB_machine_cmpswp2 __TBB_machine_cmpswp2full_fence - #define __TBB_machine_cmpswp4 __TBB_machine_cmpswp4full_fence - #define __TBB_machine_cmpswp8 __TBB_machine_cmpswp8full_fence - - #if __TBB_WORDSIZE==8 - #define __TBB_machine_fetchadd8 __TBB_machine_fetchadd8full_fence - #define __TBB_machine_fetchstore8 __TBB_machine_fetchstore8full_fence - #define __TBB_FetchAndAddWrelease(P,V) __TBB_machine_fetchadd8release(P,V) - #define __TBB_FetchAndIncrementWacquire(P) __TBB_machine_fetchadd8acquire(P,1) - #define __TBB_FetchAndDecrementWrelease(P) __TBB_machine_fetchadd8release(P,(-1)) - #else - #define __TBB_machine_fetchadd4 __TBB_machine_fetchadd4full_fence - #define __TBB_machine_fetchstore4 __TBB_machine_fetchstore4full_fence - #define __TBB_FetchAndAddWrelease(P,V) __TBB_machine_fetchadd4release(P,V) - #define __TBB_FetchAndIncrementWacquire(P) __TBB_machine_fetchadd4acquire(P,1) - #define __TBB_FetchAndDecrementWrelease(P) __TBB_machine_fetchadd4release(P,(-1)) - #endif /* __TBB_WORDSIZE==4 */ -#else /* !__TBB_USE_FENCED_ATOMICS */ - #define __TBB_FetchAndAddWrelease(P,V) __TBB_FetchAndAddW(P,V) - #define __TBB_FetchAndIncrementWacquire(P) __TBB_FetchAndAddW(P,1) - #define __TBB_FetchAndDecrementWrelease(P) __TBB_FetchAndAddW(P,(-1)) -#endif /* !__TBB_USE_FENCED_ATOMICS */ - -#if __TBB_WORDSIZE==4 - #define __TBB_CompareAndSwapW(P,V,C) __TBB_machine_cmpswp4(P,V,C) - #define __TBB_FetchAndAddW(P,V) __TBB_machine_fetchadd4(P,V) - #define __TBB_FetchAndStoreW(P,V) __TBB_machine_fetchstore4(P,V) -#elif __TBB_WORDSIZE==8 - #if __TBB_USE_GENERIC_DWORD_LOAD_STORE || __TBB_USE_GENERIC_DWORD_FETCH_ADD || __TBB_USE_GENERIC_DWORD_FETCH_STORE - #error These macros should only be used on 32-bit platforms. - #endif - - #define __TBB_CompareAndSwapW(P,V,C) __TBB_machine_cmpswp8(P,V,C) - #define __TBB_FetchAndAddW(P,V) __TBB_machine_fetchadd8(P,V) - #define __TBB_FetchAndStoreW(P,V) __TBB_machine_fetchstore8(P,V) -#else /* __TBB_WORDSIZE != 8 */ - #error Unsupported machine word size. -#endif /* __TBB_WORDSIZE */ - -#ifndef __TBB_Pause - inline void __TBB_Pause(int32_t) { - __TBB_Yield(); - } -#endif - -namespace tbb { - -//! Sequentially consistent full memory fence. -inline void atomic_fence () { __TBB_full_memory_fence(); } - -namespace internal { //< @cond INTERNAL - -//! Class that implements exponential backoff. -/** See implementation of spin_wait_while_eq for an example. */ -class atomic_backoff : no_copy { - //! Time delay, in units of "pause" instructions. - /** Should be equal to approximately the number of "pause" instructions - that take the same time as an context switch. Must be a power of two.*/ - static const int32_t LOOPS_BEFORE_YIELD = 16; - int32_t count; -public: - // In many cases, an object of this type is initialized eagerly on hot path, - // as in for(atomic_backoff b; ; b.pause()) { /*loop body*/ } - // For this reason, the construction cost must be very small! - atomic_backoff() : count(1) {} - // This constructor pauses immediately; do not use on hot paths! - atomic_backoff( bool ) : count(1) { pause(); } - - //! Pause for a while. - void pause() { - if( count<=LOOPS_BEFORE_YIELD ) { - __TBB_Pause(count); - // Pause twice as long the next time. - count*=2; - } else { - // Pause is so long that we might as well yield CPU to scheduler. - __TBB_Yield(); - } - } - - //! Pause for a few times and return false if saturated. - bool bounded_pause() { - __TBB_Pause(count); - if( count -void spin_wait_while_eq( const volatile T& location, U value ) { - atomic_backoff backoff; - while( location==value ) backoff.pause(); -} - -//! Spin UNTIL the value of the variable is equal to a given value -/** T and U should be comparable types. */ -template -void spin_wait_until_eq( const volatile T& location, const U value ) { - atomic_backoff backoff; - while( location!=value ) backoff.pause(); -} - -template -void spin_wait_while(predicate_type condition){ - atomic_backoff backoff; - while( condition() ) backoff.pause(); -} - -//////////////////////////////////////////////////////////////////////////////// -// Generic compare-and-swap applied to only a part of a machine word. -// -#ifndef __TBB_ENDIANNESS -#define __TBB_ENDIANNESS __TBB_ENDIAN_DETECT -#endif - -#if __TBB_USE_GENERIC_PART_WORD_CAS && __TBB_ENDIANNESS==__TBB_ENDIAN_UNSUPPORTED -#error Generic implementation of part-word CAS may not be used with __TBB_ENDIAN_UNSUPPORTED -#endif - -#if __TBB_ENDIANNESS!=__TBB_ENDIAN_UNSUPPORTED -// -// This function is the only use of __TBB_ENDIANNESS. -// The following restrictions/limitations apply for this operation: -// - T must be an integer type of at most 4 bytes for the casts and calculations to work -// - T must also be less than 4 bytes to avoid compiler warnings when computing mask -// (and for the operation to be useful at all, so no workaround is applied) -// - the architecture must consistently use either little-endian or big-endian (same for all locations) -// -// TODO: static_assert for the type requirements stated above -template -inline T __TBB_MaskedCompareAndSwap (volatile T * const ptr, const T value, const T comparand ) { - struct endianness{ static bool is_big_endian(){ - #if __TBB_ENDIANNESS==__TBB_ENDIAN_DETECT - const uint32_t probe = 0x03020100; - return (((const char*)(&probe))[0]==0x03); - #elif __TBB_ENDIANNESS==__TBB_ENDIAN_BIG || __TBB_ENDIANNESS==__TBB_ENDIAN_LITTLE - return __TBB_ENDIANNESS==__TBB_ENDIAN_BIG; - #else - #error Unexpected value of __TBB_ENDIANNESS - #endif - }}; - - const uint32_t byte_offset = (uint32_t) ((uintptr_t)ptr & 0x3); - volatile uint32_t * const aligned_ptr = (uint32_t*)((uintptr_t)ptr - byte_offset ); - - // location of T within uint32_t for a C++ shift operation - const uint32_t bits_to_shift = 8*(endianness::is_big_endian() ? (4 - sizeof(T) - (byte_offset)) : byte_offset); - const uint32_t mask = (((uint32_t)1<<(sizeof(T)*8)) - 1 )<> bits_to_shift); - } - else continue; // CAS failed but the bits of interest were not changed - } -} -#endif // __TBB_ENDIANNESS!=__TBB_ENDIAN_UNSUPPORTED -//////////////////////////////////////////////////////////////////////////////// - -template -inline T __TBB_CompareAndSwapGeneric (volatile void *ptr, T value, T comparand ); - -template<> -inline int8_t __TBB_CompareAndSwapGeneric <1,int8_t> (volatile void *ptr, int8_t value, int8_t comparand ) { -#if __TBB_USE_GENERIC_PART_WORD_CAS - return __TBB_MaskedCompareAndSwap((volatile int8_t *)ptr,value,comparand); -#else - return __TBB_machine_cmpswp1(ptr,value,comparand); -#endif -} - -template<> -inline int16_t __TBB_CompareAndSwapGeneric <2,int16_t> (volatile void *ptr, int16_t value, int16_t comparand ) { -#if __TBB_USE_GENERIC_PART_WORD_CAS - return __TBB_MaskedCompareAndSwap((volatile int16_t *)ptr,value,comparand); -#else - return __TBB_machine_cmpswp2(ptr,value,comparand); -#endif -} - -template<> -inline int32_t __TBB_CompareAndSwapGeneric <4,int32_t> (volatile void *ptr, int32_t value, int32_t comparand ) { - // Cast shuts up /Wp64 warning - return (int32_t)__TBB_machine_cmpswp4(ptr,value,comparand); -} - -#if __TBB_64BIT_ATOMICS -template<> -inline int64_t __TBB_CompareAndSwapGeneric <8,int64_t> (volatile void *ptr, int64_t value, int64_t comparand ) { - return __TBB_machine_cmpswp8(ptr,value,comparand); -} -#endif - -template -inline T __TBB_FetchAndAddGeneric (volatile void *ptr, T addend) { - T result; - for( atomic_backoff b;;b.pause() ) { - result = *reinterpret_cast(ptr); - // __TBB_CompareAndSwapGeneric presumed to have full fence. - if( __TBB_CompareAndSwapGeneric ( ptr, result+addend, result )==result ) - break; - } - return result; -} - -template -inline T __TBB_FetchAndStoreGeneric (volatile void *ptr, T value) { - T result; - for( atomic_backoff b;;b.pause() ) { - result = *reinterpret_cast(ptr); - // __TBB_CompareAndSwapGeneric presumed to have full fence. - if( __TBB_CompareAndSwapGeneric ( ptr, value, result )==result ) - break; - } - return result; -} - -#if __TBB_USE_GENERIC_PART_WORD_CAS -#define __TBB_machine_cmpswp1 tbb::internal::__TBB_CompareAndSwapGeneric<1,int8_t> -#define __TBB_machine_cmpswp2 tbb::internal::__TBB_CompareAndSwapGeneric<2,int16_t> -#endif - -#if __TBB_USE_GENERIC_FETCH_ADD || __TBB_USE_GENERIC_PART_WORD_FETCH_ADD -#define __TBB_machine_fetchadd1 tbb::internal::__TBB_FetchAndAddGeneric<1,int8_t> -#define __TBB_machine_fetchadd2 tbb::internal::__TBB_FetchAndAddGeneric<2,int16_t> -#endif - -#if __TBB_USE_GENERIC_FETCH_ADD -#define __TBB_machine_fetchadd4 tbb::internal::__TBB_FetchAndAddGeneric<4,int32_t> -#endif - -#if __TBB_USE_GENERIC_FETCH_ADD || __TBB_USE_GENERIC_DWORD_FETCH_ADD -#define __TBB_machine_fetchadd8 tbb::internal::__TBB_FetchAndAddGeneric<8,int64_t> -#endif - -#if __TBB_USE_GENERIC_FETCH_STORE || __TBB_USE_GENERIC_PART_WORD_FETCH_STORE -#define __TBB_machine_fetchstore1 tbb::internal::__TBB_FetchAndStoreGeneric<1,int8_t> -#define __TBB_machine_fetchstore2 tbb::internal::__TBB_FetchAndStoreGeneric<2,int16_t> -#endif - -#if __TBB_USE_GENERIC_FETCH_STORE -#define __TBB_machine_fetchstore4 tbb::internal::__TBB_FetchAndStoreGeneric<4,int32_t> -#endif - -#if __TBB_USE_GENERIC_FETCH_STORE || __TBB_USE_GENERIC_DWORD_FETCH_STORE -#define __TBB_machine_fetchstore8 tbb::internal::__TBB_FetchAndStoreGeneric<8,int64_t> -#endif - -#if __TBB_USE_FETCHSTORE_AS_FULL_FENCED_STORE -#define __TBB_MACHINE_DEFINE_ATOMIC_SELECTOR_FETCH_STORE(S) \ - atomic_selector::word atomic_selector::fetch_store ( volatile void* location, word value ) { \ - return __TBB_machine_fetchstore##S( location, value ); \ - } - -__TBB_MACHINE_DEFINE_ATOMIC_SELECTOR_FETCH_STORE(1) -__TBB_MACHINE_DEFINE_ATOMIC_SELECTOR_FETCH_STORE(2) -__TBB_MACHINE_DEFINE_ATOMIC_SELECTOR_FETCH_STORE(4) -__TBB_MACHINE_DEFINE_ATOMIC_SELECTOR_FETCH_STORE(8) - -#undef __TBB_MACHINE_DEFINE_ATOMIC_SELECTOR_FETCH_STORE -#endif /* __TBB_USE_FETCHSTORE_AS_FULL_FENCED_STORE */ - -#if __TBB_USE_GENERIC_DWORD_LOAD_STORE -/*TODO: find a more elegant way to handle function names difference*/ -#if ! __TBB_USE_FENCED_ATOMICS - /* This name forwarding is needed for generic implementation of - * load8/store8 defined below (via macro) to pick the right CAS function*/ - #define __TBB_machine_cmpswp8full_fence __TBB_machine_cmpswp8 -#endif -__TBB_MACHINE_DEFINE_LOAD8_GENERIC_FENCED(full_fence) -__TBB_MACHINE_DEFINE_STORE8_GENERIC_FENCED(full_fence) - -#if ! __TBB_USE_FENCED_ATOMICS - #undef __TBB_machine_cmpswp8full_fence -#endif - -#define __TBB_machine_store8 tbb::internal::__TBB_machine_generic_store8full_fence -#define __TBB_machine_load8 tbb::internal::__TBB_machine_generic_load8full_fence -#endif /* __TBB_USE_GENERIC_DWORD_LOAD_STORE */ - -#if __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE -/** Fenced operations use volatile qualifier to prevent compiler from optimizing - them out, and on architectures with weak memory ordering to induce compiler - to generate code with appropriate acquire/release semantics. - On architectures like IA32, Intel64 (and likely Sparc TSO) volatile has - no effect on code gen, and consistency helpers serve as a compiler fence (the - latter being true for IA64/gcc as well to fix a bug in some gcc versions). - This code assumes that the generated instructions will operate atomically, - which typically requires a type that can be moved in a single instruction, - cooperation from the compiler for effective use of such an instruction, - and appropriate alignment of the data. **/ -template -struct machine_load_store { - static T load_with_acquire ( const volatile T& location ) { - T to_return = location; - __TBB_acquire_consistency_helper(); - return to_return; - } - static void store_with_release ( volatile T &location, T value ) { - __TBB_release_consistency_helper(); - location = value; - } -}; - -//in general, plain load and store of 32bit compiler is not atomic for 64bit types -#if __TBB_WORDSIZE==4 && __TBB_64BIT_ATOMICS -template -struct machine_load_store { - static T load_with_acquire ( const volatile T& location ) { - return (T)__TBB_machine_load8( (const volatile void*)&location ); - } - static void store_with_release ( volatile T& location, T value ) { - __TBB_machine_store8( (volatile void*)&location, (int64_t)value ); - } -}; -#endif /* __TBB_WORDSIZE==4 && __TBB_64BIT_ATOMICS */ -#endif /* __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE */ - -#if __TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE -template -struct machine_load_store_seq_cst { - static T load ( const volatile T& location ) { - __TBB_full_memory_fence(); - return machine_load_store::load_with_acquire( location ); - } -#if __TBB_USE_FETCHSTORE_AS_FULL_FENCED_STORE - static void store ( volatile T &location, T value ) { - atomic_selector::fetch_store( (volatile void*)&location, (typename atomic_selector::word)value ); - } -#else /* !__TBB_USE_FETCHSTORE_AS_FULL_FENCED_STORE */ - static void store ( volatile T &location, T value ) { - machine_load_store::store_with_release( location, value ); - __TBB_full_memory_fence(); - } -#endif /* !__TBB_USE_FETCHSTORE_AS_FULL_FENCED_STORE */ -}; - -#if __TBB_WORDSIZE==4 && __TBB_64BIT_ATOMICS -/** The implementation does not use functions __TBB_machine_load8/store8 as they - are not required to be sequentially consistent. **/ -template -struct machine_load_store_seq_cst { - static T load ( const volatile T& location ) { - // Comparand and new value may be anything, they only must be equal, and - // the value should have a low probability to be actually found in 'location'. - const int64_t anyvalue = 2305843009213693951LL; - return __TBB_machine_cmpswp8( (volatile void*)const_cast(&location), anyvalue, anyvalue ); - } - static void store ( volatile T &location, T value ) { - int64_t result = (volatile int64_t&)location; - while ( __TBB_machine_cmpswp8((volatile void*)&location, (int64_t)value, result) != result ) - result = (volatile int64_t&)location; - } -}; -#endif /* __TBB_WORDSIZE==4 && __TBB_64BIT_ATOMICS */ -#endif /*__TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE */ - -#if __TBB_USE_GENERIC_RELAXED_LOAD_STORE -// Relaxed operations add volatile qualifier to prevent compiler from optimizing them out. -/** Volatile should not incur any additional cost on IA32, Intel64, and Sparc TSO - architectures. However on architectures with weak memory ordering compiler may - generate code with acquire/release semantics for operations on volatile data. **/ -template -struct machine_load_store_relaxed { - static inline T load ( const volatile T& location ) { - return location; - } - static inline void store ( volatile T& location, T value ) { - location = value; - } -}; - -#if __TBB_WORDSIZE==4 && __TBB_64BIT_ATOMICS -template -struct machine_load_store_relaxed { - static inline T load ( const volatile T& location ) { - return (T)__TBB_machine_load8( (const volatile void*)&location ); - } - static inline void store ( volatile T& location, T value ) { - __TBB_machine_store8( (volatile void*)&location, (int64_t)value ); - } -}; -#endif /* __TBB_WORDSIZE==4 && __TBB_64BIT_ATOMICS */ -#endif /* __TBB_USE_GENERIC_RELAXED_LOAD_STORE */ - -#undef __TBB_WORDSIZE //this macro is forbidden to use outside of atomic machinery - -template -inline T __TBB_load_with_acquire(const volatile T &location) { - return machine_load_store::load_with_acquire( location ); -} -template -inline void __TBB_store_with_release(volatile T& location, V value) { - machine_load_store::store_with_release( location, T(value) ); -} -//! Overload that exists solely to avoid /Wp64 warnings. -inline void __TBB_store_with_release(volatile size_t& location, size_t value) { - machine_load_store::store_with_release( location, value ); -} - -template -inline T __TBB_load_full_fence(const volatile T &location) { - return machine_load_store_seq_cst::load( location ); -} -template -inline void __TBB_store_full_fence(volatile T& location, V value) { - machine_load_store_seq_cst::store( location, T(value) ); -} -//! Overload that exists solely to avoid /Wp64 warnings. -inline void __TBB_store_full_fence(volatile size_t& location, size_t value) { - machine_load_store_seq_cst::store( location, value ); -} - -template -inline T __TBB_load_relaxed (const volatile T& location) { - return machine_load_store_relaxed::load( const_cast(location) ); -} -template -inline void __TBB_store_relaxed ( volatile T& location, V value ) { - machine_load_store_relaxed::store( const_cast(location), T(value) ); -} -//! Overload that exists solely to avoid /Wp64 warnings. -inline void __TBB_store_relaxed ( volatile size_t& location, size_t value ) { - machine_load_store_relaxed::store( const_cast(location), value ); -} - -// Macro __TBB_TypeWithAlignmentAtLeastAsStrict(T) should be a type with alignment at least as -// strict as type T. The type should have a trivial default constructor and destructor, so that -// arrays of that type can be declared without initializers. -// It is correct (but perhaps a waste of space) if __TBB_TypeWithAlignmentAtLeastAsStrict(T) expands -// to a type bigger than T. -// The default definition here works on machines where integers are naturally aligned and the -// strictest alignment is 64. -#ifndef __TBB_TypeWithAlignmentAtLeastAsStrict - -#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 { \ - uint32_t member[PowerOf2/sizeof(uint32_t)]; \ -} __attribute__((aligned(PowerOf2))); -#define __TBB_alignof(T) __alignof__(T) - -#elif __TBB_DECLSPEC_ALIGN_PRESENT - -#define __TBB_DefineTypeWithAlignment(PowerOf2) \ -__declspec(align(PowerOf2)) \ -struct __TBB_machine_type_with_alignment_##PowerOf2 { \ - uint32_t member[PowerOf2/sizeof(uint32_t)]; \ -}; -#define __TBB_alignof(T) __alignof(T) - -#else /* A compiler with unknown syntax for data alignment */ -#error Must define __TBB_TypeWithAlignmentAtLeastAsStrict(T) -#endif - -/* Now declare types aligned to useful powers of two */ -// TODO: Is __TBB_DefineTypeWithAlignment(8) needed on 32 bit platforms? -__TBB_DefineTypeWithAlignment(16) -__TBB_DefineTypeWithAlignment(32) -__TBB_DefineTypeWithAlignment(64) - -typedef __TBB_machine_type_with_alignment_64 __TBB_machine_type_with_strictest_alignment; - -// Primary template is a declaration of incomplete type so that it fails with unknown alignments -template struct type_with_alignment; - -// Specializations for allowed alignments -template<> struct type_with_alignment<1> { char member; }; -template<> struct type_with_alignment<2> { uint16_t member; }; -template<> struct type_with_alignment<4> { uint32_t member; }; -template<> struct type_with_alignment<8> { uint64_t member; }; -template<> struct type_with_alignment<16> {__TBB_machine_type_with_alignment_16 member; }; -template<> struct type_with_alignment<32> {__TBB_machine_type_with_alignment_32 member; }; -template<> struct type_with_alignment<64> {__TBB_machine_type_with_alignment_64 member; }; - -#if __TBB_ALIGNOF_NOT_INSTANTIATED_TYPES_BROKEN -//! Work around for bug in GNU 3.2 and MSVC compilers. -/** Bug is that compiler sometimes returns 0 for __alignof(T) when T has not yet been instantiated. - The work-around forces instantiation by forcing computation of sizeof(T) before __alignof(T). */ -template -struct work_around_alignment_bug { - static const size_t alignment = __TBB_alignof(T); -}; -#define __TBB_TypeWithAlignmentAtLeastAsStrict(T) tbb::internal::type_with_alignment::alignment> -#else -#define __TBB_TypeWithAlignmentAtLeastAsStrict(T) tbb::internal::type_with_alignment<__TBB_alignof(T)> -#endif /* __TBB_ALIGNOF_NOT_INSTANTIATED_TYPES_BROKEN */ - -#endif /* __TBB_TypeWithAlignmentAtLeastAsStrict */ - -// Template class here is to avoid instantiation of the static data for modules that don't use it -template -struct reverse { - static const T byte_table[256]; -}; -// An efficient implementation of the reverse function utilizes a 2^8 lookup table holding the bit-reversed -// values of [0..2^8 - 1]. Those values can also be computed on the fly at a slightly higher cost. -template -const T reverse::byte_table[256] = { - 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0, - 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8, - 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4, 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4, - 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC, - 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2, 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2, - 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA, - 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6, - 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE, 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE, - 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1, 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1, - 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9, - 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5, 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5, - 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED, 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD, - 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3, - 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB, 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB, - 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7, - 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF -}; - -} // namespace internal @endcond -} // namespace tbb - -// Preserving access to legacy APIs -using tbb::internal::__TBB_load_with_acquire; -using tbb::internal::__TBB_store_with_release; - -// Mapping historically used names to the ones expected by atomic_load_store_traits -#define __TBB_load_acquire __TBB_load_with_acquire -#define __TBB_store_release __TBB_store_with_release - -#ifndef __TBB_Log2 -inline intptr_t __TBB_Log2( uintptr_t x ) { - if( x==0 ) return -1; - intptr_t result = 0; - -#if !defined(_M_ARM) - uintptr_t tmp_; - if( sizeof(x)>4 && (tmp_ = ((uint64_t)x)>>32) ) { x=tmp_; result += 32; } -#endif - if( uintptr_t tmp = x>>16 ) { x=tmp; result += 16; } - if( uintptr_t tmp = x>>8 ) { x=tmp; result += 8; } - if( uintptr_t tmp = x>>4 ) { x=tmp; result += 4; } - if( uintptr_t tmp = x>>2 ) { x=tmp; result += 2; } - - return (x&2)? result+1: result; -} -#endif - -#ifndef __TBB_AtomicOR -inline void __TBB_AtomicOR( volatile void *operand, uintptr_t addend ) { - for( tbb::internal::atomic_backoff b;;b.pause() ) { - uintptr_t tmp = *(volatile uintptr_t *)operand; - uintptr_t result = __TBB_CompareAndSwapW(operand, tmp|addend, tmp); - if( result==tmp ) break; - } -} -#endif - -#ifndef __TBB_AtomicAND -inline void __TBB_AtomicAND( volatile void *operand, uintptr_t addend ) { - for( tbb::internal::atomic_backoff b;;b.pause() ) { - uintptr_t tmp = *(volatile uintptr_t *)operand; - uintptr_t result = __TBB_CompareAndSwapW(operand, tmp&addend, tmp); - if( result==tmp ) break; - } -} -#endif - -#if __TBB_PREFETCHING -#ifndef __TBB_cl_prefetch -#error This platform does not define cache management primitives required for __TBB_PREFETCHING -#endif - -#ifndef __TBB_cl_evict -#define __TBB_cl_evict(p) -#endif -#endif - -#ifndef __TBB_Flag -typedef unsigned char __TBB_Flag; -#endif -typedef __TBB_atomic __TBB_Flag __TBB_atomic_flag; - -#ifndef __TBB_TryLockByte -inline bool __TBB_TryLockByte( __TBB_atomic_flag &flag ) { - return __TBB_machine_cmpswp1(&flag,1,0)==0; -} -#endif - -#ifndef __TBB_LockByte -inline __TBB_Flag __TBB_LockByte( __TBB_atomic_flag& flag ) { - tbb::internal::atomic_backoff backoff; - while( !__TBB_TryLockByte(flag) ) backoff.pause(); - return 0; -} -#endif - -#ifndef __TBB_UnlockByte -#define __TBB_UnlockByte(addr) __TBB_store_with_release((addr),0) -#endif - -// 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(); } - -inline bool __TBB_TryLockByteElided( __TBB_atomic_flag& flag ) { - bool res = __TBB_machine_try_lock_elided( &flag )!=0; - // to avoid the "lemming" effect, we need to abort the transaction - // if __TBB_machine_try_lock_elided returns false (i.e., someone else - // has acquired the mutex non-speculatively). - if( !res ) __TBB_TryLockByteElidedCancel(); - return res; -} - -inline void __TBB_LockByteElided( __TBB_atomic_flag& flag ) -{ - for(;;) { - tbb::internal::spin_wait_while_eq( flag, 1 ); - if( __TBB_machine_try_lock_elided( &flag ) ) - return; - // Another thread acquired the lock "for real". - // To avoid the "lemming" effect, we abort the transaction. - __TBB_TryLockByteElidedCancel(); - } -} - -inline void __TBB_UnlockByteElided( __TBB_atomic_flag& flag ) { - __TBB_machine_unlock_elided( &flag ); -} -#endif - -#ifndef __TBB_ReverseByte -inline unsigned char __TBB_ReverseByte(unsigned char src) { - return tbb::internal::reverse::byte_table[src]; -} -#endif - -template -T __TBB_ReverseBits(T src) { - T dst; - unsigned char *original = (unsigned char *) &src; - unsigned char *reversed = (unsigned char *) &dst; - - for( int i = sizeof(T)-1; i >= 0; i-- ) - reversed[i] = __TBB_ReverseByte( original[sizeof(T)-i-1] ); - - return dst; -} - -#endif /* __TBB_machine_H */ diff --git a/lib/3rdParty/tbb/include/tbb/tbb_profiling.h b/lib/3rdParty/tbb/include/tbb/tbb_profiling.h deleted file mode 100644 index ffaf98b9..00000000 --- a/lib/3rdParty/tbb/include/tbb/tbb_profiling.h +++ /dev/null @@ -1,284 +0,0 @@ -/* - 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_profiling_H -#define __TBB_profiling_H - -namespace tbb { - namespace internal { - - // - // This is not under __TBB_ITT_STRUCTURE_API because these values are used directly in flow_graph.h. - // - - // include list of index names - #define TBB_STRING_RESOURCE(index_name,str) index_name, - enum string_index { - #include "internal/_tbb_strings.h" - NUM_STRINGS - }; - #undef TBB_STRING_RESOURCE - - enum itt_relation - { - __itt_relation_is_unknown = 0, - __itt_relation_is_dependent_on, /**< "A is dependent on B" means that A cannot start until B completes */ - __itt_relation_is_sibling_of, /**< "A is sibling of B" means that A and B were created as a group */ - __itt_relation_is_parent_of, /**< "A is parent of B" means that A created B */ - __itt_relation_is_continuation_of, /**< "A is continuation of B" means that A assumes the dependencies of B */ - __itt_relation_is_child_of, /**< "A is child of B" means that A was created by B (inverse of is_parent_of) */ - __itt_relation_is_continued_by, /**< "A is continued by B" means that B assumes the dependencies of A (inverse of is_continuation_of) */ - __itt_relation_is_predecessor_to /**< "A is predecessor to B" means that B cannot start until A completes (inverse of is_dependent_on) */ - }; - - } -} - -// Check if the tools support is enabled -#if (_WIN32||_WIN64||__linux__) && !__MINGW32__ && TBB_USE_THREADING_TOOLS - -#if _WIN32||_WIN64 -#include /* mbstowcs_s */ -#endif -#include "tbb_stddef.h" - -namespace tbb { - namespace internal { - -#if _WIN32||_WIN64 - void __TBB_EXPORTED_FUNC itt_set_sync_name_v3( void *obj, const wchar_t* name ); - inline size_t multibyte_to_widechar( wchar_t* wcs, const char* mbs, size_t bufsize) { -#if _MSC_VER>=1400 - size_t len; - mbstowcs_s( &len, wcs, bufsize, mbs, _TRUNCATE ); - return len; // mbstowcs_s counts null terminator -#else - size_t len = mbstowcs( wcs, mbs, bufsize ); - if(wcs && len!=size_t(-1) ) - wcs[len - inline void itt_store_word_with_release(tbb::atomic& dst, U src) { -#if TBB_USE_THREADING_TOOLS - // This assertion should be replaced with static_assert - __TBB_ASSERT(sizeof(T) == sizeof(void *), "Type must be word-sized."); - itt_store_pointer_with_release_v3(&dst, (void *)uintptr_t(src)); -#else - dst = src; -#endif // TBB_USE_THREADING_TOOLS - } - - template - inline T itt_load_word_with_acquire(const tbb::atomic& src) { -#if TBB_USE_THREADING_TOOLS - // This assertion should be replaced with static_assert - __TBB_ASSERT(sizeof(T) == sizeof(void *), "Type must be word-sized."); -#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) - // Workaround for overzealous compiler warnings - #pragma warning (push) - #pragma warning (disable: 4311) -#endif - T result = (T)itt_load_pointer_with_acquire_v3(&src); -#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) - #pragma warning (pop) -#endif - return result; -#else - return src; -#endif // TBB_USE_THREADING_TOOLS - } - - template - inline void itt_store_word_with_release(T& dst, T src) { -#if TBB_USE_THREADING_TOOLS - // This assertion should be replaced with static_assert - __TBB_ASSERT(sizeof(T) == sizeof(void *), "Type must be word-sized."); - itt_store_pointer_with_release_v3(&dst, (void *)src); -#else - __TBB_store_with_release(dst, src); -#endif // TBB_USE_THREADING_TOOLS - } - - template - inline T itt_load_word_with_acquire(const T& src) { -#if TBB_USE_THREADING_TOOLS - // This assertion should be replaced with static_assert - __TBB_ASSERT(sizeof(T) == sizeof(void *), "Type must be word-sized"); - return (T)itt_load_pointer_with_acquire_v3(&src); -#else - return __TBB_load_with_acquire(src); -#endif // TBB_USE_THREADING_TOOLS - } - - template - inline void itt_hide_store_word(T& dst, T src) { -#if TBB_USE_THREADING_TOOLS - //TODO: This assertion should be replaced with static_assert - __TBB_ASSERT(sizeof(T) == sizeof(void *), "Type must be word-sized"); - itt_store_pointer_with_release_v3(&dst, (void *)src); -#else - dst = src; -#endif - } - - //TODO: rename to itt_hide_load_word_relaxed - template - inline T itt_hide_load_word(const T& src) { -#if TBB_USE_THREADING_TOOLS - //TODO: This assertion should be replaced with static_assert - __TBB_ASSERT(sizeof(T) == sizeof(void *), "Type must be word-sized."); - return (T)itt_load_pointer_v3(&src); -#else - return src; -#endif - } - -#if TBB_USE_THREADING_TOOLS - inline void call_itt_notify(notify_type t, void *ptr) { - call_itt_notify_v5((int)t, ptr); - } - -#else - inline void call_itt_notify(notify_type /*t*/, void * /*ptr*/) {} - -#endif // TBB_USE_THREADING_TOOLS - -#if __TBB_ITT_STRUCTURE_API - inline void itt_make_task_group( itt_domain_enum domain, void *group, unsigned long long group_extra, - void *parent, unsigned long long parent_extra, string_index name_index ) { - itt_make_task_group_v7( domain, group, group_extra, parent, parent_extra, name_index ); - } - - inline void itt_metadata_str_add( itt_domain_enum domain, void *addr, unsigned long long addr_extra, - string_index key, const char *value ) { - itt_metadata_str_add_v7( domain, addr, addr_extra, key, value ); - } - - inline void itt_relation_add( itt_domain_enum domain, void *addr0, unsigned long long addr0_extra, - itt_relation relation, void *addr1, unsigned long long addr1_extra ) { - itt_relation_add_v7( domain, addr0, addr0_extra, relation, addr1, addr1_extra ); - } - - inline void itt_task_begin( itt_domain_enum domain, void *task, unsigned long long task_extra, - void *parent, unsigned long long parent_extra, string_index name_index ) { - itt_task_begin_v7( domain, task, task_extra, parent, parent_extra, name_index ); - } - - inline void itt_task_end( itt_domain_enum domain ) { - itt_task_end_v7( domain ); - } - - inline void itt_region_begin( itt_domain_enum domain, void *region, unsigned long long region_extra, - void *parent, unsigned long long parent_extra, string_index name_index ) { - itt_region_begin_v9( domain, region, region_extra, parent, parent_extra, name_index ); - } - - inline void itt_region_end( itt_domain_enum domain, void *region, unsigned long long region_extra ) { - itt_region_end_v9( domain, region, region_extra ); - } -#endif // __TBB_ITT_STRUCTURE_API - - } // namespace internal -} // namespace tbb - -#endif /* __TBB_profiling_H */ diff --git a/lib/3rdParty/tbb/include/tbb/tbb_stddef.h b/lib/3rdParty/tbb/include/tbb/tbb_stddef.h deleted file mode 100644 index 236f3d83..00000000 --- a/lib/3rdParty/tbb/include/tbb/tbb_stddef.h +++ /dev/null @@ -1,542 +0,0 @@ -/* - 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_tbb_stddef_H -#define __TBB_tbb_stddef_H - -// Marketing-driven product version -#define TBB_VERSION_MAJOR 2017 -#define TBB_VERSION_MINOR 0 - -// Engineering-focused interface version -#define TBB_INTERFACE_VERSION 9107 -#define TBB_INTERFACE_VERSION_MAJOR TBB_INTERFACE_VERSION/1000 - -// The oldest major interface version still supported -// To be used in SONAME, manifests, etc. -#define TBB_COMPATIBLE_INTERFACE_VERSION 2 - -#define __TBB_STRING_AUX(x) #x -#define __TBB_STRING(x) __TBB_STRING_AUX(x) - -// We do not need defines below for resource processing on windows -#if !defined RC_INVOKED - -// Define groups for Doxygen documentation -/** - * @defgroup algorithms Algorithms - * @defgroup containers Containers - * @defgroup memory_allocation Memory Allocation - * @defgroup synchronization Synchronization - * @defgroup timing Timing - * @defgroup task_scheduling Task Scheduling - */ - -// Simple text that is displayed on the main page of Doxygen documentation. -/** - * \mainpage Main Page - * - * Click the tabs above for information about the - * - Modules (groups of functionality) implemented by the library - * - Classes provided by the library - * - Files constituting the library. - * . - * Please note that significant part of TBB functionality is implemented in the form of - * template functions, descriptions of which are not accessible on the Classes - * tab. Use Modules or Namespace/Namespace Members - * tabs to find them. - * - * Additional pieces of information can be found here - * - \subpage concepts - * . - */ - -/** \page concepts TBB concepts - - A concept is a set of requirements to a type, which are necessary and sufficient - for the type to model a particular behavior or a set of behaviors. Some concepts - are specific to a particular algorithm (e.g. algorithm body), while other ones - are common to several algorithms (e.g. range concept). - - All TBB algorithms make use of different classes implementing various concepts. - Implementation classes are supplied by the user as type arguments of template - parameters and/or as objects passed as function call arguments. The library - provides predefined implementations of some concepts (e.g. several kinds of - \ref range_req "ranges"), while other ones must always be implemented by the user. - - TBB defines a set of minimal requirements each concept must conform to. Here is - the list of different concepts hyperlinked to the corresponding requirements specifications: - - \subpage range_req - - \subpage parallel_do_body_req - - \subpage parallel_for_body_req - - \subpage parallel_reduce_body_req - - \subpage parallel_scan_body_req - - \subpage parallel_sort_iter_req -**/ - -// tbb_config.h should be included the first since it contains macro definitions used in other headers -#include "tbb_config.h" - -#if _MSC_VER >=1400 - #define __TBB_EXPORTED_FUNC __cdecl - #define __TBB_EXPORTED_METHOD __thiscall -#else - #define __TBB_EXPORTED_FUNC - #define __TBB_EXPORTED_METHOD -#endif - -#if __INTEL_COMPILER || _MSC_VER -#define __TBB_NOINLINE(decl) __declspec(noinline) decl -#elif __GNUC__ -#define __TBB_NOINLINE(decl) decl __attribute__ ((noinline)) -#else -#define __TBB_NOINLINE(decl) decl -#endif - -#if __TBB_NOEXCEPT_PRESENT -#define __TBB_NOEXCEPT(expression) noexcept(expression) -#else -#define __TBB_NOEXCEPT(expression) -#endif - -#include /* Need size_t and ptrdiff_t */ - -#if _MSC_VER - #define __TBB_tbb_windef_H - #include "internal/_tbb_windef.h" - #undef __TBB_tbb_windef_H -#endif -#if !defined(_MSC_VER) || _MSC_VER>=1600 - #include -#endif - -//! Type for an assertion handler -typedef void(*assertion_handler_type)( const char* filename, int line, const char* expression, const char * comment ); - -#if __TBBMALLOC_BUILD -namespace rml { namespace internal { - #define __TBB_ASSERT_RELEASE(predicate,message) ((predicate)?((void)0) : rml::internal::assertion_failure(__FILE__,__LINE__,#predicate,message)) -#else -namespace tbb { - #define __TBB_ASSERT_RELEASE(predicate,message) ((predicate)?((void)0) : tbb::assertion_failure(__FILE__,__LINE__,#predicate,message)) -#endif - - //! Set assertion handler and return previous value of it. - assertion_handler_type __TBB_EXPORTED_FUNC set_assertion_handler( assertion_handler_type new_handler ); - - //! Process an assertion failure. - /** Normally called from __TBB_ASSERT macro. - If assertion handler is null, print message for assertion failure and abort. - Otherwise call the assertion handler. */ - void __TBB_EXPORTED_FUNC assertion_failure( const char* filename, int line, const char* expression, const char* comment ); - -#if __TBBMALLOC_BUILD -}} // namespace rml::internal -#else -} // namespace tbb -#endif - -#if TBB_USE_ASSERT - - //! Assert that x is true. - /** If x is false, print assertion failure message. - If the comment argument is not NULL, it is printed as part of the failure message. - The comment argument has no other effect. */ - #define __TBB_ASSERT(predicate,message) __TBB_ASSERT_RELEASE(predicate,message) - - #define __TBB_ASSERT_EX __TBB_ASSERT - -#else /* !TBB_USE_ASSERT */ - - //! No-op version of __TBB_ASSERT. - #define __TBB_ASSERT(predicate,comment) ((void)0) - //! "Extended" version is useful to suppress warnings if a variable is only used with an assert - #define __TBB_ASSERT_EX(predicate,comment) ((void)(1 && (predicate))) - -#endif /* !TBB_USE_ASSERT */ - -//! The namespace tbb contains all components of the library. -namespace tbb { - - namespace internal { -#if _MSC_VER && _MSC_VER<1600 - typedef __int8 int8_t; - typedef __int16 int16_t; - typedef __int32 int32_t; - typedef __int64 int64_t; - typedef unsigned __int8 uint8_t; - typedef unsigned __int16 uint16_t; - typedef unsigned __int32 uint32_t; - typedef unsigned __int64 uint64_t; -#else /* Posix */ - using ::int8_t; - using ::int16_t; - using ::int32_t; - using ::int64_t; - using ::uint8_t; - using ::uint16_t; - using ::uint32_t; - using ::uint64_t; -#endif /* Posix */ - } // namespace internal - - using std::size_t; - using std::ptrdiff_t; - -//! The function returns the interface version of the TBB shared library being used. -/** - * The version it returns is determined at runtime, not at compile/link time. - * So it can be different than the value of TBB_INTERFACE_VERSION obtained at compile time. - */ -extern "C" int __TBB_EXPORTED_FUNC TBB_runtime_interface_version(); - -/** - * @cond INTERNAL - * @brief Identifiers declared inside namespace internal should never be used directly by client code. - */ -namespace internal { - -//! Compile-time constant that is upper bound on cache line/sector size. -/** It should be used only in situations where having a compile-time upper - bound is more useful than a run-time exact answer. - @ingroup memory_allocation */ -const size_t NFS_MaxLineSize = 128; - -/** Label for data that may be accessed from different threads, and that may eventually become wrapped - in a formal atomic type. - - Note that no problems have yet been observed relating to the definition currently being empty, - even if at least "volatile" would seem to be in order to avoid data sometimes temporarily hiding - in a register (although "volatile" as a "poor man's atomic" lacks several other features of a proper - atomic, some of which are now provided instead through specialized functions). - - Note that usage is intentionally compatible with a definition as qualifier "volatile", - both as a way to have the compiler help enforce use of the label and to quickly rule out - one potential issue. - - Note however that, with some architecture/compiler combinations, e.g. on IA-64 architecture, "volatile" - also has non-portable memory semantics that are needlessly expensive for "relaxed" operations. - - Note that this must only be applied to data that will not change bit patterns when cast to/from - an integral type of the same length; tbb::atomic must be used instead for, e.g., floating-point types. - - 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]; -}; -template struct padded_base : T {}; - -//! Pads type T to fill out to a multiple of cache line size. -template -struct padded : padded_base {}; - -//! Extended variant of the standard offsetof macro -/** The standard offsetof macro is not sufficient for TBB as it can be used for - POD-types only. The constant 0x1000 (not NULL) is necessary to appease GCC. **/ -#define __TBB_offsetof(class_name, member_name) \ - ((ptrdiff_t)&(reinterpret_cast(0x1000)->member_name) - 0x1000) - -//! Returns address of the object containing a member with the given name and address -#define __TBB_get_object_ref(class_name, member_name, member_addr) \ - (*reinterpret_cast((char*)member_addr - __TBB_offsetof(class_name, member_name))) - -//! Throws std::runtime_error with what() returning error_code description prefixed with aux_info -void __TBB_EXPORTED_FUNC handle_perror( int error_code, const char* aux_info ); - -#if TBB_USE_EXCEPTIONS - #define __TBB_TRY try - #define __TBB_CATCH(e) catch(e) - #define __TBB_THROW(e) throw e - #define __TBB_RETHROW() throw -#else /* !TBB_USE_EXCEPTIONS */ - inline bool __TBB_false() { return false; } - #define __TBB_TRY - #define __TBB_CATCH(e) if ( tbb::internal::__TBB_false() ) - #define __TBB_THROW(e) ((void)0) - #define __TBB_RETHROW() ((void)0) -#endif /* !TBB_USE_EXCEPTIONS */ - -//! Report a runtime warning. -void __TBB_EXPORTED_FUNC runtime_warning( const char* format, ... ); - -#if TBB_USE_ASSERT -static void* const poisoned_ptr = reinterpret_cast(-1); - -//! Set p to invalid pointer value. -// Also works for regular (non-__TBB_atomic) pointers. -template -inline void poison_pointer( T* __TBB_atomic & p ) { p = reinterpret_cast(poisoned_ptr); } - -/** Expected to be used in assertions only, thus no empty form is defined. **/ -template -inline bool is_poisoned( T* p ) { return p == reinterpret_cast(poisoned_ptr); } -#else -template -inline void poison_pointer( T* __TBB_atomic & ) {/*do nothing*/} -#endif /* !TBB_USE_ASSERT */ - -//! Cast between unrelated pointer types. -/** This method should be used sparingly as a last resort for dealing with - situations that inherently break strict ISO C++ aliasing rules. */ -// T is a pointer type because it will be explicitly provided by the programmer as a template argument; -// U is a referent type to enable the compiler to check that "ptr" is a pointer, deducing U in the process. -template -inline T punned_cast( U* ptr ) { - uintptr_t x = reinterpret_cast(ptr); - return reinterpret_cast(x); -} - -//! Base class for types that should not be assigned. -class no_assign { - // Deny assignment - void operator=( const no_assign& ); -public: -#if __GNUC__ - //! Explicitly define default construction, because otherwise gcc issues gratuitous warning. - no_assign() {} -#endif /* __GNUC__ */ -}; - -//! Base class for types that should not be copied or assigned. -class no_copy: no_assign { - //! Deny copy construction - no_copy( const no_copy& ); -public: - //! Allow default construction - no_copy() {} -}; - -#if TBB_DEPRECATED_MUTEX_COPYING -class mutex_copy_deprecated_and_disabled {}; -#else -// By default various implementations of mutexes are not copy constructible -// and not copy assignable. -class mutex_copy_deprecated_and_disabled : no_copy {}; -#endif - -//! A function to check if passed in pointer is aligned on a specific border -template -inline bool is_aligned(T* pointer, uintptr_t alignment) { - return 0==((uintptr_t)pointer & (alignment-1)); -} - -//! A function to check if passed integer is a power of 2 -template -inline bool is_power_of_two(integer_type arg) { - return arg && (0 == (arg & (arg - 1))); -} - -//! A function to compute arg modulo divisor where divisor is a power of 2. -template -inline argument_integer_type modulo_power_of_two(argument_integer_type arg, divisor_integer_type divisor) { - __TBB_ASSERT( is_power_of_two(divisor), "Divisor should be a power of two" ); - return (arg & (divisor - 1)); -} - - -//! A function to determine if arg is a power of 2 at least as big as another power of 2. -// i.e. for strictly positive i and j, with j being a power of 2, -// determines whether i==j< -inline bool is_power_of_two_at_least(argument_integer_type arg, power2_integer_type power2) { - __TBB_ASSERT( is_power_of_two(power2), "Divisor should be a power of two" ); - return 0 == (arg & (arg - power2)); -} - -//! Utility template function to prevent "unused" warnings by various compilers. -template void suppress_unused_warning( const T1& ) {} -template void suppress_unused_warning( const T1&, const T2& ) {} -template void suppress_unused_warning( const T1&, const T2&, const T3& ) {} - -// Struct to be used as a version tag for inline functions. -/** Version tag can be necessary to prevent loader on Linux from using the wrong - symbol in debug builds (when inline functions are compiled as out-of-line). **/ -struct version_tag_v3 {}; - -typedef version_tag_v3 version_tag; - -} // internal - -//! Dummy type that distinguishes splitting constructor from copy constructor. -/** - * See description of parallel_for and parallel_reduce for example usages. - * @ingroup algorithms - */ -class split { -}; - -//! Type enables transmission of splitting proportion from partitioners to range objects -/** - * In order to make use of such facility Range objects must implement - * splitting constructor with this type passed and initialize static - * constant boolean field 'is_splittable_in_proportion' with the value - * of 'true' - */ -class proportional_split: internal::no_assign { -public: - proportional_split(size_t _left = 1, size_t _right = 1) : my_left(_left), my_right(_right) { } - - size_t left() const { return my_left; } - size_t right() const { return my_right; } - - // used when range does not support proportional split - operator split() const { return split(); } - -#if __TBB_ENABLE_RANGE_FEEDBACK - void set_proportion(size_t _left, size_t _right) { - my_left = _left; - my_right = _right; - } -#endif -private: - size_t my_left, my_right; -}; - -} // tbb - -// Following is a set of classes and functions typically used in compile-time "metaprogramming". -// TODO: move all that to a separate header - -#if __TBB_ALLOCATOR_TRAITS_PRESENT -#include //for allocator_traits -#endif - -#if __TBB_CPP11_RVALUE_REF_PRESENT || _LIBCPP_VERSION -#include // for std::move -#endif - -namespace tbb { -namespace internal { - -//! Class for determining type of std::allocator::value_type. -template -struct allocator_type { - typedef T value_type; -}; - -#if _MSC_VER -//! Microsoft std::allocator has non-standard extension that strips const from a type. -template -struct allocator_type { - typedef T value_type; -}; -#endif - -// Ad-hoc implementation of true_type & false_type -// Intended strictly for internal use! For public APIs (traits etc), use C++11 analogues. -template -struct bool_constant { - static /*constexpr*/ const bool value = v; -}; -typedef bool_constant true_type; -typedef bool_constant false_type; - -#if __TBB_ALLOCATOR_TRAITS_PRESENT -using std::allocator_traits; -#else -template -struct allocator_traits{ - typedef tbb::internal::false_type propagate_on_container_move_assignment; -}; -#endif - -//! A template to select either 32-bit or 64-bit constant as compile time, depending on machine word size. -template -struct select_size_t_constant { - //Explicit cast is needed to avoid compiler warnings about possible truncation. - //The value of the right size, which is selected by ?:, is anyway not truncated or promoted. - static const size_t value = (size_t)((sizeof(size_t)==sizeof(u)) ? u : ull); -}; - -#if __TBB_CPP11_RVALUE_REF_PRESENT -using std::move; -using std::forward; -#elif defined(_LIBCPP_NAMESPACE) -// libc++ defines "pre-C++11 move and forward" similarly to ours; use it to avoid name conflicts in some cases. -using std::_LIBCPP_NAMESPACE::move; -using std::_LIBCPP_NAMESPACE::forward; -#else -// It is assumed that cv qualifiers, if any, are part of the deduced type. -template -T& move( T& x ) { return x; } -template -T& forward( T& x ) { return x; } -#endif /* __TBB_CPP11_RVALUE_REF_PRESENT */ - -// Helper macros to simplify writing templates working with both C++03 and C++11. -#if __TBB_CPP11_RVALUE_REF_PRESENT -#define __TBB_FORWARDING_REF(A) A&& -#else -// It is assumed that cv qualifiers, if any, are part of a deduced type. -// Thus this macro should not be used in public interfaces. -#define __TBB_FORWARDING_REF(A) A& -#endif -#if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT -#define __TBB_PARAMETER_PACK ... -#define __TBB_PACK_EXPANSION(A) A... -#else -#define __TBB_PARAMETER_PACK -#define __TBB_PACK_EXPANSION(A) A -#endif /* __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT */ - -#if __TBB_CPP11_DECLTYPE_PRESENT -#if __TBB_CPP11_DECLVAL_BROKEN -// Ad-hoc implementation of std::declval -template __TBB_FORWARDING_REF(T) declval() /*noexcept*/; -#else -using std::declval; -#endif -#endif - -template -struct STATIC_ASSERTION_FAILED; - -template <> -struct STATIC_ASSERTION_FAILED { enum {value=1};}; - -template<> -struct STATIC_ASSERTION_FAILED; //intentionally left undefined to cause compile time error - -//! @endcond -}} // namespace tbb::internal - -#if __TBB_STATIC_ASSERT_PRESENT -#define __TBB_STATIC_ASSERT(condition,msg) static_assert(condition,msg) -#else -//please note condition is intentionally inverted to get a bit more understandable error msg -#define __TBB_STATIC_ASSERT_IMPL1(condition,msg,line) \ - 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 condition, at compile time -#define __TBB_STATIC_ASSERT(condition,msg) __TBB_STATIC_ASSERT_IMPL(condition,msg,__LINE__) -#endif - -#endif /* RC_INVOKED */ -#endif /* __TBB_tbb_stddef_H */ diff --git a/lib/3rdParty/tbb/include/tbb/tbb_thread.h b/lib/3rdParty/tbb/include/tbb/tbb_thread.h deleted file mode 100644 index d1cafd65..00000000 --- a/lib/3rdParty/tbb/include/tbb/tbb_thread.h +++ /dev/null @@ -1,342 +0,0 @@ -/* - 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_tbb_thread_H -#define __TBB_tbb_thread_H - -#include "tbb_stddef.h" - -#if _WIN32||_WIN64 -#include "machine/windows_api.h" -#define __TBB_NATIVE_THREAD_ROUTINE unsigned WINAPI -#define __TBB_NATIVE_THREAD_ROUTINE_PTR(r) unsigned (WINAPI* r)( void* ) -namespace tbb { namespace internal { -#if __TBB_WIN8UI_SUPPORT - typedef size_t thread_id_type; -#else // __TBB_WIN8UI_SUPPORT - typedef DWORD thread_id_type; -#endif // __TBB_WIN8UI_SUPPORT -}} //namespace tbb::internal -#else -#define __TBB_NATIVE_THREAD_ROUTINE void* -#define __TBB_NATIVE_THREAD_ROUTINE_PTR(r) void* (*r)( void* ) -#include -namespace tbb { namespace internal { - typedef pthread_t thread_id_type; -}} //namespace tbb::internal -#endif // _WIN32||_WIN64 - -#include "atomic.h" -#include "internal/_tbb_hash_compare_impl.h" -#include "tick_count.h" - -#if !TBB_USE_EXCEPTIONS && _MSC_VER - // Suppress "C++ exception handler used, but unwind semantics are not enabled" warning in STL headers - #pragma warning (push) - #pragma warning (disable: 4530) -#endif - -#include __TBB_STD_SWAP_HEADER -#include - -#if !TBB_USE_EXCEPTIONS && _MSC_VER - #pragma warning (pop) -#endif - -namespace tbb { - -namespace internal { - class tbb_thread_v3; -} - -inline void swap( internal::tbb_thread_v3& t1, internal::tbb_thread_v3& t2 ) __TBB_NOEXCEPT(true); - -namespace internal { - - //! Allocate a closure - void* __TBB_EXPORTED_FUNC allocate_closure_v3( size_t size ); - //! Free a closure allocated by allocate_closure_v3 - void __TBB_EXPORTED_FUNC free_closure_v3( void* ); - - struct thread_closure_base { - void* operator new( size_t size ) {return allocate_closure_v3(size);} - void operator delete( void* ptr ) {free_closure_v3(ptr);} - }; - - template struct thread_closure_0: thread_closure_base { - F function; - - static __TBB_NATIVE_THREAD_ROUTINE start_routine( void* c ) { - thread_closure_0 *self = static_cast(c); - self->function(); - delete self; - return 0; - } - thread_closure_0( const F& f ) : function(f) {} - }; - //! Structure used to pass user function with 1 argument to thread. - template struct thread_closure_1: thread_closure_base { - F function; - X arg1; - //! Routine passed to Windows's _beginthreadex by thread::internal_start() inside tbb.dll - static __TBB_NATIVE_THREAD_ROUTINE start_routine( void* c ) { - thread_closure_1 *self = static_cast(c); - self->function(self->arg1); - delete self; - return 0; - } - thread_closure_1( const F& f, const X& x ) : function(f), arg1(x) {} - }; - template struct thread_closure_2: thread_closure_base { - F function; - X arg1; - Y arg2; - //! Routine passed to Windows's _beginthreadex by thread::internal_start() inside tbb.dll - static __TBB_NATIVE_THREAD_ROUTINE start_routine( void* c ) { - thread_closure_2 *self = static_cast(c); - self->function(self->arg1, self->arg2); - delete self; - return 0; - } - thread_closure_2( const F& f, const X& x, const Y& y ) : function(f), arg1(x), arg2(y) {} - }; - - //! Versioned thread class. - class tbb_thread_v3 { -#if __TBB_IF_NO_COPY_CTOR_MOVE_SEMANTICS_BROKEN - // Workaround for a compiler bug: declaring the copy constructor as public - // enables use of the moving constructor. - // The definition is not provided in order to prohibit copying. - public: -#endif - tbb_thread_v3(const tbb_thread_v3&); // = delete; // Deny access - public: -#if _WIN32||_WIN64 - typedef HANDLE native_handle_type; -#else - typedef pthread_t native_handle_type; -#endif // _WIN32||_WIN64 - - class id; - //! Constructs a thread object that does not represent a thread of execution. - tbb_thread_v3() __TBB_NOEXCEPT(true) : my_handle(0) -#if _WIN32||_WIN64 - , my_thread_id(0) -#endif // _WIN32||_WIN64 - {} - - //! Constructs an object and executes f() in a new thread - template explicit tbb_thread_v3(F f) { - typedef internal::thread_closure_0 closure_type; - internal_start(closure_type::start_routine, new closure_type(f)); - } - //! Constructs an object and executes f(x) in a new thread - template tbb_thread_v3(F f, X x) { - typedef internal::thread_closure_1 closure_type; - internal_start(closure_type::start_routine, new closure_type(f,x)); - } - //! Constructs an object and executes f(x,y) in a new thread - template tbb_thread_v3(F f, X x, Y y) { - typedef internal::thread_closure_2 closure_type; - internal_start(closure_type::start_routine, new closure_type(f,x,y)); - } - -#if __TBB_CPP11_RVALUE_REF_PRESENT - tbb_thread_v3(tbb_thread_v3&& x) __TBB_NOEXCEPT(true) - : my_handle(x.my_handle) -#if _WIN32||_WIN64 - , my_thread_id(x.my_thread_id) -#endif - { - x.internal_wipe(); - } - tbb_thread_v3& operator=(tbb_thread_v3&& x) __TBB_NOEXCEPT(true) { - internal_move(x); - return *this; - } - private: - tbb_thread_v3& operator=(const tbb_thread_v3& x); // = delete; - public: -#else // __TBB_CPP11_RVALUE_REF_PRESENT - tbb_thread_v3& operator=(tbb_thread_v3& x) { - internal_move(x); - return *this; - } -#endif // __TBB_CPP11_RVALUE_REF_PRESENT - - void swap( tbb_thread_v3& t ) __TBB_NOEXCEPT(true) {tbb::swap( *this, t );} - bool joinable() const __TBB_NOEXCEPT(true) {return my_handle!=0; } - //! The completion of the thread represented by *this happens before join() returns. - void __TBB_EXPORTED_METHOD join(); - //! When detach() returns, *this no longer represents the possibly continuing thread of execution. - void __TBB_EXPORTED_METHOD detach(); - ~tbb_thread_v3() {if( joinable() ) detach();} - inline id get_id() const __TBB_NOEXCEPT(true); - native_handle_type native_handle() { return my_handle; } - - //! The number of hardware thread contexts. - /** Before TBB 3.0 U4 this methods returned the number of logical CPU in - the system. Currently on Windows, Linux and FreeBSD it returns the - number of logical CPUs available to the current process in accordance - with its affinity mask. - - NOTE: The return value of this method never changes after its first - invocation. This means that changes in the process affinity mask that - took place after this method was first invoked will not affect the - number of worker threads in the TBB worker threads pool. **/ - static unsigned __TBB_EXPORTED_FUNC hardware_concurrency() __TBB_NOEXCEPT(true); - private: - native_handle_type my_handle; -#if _WIN32||_WIN64 - thread_id_type my_thread_id; -#endif // _WIN32||_WIN64 - - void internal_wipe() __TBB_NOEXCEPT(true) { - my_handle = 0; -#if _WIN32||_WIN64 - my_thread_id = 0; -#endif - } - void internal_move(tbb_thread_v3& x) __TBB_NOEXCEPT(true) { - if (joinable()) detach(); - my_handle = x.my_handle; -#if _WIN32||_WIN64 - my_thread_id = x.my_thread_id; -#endif // _WIN32||_WIN64 - x.internal_wipe(); - } - - /** Runs start_routine(closure) on another thread and sets my_handle to the handle of the created thread. */ - void __TBB_EXPORTED_METHOD internal_start( __TBB_NATIVE_THREAD_ROUTINE_PTR(start_routine), - void* closure ); - friend void __TBB_EXPORTED_FUNC move_v3( tbb_thread_v3& t1, tbb_thread_v3& t2 ); - friend void tbb::swap( tbb_thread_v3& t1, tbb_thread_v3& t2 ) __TBB_NOEXCEPT(true); - }; - - class tbb_thread_v3::id { - thread_id_type my_id; - id( thread_id_type id_ ) : my_id(id_) {} - - friend class tbb_thread_v3; - public: - id() __TBB_NOEXCEPT(true) : my_id(0) {} - - friend bool operator==( tbb_thread_v3::id x, tbb_thread_v3::id y ) __TBB_NOEXCEPT(true); - friend bool operator!=( tbb_thread_v3::id x, tbb_thread_v3::id y ) __TBB_NOEXCEPT(true); - friend bool operator<( tbb_thread_v3::id x, tbb_thread_v3::id y ) __TBB_NOEXCEPT(true); - friend bool operator<=( tbb_thread_v3::id x, tbb_thread_v3::id y ) __TBB_NOEXCEPT(true); - friend bool operator>( tbb_thread_v3::id x, tbb_thread_v3::id y ) __TBB_NOEXCEPT(true); - friend bool operator>=( tbb_thread_v3::id x, tbb_thread_v3::id y ) __TBB_NOEXCEPT(true); - - template - friend std::basic_ostream& - operator<< (std::basic_ostream &out, - tbb_thread_v3::id id) - { - out << id.my_id; - return out; - } - friend tbb_thread_v3::id __TBB_EXPORTED_FUNC thread_get_id_v3(); - - friend inline size_t tbb_hasher( const tbb_thread_v3::id& id ) { - __TBB_STATIC_ASSERT(sizeof(id.my_id) <= sizeof(size_t), "Implementaion assumes that thread_id_type fits into machine word"); - return tbb::tbb_hasher(id.my_id); - } - - // A workaround for lack of tbb::atomic (which would require id to be POD in C++03). - friend id atomic_compare_and_swap(id& location, const id& value, const id& comparand){ - return as_atomic(location.my_id).compare_and_swap(value.my_id, comparand.my_id); - } - }; // tbb_thread_v3::id - - tbb_thread_v3::id tbb_thread_v3::get_id() const __TBB_NOEXCEPT(true) { -#if _WIN32||_WIN64 - return id(my_thread_id); -#else - return id(my_handle); -#endif // _WIN32||_WIN64 - } - - void __TBB_EXPORTED_FUNC move_v3( tbb_thread_v3& t1, tbb_thread_v3& t2 ); - tbb_thread_v3::id __TBB_EXPORTED_FUNC thread_get_id_v3(); - void __TBB_EXPORTED_FUNC thread_yield_v3(); - void __TBB_EXPORTED_FUNC thread_sleep_v3(const tick_count::interval_t &i); - - inline bool operator==(tbb_thread_v3::id x, tbb_thread_v3::id y) __TBB_NOEXCEPT(true) - { - return x.my_id == y.my_id; - } - inline bool operator!=(tbb_thread_v3::id x, tbb_thread_v3::id y) __TBB_NOEXCEPT(true) - { - return x.my_id != y.my_id; - } - inline bool operator<(tbb_thread_v3::id x, tbb_thread_v3::id y) __TBB_NOEXCEPT(true) - { - return x.my_id < y.my_id; - } - inline bool operator<=(tbb_thread_v3::id x, tbb_thread_v3::id y) __TBB_NOEXCEPT(true) - { - return x.my_id <= y.my_id; - } - inline bool operator>(tbb_thread_v3::id x, tbb_thread_v3::id y) __TBB_NOEXCEPT(true) - { - return x.my_id > y.my_id; - } - inline bool operator>=(tbb_thread_v3::id x, tbb_thread_v3::id y) __TBB_NOEXCEPT(true) - { - return x.my_id >= y.my_id; - } - -} // namespace internal; - -//! Users reference thread class by name tbb_thread -typedef internal::tbb_thread_v3 tbb_thread; - -using internal::operator==; -using internal::operator!=; -using internal::operator<; -using internal::operator>; -using internal::operator<=; -using internal::operator>=; - -inline void move( tbb_thread& t1, tbb_thread& t2 ) { - internal::move_v3(t1, t2); -} - -inline void swap( internal::tbb_thread_v3& t1, internal::tbb_thread_v3& t2 ) __TBB_NOEXCEPT(true) { - std::swap(t1.my_handle, t2.my_handle); -#if _WIN32||_WIN64 - std::swap(t1.my_thread_id, t2.my_thread_id); -#endif /* _WIN32||_WIN64 */ -} - -namespace this_tbb_thread { - inline tbb_thread::id get_id() { return internal::thread_get_id_v3(); } - //! Offers the operating system the opportunity to schedule another thread. - inline void yield() { internal::thread_yield_v3(); } - //! The current thread blocks at least until the time specified. - inline void sleep(const tick_count::interval_t &i) { - internal::thread_sleep_v3(i); - } -} // namespace this_tbb_thread - -} // namespace tbb - -#endif /* __TBB_tbb_thread_H */ diff --git a/lib/3rdParty/tbb/include/tbb/tbbmalloc_proxy.h b/lib/3rdParty/tbb/include/tbb/tbbmalloc_proxy.h deleted file mode 100644 index 76cbd6d7..00000000 --- a/lib/3rdParty/tbb/include/tbb/tbbmalloc_proxy.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - 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. - - - - -*/ - -/* -Replacing the standard memory allocation routines in Microsoft* C/C++ RTL -(malloc/free, global new/delete, etc.) with the TBB memory allocator. - -Include the following header to a source of any binary which is loaded during -application startup - -#include "tbb/tbbmalloc_proxy.h" - -or add following parameters to the linker options for the binary which is -loaded during application startup. It can be either exe-file or dll. - -For win32 -tbbmalloc_proxy.lib /INCLUDE:"___TBB_malloc_proxy" -win64 -tbbmalloc_proxy.lib /INCLUDE:"__TBB_malloc_proxy" -*/ - -#ifndef __TBB_tbbmalloc_proxy_H -#define __TBB_tbbmalloc_proxy_H - -#if _MSC_VER - -#ifdef _DEBUG - #pragma comment(lib, "tbbmalloc_proxy_debug.lib") -#else - #pragma comment(lib, "tbbmalloc_proxy.lib") -#endif - -#if defined(_WIN64) - #pragma comment(linker, "/include:__TBB_malloc_proxy") -#else - #pragma comment(linker, "/include:___TBB_malloc_proxy") -#endif - -#else -/* Primarily to support MinGW */ - -extern "C" void __TBB_malloc_proxy(); -struct __TBB_malloc_proxy_caller { - __TBB_malloc_proxy_caller() { __TBB_malloc_proxy(); } -} volatile __TBB_malloc_proxy_helper_object; - -#endif // _MSC_VER - -#endif //__TBB_tbbmalloc_proxy_H diff --git a/lib/3rdParty/tbb/include/tbb/tick_count.h b/lib/3rdParty/tbb/include/tbb/tick_count.h deleted file mode 100644 index a7f4e0f3..00000000 --- a/lib/3rdParty/tbb/include/tbb/tick_count.h +++ /dev/null @@ -1,140 +0,0 @@ -/* - 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_tick_count_H -#define __TBB_tick_count_H - -#include "tbb_stddef.h" - -#if _WIN32||_WIN64 -#include "machine/windows_api.h" -#elif __linux__ -#include -#else /* generic Unix */ -#include -#endif /* (choice of OS) */ - -namespace tbb { - -//! Absolute timestamp -/** @ingroup timing */ -class tick_count { -public: - //! Relative time interval. - class interval_t { - long long value; - explicit interval_t( long long value_ ) : value(value_) {} - public: - //! Construct a time interval representing zero time duration - interval_t() : value(0) {}; - - //! Construct a time interval representing sec seconds time duration - explicit interval_t( double sec ); - - //! Return the length of a time interval in seconds - double seconds() const; - - friend class tbb::tick_count; - - //! Extract the intervals from the tick_counts and subtract them. - friend interval_t operator-( const tick_count& t1, const tick_count& t0 ); - - //! Add two intervals. - friend interval_t operator+( const interval_t& i, const interval_t& j ) { - return interval_t(i.value+j.value); - } - - //! Subtract two intervals. - friend interval_t operator-( const interval_t& i, const interval_t& j ) { - return interval_t(i.value-j.value); - } - - //! Accumulation operator - interval_t& operator+=( const interval_t& i ) {value += i.value; return *this;} - - //! Subtraction operator - interval_t& operator-=( const interval_t& i ) {value -= i.value; return *this;} - private: - static long long ticks_per_second(){ -#if _WIN32||_WIN64 - LARGE_INTEGER qpfreq; - int rval = QueryPerformanceFrequency(&qpfreq); - __TBB_ASSERT_EX(rval, "QueryPerformanceFrequency returned zero"); - return static_cast(qpfreq.QuadPart); -#elif __linux__ - return static_cast(1E9); -#else /* generic Unix */ - return static_cast(1E6); -#endif /* (choice of OS) */ - } - }; - - //! Construct an absolute timestamp initialized to zero. - tick_count() : my_count(0) {}; - - //! Return current time. - static tick_count now(); - - //! Subtract two timestamps to get the time interval between - friend interval_t operator-( const tick_count& t1, const tick_count& t0 ); - - //! Return the resolution of the clock in seconds per tick. - static double resolution() { return 1.0 / interval_t::ticks_per_second(); } - -private: - long long my_count; -}; - -inline tick_count tick_count::now() { - tick_count result; -#if _WIN32||_WIN64 - LARGE_INTEGER qpcnt; - int rval = QueryPerformanceCounter(&qpcnt); - __TBB_ASSERT_EX(rval, "QueryPerformanceCounter failed"); - result.my_count = qpcnt.QuadPart; -#elif __linux__ - struct timespec ts; - int status = clock_gettime( CLOCK_REALTIME, &ts ); - __TBB_ASSERT_EX( status==0, "CLOCK_REALTIME not supported" ); - result.my_count = static_cast(1000000000UL)*static_cast(ts.tv_sec) + static_cast(ts.tv_nsec); -#else /* generic Unix */ - struct timeval tv; - int status = gettimeofday(&tv, NULL); - __TBB_ASSERT_EX( status==0, "gettimeofday failed" ); - result.my_count = static_cast(1000000)*static_cast(tv.tv_sec) + static_cast(tv.tv_usec); -#endif /*(choice of OS) */ - return result; -} - -inline tick_count::interval_t::interval_t( double sec ) { - value = static_cast(sec*interval_t::ticks_per_second()); -} - -inline tick_count::interval_t operator-( const tick_count& t1, const tick_count& t0 ) { - return tick_count::interval_t( t1.my_count-t0.my_count ); -} - -inline double tick_count::interval_t::seconds() const { - return value*tick_count::resolution(); -} - -} // namespace tbb - -#endif /* __TBB_tick_count_H */ diff --git a/lib/3rdParty/tbb/index.html b/lib/3rdParty/tbb/index.html deleted file mode 100644 index 13f29bc8..00000000 --- a/lib/3rdParty/tbb/index.html +++ /dev/null @@ -1,50 +0,0 @@ - - -

    Overview

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

    Common directories

    -
    -
    doc -
    Documentation for the library. -
    include -
    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

    -

    -To build Intel TBB, use the top-level Makefile; see also the build directions. -To port Intel TBB to a new platform, operating system or architecture, see the porting directions. -

    -

    Files

    -
    -
    Makefile -
    Top-level Makefile for Intel TBB. See also the build directions. -
    -

    Directories

    -
    -
    src -
    Source code for the library. -
    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 macOS*. For Windows* OS: start-up scripts and dynamic-link libraries. -
    lib -
    Platform-specific binary files for the library. -
    -
    -

    -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. -

    -* Other names and brands may be claimed as the property of others. - - diff --git a/lib/3rdParty/tbb/lib/x64/v140/irml/irml.lib b/lib/3rdParty/tbb/lib/x64/v140/irml/irml.lib deleted file mode 100644 index 8228932b8639e2dbd7235bc98401d9226f3956c5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2934 zcmb_e&rcIU6#n{y(k@1bdeLaCgrHs!N?RZ?q+m@Xw1t%7g~L$WB8@FeN>w;{<7D_F zym=>{IU5d!qX+*I6MS!X-1mPB^1Y1Hdp49tR>>U~nHWM(r9q2DlDI>>49ISL4X8(NiFLs?<_`b){HR z+1G2Yic71dm7=P*nhhvbSkL9IYVn2DwzBkQy|ApZ3#A1zFXnT~+^y}Xt#YMpwhl;C zZ|*9sf^91ebFZc~zN{%NE~;kvLrpR8Uaj@1)^dNY*DdE)yMCe9@qa4iMniqBx3^XE zz`;@Voh{P?=3~Tv_EFor;cIkbCd_o05F;v#hk-1`dw&oZC2ky(Ffv3k>W^rC8nx(x z0Ad(K5CaG!iikCnafp`Nl@q?+E2ZDtE=01KaXHu;8eJ0`Jq3E$Z6T=M>kfG@yV%ia z`F@SN_SZV6^_j)#Hc@Rfgd5kM4znFjR1ZTa-2eVI5};fsesGzn*4}-5KelGifO#5x zm5I}5FtRvNua?{8v4p7Z(cmZ5KaL!j$PUjgO8-YRKNg?SvDNRHPe!F=n>Zsmqb`;VGLlhAk+a>IOq`zW`n$Ki z?CS$U?+*{tvZZl;!*Ets5Ba2eX00zw(eu4(B!rMbudz%`$(zcH`cNA_su=ZBpmd8QgcQU?LJOo+W5Qvq{UePnOG?FX^2Uh| zq8C1a2R?$~G+%C4wignUrngOJteLrV zI%`dP`BRF_%x2W=Lju4ZAhrMucYu*&AhEByK_m6iy3^xF0Qbb1)8k2^lR~T%Hr9(J zvHW`TRdHpbv|bdAcB?6>wU1vuL5Q`t`TRv4eCsJWDy27X*H*>yVrh{U6$^P`@78ui zyh7iLo3`@$LN9njB_y|0M5c(S)04fI`{*Y_H6cQml5H4}&E==`a z_aN+du_w`@KEz#Twa)3FEbAp;s@iN$nqgJLn#y*oM)fd?tp`8ejYmK+cUnqj{KTdr zu}l*x7oL{G*ix!dEqBTjX;*NMCcmivRg5T&IZT}>y{uwmj3x%zbM=^?gLy(F3ik+iyJ;U8GLa*Fjis^H@HC|{`+V-AZ@0ibvFU10@k7NM(S^*GFb!XMRmcVJ#o zJQ#RS-_YC}kVe;unzS|3hZ;ko=BMsJSULTqeE` z$&Y~#Uc!r*@O(?prTcEq$+tgb!HKs1<^uA~QkNw2mGiB?<&bmpE#vYzuYbFQ8d>iq zZul~{YmyJwiOj59&P@Ib;+(A>a!pIgv&JZrflre+obZz2(Y0n(aDCRFlJy8x8~w}Y zwSp^S%ChuUxtbW#>czjQ|F-G=R`^c(m~2M7Ha+j2&!m?OzuTb5#-zo-2i0rtS|iK< MMMCIaYM;@>KSyKTX#fBK diff --git a/lib/3rdParty/tbb/lib/x64/v140/tbb.def b/lib/3rdParty/tbb/lib/x64/v140/tbb.def deleted file mode 100644 index 62145ca1..00000000 --- a/lib/3rdParty/tbb/lib/x64/v140/tbb.def +++ /dev/null @@ -1,1126 +0,0 @@ -; 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 organized with a section for each .cpp file. -; Each of these sections is in alphabetical order. - -EXPORTS - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -__TBB_machine_cmpswp1 -__TBB_machine_fetchadd1 -__TBB_machine_fetchstore1 -__TBB_machine_cmpswp2 -__TBB_machine_fetchadd2 -__TBB_machine_fetchstore2 -__TBB_machine_pause -__TBB_machine_try_lock_elided -__TBB_machine_unlock_elided -__TBB_machine_is_in_transaction - - -?NFS_Allocate@internal@tbb@@YAPEAX_K0PEAX@Z -?NFS_GetLineSize@internal@tbb@@YA_KXZ -?NFS_Free@internal@tbb@@YAXPEAX@Z -?allocate_via_handler_v3@internal@tbb@@YAPEAX_K@Z -?deallocate_via_handler_v3@internal@tbb@@YAXPEAX@Z -?is_malloc_used_v3@internal@tbb@@YA_NXZ - - - -?resize@affinity_partitioner_base_v3@internal@tbb@@AEAAXI@Z -?allocate@allocate_additional_child_of_proxy@internal@tbb@@QEBAAEAVtask@3@_K@Z -?allocate@allocate_child_proxy@internal@tbb@@QEBAAEAVtask@3@_K@Z -?allocate@allocate_continuation_proxy@internal@tbb@@QEBAAEAVtask@3@_K@Z -?allocate@allocate_root_proxy@internal@tbb@@SAAEAVtask@3@_K@Z -?destroy@task_base@internal@interface5@tbb@@SAXAEAVtask@4@@Z -?free@allocate_additional_child_of_proxy@internal@tbb@@QEBAXAEAVtask@3@@Z -?free@allocate_child_proxy@internal@tbb@@QEBAXAEAVtask@3@@Z -?free@allocate_continuation_proxy@internal@tbb@@QEBAXAEAVtask@3@@Z -?free@allocate_root_proxy@internal@tbb@@SAXAEAVtask@3@@Z -?internal_set_ref_count@task@tbb@@AEAAXH@Z -?internal_decrement_ref_count@task@tbb@@AEAA_JXZ -?is_owned_by_current_thread@task@tbb@@QEBA_NXZ -?note_affinity@task@tbb@@UEAAXG@Z -?self@task@tbb@@SAAEAV12@XZ -?spawn_and_wait_for_all@task@tbb@@QEAAXAEAVtask_list@2@@Z -?default_num_threads@task_scheduler_init@tbb@@SAHXZ -?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 -?internal_attach@task_arena_base@internal@interface7@tbb@@IEAAXXZ -?internal_enqueue@task_arena_base@internal@interface7@tbb@@IEBAXAEAVtask@4@_J@Z -?internal_execute@task_arena_base@internal@interface7@tbb@@IEBAXAEAVdelegate_base@234@@Z -?internal_wait@task_arena_base@internal@interface7@tbb@@IEBAXXZ - - - - - -?destroy@task@tbb@@QEAAXAEAV12@@Z - - - - -?allocate@allocate_root_with_context_proxy@internal@tbb@@QEBAAEAVtask@3@_K@Z -?free@allocate_root_with_context_proxy@internal@tbb@@QEBAXAEAVtask@3@@Z -?change_group@task@tbb@@QEAAXAEAVtask_group_context@2@@Z -?is_group_execution_cancelled@task_group_context@tbb@@QEBA_NXZ -?cancel_group_execution@task_group_context@tbb@@QEAA_NXZ -?reset@task_group_context@tbb@@QEAAXXZ -?capture_fp_settings@task_group_context@tbb@@QEAAXXZ -?init@task_group_context@tbb@@IEAAXXZ -?register_pending_exception@task_group_context@tbb@@QEAAXXZ -??1task_group_context@tbb@@QEAA@XZ - -?set_priority@task_group_context@tbb@@QEAAXW4priority_t@2@@Z -?priority@task_group_context@tbb@@QEBA?AW4priority_t@2@XZ - -?name@captured_exception@tbb@@UEBAPEBDXZ -?what@captured_exception@tbb@@UEBAPEBDXZ -??1captured_exception@tbb@@UEAA@XZ -?move@captured_exception@tbb@@UEAAPEAV12@XZ -?destroy@captured_exception@tbb@@UEAAXXZ -?set@captured_exception@tbb@@QEAAXPEBD0@Z -?clear@captured_exception@tbb@@QEAAXXZ - - - -?throw_bad_last_alloc_exception_v4@internal@tbb@@YAXXZ -?throw_exception_v4@internal@tbb@@YAXW4exception_id@12@@Z -?what@bad_last_alloc@tbb@@UEBAPEBDXZ -?what@missing_wait@tbb@@UEBAPEBDXZ -?what@invalid_multiple_scheduling@tbb@@UEBAPEBDXZ -?what@improper_lock@tbb@@UEBAPEBDXZ -?what@user_abort@tbb@@UEBAPEBDXZ - - -?assertion_failure@tbb@@YAXPEBDH00@Z -?get_initial_auto_partitioner_divisor@internal@tbb@@YA_KXZ -?handle_perror@internal@tbb@@YAXHPEBD@Z -?set_assertion_handler@tbb@@YAP6AXPEBDH00@ZP6AX0H00@Z@Z -?runtime_warning@internal@tbb@@YAXPEBDZZ -TBB_runtime_interface_version - - -?itt_load_pointer_with_acquire_v3@internal@tbb@@YAPEAXPEBX@Z -?itt_store_pointer_with_release_v3@internal@tbb@@YAXPEAX0@Z -?call_itt_notify_v5@internal@tbb@@YAXHPEAX@Z -?itt_load_pointer_v3@internal@tbb@@YAPEAXPEBX@Z -?itt_set_sync_name_v3@internal@tbb@@YAXPEAXPEB_W@Z - - - - - - - - - - - -??_7pipeline@tbb@@6B@ -??0pipeline@tbb@@QEAA@XZ -??1filter@tbb@@UEAA@XZ -??1pipeline@tbb@@UEAA@XZ -?add_filter@pipeline@tbb@@QEAAXAEAVfilter@2@@Z -?clear@pipeline@tbb@@QEAAXXZ -?inject_token@pipeline@tbb@@AEAAXAEAVtask@2@@Z -?run@pipeline@tbb@@QEAAX_K@Z - -?run@pipeline@tbb@@QEAAX_KAEAVtask_group_context@2@@Z - -?process_item@thread_bound_filter@tbb@@QEAA?AW4result_type@12@XZ -?try_process_item@thread_bound_filter@tbb@@QEAA?AW4result_type@12@XZ -?set_end_of_input@filter@tbb@@IEAAXXZ - - -?internal_construct@queuing_rw_mutex@tbb@@QEAAXXZ -?acquire@scoped_lock@queuing_rw_mutex@tbb@@QEAAXAEAV23@_N@Z -?downgrade_to_reader@scoped_lock@queuing_rw_mutex@tbb@@QEAA_NXZ -?release@scoped_lock@queuing_rw_mutex@tbb@@QEAAXXZ -?upgrade_to_writer@scoped_lock@queuing_rw_mutex@tbb@@QEAA_NXZ -?try_acquire@scoped_lock@queuing_rw_mutex@tbb@@QEAA_NAEAV23@_N@Z - - -?try_lock_read@reader_writer_lock@interface5@tbb@@QEAA_NXZ -?try_lock@reader_writer_lock@interface5@tbb@@QEAA_NXZ -?unlock@reader_writer_lock@interface5@tbb@@QEAAXXZ -?lock_read@reader_writer_lock@interface5@tbb@@QEAAXXZ -?lock@reader_writer_lock@interface5@tbb@@QEAAXXZ -?internal_construct@reader_writer_lock@interface5@tbb@@AEAAXXZ -?internal_destroy@reader_writer_lock@interface5@tbb@@AEAAXXZ -?internal_construct@scoped_lock@reader_writer_lock@interface5@tbb@@AEAAXAEAV234@@Z -?internal_destroy@scoped_lock@reader_writer_lock@interface5@tbb@@AEAAXXZ -?internal_construct@scoped_lock_read@reader_writer_lock@interface5@tbb@@AEAAXAEAV234@@Z -?internal_destroy@scoped_lock_read@reader_writer_lock@interface5@tbb@@AEAAXXZ - - - -?internal_itt_releasing@spin_rw_mutex@tbb@@CAXPEAV12@@Z -?internal_acquire_writer@spin_rw_mutex@tbb@@CA_NPEAV12@@Z -?internal_acquire_reader@spin_rw_mutex@tbb@@CAXPEAV12@@Z -?internal_downgrade@spin_rw_mutex@tbb@@CAXPEAV12@@Z -?internal_upgrade@spin_rw_mutex@tbb@@CA_NPEAV12@@Z -?internal_release_reader@spin_rw_mutex@tbb@@CAXPEAV12@@Z -?internal_release_writer@spin_rw_mutex@tbb@@CAXPEAV12@@Z -?internal_try_acquire_writer@spin_rw_mutex@tbb@@CA_NPEAV12@@Z -?internal_try_acquire_reader@spin_rw_mutex@tbb@@CA_NPEAV12@@Z - - - -?internal_construct@spin_rw_mutex_v3@tbb@@AEAAXXZ -?internal_upgrade@spin_rw_mutex_v3@tbb@@AEAA_NXZ -?internal_downgrade@spin_rw_mutex_v3@tbb@@AEAAXXZ -?internal_acquire_reader@spin_rw_mutex_v3@tbb@@AEAAXXZ -?internal_acquire_writer@spin_rw_mutex_v3@tbb@@AEAA_NXZ -?internal_release_reader@spin_rw_mutex_v3@tbb@@AEAAXXZ -?internal_release_writer@spin_rw_mutex_v3@tbb@@AEAAXXZ -?internal_try_acquire_reader@spin_rw_mutex_v3@tbb@@AEAA_NXZ -?internal_try_acquire_writer@spin_rw_mutex_v3@tbb@@AEAA_NXZ - - -?internal_acquire_writer@x86_rtm_rw_mutex@internal@interface8@tbb@@AEAAXAEAVscoped_lock@1234@_N@Z -?internal_acquire_reader@x86_rtm_rw_mutex@internal@interface8@tbb@@AEAAXAEAVscoped_lock@1234@_N@Z -?internal_upgrade@x86_rtm_rw_mutex@internal@interface8@tbb@@AEAA_NAEAVscoped_lock@1234@@Z -?internal_downgrade@x86_rtm_rw_mutex@internal@interface8@tbb@@AEAA_NAEAVscoped_lock@1234@@Z -?internal_try_acquire_writer@x86_rtm_rw_mutex@internal@interface8@tbb@@AEAA_NAEAVscoped_lock@1234@@Z -?internal_release@x86_rtm_rw_mutex@internal@interface8@tbb@@AEAAXAEAVscoped_lock@1234@@Z -?internal_construct@x86_rtm_rw_mutex@internal@interface8@tbb@@AEAAXXZ - - -?internal_construct@spin_mutex@tbb@@QEAAXXZ -?internal_acquire@scoped_lock@spin_mutex@tbb@@AEAAXAEAV23@@Z -?internal_release@scoped_lock@spin_mutex@tbb@@AEAAXXZ -?internal_try_acquire@scoped_lock@spin_mutex@tbb@@AEAA_NAEAV23@@Z - - -?internal_acquire@scoped_lock@mutex@tbb@@AEAAXAEAV23@@Z -?internal_release@scoped_lock@mutex@tbb@@AEAAXXZ -?internal_try_acquire@scoped_lock@mutex@tbb@@AEAA_NAEAV23@@Z -?internal_construct@mutex@tbb@@AEAAXXZ -?internal_destroy@mutex@tbb@@AEAAXXZ - - -?internal_construct@recursive_mutex@tbb@@AEAAXXZ -?internal_destroy@recursive_mutex@tbb@@AEAAXXZ -?internal_acquire@scoped_lock@recursive_mutex@tbb@@AEAAXAEAV23@@Z -?internal_try_acquire@scoped_lock@recursive_mutex@tbb@@AEAA_NAEAV23@@Z -?internal_release@scoped_lock@recursive_mutex@tbb@@AEAAXXZ - - -?internal_construct@queuing_mutex@tbb@@QEAAXXZ -?acquire@scoped_lock@queuing_mutex@tbb@@QEAAXAEAV23@@Z -?release@scoped_lock@queuing_mutex@tbb@@QEAAXXZ -?try_acquire@scoped_lock@queuing_mutex@tbb@@QEAA_NAEAV23@@Z - - -?internal_construct@critical_section_v4@internal@tbb@@QEAAXXZ - - - -?internal_grow_predicate@hash_map_segment_base@internal@tbb@@QEBA_NXZ - - -??0concurrent_queue_base@internal@tbb@@IEAA@_K@Z -??0concurrent_queue_iterator_base@internal@tbb@@IEAA@AEBVconcurrent_queue_base@12@@Z -??1concurrent_queue_base@internal@tbb@@MEAA@XZ -??1concurrent_queue_iterator_base@internal@tbb@@IEAA@XZ -?advance@concurrent_queue_iterator_base@internal@tbb@@IEAAXXZ -?assign@concurrent_queue_iterator_base@internal@tbb@@IEAAXAEBV123@@Z -?internal_pop@concurrent_queue_base@internal@tbb@@IEAAXPEAX@Z -?internal_pop_if_present@concurrent_queue_base@internal@tbb@@IEAA_NPEAX@Z -?internal_push@concurrent_queue_base@internal@tbb@@IEAAXPEBX@Z -?internal_push_if_not_full@concurrent_queue_base@internal@tbb@@IEAA_NPEBX@Z -?internal_set_capacity@concurrent_queue_base@internal@tbb@@IEAAX_J_K@Z -?internal_size@concurrent_queue_base@internal@tbb@@IEBA_JXZ - - - -??0concurrent_queue_iterator_base_v3@internal@tbb@@IEAA@AEBVconcurrent_queue_base_v3@12@@Z -??0concurrent_queue_iterator_base_v3@internal@tbb@@IEAA@AEBVconcurrent_queue_base_v3@12@_K@Z -??1concurrent_queue_iterator_base_v3@internal@tbb@@IEAA@XZ -?assign@concurrent_queue_iterator_base_v3@internal@tbb@@IEAAXAEBV123@@Z -?advance@concurrent_queue_iterator_base_v3@internal@tbb@@IEAAXXZ -??0concurrent_queue_base_v3@internal@tbb@@IEAA@_K@Z -??1concurrent_queue_base_v3@internal@tbb@@MEAA@XZ -?internal_push@concurrent_queue_base_v3@internal@tbb@@IEAAXPEBX@Z -?internal_push_move@concurrent_queue_base_v8@internal@tbb@@IEAAXPEBX@Z -?internal_push_if_not_full@concurrent_queue_base_v3@internal@tbb@@IEAA_NPEBX@Z -?internal_push_move_if_not_full@concurrent_queue_base_v8@internal@tbb@@IEAA_NPEBX@Z -?internal_pop@concurrent_queue_base_v3@internal@tbb@@IEAAXPEAX@Z -?internal_pop_if_present@concurrent_queue_base_v3@internal@tbb@@IEAA_NPEAX@Z -?internal_abort@concurrent_queue_base_v3@internal@tbb@@IEAAXXZ -?internal_size@concurrent_queue_base_v3@internal@tbb@@IEBA_JXZ -?internal_empty@concurrent_queue_base_v3@internal@tbb@@IEBA_NXZ -?internal_finish_clear@concurrent_queue_base_v3@internal@tbb@@IEAAXXZ -?internal_set_capacity@concurrent_queue_base_v3@internal@tbb@@IEAAX_J_K@Z -?internal_throw_exception@concurrent_queue_base_v3@internal@tbb@@IEBAXXZ -?assign@concurrent_queue_base_v3@internal@tbb@@IEAAXAEBV123@@Z -?move_content@concurrent_queue_base_v8@internal@tbb@@IEAAXAEAV123@@Z - - - -?internal_assign@concurrent_vector_base@internal@tbb@@IEAAXAEBV123@_KP6AXPEAX1@ZP6AX2PEBX1@Z5@Z -?internal_capacity@concurrent_vector_base@internal@tbb@@IEBA_KXZ -?internal_clear@concurrent_vector_base@internal@tbb@@IEAAXP6AXPEAX_K@Z_N@Z -?internal_copy@concurrent_vector_base@internal@tbb@@IEAAXAEBV123@_KP6AXPEAXPEBX1@Z@Z -?internal_grow_by@concurrent_vector_base@internal@tbb@@IEAA_K_K0P6AXPEAX0@Z@Z -?internal_grow_to_at_least@concurrent_vector_base@internal@tbb@@IEAAX_K0P6AXPEAX0@Z@Z -?internal_push_back@concurrent_vector_base@internal@tbb@@IEAAPEAX_KAEA_K@Z -?internal_reserve@concurrent_vector_base@internal@tbb@@IEAAX_K00@Z - - - -??1concurrent_vector_base_v3@internal@tbb@@IEAA@XZ -?internal_assign@concurrent_vector_base_v3@internal@tbb@@IEAAXAEBV123@_KP6AXPEAX1@ZP6AX2PEBX1@Z5@Z -?internal_capacity@concurrent_vector_base_v3@internal@tbb@@IEBA_KXZ -?internal_clear@concurrent_vector_base_v3@internal@tbb@@IEAA_KP6AXPEAX_K@Z@Z -?internal_copy@concurrent_vector_base_v3@internal@tbb@@IEAAXAEBV123@_KP6AXPEAXPEBX1@Z@Z -?internal_grow_by@concurrent_vector_base_v3@internal@tbb@@IEAA_K_K0P6AXPEAXPEBX0@Z2@Z -?internal_grow_to_at_least@concurrent_vector_base_v3@internal@tbb@@IEAAX_K0P6AXPEAXPEBX0@Z2@Z -?internal_push_back@concurrent_vector_base_v3@internal@tbb@@IEAAPEAX_KAEA_K@Z -?internal_reserve@concurrent_vector_base_v3@internal@tbb@@IEAAX_K00@Z -?internal_compact@concurrent_vector_base_v3@internal@tbb@@IEAAPEAX_KPEAXP6AX10@ZP6AX1PEBX0@Z@Z -?internal_swap@concurrent_vector_base_v3@internal@tbb@@IEAAXAEAV123@@Z -?internal_throw_exception@concurrent_vector_base_v3@internal@tbb@@IEBAX_K@Z -?internal_resize@concurrent_vector_base_v3@internal@tbb@@IEAAX_K00PEBXP6AXPEAX0@ZP6AX210@Z@Z -?internal_grow_to_at_least_with_result@concurrent_vector_base_v3@internal@tbb@@IEAA_K_K0P6AXPEAXPEBX0@Z2@Z - - -?allocate_closure_v3@internal@tbb@@YAPEAX_K@Z -?detach@tbb_thread_v3@internal@tbb@@QEAAXXZ -?free_closure_v3@internal@tbb@@YAXPEAX@Z -?hardware_concurrency@tbb_thread_v3@internal@tbb@@SAIXZ -?internal_start@tbb_thread_v3@internal@tbb@@AEAAXP6AIPEAX@Z0@Z -?join@tbb_thread_v3@internal@tbb@@QEAAXXZ -?move_v3@internal@tbb@@YAXAEAVtbb_thread_v3@12@0@Z -?thread_get_id_v3@internal@tbb@@YA?AVid@tbb_thread_v3@12@XZ -?thread_sleep_v3@internal@tbb@@YAXAEBVinterval_t@tick_count@2@@Z -?thread_yield_v3@internal@tbb@@YAXXZ - - -?internal_initialize_condition_variable@internal@interface5@tbb@@YAXAEATcondvar_impl_t@123@@Z -?internal_condition_variable_wait@internal@interface5@tbb@@YA_NAEATcondvar_impl_t@123@PEAVmutex@3@PEBVinterval_t@tick_count@3@@Z -?internal_condition_variable_notify_one@internal@interface5@tbb@@YAXAEATcondvar_impl_t@123@@Z -?internal_condition_variable_notify_all@internal@interface5@tbb@@YAXAEATcondvar_impl_t@123@@Z -?internal_destroy_condition_variable@internal@interface5@tbb@@YAXAEATcondvar_impl_t@123@@Z - - -?active_value@global_control@interface9@tbb@@CA_KH@Z -?internal_create@global_control@interface9@tbb@@AEAAXXZ -?internal_destroy@global_control@interface9@tbb@@AEAAXXZ - - - - diff --git a/lib/3rdParty/tbb/lib/x64/v140/tbb.lib b/lib/3rdParty/tbb/lib/x64/v140/tbb.lib deleted file mode 100644 index 7db38e1f18271daab5f9ec0f1304c605874ca3cd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 96548 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 P_OiZI;LXh-Gw1&c2zi8F diff --git a/lib/3rdParty/tbb/lib/x64/v140/tbb_preview.lib b/lib/3rdParty/tbb/lib/x64/v140/tbb_preview.lib deleted file mode 100644 index f3b8e82a70159b7e0a377519b242ccc075ea7b2e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 102718 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 diff --git a/lib/3rdParty/tbb/lib/x64/v140/tbbmalloc_proxy.lib b/lib/3rdParty/tbb/lib/x64/v140/tbbmalloc_proxy.lib deleted file mode 100644 index 45c14dfa9c276f10c03451161c3114ce08432b67..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1928 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 KY%vxa}Chu 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 O$%}&?a{H^p1^fq>hpB!5 diff --git a/lib/3rdParty/tbb/lib/x86/v140/irml/irml_debug.lib b/lib/3rdParty/tbb/lib/x86/v140/irml/irml_debug.lib deleted file mode 100644 index 46e6109b049190ec3d030d3b843c23e6b3985290..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3058 zcmcIm%}yIJ5T4yYAWKCNrBW|NTNU-^0yN1|kWdvUm5Q=~CF{*WBbv3pHjd+Q#+EbL z)m)w}y;*ymTh8WJbF5OYRavS0{?i9wY-QbbuiL=az{oerzg=HRv!#Xn0#0JNjLW>e z@-Evh6dPXs0A-ch9x8MiE-O~O{j%P?RmJj)i>y}oSZ3tte!2d+Tn_;BN|w%K+t1M} zIZm-qt+Fqb#ty3;2rO3F-S$+#5G#%xq8Ix@F0{4knIUtMI$Kr@DYDTAa2y3V8vr;$ z&WvF_90E8&$5aRs9ux;ml19#JhZv<#x4x7|Jb zzn&D`Z2c8+^&Dwpbt_GqRQgot;Ix>pb3H8kg2bFGRjX5Wr_;ol4!GhP5y(CGzAm2|IYyC?y3Wi<6a7p;4HKO9dW1@DuAFA&6j`g6UIXHzUL_f*lj_ zq#emqV4s@U-bV&f8CDnd6z+{6lYxFoWf<%E=4hr;tb6<3cEf&_dv3eSD`~E6`P{)V zO{5>-$;o@r7=bMIcc_|@j78UZ*1iA7Q0QY)FO86QHD_e%~$d)qtQ&92&reVdG&c`08@^eUoUbqzYpruZ5MF@oW@kQztmIj+vE9{&mA z8+e+wx#e15)nR8gIr8wf)m2X*s_CQBTTH#1R1i>yU0^!;mD1T22{4sQPsQkccf+Df YZxwOJw|xWrD}GpX`vd&eH%trcU&wjlVgLXD diff --git a/lib/3rdParty/tbb/lib/x86/v140/tbb.def b/lib/3rdParty/tbb/lib/x86/v140/tbb.def deleted file mode 100644 index 395056c9..00000000 --- a/lib/3rdParty/tbb/lib/x86/v140/tbb.def +++ /dev/null @@ -1,1133 +0,0 @@ -; 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. -; -; -; -; - - -EXPORTS - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -__TBB_machine_cmpswp8 - - - -__TBB_machine_fetchadd8 - - - -__TBB_machine_fetchstore8 -__TBB_machine_store8 -__TBB_machine_load8 -__TBB_machine_trylockbyte -__TBB_machine_try_lock_elided -__TBB_machine_unlock_elided -__TBB_machine_is_in_transaction - - -?NFS_Allocate@internal@tbb@@YAPAXIIPAX@Z -?NFS_GetLineSize@internal@tbb@@YAIXZ -?NFS_Free@internal@tbb@@YAXPAX@Z -?allocate_via_handler_v3@internal@tbb@@YAPAXI@Z -?deallocate_via_handler_v3@internal@tbb@@YAXPAX@Z -?is_malloc_used_v3@internal@tbb@@YA_NXZ - - -?allocate@allocate_additional_child_of_proxy@internal@tbb@@QBEAAVtask@3@I@Z -?allocate@allocate_child_proxy@internal@tbb@@QBEAAVtask@3@I@Z -?allocate@allocate_continuation_proxy@internal@tbb@@QBEAAVtask@3@I@Z -?allocate@allocate_root_proxy@internal@tbb@@SAAAVtask@3@I@Z -?destroy@task_base@internal@interface5@tbb@@SAXAAVtask@4@@Z -?free@allocate_additional_child_of_proxy@internal@tbb@@QBEXAAVtask@3@@Z -?free@allocate_child_proxy@internal@tbb@@QBEXAAVtask@3@@Z -?free@allocate_continuation_proxy@internal@tbb@@QBEXAAVtask@3@@Z -?free@allocate_root_proxy@internal@tbb@@SAXAAVtask@3@@Z -?internal_set_ref_count@task@tbb@@AAEXH@Z -?internal_decrement_ref_count@task@tbb@@AAEHXZ -?is_owned_by_current_thread@task@tbb@@QBE_NXZ -?note_affinity@task@tbb@@UAEXG@Z -?resize@affinity_partitioner_base_v3@internal@tbb@@AAEXI@Z -?self@task@tbb@@SAAAV12@XZ -?spawn_and_wait_for_all@task@tbb@@QAEXAAVtask_list@2@@Z -?default_num_threads@task_scheduler_init@tbb@@SAHXZ -?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 -?internal_attach@task_arena_base@internal@interface7@tbb@@IAEXXZ -?internal_enqueue@task_arena_base@internal@interface7@tbb@@IBEXAAVtask@4@H@Z -?internal_execute@task_arena_base@internal@interface7@tbb@@IBEXAAVdelegate_base@234@@Z -?internal_wait@task_arena_base@internal@interface7@tbb@@IBEXXZ - - - - - - -?destroy@task@tbb@@QAEXAAV12@@Z - - - - -?allocate@allocate_root_with_context_proxy@internal@tbb@@QBEAAVtask@3@I@Z -?free@allocate_root_with_context_proxy@internal@tbb@@QBEXAAVtask@3@@Z -?change_group@task@tbb@@QAEXAAVtask_group_context@2@@Z -?is_group_execution_cancelled@task_group_context@tbb@@QBE_NXZ -?cancel_group_execution@task_group_context@tbb@@QAE_NXZ -?reset@task_group_context@tbb@@QAEXXZ -?capture_fp_settings@task_group_context@tbb@@QAEXXZ -?init@task_group_context@tbb@@IAEXXZ -?register_pending_exception@task_group_context@tbb@@QAEXXZ -??1task_group_context@tbb@@QAE@XZ - -?set_priority@task_group_context@tbb@@QAEXW4priority_t@2@@Z -?priority@task_group_context@tbb@@QBE?AW4priority_t@2@XZ - -?name@captured_exception@tbb@@UBEPBDXZ -?what@captured_exception@tbb@@UBEPBDXZ -??1captured_exception@tbb@@UAE@XZ -?move@captured_exception@tbb@@UAEPAV12@XZ -?destroy@captured_exception@tbb@@UAEXXZ -?set@captured_exception@tbb@@QAEXPBD0@Z -?clear@captured_exception@tbb@@QAEXXZ - - - -?throw_bad_last_alloc_exception_v4@internal@tbb@@YAXXZ -?throw_exception_v4@internal@tbb@@YAXW4exception_id@12@@Z -?what@bad_last_alloc@tbb@@UBEPBDXZ -?what@missing_wait@tbb@@UBEPBDXZ -?what@invalid_multiple_scheduling@tbb@@UBEPBDXZ -?what@improper_lock@tbb@@UBEPBDXZ -?what@user_abort@tbb@@UBEPBDXZ - - -?assertion_failure@tbb@@YAXPBDH00@Z -?get_initial_auto_partitioner_divisor@internal@tbb@@YAIXZ -?handle_perror@internal@tbb@@YAXHPBD@Z -?set_assertion_handler@tbb@@YAP6AXPBDH00@ZP6AX0H00@Z@Z -?runtime_warning@internal@tbb@@YAXPBDZZ -TBB_runtime_interface_version - - -?itt_load_pointer_with_acquire_v3@internal@tbb@@YAPAXPBX@Z -?itt_store_pointer_with_release_v3@internal@tbb@@YAXPAX0@Z -?call_itt_notify_v5@internal@tbb@@YAXHPAX@Z -?itt_set_sync_name_v3@internal@tbb@@YAXPAXPB_W@Z -?itt_load_pointer_v3@internal@tbb@@YAPAXPBX@Z - - - - - - - - - - - -??0pipeline@tbb@@QAE@XZ -??1filter@tbb@@UAE@XZ -??1pipeline@tbb@@UAE@XZ -??_7pipeline@tbb@@6B@ -?add_filter@pipeline@tbb@@QAEXAAVfilter@2@@Z -?clear@pipeline@tbb@@QAEXXZ -?inject_token@pipeline@tbb@@AAEXAAVtask@2@@Z -?run@pipeline@tbb@@QAEXI@Z - -?run@pipeline@tbb@@QAEXIAAVtask_group_context@2@@Z - -?process_item@thread_bound_filter@tbb@@QAE?AW4result_type@12@XZ -?try_process_item@thread_bound_filter@tbb@@QAE?AW4result_type@12@XZ -?set_end_of_input@filter@tbb@@IAEXXZ - - -?internal_construct@queuing_rw_mutex@tbb@@QAEXXZ -?acquire@scoped_lock@queuing_rw_mutex@tbb@@QAEXAAV23@_N@Z -?downgrade_to_reader@scoped_lock@queuing_rw_mutex@tbb@@QAE_NXZ -?release@scoped_lock@queuing_rw_mutex@tbb@@QAEXXZ -?upgrade_to_writer@scoped_lock@queuing_rw_mutex@tbb@@QAE_NXZ -?try_acquire@scoped_lock@queuing_rw_mutex@tbb@@QAE_NAAV23@_N@Z - - -?try_lock_read@reader_writer_lock@interface5@tbb@@QAE_NXZ -?try_lock@reader_writer_lock@interface5@tbb@@QAE_NXZ -?unlock@reader_writer_lock@interface5@tbb@@QAEXXZ -?lock_read@reader_writer_lock@interface5@tbb@@QAEXXZ -?lock@reader_writer_lock@interface5@tbb@@QAEXXZ -?internal_construct@reader_writer_lock@interface5@tbb@@AAEXXZ -?internal_destroy@reader_writer_lock@interface5@tbb@@AAEXXZ -?internal_construct@scoped_lock@reader_writer_lock@interface5@tbb@@AAEXAAV234@@Z -?internal_destroy@scoped_lock@reader_writer_lock@interface5@tbb@@AAEXXZ -?internal_construct@scoped_lock_read@reader_writer_lock@interface5@tbb@@AAEXAAV234@@Z -?internal_destroy@scoped_lock_read@reader_writer_lock@interface5@tbb@@AAEXXZ - - - -?internal_acquire_reader@spin_rw_mutex@tbb@@CAXPAV12@@Z -?internal_acquire_writer@spin_rw_mutex@tbb@@CA_NPAV12@@Z -?internal_downgrade@spin_rw_mutex@tbb@@CAXPAV12@@Z -?internal_itt_releasing@spin_rw_mutex@tbb@@CAXPAV12@@Z -?internal_release_reader@spin_rw_mutex@tbb@@CAXPAV12@@Z -?internal_release_writer@spin_rw_mutex@tbb@@CAXPAV12@@Z -?internal_upgrade@spin_rw_mutex@tbb@@CA_NPAV12@@Z -?internal_try_acquire_writer@spin_rw_mutex@tbb@@CA_NPAV12@@Z -?internal_try_acquire_reader@spin_rw_mutex@tbb@@CA_NPAV12@@Z - - - -?internal_construct@spin_rw_mutex_v3@tbb@@AAEXXZ -?internal_upgrade@spin_rw_mutex_v3@tbb@@AAE_NXZ -?internal_downgrade@spin_rw_mutex_v3@tbb@@AAEXXZ -?internal_acquire_reader@spin_rw_mutex_v3@tbb@@AAEXXZ -?internal_acquire_writer@spin_rw_mutex_v3@tbb@@AAE_NXZ -?internal_release_reader@spin_rw_mutex_v3@tbb@@AAEXXZ -?internal_release_writer@spin_rw_mutex_v3@tbb@@AAEXXZ -?internal_try_acquire_reader@spin_rw_mutex_v3@tbb@@AAE_NXZ -?internal_try_acquire_writer@spin_rw_mutex_v3@tbb@@AAE_NXZ - - -?internal_construct@x86_rtm_rw_mutex@internal@interface8@tbb@@AAEXXZ -?internal_release@x86_rtm_rw_mutex@internal@interface8@tbb@@AAEXAAVscoped_lock@1234@@Z -?internal_acquire_writer@x86_rtm_rw_mutex@internal@interface8@tbb@@AAEXAAVscoped_lock@1234@_N@Z -?internal_acquire_reader@x86_rtm_rw_mutex@internal@interface8@tbb@@AAEXAAVscoped_lock@1234@_N@Z -?internal_upgrade@x86_rtm_rw_mutex@internal@interface8@tbb@@AAE_NAAVscoped_lock@1234@@Z -?internal_downgrade@x86_rtm_rw_mutex@internal@interface8@tbb@@AAE_NAAVscoped_lock@1234@@Z -?internal_try_acquire_writer@x86_rtm_rw_mutex@internal@interface8@tbb@@AAE_NAAVscoped_lock@1234@@Z - - -?internal_construct@spin_mutex@tbb@@QAEXXZ -?internal_acquire@scoped_lock@spin_mutex@tbb@@AAEXAAV23@@Z -?internal_release@scoped_lock@spin_mutex@tbb@@AAEXXZ -?internal_try_acquire@scoped_lock@spin_mutex@tbb@@AAE_NAAV23@@Z - - -?internal_acquire@scoped_lock@mutex@tbb@@AAEXAAV23@@Z -?internal_release@scoped_lock@mutex@tbb@@AAEXXZ -?internal_try_acquire@scoped_lock@mutex@tbb@@AAE_NAAV23@@Z -?internal_construct@mutex@tbb@@AAEXXZ -?internal_destroy@mutex@tbb@@AAEXXZ - - -?internal_acquire@scoped_lock@recursive_mutex@tbb@@AAEXAAV23@@Z -?internal_release@scoped_lock@recursive_mutex@tbb@@AAEXXZ -?internal_try_acquire@scoped_lock@recursive_mutex@tbb@@AAE_NAAV23@@Z -?internal_construct@recursive_mutex@tbb@@AAEXXZ -?internal_destroy@recursive_mutex@tbb@@AAEXXZ - - -?internal_construct@queuing_mutex@tbb@@QAEXXZ -?acquire@scoped_lock@queuing_mutex@tbb@@QAEXAAV23@@Z -?release@scoped_lock@queuing_mutex@tbb@@QAEXXZ -?try_acquire@scoped_lock@queuing_mutex@tbb@@QAE_NAAV23@@Z - - -?internal_construct@critical_section_v4@internal@tbb@@QAEXXZ - - - -?internal_grow_predicate@hash_map_segment_base@internal@tbb@@QBE_NXZ - - -?advance@concurrent_queue_iterator_base@internal@tbb@@IAEXXZ -?assign@concurrent_queue_iterator_base@internal@tbb@@IAEXABV123@@Z -?internal_size@concurrent_queue_base@internal@tbb@@IBEHXZ -??0concurrent_queue_base@internal@tbb@@IAE@I@Z -??0concurrent_queue_iterator_base@internal@tbb@@IAE@ABVconcurrent_queue_base@12@@Z -??1concurrent_queue_base@internal@tbb@@MAE@XZ -??1concurrent_queue_iterator_base@internal@tbb@@IAE@XZ -?internal_pop@concurrent_queue_base@internal@tbb@@IAEXPAX@Z -?internal_pop_if_present@concurrent_queue_base@internal@tbb@@IAE_NPAX@Z -?internal_push@concurrent_queue_base@internal@tbb@@IAEXPBX@Z -?internal_push_if_not_full@concurrent_queue_base@internal@tbb@@IAE_NPBX@Z -?internal_set_capacity@concurrent_queue_base@internal@tbb@@IAEXHI@Z - - - -??1concurrent_queue_iterator_base_v3@internal@tbb@@IAE@XZ -??0concurrent_queue_iterator_base_v3@internal@tbb@@IAE@ABVconcurrent_queue_base_v3@12@@Z -??0concurrent_queue_iterator_base_v3@internal@tbb@@IAE@ABVconcurrent_queue_base_v3@12@I@Z -?advance@concurrent_queue_iterator_base_v3@internal@tbb@@IAEXXZ -?assign@concurrent_queue_iterator_base_v3@internal@tbb@@IAEXABV123@@Z -??0concurrent_queue_base_v3@internal@tbb@@IAE@I@Z -??1concurrent_queue_base_v3@internal@tbb@@MAE@XZ -?internal_pop@concurrent_queue_base_v3@internal@tbb@@IAEXPAX@Z -?internal_pop_if_present@concurrent_queue_base_v3@internal@tbb@@IAE_NPAX@Z -?internal_abort@concurrent_queue_base_v3@internal@tbb@@IAEXXZ -?internal_push@concurrent_queue_base_v3@internal@tbb@@IAEXPBX@Z -?internal_push_move@concurrent_queue_base_v8@internal@tbb@@IAEXPBX@Z -?internal_push_if_not_full@concurrent_queue_base_v3@internal@tbb@@IAE_NPBX@Z -?internal_push_move_if_not_full@concurrent_queue_base_v8@internal@tbb@@IAE_NPBX@Z -?internal_size@concurrent_queue_base_v3@internal@tbb@@IBEHXZ -?internal_empty@concurrent_queue_base_v3@internal@tbb@@IBE_NXZ -?internal_set_capacity@concurrent_queue_base_v3@internal@tbb@@IAEXHI@Z -?internal_finish_clear@concurrent_queue_base_v3@internal@tbb@@IAEXXZ -?internal_throw_exception@concurrent_queue_base_v3@internal@tbb@@IBEXXZ -?assign@concurrent_queue_base_v3@internal@tbb@@IAEXABV123@@Z -?move_content@concurrent_queue_base_v8@internal@tbb@@IAEXAAV123@@Z - - - -?internal_assign@concurrent_vector_base@internal@tbb@@IAEXABV123@IP6AXPAXI@ZP6AX1PBXI@Z4@Z -?internal_capacity@concurrent_vector_base@internal@tbb@@IBEIXZ -?internal_clear@concurrent_vector_base@internal@tbb@@IAEXP6AXPAXI@Z_N@Z -?internal_copy@concurrent_vector_base@internal@tbb@@IAEXABV123@IP6AXPAXPBXI@Z@Z -?internal_grow_by@concurrent_vector_base@internal@tbb@@IAEIIIP6AXPAXI@Z@Z -?internal_grow_to_at_least@concurrent_vector_base@internal@tbb@@IAEXIIP6AXPAXI@Z@Z -?internal_push_back@concurrent_vector_base@internal@tbb@@IAEPAXIAAI@Z -?internal_reserve@concurrent_vector_base@internal@tbb@@IAEXIII@Z - - - -??1concurrent_vector_base_v3@internal@tbb@@IAE@XZ -?internal_assign@concurrent_vector_base_v3@internal@tbb@@IAEXABV123@IP6AXPAXI@ZP6AX1PBXI@Z4@Z -?internal_capacity@concurrent_vector_base_v3@internal@tbb@@IBEIXZ -?internal_clear@concurrent_vector_base_v3@internal@tbb@@IAEIP6AXPAXI@Z@Z -?internal_copy@concurrent_vector_base_v3@internal@tbb@@IAEXABV123@IP6AXPAXPBXI@Z@Z -?internal_grow_by@concurrent_vector_base_v3@internal@tbb@@IAEIIIP6AXPAXPBXI@Z1@Z -?internal_grow_to_at_least@concurrent_vector_base_v3@internal@tbb@@IAEXIIP6AXPAXPBXI@Z1@Z -?internal_push_back@concurrent_vector_base_v3@internal@tbb@@IAEPAXIAAI@Z -?internal_reserve@concurrent_vector_base_v3@internal@tbb@@IAEXIII@Z -?internal_compact@concurrent_vector_base_v3@internal@tbb@@IAEPAXIPAXP6AX0I@ZP6AX0PBXI@Z@Z -?internal_swap@concurrent_vector_base_v3@internal@tbb@@IAEXAAV123@@Z -?internal_throw_exception@concurrent_vector_base_v3@internal@tbb@@IBEXI@Z -?internal_resize@concurrent_vector_base_v3@internal@tbb@@IAEXIIIPBXP6AXPAXI@ZP6AX10I@Z@Z -?internal_grow_to_at_least_with_result@concurrent_vector_base_v3@internal@tbb@@IAEIIIP6AXPAXPBXI@Z1@Z - - -?join@tbb_thread_v3@internal@tbb@@QAEXXZ -?detach@tbb_thread_v3@internal@tbb@@QAEXXZ -?internal_start@tbb_thread_v3@internal@tbb@@AAEXP6GIPAX@Z0@Z -?allocate_closure_v3@internal@tbb@@YAPAXI@Z -?free_closure_v3@internal@tbb@@YAXPAX@Z -?hardware_concurrency@tbb_thread_v3@internal@tbb@@SAIXZ -?thread_yield_v3@internal@tbb@@YAXXZ -?thread_sleep_v3@internal@tbb@@YAXABVinterval_t@tick_count@2@@Z -?move_v3@internal@tbb@@YAXAAVtbb_thread_v3@12@0@Z -?thread_get_id_v3@internal@tbb@@YA?AVid@tbb_thread_v3@12@XZ - - -?internal_initialize_condition_variable@internal@interface5@tbb@@YAXAATcondvar_impl_t@123@@Z -?internal_condition_variable_wait@internal@interface5@tbb@@YA_NAATcondvar_impl_t@123@PAVmutex@3@PBVinterval_t@tick_count@3@@Z -?internal_condition_variable_notify_one@internal@interface5@tbb@@YAXAATcondvar_impl_t@123@@Z -?internal_condition_variable_notify_all@internal@interface5@tbb@@YAXAATcondvar_impl_t@123@@Z -?internal_destroy_condition_variable@internal@interface5@tbb@@YAXAATcondvar_impl_t@123@@Z - - -?active_value@global_control@interface9@tbb@@CAIH@Z -?internal_create@global_control@interface9@tbb@@AAEXXZ -?internal_destroy@global_control@interface9@tbb@@AAEXXZ - - - - - - diff --git a/lib/3rdParty/tbb/lib/x86/v140/tbb.lib b/lib/3rdParty/tbb/lib/x86/v140/tbb.lib deleted file mode 100644 index 07aca34721b59235c1727163cb818ed7ff6574c2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 94556 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 Ikg4ha09Hpovj6}9 diff --git a/lib/3rdParty/tbb/lib/x86/v140/tbb_debug.lib b/lib/3rdParty/tbb/lib/x86/v140/tbb_debug.lib deleted file mode 100644 index 1dee6789ce431c94ba4374557da38389359c060e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 96002 zcmeHw3!G%dRrk5eGXw}BBoG40^2qWCftlUe*;xW~&+IPj!mfWll zRrmHpzu)iM->-J2r>jo=>(r@Jryl3jS(nwivkO-ocgafi-{{!-@$r$>>qpk8e;-Lc zu3kT}hW)2#L*?}dQUf#X?Px(ok~ z>A)Q<^;hBds{p>Sk)>~L1)%heC*l;qaS*4Yry!uT>(V&Ei#vd&m+&X1|GbZ-m#zT7 z6db$2(s36;5T~c`C#IL<-zgn`EK6I)A)s`@HkNihhV(JL4e?Q$Ihmz8(xf!^JWEG^ z8u4H{>CPk}FHXWV|4x=(`vL@%Za$i&iH}1->HH6{H2wqxl(w#B>9xBsKc50N=G1ON;Tv$r6bQ^=@oB>fKvEOoZy9N zpcKsQVd>@v5htd%VO^BkND~u0e|(&Ro34a79aBdfnCc&4>8OnmP-;BM(k=KMrS?TE z-HLrisq^6^p`3Iu-HN=R1n*|)gvTMEbmBgiBIGrtS*(Xrx60D)XCa`pcLhr;UW9So-!|0GNWKuue*^JdLH9hq1pg&8}i8oIrkI zTD+O1=xM}-=`6&63BFa2Q}D7oAx`^Vf`C%%ZkG1n3jw9(Cz6Ey-Ne)amTvqI1aUeS ze_}d&fu#$-4gsZe?qTU798Z+aMP5?6=rNW~IUWK^ug1KTE=C%ZCN5%W!-Eh|+W1M9 zw&UL^T|dUsb%>SH8*gW6`^WHmOcy`G(kTxieN3;plckO0NC(rVeJoAi2LYw)acogq zbrMTcD6f=GJ)5OhV;M?2u4d^HlqX6z+``hiFJQYcy{gO7)GjQK={l^3(#chpCPyHk zv<>M}T8Vu}=|U_=>Ex$bntT-VVcLdmp>)oXEWHW)oYGla;{@MCdB7Cx>#%goizvUC zRw9omt@(DG;5(-Sr672Or7cJs6MS_SOaIyjp!EEmEPd_$0GNXHx3P5ThajMI*$S4f zcqasuuKH@6;OnTjDE-^2Bz+!#V*1V_aSB%KK{?-pb$yAYubqbUPeYogu=E!Ep3*Dd z!_s9BU_F>B&m{?YR>4%gou#Xhx0EhG!hqx=%wuY1M~WTKy0Nl*X`bN|#^8(x$JYynG$o_)MIF)9!;fy>2y@$8^Ramd=}j zfYKV26H05RS-KqSq;w_LOXSsFhU^(&^m_p|h}6*xXIUHyEV z;Jme)H|3OSSO{0hgo`S2Leh9C$qE;f2Z_@X_j7(SSX$OEK6^0LVyXr z^b&pyBpa`4l*cZ2Y=PT9DJvgXtrx6g#0Tdf4_UU*`D1$bGRSrxuIrA zmkp_K7&RO9sBSEu%B0X(YUNT$XHm*GdSRm#_Pe!KuQuCnv|D-<*=&_~Y4cqW)Htv+a%BvZS}{QE296jp<$4 zjk1LHWboOtRcc9F!vl?4xKL}=n^8AButwW-(QMCBm3rh_LWS>Lu7X{<7}pgp^`g42 zCE+%~YRB9IE>#E3z#-ot!KyVwR36QG*q#eJ-S(lwDb8I#wP|v4SHITVUtLq(lI7qK zC~D9#NagT&(9j`hxB89NQjK_2k}C)v zlLl$5QRZs1(ORZcwomTi)sIz$bd;b_nIo-GL{0}t)<{T(L@kBNDq9XXJj$nQb`T~P z0N!L$I4siSP`z{M3ZKHlUeph}(Ofv&UTXDY(PR=hIk{=iW+8db`32>AG~109qn45W zW=Y{DGb$Qw4uwdYw-2^ZkIx(qXP3HNs-(ZrjcRqN1*l?EI^DfYrPc07VQp@%(Q5SB zh-GZqiEOz_uq7{Br5p8VTIZC)POaOICkUKQNd;tQB4WHWArvQ2=|#;si65~>8(m!$ zTsLQ^^g6YJtq|w^@L;Xc59iw55Os${?RtcnsHm{n==H0sCGAkKG-}AX+ETM0ww4x? z{_Mq7hP~N^sJ=ut2z3b8k&*xvD2bAaJyB~?|HLX;R|z$9v(z14W!!5J66IV07O9{a zy4YxuNos9?=yCS~VjRzq&E06thYp2Nc*AYsHn};>R1S+#skCQ$QTITmeaW9SCMk88 z44^mx!GXovA=Hm8rfFuA3A~0{r)HYQ*D(>jW^(iNRBYviarWvOc{U&D)M3*X$hmUt zHQP+NGaUJ_g~$w0mZ2pOrRCd&ja#r!HGoQx5_nQVT>?&VN&-!--^Wb{HkwO7DM&`( zh+4NUMN7%Ba{@9om=3CARh{851d1#>QOVAM}5f#z-s+)jD|^EV5W)G zqi2z!8ksLdL|J(-&6G^vXbuQnEw3&#xlF64gN^q^}Z087sLsjS8zSje-fi+T3{O424j(&kstGDkfW{KiCT3s+@eFXQHOS1Y(1ec zsVIR;WmF^EytAdHM{Yh`y^uC(w7Yx(rj=f_40ez4Y+-5@Qk+7ClQeT|YExx0RkhI9 zMT=KjwZ*8K2vJ?`INE96IkjneYNM#dEpz4ILapyi(=9Xhvk~OvCZ(Tq@>LewXx>{g zO;7Gp7Ol?t2eY1qxFqy^_RGmla%qH1vnuw`h?q?rb5~}YQLSsGE4tk&Zw2>5+6U3j zsfW#4uTQJ@_N)-7@W5DVM|$t1#EfEvlR5|LMqA15G4Xw)UR5j*R;~D62U1&}$++5B zHov9EOf28ljEvS|qt_$d$qX*t=!+>?vN1Z1)&bmNsE3QVuhHlXz?Yj-nZEFGB@E?;3sUO0nxyP7KY;Ie+B802o5;~7n~ zIyqG1{FxpXETZ2>VrGdtXgc&STX%b_lk6wtxTmd(rI+?u0ShMAvm|nc7^_1v`gk1O|*Rz9jKPkeTOB~ zdT@tdu1EiEr4p`Fi;YiJ`Qg9zy9%BRhY2>dWU>@bzLOW^K1C7>B1<}LH)wO<8swH} z77tO{`=eG>%|Ztf{4i2R=Tn6AP>L)yTiRGRXE2rJrw{6)Nk(X(X(@`Rfa~Z zv(&H3Lrh(t(kzvi6=e+vXnaGW-NF;`rP+R!b{oms>K;Tx2{)41@FfuuO!X~RN#>Gj zZx&4>G=s@BGFOCBv3gBaJ~}8|zEa1N#`$io9^rt((^dSX>xM$!4kWd-esB_6=q!_*;>6*xJU3ZT^VSUG9}mA0AA+9$E;3)=&k)gIYE%Rt(Vlon3hmhmf{t(DK5x?00+xz#!r z7xfOT3*Ux17Zi2TYL}T6v<2bGSg*pOPQI3B`oyT7lyghv?BcJVxk^x&&b(j z+i|ckaw{cjF$`t79-YzQSWMJo(~WtR`IODps2fRgjaoMHDxC_8I{E0;36)%@j-@_j zvo+=cwbkfSR@9g`c;t3!dFxF;Uw0nr+`63zh`PnNKQu8OcKeIMGT@_+?c&l#_=KY_ z@FpejB=S=ABY{Ss7FyzpVU=(aQTL%X5Cqgia?>`xYVWI%r=!3 zHR_m^D&@%HY$;KTi7#rI0*o~h5Os?YqGs0FVYa-2BHug7r)SP7sOkE=ix;Z#`2Ij7 zAHaC`em)g}LMI2t@{ST=D=%s`$%d(P0V#1HCGZFtFcq^)j;)lag-eDlciIkdDI;nS z?cm33lDs+}=4H!RPx4aP*~yMjlsZ{Apc@pe=tR>{NC>81q1;m|wOv^eGzqaDr&M0o zU$b~_*T8!wVGnNs(8cl0&AZ(0b0#6`$CLYmc+MTwv1)YYSg7?D&`Y20T+hdTqpFWI zJ9$rCSLfTWB}n1Tj01E{zKY_@eVmAi5nTf4)-V=F%3Uf3qMmz~AwhTM8uKmx>L;gg zFIsk8C{IZAP3*Rs;fSV3woGl3{4fXWFyHcc-^ZyoyqzQ68u2Tnt0Sk6tH@+MF69_N zgQFy2x?!D`M-BI{P2E=VD5I+(546yB8h8$cg?x3|ovg%b8c5?zxeYgvFn!*g`&BSnS3EjQj`Cc&c(I(K+muz)6v%pBj%`(szFJ>I%(bDxODQ#^zhl$!;PB+^0 zH91Xz*@}{4LdO{AlWf@nlah^yf+2S%(NZciHCYJ?Y|JS{t9-Q-q;bHtV&YihM?)a! z7$-M90N*LnMny#tGA}fpffgQ^$j$Drl>baH7(PJbSOv7Xd~z+OPaZyO#>GavHvcMVqjWGX-74= zl&HHG@leL8p>JG~(7S>()6I;!~R>hsOcFLPR7C%pF+_H46Y*pp)}r%r@cPiQXYYpej(tTah#FB)4Gf*a81E_{!2tAw!Rp8hT!$qocC#Vdtd_#9h?lkVXn zYSoXhz-rfoTB<_1GN7XxUJi+D3TM7L)B>hR;%qj^0X#(d0(qXM)Iu(kPjdugx`Bn&!0OOb z-KRCqigTIjs@#HMLFg1E2?U&Fxq2hPH9JOyVj(u2DZ3XCz0m7poM$U~x>_|oeieH* zLXIrL4;2fL7({5qt&(<+0@!6vq}XE>LLdhL;qyzxQ5J2K)pJ^kqv((uBkgqS7@Y?5 z^3^6q*tPV|_DN~MTd*`mszSH?@Ngr-HySitlJ<^VvT}O8W)yX_^l&vAt4@ptg<FF}l{^W{b*FJpYq~F5Y_aDaYFz2UyZFurj#|qkCm46&DDS zwiclv#+e8KOya|y-UtuWx{caQ)AGCm#`Bq++(9KUFTLtReWLD04d%IJs6yb+f@T57 zc7b*FD7!MYriwAA^|B^k7UETC7`OZwtQ<%JBegN|4+p8?gL@BZ zm|V6B7yJ}2f0^+Yu0r5XZg^^>U^w81O&{-q_UV=~>QRhOJ>P84&{I3OYus%o>?Rki z^`v>K)eVzdq)^laN(w&VvlMhkF{eVB)rE@Vy&rlN7IpI5x5X;;D_!6P(=q;n=~n>Y zUHISQ|AN2Z1E!C50~qTC@Gz#+mjZZiKY-&81aKGreh28=2F;2Uo*VY=@>0j_unVBy#RE<7%Pr!XzNJb+`54`6&t0NXAI;4#d9$J+up zc_x4>>H$1I7r>{H&YdR(0GQr6AHWN*4dCdT1Nitv03SF%fG5TSSiLoXUHJF=M*`S9 zig|Yi@XyBt@GRE%0Mh^9kpVn_f4k!d#9RyD4E+4|R|N1(7{K%k0DG{W2azUV-5+dY z+nxuw@}>alNaG`jW8+Z)JlVj{w*+tzem`|<03YrkPcVHPe}6Z&_wf?~*mol0j%QyT$Y-Q~+AER2*zQ$Wb^>wT zycodKNbA|Nu-r?<|pNiihy{mTwaOEWd+;Ri<3)aPx_Y}%a2ix`{@fY)cdky0M4!|P;=11As z^;LlWzakH?U*7*UfZNt%n=eJ)UWPJpMF3yD3i*!jCa(H7fX`!k1k3JO5x|$Q+-aEq z6wJHlEdjg-dHevDd9H%kFx_57+E-)yu?=@`#-F2zaVyr1^*)LH{{?L4y{DrLz7G2v z+y2mMEI$^&WtSsAkuT3+o%fxF{ea&eIwOFY^N=TqeR?gH#XR?38NkXjv7OfhaND)W zGsJl;%Ip0o6DzPkpU1jy|1W?kl$|f1h-Fd69$pBb^Hv-K^m853dIQpVJ<0*nX}%eG zgtBl7%KdW}1n?>B{`bI#;8);-@Efojs_3*HC#bUdL?v>K^mnnO81!^myT$$9=giBX6uvFIw zx*CvNBGrLVNb1p;s8VirJ9T*oCwx<5T;g65UDTyRHWvCn8+%>k(DH)Ydd%?TmkTvl ze)X3sECm!^YPu)Eokpb;(|19pqM~aHF6Z~RWkRo_<}@{MT}PfS;za!S!trxi(_G}OtJF(q1?glV&P{|2V0ur z=}PM(kF?Px9#z$qc6gyNmx$$^MYpmpuhSSP+4fZFl!>N=0pHzT@1;9rc~RR--7_;5 zR+N-R8k0LbahozXt~5@1dYP1{_{7pK`W{U(h4{Q4Q}Df@irZ5VESIXElhYGC4sjKh zWP2Y=ct6tU`V_|?Up$6mQzy}!iABKoG~ziWwm}B-Zu|@F{TQCmMcS?hKPBV$rkHgttsf^H*iH6fg+7kk4~z$^Gv?m!Z9ET`-~_>-Yvx$Bs&J$rjxLSmt#fswv5DG?g-g)NzK`qY`f>oSD1x$pMDW&G9^7bDhD zl0h|uqi2P0N$~FiaYK+VN#WG|LW@_9pAH36uS-a|x%q3!on65j$kR;{d^C&cPkpri z%xoaQ87DhKZSp+eSaUr0#lg~b+>r>zQ<_UK`@v*xrb_W~-54HE*PPq(j1zArXnM$R zu1WE6xXvCH=Mk-jGG3pSdIo#d`J`DYw$#NJ$?@f<0#AJlD)k7@s^j20-DnPn5ZzD` zi!tnWiuEFA$061}?077mEhh;`W{B{$o}-X!ak&jHUXwHuTnB-+R*8<+h|&=o+Qkfs z`TTVnee7;rTxD!T5gF5Qu!;g+gEbCQC9#h#Wu;V1N&nXWxzCV`4jPJ+s@ml&u`efqn;(m(p$2 zxzwgBXRED{yR#6o;y!x{jbVCW3BvhdPO>AL#W?Yyp&ipYGKR(09=g3ORhZ(181`wf zEI5rzNe#qIVSi^PspjGyhk^)(lUZ!EXjSYy^JnZD^f$q1vxB$gP3kifM}`G$k+7KQ zNE_5zwz9+d!G?w@g0HGKwUK*GMNKNyi-<;>=9RZ%!c6b%p)v^_ou{7PtK63}uyVZI8Bur4c;;u#v}m$L^z(kE&jXi@~K1j!TR`A4i^M zw=S9yI**Z+&%Q?EA72HIJu0i!>ysGJl|~Q4MbllQaH)q6{AwK763OX>xaEO4W)6q^ z8Y6Q*llHa*)%3&k8oFpO;xaE*>CF&)9pv)y@iF6r;%d*?MPhTHi-d3q8^r`zcl} zH!YdIAPa5?L81Je8(XzSG_Oq;L8mrNPi-V@=tLHUwK>|Y!LV&4t!$*?)yF+ok!-YQ zmH82A3)@uL@8c77Vb7%EDj*=AM?0~oRAKJS>YgRa;Z z-5%WuSs?c;+iB}LzBXZaFrNC-@D(1dXxI|_^iq+2V=+Q+%5IAuzT^`>YZUsRq8#0b zq)5>q%p3bQ#;rS5l-w<8qQ$^HaZs-V}%;QdDuk3WA4zEl))#) z4vjTcD9ZQ|CuIx!TPNkMUgYE|jfUq8dYd;f<`%UdC#=D!%D%LKfz!PO^`bhlTWGQ8w-JN@j*7FU*t{758`!n@!HVP;3Rd9J`>%h?1Rddp7Fz=&6Rq zYSJAucxqJ-Vgp?(Vf)Vx)cVgcK;FaLT5pLYH zeZvh~rgvO-Lx=#vdNi{%kKbwjSnTu;b|%t)o{Rdk3wX~` z|3!~Xrp#ApJmLv;zguhd$T2vEsMOVL*Rlllv<5O9A+Mu)8XkU4!ZCBWAEm!y@)r)u zVULD7zZdncYut0(r6+l_NAm=Q-qj?(T+XfRA-#!_oreiozFUyFy$bF^_g@z!>J7K6_0F#awDHB3`yA^#B5YaW}HglY~_~n_I;34y|SK8oQ4LN)E-EG zt1-Odfq~jyZdtfaB{M!%<*nX!<@RurJFBG4GddJt;d$ijHdmtrH&MMR>TgAbwVihC z(uAe(HM-lcdB&P|(ah{aHWuETji>1ZWr1i2ykvbayQ-W`jJc#o<-j&> z4KgfF15T)rgA#9B1{H01G+Ilw zcuNE)`9p_O%)#vnM>v+t`#uz0uJK#x*)H_cSQDz3vov&bU*b&6cVZGbwGVC?=SzNT zOM;lWLQKOp|H&}nij;#TU;Ac3c{n#EwHI`88kFwzDazO!J=xYrd7bZB7l>joqqWwW zkJ#p(VKu1kdC1Dd$?1thjIR)9)s%qZ?EsZfF5m_=D9J9(8I62J@A1oNnKd(8?WJhO zbE0Z24s3CQW7L3xt9ukLz^{?fQixsB(=InNlTo~SONgj0P9D0L?;4;o7Nb(7=HW1< zMdPA_9bj1WuWM-+-D{*})4PcyRnq*z?o>&6w(o>HhuvPFjf|3b2xUnq_7jBq_ zI$P3olt^->ygF&6qB%>9L=M8H_~M`KV@KbmY<2JBwMs$Wy00_t`teZ`RXtc^K|v z*>)MJI!$TJ<3O0!Lh`Zyon6T?s7g4LrD-|2m1PV0IG349=j#W)!gd@i8nF-*@On{? z!qd9fDvc|b(@%o|%MnP_yhf?HQA6_r$#f9kKge@Kb1ayr28QjDmWEZxF)c%+74IXm zm8y$}%ND#z$G2U_s>&KRSzNNKbv{>T8OeIojOJ;FJl;-9{P5CvOSr0~N#TYcUX%E4 zy_=?0tU9+fEzDxhYg$s0SD1V!*<$0P=`naD2sa=!dOv1mK4C2n1a0BSmIr*8?riD0 z(t9yZgF$LSd6@;r3LJA>|mv76Xh zlEob5jHFy3YW(j^5Op_T^9@H`DW8?1uDouWR$~(KqJHZr-TtUXEhNMX?*7_JlW^O1 ze|cHm#wy>JHSasyO6S*H$jL4(pv7J7G?Y?KW|ASIRT5|~xIcSFcZqd7n(XjgJ-6hS z+?L^K@pP*Rmdyn(lRw2HGyI{w5}$$K@06DzQQS2zO)7O?yM&FFy7nxa#DdEjL1Yd^ z8C)fu^)mGEhO_RlOx4=_RIrvCN(QmU_tU-I1Cx4P z-_T65d$@W?+wxQ@Rue9}o$4_Qv*ykBt_N;|3BdBsgEApa&&NA&%2SniDNA}+(an)C zsU**xFv(WjsW2gs@5?n6d&}^A+_i8}yp+dHLZ!Hy;eY_1MdKSJvdSd`ft**Q*;o~z z#8lT7vYqddeVyxgH~?1E{g4w_YE`or7Nwg;{;r6EvWr7vlH2T-ILP4SoG5Y^a8Z;B z=Q%1$S-I$1Z=+`26*+}sPK!zDlqqbwZ6;RNiPu_@hfsNy>@nM-Zj34wt23j>TEL}I zDJ&cp4~(TYvT$zGIyUn11`}F8`m?65WNo@B0!~7{#6mw)j0CWFo!Qj?AQL~6dWQ6GrB;^&z1?Zixym!zf!)mQQzxIe_a zN15;Fj?Fu_T@!Ac+%XA*Z!WGko0qIyIXbp}e0*f}`jIs&m4742r?n%a$#46P+Zr4J zr|uow`wDz3@mPG$6#oSm$4;u}Zf73>-|oY=CHaTsXBAGGy0}rV^=s#@=3kwHzkCYQ z7n466fj_G-@>r5@Joz)ew}_QseLNriy$UNITY*1M!B_t1-w8^i&VyH-bPWELDAGTo zaL>&rU)z}NwtMZl{>t-jxM1bhE!(b%zfJvjJbtEvL;&zfLHg|^{Qs!DoH{g=fK z;=SkQAowqQdXiO0W#}IPTmih zl9>1L56MrG7^1rjlHk(2XJXYx_iS&zO~`y>Bki+TfsJpLk+wErQ7ptX(&T^ANE_pS zC&B#;|B(C~GJjoo`Ub4pB96XXo#5(g<-X$pXqavdNQYe>x9~{gGm$B~i#&R1nW0n< z-eY58EEyUpG*v`{@Aw+gWH&kVfE0KRV|8?N-C(TB+^HcRdQny9Zm)RXY1m})Qcpr~ zC=mTQh#mx5#Pf*w2p7b9R+>OlZstr@8aMBHRSp*r_mRtnJ1eqEGaMvj?Sx)pS0V1B z81Br1oIK2xdel!2wT>HV9l=_Uj%&?(jI><+6Wshsjnm7p{$rB*dCcX0C=Opz!yySm zP!bCl_!O23Vma1=B`fG!IQ}|pyW}6NkT7dDt&p_pc!;6 zy0q>cY=otdT!Bd5pdfJzf~1O;^2tGmtm7&qg@(4WSH@`agDWX@`s)UZ{y!^0P&jCl z3e9`mjY{VO@($AV$epuo*m9PHJp4gMmc*!TotC~GCGaC zh#_){zg7;#xM4J3j40kLqcFsED_8q^0}sejyf|GubMWOs1K0{mdiQzzq~u^+eikt7 z7_3KRmoQ|map+VQdFzq&1|-)al93n*cTg`B;I1UP(Ge~{>WoeY;G=|2jdka-q8s#P z963*gseE$KgSNev)mfC*)!a~V8D_5Qkb7%1xExk;HhBKBXR$!WviK~kI2$bA-W(m_ zYD1MdvLe?SP`Rw&hKbRp-N!jb+v+U|d8qJ4opDOa{W?NXIFw>JTZ)9%A52I1=W2EPBn8b@VJV*+`pmXpekq}%@Bl^| ze>gjdwjI~Ea10H6u>r$|#|Jk$BZ=(D?B=g`FWJt2FZ04uemBI%m&+NJTcX)MPQ?48 z^zHa0$W&}c#bJUK!SKI*VcVs=f?+8Uwo?VCd~%TC3BwwCBaZKiip?V&sDeTrWe%9u z8!*xCcr_Q3$?=iq3>IdzBszme+=A#PbJ1yhDNVq<$KQI34KSrcrgg3)wOOsoaZ$_h z%O+tPoKewEQVc8!S5*$v=o-!{)h=maA8xc^^74A5j+MQML>$+0=+_(0X|F=`o3!Y4 z4y?SNB|lshmbd&(7;I$P-MP{km)z5uO)zg%w!Xf~hU$MrUyrWl+t{k4Hjt;ARrIz% zwwhDS+$gpsrD1e6SK})3CL-VBj@-J1Y!36Qf>%Dd%s>W7rq$lnD)wTbeHB0jEDFxr z)Q%L*kk=^qip308;VGY7xM$f1*{Yz^MedMpbET!0#UfVV`15XbM6dg&k$2bnpwmdE z4xj?pfqS-nnr$k+Qo)lIT;4X?=m_s*b#(7WE?(!1Qp3W@P12ywY!3Qs|JC{(2)aQ$ zt>PSVwC9riU9IQue#Cu!3ir^XNUP8b@Z60321o3L!&8^VKCage%hT*UGjtxSa-Ul2`svRt2{Gi(Li`hO39A_m(CMt4zATzB>m? z_R3)fj`x_h?P2UO;BgOstO}3v$w97dH(&M|v6%xaEA{)&jH7ysJ;a{7(SSx?B|35~ z-pz=kpsR4bdv;Z6B?ot@5;U9}|auL@fE? z{(8$cPTyuj!Uw6m+|6Fy^zTi}t;3rQc>ET+<#oyEsNN>K8GA2GVKm0EPp=Jd3p=%< z9R#sgyIA?;AZs>nzkRM~wT7-EU~d_)?Zebm#6IEt6~_6G6x&(gjEbtnI{_+4<S z+x%W<6^u^r4=C09bIi7%TTh|!dDuXOrF?SWk?m$@q(wDsJI!_%WloF0aZb&sHecS@ zEXa8SvSqVFEcZPYv{(vQA*DGsI?6Y*)qRAUa4u-%q4csnGElws>ZoNe;T9d%p#_Ck zw?q^;{_~e@Y`0Z(bL4@EdeIx5yf(d-hwffV1SaEeQ8dHtj; zYKyghtAe`3vnr)A^1}*M!;>dZSHW2Jy%rUy^2uQ=jat_2JrA5(Q(yNEi~_L0=(6;E zKa02612bhYS|X(^WijSIFr!)ZrCzQni`X&~94LZVD-OCRaa7>SCl~2mqrctT$5D3B zihGz(?I@_d?G&5Gy-O~sCZpIK;I zjDEY!wxG?b{vHL@uwOGOC#|+s=-UB|n7kbwj4tTIi=bgcDiIy7c?f z=;(bMoVj{Y3nK&btG$-kL3pW_?lWa!Djapurz3o@s8-8fmVd7iWPy;PXqQaCzdw(@@{i?hT_Un)@LlS`jl_M3jV08TAeab!2VA-MhaV;jV9Xjo0 z?ef-+?F{Em9qRw~JNZB1jEZz0N>;Txl-oBpPTi%&WV_WaUe{A(-+TVGc`y8=GpZqT zikqgX(Mh+H?@nPV^ctYbGXIe}!qu8OZ{2|Se#!%%c5bED0W-r=0qigf*y7>dlSY_& znoqi)Yy^nY|MYnLpb}!G-$qC9mkjKoa`vYc+{NETRCwtQ=Gy2Q{b;=vW$itA$h?-~j+bS;XJ=ca zvtLnKz#qBIds0^!uimz@Z7=G*`FL_VSi$Bp>#o+@1#{TH@6)1Lj!yMOZMy;Weg$=* zr-cO?OloABxJ77W0%BXn`eHDaCp2sT7KPRd*R_j9F6nM zZfyuuZ<)632mLl-a(*aW?JDJygHE=^h5j(dLDz};#tRYQfeFoNK6(q{o@ceZOxtXz z-x(l8gIx``hGPmL5Id5`i7`j=vbn+|b;vnz%od;S5yIp4V!8^#TYhXWxBPC5qTP?e z+8o`&?PFlNT5o?9tE^V>&7M71mG2ds4*Uq!U;K^tlAN){D*8P_mjAN0{_*&-xcKHx zY8ImiD!L%-Rg7(B}Gpk>7Ftm19=r4G~Ohwx9N4TgfjCOdzaV4%YUu8qP@ zt=n((8yIn;8wYOAT10fdo85@?*OJ`DA~ohNz%ln&jBF_#ijg=ngqm$0P=92pndU6i z)k)m`c;3an8b(Y=+v@A%38H>uF$yuNX^Sr5X6DoBsf{AqA(4Gh&s!F3?f(;2Gv4^LMBK;bXH9h9_S-zA|1?1n)&?(?uvoWUHdyyg#z(wU z8#j+25c+*2{;m9MZi_4X363gi)x-8&*l2Z@`c?Vy!QsS}wcT$1GmasD?#AJ}dyHob zwL{0Z&usTZ9*>cAY6n|k4f#V`KH*%u8`hdlNs39S@R8kY^oD}U7Lnr5303Ma%@l^W z{5>gK&wVmRvOw<8VH{Apo>lgHCo7Y?8g&wK)mYC!^X@r|&Gi=&vR*TaIyzt!Fd^21 z_@W&OQ@=60A1BZyyc@1j$-d}pqwWa_-Qh;m)UqwRH1^htHhuJ$35NDToTckwv)1dA zT(@V#=+JD`p$R-ZFqWMsGTr8l%63cPNrB1^WA~W&9;Hk7JhX3**>HU-#$`Cr)CX-E z-l?47_9XdVJmrEbW0`Vj;kNR#i*5hquQ)o79igF|$nm3xlx0ZwU_UKm^4S;C0P~fw zQOixX&v0Cw?tkM-(Y6A5nh-9vJo+-L!hAVqJ6rwh7*A)uTdPO(0t!D-oo#m_RA}wl z{Z&3PH6x(B9ve5@n;b;Qqu>>U;g+Z)f% z4p1}}QLsC>CX71<)qBsb3VIe?Y}qF+oOZ4@--XyOfQRnAzO2!hg}`^yR}xYHcN(O zX^tCY{2Z+RAF}l~+qLrCw!I|(kJ&o4j8??kVgJuImcN*-vyb*EY1c49MHkh}a@i(d fU((i2mCqdRN2O~voC&`P`}d!+H8Y#U(CYsS&+jJz diff --git a/lib/3rdParty/tbb/lib/x86/v140/tbb_preview.lib b/lib/3rdParty/tbb/lib/x86/v140/tbb_preview.lib deleted file mode 100644 index da1cfbf84c2c996dbc20f0e54bb535e81a4d2a4e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 100676 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 - - - - - - - $(SolutionDir)lib\3rdParty\tbb\include;%(AdditionalIncludeDirectories) - - - $(SolutionDir)lib\3rdParty\tbb\lib\$(PlatformShortName)\$(PlatformToolset);%(AdditionalLibraryDirectories) - tbb.lib;%(AdditionalDependencies) - - - xcopy /I /E /Y /D /C "$(SolutionDir)lib\3rdParty\tbb\bin\$(PlatformShortName)\$(PlatformToolset)\tbb.dll" "$(OutDir)" - - - - \ No newline at end of file diff --git a/lib/3rdParty/tbb/tbb_d.props b/lib/3rdParty/tbb/tbb_d.props deleted file mode 100644 index 4b300f96..00000000 --- a/lib/3rdParty/tbb/tbb_d.props +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - $(SolutionDir)lib\3rdParty\tbb\include;%(AdditionalIncludeDirectories) - - - $(SolutionDir)lib\3rdParty\tbb\lib\$(PlatformShortName)\$(PlatformToolset);%(AdditionalLibraryDirectories) - tbb_debug.lib;%(AdditionalDependencies) - - - xcopy /I /E /Y /D /C "$(SolutionDir)lib\3rdParty\tbb\bin\$(PlatformShortName)\$(PlatformToolset)\tbb_debug.dll" "$(OutDir)" - - - - \ No newline at end of file diff --git a/lib/local/CppInerop/CppInerop.vcxproj b/lib/local/CppInerop/CppInerop.vcxproj index 8b13fa5e..7551cf4a 100644 --- a/lib/local/CppInerop/CppInerop.vcxproj +++ b/lib/local/CppInerop/CppInerop.vcxproj @@ -64,7 +64,6 @@ - @@ -72,7 +71,6 @@ - @@ -80,7 +78,6 @@ - @@ -88,7 +85,6 @@ - diff --git a/lib/local/FaceAnalyser/CMakeLists.txt b/lib/local/FaceAnalyser/CMakeLists.txt index ef2b7d57..a55f4dc0 100644 --- a/lib/local/FaceAnalyser/CMakeLists.txt +++ b/lib/local/FaceAnalyser/CMakeLists.txt @@ -33,12 +33,11 @@ target_include_directories(FaceAnalyser PUBLIC $/include/OpenFace>) target_include_directories(FaceAnalyser PRIVATE ${FACEANALYSER_SOURCE_DIR}/include) -target_include_directories(FaceAnalyser PUBLIC ${TBB_ROOT_DIR}/include) target_include_directories(FaceAnalyser PUBLIC ${Boost_INCLUDE_DIRS}) target_include_directories(FaceAnalyser PUBLIC ${Boost_INCLUDE_DIRS}/boost) target_include_directories(FaceAnalyser PUBLIC ${OpenCV_INCLUDE_DIRS}) -target_link_libraries(FaceAnalyser PUBLIC ${OpenCV_LIBS} ${Boost_LIBRARIES} ${TBB_LIBRARIES} ${OpenBLAS_LIB}) +target_link_libraries(FaceAnalyser PUBLIC ${OpenCV_LIBS} ${Boost_LIBRARIES} ${OpenBLAS_LIB}) target_link_libraries(FaceAnalyser PUBLIC dlib::dlib) target_include_directories(FaceAnalyser PRIVATE ${OpenBLAS_INCLUDE_DIR}) diff --git a/lib/local/FaceAnalyser/FaceAnalyser.vcxproj b/lib/local/FaceAnalyser/FaceAnalyser.vcxproj index 87f344c9..4a903c50 100644 --- a/lib/local/FaceAnalyser/FaceAnalyser.vcxproj +++ b/lib/local/FaceAnalyser/FaceAnalyser.vcxproj @@ -56,7 +56,6 @@ - @@ -65,14 +64,12 @@ - - @@ -80,7 +77,6 @@ - diff --git a/lib/local/GazeAnalyser/CMakeLists.txt b/lib/local/GazeAnalyser/CMakeLists.txt index d98974a2..144ba046 100644 --- a/lib/local/GazeAnalyser/CMakeLists.txt +++ b/lib/local/GazeAnalyser/CMakeLists.txt @@ -20,12 +20,11 @@ target_include_directories(GazeAnalyser PUBLIC $/include/OpenFace>) target_include_directories(GazeAnalyser PRIVATE ${GAZEANALYSER_SOURCE_DIR}/include) -target_include_directories(GazeAnalyser PUBLIC ${TBB_ROOT_DIR}/include) target_include_directories(GazeAnalyser PUBLIC ${Boost_INCLUDE_DIRS}) target_include_directories(GazeAnalyser PUBLIC ${Boost_INCLUDE_DIRS}/boost) target_include_directories(GazeAnalyser PUBLIC ${OpenCV_INCLUDE_DIRS}) -target_link_libraries(GazeAnalyser PUBLIC ${OpenCV_LIBS} ${Boost_LIBRARIES} ${TBB_LIBRARIES} ${OpenBLAS_LIB}) +target_link_libraries(GazeAnalyser PUBLIC ${OpenCV_LIBS} ${Boost_LIBRARIES} ${OpenBLAS_LIB}) target_link_libraries(GazeAnalyser PUBLIC dlib::dlib) target_include_directories(GazeAnalyser PRIVATE ${OpenBLAS_INCLUDE_DIR}) diff --git a/lib/local/GazeAnalyser/GazeAnalyser.vcxproj b/lib/local/GazeAnalyser/GazeAnalyser.vcxproj index 9a964dfd..8e262e47 100644 --- a/lib/local/GazeAnalyser/GazeAnalyser.vcxproj +++ b/lib/local/GazeAnalyser/GazeAnalyser.vcxproj @@ -57,28 +57,24 @@ - - - - diff --git a/lib/local/LandmarkDetector/CMakeLists.txt b/lib/local/LandmarkDetector/CMakeLists.txt index 21d900c9..adc26239 100644 --- a/lib/local/LandmarkDetector/CMakeLists.txt +++ b/lib/local/LandmarkDetector/CMakeLists.txt @@ -45,12 +45,11 @@ target_include_directories(LandmarkDetector PUBLIC $/include/OpenFace>) target_include_directories(LandmarkDetector PRIVATE ${LandmarkDetector_SOURCE_DIR}/include) -target_include_directories(LandmarkDetector PUBLIC ${TBB_ROOT_DIR}/include) target_include_directories(LandmarkDetector PUBLIC ${Boost_INCLUDE_DIRS}) target_include_directories(LandmarkDetector PUBLIC ${Boost_INCLUDE_DIRS}/boost) target_include_directories(LandmarkDetector PUBLIC ${OpenCV_INCLUDE_DIRS}) -target_link_libraries(LandmarkDetector PUBLIC ${OpenCV_LIBS} ${Boost_LIBRARIES} ${TBB_LIBRARIES} ${OpenBLAS_LIB}) +target_link_libraries(LandmarkDetector PUBLIC ${OpenCV_LIBS} ${Boost_LIBRARIES} ${OpenBLAS_LIB}) target_link_libraries(LandmarkDetector PUBLIC dlib::dlib) target_include_directories(LandmarkDetector PRIVATE ${OpenBLAS_INCLUDE_DIR}) diff --git a/lib/local/LandmarkDetector/LandmarkDetector.vcxproj b/lib/local/LandmarkDetector/LandmarkDetector.vcxproj index cf50f08b..4220ddac 100644 --- a/lib/local/LandmarkDetector/LandmarkDetector.vcxproj +++ b/lib/local/LandmarkDetector/LandmarkDetector.vcxproj @@ -54,7 +54,6 @@ - @@ -62,7 +61,6 @@ - @@ -70,7 +68,6 @@ - @@ -78,7 +75,6 @@ - diff --git a/lib/local/LandmarkDetector/src/FaceDetectorMTCNN.cpp b/lib/local/LandmarkDetector/src/FaceDetectorMTCNN.cpp index 886d5a88..5ba1c3eb 100644 --- a/lib/local/LandmarkDetector/src/FaceDetectorMTCNN.cpp +++ b/lib/local/LandmarkDetector/src/FaceDetectorMTCNN.cpp @@ -40,9 +40,6 @@ #include #include -// TBB includes -#include - // System includes #include @@ -681,7 +678,6 @@ bool FaceDetectorMTCNN::DetectFaces(vector >& o_regions, const vector > scores_cross_scale(num_scales); vector > > proposal_corrections_cross_scale(num_scales); - //tbb::parallel_for(0, (int)num_scales, [&](int i) { for (int i = 0; i < num_scales; ++i) { double scale = ((double)face_support / (double)min_face_size)*cv::pow(pyramid_factor, i); @@ -746,7 +742,7 @@ bool FaceDetectorMTCNN::DetectFaces(vector >& o_regions, const // Creating proposal images from previous step detections vector above_thresh; above_thresh.resize(proposal_boxes_all.size(), false); - //tbb::parallel_for(0, (int)proposal_boxes_all.size(), [&](int k) { + for (size_t k = 0; k < proposal_boxes_all.size(); ++k) { float width_target = proposal_boxes_all[k].width + 1; @@ -819,7 +815,7 @@ bool FaceDetectorMTCNN::DetectFaces(vector >& o_regions, const // Preparing for the ONet stage above_thresh.clear(); above_thresh.resize(proposal_boxes_all.size()); - //tbb::parallel_for(0, (int)proposal_boxes_all.size(), [&](int k) { + for (size_t k = 0; k < proposal_boxes_all.size(); ++k) { float width_target = proposal_boxes_all[k].width + 1; diff --git a/lib/local/LandmarkDetector/src/LandmarkDetectionValidator.cpp b/lib/local/LandmarkDetector/src/LandmarkDetectionValidator.cpp index 13f2e6f0..9e30b3be 100644 --- a/lib/local/LandmarkDetector/src/LandmarkDetectionValidator.cpp +++ b/lib/local/LandmarkDetector/src/LandmarkDetectionValidator.cpp @@ -40,9 +40,6 @@ #include #include -// TBB includes -#include - // System includes #include diff --git a/lib/local/LandmarkDetector/src/LandmarkDetectorModel.cpp b/lib/local/LandmarkDetector/src/LandmarkDetectorModel.cpp index 136fd591..5416dd88 100644 --- a/lib/local/LandmarkDetector/src/LandmarkDetectorModel.cpp +++ b/lib/local/LandmarkDetector/src/LandmarkDetectorModel.cpp @@ -40,9 +40,6 @@ #include #include -// TBB includes -#include - // Local includes #include #include @@ -646,41 +643,43 @@ bool CLNF::DetectLandmarks(const cv::Mat_ &image, FaceModelParameters& pa bool parts_used = false; // Do the hierarchical models in parallel - tbb::parallel_for(0, (int)hierarchical_models.size(), [&](int part_model){ - { - - int n_part_points = hierarchical_models[part_model].pdm.NumberOfPoints(); - - vector> mappings = this->hierarchical_mapping[part_model]; - - cv::Mat_ part_model_locs(n_part_points * 2, 1, 0.0f); - - // Extract the corresponding landmarks - for (size_t mapping_ind = 0; mapping_ind < mappings.size(); ++mapping_ind) + parallel_for_(cv::Range(0, hierarchical_models.size()), [&](const cv::Range& range) { + for (int part_model = range.start; part_model < range.end; part_model++) { - part_model_locs.at(mappings[mapping_ind].second) = detected_landmarks.at(mappings[mapping_ind].first); - part_model_locs.at(mappings[mapping_ind].second + n_part_points) = detected_landmarks.at(mappings[mapping_ind].first + this->pdm.NumberOfPoints()); + + int n_part_points = hierarchical_models[part_model].pdm.NumberOfPoints(); + + vector> mappings = this->hierarchical_mapping[part_model]; + + cv::Mat_ part_model_locs(n_part_points * 2, 1, 0.0f); + + // Extract the corresponding landmarks + for (size_t mapping_ind = 0; mapping_ind < mappings.size(); ++mapping_ind) + { + part_model_locs.at(mappings[mapping_ind].second) = detected_landmarks.at(mappings[mapping_ind].first); + part_model_locs.at(mappings[mapping_ind].second + n_part_points) = detected_landmarks.at(mappings[mapping_ind].first + this->pdm.NumberOfPoints()); + } + + // Fit the part based model PDM + hierarchical_models[part_model].pdm.CalcParams(hierarchical_models[part_model].params_global, hierarchical_models[part_model].params_local, part_model_locs); + + // Only do this if we don't need to upsample + if (params_global[0] > 0.9 * hierarchical_models[part_model].patch_experts.patch_scaling[0]) + { + parts_used = true; + + this->hierarchical_params[part_model].window_sizes_current = this->hierarchical_params[part_model].window_sizes_init; + + // Do the actual landmark detection + hierarchical_models[part_model].DetectLandmarks(image, hierarchical_params[part_model]); + + } + else + { + hierarchical_models[part_model].pdm.CalcShape2D(hierarchical_models[part_model].detected_landmarks, hierarchical_models[part_model].params_local, hierarchical_models[part_model].params_global); + } + } - - // Fit the part based model PDM - hierarchical_models[part_model].pdm.CalcParams(hierarchical_models[part_model].params_global, hierarchical_models[part_model].params_local, part_model_locs); - - // Only do this if we don't need to upsample - if (params_global[0] > 0.9 * hierarchical_models[part_model].patch_experts.patch_scaling[0]) - { - parts_used = true; - - this->hierarchical_params[part_model].window_sizes_current = this->hierarchical_params[part_model].window_sizes_init; - - // Do the actual landmark detection - hierarchical_models[part_model].DetectLandmarks(image, hierarchical_params[part_model]); - - } - else - { - hierarchical_models[part_model].pdm.CalcShape2D(hierarchical_models[part_model].detected_landmarks, hierarchical_models[part_model].params_local, hierarchical_models[part_model].params_global); - } - } }); // Recompute main model based on the fit part models diff --git a/lib/local/LandmarkDetector/src/Patch_experts.cpp b/lib/local/LandmarkDetector/src/Patch_experts.cpp index 9ceb3c75..f7c90734 100644 --- a/lib/local/LandmarkDetector/src/Patch_experts.cpp +++ b/lib/local/LandmarkDetector/src/Patch_experts.cpp @@ -38,9 +38,6 @@ #include "RotationHelpers.h" -// TBB includes -#include - // Math includes #define _USE_MATH_DEFINES #include @@ -212,133 +209,129 @@ void Patch_experts::Response(vector >& patch_expert_responses, c // We do not want to create threads for invisible landmarks, so construct an index of visible ones std::vector vis_lmk = Collect_visible_landmarks(visibilities, scale, view_id, n); - // calculate the patch responses for every landmark, Actual work happens here. If openMP is turned on it is possible to do this in parallel, - // this might work well on some machines, while potentially have an adverse effect on others - //#ifdef _OPENMP - //#pragma omp parallel for - //#endif - tbb::parallel_for(0, (int)vis_lmk.size(), [&](int i) { - //for (int i = 0; i < vis_lmk.size(); i++) - { - - // Work out how big the area of interest has to be to get a response of window size - int area_of_interest_width; - int area_of_interest_height; - int ind = vis_lmk.at(i); - - if (use_cen) - { - area_of_interest_width = window_size + cen_expert_intensity[scale][view_id][ind].width_support - 1; - area_of_interest_height = window_size + cen_expert_intensity[scale][view_id][ind].height_support - 1; - } - else if (use_ccnf) - { - area_of_interest_width = window_size + ccnf_expert_intensity[scale][view_id][ind].width - 1; - area_of_interest_height = window_size + ccnf_expert_intensity[scale][view_id][ind].height - 1; - } - else - { - area_of_interest_width = window_size + svr_expert_intensity[scale][view_id][ind].width - 1; - area_of_interest_height = window_size + svr_expert_intensity[scale][view_id][ind].height - 1; - } - - // scale and rotate to mean shape to reference frame - cv::Mat sim = (cv::Mat_(2, 3) << a1, -b1, landmark_locations.at(ind, 0) - a1 * (area_of_interest_width - 1.0f) / 2.0f + b1 * (area_of_interest_width - 1.0f) / 2.0f, b1, a1, landmark_locations.at(ind + n, 0) - a1 * (area_of_interest_width - 1.0f) / 2.0f - b1 * (area_of_interest_width - 1.0f) / 2.0f); - - // Extract the region of interest around the current landmark location - cv::Mat_ area_of_interest(area_of_interest_height, area_of_interest_width, 0.0f); - - cv::warpAffine(grayscale_image, area_of_interest, sim, area_of_interest.size(), cv::WARP_INVERSE_MAP + cv::INTER_LINEAR); - - // Get intensity response either from the SVR, CCNF, or CEN patch experts (prefer CEN as they are the most accurate so far) - if (!cen_expert_intensity.empty()) + // calculate the patch responses for every landmark (this is the heavy lifting of landmark detection) + parallel_for_(cv::Range(0, vis_lmk.size()), [&](const cv::Range& range) { + for (int i = range.start; i < range.end; i++) { - int im2col_size = (area_of_interest_width * area_of_interest_height - 1) / 2; + // Work out how big the area of interest has to be to get a response of window size + int area_of_interest_width; + int area_of_interest_height; + int ind = vis_lmk.at(i); - cv::Mat_ prealloc_mat = preallocated_im2col[ind][im2col_size]; - - // If frontal view we can do mirrored landmarks together - if (view_id == 0) + if (use_cen) { - // If the patch expert does not have values, means it's a mirrored version and will be done in another part of a loop - if (!cen_expert_intensity[scale][view_id][ind].biases.empty()) - { - // No mirrored expert, so do normally - int mirror_id = mirror_inds.at(ind); - if (mirror_id == ind) - { - cv::Mat_ empty(0,0,0.0f); - cen_expert_intensity[scale][view_id][ind].ResponseSparse(area_of_interest, empty, patch_expert_responses[ind], empty, interp_mat, prealloc_mat, empty); - } - else - { - - // Grab mirrored area of interest - - // scale and rotate to mean shape to reference frame - cv::Mat sim_r = (cv::Mat_(2, 3) << a1, -b1, landmark_locations.at(mirror_id, 0) - a1 * (area_of_interest_width - 1.0f) / 2.0f + b1 * (area_of_interest_width - 1.0f) / 2.0f, b1, a1, landmark_locations.at(mirror_id + n, 0) - a1 * (area_of_interest_width - 1.0f) / 2.0f - b1 * (area_of_interest_width - 1.0f) / 2.0f); - - // Extract the region of interest around the current landmark location - cv::Mat_ area_of_interest_r(area_of_interest_height, area_of_interest_width, 0.0f); - - cv::warpAffine(grayscale_image, area_of_interest_r, sim_r, area_of_interest_r.size(), cv::WARP_INVERSE_MAP + cv::INTER_LINEAR); - - cv::Mat_ prealloc_mat_right = preallocated_im2col[mirror_id][im2col_size]; - - cen_expert_intensity[scale][view_id][ind].ResponseSparse(area_of_interest, area_of_interest_r, patch_expert_responses[ind], patch_expert_responses[mirror_id], interp_mat, prealloc_mat, prealloc_mat_right); - - preallocated_im2col[mirror_id][im2col_size] = prealloc_mat_right; - - } - } + area_of_interest_width = window_size + cen_expert_intensity[scale][view_id][ind].width_support - 1; + area_of_interest_height = window_size + cen_expert_intensity[scale][view_id][ind].height_support - 1; + } + else if (use_ccnf) + { + area_of_interest_width = window_size + ccnf_expert_intensity[scale][view_id][ind].width - 1; + area_of_interest_height = window_size + ccnf_expert_intensity[scale][view_id][ind].height - 1; } else { - // For space and memory saving use a mirrored patch expert - if (!cen_expert_intensity[scale][view_id][ind].biases.empty()) + area_of_interest_width = window_size + svr_expert_intensity[scale][view_id][ind].width - 1; + area_of_interest_height = window_size + svr_expert_intensity[scale][view_id][ind].height - 1; + } + + // scale and rotate to mean shape to reference frame + cv::Mat sim = (cv::Mat_(2, 3) << a1, -b1, landmark_locations.at(ind, 0) - a1 * (area_of_interest_width - 1.0f) / 2.0f + b1 * (area_of_interest_width - 1.0f) / 2.0f, b1, a1, landmark_locations.at(ind + n, 0) - a1 * (area_of_interest_width - 1.0f) / 2.0f - b1 * (area_of_interest_width - 1.0f) / 2.0f); + + // Extract the region of interest around the current landmark location + cv::Mat_ area_of_interest(area_of_interest_height, area_of_interest_width, 0.0f); + + cv::warpAffine(grayscale_image, area_of_interest, sim, area_of_interest.size(), cv::WARP_INVERSE_MAP + cv::INTER_LINEAR); + + // Get intensity response either from the SVR, CCNF, or CEN patch experts (prefer CEN as they are the most accurate so far) + if (!cen_expert_intensity.empty()) + { + + int im2col_size = (area_of_interest_width * area_of_interest_height - 1) / 2; + + cv::Mat_ prealloc_mat = preallocated_im2col[ind][im2col_size]; + + // If frontal view we can do mirrored landmarks together + if (view_id == 0) { - cv::Mat_ empty(0, 0, 0.0f); - cen_expert_intensity[scale][view_id][ind].ResponseSparse(area_of_interest, empty, patch_expert_responses[ind], empty, interp_mat, prealloc_mat, empty); - - // A slower, but slightly more accurate version - //cen_expert_intensity[scale][view_id][ind].Response(area_of_interest, patch_expert_responses[ind]); + // If the patch expert does not have values, means it's a mirrored version and will be done in another part of a loop + if (!cen_expert_intensity[scale][view_id][ind].biases.empty()) + { + // No mirrored expert, so do normally + int mirror_id = mirror_inds.at(ind); + if (mirror_id == ind) + { + cv::Mat_ empty(0, 0, 0.0f); + cen_expert_intensity[scale][view_id][ind].ResponseSparse(area_of_interest, empty, patch_expert_responses[ind], empty, interp_mat, prealloc_mat, empty); + } + else + { + + // Grab mirrored area of interest + + // scale and rotate to mean shape to reference frame + cv::Mat sim_r = (cv::Mat_(2, 3) << a1, -b1, landmark_locations.at(mirror_id, 0) - a1 * (area_of_interest_width - 1.0f) / 2.0f + b1 * (area_of_interest_width - 1.0f) / 2.0f, b1, a1, landmark_locations.at(mirror_id + n, 0) - a1 * (area_of_interest_width - 1.0f) / 2.0f - b1 * (area_of_interest_width - 1.0f) / 2.0f); + + // Extract the region of interest around the current landmark location + cv::Mat_ area_of_interest_r(area_of_interest_height, area_of_interest_width, 0.0f); + + cv::warpAffine(grayscale_image, area_of_interest_r, sim_r, area_of_interest_r.size(), cv::WARP_INVERSE_MAP + cv::INTER_LINEAR); + + cv::Mat_ prealloc_mat_right = preallocated_im2col[mirror_id][im2col_size]; + + cen_expert_intensity[scale][view_id][ind].ResponseSparse(area_of_interest, area_of_interest_r, patch_expert_responses[ind], patch_expert_responses[mirror_id], interp_mat, prealloc_mat, prealloc_mat_right); + + preallocated_im2col[mirror_id][im2col_size] = prealloc_mat_right; + + } + } } else { - cv::Mat_ empty(0, 0, 0.0f); - cen_expert_intensity[scale][mirror_views.at(view_id)][mirror_inds.at(ind)].ResponseSparse(empty, area_of_interest, empty, patch_expert_responses[ind], interp_mat, empty, prealloc_mat); + // For space and memory saving use a mirrored patch expert + if (!cen_expert_intensity[scale][view_id][ind].biases.empty()) + { + cv::Mat_ empty(0, 0, 0.0f); + cen_expert_intensity[scale][view_id][ind].ResponseSparse(area_of_interest, empty, patch_expert_responses[ind], empty, interp_mat, prealloc_mat, empty); + + // A slower, but slightly more accurate version + //cen_expert_intensity[scale][view_id][ind].Response(area_of_interest, patch_expert_responses[ind]); + } + else + { + cv::Mat_ empty(0, 0, 0.0f); + cen_expert_intensity[scale][mirror_views.at(view_id)][mirror_inds.at(ind)].ResponseSparse(empty, area_of_interest, empty, patch_expert_responses[ind], interp_mat, empty, prealloc_mat); + } } + + preallocated_im2col[ind][im2col_size] = prealloc_mat; + } + else if (!ccnf_expert_intensity.empty()) + { + // get the correct size response window + patch_expert_responses[ind] = cv::Mat_(window_size, window_size); - preallocated_im2col[ind][im2col_size] = prealloc_mat; + int im2col_size = area_of_interest_width * area_of_interest_height; + cv::Mat_ prealloc_mat = preallocated_im2col[ind][im2col_size]; + + ccnf_expert_intensity[scale][view_id][ind].ResponseOpenBlas(area_of_interest, patch_expert_responses[ind], prealloc_mat); + + preallocated_im2col[ind][im2col_size] = prealloc_mat; + + // Below is an alternative way to compute the same, but that uses FFT instead of OpenBLAS + // ccnf_expert_intensity[scale][view_id][ind].Response(area_of_interest, patch_expert_responses[ind]); + + } + else + { + // get the correct size response window + patch_expert_responses[ind] = cv::Mat_(window_size, window_size); + + svr_expert_intensity[scale][view_id][ind].Response(area_of_interest, patch_expert_responses[ind]); + } } - else if (!ccnf_expert_intensity.empty()) - { - // get the correct size response window - patch_expert_responses[ind] = cv::Mat_(window_size, window_size); - - int im2col_size = area_of_interest_width * area_of_interest_height; - - cv::Mat_ prealloc_mat = preallocated_im2col[ind][im2col_size]; - - ccnf_expert_intensity[scale][view_id][ind].ResponseOpenBlas(area_of_interest, patch_expert_responses[ind], prealloc_mat); - - preallocated_im2col[ind][im2col_size] = prealloc_mat; - - // Below is an alternative way to compute the same, but that uses FFT instead of OpenBLAS - // ccnf_expert_intensity[scale][view_id][ind].Response(area_of_interest, patch_expert_responses[ind]); - - } - else - { - // get the correct size response window - patch_expert_responses[ind] = cv::Mat_(window_size, window_size); - - svr_expert_intensity[scale][view_id][ind].Response(area_of_interest, patch_expert_responses[ind]); - } - } }); } diff --git a/lib/local/Utilities/CMakeLists.txt b/lib/local/Utilities/CMakeLists.txt index a53cb2e2..3940e000 100644 --- a/lib/local/Utilities/CMakeLists.txt +++ b/lib/local/Utilities/CMakeLists.txt @@ -28,12 +28,11 @@ target_include_directories(Utilities PUBLIC $/include/OpenFace>) target_include_directories(Utilities PRIVATE ${UTILITIES_SOURCE_DIR}/include) -target_include_directories(Utilities PUBLIC ${TBB_ROOT_DIR}/include) target_include_directories(Utilities PUBLIC ${Boost_INCLUDE_DIRS}) target_include_directories(Utilities PUBLIC ${Boost_INCLUDE_DIRS}/boost) target_include_directories(Utilities PUBLIC ${OpenCV_INCLUDE_DIRS}) -target_link_libraries(Utilities PUBLIC ${OpenCV_LIBS} ${Boost_LIBRARIES} ${TBB_LIBRARIES}) +target_link_libraries(Utilities PUBLIC ${OpenCV_LIBS} ${Boost_LIBRARIES}) target_link_libraries(Utilities PUBLIC dlib::dlib) install (TARGETS Utilities EXPORT OpenFaceTargets LIBRARY DESTINATION lib ARCHIVE DESTINATION lib) diff --git a/lib/local/Utilities/Utilities.vcxproj b/lib/local/Utilities/Utilities.vcxproj index 80b47e8e..6f5bfac2 100644 --- a/lib/local/Utilities/Utilities.vcxproj +++ b/lib/local/Utilities/Utilities.vcxproj @@ -61,7 +61,6 @@ - @@ -69,7 +68,6 @@ - @@ -77,7 +75,6 @@ - @@ -85,7 +82,6 @@ - @@ -174,6 +170,7 @@ + diff --git a/lib/local/Utilities/Utilities.vcxproj.filters b/lib/local/Utilities/Utilities.vcxproj.filters index eadc61ce..01173dad 100644 --- a/lib/local/Utilities/Utilities.vcxproj.filters +++ b/lib/local/Utilities/Utilities.vcxproj.filters @@ -71,5 +71,8 @@ Header Files + + Header Files + \ No newline at end of file diff --git a/lib/local/Utilities/include/ConcurrentQueue.h b/lib/local/Utilities/include/ConcurrentQueue.h new file mode 100644 index 00000000..a5a44836 --- /dev/null +++ b/lib/local/Utilities/include/ConcurrentQueue.h @@ -0,0 +1,101 @@ +// +// Copyright (c) 2013 Juan Palacios juan.palacios.puyana@gmail.com +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met : +// +// 1. Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef CONCURRENT_QUEUE_ +#define CONCURRENT_QUEUE_ + +#include +#include +#include +#include + +template +class ConcurrentQueue +{ +public: + + T pop() + { + std::unique_lock mlock(mutex_); + while (queue_.empty()) + { + cond_empty_.wait(mlock); + } + auto val = queue_.front(); + queue_.pop(); + mlock.unlock(); + cond_full_.notify_one(); + return val; + } + + void pop(T& item) + { + std::unique_lock mlock(mutex_); + while (queue_.empty()) + { + cond_empty_.wait(mlock); + } + item = queue_.front(); + queue_.pop(); + mlock.unlock(); + cond_full_.notify_one(); + } + + void push(const T& item) + { + std::unique_lock mlock(mutex_); + + while (capacity_ > 0 && queue_.size() >= capacity_) + { + cond_full_.wait(mlock); + } + queue_.push(item); + mlock.unlock(); + cond_empty_.notify_one(); + } + + void set_capacity(int capacity) + { + std::unique_lock mlock(mutex_); + capacity_ = capacity; + } + + bool empty() + { + std::unique_lock mlock(mutex_); + return queue_.empty(); + } + + ConcurrentQueue() = default; + ConcurrentQueue(const ConcurrentQueue&) = delete; // disable copying + ConcurrentQueue& operator=(const ConcurrentQueue&) = delete; // disable assignment + +private: + std::queue queue_; + std::mutex mutex_; + std::condition_variable cond_empty_; + std::condition_variable cond_full_; + // If capacity greater than one, the queue will block on push if there are too many elements in it + int capacity_ = 0; +}; + +#endif \ No newline at end of file diff --git a/lib/local/Utilities/include/RecorderOpenFace.h b/lib/local/Utilities/include/RecorderOpenFace.h index 524889a7..07805dc6 100644 --- a/lib/local/Utilities/include/RecorderOpenFace.h +++ b/lib/local/Utilities/include/RecorderOpenFace.h @@ -45,14 +45,9 @@ #include #include -#include "tbb/concurrent_queue.h" +#include -#ifdef _WIN32 - // For speeding up writing - #include "tbb/task_group.h" -#else - #include -#endif +#include namespace Utilities { @@ -126,6 +121,10 @@ namespace Utilities void PrepareRecording(const std::string& in_filename); + // A thread that will write image and video output (the slowest parts of output_ + void VideoWritingTask(bool is_sequence); + void AlignedImageWritingTask(); + // Keeping track of what to output and how to output it const RecorderOpenFaceParameters params; @@ -177,22 +176,16 @@ namespace Utilities const int TRACKED_QUEUE_CAPACITY = 100; bool tracked_writing_thread_started; cv::Mat vis_to_out; - tbb::concurrent_bounded_queue > vis_to_out_queue; + ConcurrentQueue > vis_to_out_queue; // For aligned face writing const int ALIGNED_QUEUE_CAPACITY = 100; bool aligned_writing_thread_started; cv::Mat aligned_face; - tbb::concurrent_bounded_queue > aligned_face_queue; + ConcurrentQueue > aligned_face_queue; -#ifdef _WIN32 - // For keeping track of tasks - tbb::task_group writing_threads; -#else std::thread video_writing_thread; std::thread aligned_writing_thread; -#endif - }; } diff --git a/lib/local/Utilities/include/SequenceCapture.h b/lib/local/Utilities/include/SequenceCapture.h index ee59a02f..56adccd0 100644 --- a/lib/local/Utilities/include/SequenceCapture.h +++ b/lib/local/Utilities/include/SequenceCapture.h @@ -39,14 +39,14 @@ #include #include -// For speeding up capture -#include "tbb/concurrent_queue.h" -#include "tbb/task_group.h" +#include // OpenCV includes #include #include +#include + namespace Utilities { @@ -110,6 +110,8 @@ namespace Utilities // Allows to differentiate if failed because no input specified or if failed to open a specified input bool no_input_specified; + // Storing the captured data queue + static const int CAPTURE_CAPACITY = 200; // 200 MB private: @@ -119,7 +121,7 @@ namespace Utilities bool capturing; // For keeping track of tasks - tbb::task_group capture_threads; + std::thread capture_thread; // A thread that will write video output, so that the rest of the application does not block on it void CaptureThread(); @@ -137,11 +139,8 @@ namespace Utilities cv::Mat latest_frame; cv::Mat_ latest_gray_frame; - - // Storing the captured data queue - const int CAPTURE_CAPACITY = 200; // 200 MB // Storing capture timestamp, RGB image, gray image - tbb::concurrent_bounded_queue > > capture_queue; + ConcurrentQueue > > capture_queue; // Keeping track of frame number and the files in the image sequence size_t frame_num; diff --git a/lib/local/Utilities/src/RecorderOpenFace.cpp b/lib/local/Utilities/src/RecorderOpenFace.cpp index 132bcf33..a6e24b39 100644 --- a/lib/local/Utilities/src/RecorderOpenFace.cpp +++ b/lib/local/Utilities/src/RecorderOpenFace.cpp @@ -79,14 +79,14 @@ void CreateDirectory(std::string output_path) } } -void VideoWritingTask(tbb::concurrent_bounded_queue > *writing_queue, bool is_sequence, cv::VideoWriter *video_writer) +void RecorderOpenFace::VideoWritingTask(bool is_sequence) { std::pair tracked_data; while (true) { - writing_queue->pop(tracked_data); + vis_to_out_queue.pop(tracked_data); // Indicate that the thread should complete if (tracked_data.second.empty()) @@ -96,9 +96,9 @@ void VideoWritingTask(tbb::concurrent_bounded_queueisOpened()) + if (video_writer.isOpened()) { - video_writer->write(tracked_data.second); + video_writer.write(tracked_data.second); } } else @@ -112,14 +112,14 @@ void VideoWritingTask(tbb::concurrent_bounded_queue > *writing_queue) +void RecorderOpenFace::AlignedImageWritingTask() { std::pair tracked_data; while (true) { - writing_queue->pop(tracked_data); + aligned_face_queue.pop(tracked_data); // Empty frame indicates termination if (tracked_data.second.empty()) @@ -373,13 +373,7 @@ void RecorderOpenFace::WriteObservation() aligned_face_queue.set_capacity(capacity); // Start the alignment output thread -#ifdef _WIN32 - // For keeping track of tasks - writing_threads.run([&] {AlignedImageWritingTask(&aligned_face_queue); }); -#else - // Start the alignment output thread - aligned_writing_thread = std::thread(&AlignedImageWritingTask, &aligned_face_queue); -#endif + aligned_writing_thread = std::thread(&RecorderOpenFace::AlignedImageWritingTask, this); } char name[100]; @@ -442,13 +436,7 @@ void RecorderOpenFace::WriteObservationTracked() } // Start the video and tracked image writing thread -#ifdef _WIN32 - // For keeping track of tasks - writing_threads.run([&] {VideoWritingTask(&vis_to_out_queue, params.isSequence(), &video_writer); }); -#else - video_writing_thread = std::thread(&VideoWritingTask, &vis_to_out_queue, params.isSequence(), &video_writer); -#endif - + video_writing_thread = std::thread(&RecorderOpenFace::VideoWritingTask, this, params.isSequence()); } @@ -541,14 +529,10 @@ void RecorderOpenFace::Close() aligned_face_queue.push(std::pair("", cv::Mat())); // Make sure the recording threads complete -#ifdef _WIN32 - writing_threads.wait(); -#else if (video_writing_thread.joinable()) video_writing_thread.join(); if (aligned_writing_thread.joinable()) aligned_writing_thread.join(); -#endif tracked_writing_thread_started = false; aligned_writing_thread_started = false; diff --git a/lib/local/Utilities/src/SequenceCapture.cpp b/lib/local/Utilities/src/SequenceCapture.cpp index 46b2ffac..11a3295a 100644 --- a/lib/local/Utilities/src/SequenceCapture.cpp +++ b/lib/local/Utilities/src/SequenceCapture.cpp @@ -279,15 +279,15 @@ void SequenceCapture::Close() // Close the capturing threads capturing = false; - // In case the queue is full and the thread is blocking, free one element so it can finish - std::tuple > data; - capture_queue.try_pop(data); + // If the queue is full it will be blocked, so need to empty it + while (!capture_queue.empty()) + { + capture_queue.pop(); + } - capture_threads.wait(); + if (capture_thread.joinable()) + capture_thread.join(); - // Empty the capture queue (in case a capture was cancelled and we still have frames in the queue) - capture_queue.clear(); - // Release the capture objects if (capture.isOpened()) capture.release(); @@ -340,7 +340,8 @@ bool SequenceCapture::OpenVideoFile(std::string video_file, float fx, float fy, this->name = video_file; capturing = true; - capture_threads.run([&] {CaptureThread(); }); + + capture_thread = std::thread(&SequenceCapture::CaptureThread, this); return true; @@ -405,8 +406,9 @@ bool SequenceCapture::OpenImageSequence(std::string directory, float fx, float f is_image_seq = true; vid_length = image_files.size(); capturing = true; - capture_threads.run([&] {CaptureThread(); }); + capture_thread = std::thread(&SequenceCapture::CaptureThread, this); + return true; } @@ -444,6 +446,7 @@ void SequenceCapture::CaptureThread() { int capacity = (CAPTURE_CAPACITY * 1024 * 1024) / (4 * frame_width * frame_height); capture_queue.set_capacity(capacity); + int frame_num_int = 0; while(capturing) @@ -486,6 +489,7 @@ void SequenceCapture::CaptureThread() ConvertToGrayscale_8bit(tmp_frame, tmp_gray_frame); capture_queue.push(std::make_tuple(timestamp_curr, tmp_frame, tmp_gray_frame)); + } } @@ -495,10 +499,12 @@ cv::Mat SequenceCapture::GetNextFrame() { std::tuple > data; - capture_queue.pop(data); + data = capture_queue.pop(); + time_stamp = std::get<0>(data); latest_frame = std::get<1>(data); latest_gray_frame = std::get<2>(data); + } else {

    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 diff --git a/lib/3rdParty/tbb/bin/x86/v140/tbb_preview.dll b/lib/3rdParty/tbb/bin/x86/v140/tbb_preview.dll deleted file mode 100644 index 209030250c32aaa1b457b76725f893ab2286aaa4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 205584 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≠G6nqO5gbVJv|?0&Ty^i4 z2L@{TuVZ1|xtA$NXVUP=vd^Ey>L9yOndWo1fUs)~w~##e_(ucwnj6V)5o{ShHsGx@ z7b=A42)pS@_qbwvA7#VinM7d6YaOQ`&1&M(nhcYn<``7X#Qj5c_?cTIEc*cLnmzmnvqVFU zqCBmbo@n;)hk4fAjJxm>TWFPDttThn7Kmj&ef1lpY03o~ZkW-KFQnd;gyiyIoDrMD zL$8|UK5b$C*Wo#u>E9>>CHdMnd)%mVGqvU?Z|3D5RK0 z16g&>!7Ry-KA9Y|iz&#j;Z)G1;B_A%o|)XW*Tpz#*qP5}yWRFrvzzt^I#4r-A^n>D z(uST1(uPnh=dl7}d!xoxbA0$FB?c>PaL3V=1M&M7Vxu|{g4u&vlJx|i$=MZtGUu1t z)y)4mJK$5ihrEBN^<>7@X{?r>b2u&J&8Lk==>taPy39OMU!Swa=(sn2GRy&3-BrCi z1l}c>FJdmo_!S~HO8JFU9c9ldq&mnfyS-jb5Q;eU^x z|I@UGTW|IAuVeZh{{Qw;hktcBZ7X)Q!~eV-HrO1u*Iw`NKQEJ-P92eXUPKs(DC)u* z%`uDq+3p$8vZs&+D7LCCJ+tr`>gS?&I69Ln-JXeLv0uLLLhj1#`wY?j$VWz}Y)dBFe^@1Kn+a^iJ^v^Rn zL^{BM6QL#4=u`zWj9bb%G5DWp|dLoZw@`C4BoOI4y6Gx60hjiq^ z*cAG}1w&bfbp#fZ<-v0@^V>4>!O1%6IO&p3nxDayowP#LvK_CXFy3RUgXiJFpcs82 zrV>J#`Ce!t6Iv@LB|H54D{(Ms-wZxR#Jgiz{;ekpRusOsvvXx|&J|K~)>*Am=l>(Z zp~VirJq~ll!E<0*-1g&OI4y8vBOh&p4fx_R$3WycaZ!Bd!+nmp2QW7nqUmlTm4`G( z8EHNfxxmOT&xmtH@Eian$e#*0A8A5lAt`x2nSYs#X747J+TWs8O3BtbF!{FOvCI!u zn5zI)5BuuasJ%+4XChOSP~lQTTFKz1Riz0c_LK>Dp)X8sDlF&x>4Kyb1hMeN>1^5z z&KVO#7oxkabdvjL{A{ZSu)VAEUa;GgrfbeQ$3+LvQXtXJa)CI9CeNX zjkRg*UrD2U8R@-%UuC$8g(JU*VtMqOe0YG16Rr3x*swo=zQo}xNx z>!#U47+vVD2zi@6ywZ%!bWLnbi<6nADL$NcoSH~$+(eT1)Oa?V@5GU8HqA>X#V?Qe zkv?wxBAW@~6XrROdF4GP0-RhhW{1P$=alyhgKLXebshb3L!`Ml=`&&gGJ!RJDpB=}N7X8o#ps&E(!ZI&ufRE!@Y z60;HXi>B0?9*+b`vIeCgLa;!>nW)5`lB5^LBe*Ue!MLPN^o~3jehGRkZyo3{8s=5c z=cSIfXR~>ivc}){IGsMe^uI+P*Z2yQ1|4Zq_{bW4F^~#t%l=_EMIW z6n^8Q0e5gCavmMBt2o1kUepo!eG0$w8w~|VzF(Vfnlbh-nZ!=!Sn>A?6Y4Lgv^ABt z$suj(4CH8cK8LNio3PvF=Nu|FqZ)^bbCo^gkw+pLe~=6`cc2D`cYe?I{9H5dJ-sM8 zX?g524H7%&6SFb>e6w0V$Ji6=_0tDlnO+omU8nN+0uaAGtL7g*u|27Oozh?yy(Ir3 z?Y{mr{_eS@W@czm|N4{8r=-Y_^B7iWX?o_Su-*7=&U$M>;2da0z8Y_rF}_FRrhqcq z5vdU|qcb}7IlJ|a946$o^M8yH@JRIs6Y_m+;FZ3gX>EM_l1zqUUv0}~U`mZ}t&2T} z{kj~jaw8$O>S&d<-T`1NCJLlCjWNl5EmyM#iVjDIEwz`^t2Y_gou6IIwOxUK55sHG z;UCk~wt{nhR@kZaBAk+a^_^BEtC(A!-!4z?{GmUsCqiZm$XE?&#x`3llMKbOi=N(c zy*uBRJ^#m=MQuGCU_m-p6?P+uyw)c_j6M6(o7|T7W`EI#!P&1f&^O_^>ti{)V_g#t z1;0zPCFAh*1Lhv)K-&c(xb-m>lTg1fJU*%LzqB%L`gYo>U;PEdCBcF8rt@HyXb?k0 z(QKMzjOuns^@DSc5=49M5BcU8@N|nsl@qx{;dbtTq5_&&W_SH}R!=X>r+Ue0%bY#=y{t5r$*~v9@~;MU!k>cQ zU6Vha|yQ9g2WCW~8Y5M`6%|bKX+#We(~^&*$o0q}QyX7n;KLsYxt)C>)=R%>{Z0RbSC^I!ywv(s zAoeO9p640J&a)zQfFk|J#Y9opzdM@qENdLZ#(vnCTl7}b+cXp}@y;Wem$|q-XMZfM z)EOqU|B1FUDhtWu&Vl&u?h`1W)AZ`fGwr(_7)loRmRwVmn}?2v)CCv0Xy2b9Le{Kv zD3%${5AN6nS7qFTw}w491Ci|-=H>X*)<2~;u`4>W=z#R(I@1hfA2kQocQ zj5>rT(9~|r{CkQSvr9%PzNhH7!MU$2B_;1S$v*ps5>)Ita`j8U{;{+z_B1>obM!T& z8-bec!2zvENd9^2N3=NP1F1l)%aC)E!;ok__@Or6#GY?`Lt7`tBCD+S`cU6k z##y*@Xo<8zO25*+odIryN#U=1Ut?GAZ=brKG5n=P&qXg;iJp&N&VG3!b`st5T1wf@ zqJ*|D^-b^wKU^m*wK&22gBkgNd+Kf1C-$WYYY2j4eZptQ;OWfA+Mf_H`E8XfSiC@}@o0d^ozB^JP8s69uWtI+kD{CJ%_%qkSW z)Ew<4521PvDDrJ8RLrRC2u2ZQ}n7H zCTYV)fKP~ zuBhmZMK44r?0oTYX$3oh=Jc|ZfAvG8z)^n+I7fQ5UFb^z$B9$g>`f<=Q@}m{>q3Qq z^uxjL>TIbDXKRXosg6-J$(KE9>|rWemY*NI`x{cv*&O-Verw=I%C1F+Oy&*Fc|kW2 z$j_H?mpiI0<$D@^E_$+gg^7w3Zw#QEpE0`34xl5%-}uCCB`Xt8Q>+#&x9h&iV!_Ps z8#;3dGxh=zf9cl_tf5KHYWl8P4XtclV+jwEr{|C}ab|i*J+%OqKxh%okCmNlB*{rr zkAo^?V2pJUCu2M%|D0n01DjK`>nmW{uYVyvDm&DDNdERGStZjgC5fPOUX7y!r~ucb zeduqzAW^|HnwM>Al`a?42Sch1YM=VN|ChIay!BUyhE*cN){g>PhjoNW_Pzod8hlGJ z`|?{q3iGXEtS_(iqhh`_$kUh8(ZZ|f;AcBqJJUJaiXC;P)(Osgfo6N*i|=y|Yt3Fp z7CC%%UcheIOMAyyY46O-v@1VPUCT+lTSHp+>$JgC|7;o``?)a#wXA<4I=sVqL0W zk{1jq|Clm|(`~G_VWv)GOpgN=+gAp%#8@oQHllrLW_z(trHsCnh^mwS&|cc7(u!GX zXlqi9#XIqO04JaS0W;=j5Z#9}UfP)$FCF4CvDgPr>K497c}M}YqaXlZX!*!Z0oH$v zQYr*m59Z$a(O#0X=@?ha+Ef4D87TD+*6KDf<_9*7AGp%abFiFcxV~1O=F?-0^$tWX zEn{xEwJTI++eH*;L6VYmXk%GNG+Q6@y#e7HSPd$>X4t8t?q;h$ux?W_b`B%Z&2@0{#6b z)40i@ag$v%EK)|Ap0jCuseKE})rqo`I<0?ZMW$~WZ+DG0f(7Oav0yO7#mo#laog=V z#kxRwR#+XxuzC%d<>W01i)96Vt5nYDIy&TKCR5Y)n`O#o9-6+#L0>-F;^w2+oV&$; zdB&4&KKFFk>rZ|V+nTBVjOjm9?PhbdS7tHtD{G%moxiI+=g)1Oqt5KYF?VX*kSL3N zPJK^~DTlM$GIyJ5n}gr(HaY#tEz8@lO^dexE=nAmHrg#O68)!V2VUws*q*tRFqbc- zWiZwY_%Cej{~+Lps7LpwY40x|Q##EiU~T?gX_mytZpv)msZim5+MTxsXv^Gj+m~XC z+*8|Phb9~-njP3aK|Bn#pFP{%JFy!OnN_Tpl83KN8t@x1*u zOqKg~B0Cb*d4Gt)5d&QiQ$n}z5npPv#3*VfJXur{xUHCyD^#s*xMmCf$f83LZl4L= zaZc)~awA;60FM>LMi}Nw0^8N7Kn5xg9WIxP%dp4gUG`G(X9VUiGnIe;U7}$scRuIj zC9fW){v;!rQkq30vEdU^dh>(Fhn(`yPLzM@a1K=l{+y$*So+-ho0A+S`uWKp4YbeB z;j50XSVrqpA=dZDmWN_59O%s`kw&r->lH)o%EZT4M z^raqe7EISX#nQP93@vlxdgVnnGgEFH%a}mxw@+NAdO;Bw*IrK9o};+U3&1($ z3VVQAEOk{I^JT0fqLbi#`-pH=u~{#@;(5QsT6N7VDz zx8Ce=G1Ffmm@o@$OBuKW? z8E^|p=lICjr`~%qBRZ{}BcSQKxa{k#$sR8{+DfYE1m(_jQf_3NDN_2fR7MOr{`B7| zKb^Z9oU0q0pv%33=3Nn-iNECzgYETcu}{7KBzsc^qDAninT9-C@!IO7LQHl~{CN_z z%V!>Z=0z@ZioSz=V>rexn$bUevN%4^lxoAPcPGmGufy-(n64{hC<$3j=}cnT>jnGg z3%GItPMrCILzcc18s@<#%{Q1vwt{fF(%!m9rX1qy|C8xMGEQIL3HqFeENZ#2^SNcH zCnI`YA{|ZriENaXp1$N@H$%S2Xf*CQ$S5cJi}+p&haq#1ZBCcDOE=!qa_bW*?26cw z_Ya!%n5)(}G`0Cb2Q?}^WcPGaJ4BQhN0_jHFTb5mng^$qtVB1I5bQWa8xLvK>O4D3WPjNT6p*8N>;$e=QpS` zGwnA& z_cCH8Z#)$?`ttsPVaPFh9=iSdrLSL|A7ciQXtZ*ax49m%v+%XTX9{0*k%(g)C%E(K z(E|go*X0LZpYG%lA>NbzFKL{mW@JQ9T!|E4#wFas&i!d`e>H6?*X$Tt@31jMymV0F z3>-QMxYZR*d!_5($pP?!X|G1o_osCYj6158@Z);SQ@0HcjC9Tn}iC_ z{t^9-)oZ(oMm_bb^w8VU^tZd-?p+G)LuvQY)$Ri7y^=s09hO7ca)^xBl(WL_goV|s zwY7?dl^Qo({@y9dQBKK!f{&WvnO5h(n0gO+gs3kok)HZ6no@2J@`MHRmS2XH5vyNx=y<_&6*Qk5V>vJ{cl~rk84Rqr_u3!P@WIni|r7{M`VP=_o1vE z#up)E?RLL5Wv;rZ(>m00A9f8mIrf;5THC^`lh_aRSgh+pin7=2Mp*V68v3I@DiH;2 z;kjZM>xkjt7)K1Oga2PGhU19glSLjT+jc4bPTaB*al7+G*on`3G!H2^vi>*3r{}Ek zX}vAS+A^Y*%MqiQtySE~eOu1xEyK9Yb$%Q7yO!h>KcvKV6V{7sYt<=TV^MOdnDdi) z6_w<0YYd-@PN^ZDb5C2&&OM;@9do4ed)RPOyzfHguLFo=H4W->TW<>tM2Fc^7?SAA zvPbih_cF&j^0M#ts3S+rc8<4$q05eCrrZ#+(GFIym{sEhGM2!({eM0I)wDY`ustAg<_kAPxra(hB$L zV8dY!M|vxb$4}F^cp)-FWcnSTXScFSW95qwcs6oz>DPaLb$&GkVfD8|)~e{aX6D2` zMks}yTAtCuDN8Hg1NMdBj&C_Ue{Mf?pf|3=(5t^Jv{>vl^uHZ^@-2n^Q_gF8iSwE` zpubUx$5BW z{|lI2++M)#54gRBlzLiETDM;U5s-fWGaR}J;TM^Fyg2g7h%1~hT;kG?*DvMucGtga zJki#}i&N`~u;Ly3KI>Qh7>ERR+%-U4qT_#lS(v!A<>sr^0X(wRaxU{!OEAy=0i%Wg z!I*itD>Z=yk5s$_&T_3vexj=M__^3Q?4@)+DZQRlCwYQ9&LJndP;ROz!EA#&`PnU# zTR+H*oNx9X*~Q>EYQVbZfxcYlo3)e!j=$zM{Hfji1uwOOI|>NKN#Q^0%P3PnU%j7l z!aqtl(Q}3Eus!(~P4K*ibZht(5qKBbH^0o|_MVZfhIa7x8&oNywq6L=RmLZSciko0 zKcG<)8(`G@?cf&=9O%99?cl1+=l2pdCjBl9u6zdPXAk^V&N;8h`R(B9QTxn$)q$?| zhx3&V!Z(0^GI21690Yv5`0Lwgj7&J(`bIG0z-ONsd0=(#-*Prl+;y1ex&zmmy_qb} z9+OKQ*JZxVY3{4LdKL7hP|ddOR0LlKkSV;iJ-gPv$x#MHYeU=;uqfAV#GS%&V0kVD zP+Cb~HXwa(>`&WO@+KWx1TbJT9%k7O0>|_zXQ$s&@+M2zf&*=tFF3%iv_vfXcJjp(Sm%X}MAE1dijR=bLLw!C4-=Jh$&Z zlLDu7vg~{X&I;<=LLwLqI4p3mZ|=&n74~NoJQW-}%VO4@(>643?qQ2g=i08`7lQ~O zuckvR{Vf6LoJLM24{+*3Q8W~}X2NYbZ7g9Y_*w=36M~=H_n&NQW8)epDli&Za*R_! zU78~gl^i7~h9i!4*;^qUtI~c+Bcr>(heNnn+j|#tS$s$`58+JP2AesdB6hg2B+&ZC zg)bdWxV83NxGB7P!eO|7>2P6|8bQWWv00QONc$AgFSXAh#MN#*SH$LDopCt${aLx~ z*XLz)^O1d1|M-lzISS&_U=>}PqdSlS8El6++{AS&eGd&P}+Yr5TdT9x*%wKnmR8c&ARvw*mc-RgP8kJ$!mb3SF#g86A?U+~S z%Pi`Ss4q`T_g_W>(@(dhi~dWOJ;SW8VWHK??&F^z z+8v#%b!CEGi7QH`(Ck&t_b_`YAASD?uq_JqY#vyMjQu)dCg40O)U+s<6oyFBQpx|n zWmCy5&mD-4MP2P@sPa~m9QJn&d?cr4KT)u|<&2bhX%pB>yv0wioO^%8lOU)&*&cr| z>o5pu_D>;e{}3N|G%~dJJC+gPeMfkGz5CNlGMbL4IbNS3fwbs$yU+>yi_AWM-U)w> z5ReCy`c~FFA(k%3>HVXtKhyb9XWty7I_=SSSE4FE7RN?km^t$FrLE-Mwi51JIQ0+z z@DD#0zT*H2Zu`@4&y3e+4`mbjZzUfHq3(EyeCq3GHNujX}Uhb%@D z7C!E1!md1de+kWbTz(S{lwNPwQ#h^`?_X%$mTzsp$juI%sBj^1tianS7aclB=Tpv{kFUv8Ia&i(s5Nk5J{pJZmDlBL`itgvr!q7pfe8ic(@Q~_6VZq#uo47@s!bp);vntd7Z?z(5~n*-5b z*)IyCYg0~5-faZ?Jdh6xY-i^k+UK)m{zJ0a%UQUwtK@h>80irS<2hP4b~fC%jx!SS z82l^@(sLvkc8mP#!e=;Y?ypf*`(Fv5%YF}X1Dp_~Yb;FQ(-e3qehkxUQ|I)V3ib}A z$ji_&;ST6{l!0{mAZtT?m-Ap=f)Lak)zRF?wIpBrDjnyiAsu(VJMR3*tFCkFKw9)- z%8CohOo4VE?qwQ2x9ke~{+L-do2NXgTJpFnqS!(EzoS6Ps4HSu*ZbH| znmv)g-44HyVh4oAnGaKOKa?ilE)D?Y3;a@h7V2hdO9l?uqYAol{vysAPFU>>Bizg} z-u__(U8A<>UHf;xWd{C%1{On@rJMKuY^Q!s!hiRe8fh$NP za~g}*|FvT#^mwy0mzSI>e7dx)${vWGr2FTl59NM)Nq^--!h4$o6Z$LLs5*#xIkSJ1 z`PaX#q@$q}mw(MQC(=SSYG&9)@ZS1V9tGG86kRbK*Nr-}hI~BBy=D*pTt85oM%WLM zeySNalgh1C{q#dxN69O_@R=1W+de0p_S=q@1-}`4=Z3anZ5$cQ?%tL3XgTKmI2_*j zR&9ON0vc3T)JLl7M$*(dwkhq3c~$k%k%w1pvQ`hmjLrskT>qa91ZQ?;bCbg*GuLIO zTamFd8}%A9vot${lY4OFH4MiLi`_;uUxts?pQN>!4|d)<4!518^9&a@;Zq&5nQ8l! zO~Y0dKI4Si&hcIuZOxf&%;c28^09AQWN*!Km7HRy`cKjwa^*LEn>x>86M~6(CgV4R z2Bd|%6^Ja?D->DG^1-xjRlmzgq<3SBPPX=BvzLMMa0;2wpZuW2#<~~>UA^e{O8UbO z$u)9r>*28Dj<_x3#!Yytx5;jp=~?drrsfeT<&0yMtzaZ8gTjsa(;4z8e6QV%FV!4@ zw-u#rR~&^+`(i-Ia&0?RXtcHO((|u(==qHnJs;by=MT5>tiJcJA2zS{J?8a|htin;hYSZA+lm#R+Em)MQ-y1L$v&nL%^3(K z8nQf8vX7ys;zK2msD5fId30b*hz`t(_EiJ#zXq@r+tB&UYoyvoUC!`cd&x;g^EAFk zg)}Poy)GS4eo>YpY1Cb!X+1G#)13B_Cs-|PUy6tc3>#=UpuJZ@jhr3)e#wcxj7=j} zInt%I$1*57a1F4TN?J0sC?t=mEw(Fo`Tp6uYcCYpr^he0S0^t(+Arf4ulN#XtBFMd|>P(W7=Aj0}Ij`ymbc^;N4# z8W@wQsFa*6RI~8Zz?d~yDLn?p1e}ldk`n;!5zwOkc8ZlnCkhvxDm=`!lEWTf0`0!g z&KI~A?!c&X=5cv@PiW-fHZ#ol{!iP?@S@Y2?C62TF8j$}F|#>8vo)ZlDfXKbj>eXb zt*gTpNZE=XovKU^{XmbRcbfB7#=fMvT+Whshf0StQx0Ypz0>qt3M_$URspImC12PTXmv*bmF#_qwu`B-;dwpf-Dui*&by3qL+K^^T>%F z#YceqHgK_PMf>lCVJik2s)MZHJN)oZ0CjU5zCrNY1pfwQw}C&_d-7ZkGEjRp!S_+H zW()SD_5obg;5FmN`-egKd$45q*0Z?68wC@ zQ;rXGwJ&o+i{{fT!L;61`|84R=Z%F?;<-bh+s*sEv?El~^kuKu$20@(=)bk!xLS*(oC&5c9 z69nHQseEGy_}h};MgLD6w%##K@SBH#Uo;5*Il&i5Dl-SeZ^~!NueFPB%$k4;qA+k_z~y-Baf0>l1>;OxIK&%ZR!n4a;l zq%p&Vc~Y3S;ujA~ANE>pHuHySIf*D&6%q1QSqaNIB!#cW* z`FYpVA1t;1m}6Gx(P!>yJrL-lHt92TR?C95}-W-+Ta1%i}*@NPf*VZ>ZG7%dQiUbOZrPq z32>elO)mfmako(O8QytG8-y;h0W zCX7sB{E3706U6xvylwg5rRl2$9}!2-4F%tk3V*5K=L`Ppsqk@ms(q9uxJL2O?7^ws z5*UF>Qi`LsrS^4LRFcOLrK5+BDS!xwGdx5$7U*BEJ;%qt;(NcqYqkJBG6g)*UX$d% zBDjfLf&0}vu3YTr`AP&XsOto^N>D%apb{dqzae=0Zw6tF5!SoHy4#OsZ#M872f_dP zHQ+l1zcLAarh&g|5d33;zgO^INP-`g1gZQJ6J$uz_>k@43D(V5T+Gtv3PBzd@w*&oZU$mz;T*C1FKjTTe)areb)BoDrHHg-` za+vvKfT#Bnxh^`~J5@OCoRvJ#+smiDMQEOY?y1C`Am92q5xXZJ5?GF7>9D2aD}3R{ z^F<+H4B~meaP|u4Vi$+|4tuvLz$}N){@zV2AMygec0U2#Dx~d-=zlSIE1~&*YCn$$ zKaQdNv_Kg9gz6QV4K)d#}Bj z^d5spT*0p01=3%E6uU=PL16i+DA=NK@^}73S8%&#f&U85348@wCX}%^gYt9&Mf$Z5 z_;~tBqb?QX5kY=E0qI21=wmAU2d@IZO=7!gF#N9GJjJIZiJu*W(gjvLKHn3GQUy6a ziGV=iBJnvyoHW*25Z=2^^tV&2A#?n<}DVkTndVisd=#57`d zVD@0XgE@>jig_2KUk5zihpEQQz;ttp$N9Y9Hm7-5RyT1uhWQ;P^XYW!GnjnLB+OjQ zI!rz0tC-!G{TTfk4?6FE<(-WQx%MBq@2R}M!woK9o6^ty%^*7 z2_KnD(nF7AIA-r>toXOwJ|QUszF^t1%Vw1>xNJpLQ*&)YeYju}f8p^{3NAOlORW*b z<1e{1oWHbcORWHAgr{C!IQ{Y~!uc#r`2TQQ z%5SBM*H{s4u5!Pds+yyls}eLLHH2PS-dq(audmoFE*yF(?r@RhUc0frp~<5OtU(r) zSqZqfo5zRXT*P>ss_HA&6Pb!gq+&yji(6S`EOD6To9j2kqwB)>+~T|$w-NJaBaL%|#OA>iv8Hr!P1#yFLh@pEGC(dv3md|}*svHw(l8obXAB2<4Lo!~9-ymGW3u#?GC0Rb64y3yK zbzn$8R|iu4DmHFxs@h2DX5^F{R%LCo$@(U9r07Q6k4)m|L`_viV|jJ7-q8rJ$UMED zmnH_!)v$Or@zad^N%j5onyQ9`uaA>yOqX0y#zn;V*LF5lSHur*Q>Cv-NrLGe&MK=E5;#GJ&36HYvxYAf9m z*_9dgc!}!aZG>2)b~6QS#bz%ZQ3qw|r1HvjbHwA)t8StccfiWG6ejYE;|{2Cb>io^ zHAmNPu8larj=RxjBod{h^>|9;sG;1-tLxqHy`13TZD@!pvC3)g+KwBk)s&#;xFz(&)RVr}f)_@TyRXes-w>&-zPa3ZI~B7NeyY32 zgWo+~9lLS!`)%;527+v>dsAfw%Kv%8_w|Kit`5~^~e0%XS&7OwpYL6#l-&ohM zzM?MP9`(5;(JOc0$_=_zSG%5uwWBAKD(lp2OQa3Wm<^QEWMYTcq5a~5aNTfAw82!FNiF<%cu9UV5TzX+pYd|FylR`z&E-mt4qu6KY)H52dLO=5 zmKmqP_zhdCn(8VV8{_R+AMJ$SQ1lYMasK0BCH$OVeY!#l#N!b!|5ToBt)=d2-q6sP zX#d9j-Ezd{`Mjk|mY0@U*2JQ)PX@L1 zu}{dxz&Eg)QQYu3VrOJ>hnwq&UybedmoX?m!o%^Bw^&Q1&EU+;{472Iuw zy6>|>$M7%MWrdb4EDKW#g}r8BWw^SbDO_D!=awH4@cMx(_)Es&pc7u29@>q)`_CQw zX@WP-5i`ay!nEZ#bT|q6%~qq~ubfep zk54&)zs;IvT?t1`#B8&9e|#zyI2sR9Pa(_O@`Yjv1le9Td;i+Jqb)p59N>t^LdAO7xT{Ly^41p?*-)OTJqN| zRkIuFEBS7yUs2IitL$o()m2qB4sxDNsbElts;VoT;??VN zbAJ7QX5PhrQB2-0cgoBeGd4A7Lp>c>z8=7X!sH>p2TQeh^ z%xbv0qPDK8lHu+(&@4SpnbBi~_WzpqFRf4`rsY3)<5rB{?qgP{ynN}Rh2_+#_2tzS z8z61Qyp~;a4F%;*Rpm{a8A8&4iQ?hF(mrXfiUXII3sx;Br(WGmYu>=q7piWstXe3< z(*)2N;T0uI%N8tIJbXCg_E$|R7-1Y$bu67bYj#Q8d-~-CS2=#yEMKs2PWhZ!%Swh1 zFN@Ys3{MST8?6ruJ$(7}83mWmxS}w;eA#S2^!z1d%Z3lHua7iVM6Q@}S>ZIl=aRDF z!xz6d zz1Z4Y=rn|9H*9W1{!QUHsp*pn3MNgNI_2^LQ^s$bc4ZRDC5uX_OPBt?PI%d@rSnRb z4X>>zoRSjWqFIaQ4Bt=}o?PEh*RZi6JbBTa@Z=>^!jr#T8=hP;zj;G=^1P+kHq4+- zDpO<2ShjAcVSF(Xo;=4%a4Pxo#j_Tb%vAoNC$^=wYU?E0*8t2}QchK0?lb_PRu-PT zr9s`&x~dtq&4f4?mpRMJO3GJ~>hqVD%z}eC<+GPAD=#aVy?kj2sO57?N|%;U-n$DS|6_3wxJ4zGHpR?8TJ0}9sl(em0o+nc+P4j zn+YyFuG!7?VJvlQt_zQ=3^!D(J;7%)Wx*U;z$zA~T$(pD)f)0M950JVgjZHH)uXZ6#X3?$Cx;JE~-MD@r2Da8#5Q z^_HrzsY?+I@s89|Oof}B(JN7@Z>Ya40qInx%Mt5kYKqp18_00oQ$+n_e; z){5H5_)EiE2}Q7`8%h$^0|a5OVa|Y##^&7-t8vXrE;bHFsv2nrG@BqA8yLDJ*3eu~ zUs<&++z^dO6`HEP5@no?u$!rj!`>W15=^2o+FZ49Gkw``b6rD(5IkDMIjPZVSxc*$ z8=_4csuGQstqoC{B@G*pK6pz!5g9}*jKIMJ^?NOBktSZNAiTwG7Py*h!rVg3p;Dr+ zAraAjr+N}UH>{`kw6&tC5(=9s;OW-a)kbb!8(vWFAk{}Vucs6y=If&yZmLo&nzvRo zB4Z*^>jJ@m6adkn6>jVsniOGmx|_C`fiy>8%9K@=&Ea?y!ka6$886GDc2m{O)&hnP zHbN}Iz_xlC%^OL}=7@ETlu-3UT!#|zEFe5n1CDDRuFP5yY1mx5fmD~0z~W}c!JVE< zc-m#_Z;lv^c32zNsOXSNTcL5^Ec!$r(vIN0kL!Am@P35%ao+oR&tvk9VcRWLrA-YQ zO>StKtuae$u=_j>i8`LpEvt$wGn0VEc~-T0Wf9s4;0@_Mj)Agx5MiUNMu)~#&TwQ2 zz-9V{4M9RU{f|c1g&z$J{Mmr1b?}`>9`L%DHKw{TI-W`b=7= zF)uAt%y%Q-%j;_^QS{pCT5^W3;GHyS(wTy@>}%3P9mur2d_!&BO-+&J@~stgrpwJ} z5SXs(lmfTmqcYZMn5hl#6fSBNoAM&uyrG8qDzzHu7n+3%R7o>tsA6?nWHV-%wwTkd z@+fIE1U0FMP$G`oHWBAK3jd8^Xhsw)%gKfezPYV# zDk@6dp+fTtu!<<^k9KcR@f@AnnfnFX&f>2;P`rx#UyS}=nHK7lnVc5d`$h7=RcWD~Nok={-m1S6MdsE9 z%}Y>DHiz9hw(e%y6_njb68#+)ofH;^Td9~d9TyGz&>ZOJ_DOw&fLz=#Wm7FBDdCu)!?Zt{_->x04B`|#{^U~yy}qidKCZT;=jnK@ zt7zH?Pfp^G9~ZsUS4TIaAk8WcOgQ8f%HNGO5tj#XGgwYWB;lnuW-8Gy`=Bn)uh*Y(u;AR54rZMzfAk_%cQMquT(XE z^|CJ!^9JfnXR*QQh~s`A_+B~be;>!a=P{=|4Sf$iX(jwWPn54y*Es(BJKzQX7T15> z9^k&sxYt_8zsL38@A_MRmlm?VlV%Q~Nh5sEoPovvtGw1X(N0l~UtZ6=j%BTnR#N~u z7TP)#FwrX4%Zg7{JD`@vBaB~oJc$^sq6ndc;6$2)yVERjJ$&voH|VTW0eLu1W_1IG z#^z`pm7F&_?gZH2daKYjQ&}!!)DsOfm2WOLTsV%tPpervMzhtU?z8|MxaLNhVJ;nq zrW&}8!}^9wS`C)9v8kewVQ0&YHtnazXr#Q6RyJb=@$YgK-+ue$DfTHT_QDkV)D*ip zOT|b3$`t>rQtZ=G?9*kZkdHI#`!>w_?PAt%7qfo5nDyJmtlutX{dO_yw~JZ7UCjFJ zV%F(?m_=69!_Hh6108fiyp+?Nz-Cj&dP-U0%)=VprJO5A;Y|CUhK-h%nd-_JGo55r zn^kmbd7AcXxjU+3IV-j*Eq9HEDc+VfG}KYsvR26?v$c!zLFG-)ANMbXK;=MYO=iq6?yO>9s(4M2$B7MmitqD`hxG{j{mm)(^ZNUmYYNv_ zZ4J{H*ceeU5&spep1N8VtzdpYrXt;XV3D()+4IZ6Jr^@=eY!Pmak8HdLV5(Jh4?LW z{np_2Kl{^}N!GgbkQVekdJ*6LpBr<}DepMr;jD%B>=}HF$36|S40F=;6P&}f&T|ZOKMngrObx~_6TwPe`guGS^DX@S_(@*= z@Z`4xKVIf1-21RUjOoO9a`A8l>iH3{q+1e@~eUNR2N5f@h}Jb8cZs$@)x}L(9ciT zPeXotfVz9uoNB)h#r&_mZYX+wT;Wdz?g1Y?;XH!91LLKGV1|;NA5XM$iG%Hm>F3 z%PF*uWAFFT63kGv{CJ`@l`zAMN9tQY@l}BRYK+I1V1}aQ#}n={;ObInZO6XLM@uk6 z(emSo)(PM`QfM8<{<4pjV1}aQ#}lomfXigeN#FV@EpxHwWBl|4H&j~safP2_QwO^A z6u#=RO6)BduUvb8?}?0!%*S{*LzQu&Qvkixa8^%KAAux~pJUBM4U*H6O` z>ZQK*(N%hPU_XrUbjpKE)sziw#HcX32RJg>sO9kU1XD8@^tZoW@o0*niIxRSqq z{xC#O>69vO<$aTO_@$<`@|x1xldC^1-gVN|GE5o@tu#o z4s*8n3U{dZdh|qJzwN+1;D#Z)!g&Pyqpq9$<*uJ!Zhjp3?E~((kB(&WF7^OpF!`8u z7>}l4mACZs(-eLWeyQ><2Cf) ziCKr)h3UZj4im~ww+b+&m`2REFu%kEhNW9y!feOv!*pZ%F`)qPm{Lq5W;bR(=2cAg zaKgY;V~$|n!;BxnSpt}^VmdH=m`NkS$24MgW1hhL4l_Q7{q&d?%+r`Y%x6cXTg8}a z%!8OtOb^Byoom`!Gi_fgt>0YB75-otWQX#v-YOnC+NvVY)H>n6c-iTi0W@ zVV=j#JU89C6Z1WcjmbMN-I|ZthS`hxDJCr!UNNatG8d@{p0Biue<+yzq{kq&sRJwec3Q$&9ah3rE3`djIdOM z;a+`C(jvR^f-B1lrY@UudHEI7%cmBWmlqV4v#PD~%Jo-OPnmvYW%ZP)leE&VvbmC_ zb_Ipg)?7ZRV9okyZC&M>B=;>FE}vS?N-k%YO_c(OuN`ZwTyIox4o?~VE_7a0BHS9m z_av6fM)E6b<=lx|=-o8eZL?X+DV=LP*Mr+;6%$|07dm)1R|=2wZ>>j(@T6MpwaPd1 z0*v38dX}|%8>$)5>+tNXNy}d~dzR3iz%7sWB*$&J++I$G}KHlam&37{+bjo+6_z6ty9RzvFB?!4iy$-rfG4v z=4}qB8B1M5W_Mw4x#gD1^@zbbS?TiK6xoo!V3rB{RFd15P1shI4{n(Q$Dz$moQ1p0 zf#cL%OBaVsG6CnCvG?7#rCU$2LU&S?!_2ZDl0Jm(rjMED3H*q-CEUzh&sf}i>8L3b zb3VuSsEA!$Gsk0fbJhss&6C`?(pRG#aqWm@{0YJrPwSh_{DwsdUZAixR@YWG=bJez zE1Y4ilUoyu2lETeT+}+;P8yjRH^V0&Nk5(Fo#c>WQG1r;Fh=F6%&IC*TIRPuD^X_S zY<_BEsIMtY?DMSQ)rb50YwQY7Wp*(%M0X-@&tGpZEWN$(4!hyCoF%;XFG&vX)A@<; z_PgOdFhqEYO98aSo5IbhPUcB`=_gry9C;NB*!?{}A(^L<*cG08R#hh)&1 z!jE|LexAJQTv)+NzH(oKo5JWJZhG5p90g;i(8S67gjei*n&+Ae2J`EAdtr~==*UiV zC-N=#t9g5HdduzO$nN97C@uxVoH$M6EgXgYL`s+nS3iXzd>8oW7Muq5lgP5v7k0~O=y@{R?}L5hEU=c3&!eY-{Um&@^U)j6sl=Y%_}`)@ z{n+c~SMj~~nBKu52H5ai8Mtmv8QyL-6Fvx7!W39~`C2Dc)XOrVfF(&JDBC#T)+>2X88G z4{zBJcs;HR3S7K(E?%7vPjgwRvg>!#dbf+W2Y98~KHh%0KRg6(u`AnBS3WPhVfOgK z^!g$Gv~EN{WZyeFk#|plBi>Sf%BvqYKML0i$D<>B#pk}JMA@~FZ@I7G?ZN3SH}#z~ zhh;-3|FdZ!*_B6*W3R_vjNSYF4Ex9Bt{(~N{P4pR=M$4-kJtoxuyO*Srwm`kX7ATU>na(!0tH%Y_Tt}Uu<;NEGwQ$ONILs zxRTXKzH_3E-o2bc&*QKEoCN=JJBeLy3tsfnPxWRtcFABgZ_QJDnzzRG^La~OC%X2l zcnfZ?``+iizr$NRiO))S;x*{!@zmqO%D(q3uzTTGbOn3lY_Oq3xF(L^cs!jv4X&3z zLcVmIx+Ou!9|@2D-M;*>?kupyKK}1L1FZP;hn4y*K0gkO(x%ZDrnU9-arwCPdVKLM zJqZ3`%=O{yKMPLC#W~-HbNp;L$VGBJ-<6Me%iA`ze7yLS z<~sUb!P|?^!qeb*`Vn?vWp6nPY@<)_9ytr_ZkLxmK3!*k(`W1aM0q;)*3-w`#M1{m|17ZG{`5Z!>^dLa zy=Q^l?SnmX2H1}q|Inv=@!x*t`1kn2o__{diJZNnrXSSpzCF9mh1P!mms9+!-c9zG z9((Xd@cToGKQ|S`{m(s_78-}~;Pp-o|I2?&_D>D}l{5JN0th)@lNIycQU_uEX^t%Lm%)zc%RSM zIHuq()7G>0{xZ!frV$r)6=Z*PY8P-I2piTx-sEQU}W&?=3VeEapAj^mQ3-*;9=H%4L-w^ zfrr3-hWA12zXA8hmKE*-_D$l;cQ@a~ucTRfXW?JP`x1D66~Ecw@b2cle-8AIz#nG6 z3^a=mL*qgCg}3ncF@#addoQLy{+-C=Dg1v1Kl8yM&f#iI7JNTLT)^)Kb{%+D2l$wR z=lQnb9o)U(HeLiBa2hfD`EL0+wAk6(cnd*P);{2u~_aEqbS0uSqW@8#X|3-DP`(}OAf74*Sb zr+Dz)!goKi4=sTXVeiG>$#*w2_d>G~n!BOX2_37K^yl69H28d%9)Kp_-Qevf?Mm+e z7P_TPnCA!w(}LN5gs`5+?S(X}2h;fz(gkC6Ll0Bh4Nc_NFFAgOv>Ojyx$({ZN~^IG zc)mmT<1YUPiQ~6HAB!LUr4N9MS@#FxF^sr=4!V37{2g)Ny8ySI&jb5YJ%B5>~^ z3rzq2VDD|7H&bmE>lV77L9KVm7%M zW|`1vw8?~KZE`c()+W}hO(rzVZ2r&pxz1Imx@vrXpYP-Q`~M!_wx@Gl&+GkupZD$S z=6&Ah{YF|@AA&E!XTWD0?)xdy&%^ak)OA1H4_EAcL18Zpsu(B-TyI%W)_^lW)uODp zW&`CwK2QZXU`)FM^MF!dK!zo?2v`q%4EzK*tgxge0?UA-z*oS}K>L-J)Qf;85D8=g zCxO3!(W|g70@w_E3k=G%q(XtcKs7MxZA)q1YQ9$fHS}oK$C4r z%?AzuKLcYo;5-Q6W1#0o$T;9@pz9_}Y6`F#COhxHafDo_ga+=lW3JAg~T$XuL{ z0ek}3Z?~kT1KWT)K)M6v18x9bJ1wcVf!}}uyU@14QQ!ffd*6~;0h|GBc4MsxumQLR zjM!sI%>_;Y_kodnaaIQK32+w}@_{841Z)7V0DbpaQi;G(;2*%{Lxcym0hPdjJWDDZ z*bh7e#QRa_z)_$c82u5-1MC4h9zdG_F+d4mm2XM80nxxF;09oS5PcGOAFw!t^*X?2 zpbi*t7<~^o2;2f33M?rPU;(fbxCuCZY)R>XVBj6#GT?9o?F+mCMfJw|lRi{m>IKS)dXegf)iEM!05y<$iE^d}QG=-=lnXVK8b%GLMo=TEQPgOP zrWi_0Nhp?*VwXHQ_R3RY*E%(&p|q5a(o?RK8#M;!9(Yh=DNme>;DwV7CQuWxm)Rt0 zGBt(rp{7#PC|}BtnojvsGpGRSWojn%3KdAbO1*}i;)1CVY8H083&UIO5!hoe3VWW- z#%T&M*o!X?@4FkY2O-&6E(tpiCS!lU6lwv^N?1fKre3Gspq5an)KV&qdXq}0mQl;8 zx2Ozi1x$riR3`N{wVGN(Wl?LXb<}z)o7zBaq&87G)Mjc6^$yJY zPHGqRKDC?LL+zzLp!QK8QhC&V>Lcm^Y>R``A?h&JlYC4ap^id*enK6ij#EX{r_^WE z396VnNqtV8qDrXK)EVk5RZ4w9ouj^_%BZiXuc`A?Idy@$NL`{XQ{PZmsH;>3^)2-s z^*vQd{XqRlU8Aa~>(mYEC#stInYu~+Le)^eQom8Rs9Neax38ROUo5iKtX@wG-s?2J zQ9UapG2GR(gE!fo&ee6i+gR7}t}|N=j{T#bBZhIKcf9J|%AMTC_?yoZBX(^i6HSsd zpPSZFC87U26Xxs95N!x2+h7?hbSf$|fYc`w8e$;(n}%Ui*HGgYTgDL68$&egD#gG3 zZl>BMwH>-;jkFP=NnM(0RzBa&bJZkT%Nvp|)FP(wU1P2vv=zg+2Wj(qX!nS)A9b&V%Glqsqp(Qu@iBzCms=*b)i5(=;pe%Wghy0prKxAJY3sKu_%A+9FVZ zAOQ9u@473{L86!wVP?TFtRB6ASgLHgg@#hq0R87Z33~ERCEjyH}<@j-2!~ZczDq? zmu6xjcHL>&p@{TrnKtQ4knoIYq_h(G-+JToCh@NsA-m>r=O$s3I&!8!vb0$bM47#K z!C^cefZwy*xGx`eQgm%Yo&`-N!-rQPK@kSBX+K#co!C|+ZpaunE;8PW3*1EBn7O5K zm~&^*xVEOVh+yC{M2`J&Z7DR!Zw*K1pb^{dEGBu1{jx%^RZI}s`@^^m7GJ!EO~1Ik z!Hfm)b@MXb1)GD!FK9KV&=y=y`7P>O)&Or22!C&8u5cC-5t~xeorzH7L;!m!h89JZjrsS7wAgY0k?o?uopv=H*f4nQ^uZ!{E!~WY5!*q%-Ofmab#Oj^xiq)am@z48}F607Nmc83CVgA(K9NAoP3 zjYnh(=c1A9nyVgDEbQ?dl#qnolT3D^DS2amC4x-Rm=YRHXqiH-vaUu;(iF{fx>^vo zr541MxzYqpZlgHnA_|LRlx?lu?>}Fj7AAwhJ83qk1=hxR9~o)101N~2iSZdjKC)ym zH)g%9q+4o*=S`hEhR`^qAv)qhT2oYVWBWFW18g=$4)U7CZv-3Euz6(b@&Vl}XmYcj z0COND6q~aNM{*l=H)bp^viRHoOLQ~!(;@}V-e?e+I8Te)!>U<5m}W8p8e6P+LE1>i zOg7xc3L3vjgL4}IhbFaBA!d^zT?im~qxrr>8~akTl=&kI;L91$EWk!~oMj0^v$2SyixOdrR-Bhab`XX;*Sy}0TUNW8w%mrT45t{!x+SxXdEokp$tn}p z3m>_ekZ&SzQG0x-Rvh_%3Ed!>|1A?n1CbZJ+yNcN0tni>g*Ir+T&v2imFx-iz%$+% z+Jh*JRvJK%Ag7#M|1+sJ)4^>tViQ$G2BUce+E``Jr)!$kqv2WQBC(T<9;`{Mm>vJE zre{{HJWGS*A9RyN%{ zYErG?aa{OkA0guf&Nb`G`(nJQ#2?o1+==1fL*t3I+@pgQvYG6jpBM!Pm`vNC{rL^H z1&3 zOX;BAV39TkcWrJ48R8AX`frpaX8H|3E!?2|T8(SA=}dE0!stQKirKuhnh@Ft?i|hxhcox=4P>TbNK3b!lG%)*iOeMyi~ZQm=O-vx(XyV* zS2aoGS+Zp&!Is(LH*0BY@~?>+HW&WcJRx&2%}w~3z1?#eBV?LXXcBU>ZcP*!pBK)^ zBaaBo&AFK~r`n1~`hm&VZaRZ#ie+x1&KSk~d}Ukl+PWKel8msMwK*7}0Gp0Pe#7!s z5-{7{&80ye*$alAAP=o3ficr)%8*YCnZjw(a(FO@;|N>MleMV;yqXs9-_tOkLo>;= z;%u3w{(0F(_I4N6MeCUzGq$Op)_P1cS!@xR9Oh0sSgX&?h%@RV8)saS!96W*&`#t; zEn%Mjwf!*YT1dqnjvEc_W>6r%x z1E-)9n=h|`RK~g`9FZ4h9P4oN<{60bFIYI%;0q?gZ6r%wg2*ArEywQ5ZhX&448j9_ zgqXD;$mB~KS1xe(F!r-X4>OURLmJMxXm}#XxfzW%Rr8W?Q!f5Z9eN_aj1vWLcgU%P zIJt(4XD*AdJxw-V^U&OrbAFN8zenXxf8$!fSZB%d#$0nF30a-N5)Uj4r>CK0;aI^z zmRceQK@%DA3>I^FWW5`A0E}r3CJ7&llR?SGXyk+!vXm?6`I2s#F#mMj=nY1aN&i{l zk;qZ9@;{a31f+*#!{dRFsO~y51|CRFcZZ4MqsYv`!o^VqClbSVlVKgve8}%>l#q|ZgV*g`(flHLD)@MzU zl!Tl^)ushudOScLeLls7-+&BWtO~kxGxBWwhYACTm<=!qa9J z1d>WMK7uu!@70zJ*1OGMP2upYPs}YR#_}X`ZYY-6g~z%YWo*zaJOFH1y2?o++=#?B z&VL0ZEiiDGqZ&E--4Te z^hX?;)>rkIdL%*-Gu_lMO_n5?Un@zhXU;NAnAd!<4oS4FpGY4fb74)jq;b6pQp1ts z&|}7Po6X3IF&@})Q=b?f6Cvn6+!9v4HAs2eT3m>p$n{tv)j}H9kQ&!kC75Iq=Zf*m zNXciKTTn_mD2YZy2^Ir$hpxE_7nYk0coN9e&06n{sHbMVk-LE*WIi-FZb8hGAe<{2 zL>|kND&v(t;+g6&1|1K*n8a)5Z#0e_GCA59lXN4#k8>;0%$gv2H~(nZGEKZEzIyq% zi80~f2D7>V&mTDn-{NUHpH1$_-Jk{0;aE{^PQ>sTBo6{$gv5|D2aWbpgB#THX*-li zW3;xz&0rgUM;TEnuJT%OYs`;Dp=Tj5?9Gni7Q@mM*(kI~^yknYM%&O7>3Nh$W6b|k zaW^mSIWo+(3va)Zg{da@B@~B@qjibqG}W=0nj(!lKPn{2wP{x{_U7pgT7?VJ+L&(^ z4C_`B$N}fZdvlV#c?jbv+Iaekvn35N;iiLuA(PGC80T0g5_xU(CdjK!%@Ty6k1$A*y8FR_?2){r>gplHTMgyV2bSbJu9?xgMJ zzeGdN#RVndp!7uYLPv}H5YxYT9J2{EbV9t66oxaGn`RfklEx*+dN=#U*nNWdSa?&g z`ZMyrpz*Jw81Ivcu!p#S`@96dgR?%-81CF@ymJVyNWc}H#k;u!@Ghl*`w^TAxIh8- z4>(tFy9Au56z`;h(+D_Ma3XMi0xkla0-U+OH;~W0z&aoX2mr}R zfnk6Om;eL-aX>n-5!ekB1C>BMVE4HtH4qpDi~;7kPhSk9|5I61yB!=ze40O8;Af@Ksn0a3)g#mJ(Qy?mB8!4p#=Gn_GA58-M9*z?~%ww4cLwENw@|A=kWOo zPy<-vyEEVlMBzL6)8Lv3qyr0q$pHC#f_&TrDuFsaPn#_DK|y0pZ_W86CAb?GvbY-E z5~zmF%|m!#4|(!hKw}VUL-R21@mOKQ2QWIyR8EU9#Ko*Tp^7VK3VOaiH_oQ~daN0tn z{NnvMZH==cD0jTU6Yd4GBqp3{*UmRQX>2l{08-THb~9k6c*ZCALI%c!Pnks)agR-* zUbZCfuR(i{C9Bo33m6xNe4fOe!n)gnya4ANJu4w3VF5LVgvJjzEZ!5RO;3h5;f9lR z8(HI>$EJYYO;{h;>~3LUFkG>>d4ZKTq!ynRLNFx6*tq2Ag!nkJF36u>=IBQGT8)P_ z6dgj&sCUOwoy}}w z&_5upk&j*0)39g)_PuX7mI_3{DaPg&l(CC7P&2UOc{{(DL^m=iL{V>(&q&yxyku$Ruk~`c#fACenT|VI!ANDd^GjG@wpex+9>`l#i((BR?IdV7z4g?2 z;Ry?T!V_SL#*%q1WB@8VE_4BP1m%ON%lCv&_>ys7QF>jAm|UL16R6qke2Mu;6_NNj zKi1UCwp*Yd;k@TbXw{HN(gV5+>X;}iKW z@d=(-8Hcyie9%?NfC&(^oUb>`cQ3rELnR@GNBFFHkvPBI6ta}$-j_Vbm}elxnL!x{ zV;m*M@qnE7ARONd`Fo-pUgzR+HQ@(;$}N$MD)Nb%ICk3PvECB#DDvty-j)wCAampm zGrVmdgvqk7#ueOnhd;vJe{!tHjK(EX*kd3fA_nUO zu+It=fwQ_3v6Djc*ol1XNRn$#%#$6=FgqO+gQJI|C|6T$FgSgkYH%2_R|4kvqWBke zgGk5dgIMu#5z&$4rOmhyi0%29RE|VGP@{s?HvCV>p-I+K*pERN0;|4Jdd%z1g5tp5 z4Dea_*%JO2)9LNl>j7;Q9y$**L`@>~M_y2CnBFGU*w6G0D^AEtZDZZ`25bBT+m+;x z6b^erG<*&Ur$P+TBV!Xs&X0~8iS$OIilDJZ#xNt9k-Xk(79uJ<#L(97yy-3s(kulG zr|9@LeizhR8=)W(ql7<`uJpfu|06YE!Qa(BfU>6nAHV=)0r@~VPzTt*jNbttzyM?c z`9L{P2iVWV?|=_r0J4C5pd6?J>|ep}fDe!g_vbp5DcUOxj->c1z-yk zdlBFY1OvH1Do_km0odTgUIe%T!9XsM3KRoX0JcA|7Xhw77LX5MLlk=v;0oje<>Ye+ z;saSgK2Q$iIOB{ofSyI!m*Pqd!dYT%zz5+>zZ>wm3c$82_97q{$OY;EIt+CIMBkkPnmtb%1L$cpx7r2Sl^+eGbY( z;q#c8M$04nF{AR#!Kq`POVC;)=rE$Ie;fJ-IfB%lQ;`>MYYhqJZd8U4vGZ5!N zUP67D`3pw+sX#tZ2lynQ&VhUYThQ27;Y#+!3zQi5-44dp8tFvgYKyA@SCViFt|DAh zadpKt1J_hsGjWBgr?SZvuF_U=MFP9X6$#{#D-tLmR}uE_B3D=JmrJhvpFQ$H13rKO zxQyTW;kO!Gbs|$J=t7i}e9JcElqARt^O zxJTef+Yk_LFF5KV(lZ#_inK=oI9qU}%?Jor0?rN`X+r{1UzOk-z>)SOAY47T6cQKT z2?%F97-#8$Bke)Z4xAIXba13?2na`m%Ov6Ooq%v2;IhDxb|WC|768r~Trl#6Ag~J1 zcHoi-hx7?Y1B=0BfXhN!CN2w{<0aG!NskY=3!Dg?kAN!#=LL?`yD3~5xa@0|_T@ZB zey9SM1I|9l7>;oD;Bvvy0?u{_&Kw435O5-JdEl~mj`S54Tt2vR0p|s-5L}&r3jfODOE#uQ;--SDA?fj4D!3eQbtF9j zmk-Xa9C0DX5riV)O2IjRGYGgUa8BUz1>6&G&ftg+FvWFr!5O|JJ;;3%rvS&2^aNZ0 zI1Ncpz$Jn6An6IXEO6c=J?IHjdU@ddNO}UU1Y96VPry}z3nS?XxO#9gBt4>A@RthM z4@Lh2M|6*ga{;#)9MMB2&I4RJIEv^U{G|ec;4;Cv3b+(-S>S>NTsF8IaJd4m09-D( zDgjppZZ9|y(OvvKs=?)x^aLC=47!J;C*YjG6@e=ja0+lG;3%T&`1Jh1m4R~=a53O2 zz@_pWk%bxHs=#r2l0*i#3tSC2qB99axMFa1;E4V-aTVYmfuo>1Ot70Y`MQDcoLgKH!M{HF0I&g28b* zn2;z(4Y)9HL?@fVJpmU3j_7BO!@qVT&|kn2U2Wn-;8MU5-EHDnaH-&k9yf7b;L^c~ zhz=)z_%{$-Cb(b$mjo`0#1(KE;Bvrm`k#-R3oe(W2OGeYUIDnh;D}vd;!45glk|v< zz{jlwS4iT*E--Pm;EKQz`@zInk3=5=M{EfbCjwUvj@T3?js{l&j@TC_&I4Q(IAUv< zxIl3A;E1hZ;*!AGL*5tjdV&0s4K5X29j_M%w-;PCIARBoxE+8Za88i-G%wo;R}Rh@ zoI$`#;Cy(QO*m(81w?iVI1RWWaQ3_`CgJ?Rm5{gs z&H%0qT$X^#1a}!+xq#aXu9Bq3%V&~a3Ak#K9?!vap(?=DlJo>zEjU|@Eqh)TlW^2% zdxp zBI)t6n8eKn=R?vnakxnyxB!x#fGYtPOwto@mEfXCdc1rlHeDS!14&Q7+0q!7;Bt8m z!<=#gmkN&aFYujkG`I|KB3>2~P6I9*T&jTc0=E@hv49Hzw+kG_%Uu#T23#IER{@s_ zt`JUL(;7Y-XOtKhUHMnwc!2%9bzxJ2G2jasm21i{$IFo!v=qzxy;D}#jin|w_JvibcnYbcw zP9&Uws{j`Wj`%;OaF4)6ffEVjse>3{z!9Iw6pjVA7##79Oq>U}3~-b{PKJTY2A3+} zGQe#m;RG@<58N&iPQaCe%L7OJDbqb_z!i|V0$FD*K^=n&7I2Q>O2H9-%M{lITp2jx ze-V!CWv&5t865G&xNxo%Oeg{FUXe-uyL;zozonEdIKS zzvl7RBK}&=Un}`*Eq{H)U#%zb_vNon{MDJij^M8f{_4eF1Ndtce@)@98T>VezwYI) zh5WUYzgFtMtU$gjY4u9RtUkmwb34e9= zHs0@lswezU-``a3gMChTOup%Q-1L23j_H%}O8jvlLv%br<|JeNjl#;P=F2%qc;WAu zI5#cWCQDnwxn<=ompV0x6Gt8a;F)pLwXsdpMHsACBl{UP57jhW<4UoXd}~YG`Tggb z6*0@y8xXh?|*`xV&O?ZxjXRcTqY`jI2d&I;?Mu!Sl2p|z*-NesJ zA}b%UdMFZ$R>=~AroVGPv=P7MTB)Y-O?hl}?Nzh)a32KkvoueaTWsY1taOVNWOTZRaoLi6R0U-tdz)hsQVdEKp8#pwA_u~-L}tu~#KS(5 z_=t6PiLvD2E{We(yy<#p16CH|ou+@en=?J$&9y~Jq!yagZ$o-U9rP@TI@4p!q%15O zS{BcM$>Q}^izMtrt?UWkvS$eI(Xjde!cNF@@;D(OWI+%fu46xsxX7d^lT0+0{(t}d zf2{_3pg=NU954Zx47>_p86NctU9j zmuTdjmykTOo=>X4Kp z8K1&%G7kB30fhPU!|$Z#!qHl!Hc0)DKLuuaEzqBg`6l&BN@MC1BjVHCz7yeJ$kMzd`lyL@19EbbFV+EWs-`-q1HobrI)@<5xt+%BJ z^xEJ2!17F zCK0iPBLY8B`6R&q{{8=@1~7{mfV{S+?dSpY2-=OFNQcld^in#LUQchLx6^s_VfrY2 zQQSuoEeVo3D?Am`6p@OJik*s^ia!(?%C*Y*s@c@JyOIemm#e@Wua20@={6E zsp|b|BmkvD`s8-W1&Iag&aPl16bXtWiq91f6jsW9%KfU-sxN};yZ4A4Yr zZfYNCAqJ=b3!KYIZ)O&Xmx%9)`%4B(Mo3hWeUbx`i;{mNZmc&upIwfUl(QA=U#y*! zmAXn7NzgDP+>fP!C z>ND!|>YM62Y8y>g&0x)Fji+XcCPEXhS*}^5*{wOCIioqRxv9CMvC($b4%Uv=dTOU= zBee0_<=Qpc-P!}%Gurdoo7y{C8(ml3VBKh)r*4WaLKm-Fu3MwqtvjGQqdTv=sk@`I z(RbAk){oYY(@)iJ)Nj)t)t}U(@`G_+BI?zK?n)1)N7Lizsq_*01bvmhPJ1#_mBkd|3B4wlz(s=1|=^E*7=>h2(>3OM*tgCE@jFG)1TPwRNyDpQ<-Q;`Z2jw=3 zu8P5m(df-n6cLJe#d5`(h8B3Juuys`rzj(pbGcf-s=Tfot#VaOR83XQP=%^uR7tAE zsx(!GDoeFlm5biLU-gOVtg2RJsUE48sFi9j^<;HCdhjasTJ+7G>O6IUx=8)Gx>Q}R z{#IRucDSwnQ|+yZ*1WA*ui32GquH-HtGS@*ucftWt($h7)>j*-4b#SG6EK=mwJWq) z+Kt+GwI67YYQNXs()QH7pc{ZbF4G0+47x?SrMkCt>vdaoyL5TFL%Kp;vF;09x$cVY z2i>najeeRwS-)7Hrq4oq?7(=)*B{ZJ(3k4J(qGhnufL(crTvLJ$vr_<DN<3G*QM^rjNPJveD!#zAWG_j7iA0fUTlA^W&PP8Hkn<*Ze+KyN7xhW74{nYfPKpLlJ=L%qyPoLm-)+rF!q+nHp;fij>t~PZprK9f5``;&B@4%gxuMpIIK9Y zs8{@@=%(zWbXH1~6P2;b4a%*`L&{H--zzOtqf}DWSe3Ub1Y>M1WZW5yu}5{nW$J;$zek)r-_=>bKPS>LY0DbLtv(J547|H;t1W= zcw42((rnOd(QMP~(tM!#NON5C725u)=DOy0%|p%K8Y}dGiP{)dqnbsy=@>dJJ#=xT95ppD*6-(ByhchV2U=o_gQ>(yxY0DZWA z4qAV;{!{$}J(Y^*@feD>bR6ALEEaEobn7A+CrOl~q4sY`{*(-6S@son9=n@8#Fnr( z+57AmsUOBvqI9M7p!6c@b|C6?7V30|OeS}ihst-$3*dw_beqsaujp!Yu0$?mVSNEEooQeCF8vQPReV@% zi%}lSX0f%bwRD;+P4-asnfztN$BMy9h4Pkilqy0sPjv}xuv=ZIu2=g*azB97l4?6) zRJiE8bTd#VR**YXE}pp}?e_F#`W`)%31mW;wag3RJ(91D`k*${vNBM1(OO^ds7vNnqA9yCE%pV*X${iyg%Z@g(s)@jCH-aTe;+Ub+yP)Kd|lNK!Z{8KqX~ z4js5#S*?78{C8AMQ_X_jTc-LDI`2zZ9+v8!>cMKM+FKo?eqa5uItn>{A33hn*y`r$ zmgqL>e$&SpFT>z4EcPYv;i962`)WpPkJr=4jsdEkPMfICG#a|?5F7e*V#kT zlhRu03$k6Zk7Xxi7i2%l{+4CR--8DEN`6UREB{B{UNKT3QFx>8XDQx6oqwZvqUfUR zt<)$3m2t}X$^+2arOI06Kg#y15s)OWsUo4P55VfERQ;}cs2U9|?S)*w0m+f4E>r)g z{zcs%+F1cxCJqwgfaZjzR8y<@N7G)bhei&7JXj5RP^A4vTdDm+`vkhcNhj55bklW# zx_P?Ax((0+AM1)>{Z#7y&^^)hgiMg?HTvoLKz$DMajE`1DSI89dB}TP=wk(~r=uX} zbLee!DSaO8^OSaBMl%6S5R<{IVG5y>YnVGsFY!Qeq&QhzBEBg8PV9`jVkC0ORLQH7 zIg)vh5hS{ca)gprvXC1ZrK{2dHlMfBN9m^w zKX>KrKnb`-cjv2=*1g%TFFo+cDC1~0(dNxM?$MmQ4Xz0GhY zav#)zTv?{HSFx%+s!Z4*_3B8?5p9X~D{V(u5uV83a`c$5byv|}M(9;~cl{Fdm5=lv z>rd&g=&MP8vA4jPtrWF~j%CuAkC`Io3UdQvm-LB^;+^7S;&Sm-u}tDFnJEd8oPj>M zFX_&{#Co!RY&e_2u3;y@F54t6msZ0j>n-zrk zt4dd`Qhf{g`A9WGT?|XwLC>zz=Ni!n;2;w z7zbt`^D?uTS;^!w=NT(;H}P=s7;&&TPFyAaMQknUE~$|}lplsNake-vV#NZqcyE8LCV&ff8*Z`01q24<|}E%>8S=~8JH?AIS;68Um@j{Hm1cZy=2V!L9W zVvTCA>POWAbr^ixOPWWTNX{BO2I*g=t=86PYqfRSdf0@HI^tjvdxu4jKgM*xsJtYu z5I=xDWhb$Rwc;pol87YnkkbbwXC*hKzna_s_brZyL8Q~4I0 z|IW}EkVlqcEiCy|@j=N}=?!U(w7bkvb`GVVEng)MQ5;efDsG^6_JX{%fkkWy|52fh z(52{*nPLl^u}o1{=t_Dm>i!5M#|7pZ6D@XO6>JowSqA$#Jn8G~A8dE27AR@=d}%Sfxl7V-r9Yw-y2<*=hQX(sDw`>bkj276%z%x*AID~Ql=qXr zDvy*W%QvFWehQ1Io5EQ!Tp@S=}>)yre$)B_>!!T~lL}=4x%tfXGlBcKm1+fhNZJc6dn zWFh+(#`hrQ>+mY~s5T=P$2p(w&>h!(&iSQRbwBEU*4>76 z^0&?wwbw)cB4!Kx^>4s3`&M70e@Mn|odwSFChK^0kmMg?4(d3)gn5fO#(aSqbP!J! zuMvOA%?osqNFlRdm%J%iA=xVF$i54`C_^u*mmZbXz~7&M9uX~H06QWdvoB@xi}Gsu z?{aU&%ZgM*21eL%#VJ_I0m`?Oo0K2HS}Rw6qx@ZYAIGmxQq6{^pQg%IeE^^DPt{@g z?Gxc0EP@xeO0xr_u}(7@zS?W>&GNOS+AG?-(EaJUw_$@->Tc=o>0I=TUZ)=qPb^%& z8KttMQebm=phU6s8}u&7FDs@4=R+@L-e$Hk@56(>&iu;MGrh(A#m?dh;wi9-UxziY zTAVH30v)wmoCj~ZQ2ZIJuyfG4SHzX#8<4lZi|fUYA$4sq*1Kb*_menFhDm66+8W6i ziI-%u#1EP|7!p55k|0Tuydg=4tjmJ;y;ZV9vRCqvqyUny7}}r=UPp!GM@cp0U>!X2 zClX86mhHkiuzgt(JD458iZOC^tOq-R^?|Jy$j-tzj$@P9g={M3#WLA-ko@nlyV!kf zK6?Z9-$1Dsyp~&)EHP8%R z$`s{~N?Vl*ZIGinr|PJ7RnLNdy+i%An$oCX8?S@M{I_PLb{b|#4x>lj({_hn9H7h4 z9fP&sS3gF-2y-15^^f$FJ@&joUm8WfMz5v|=^L2C7{!D_<6dKe#OpCL@mM?zwX;%k z2sTy^R>dxY{a?rSl}?bp4W0g*w6AP}Y@uu)?9<1xVeq<;m)2vhdhYX)JwQBQts0BS0j4MSZ$VxPdDvzFRQ?WFcn2dSgf2{VWu zs3nt+7bvZPcTp#=haLAsPARMv_Wx?trbCitDzlW?&_r96xyoJ2y-FAD2+SyX!C&*y z7Q@~v#n>&^UdHHcsy!Z|-(q_UovqGJXRmXBE^*R{bk6XmN5DR0F{U-JW+_+fCxrf+ z#H7GpNoCUE9b__Dj6s|vP7yDLen>}8%@k*$ujYuiqPOmX4O1-^mMd5q23sjcYJgTv zkuH{|V%{`EnhEWfjoH(!(p>bDz0y3Xm)sk@!%rRnA0SvB2I&?fH^`IZd*yi;#|7{R zisZ%e5_u^`bUEf!E98}sf7SBl^=7NEQ`jpU6pjifg$OdxMKc0YkcEGx(YQhydTG2h zJ{mtw0Q{|BNc$*FjK-iz(xhOnCRG!RIk+g;_!-cOS=wx^u|BF{%hl=Z^$vPxy^DT? zp4Kb$KJYAKFw2&zPlrvq3qF3azFdD?MRYM;LD$f=^bjK&9ICI=Gwd&ANXVjuI960$!vwixQp4# z0dS+=$Cl<|_*@=T)REhR0u}tW(xwuEJJj zr?OW$s2o)yl>*N-yj6j!V9dQlVHVi{pEC>d$GcPom=7pY6{|{BRjN8wy~omYd|1Z%CWRs_kwYCU-A;D?!oKrQL-F_^2$*5=?TN}jd=@`6YTVqqF(ge@l* zG&*mckIoO$HW*f3hAvZ=g}LXw@N$YUBU!Gi(vdMzi&63j<3xmU!eWeQ^sag@eX!o3 zPr@k4z}5`} zC|L@6Kpxt^T2_lEE0o*?5+eYzq8KvaG9>2{xvheR-4}=!O@Z%{qsUe4MT=fmR4S^` znl)%21!ncVR6b~v#hA_CtI9_!RH|xJwy1d)b)Js8&PPpG!kQlenGpa9kq+O)N$ZT- zOM*q1fqKe^MOX=Is1~(E={!&~2F$}0!)CjTStknRAHmH$1)}UxkP+$dt#eWKe0>2* zU#=%5uhG})>qz+x*vAd!x5F&F6C{NTEJ+rdb^1U~#L!9fV#tbg%%tVgd+B`WG9oQX zVOv*2Uev>%q~K3FG0w~gNDT!fh971GPRK9<(8BWUVgX5GgEuClOtM+NOjUyv_Q6dLAv|UeslmGNC$Ir zK87}+4O945%s@MuL|ur|QK|pmXeaU({LR0=?r3 z`_vn~%n!OJP!h)J9|LSuqYg4^pd3lAWEbqzJZPdqNf9j7Qdp|xlFQIYRp^^FuvJaH z)0QRr$&q#9bkqpwC>9p0D|)LJp56L!`YMVg8f!5u)^t2+$cDwb3w=0`*IZ@j&6n9K z^ynH+e?8$fm=pT8vy_GwQ}FhhQIi?%nN-e}A^L19uhEL&x0ayKUzS!tcGX}m*{Ip< zWcD%#Xg6ofim(_98eYQ%%7VF3kp$_M4zD(o({#CzbNR9YSutivOJ$caFH;GPR|}o@ z1agmz9tY??XGp*ias_msD{ngmb2>0dPPAZ#JQGhkwn7u`;_asr&UUKc?50}I)+BbO zEpIEiC`Mr9X%w!IpgsyeZUhqTn4(w=-I$57m<@Tli<78@7?nmXS*fVvWNSTUW2}|7 zN;`fgb_6#IYn*{K&b~$|W1u}3D^oFcvpAcT*sJ8}Khd9M@WL)bhgK_zlzxOUZPcSq z(4u5qv(Tj;oHh;M^eNG$Nf_zr80*>a7q()&=W)`!SXF{Ce_2(bs)k&z#f;(;6~*gT z5!NfXK+Y@F8qC3at9_thgE0$bP$zM+Aw!+1&QWhw=R(`&;|XptW(7*sm(>-VKB!gK zLGw}?Yv^7FXkTZ}wlvz6-keQov?qT?Big-KUxH^2CLLc1U02O(yL#xm zC&V_c!rqs-P_%V3iApSA1!S2QXZZ$mdMpL@Zw9=M99X}5nS4kqlP;@*gsS7TnJv69 zM|fZ^u!9w_guP$|2VhP$N^Ib?Tn2m;lcp;aE1=aJAsGyi0{IyAPgqB2uPBV;0*qU0 zj8H#ls!WW*%dj*YU|;&l(=m=pU`g6xlmuc_RUY(2H>jH~nFRVElI;H^D z1EnDa{J-zd{w3te(vqUn2L5ByVc2r7+twoZH<@<(+d%V;$SheR5_oK{LSGyQa1?GJGWaEG>KZ!&*FjeDYyKyBYJb4I=qQlI06x(Fxg2WIE9uY^fvPkZEOm5X2XH;qVb7|WS4u9yPHTphVIw9Gb3ZfG=pPEB(!2CzA6M?>7}bo8TpUo z%8u?xa@DDam9OtOW;8w0n8(3f9$lsl75T0Y~p#HSnj){Thy^!xZnFJ0VLMPU%v9f{)$)Uj!%p1ZI|-tmb};-9pA0Fc=uF|b?y63i&HA2EzzSbcBWbQp+C_*m-(L}NH7Z$;XVsH#)+`76Y$cyY?0q)-z#NicQ~X%U07!YLZ40J+L8;#qwVKeW$ql`Uq}J z+mQ_Ru&{V)ZHblBoyfPY*49>*?Ne#3O$UDL_iRr}U^CeC)pq%*%z5dXf1dj0-%DMV zt={IFwzjxKtxOHA)Vh?z+6g?*g2h^P$6HTxi-ka9y;H9?|TD}55MaZ z+Bc}Pc0!SCNa^Boir!k0o8j>4x;tAwdtKaj>D1a!Y&_1`c2IWvCVTi-OiXU3p<8EV z)n@6eC9wlOnpTZBdA7S`NAJD(XIa{(hL6>~yKO!*ZSlQ@?*1t+*qr>jx_s4PkAEVU zdv_nd`GW($9)ES(`0~4V>P0ou`H@fTUVi)cT3K~%$pZB!{km2LPuTR*#$dmVvUjCl z|6aduO83Wy{6<%A_^ba(y+drBWc1?B*%y;~-jA9UHc;`$xZauV-|!lk9{j~RmDhzs!XUv)nKA!J)&RL&! z^~cp`J}`7tZ5U(ohDEsg_d#!}Ym>M1PJI-$V}<7RhmT96VrPeZ_1MSxTv|xvQJ0&y z9QLdlcy9Z$cfP_2?zH~N1mb?9sd+)#8hyS{C^4K>n3s!Pe_W6AO|NyC5YVSC1ES% z=%fXl)R!`_Ip7E44^m&u&@x6YmS6#da_0YxDoV3#DcmiIaJPhT$5=ZyGyZN+-%ft^ z-H&Bm*>S7OYkAtQdoJ5Dq1(BzB?DJR_nL7YMtADf<5j+uA51(Sv-IF+eRo(?ja?LD z7jb#Ynz(_t?@!Cwu}~^s8B<%xEFT{^^lZW53`6+(eT^?}Z<;PECzi#T~xxhuT^X1`v>U-WaXeO*U^o8#2`CgYhF3ubKv&YcD z9`{QptseYdo!>I*_O@HUpTE)L2 zd;jE>cp)e1!rHt%RdVgbpJdC{_nB2Zz$>cL%G23{UUd1!@^brM|MBsCb8U~95UTwX z*N2&oZW|K$|2A$GY(x!UDw zUfDsB67?D%79SeI=~?5r#;|TOsv8D1r+Md^G6l^Wj>mUu(|2gz(G3YFwURLQb@#)Y zzDe$GNGyqVZisBL+>wtQADU=r5*u}c0`#-yYy`T~(hd!V0sTU5pN5)ou(ZnUWGDDh zVEjTda>`VC-0HWocY^!&D4#cNb?Sz(lixcLSA0Bd->JBRmM?m~Ho9iCS6RCK!~L7p zPaiLf8k&D;F>|AD!J?B9H{MsD9qO1P{V3F8?^w}>knim$ebRZ(rOjbq2dyfM>EW3h zH?y727qG;J&Tk4a2C!G94{I8a+(+|D;?VO5%qr3S3G5dmNP3juu z!gZQRucJ2}_vtE+ym4*lNXvchE~7pg;W@_nv)JRaGsf@s7G3)}e9GhNCqJ9}&7;@; zcsF9*A$8dGnve1}Pw)Nd_b*(_T|Y(de^349Hy4kdw4FK4b<9t?wW5d8g0*#%uCviz z3yN>kU##z&{!K!kHL4GSH5=81Dg&V2Ir5=OU+1<1f8w&I7x3#u9$ytoW-5!b;ECe z6fiV2SGv0T#iQ1Dzf&C&ryeXVs{5tuTxy|2WmB`OV!^lH`hNA!KZl}T$w*%|r~TaW zDeF7754K`$FD9OF=zHy_v(_(+-2C2prwxbS${91$X>I5<<;pb^hJEh6$Plg4-2H3x z(=Hv~%C5GUeg2(-{yV#T@Y}G;1H&^tEdEvnye>}J(dU~ll1@XBCedlufxI#u67jqL zt?~C)e|Xif<4O9DO_T#srttz@>O0otB6aN1$<&QSZey6i=*67F@nQqp;0gKp`G_Wm zC(Vyfn8OUDMI@Y6k3KEKLCa2yk53|66UtI5fk((RbOTL)cwf7$FPx;m% zzd!A^>1_RSUB}0|z(3dDWEXzxFz1)8hnMB1ElfTzH|uKc-<=rC#ollM{x$6Zon33oa`I2QDi3Fz4IftERqrs)Og`Sl#Bw8+w1Y zSTe&+^Y+x+osI+^7!lg{+Kf_t(XX$TymMge<{LX_Iu{)Kz+Zble&5sa0iV_FeOh0* z|5y26#|rB^ss5~SAJcC|Mf#UL?tXjx`ikJfOc(z=hZnbY{AKQ~^Id+>ez0-7*Qc6? z2R`mR(7U+X(prD@gG)PZymIuA^}uNxQrAbcG+q(Hu*%FYwY;k0 zsp}7am5<3-vQwfO71+Y{B4%k4pyo z-Ld+#%K1ybz5+FBR?9Y5qg{zM;9RnHv=!7S-Hi|;>y9+ks*N>1QnUx5`de#hHLc8* z=Sr7L8Z=YPD6+{<5>Y~&&NB^0)0lO4BO{ShbqzWhs%|JfgdQZ&R(*ups!58?EOJaA zSWsan-n<*MWm)-Gh1-YD=v*`N;e}sy_mZvS?oKlt@27b>sdLiovZZN*E}hC9_Nw`X4uJ_kF*Ut4`JkCztsn3J$ z2V<7&0{4}SO8fH9_8X6RP0G5LUHU=dj$1a1UV8V(9rq_q-?lJhY>s2p+1Fg>y!6L{ zg?BPPp0ny`yl4HQyV{A?73))9o>}GQ{NkZCJ%agdo@b?vk)vkxX z!rGx_$6s7sRQc9B7k1ydtB$u<;KiACsgS!-M!D+{edt12-6&Dz7lE@@Oj+_?P*CxV z6T)gEb5%7 zhZMV&;=lLwOLA&EG2iASwdspd-bsx|0_^!xSGognh;k@;CL*j2If8jE1 zydvbwkB%Bvj?4(y+bz^;X{LC`CDG@@jt9FWSiJE0rAJ>r?x#`Di%@5*nS#~Hst*iD zS4FIw^!9ICuU9`w5A1eu8M7xTcGsq)BWtv)7T&BnGadziJHv6c< zXr~U<$9}wgDN-@gQh!Ksv#MT^-lyw^+&gxL-xXzVhDR=V!FB8Lk}oD?eR9USWA_WE z*D9RGSxmQ^F#RKTLdIS%SNoSsJCwZ_nc7Ko%r|;_5Vi8%WiekIN!W3!r|(~vGV|iR zwH7nG&+9Aw{or37UECGt2l#FKV}e!x>u2U%&7AX&cKF%&x}GcV7Vmm6=(krSBQFik z9J{br_n4ovdk-yi3zmF0K3KYD(?4m(#p@@wP*!T{oZra9Xl=L=_ey zCzM`u=fx+J0Tme&KP!au2pYW+81+N>utt&DGVtiR$qB@NfH~h(RNFKW{i`O%-o7;S z6PrG@O63Q2o6={0dFL9fFv@8LuR)H?9iBUM`4EAeZsS%l0;O@E?cVKf=9veF_7rTM zXjpkJc>9-Qn+X$627mIP$Fz@o?-@2JeZG5#UEk+M76f-0Q*ZTY$!Cd0^Xbds$lbDOK#|fs0Fu=NH^;CmOfjRe8R0 z`u_cNAFX}0U=ofIt*F(Z@t_}9yy z5`zL>n=JUNW?;a-^>4v*bsckVna|JVmg%rNZ}aYmn=XIQpf({z>oZS5hD%^_4yIMtK!c8Q*={WVuGZS52YJ4u`vOs3tmCXV2y=xC4acvLn8PCruw*_ z^h+=G*FXz4Y8G*zSpZW5;DSjbLlZM26YwkmoC_>X8+RcUrT$TNR4;=>SPS0AeDzO=nh-p(L}igh+$%2uEZ?AktYqV zhUZ;mjpIH#ant%~cmK~fI@cEw{`&fX_Fv&mUH^7ZHJpPk=Q zUlo&75oR`HzsDmVqcFwa= zKHgI!wb5TxvmRD{*@^U>aK*^zKv>XD&}y2=|r&J}g# z`PP01y_|Kg$}Y&{*pYstq;y8>-d$|v%-14IKcw7eH3?q*>VLo6nR?#+RrTeCqQN4! z)HK{&1--moOT%{V$g0at&CiWxUmJKxXtCMlNef#!JiIz1y?;8}9L@LA_-M1chkc^- zzOs(M`3g_owXV6gXA4{CgGUz?)|V`kXPq1VC-8Y^jkk|yY+c0mrS|jl65f>L|B-2a z%Dt1@@OzJ&@`cOCPVJqtVUoCg?j%pUB?7bGCv6Eld)Xs&I^XsydH;idtz3G4Mb5LP zYM&&_wG)@ISf=jCeXH!h{l1Ls#hLRrf8p6xxX+sZ)~D(qPH$)RRo*PA_kVWW-}QDP zcX5^9hZ)BbJM($BcsX~S&3ekO+Z(i+eG~UZ`O@-5!AoR2rGEtPinU}|GVScaiFTXS zXI-gbf1t-wzW&C?^}ANeEwQXiU6!!x&ExWUE-P=BS?usGTYop->CW-5_xF*mPw5T)rwO{e@f+T~6!1jOCcvgQOA{kQed6<>#K>MeQl4t)6!PRSNahDUF@brhK25ukMrYeN`#vxcr83p zeNQ^6w%n&UIq#6Hh{>-rJMZ2(Q4$u=w6yZ1;^I?*PyXHzk`Zz}ZT3caRbuDyqWRqV zCbGHu?Mn@cjn`?seJgdr75+cVyE;n!<_1;W*v>LbIZ3jcwPAAeraJ7<1b)Y z4II#eE+61zGi+jf4itI}N;rvBY#A_#U~P$TvaxFOF*8ZAGAxJ%u0epigV~T9&S7T+ zrUbYQt06zIjbRQd&6>R#m7 zXNAN*FN0rcE8mQj3qGq){GGO)!NQqS$mRp*C$t77`QDq zFqEF0ueNf^i~ji!nCE?Pjho$k!Q^nY9&>pzcm6!4zPaLxCttkZdiwU^lI!bE=ica1 zYLtwh8&Rw;E9)xqTYLkXV{uo^DouSm=9#u{O9Bpf+tvDa@_wE1GV)h`-FuG5Lcf-- zbHDIs{t`*eTwV9I{!E@#XKaquX1B-w|FQGbh0~{OthYVt45~Czn8~ghd!i+~=EvS6 URkr6DKNxB&{Ez;~4_TW707o5>I{*Lx diff --git a/lib/3rdParty/tbb/bin/x86/v140/tbbmalloc.dll b/lib/3rdParty/tbb/bin/x86/v140/tbbmalloc.dll deleted file mode 100644 index 99c6495ba97e74e9a316e21e0cfdf977baca4d4e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 87312 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 Qv#UqS`Z - - -

  • KLp0(D%1F~PHlHo~9gEI$MKh95(_>fD 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�ic-VN@ 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%0A56pn->S&F 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 Cj=!M* diff --git a/lib/3rdParty/tbb/bin/x64/v140/tbb_preview.dll b/lib/3rdParty/tbb/bin/x64/v140/tbb_preview.dll deleted file mode 100644 index 735180808029827e849656c6d56f415327a588b1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 268560 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�o1^Z2K11SDK*btZHT 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 VDckn<>U;ghq2}KVE`40*{{xHd$YB5g diff --git a/lib/3rdParty/tbb/bin/x64/v140/tbbmalloc.dll b/lib/3rdParty/tbb/bin/x64/v140/tbbmalloc.dll deleted file mode 100644 index cee43368f5caae98d5649e20e757d1b9a1289bf4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 126224 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