diff --git a/inst/include/.gitignore b/inst/include/.gitignore
new file mode 100644
index 000000000..c8dc0b1c0
--- /dev/null
+++ b/inst/include/.gitignore
@@ -0,0 +1,6 @@
+
+# These TBB libraries are copied in at configure time.
+/index.html
+/serial
+/tbb
+
diff --git a/inst/include/index.html b/inst/include/index.html
deleted file mode 100644
index b0962e012..000000000
--- a/inst/include/index.html
+++ /dev/null
@@ -1,25 +0,0 @@
-
-
-
-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/inst/include/tbb_local/serial/tbb/parallel_for.h b/inst/include/tbb_local/serial/tbb/parallel_for.h
deleted file mode 100644
index 5b42a6708..000000000
--- a/inst/include/tbb_local/serial/tbb/parallel_for.h
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- Copyright (c) 2005-2019 Intel Corporation
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT 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
-
-#include "tbb_annotate.h"
-
-#ifndef __TBB_NORMAL_EXECUTION
-#include "tbb/blocked_range.h"
-#include "tbb/partitioner.h"
-#endif
-
-#if TBB_USE_EXCEPTIONS
-#include
-#include // required to construct std exception classes
-#else
-#include
-#include
-#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 ) {
-#if TBB_USE_EXCEPTIONS
- throw std::invalid_argument( "nonpositive_step" );
-#else
- std::cerr << "nonpositive step in a call to parallel_for" << std::endl;
- std::abort();
-#endif
- } 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/inst/include/tbb_local/serial/tbb/tbb_annotate.h b/inst/include/tbb_local/serial/tbb/tbb_annotate.h
deleted file mode 100644
index 6b79be2d0..000000000
--- a/inst/include/tbb_local/serial/tbb/tbb_annotate.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- Copyright (c) 2005-2019 Intel Corporation
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT 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/inst/include/tbb_local/tbb/aggregator.h b/inst/include/tbb_local/tbb/aggregator.h
deleted file mode 100644
index 33e83679e..000000000
--- a/inst/include/tbb_local/tbb/aggregator.h
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- Copyright (c) 2005-2019 Intel Corporation
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT 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/inst/include/tbb_local/tbb/aligned_space.h b/inst/include/tbb_local/tbb/aligned_space.h
deleted file mode 100644
index 03b09d098..000000000
--- a/inst/include/tbb_local/tbb/aligned_space.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- Copyright (c) 2005-2019 Intel Corporation
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT 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() const {return internal::punned_cast(this);}
-
- //! Pointer to one past last element in array.
- T* end() const {return begin()+N;}
-};
-
-} // namespace tbb
-
-#endif /* __TBB_aligned_space_H */
diff --git a/inst/include/tbb_local/tbb/atomic.h b/inst/include/tbb_local/tbb/atomic.h
deleted file mode 100644
index 92d1e11ae..000000000
--- a/inst/include/tbb_local/tbb/atomic.h
+++ /dev/null
@@ -1,554 +0,0 @@
-/*
- Copyright (c) 2005-2019 Intel Corporation
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT 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/inst/include/tbb_local/tbb/blocked_range.h b/inst/include/tbb_local/tbb/blocked_range.h
deleted file mode 100644
index d1ff1f459..000000000
--- a/inst/include/tbb_local/tbb/blocked_range.h
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- Copyright (c) 2005-2019 Intel Corporation
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT 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 {
-
-namespace internal {
-
-// blocked_rangeNd_impl forward declaration in tbb::internal namespace to
-// name it as a friend for a tbb::blocked_range.
-template
-class blocked_rangeNd_impl;
-
-} // namespace internal
-
-/** \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;
-
-#if __TBB_DEPRECATED_BLOCKED_RANGE_DEFAULT_CTOR
- //! Construct range with default-constructed values for begin, end, and grainsize.
- /** Requires that Value have a default constructor. */
- blocked_range() : my_end(), my_begin(), my_grainsize() {}
-#endif
-
- //! 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;
-
- template
- friend class internal::blocked_rangeNd_impl;
-};
-
-} // namespace tbb
-
-#endif /* __TBB_blocked_range_H */
diff --git a/inst/include/tbb_local/tbb/blocked_range2d.h b/inst/include/tbb_local/tbb/blocked_range2d.h
deleted file mode 100644
index cd0fe1c3f..000000000
--- a/inst/include/tbb_local/tbb/blocked_range2d.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- Copyright (c) 2005-2019 Intel Corporation
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT 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 {
- // Range is empty if at least one dimension is empty.
- 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 */
-
- //! 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;}
-
-private:
-
- 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);
- }
- }
-};
-
-} // namespace tbb
-
-#endif /* __TBB_blocked_range2d_H */
diff --git a/inst/include/tbb_local/tbb/blocked_range3d.h b/inst/include/tbb_local/tbb/blocked_range3d.h
deleted file mode 100644
index 5c6cf9f0e..000000000
--- a/inst/include/tbb_local/tbb/blocked_range3d.h
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- Copyright (c) 2005-2019 Intel Corporation
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT 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 {
- // Range is empty if at least one dimension is empty.
- 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 */
-
- //! 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;}
-
-private:
-
- 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);
- }
- }
- }
-};
-
-} // namespace tbb
-
-#endif /* __TBB_blocked_range3d_H */
diff --git a/inst/include/tbb_local/tbb/blocked_rangeNd.h b/inst/include/tbb_local/tbb/blocked_rangeNd.h
deleted file mode 100644
index b623d0021..000000000
--- a/inst/include/tbb_local/tbb/blocked_rangeNd.h
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- Copyright (c) 2017-2019 Intel Corporation
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT 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_rangeNd_H
-#define __TBB_blocked_rangeNd_H
-
-#if ! TBB_PREVIEW_BLOCKED_RANGE_ND
- #error Set TBB_PREVIEW_BLOCKED_RANGE_ND to include blocked_rangeNd.h
-#endif
-
-#include "tbb_config.h"
-
-// tbb::blocked_rangeNd requires C++11 support
-#if __TBB_CPP11_PRESENT && __TBB_CPP11_ARRAY_PRESENT && __TBB_CPP11_TEMPLATE_ALIASES_PRESENT
-
-#include "internal/_template_helpers.h" // index_sequence, make_index_sequence
-
-#include
-#include // std::any_of
-#include // std::is_same, std::enable_if
-
-#include "tbb/blocked_range.h"
-
-namespace tbb {
-namespace internal {
-
-/*
- The blocked_rangeNd_impl uses make_index_sequence to automatically generate a ctor with
- exactly N arguments of the type tbb::blocked_range. Such ctor provides an opportunity
- to use braced-init-list parameters to initialize each dimension.
- Use of parameters, whose representation is a braced-init-list, but they're not
- std::initializer_list or a reference to one, produces a non-deduced context
- within template argument deduction.
-
- NOTE: blocked_rangeNd must be exactly a templated alias to the blocked_rangeNd_impl
- (and not e.g. a derived class), otherwise it would need to declare its own ctor
- facing the same problem that the impl class solves.
-*/
-
-template>
-class blocked_rangeNd_impl;
-
-template
-class blocked_rangeNd_impl> {
-public:
- //! Type of a value.
- using value_type = Value;
-
-private:
-
- //! Helper type to construct range with N tbb::blocked_range objects.
- template
- using dim_type_helper = tbb::blocked_range;
-
-public:
- blocked_rangeNd_impl() = delete;
-
- //! Constructs N-dimensional range over N half-open intervals each represented as tbb::blocked_range.
- blocked_rangeNd_impl(const dim_type_helper&... args) : my_dims{ {args...} } {}
-
- //! Dimensionality of a range.
- static constexpr unsigned int ndims() { return N; }
-
- //! Range in certain dimension.
- const tbb::blocked_range& dim(unsigned int dimension) const {
- __TBB_ASSERT(dimension < N, "out of bound");
- return my_dims[dimension];
- }
-
- //------------------------------------------------------------------------
- // Methods that implement Range concept
- //------------------------------------------------------------------------
-
- //! True if at least one dimension is empty.
- bool empty() const {
- return std::any_of(my_dims.begin(), my_dims.end(), [](const tbb::blocked_range& d) {
- return d.empty();
- });
- }
-
- //! True if at least one dimension is divisible.
- bool is_divisible() const {
- return std::any_of(my_dims.begin(), my_dims.end(), [](const tbb::blocked_range& d) {
- return d.is_divisible();
- });
- }
-
-#if __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES
- //! Static field to support proportional split.
- static const bool is_splittable_in_proportion = true;
-
- blocked_rangeNd_impl(blocked_rangeNd_impl& r, proportional_split proportion) : my_dims(r.my_dims) {
- do_split(r, proportion);
- }
-#endif
-
- blocked_rangeNd_impl(blocked_rangeNd_impl& r, split proportion) : my_dims(r.my_dims) {
- do_split(r, proportion);
- }
-
-private:
- __TBB_STATIC_ASSERT(N != 0, "zero dimensional blocked_rangeNd can't be constructed");
-
- //! Ranges in each dimension.
- std::array, N> my_dims;
-
- template
- void do_split(blocked_rangeNd_impl& r, split_type proportion) {
- __TBB_STATIC_ASSERT((is_same_type::value
- || is_same_type::value),
- "type of split object is incorrect");
- __TBB_ASSERT(r.is_divisible(), "can't split not divisible range");
-
- auto my_it = std::max_element(my_dims.begin(), my_dims.end(), [](const tbb::blocked_range& first, const tbb::blocked_range& second) {
- return (first.size() * second.grainsize() < second.size() * first.grainsize());
- });
-
- auto r_it = r.my_dims.begin() + (my_it - my_dims.begin());
-
- my_it->my_begin = tbb::blocked_range::do_split(*r_it, proportion);
-
- // (!(my_it->my_begin < r_it->my_end) && !(r_it->my_end < my_it->my_begin)) equals to
- // (my_it->my_begin == r_it->my_end), but we can't use operator== due to Value concept
- __TBB_ASSERT(!(my_it->my_begin < r_it->my_end) && !(r_it->my_end < my_it->my_begin),
- "blocked_range has been split incorrectly");
- }
-};
-
-} // namespace internal
-
-template
-using blocked_rangeNd = internal::blocked_rangeNd_impl;
-
-} // namespace tbb
-
-#endif /* __TBB_CPP11_PRESENT && __TBB_CPP11_ARRAY_PRESENT && __TBB_CPP11_TEMPLATE_ALIASES_PRESENT */
-#endif /* __TBB_blocked_rangeNd_H */
diff --git a/inst/include/tbb_local/tbb/cache_aligned_allocator.h b/inst/include/tbb_local/tbb/cache_aligned_allocator.h
deleted file mode 100644
index a9983298b..000000000
--- a/inst/include/tbb_local/tbb/cache_aligned_allocator.h
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- Copyright (c) 2005-2019 Intel Corporation
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT 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
-
-#if __TBB_CPP17_MEMORY_RESOURCE_PRESENT
-#include
-#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;}
-
-#if __TBB_CPP17_MEMORY_RESOURCE_PRESENT
-
-//! C++17 memory resource wrapper to ensure cache line size alignment
-class cache_aligned_resource : public std::pmr::memory_resource {
-public:
- cache_aligned_resource() : cache_aligned_resource(std::pmr::get_default_resource()) {}
- explicit cache_aligned_resource(std::pmr::memory_resource* upstream) : m_upstream(upstream) {}
-
- std::pmr::memory_resource* upstream_resource() const {
- return m_upstream;
- }
-
-private:
- //! We don't know what memory resource set. Use padding to guarantee alignment
- void* do_allocate(size_t bytes, size_t alignment) override {
- size_t cache_line_alignment = correct_alignment(alignment);
- uintptr_t base = (uintptr_t)m_upstream->allocate(correct_size(bytes) + cache_line_alignment);
- __TBB_ASSERT(base != 0, "Upstream resource returned NULL.");
-#if _MSC_VER && !defined(__INTEL_COMPILER)
- // unary minus operator applied to unsigned type, result still unsigned
- #pragma warning(push)
- #pragma warning(disable: 4146 4706)
-#endif
- // Round up to the next cache line (align the base address)
- uintptr_t result = (base + cache_line_alignment) & -cache_line_alignment;
-#if _MSC_VER && !defined(__INTEL_COMPILER)
- #pragma warning(pop)
-#endif
- // Record where block actually starts.
- ((uintptr_t*)result)[-1] = base;
- return (void*)result;
- }
-
- void do_deallocate(void* ptr, size_t bytes, size_t alignment) override {
- if (ptr) {
- // Recover where block actually starts
- uintptr_t base = ((uintptr_t*)ptr)[-1];
- m_upstream->deallocate((void*)base, correct_size(bytes) + correct_alignment(alignment));
- }
- }
-
- bool do_is_equal(const std::pmr::memory_resource& other) const noexcept override {
- if (this == &other) { return true; }
-#if __TBB_USE_OPTIONAL_RTTI
- const cache_aligned_resource* other_res = dynamic_cast(&other);
- return other_res && (this->upstream_resource() == other_res->upstream_resource());
-#else
- return false;
-#endif
- }
-
- size_t correct_alignment(size_t alignment) {
- __TBB_ASSERT(tbb::internal::is_power_of_two(alignment), "Alignment is not a power of 2");
-#if __TBB_CPP17_HW_INTERFERENCE_SIZE_PRESENT
- size_t cache_line_size = std::hardware_destructive_interference_size;
-#else
- size_t cache_line_size = internal::NFS_GetLineSize();
-#endif
- return alignment < cache_line_size ? cache_line_size : alignment;
- }
-
- size_t correct_size(size_t bytes) {
- // To handle the case, when small size requested. There could be not
- // enough space to store the original pointer.
- return bytes < sizeof(uintptr_t) ? sizeof(uintptr_t) : bytes;
- }
-
- std::pmr::memory_resource* m_upstream;
-};
-
-#endif /* __TBB_CPP17_MEMORY_RESOURCE_PRESENT */
-
-} // namespace tbb
-
-#endif /* __TBB_cache_aligned_allocator_H */
-
diff --git a/inst/include/tbb_local/tbb/combinable.h b/inst/include/tbb_local/tbb/combinable.h
deleted file mode 100644
index a8aaf61cd..000000000
--- a/inst/include/tbb_local/tbb/combinable.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- Copyright (c) 2005-2019 Intel Corporation
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT 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/inst/include/tbb_local/tbb/compat/condition_variable b/inst/include/tbb_local/tbb/compat/condition_variable
deleted file mode 100644
index 8dc4e9133..000000000
--- a/inst/include/tbb_local/tbb/compat/condition_variable
+++ /dev/null
@@ -1,472 +0,0 @@
-/*
- Copyright (c) 2005-2019 Intel Corporation
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT 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