diff --git a/CHANGES b/CHANGES index 5eae7dd..2acb3a1 100644 --- a/CHANGES +++ b/CHANGES @@ -2,6 +2,27 @@ The list of most significant changes made over time in Intel(R) Threading Building Blocks (Intel(R) TBB). +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 diff --git a/Makefile b/Makefile index 38f1c3c..8198698 100644 --- a/Makefile +++ b/Makefile @@ -54,6 +54,10 @@ rml: mkdir examples: tbb tbbmalloc $(MAKE) -C examples -r -f Makefile tbb_root=.. release test +python: mkdir + $(MAKE) -C "$(work_dir)_release" -r -f $(tbb_root)/build/Makefile.tbb cfg=release + bash -c ". $(work_dir)_release$(SLASH)tbbvars.sh && $(MAKE) -rC '$(full_tbb_root)/python' CXX=$(compiler) install test-install" + .PHONY: clean clean_examples mkdir info clean: clean_examples diff --git a/README.md b/README.md index 9276d9d..f7d4110 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![Build Status](https://travis-ci.org/wjakob/tbb.svg?branch=master)](https://travis-ci.org/wjakob/tbb) [![Build status](https://ci.appveyor.com/api/projects/status/fvepmk5nxekq27r8?svg=true)](https://ci.appveyor.com/project/wjakob/tbb/branch/master) -This is git repository is currently based on TBB 4.4 Update 4 and will be +This is git repository is currently based on TBB 4.4 Update 5 and will be updated from time to time to track the most recent release. The only modification is the addition of a CMake-based build system. diff --git a/build/index.html b/build/index.html index 32b34c5..e696580 100644 --- a/build/index.html +++ b/build/index.html @@ -45,6 +45,8 @@ To port Intel TBB to a new platform, operating system or architecture, see the <
  • GNU make utility. On Windows OS, if a UNIX* emulator is used to run GNU make, it should be able to run Windows OS utilities and commands. On Linux OS, OS X, etc., shell commands issued by GNU make should execute in a Bourne or BASH compatible shell. + In the following examples, replace make with the correct GNU make command for + your system (for example, gmake). GNU make version 3.80 and more recent are supported.

    @@ -57,7 +59,7 @@ On systems that support both 64-bit and 32-bit libraries, these steps build the

  • Change to the top-level directory of the installed software.
  • If using the Intel® C++ compiler, make sure the appropriate compiler is available in your PATH (e.g., by sourcing the appropriate iccvars script for the compiler to be used). -
  • Invoke GNU make using no arguments, for example, 'gmake'. +
  • Invoke GNU make using no arguments, for example, make.

    @@ -68,15 +70,15 @@ or related systems that support both 64-bit and 32-bit libraries), perform the f

  • Change to the top-level directory of the installed software.
  • If using the Intel® C++ compiler, make sure the appropriate compiler is available in your PATH (e.g., by sourcing the appropriate iccvars script for the compiler to be used). -
  • Invoke GNU make as follows, 'gmake arch=ia32'. +
  • Explicitly specify the architecture when invoking GNU make, e.g. make arch=ia32.

    The default make target will build the release and debug versions of the Intel TBB library.

    Other targets are available in the top-level Makefile. You might find the following targets useful:

    See also the list of other targets below.

    @@ -100,9 +102,9 @@ To perform different build and/or test operations, use the following steps.
  • Invoke GNU make by using one or more of the following commands.
    make -
    Default build. Equivalent to 'make tbb tbbmalloc'. +
    Default build. Equivalent to make tbb tbbmalloc.
    make all -
    Equivalent to 'make tbb tbbmalloc test examples'. +
    Equivalent to make tbb tbbmalloc test examples.
    cd src;make release
    Build and test release libraries only.
    cd src;make debug @@ -114,7 +116,9 @@ To perform different build and/or test operations, use the following steps.
    make test
    Compile and run unit-tests
    make examples -
    Build libraries and run all examples, like doing 'make debug clean release' from the general example Makefile. +
    Build libraries and run all examples, like doing make debug clean release from the general example Makefile. +
    make python +
    Build, install, and test Python* API for Intel TBB. See details here.
    make compiler={icl, icc, gcc, clang} [(above options or targets)]
    Build and run as above, but use specified compilers instead of default, native compilers
      @@ -137,7 +141,7 @@ To perform different build and/or test operations, use the following steps.
      Build and run as above, but build libraries for the selected ABI. Might be useful for cross-compilation; ensure proper environment is set before running this command.
      make tbb_root={(Intel TBB directory)} [(above options or targets)] -
      Build and run as above; for use when invoking 'make' from a directory other than the top-level directory. +
      Build and run as above; for use when invoking make from a directory other than the top-level directory.
      make tbb_build_dir={(build directory)} [(above options or targets)]
      Build and run as above, but place the built libraries in the specified directory, rather than in the default sub-directory within the build/ directory. This command might have troubles with the build in case the sources installed to the directory with spaces in the path.
      make tbb_build_prefix={(build sub-directory)} [(above options or targets)] @@ -229,8 +233,7 @@ See the Makefile infrastructure files for examples.

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

      -Intel and Itanium are registered trademarks or trademarks of Intel Corporation or its -subsidiaries in the United States and other countries. +Intel, the Intel logo and Itanium are trademarks of Intel Corporation in the U.S. and/or other countries.

      * Other names and brands may be claimed as the property of others. diff --git a/build/ios.macos.inc b/build/ios.macos.inc index f03bd8c..95b3bad 100644 --- a/build/ios.macos.inc +++ b/build/ios.macos.inc @@ -20,7 +20,7 @@ ifneq ($(arch),$(filter $(arch),ia32 intel64 armv7 armv7s arm64)) $(error $(arch) is unknown architecture. Known arhitechtures are ia32 intel64 armv7 armv7s arm64) endif -# if target is ios but arch is ia32/intel64 then build for 32/64 simulator! +# If target is ios but arch is ia32/intel64 then build for 32/64 simulator! ifeq (,$(SDKROOT)) ifeq ($(arch),$(filter $(arch),ia32 intel64)) export SDKROOT:=$(shell xcodebuild -sdk -version | grep -o -E '/.*SDKs/iPhoneSimulator.*' 2>/dev/null) diff --git a/build/linux.icc.inc b/build/linux.icc.inc index 1bae169..593608d 100644 --- a/build/linux.icc.inc +++ b/build/linux.icc.inc @@ -70,7 +70,10 @@ ifeq (ia64,$(arch)) # strict-ansi does not work with on RHEL 4 AS CPLUS_FLAGS += $(PIC_KEY) $(if $(findstring cc3.,$(runtime)),-ansi,-strict-ansi) else - CPLUS_FLAGS += -strict-ansi +# For ICC 16 and older, -strict-ansi does not work with GNU C++ library headers +# in std=c++14 mode, use -ansi for them +# egrep returns 0 or 1, compare it in concatenation + CPLUS_FLAGS += $(if $(findstring c++14_1,$(stdver)_$(shell icc -dumpversion| egrep -c "^1[1-6]\.")),-ansi,-strict-ansi) endif ifneq (,$(codecov)) diff --git a/doc/Release_Notes.txt b/doc/Release_Notes.txt index a8870b4..511d1d0 100644 --- a/doc/Release_Notes.txt +++ b/doc/Release_Notes.txt @@ -169,9 +169,8 @@ Library Issues ------------------------------------------------------------------------ (C) 2016 Intel Corporation -Intel, Xeon and Pentium are registered trademarks or trademarks of -Intel Corporation or its subsidiaries in the United States and other -countries. +Intel, the Intel logo, Intel Core, Xeon, Xeon Phi and Pentium are +trademarks of Intel Corporation in the U.S. and/or other countries. * Other names and brands may be claimed as the property of others. diff --git a/examples/common/examples-common.inc b/examples/common/examples-common.inc index a0c1c9f..b0b0a37 100644 --- a/examples/common/examples-common.inc +++ b/examples/common/examples-common.inc @@ -17,7 +17,7 @@ # reasons why the executable file might be covered by the GNU General Public License. # detect if a compiler can support C++11 -# if CXX0XFLAGS already set, do not change it +# If CXX0XFLAGS already set, do not change it ifneq (,$(findstring $(CXX), icc icpc clang++)) # every supported icc or clang is OK CXX0XFLAGS ?= -std=c++0x diff --git a/examples/graph/fgbzip2/fgbzip2.cpp b/examples/graph/fgbzip2/fgbzip2.cpp index 513a640..e4b43d4 100644 --- a/examples/graph/fgbzip2/fgbzip2.cpp +++ b/examples/graph/fgbzip2/fgbzip2.cpp @@ -54,6 +54,10 @@ struct buffer_t { bool operator==( const buffer_t& other ) { return (this == &other) || (seq_id == other.seq_id && len == other.len && b == other.b); } + + bool operator!=(const buffer_t& other) { + return !(*this == other); + } }; buffer_t dummyBuffer = {0}; @@ -106,28 +110,13 @@ public: IOActivity( std::ifstream& inputStream, std::ofstream& output, size_t chunkSize ) : my_inputStream(inputStream), my_outputStream(output), my_chunkSize(chunkSize), my_fileWriter( [this]() { - std::priority_queue< buffer_t, std::vector, buffer_comp > my_outputQueue; - size_t my_nextOutputId = 0; - - while( true ) { - buffer_t buffer; - my_writeQueue.pop( buffer ); - if( buffer == dummyBuffer ) break; - if( buffer.seq_id == my_nextOutputId ) { - my_outputStream.write( buffer.b, buffer.len ); - delete[] buffer.b; - ++my_nextOutputId; - while( !my_outputQueue.empty() && my_outputQueue.top().seq_id == my_nextOutputId ) { - buffer = my_outputQueue.top(); - my_outputQueue.pop(); - my_outputStream.write( buffer.b, buffer.len ); - delete[] buffer.b; - ++my_nextOutputId; - } - } else { - my_outputQueue.push( buffer ); - } - } + buffer_t buffer; + my_writeQueue.pop(buffer); + while (buffer != dummyBuffer) { + my_outputStream.write(buffer.b, buffer.len); + delete[] buffer.b; + my_writeQueue.pop(buffer); + }; }) {} @@ -191,7 +180,8 @@ void fgCompressionAsyncIO( std::ifstream& inputStream, std::ofstream& outputStre return buffer.seq_id; }); - async_file_writer_node output_writer( g, tbb::flow::unlimited, [&ioActivity](const buffer_t& buffer, async_file_writer_node::async_gateway_type& asyncGateway ) { + // The node is serial to preserve the right order of buffers set by the preceding sequencer_node + async_file_writer_node output_writer( g, tbb::flow::serial, [&ioActivity](const buffer_t& buffer, async_file_writer_node::async_gateway_type& asyncGateway ) { ioActivity.write( buffer ); }); diff --git a/examples/parallel_for/game_of_life/msvs/resource.h b/examples/parallel_for/game_of_life/msvs/resource.h index d5ac7c4..031c527 100644 --- a/examples/parallel_for/game_of_life/msvs/resource.h +++ b/examples/parallel_for/game_of_life/msvs/resource.h @@ -1,3 +1,23 @@ +/* + Copyright 2005-2016 Intel Corporation. All Rights Reserved. + + This file is part of Threading Building Blocks. Threading Building Blocks is free software; + you can redistribute it and/or modify it under the terms of the GNU General Public License + version 2 as published by the Free Software Foundation. Threading Building Blocks is + distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. You should have received a copy of + the GNU General Public License along with Threading Building Blocks; if not, write to the + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + As a special exception, you may use this file as part of a free software library without + restriction. Specifically, if other files instantiate templates or use macros or inline + functions from this file, or you compile this file and link it with other files to produce + an executable, this file does not by itself cause the resulting executable to be covered + by the GNU General Public License. This exception does not however invalidate any other + reasons why the executable file might be covered by the GNU General Public License. +*/ + //{{NO_DEPENDENCIES}} // Microsoft Visual C++ generated include file. // Used by app.rc diff --git a/examples/parallel_for/polygon_overlay/msvs/resource.h b/examples/parallel_for/polygon_overlay/msvs/resource.h index e70b4ea..1ee7fd8 100644 --- a/examples/parallel_for/polygon_overlay/msvs/resource.h +++ b/examples/parallel_for/polygon_overlay/msvs/resource.h @@ -1,3 +1,23 @@ +/* + Copyright 2005-2016 Intel Corporation. All Rights Reserved. + + This file is part of Threading Building Blocks. Threading Building Blocks is free software; + you can redistribute it and/or modify it under the terms of the GNU General Public License + version 2 as published by the Free Software Foundation. Threading Building Blocks is + distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. You should have received a copy of + the GNU General Public License along with Threading Building Blocks; if not, write to the + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + As a special exception, you may use this file as part of a free software library without + restriction. Specifically, if other files instantiate templates or use macros or inline + functions from this file, or you compile this file and link it with other files to produce + an executable, this file does not by itself cause the resulting executable to be covered + by the GNU General Public License. This exception does not however invalidate any other + reasons why the executable file might be covered by the GNU General Public License. +*/ + //{{NO_DEPENDENCIES}} // Microsoft Visual C++ generated include file. // Used by pover.rc diff --git a/examples/parallel_for/seismic/msvs/resource.h b/examples/parallel_for/seismic/msvs/resource.h index 44453d7..c9e40b0 100644 --- a/examples/parallel_for/seismic/msvs/resource.h +++ b/examples/parallel_for/seismic/msvs/resource.h @@ -1,3 +1,23 @@ +/* + Copyright 2005-2016 Intel Corporation. All Rights Reserved. + + This file is part of Threading Building Blocks. Threading Building Blocks is free software; + you can redistribute it and/or modify it under the terms of the GNU General Public License + version 2 as published by the Free Software Foundation. Threading Building Blocks is + distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. You should have received a copy of + the GNU General Public License along with Threading Building Blocks; if not, write to the + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + As a special exception, you may use this file as part of a free software library without + restriction. Specifically, if other files instantiate templates or use macros or inline + functions from this file, or you compile this file and link it with other files to produce + an executable, this file does not by itself cause the resulting executable to be covered + by the GNU General Public License. This exception does not however invalidate any other + reasons why the executable file might be covered by the GNU General Public License. +*/ + //{{NO_DEPENDENCIES}} // Microsoft Visual C++ generated include file. // Used by SeismicSimulation.rc diff --git a/examples/parallel_for/tachyon/android/jni/Android.mk b/examples/parallel_for/tachyon/android/jni/Android.mk index 748fccf..9c30489 100644 --- a/examples/parallel_for/tachyon/android/jni/Android.mk +++ b/examples/parallel_for/tachyon/android/jni/Android.mk @@ -1,20 +1,20 @@ # Copyright 2005-2016 Intel Corporation. All Rights Reserved. # -# The source code contained or described herein and all documents related -# to the source code ("Material") are owned by Intel Corporation or its -# suppliers or licensors. Title to the Material remains with Intel -# Corporation or its suppliers and licensors. The Material is protected -# by worldwide copyright laws and treaty provisions. No part of the -# Material may be used, copied, reproduced, modified, published, uploaded, -# posted, transmitted, distributed, or disclosed in any way without -# Intel's prior express written permission. +# This file is part of Threading Building Blocks. Threading Building Blocks is free software; +# you can redistribute it and/or modify it under the terms of the GNU General Public License +# version 2 as published by the Free Software Foundation. Threading Building Blocks is +# distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. You should have received a copy of +# the GNU General Public License along with Threading Building Blocks; if not, write to the +# Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # -# No license under any patent, copyright, trade secret or other -# intellectual property right is granted to or conferred upon you by -# disclosure or delivery of the Materials, either expressly, by -# implication, inducement, estoppel or otherwise. Any license under such -# intellectual property rights must be express and approved by Intel in -# writing. +# As a special exception, you may use this file as part of a free software library without +# restriction. Specifically, if other files instantiate templates or use macros or inline +# functions from this file, or you compile this file and link it with other files to produce +# an executable, this file does not by itself cause the resulting executable to be covered +# by the GNU General Public License. This exception does not however invalidate any other +# reasons why the executable file might be covered by the GNU General Public License. # The original source for this example is diff --git a/examples/parallel_for/tachyon/android/jni/Application.mk b/examples/parallel_for/tachyon/android/jni/Application.mk index e697b2d..c55fdd4 100644 --- a/examples/parallel_for/tachyon/android/jni/Application.mk +++ b/examples/parallel_for/tachyon/android/jni/Application.mk @@ -1,20 +1,20 @@ # Copyright 2005-2016 Intel Corporation. All Rights Reserved. # -# The source code contained or described herein and all documents related -# to the source code ("Material") are owned by Intel Corporation or its -# suppliers or licensors. Title to the Material remains with Intel -# Corporation or its suppliers and licensors. The Material is protected -# by worldwide copyright laws and treaty provisions. No part of the -# Material may be used, copied, reproduced, modified, published, uploaded, -# posted, transmitted, distributed, or disclosed in any way without -# Intel's prior express written permission. +# This file is part of Threading Building Blocks. Threading Building Blocks is free software; +# you can redistribute it and/or modify it under the terms of the GNU General Public License +# version 2 as published by the Free Software Foundation. Threading Building Blocks is +# distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. You should have received a copy of +# the GNU General Public License along with Threading Building Blocks; if not, write to the +# Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # -# No license under any patent, copyright, trade secret or other -# intellectual property right is granted to or conferred upon you by -# disclosure or delivery of the Materials, either expressly, by -# implication, inducement, estoppel or otherwise. Any license under such -# intellectual property rights must be express and approved by Intel in -# writing. +# As a special exception, you may use this file as part of a free software library without +# restriction. Specifically, if other files instantiate templates or use macros or inline +# functions from this file, or you compile this file and link it with other files to produce +# an executable, this file does not by itself cause the resulting executable to be covered +# by the GNU General Public License. This exception does not however invalidate any other +# reasons why the executable file might be covered by the GNU General Public License. APP_ABI:= all APP_STL:=gnustl_shared diff --git a/examples/parallel_for/tachyon/android/jni/jni-engine.cpp b/examples/parallel_for/tachyon/android/jni/jni-engine.cpp index ce55c73..abad09a 100644 --- a/examples/parallel_for/tachyon/android/jni/jni-engine.cpp +++ b/examples/parallel_for/tachyon/android/jni/jni-engine.cpp @@ -1,21 +1,21 @@ /* Copyright 2005-2016 Intel Corporation. All Rights Reserved. - The source code contained or described herein and all documents related - to the source code ("Material") are owned by Intel Corporation or its - suppliers or licensors. Title to the Material remains with Intel - Corporation or its suppliers and licensors. The Material is protected - by worldwide copyright laws and treaty provisions. No part of the - Material may be used, copied, reproduced, modified, published, uploaded, - posted, transmitted, distributed, or disclosed in any way without - Intel's prior express written permission. + This file is part of Threading Building Blocks. Threading Building Blocks is free software; + you can redistribute it and/or modify it under the terms of the GNU General Public License + version 2 as published by the Free Software Foundation. Threading Building Blocks is + distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. You should have received a copy of + the GNU General Public License along with Threading Building Blocks; if not, write to the + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - No license under any patent, copyright, trade secret or other - intellectual property right is granted to or conferred upon you by - disclosure or delivery of the Materials, either expressly, by - implication, inducement, estoppel or otherwise. Any license under such - intellectual property rights must be express and approved by Intel in - writing. + As a special exception, you may use this file as part of a free software library without + restriction. Specifically, if other files instantiate templates or use macros or inline + functions from this file, or you compile this file and link it with other files to produce + an executable, this file does not by itself cause the resulting executable to be covered + by the GNU General Public License. This exception does not however invalidate any other + reasons why the executable file might be covered by the GNU General Public License. */ /* diff --git a/examples/parallel_for/tachyon/android/src/com/intel/tbb/example/tachyon/tachyon.java b/examples/parallel_for/tachyon/android/src/com/intel/tbb/example/tachyon/tachyon.java index df6850b..070f9ba 100644 --- a/examples/parallel_for/tachyon/android/src/com/intel/tbb/example/tachyon/tachyon.java +++ b/examples/parallel_for/tachyon/android/src/com/intel/tbb/example/tachyon/tachyon.java @@ -1,21 +1,21 @@ /* Copyright 2005-2016 Intel Corporation. All Rights Reserved. - The source code contained or described herein and all documents related - to the source code ("Material") are owned by Intel Corporation or its - suppliers or licensors. Title to the Material remains with Intel - Corporation or its suppliers and licensors. The Material is protected - by worldwide copyright laws and treaty provisions. No part of the - Material may be used, copied, reproduced, modified, published, uploaded, - posted, transmitted, distributed, or disclosed in any way without - Intel's prior express written permission. + This file is part of Threading Building Blocks. Threading Building Blocks is free software; + you can redistribute it and/or modify it under the terms of the GNU General Public License + version 2 as published by the Free Software Foundation. Threading Building Blocks is + distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. You should have received a copy of + the GNU General Public License along with Threading Building Blocks; if not, write to the + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - No license under any patent, copyright, trade secret or other - intellectual property right is granted to or conferred upon you by - disclosure or delivery of the Materials, either expressly, by - implication, inducement, estoppel or otherwise. Any license under such - intellectual property rights must be express and approved by Intel in - writing. + As a special exception, you may use this file as part of a free software library without + restriction. Specifically, if other files instantiate templates or use macros or inline + functions from this file, or you compile this file and link it with other files to produce + an executable, this file does not by itself cause the resulting executable to be covered + by the GNU General Public License. This exception does not however invalidate any other + reasons why the executable file might be covered by the GNU General Public License. */ /* diff --git a/examples/parallel_for/tachyon/msvs/resource.h b/examples/parallel_for/tachyon/msvs/resource.h index 5f70f0c..dd14356 100644 --- a/examples/parallel_for/tachyon/msvs/resource.h +++ b/examples/parallel_for/tachyon/msvs/resource.h @@ -1,3 +1,23 @@ +/* + Copyright 2005-2016 Intel Corporation. All Rights Reserved. + + This file is part of Threading Building Blocks. Threading Building Blocks is free software; + you can redistribute it and/or modify it under the terms of the GNU General Public License + version 2 as published by the Free Software Foundation. Threading Building Blocks is + distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. You should have received a copy of + the GNU General Public License along with Threading Building Blocks; if not, write to the + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + As a special exception, you may use this file as part of a free software library without + restriction. Specifically, if other files instantiate templates or use macros or inline + functions from this file, or you compile this file and link it with other files to produce + an executable, this file does not by itself cause the resulting executable to be covered + by the GNU General Public License. This exception does not however invalidate any other + reasons why the executable file might be covered by the GNU General Public License. +*/ + #define IDC_MYICON 2 #define IDD_GUI 102 #define IDS_APP_TITLE 103 diff --git a/examples/parallel_for/tachyon/msvs/win8ui/App.xaml.cpp b/examples/parallel_for/tachyon/msvs/win8ui/App.xaml.cpp index 0450c3c..98fa60f 100644 --- a/examples/parallel_for/tachyon/msvs/win8ui/App.xaml.cpp +++ b/examples/parallel_for/tachyon/msvs/win8ui/App.xaml.cpp @@ -1,21 +1,21 @@ /* Copyright 2005-2016 Intel Corporation. All Rights Reserved. - The source code contained or described herein and all documents related - to the source code ("Material") are owned by Intel Corporation or its - suppliers or licensors. Title to the Material remains with Intel - Corporation or its suppliers and licensors. The Material is protected - by worldwide copyright laws and treaty provisions. No part of the - Material may be used, copied, reproduced, modified, published, uploaded, - posted, transmitted, distributed, or disclosed in any way without - Intel's prior express written permission. + This file is part of Threading Building Blocks. Threading Building Blocks is free software; + you can redistribute it and/or modify it under the terms of the GNU General Public License + version 2 as published by the Free Software Foundation. Threading Building Blocks is + distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. You should have received a copy of + the GNU General Public License along with Threading Building Blocks; if not, write to the + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - No license under any patent, copyright, trade secret or other - intellectual property right is granted to or conferred upon you by - disclosure or delivery of the Materials, either expressly, by - implication, inducement, estoppel or otherwise. Any license under such - intellectual property rights must be express and approved by Intel in - writing. + As a special exception, you may use this file as part of a free software library without + restriction. Specifically, if other files instantiate templates or use macros or inline + functions from this file, or you compile this file and link it with other files to produce + an executable, this file does not by itself cause the resulting executable to be covered + by the GNU General Public License. This exception does not however invalidate any other + reasons why the executable file might be covered by the GNU General Public License. */ #include "DirectXPage.xaml.h" diff --git a/examples/parallel_for/tachyon/msvs/win8ui/App.xaml.h b/examples/parallel_for/tachyon/msvs/win8ui/App.xaml.h index 0d1352d..084062a 100644 --- a/examples/parallel_for/tachyon/msvs/win8ui/App.xaml.h +++ b/examples/parallel_for/tachyon/msvs/win8ui/App.xaml.h @@ -1,21 +1,21 @@ /* Copyright 2005-2016 Intel Corporation. All Rights Reserved. - The source code contained or described herein and all documents related - to the source code ("Material") are owned by Intel Corporation or its - suppliers or licensors. Title to the Material remains with Intel - Corporation or its suppliers and licensors. The Material is protected - by worldwide copyright laws and treaty provisions. No part of the - Material may be used, copied, reproduced, modified, published, uploaded, - posted, transmitted, distributed, or disclosed in any way without - Intel's prior express written permission. + This file is part of Threading Building Blocks. Threading Building Blocks is free software; + you can redistribute it and/or modify it under the terms of the GNU General Public License + version 2 as published by the Free Software Foundation. Threading Building Blocks is + distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. You should have received a copy of + the GNU General Public License along with Threading Building Blocks; if not, write to the + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - No license under any patent, copyright, trade secret or other - intellectual property right is granted to or conferred upon you by - disclosure or delivery of the Materials, either expressly, by - implication, inducement, estoppel or otherwise. Any license under such - intellectual property rights must be express and approved by Intel in - writing. + As a special exception, you may use this file as part of a free software library without + restriction. Specifically, if other files instantiate templates or use macros or inline + functions from this file, or you compile this file and link it with other files to produce + an executable, this file does not by itself cause the resulting executable to be covered + by the GNU General Public License. This exception does not however invalidate any other + reasons why the executable file might be covered by the GNU General Public License. */ diff --git a/examples/parallel_for/tachyon/msvs/win8ui/DirectXBase.cpp b/examples/parallel_for/tachyon/msvs/win8ui/DirectXBase.cpp index 619db14..073beac 100644 --- a/examples/parallel_for/tachyon/msvs/win8ui/DirectXBase.cpp +++ b/examples/parallel_for/tachyon/msvs/win8ui/DirectXBase.cpp @@ -1,21 +1,21 @@ /* Copyright 2005-2016 Intel Corporation. All Rights Reserved. - The source code contained or described herein and all documents related - to the source code ("Material") are owned by Intel Corporation or its - suppliers or licensors. Title to the Material remains with Intel - Corporation or its suppliers and licensors. The Material is protected - by worldwide copyright laws and treaty provisions. No part of the - Material may be used, copied, reproduced, modified, published, uploaded, - posted, transmitted, distributed, or disclosed in any way without - Intel's prior express written permission. + This file is part of Threading Building Blocks. Threading Building Blocks is free software; + you can redistribute it and/or modify it under the terms of the GNU General Public License + version 2 as published by the Free Software Foundation. Threading Building Blocks is + distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. You should have received a copy of + the GNU General Public License along with Threading Building Blocks; if not, write to the + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - No license under any patent, copyright, trade secret or other - intellectual property right is granted to or conferred upon you by - disclosure or delivery of the Materials, either expressly, by - implication, inducement, estoppel or otherwise. Any license under such - intellectual property rights must be express and approved by Intel in - writing. + As a special exception, you may use this file as part of a free software library without + restriction. Specifically, if other files instantiate templates or use macros or inline + functions from this file, or you compile this file and link it with other files to produce + an executable, this file does not by itself cause the resulting executable to be covered + by the GNU General Public License. This exception does not however invalidate any other + reasons why the executable file might be covered by the GNU General Public License. */ #include "pch.h" diff --git a/examples/parallel_for/tachyon/msvs/win8ui/DirectXBase.h b/examples/parallel_for/tachyon/msvs/win8ui/DirectXBase.h index 6cb0776..b9f4103 100644 --- a/examples/parallel_for/tachyon/msvs/win8ui/DirectXBase.h +++ b/examples/parallel_for/tachyon/msvs/win8ui/DirectXBase.h @@ -1,21 +1,21 @@ /* Copyright 2005-2016 Intel Corporation. All Rights Reserved. - The source code contained or described herein and all documents related - to the source code ("Material") are owned by Intel Corporation or its - suppliers or licensors. Title to the Material remains with Intel - Corporation or its suppliers and licensors. The Material is protected - by worldwide copyright laws and treaty provisions. No part of the - Material may be used, copied, reproduced, modified, published, uploaded, - posted, transmitted, distributed, or disclosed in any way without - Intel's prior express written permission. + This file is part of Threading Building Blocks. Threading Building Blocks is free software; + you can redistribute it and/or modify it under the terms of the GNU General Public License + version 2 as published by the Free Software Foundation. Threading Building Blocks is + distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. You should have received a copy of + the GNU General Public License along with Threading Building Blocks; if not, write to the + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - No license under any patent, copyright, trade secret or other - intellectual property right is granted to or conferred upon you by - disclosure or delivery of the Materials, either expressly, by - implication, inducement, estoppel or otherwise. Any license under such - intellectual property rights must be express and approved by Intel in - writing. + As a special exception, you may use this file as part of a free software library without + restriction. Specifically, if other files instantiate templates or use macros or inline + functions from this file, or you compile this file and link it with other files to produce + an executable, this file does not by itself cause the resulting executable to be covered + by the GNU General Public License. This exception does not however invalidate any other + reasons why the executable file might be covered by the GNU General Public License. */ #pragma once diff --git a/examples/parallel_for/tachyon/msvs/win8ui/DirectXPage.xaml.cpp b/examples/parallel_for/tachyon/msvs/win8ui/DirectXPage.xaml.cpp index 3c08ffa..beb4880 100644 --- a/examples/parallel_for/tachyon/msvs/win8ui/DirectXPage.xaml.cpp +++ b/examples/parallel_for/tachyon/msvs/win8ui/DirectXPage.xaml.cpp @@ -1,21 +1,21 @@ /* Copyright 2005-2016 Intel Corporation. All Rights Reserved. - The source code contained or described herein and all documents related - to the source code ("Material") are owned by Intel Corporation or its - suppliers or licensors. Title to the Material remains with Intel - Corporation or its suppliers and licensors. The Material is protected - by worldwide copyright laws and treaty provisions. No part of the - Material may be used, copied, reproduced, modified, published, uploaded, - posted, transmitted, distributed, or disclosed in any way without - Intel's prior express written permission. + This file is part of Threading Building Blocks. Threading Building Blocks is free software; + you can redistribute it and/or modify it under the terms of the GNU General Public License + version 2 as published by the Free Software Foundation. Threading Building Blocks is + distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. You should have received a copy of + the GNU General Public License along with Threading Building Blocks; if not, write to the + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - No license under any patent, copyright, trade secret or other - intellectual property right is granted to or conferred upon you by - disclosure or delivery of the Materials, either expressly, by - implication, inducement, estoppel or otherwise. Any license under such - intellectual property rights must be express and approved by Intel in - writing. + As a special exception, you may use this file as part of a free software library without + restriction. Specifically, if other files instantiate templates or use macros or inline + functions from this file, or you compile this file and link it with other files to produce + an executable, this file does not by itself cause the resulting executable to be covered + by the GNU General Public License. This exception does not however invalidate any other + reasons why the executable file might be covered by the GNU General Public License. */ diff --git a/examples/parallel_for/tachyon/msvs/win8ui/DirectXPage.xaml.h b/examples/parallel_for/tachyon/msvs/win8ui/DirectXPage.xaml.h index d16f164..3bf5f35 100644 --- a/examples/parallel_for/tachyon/msvs/win8ui/DirectXPage.xaml.h +++ b/examples/parallel_for/tachyon/msvs/win8ui/DirectXPage.xaml.h @@ -1,21 +1,21 @@ /* Copyright 2005-2016 Intel Corporation. All Rights Reserved. - The source code contained or described herein and all documents related - to the source code ("Material") are owned by Intel Corporation or its - suppliers or licensors. Title to the Material remains with Intel - Corporation or its suppliers and licensors. The Material is protected - by worldwide copyright laws and treaty provisions. No part of the - Material may be used, copied, reproduced, modified, published, uploaded, - posted, transmitted, distributed, or disclosed in any way without - Intel's prior express written permission. + This file is part of Threading Building Blocks. Threading Building Blocks is free software; + you can redistribute it and/or modify it under the terms of the GNU General Public License + version 2 as published by the Free Software Foundation. Threading Building Blocks is + distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. You should have received a copy of + the GNU General Public License along with Threading Building Blocks; if not, write to the + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - No license under any patent, copyright, trade secret or other - intellectual property right is granted to or conferred upon you by - disclosure or delivery of the Materials, either expressly, by - implication, inducement, estoppel or otherwise. Any license under such - intellectual property rights must be express and approved by Intel in - writing. + As a special exception, you may use this file as part of a free software library without + restriction. Specifically, if other files instantiate templates or use macros or inline + functions from this file, or you compile this file and link it with other files to produce + an executable, this file does not by itself cause the resulting executable to be covered + by the GNU General Public License. This exception does not however invalidate any other + reasons why the executable file might be covered by the GNU General Public License. */ #pragma once diff --git a/examples/parallel_for/tachyon/msvs/win8ui/copy_libraries_and_assets.bat b/examples/parallel_for/tachyon/msvs/win8ui/copy_libraries_and_assets.bat old mode 100755 new mode 100644 index dc90411..874dd4d --- a/examples/parallel_for/tachyon/msvs/win8ui/copy_libraries_and_assets.bat +++ b/examples/parallel_for/tachyon/msvs/win8ui/copy_libraries_and_assets.bat @@ -2,21 +2,21 @@ REM REM Copyright 2005-2016 Intel Corporation. All Rights Reserved. REM -REM The source code contained or described herein and all documents related -REM to the source code ("Material") are owned by Intel Corporation or its -REM suppliers or licensors. Title to the Material remains with Intel -REM Corporation or its suppliers and licensors. The Material is protected -REM by worldwide copyright laws and treaty provisions. No part of the -REM Material may be used, copied, reproduced, modified, published, uploaded, -REM posted, transmitted, distributed, or disclosed in any way without -REM Intel's prior express written permission. +REM This file is part of Threading Building Blocks. Threading Building Blocks is free software; +REM you can redistribute it and/or modify it under the terms of the GNU General Public License +REM version 2 as published by the Free Software Foundation. Threading Building Blocks is +REM distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the +REM implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +REM See the GNU General Public License for more details. You should have received a copy of +REM the GNU General Public License along with Threading Building Blocks; if not, write to the +REM Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA REM -REM No license under any patent, copyright, trade secret or other -REM intellectual property right is granted to or conferred upon you by -REM disclosure or delivery of the Materials, either expressly, by -REM implication, inducement, estoppel or otherwise. Any license under such -REM intellectual property rights must be express and approved by Intel in -REM writing. +REM As a special exception, you may use this file as part of a free software library without +REM restriction. Specifically, if other files instantiate templates or use macros or inline +REM functions from this file, or you compile this file and link it with other files to produce +REM an executable, this file does not by itself cause the resulting executable to be covered +REM by the GNU General Public License. This exception does not however invalidate any other +REM reasons why the executable file might be covered by the GNU General Public License. REM :: Getting parameters :: Architecture diff --git a/examples/parallel_for/tachyon/msvs/win8ui/pch.h b/examples/parallel_for/tachyon/msvs/win8ui/pch.h index 59cde67..e1d10d1 100644 --- a/examples/parallel_for/tachyon/msvs/win8ui/pch.h +++ b/examples/parallel_for/tachyon/msvs/win8ui/pch.h @@ -1,21 +1,21 @@ /* Copyright 2005-2016 Intel Corporation. All Rights Reserved. - The source code contained or described herein and all documents related - to the source code ("Material") are owned by Intel Corporation or its - suppliers or licensors. Title to the Material remains with Intel - Corporation or its suppliers and licensors. The Material is protected - by worldwide copyright laws and treaty provisions. No part of the - Material may be used, copied, reproduced, modified, published, uploaded, - posted, transmitted, distributed, or disclosed in any way without - Intel's prior express written permission. + This file is part of Threading Building Blocks. Threading Building Blocks is free software; + you can redistribute it and/or modify it under the terms of the GNU General Public License + version 2 as published by the Free Software Foundation. Threading Building Blocks is + distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. You should have received a copy of + the GNU General Public License along with Threading Building Blocks; if not, write to the + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - No license under any patent, copyright, trade secret or other - intellectual property right is granted to or conferred upon you by - disclosure or delivery of the Materials, either expressly, by - implication, inducement, estoppel or otherwise. Any license under such - intellectual property rights must be express and approved by Intel in - writing. + As a special exception, you may use this file as part of a free software library without + restriction. Specifically, if other files instantiate templates or use macros or inline + functions from this file, or you compile this file and link it with other files to produce + an executable, this file does not by itself cause the resulting executable to be covered + by the GNU General Public License. This exception does not however invalidate any other + reasons why the executable file might be covered by the GNU General Public License. */ #pragma once diff --git a/examples/parallel_for/tachyon/msvs/win8ui/tbbTachyonRenderer.cpp b/examples/parallel_for/tachyon/msvs/win8ui/tbbTachyonRenderer.cpp index 4c2093c..68fbf65 100644 --- a/examples/parallel_for/tachyon/msvs/win8ui/tbbTachyonRenderer.cpp +++ b/examples/parallel_for/tachyon/msvs/win8ui/tbbTachyonRenderer.cpp @@ -1,21 +1,21 @@ /* -Copyright 2005-2016 Intel Corporation. All Rights Reserved. + Copyright 2005-2016 Intel Corporation. All Rights Reserved. -The source code contained or described herein and all documents related -to the source code ("Material") are owned by Intel Corporation or its -suppliers or licensors. Title to the Material remains with Intel -Corporation or its suppliers and licensors. The Material is protected -by worldwide copyright laws and treaty provisions. No part of the -Material may be used, copied, reproduced, modified, published, uploaded, -posted, transmitted, distributed, or disclosed in any way without -Intel's prior express written permission. + This file is part of Threading Building Blocks. Threading Building Blocks is free software; + you can redistribute it and/or modify it under the terms of the GNU General Public License + version 2 as published by the Free Software Foundation. Threading Building Blocks is + distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. You should have received a copy of + the GNU General Public License along with Threading Building Blocks; if not, write to the + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -No license under any patent, copyright, trade secret or other -intellectual property right is granted to or conferred upon you by -disclosure or delivery of the Materials, either expressly, by -implication, inducement, estoppel or otherwise. Any license under such -intellectual property rights must be express and approved by Intel in -writing. + As a special exception, you may use this file as part of a free software library without + restriction. Specifically, if other files instantiate templates or use macros or inline + functions from this file, or you compile this file and link it with other files to produce + an executable, this file does not by itself cause the resulting executable to be covered + by the GNU General Public License. This exception does not however invalidate any other + reasons why the executable file might be covered by the GNU General Public License. */ #include "pch.h" diff --git a/examples/parallel_for/tachyon/msvs/win8ui/tbbTachyonRenderer.h b/examples/parallel_for/tachyon/msvs/win8ui/tbbTachyonRenderer.h index 58663bc..5916f96 100644 --- a/examples/parallel_for/tachyon/msvs/win8ui/tbbTachyonRenderer.h +++ b/examples/parallel_for/tachyon/msvs/win8ui/tbbTachyonRenderer.h @@ -1,21 +1,21 @@ /* Copyright 2005-2016 Intel Corporation. All Rights Reserved. - The source code contained or described herein and all documents related - to the source code ("Material") are owned by Intel Corporation or its - suppliers or licensors. Title to the Material remains with Intel - Corporation or its suppliers and licensors. The Material is protected - by worldwide copyright laws and treaty provisions. No part of the - Material may be used, copied, reproduced, modified, published, uploaded, - posted, transmitted, distributed, or disclosed in any way without - Intel's prior express written permission. + This file is part of Threading Building Blocks. Threading Building Blocks is free software; + you can redistribute it and/or modify it under the terms of the GNU General Public License + version 2 as published by the Free Software Foundation. Threading Building Blocks is + distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. You should have received a copy of + the GNU General Public License along with Threading Building Blocks; if not, write to the + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - No license under any patent, copyright, trade secret or other - intellectual property right is granted to or conferred upon you by - disclosure or delivery of the Materials, either expressly, by - implication, inducement, estoppel or otherwise. Any license under such - intellectual property rights must be express and approved by Intel in - writing. + As a special exception, you may use this file as part of a free software library without + restriction. Specifically, if other files instantiate templates or use macros or inline + functions from this file, or you compile this file and link it with other files to produce + an executable, this file does not by itself cause the resulting executable to be covered + by the GNU General Public License. This exception does not however invalidate any other + reasons why the executable file might be covered by the GNU General Public License. */ #pragma once diff --git a/examples/task_arena/fractal/msvs/resource.h b/examples/task_arena/fractal/msvs/resource.h index ef7ac10..e3ea078 100644 --- a/examples/task_arena/fractal/msvs/resource.h +++ b/examples/task_arena/fractal/msvs/resource.h @@ -1,3 +1,23 @@ +/* + Copyright 2005-2016 Intel Corporation. All Rights Reserved. + + This file is part of Threading Building Blocks. Threading Building Blocks is free software; + you can redistribute it and/or modify it under the terms of the GNU General Public License + version 2 as published by the Free Software Foundation. Threading Building Blocks is + distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. You should have received a copy of + the GNU General Public License along with Threading Building Blocks; if not, write to the + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + As a special exception, you may use this file as part of a free software library without + restriction. Specifically, if other files instantiate templates or use macros or inline + functions from this file, or you compile this file and link it with other files to produce + an executable, this file does not by itself cause the resulting executable to be covered + by the GNU General Public License. This exception does not however invalidate any other + reasons why the executable file might be covered by the GNU General Public License. +*/ + #define IDC_MYICON 2 #define IDD_GUI 102 #define IDS_APP_TITLE 103 diff --git a/include/tbb/concurrent_unordered_map.h b/include/tbb/concurrent_unordered_map.h index 09a2a28..47ae858 100644 --- a/include/tbb/concurrent_unordered_map.h +++ b/include/tbb/concurrent_unordered_map.h @@ -142,7 +142,7 @@ public: } #endif //# __TBB_INITIALIZER_LISTS_PRESENT -#if __TBB_CPP11_RVALUE_REF_PRESENT && __TBB_CPP11_IMPLICIT_MOVE_MEMBERS_GENERATION_FOR_DERIVED_BROKEN +#if __TBB_CPP11_IMPLICIT_MOVE_MEMBERS_GENERATION_BROKEN concurrent_unordered_map(const concurrent_unordered_map& table) : base_type(table) { @@ -162,7 +162,7 @@ public: { return static_cast(base_type::operator=(std::move(table))); } -#endif //__TBB_CPP11_IMPLICIT_MOVE_MEMBERS_GENERATION_FOR_DERIVED_BROKEN +#endif //__TBB_CPP11_IMPLICIT_MOVE_MEMBERS_GENERATION_BROKEN concurrent_unordered_map(const concurrent_unordered_map& table, const Allocator& a) : base_type(table, a) @@ -283,7 +283,7 @@ public: } #endif //# __TBB_INITIALIZER_LISTS_PRESENT -#if __TBB_CPP11_RVALUE_REF_PRESENT && __TBB_CPP11_IMPLICIT_MOVE_MEMBERS_GENERATION_FOR_DERIVED_BROKEN +#if __TBB_CPP11_IMPLICIT_MOVE_MEMBERS_GENERATION_BROKEN concurrent_unordered_multimap(const concurrent_unordered_multimap& table) : base_type(table) { @@ -303,7 +303,7 @@ public: { return static_cast(base_type::operator=(std::move(table))); } -#endif //__TBB_CPP11_IMPLICIT_MOVE_MEMBERS_GENERATION_FOR_DERIVED_BROKEN +#endif //__TBB_CPP11_IMPLICIT_MOVE_MEMBERS_GENERATION_BROKEN concurrent_unordered_multimap(const concurrent_unordered_multimap& table, const Allocator& a) : base_type(table, a) diff --git a/include/tbb/concurrent_unordered_set.h b/include/tbb/concurrent_unordered_set.h index 62d992b..846ac79 100644 --- a/include/tbb/concurrent_unordered_set.h +++ b/include/tbb/concurrent_unordered_set.h @@ -119,7 +119,7 @@ public: } #endif //# __TBB_INITIALIZER_LISTS_PRESENT -#if __TBB_CPP11_RVALUE_REF_PRESENT && __TBB_CPP11_IMPLICIT_MOVE_MEMBERS_GENERATION_FOR_DERIVED_BROKEN +#if __TBB_CPP11_IMPLICIT_MOVE_MEMBERS_GENERATION_BROKEN concurrent_unordered_set(const concurrent_unordered_set& table) : base_type(table) { @@ -139,7 +139,7 @@ public: { return static_cast(base_type::operator=(std::move(table))); } -#endif //__TBB_CPP11_IMPLICIT_MOVE_MEMBERS_GENERATION_FOR_DERIVED_BROKEN +#endif //__TBB_CPP11_IMPLICIT_MOVE_MEMBERS_GENERATION_BROKEN concurrent_unordered_set(const concurrent_unordered_set& table, const Allocator& a) : base_type(table, a) @@ -225,7 +225,7 @@ public: } #endif //# __TBB_INITIALIZER_LISTS_PRESENT -#if __TBB_CPP11_RVALUE_REF_PRESENT && __TBB_CPP11_IMPLICIT_MOVE_MEMBERS_GENERATION_FOR_DERIVED_BROKEN +#if __TBB_CPP11_IMPLICIT_MOVE_MEMBERS_GENERATION_BROKEN concurrent_unordered_multiset(const concurrent_unordered_multiset& table) : base_type(table) { @@ -245,7 +245,7 @@ public: { return static_cast(base_type::operator=(std::move(table))); } -#endif //__TBB_CPP11_IMPLICIT_MOVE_MEMBERS_GENERATION_FOR_DERIVED_BROKEN +#endif //__TBB_CPP11_IMPLICIT_MOVE_MEMBERS_GENERATION_BROKEN concurrent_unordered_multiset(const concurrent_unordered_multiset& table, const Allocator& a) : base_type(table, a) diff --git a/include/tbb/internal/_concurrent_unordered_impl.h b/include/tbb/internal/_concurrent_unordered_impl.h index 21f2ae6..f1bc705 100644 --- a/include/tbb/internal/_concurrent_unordered_impl.h +++ b/include/tbb/internal/_concurrent_unordered_impl.h @@ -708,7 +708,7 @@ protected: my_allocator(a), my_maximum_bucket_size((float) initial_bucket_load) { if( n_of_buckets == 0) ++n_of_buckets; - my_number_of_buckets = 1<<__TBB_Log2((uintptr_t)n_of_buckets*2-1); // round up to power of 2 + my_number_of_buckets = size_type(1)<<__TBB_Log2((uintptr_t)n_of_buckets*2-1); // round up to power of 2 internal_init(); } @@ -1194,7 +1194,7 @@ public: size_type current_buckets = my_number_of_buckets; if (current_buckets >= buckets) return; - my_number_of_buckets = 1<<__TBB_Log2((uintptr_t)buckets*2-1); // round up to power of 2 + my_number_of_buckets = size_type(1)<<__TBB_Log2((uintptr_t)buckets*2-1); // round up to power of 2 } private: diff --git a/include/tbb/scalable_allocator.h b/include/tbb/scalable_allocator.h index 26853b4..e2bdaec 100644 --- a/include/tbb/scalable_allocator.h +++ b/include/tbb/scalable_allocator.h @@ -282,18 +282,18 @@ public: template void construct(U *p, Args&&... args) { ::new((void *)p) U(std::forward(args)...); } -#else // __TBB_ALLOCATOR_CONSTRUCT_VARIADIC +#else /* __TBB_ALLOCATOR_CONSTRUCT_VARIADIC */ #if __TBB_CPP11_RVALUE_REF_PRESENT void construct( pointer p, value_type&& value ) { ::new((void*)(p)) value_type( std::move( value ) ); } #endif void construct( pointer p, const value_type& value ) {::new((void*)(p)) value_type(value);} -#endif // __TBB_ALLOCATOR_CONSTRUCT_VARIADIC +#endif /* __TBB_ALLOCATOR_CONSTRUCT_VARIADIC */ void destroy( pointer p ) {p->~value_type();} }; #if _MSC_VER && !defined(__INTEL_COMPILER) #pragma warning (pop) -#endif // warning 4100 is back +#endif /* warning 4100 is back */ //! Analogous to std::allocator, as defined in ISO C++ Standard, Section 20.4.1 /** @ingroup memory_allocation */ @@ -336,6 +336,6 @@ inline bool operator!=( const scalable_allocator&, const scalable_allocator= 40700 || __TBB_CPP11_TYPE_PROPERTIES_PRESENT) -// In GCC and MSVC, implementation of std::move_if_noexcept is not aligned with noexcept +// In GCC, std::move_if_noexcept appeared later than noexcept #define __TBB_MOVE_IF_NOEXCEPT_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40700 || _MSC_VER >= 1900 || __clang__ && _LIBCPP_VERSION && __TBB_NOEXCEPT_PRESENT) //TODO: Probably more accurate way is to analyze version of stdlibc++ via__GLIBCXX__ instead of __TBB_GCC_VERSION #define __TBB_ALLOCATOR_TRAITS_PRESENT (__cplusplus >= 201103L && _LIBCPP_VERSION || _MSC_VER >= 1700 || \ @@ -552,7 +552,7 @@ #endif #if (_WIN32||_WIN64) && __INTEL_COMPILER == 1110 - /** That's a bug in Intel compiler 11.1.044/IA-32/Windows, that leads to a worker thread crash on the thread's startup. **/ + /** That's a bug in Intel(R) C++ Compiler 11.1.044/IA-32 architecture/Windows* OS, that leads to a worker thread crash on the thread's startup. **/ #define __TBB_ICL_11_1_CODE_GEN_BROKEN 1 #endif @@ -585,7 +585,7 @@ #endif /* __FreeBSD__ */ #if (__linux__ || __APPLE__) && __i386__ && defined(__INTEL_COMPILER) - /** The Intel compiler for IA-32 (Linux|OS X) crashes or generates + /** The Intel(R) C++ Compiler for IA-32 architecture (Linux* OS|OS X*) crashes or generates incorrect code when __asm__ arguments have a cast to volatile. **/ #define __TBB_ICC_ASM_VOLATILE_BROKEN 1 #endif @@ -639,11 +639,12 @@ #define __TBB_GCC_CAS8_BUILTIN_INLINING_BROKEN 1 #endif -#if __TBB_x86_32 && (__linux__ || __APPLE__ || _WIN32 || __sun || __ANDROID__) && (__INTEL_COMPILER || (__GNUC__==3 && __GNUC_MINOR__==3 )||(__MINGW32__ ) && (__GNUC__==4 && __GNUC_MINOR__==5 ) || __SUNPRO_CC) - // Some compilers for IA-32 fail to provide 8-byte alignment of objects on the stack, - // even if the object specifies 8-byte alignment. On such platforms, the IA-32 implementation - // of 64 bit atomics (e.g. atomic) use different tactics depending upon - // whether the object is properly aligned or not. +#if __TBB_x86_32 && ( __INTEL_COMPILER || (__GNUC__==5 && __GNUC_MINOR__==2 && __GXX_EXPERIMENTAL_CXX0X__) \ + || (__GNUC__==3 && __GNUC_MINOR__==3) || (__MINGW32__ && __GNUC__==4 && __GNUC_MINOR__==5) || __SUNPRO_CC ) + // Some compilers for IA-32 architecture fail to provide 8-byte alignment of objects on the stack, + // even if the object specifies 8-byte alignment. On such platforms, the implementation + // of 64 bit atomics for IA-32 architecture (e.g. atomic) use different tactics + // depending upon whether the object is properly aligned or not. #define __TBB_FORCE_64BIT_ALIGNMENT_BROKEN 1 #else #define __TBB_FORCE_64BIT_ALIGNMENT_BROKEN 0 @@ -662,9 +663,17 @@ // A compiler bug: a disabled copy constructor prevents use of the moving constructor #define __TBB_IF_NO_COPY_CTOR_MOVE_SEMANTICS_BROKEN (_MSC_VER && (__INTEL_COMPILER >= 1300 && __INTEL_COMPILER <= 1310) && !__INTEL_CXX11_MODE__) -// MSVC 2013 and ICC do not generate implicit move constructor for empty derived class -#define __TBB_CPP11_IMPLICIT_MOVE_MEMBERS_GENERATION_FOR_DERIVED_BROKEN (__TBB_CPP11_RVALUE_REF_PRESENT && \ - ( !__INTEL_COMPILER && _MSC_VER && _MSC_VER <= 1800 || __INTEL_COMPILER && __INTEL_COMPILER <= 1600 )) +#if __TBB_CPP11_RVALUE_REF_PRESENT +//Some compilers added implicit generation of move constructor & assignment operator in a later version +#if _MSC_VER + // Covers Intel C++ Compiler for Windows, which has compatible behavior + #define __TBB_CPP11_IMPLICIT_MOVE_MEMBERS_GENERATION_BROKEN (_MSC_VER <= 1800) +#elif __INTEL_COMPILER + #define __TBB_CPP11_IMPLICIT_MOVE_MEMBERS_GENERATION_BROKEN (__INTEL_COMPILER < 1400 || __INTEL_COMPILER==1600) +#elif __clang__ + #define __TBB_CPP11_IMPLICIT_MOVE_MEMBERS_GENERATION_BROKEN (!__has_feature(cxx_implicit_moves)) +#endif +#endif /* __TBB_CPP11_RVALUE_REF_PRESENT */ #define __TBB_CPP11_DECLVAL_BROKEN (_MSC_VER == 1600 || (__GNUC__ && __TBB_GCC_VERSION < 40500) ) @@ -686,8 +695,8 @@ #define __TBB_ATOMIC_CTORS (__TBB_CONSTEXPR_PRESENT && __TBB_DEFAULTED_AND_DELETED_FUNC_PRESENT && (!__TBB_ZERO_INIT_WITH_DEFAULTED_CTOR_BROKEN)) // Many OS versions (Android 4.0.[0-3] for example) need workaround for dlopen to avoid non-recursive loader lock hang -// Setting the workaround for all compile targets ($APP_PLATFORM) below Android 4.4 (android-19) -#if __ANDROID__ +// Setting the workaround for all compile targets ($APP_PLATFORM) below Android 4.4 (android-19) +#if __ANDROID__ #include #define __TBB_USE_DLOPEN_REENTRANCY_WORKAROUND (__ANDROID_API__ < 19) #endif diff --git a/include/tbb/tbb_stddef.h b/include/tbb/tbb_stddef.h index 20f6718..7198c22 100644 --- a/include/tbb/tbb_stddef.h +++ b/include/tbb/tbb_stddef.h @@ -26,7 +26,7 @@ #define TBB_VERSION_MINOR 4 // Engineering-focused interface version -#define TBB_INTERFACE_VERSION 9004 +#define TBB_INTERFACE_VERSION 9005 #define TBB_INTERFACE_VERSION_MAJOR TBB_INTERFACE_VERSION/1000 // The oldest major interface version still supported diff --git a/index.html b/index.html index 4e95262..abcefa6 100644 --- a/index.html +++ b/index.html @@ -1,41 +1,35 @@ +

      Overview

      -Top level directory for Intel® Threading Building Blocks. -

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

      Intel TBB source package

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

      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

      + +

      Files

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

      Directories

      + +

      Directories

      +
      bin +
      Start-up scripts for sourcing library. +
      include +
      Include files required for compiling code that uses the library. +
      examples +
      Examples of how to use the library. +
      lib +
      Platform-specific binary files for the library.
      src
      Source code for the library.
      build
      Internal Makefile infrastructure for Intel TBB. Do not use directly; see the build directions.
      -

      Intel TBB binary package

      -

      Directories

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

      Copyright © 2005-2016 Intel Corporation. All Rights Reserved. @@ -46,3 +40,4 @@ 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/src/Makefile b/src/Makefile index d457e77..f1fee32 100644 --- a/src/Makefile +++ b/src/Makefile @@ -94,6 +94,9 @@ else @$(MAKE) -C "$(work_dir)_$(cfg)" -r -f $(tbb_root)/build/Makefile.test $@ endif +python_%: tbb_release + bash -c ". $(work_dir)_release$(SLASH)tbbvars.sh && $(MAKE) -rC '$(full_tbb_root)/python' CXX=$(compiler) $(subst python_,,$@)" + .PHONY: test_release test_debug test_release_no_depends test_debug_no_depends .PHONY: tbb_release tbb_debug tbb_test_release tbb_test_debug tbb_test_release_no_depends tbb_test_debug_no_depends # do not delete double-space after -C option diff --git a/src/index.html b/src/index.html index 30ebf79..77c719c 100644 --- a/src/index.html +++ b/src/index.html @@ -44,6 +44,8 @@ This directory contains the source code and unit tests for Intel® Threading
      Enables warnings as errors.
      make examples/{target}
      Invokes examples/Makefile with specified target. +
      make python_{target} [compiler={icl, icc}] +
      Invokes Makefile with the specified target in python directory. E.g. 'python_install' target builds and installs the module into Python.
      make clean_release clean_debug clean_examples
      Removes release or debug build directories, or cleans all examples.
      make test_no_depends diff --git a/src/rml/test/test_rml_mixed.cpp b/src/rml/test/test_rml_mixed.cpp index 7ed06a1..1de5bcc 100644 --- a/src/rml/test/test_rml_mixed.cpp +++ b/src/rml/test/test_rml_mixed.cpp @@ -38,7 +38,7 @@ int TestMain () { // non-deterministic. Thus dynamic_link fails on some systems when the // application changes its current directory after the library (TBB/OpenMP/...) // is loaded but before the static constructors in the library are executed. -#define CHDIR_SUPPORT_BROKEN ( (__TBB_GCC_VERSION >= 40600 && __TBB_GCC_VERSION < 50200) || (__linux__ && __TBB_CLANG_VERSION == 30500) ) +#define CHDIR_SUPPORT_BROKEN ( __TBB_GCC_VERSION >= 40600 || (__linux__ && __TBB_CLANG_VERSION >= 30500) ) const int OMP_ParallelRegionSize = 16; int TBB_MaxThread = 4; // Includes master diff --git a/src/tbb/arena.cpp b/src/tbb/arena.cpp index fbf42b5..12eac90 100644 --- a/src/tbb/arena.cpp +++ b/src/tbb/arena.cpp @@ -225,7 +225,7 @@ arena::arena ( market& m, unsigned num_slots, unsigned num_reserved_slots ) { my_task_stream.initialize(my_num_slots); ITT_SYNC_CREATE(&my_task_stream, SyncType_Scheduler, SyncObj_TaskStream); #if __TBB_ENQUEUE_ENFORCED_CONCURRENCY - my_mandatory_mode = no_mandatory; + my_concurrency_mode = cm_normal; #endif #if !__TBB_FP_CONTEXT my_cpu_ctl_env.get_env(); @@ -236,7 +236,7 @@ arena& arena::allocate_arena( market& m, unsigned num_slots, unsigned num_reserv __TBB_ASSERT( sizeof(base_type) + sizeof(arena_slot) == sizeof(arena), "All arena data fields must go to arena_base" ); __TBB_ASSERT( sizeof(base_type) % NFS_GetLineSize() == 0, "arena slots area misaligned: wrong padding" ); __TBB_ASSERT( sizeof(mail_outbox) == NFS_MaxLineSize, "Mailbox padding is wrong" ); - size_t n = allocation_size(num_slots); + size_t n = allocation_size(num_arena_slots(num_slots)); unsigned char* storage = (unsigned char*)NFS_Allocate( 1, n, NULL ); // Zero all slots to indicate that they are empty memset( storage, 0, n ); @@ -249,7 +249,7 @@ void arena::free_arena () { __TBB_ASSERT( !my_num_workers_requested && !my_num_workers_allotted, "Dying arena requests workers" ); __TBB_ASSERT( my_pool_state == SNAPSHOT_EMPTY || !my_max_num_workers, "Inconsistent state of a dying arena" ); #if __TBB_ENQUEUE_ENFORCED_CONCURRENCY - __TBB_ASSERT( my_mandatory_mode != global_mandatory, NULL ); + __TBB_ASSERT( my_concurrency_mode != cm_enforced_global, NULL ); #endif #if !__TBB_STATISTICS_EARLY_DUMP GATHER_STATISTIC( dump_arena_statistics() ); @@ -286,7 +286,7 @@ void arena::free_arena () { __TBB_ASSERT( my_pool_state == SNAPSHOT_EMPTY || !my_max_num_workers, NULL ); this->~arena(); #if TBB_USE_ASSERT > 1 - memset( storage, 0, allocation_size(my_max_num_workers) ); + memset( storage, 0, allocation_size(my_num_slots) ); #endif /* TBB_USE_ASSERT */ NFS_Free( storage ); } @@ -365,24 +365,21 @@ void arena::orphan_offloaded_tasks(generic_scheduler& s) { } #endif /* __TBB_TASK_PRIORITY */ -void arena::restore_priorities_if_need() { +bool arena::has_enqueued_tasks() { + // Look for enqueued tasks at all priority levels + for ( int p = 0; p < num_priority_levels; ++p ) + if ( !my_task_stream.empty(p) ) + return true; + return false; +} + +void arena::restore_priority_if_need() { // Check for the presence of enqueued tasks "lost" on some of // priority levels because updating arena priority and switching // arena into "populated" (FULL) state happen non-atomically. // Imposing atomicity would require task::enqueue() to use a lock, // which is unacceptable. -#if __TBB_TASK_PRIORITY - bool switch_back = false; - for ( int p = 0; p < num_priority_levels; ++p ) { - if ( !my_task_stream.empty(p) ) { - switch_back = true; - break; - } - } -#else - bool switch_back = !my_task_stream.empty(0); -#endif /* __TBB_TASK_PRIORITY */ - if ( switch_back ) { + if ( has_enqueued_tasks() ) { advertise_new_work(); #if __TBB_TASK_PRIORITY // update_arena_priority() expects non-zero arena::my_num_workers_requested, @@ -500,17 +497,17 @@ bool arena::is_out_of_work() { int current_demand = (int)my_max_num_workers; if( my_pool_state.compare_and_swap( SNAPSHOT_EMPTY, busy )==busy ) { #if __TBB_ENQUEUE_ENFORCED_CONCURRENCY - if( my_mandatory_mode==global_mandatory ) { + if( my_concurrency_mode==cm_enforced_global ) { // adjust_demand() called inside, if needed my_market->mandatory_concurrency_disable( this ); } else #endif /* __TBB_ENQUEUE_ENFORCED_CONCURRENCY */ { // This thread transitioned pool to empty state, and thus is - // responsible for telling RML that there is no other work to do. + // responsible for telling the market that there is no work to do. my_market->adjust_demand( *this, -current_demand ); } - restore_priorities_if_need(); + restore_priority_if_need(); return true; } return false; diff --git a/src/tbb/arena.h b/src/tbb/arena.h index 41fd86c..2be98d6 100644 --- a/src/tbb/arena.h +++ b/src/tbb/arena.h @@ -43,11 +43,11 @@ class allocate_root_with_context_proxy; namespace internal { -//! arena data except the array of slots +//! The structure of an arena, except the array of slots. /** Separated in order to simplify padding. Intrusive list node base class is used by market to form a list of arenas. **/ struct arena_base : padded { - //! Number of workers that have been marked out by the resource manager to service the arena + //! The number of workers that have been marked out by the resource manager to service the arena. unsigned my_num_workers_allotted; // heavy use in stealing loop //! Reference counter for the arena. @@ -57,30 +57,27 @@ struct arena_base : padded { atomic my_references; // heavy use in stealing loop #if __TBB_TASK_PRIORITY - //! Highest priority of recently spawned or enqueued tasks. + //! The highest priority of recently spawned or enqueued tasks. volatile intptr_t my_top_priority; // heavy use in stealing loop #endif /* !__TBB_TASK_PRIORITY */ - //! Maximal number of currently busy slots. + //! The maximal number of currently busy slots. atomic my_limit; // heavy use in stealing loop - //! Task pool for the tasks scheduled via task::enqueue() method + //! Task pool for the tasks scheduled via task::enqueue() method. /** Such scheduling guarantees eventual execution even if - new tasks are constantly coming (by extracting scheduled tasks in relaxed FIFO order); - - the enqueuing thread does not call any of wait_for_all methods. **/ -#if __TBB_TASK_PRIORITY + - the enqueuing thread does not call any of wait_for_all methods. + Depending on __TBB_TASK_PRIORITY, num_priority_levels can be 1 or more. **/ task_stream my_task_stream; // heavy use in stealing loop -#else /* !__TBB_TASK_PRIORITY */ - task_stream<1> my_task_stream; // heavy use in stealing loop -#endif /* !__TBB_TASK_PRIORITY */ - //! Number of workers that are currently requested from the resource manager - int my_num_workers_requested; - - //! Number of workers requested by the master thread owning the arena + //! The number of workers requested by the master thread owning the arena. unsigned my_max_num_workers; + //! The number of workers that are currently requested from the resource manager. + int my_num_workers_requested; + //! Current task pool state and estimate of available tasks amount. /** The estimate is either 0 (SNAPSHOT_EMPTY) or infinity (SNAPSHOT_FULL). Special state is "busy" (any other unsigned value). @@ -89,12 +86,12 @@ struct arena_base : padded { tbb::atomic my_pool_state; #if __TBB_ARENA_OBSERVER - //! List of local observers attached to this arena. + //! The list of local observers attached to this arena. observer_list my_observers; #endif #if __TBB_TASK_PRIORITY - //! Lowest normalized priority of available spawned or enqueued tasks. + //! The lowest normalized priority of available spawned or enqueued tasks. intptr_t my_bottom_priority; //! Tracks events that may bring tasks in offload areas to the top priority level. @@ -102,13 +99,13 @@ struct arena_base : padded { is elevated to the current arena's top level. **/ uintptr_t my_reload_epoch; - //! List of offloaded tasks abandoned by workers revoked by the market + //! The list of offloaded tasks abandoned by workers revoked by the market. task* my_orphaned_tasks; //! Counter used to track the occurrence of recent orphaning and re-sharing operations. tbb::atomic my_abandonment_epoch; - //! Highest priority level containing enqueued tasks + //! The highest priority level containing enqueued tasks. /** It being greater than 0 means that high priority enqueued tasks had to be bypassed because all workers were blocked in nested dispatch loops and were unable to progress at then current priority level. **/ @@ -117,10 +114,10 @@ struct arena_base : padded { // Below are rarely modified members - //! Market owning this arena + //! The market that owns this arena. market* my_market; - //! ABA prevention marker + //! ABA prevention marker. uintptr_t my_aba_epoch; #if !__TBB_FP_CONTEXT @@ -135,24 +132,25 @@ struct arena_base : padded { task_group_context* my_default_ctx; #endif /* __TBB_TASK_GROUP_CONTEXT */ - //! Number of slots in the arena + //! The number of slots in the arena. unsigned my_num_slots; - //! Number of reserved slots (can be occupied only by masters) + //! The number of reserved slots (can be occupied only by masters). unsigned my_num_reserved_slots; #if __TBB_ENQUEUE_ENFORCED_CONCURRENCY - enum mandatory_mode { - no_mandatory, - local_mandatory, - global_mandatory + //! Possible states for the concurrency mode of an arena. + enum concurrency_mode { + cm_normal = 0, // arena is served by workers as usual + cm_enforced_local, // arena needs an extra worker despite the arena limit + cm_enforced_global // arena needs an extra worker despite a global limit }; - //! Is mandatory concurrency subject of per-arena set or global control? - mandatory_mode my_mandatory_mode; + //! The concurrency mode of an arena. + concurrency_mode my_concurrency_mode; #endif /* __TBB_ENQUEUE_ENFORCED_CONCURRENCY */ - //! exit notifications after arena slot is released + //! Waiting object for master threads that cannot join the arena. concurrent_monitor my_exit_monitors; #if TBB_USE_ASSERT @@ -163,12 +161,12 @@ struct arena_base : padded { class arena: public padded { - //! Restore priorities of arenas and task presence status of the arena, if new enqueued tasks found - void restore_priorities_if_need(); + //! If enqueued tasks found, restore arena priority and task presence status + void restore_priority_if_need(); public: typedef padded base_type; - //! type of work that advertised by advertise_new_work() + //! Types of work advertised by advertise_new_work() enum new_work_type { work_spawned, wakeup, @@ -185,8 +183,8 @@ public: return max(2u, num_slots); } - static int allocation_size ( unsigned max_num_workers ) { - return sizeof(base_type) + num_arena_slots(max_num_workers) * (sizeof(mail_outbox) + sizeof(arena_slot)); + static int allocation_size ( unsigned num_slots ) { + return sizeof(base_type) + num_slots * (sizeof(mail_outbox) + sizeof(arena_slot)); } //! Get reference to mailbox corresponding to given affinity_id. @@ -259,16 +257,19 @@ public: intptr_t workers_task_node_count(); #endif + //! Check for the presence of enqueued tasks at all priority levels + bool has_enqueued_tasks(); + #if __TBB_ENQUEUE_ENFORCED_CONCURRENCY //! Recall worker if global mandatory is enabled, but not for this arena bool recall_by_mandatory_request() const { - return my_market->my_mandatory_num_requested && my_mandatory_mode==arena_base::no_mandatory; + return my_market->my_mandatory_num_requested && my_concurrency_mode==cm_normal; } - //! Mandatory parallelism requested by this arena - bool mandatory_requested() const { - return my_num_workers_requested && my_market->my_mandatory_num_requested - && my_mandatory_mode!=arena_base::no_mandatory; + //! The arena is currently in an enforced concurrency mode + bool must_have_concurrency() const { + return my_num_workers_requested && + ( my_concurrency_mode==cm_enforced_local || my_concurrency_mode==cm_enforced_global ); } #endif static const size_t out_of_arena = ~size_t(0); @@ -355,11 +356,8 @@ inline void arena::on_thread_leaving ( ) { // because it can create the demand of workers, // but the arena can be already empty (and so ready for destroying) if( ref_param==ref_external && my_num_slots != my_num_reserved_slots - && 0 == m->my_num_workers_soft_limit && my_mandatory_mode==no_mandatory ) { + && 0 == m->my_num_workers_soft_limit && my_concurrency_mode==cm_normal ) { bool is_out = false; -#if !__TBB_TASK_PRIORITY - const int num_priority_levels = 1; -#endif for (int i=0; i void arena::advertise_new_work() { if( work_type == work_enqueued ) { #if __TBB_ENQUEUE_ENFORCED_CONCURRENCY if( my_market->my_num_workers_soft_limit == 0 ) { - if( my_mandatory_mode!=global_mandatory ) { + if( my_concurrency_mode!=cm_enforced_global ) { if( my_market->mandatory_concurrency_enable( this ) ) { my_pool_state = SNAPSHOT_FULL; return; @@ -387,19 +385,19 @@ template void arena::advertise_new_work() { } } else if( my_max_num_workers==0 ) { my_max_num_workers = 1; - __TBB_ASSERT(my_mandatory_mode==no_mandatory, ""); - my_mandatory_mode = local_mandatory; + __TBB_ASSERT(my_concurrency_mode==cm_normal, NULL); + my_concurrency_mode = cm_enforced_local; my_pool_state = SNAPSHOT_FULL; my_market->adjust_demand( *this, 1 ); return; } #endif /* __TBB_ENQUEUE_ENFORCED_CONCURRENCY */ // Local memory fence here and below is required to avoid missed wakeups; see the comment below. - // Starvation resistant tasks require mandatory concurrency, so missed wakeups are unacceptable. + // Starvation resistant tasks require concurrency, so missed wakeups are unacceptable. atomic_fence(); } else if( work_type == wakeup ) { - __TBB_ASSERT(my_max_num_workers!=0, "Not expect mandatory concurrency request."); + __TBB_ASSERT(my_max_num_workers!=0, "Unexpected worker wakeup request"); atomic_fence(); } // Double-check idiom that, in case of spawning, is deliberately sloppy about memory fences. @@ -424,12 +422,12 @@ template void arena::advertise_new_work() { } } // This thread transitioned pool from empty to full state, and thus is responsible for - // telling RML that there is work to do. + // telling the market that there is work to do. #if __TBB_ENQUEUE_ENFORCED_CONCURRENCY if( work_type == work_spawned ) { - if( my_mandatory_mode!=no_mandatory ) { - switch( my_mandatory_mode ) { - case local_mandatory: + if( my_concurrency_mode!=cm_normal ) { + switch( my_concurrency_mode ) { + case cm_enforced_local: __TBB_ASSERT(my_max_num_workers==1, ""); __TBB_ASSERT(!governor::local_scheduler()->is_worker(), ""); // There was deliberate oversubscription on 1 core for sake of starvation-resistant tasks. @@ -437,11 +435,11 @@ template void arena::advertise_new_work() { // with relaxed sequential semantics, and oversubscription should be avoided. // Demand for workers has been decreased to 0 during SNAPSHOT_EMPTY, so just keep it. my_max_num_workers = 0; - my_mandatory_mode = no_mandatory; + my_concurrency_mode = cm_normal; break; - case global_mandatory: + case cm_enforced_global: my_market->mandatory_concurrency_disable( this ); - restore_priorities_if_need(); + restore_priority_if_need(); break; default: break; diff --git a/src/tbb/custom_scheduler.h b/src/tbb/custom_scheduler.h index 6174f00..14e2e2c 100644 --- a/src/tbb/custom_scheduler.h +++ b/src/tbb/custom_scheduler.h @@ -203,6 +203,7 @@ task* custom_scheduler::receive_or_steal_task( __TBB_atomic ref #if __TBB_TASK_PRIORITY // Check if any earlier offloaded non-top priority tasks become returned to the top level else if ( my_offloaded_tasks && (t=reload_tasks()) ) { + __TBB_ASSERT( !is_proxy(*t), "The proxy task cannot be offloaded" ); // just proceed with the obtained task } #endif /* __TBB_TASK_PRIORITY */ @@ -295,6 +296,7 @@ fail: if ( t ) { if( SchedulerTraits::itt_possible ) ITT_NOTIFY(sync_cancel, this); + __TBB_ASSERT( !is_proxy(*t), "The proxy task cannot be offloaded" ); break; // exit stealing loop and return } } @@ -417,6 +419,7 @@ void custom_scheduler::local_wait_for_all( task& parent, task* assert_context_valid(t->prefix().context); if ( !t->prefix().context->my_cancellation_requested ) #endif + // TODO: make the assert stronger by prohibiting allocated state. __TBB_ASSERT( 1L<state() & (1L<my_max_num_workers > 0 || my_market->my_ref_count > 1 - // || parent.prefix().ref_count == 1, "deadlock detected" ); - // Dispatching task pointer is NULL *iff* this is a worker thread in its outermost // dispatch loop (i.e. its execution stack is empty). In this case it should exit it // either when there is no more work in the current arena, or when revoked by the market. diff --git a/src/tbb/itt_notify.cpp b/src/tbb/itt_notify.cpp index 82d0524..2e0e449 100644 --- a/src/tbb/itt_notify.cpp +++ b/src/tbb/itt_notify.cpp @@ -49,6 +49,12 @@ extern "C" void MallocInitializeITT(); namespace tbb { namespace internal { int __TBB_load_ittnotify() { +#if !(_WIN32||_WIN64) + // tool_api crashes without dlopen, check that it's present. Common case + // for lack of dlopen is static binaries, i.e. ones build with -static. + if (dlopen == NULL) + return 0; +#endif return __itt_init_ittlib(NULL, // groups for: (__itt_group_id)(__itt_group_sync // prepare/cancel/acquired/releasing | __itt_group_thread // name threads diff --git a/src/tbb/market.cpp b/src/tbb/market.cpp index 7eadfef..0d257e5 100644 --- a/src/tbb/market.cpp +++ b/src/tbb/market.cpp @@ -214,7 +214,7 @@ void market::set_active_num_workers ( unsigned soft_limit ) { } // have my_ref_count for market, use it safely { - arenas_list_mutex_type::scoped_lock lock(m->my_arenas_list_mutex); + arenas_list_mutex_type::scoped_lock lock( m->my_arenas_list_mutex ); __TBB_ASSERT(soft_limit <= m->my_num_workers_hard_limit, NULL); m->my_num_workers_soft_limit = soft_limit; // report only once after new soft limit value is set @@ -236,7 +236,7 @@ void market::set_active_num_workers ( unsigned soft_limit ) { m->my_num_workers_requested = requested; #if __TBB_TASK_PRIORITY m->my_priority_levels[m->my_global_top_priority].workers_available = soft_limit; - m->update_allotment(m->my_global_top_priority); + m->update_allotment( m->my_global_top_priority ); #else m->update_allotment(); #endif @@ -246,32 +246,31 @@ void market::set_active_num_workers ( unsigned soft_limit ) { // enable mandatory concurrency, if enqueued tasks are found // and zero soft_limit requested #if __TBB_TASK_PRIORITY - for ( int p = m->my_global_top_priority; - p >= m->my_global_bottom_priority; --p ) { + for( int p = m->my_global_top_priority; p >= m->my_global_bottom_priority; --p ) { priority_level_info &pl = m->my_priority_levels[p]; arena_list_type &arenas = pl.arenas; #else const int p = 0; arena_list_type &arenas = m->my_arenas; #endif /* __TBB_TASK_PRIORITY */ - for (arena_list_type::iterator it = arenas.begin(); - it != arenas.end(); ++it ) + for( arena_list_type::iterator it = arenas.begin(); it != arenas.end(); ++it ) { if( !it->my_task_stream.empty(p) ) { // switch local_mandatory to global_mandatory unconditionally if( m->mandatory_concurrency_enable_impl( &*it ) ) need_mandatory = true; } + } #if __TBB_TASK_PRIORITY } #endif /* __TBB_TASK_PRIORITY */ } #endif /* __TBB_ENQUEUE_ENFORCED_CONCURRENCY */ } - // Must be called outside of any locks - if ( requested != old_requested ) - m->my_server->adjust_job_count_estimate( requested - old_requested ); - if( need_mandatory ) - m->my_server->adjust_job_count_estimate( 1 ); + // adjust_job_count_estimate must be called outside of any locks + int delta = requested - old_requested; + if( need_mandatory ) ++delta; + if( delta!=0 ) + m->my_server->adjust_job_count_estimate( delta ); // release internal market reference to match ++m->my_ref_count above m->release(); } @@ -365,13 +364,11 @@ arena* market::arena_in_need ( arena_list_type &arenas, arena *&next ) { return NULL; } -void market::update_allotment ( arena_list_type& arenas, int workers_demand, int max_workers ) { +int market::update_allotment ( arena_list_type& arenas, int workers_demand, int max_workers ) { __TBB_ASSERT( workers_demand, NULL ); max_workers = min(workers_demand, max_workers); int carry = 0; -#if TBB_USE_ASSERT int assigned = 0; -#endif /* TBB_USE_ASSERT */ arena_list_type::iterator it = arenas.begin(); for ( ; it != arenas.end(); ++it ) { arena& a = *it; @@ -383,16 +380,20 @@ void market::update_allotment ( arena_list_type& arenas, int workers_demand, int int allotted = tmp / workers_demand; carry = tmp % workers_demand; // a.my_num_workers_requested may temporarily exceed a.my_max_num_workers - a.my_num_workers_allotted = min( allotted, (int)a.my_max_num_workers ); + allotted = min( allotted, (int)a.my_max_num_workers ); #if __TBB_ENQUEUE_ENFORCED_CONCURRENCY - if ( !a.my_num_workers_allotted && a.mandatory_requested() ) - a.my_num_workers_allotted = 1; + if ( !allotted && a.must_have_concurrency() ) + allotted = 1; #endif -#if TBB_USE_ASSERT - assigned += a.my_num_workers_allotted; -#endif /* TBB_USE_ASSERT */ + a.my_num_workers_allotted = allotted; + assigned += allotted; } - __TBB_ASSERT( assigned <= workers_demand, NULL ); +#if __TBB_ENQUEUE_ENFORCED_CONCURRENCY + __TBB_ASSERT( assigned <= workers_demand, NULL ); // weaker assertion due to enforced allotment +#else + __TBB_ASSERT( assigned <= max_workers, NULL ); +#endif + return assigned; } #if __TBB_TASK_PRIORITY @@ -437,9 +438,8 @@ void market::update_allotment ( intptr_t highest_affected_priority ) { priority_level_info &pl = my_priority_levels[i]; pl.workers_available = available; if ( pl.workers_requested ) { - update_allotment( pl.arenas, pl.workers_requested, available ); - available -= pl.workers_requested; - if ( available < 0 ) { + available -= update_allotment( pl.arenas, pl.workers_requested, available ); + if ( available < 0 ) { // TODO: assertion? available = 0; break; } @@ -453,11 +453,10 @@ void market::update_allotment ( intptr_t highest_affected_priority ) { for ( ; it != pl.arenas.end(); ++it ) { __TBB_ASSERT( it->my_num_workers_requested >= 0 || !it->my_num_workers_allotted, NULL ); #if __TBB_ENQUEUE_ENFORCED_CONCURRENCY - if ( it->mandatory_requested() ) - it->my_num_workers_allotted = 1; - else + it->my_num_workers_allotted = it->must_have_concurrency() ? 1 : 0; +#else + it->my_num_workers_allotted = 0; #endif - it->my_num_workers_allotted = 0; } } } @@ -465,7 +464,7 @@ void market::update_allotment ( intptr_t highest_affected_priority ) { #if __TBB_ENQUEUE_ENFORCED_CONCURRENCY bool market::mandatory_concurrency_enable_impl ( arena *a, bool *enabled ) { - if( a->my_mandatory_mode==arena_base::global_mandatory ) { + if( a->my_concurrency_mode==arena_base::cm_enforced_global ) { if( enabled ) *enabled = false; return false; @@ -473,7 +472,7 @@ bool market::mandatory_concurrency_enable_impl ( arena *a, bool *enabled ) { if( enabled ) *enabled = true; a->my_max_num_workers = 1; - a->my_mandatory_mode = arena_base::global_mandatory; + a->my_concurrency_mode = arena_base::cm_enforced_global; #if __TBB_TASK_PRIORITY priority_level_info &pl = my_priority_levels[a->my_top_priority]; pl.workers_requested++; @@ -510,7 +509,7 @@ void market::mandatory_concurrency_disable ( arena *a ) { { arenas_list_mutex_type::scoped_lock lock(my_arenas_list_mutex); - if( a->my_mandatory_mode!=arena_base::global_mandatory ) + if( a->my_concurrency_mode!=arena_base::cm_enforced_global ) return; __TBB_ASSERT( a->my_max_num_workers==1, NULL ); a->my_max_num_workers = 0; @@ -544,7 +543,7 @@ void market::mandatory_concurrency_disable ( arena *a ) { else if( p!= my_global_top_priority ) update_global_top_priority(p); #endif - a->my_mandatory_mode = arena::no_mandatory; + a->my_concurrency_mode = arena::cm_normal; } if( delta_adjust_demand ) adjust_demand( *a, -delta_adjust_demand ); @@ -563,7 +562,7 @@ void market::adjust_demand ( arena& a, int delta ) { if ( a.my_num_workers_requested <= 0 ) { #if __TBB_ENQUEUE_ENFORCED_CONCURRENCY // must not recall worker from arena with mandatory parallelism - if ( a.my_market->my_mandatory_num_requested && a.my_mandatory_mode!=arena_base::no_mandatory ) + if ( a.my_market->my_mandatory_num_requested && a.my_concurrency_mode!=arena_base::cm_normal ) a.my_num_workers_allotted = 1; else #endif @@ -612,7 +611,7 @@ void market::adjust_demand ( arena& a, int delta ) { #if __TBB_ENQUEUE_ENFORCED_CONCURRENCY // must not recall worker from arena with mandatory parallelism if ( !a.my_num_workers_allotted && a.my_num_workers_requested - && a.my_market->my_mandatory_num_requested && a.my_mandatory_mode!=arena_base::no_mandatory ) + && a.my_market->my_mandatory_num_requested && a.my_concurrency_mode!=arena_base::cm_normal ) a.my_num_workers_allotted = 1; #endif my_priority_levels[p - 1].workers_available = my_num_workers_soft_limit - a.my_num_workers_allotted; @@ -645,13 +644,13 @@ void market::adjust_demand ( arena& a, int delta ) { if ( delta > 0 ) { // can't overflow soft_limit, but remember values request by arenas in // my_total_demand to not prematurely release workers to RML - if ( my_num_workers_requested+delta > (int)my_num_workers_soft_limit ) { + if ( my_num_workers_requested+delta > (int)my_num_workers_soft_limit ) delta = my_num_workers_soft_limit - my_num_workers_requested; - } - } else + } else { // the number of workers should not be decreased below my_total_demand if ( my_num_workers_requested+delta < my_total_demand ) delta = min(my_total_demand, (int)my_num_workers_soft_limit) - my_num_workers_requested; + } my_num_workers_requested += delta; __TBB_ASSERT( my_num_workers_requested <= (int)my_num_workers_soft_limit, NULL ); @@ -783,6 +782,7 @@ bool market::update_arena_priority ( arena& a, intptr_t new_priority ) { // TODO: do not acquire this global lock while checking arena's state. arenas_list_mutex_type::scoped_lock lock(my_arenas_list_mutex); + tbb::internal::assert_priority_valid(new_priority); __TBB_ASSERT( my_global_top_priority >= a.my_top_priority || a.my_num_workers_requested <= 0, NULL ); assert_market_valid(); if ( a.my_top_priority == new_priority ) { @@ -830,11 +830,11 @@ bool market::update_arena_priority ( arena& a, intptr_t new_priority ) { ++my_global_bottom_priority; __TBB_ASSERT( my_global_bottom_priority <= new_priority, NULL ); #if __TBB_ENQUEUE_ENFORCED_CONCURRENCY - const bool active_mandatory = my_mandatory_num_requested && a.my_mandatory_mode!=arena_base::no_mandatory; + const bool enforced_concurrency = my_mandatory_num_requested && a.must_have_concurrency(); #else - const bool active_mandatory = false; + const bool enforced_concurrency = false; #endif - __TBB_ASSERT_EX(active_mandatory || my_priority_levels[my_global_bottom_priority].workers_requested > 0, NULL ); + __TBB_ASSERT_EX( enforced_concurrency || my_priority_levels[my_global_bottom_priority].workers_requested > 0, NULL ); } update_allotment( highest_affected_level ); diff --git a/src/tbb/market.h b/src/tbb/market.h index 5ab8fe5..6fb5f8f 100644 --- a/src/tbb/market.h +++ b/src/tbb/market.h @@ -227,9 +227,6 @@ private: void assert_market_valid () const {} #endif /* !__TBB_TASK_PRIORITY */ - //! Returns number of masters doing computational (CPU-intensive) work - int num_active_masters () { return 1; } // APM TODO: replace with a real mechanism - //////////////////////////////////////////////////////////////////////////////// // Helpers to unify code branches dependent on priority feature presence @@ -239,7 +236,7 @@ private: arena* arena_in_need ( arena_list_type &arenas, arena *&next ); - static void update_allotment ( arena_list_type& arenas, int total_demand, int max_workers ); + static int update_allotment ( arena_list_type& arenas, int total_demand, int max_workers ); //////////////////////////////////////////////////////////////////////////////// diff --git a/src/tbb/queuing_rw_mutex.cpp b/src/tbb/queuing_rw_mutex.cpp index b0a2ad9..0a517ea 100644 --- a/src/tbb/queuing_rw_mutex.cpp +++ b/src/tbb/queuing_rw_mutex.cpp @@ -319,7 +319,7 @@ retry: __TBB_store_relaxed(my_prev, pred); acquire_internal_lock(); - __TBB_store_with_release(pred->my_next,reinterpret_cast(NULL)); + __TBB_store_with_release(pred->my_next,static_cast(NULL)); if( !__TBB_load_relaxed(my_next) && this != my_mutex->q_tail.compare_and_swap(pred, this) ) { spin_wait_while_eq( my_next, (void*)NULL ); diff --git a/src/tbb/scheduler.cpp b/src/tbb/scheduler.cpp index a0e2d83..db8bd43 100644 --- a/src/tbb/scheduler.cpp +++ b/src/tbb/scheduler.cpp @@ -561,7 +561,7 @@ inline task* generic_scheduler::prepare_for_spawning( task* t ) { // Mark proxy as present in both locations (sender's task pool and destination mailbox) proxy.task_and_tag = intptr_t(t) | task_proxy::location_mask; #if __TBB_TASK_PRIORITY - proxy.prefix().context = t->prefix().context; + poison_pointer( proxy.prefix().context ); #endif /* __TBB_TASK_PRIORITY */ ITT_NOTIFY( sync_releasing, proxy.outbox ); // Mail the proxy - after this point t may be destroyed by another thread at any moment. @@ -683,84 +683,46 @@ task* generic_scheduler::winnow_task_pool () { // the corresponding checking sequence in arena::is_out_of_work() is not atomic // anyway, fences aren't used, so that not to penalize warmer path. auto_indicator indicator(my_pool_reshuffling_pending); - // The purpose of the synchronization algorithm here is for the owner thread - // to avoid locking task pool most of the time. -#if __TBB_TODO - // Just locking the task pool unconditionally would produce simpler code, + + // Locking the task pool unconditionally produces simpler code, // scalability of which should not suffer unless priority jitter takes place. - // Since priority jitter is nocuous by itself, we may want to evaluate - // applicability of the simpler variant... - // Non-blocking variant also prevent us from relocating remaining tasks to - // the beginning of the task pool, not sure if it makes much sense. -#endif + // TODO: consider the synchronization algorithm here is for the owner thread + // to avoid locking task pool most of the time. + acquire_task_pool(); size_t T0 = __TBB_load_relaxed(my_arena_slot->tail); - __TBB_store_relaxed( my_arena_slot->tail, __TBB_load_relaxed(my_arena_slot->head) - 1 ); - atomic_fence(); - size_t H = __TBB_load_relaxed(my_arena_slot->head); - size_t T = __TBB_load_relaxed(my_arena_slot->tail); - __TBB_ASSERT( (intptr_t)T <= (intptr_t)T0, NULL); - __TBB_ASSERT( (intptr_t)H >= (intptr_t)T || (H == T0 && T == T0), NULL ); - bool acquired = false; - if ( H == T ) { - // Either no contention with thieves during arbitration protocol execution or ... - if ( H >= T0 ) { - // ... the task pool got empty - reset_task_pool_and_leave( /*locked=*/false ); - return NULL; + size_t H0 = __TBB_load_relaxed(my_arena_slot->head); + size_t dst = 0; + for ( size_t src = H0; src < T0; ++src ) { + task *curr = my_arena_slot->task_pool_ptr[src]; + // We cannot offload a proxy task (check the priority of it) because it can be already consumed. + if ( !is_proxy(*curr) ) { + intptr_t p = priority(*curr); + if ( p < *my_ref_top_priority ) { + offload_task( *curr, p ); + continue; + } } - } - else { - // Contention with thieves detected. Now without taking lock it is impossible - // to define the current head value because of its jitter caused by continuing - // stealing attempts (the pool is not locked so far). - acquired = true; - acquire_task_pool(); - H = __TBB_load_relaxed(my_arena_slot->head); - if ( H >= T0 ) { - reset_task_pool_and_leave( /*locked=*/true ); - return NULL; - } - } - size_t src, - dst = T0; - // Find the first task to offload. - for ( src = H; src < T0; ++src ) { - task &t = *my_arena_slot->task_pool_ptr[src]; - intptr_t p = priority(t); - if ( p < *my_ref_top_priority ) { - // Position of the first offloaded task will be the starting point - // for relocation of subsequent tasks that survive winnowing. - dst = src; - offload_task( t, p ); - break; - } - } - for ( ++src; src < T0; ++src ) { - task &t = *my_arena_slot->task_pool_ptr[src]; - intptr_t p = priority(t); - if ( p < *my_ref_top_priority ) - offload_task( t, p ); - else - my_arena_slot->task_pool_ptr[dst++] = &t; + my_arena_slot->task_pool_ptr[dst++] = curr; } __TBB_ASSERT( T0 >= dst, NULL ); - task *t = H < dst ? my_arena_slot->task_pool_ptr[--dst] : NULL; - if ( H == dst ) { - // No tasks remain the primary pool - reset_task_pool_and_leave( acquired ); + + task *t = NULL; + while ( !t && dst ) { + t = my_arena_slot->task_pool_ptr[--dst]; + __TBB_ASSERT( !is_poisoned(t), NULL ); + poison_pointer( my_arena_slot->task_pool_ptr[dst] ); + if ( is_proxy(*t) ) + t = consume_proxy( *t ); } - else if ( acquired ) { - __TBB_ASSERT( !is_poisoned(my_arena_slot->task_pool_ptr[H]), NULL ); - __TBB_store_relaxed( my_arena_slot->tail, dst ); + if (dst) { + __TBB_store_relaxed(my_arena_slot->head, 0); + __TBB_store_relaxed(my_arena_slot->tail, dst); release_task_pool(); + } else { + reset_task_pool_and_leave(/*locked = */true); } - else { - __TBB_ASSERT( !is_poisoned(my_arena_slot->task_pool_ptr[H]), NULL ); - // Release fence is necessary to make sure possibly relocated task pointers - // become visible to potential thieves - __TBB_store_with_release( my_arena_slot->tail, dst ); - } - my_arena_slot->fill_with_canary_pattern( dst, T0 ); + // Choose max(dst, H0) because ranges [0,dst) and [H0,T0) can overlap. + my_arena_slot->fill_with_canary_pattern(max(dst, H0), T0); assert_task_pool_valid(); return t; } @@ -774,13 +736,14 @@ task* generic_scheduler::reload_tasks ( task*& offloaded_tasks, task**& offloade task *t; while ( (t = *link) ) { task** next_ptr = &t->prefix().next_offloaded; + __TBB_ASSERT( !is_proxy(*t), "The proxy tasks cannot be offloaded" ); if ( priority(*t) >= top_priority ) { tasks.push_back( t ); // Note that owner is an alias of next_offloaded. Thus the following // assignment overwrites *next_ptr task* next = *next_ptr; t->prefix().owner = this; - __TBB_ASSERT( t->prefix().state == task::ready || t->prefix().extra_state == es_task_proxy, NULL ); + __TBB_ASSERT( t->prefix().state == task::ready, NULL ); *link = next; } else { @@ -852,6 +815,24 @@ task* generic_scheduler::reload_tasks () { } #endif /* __TBB_TASK_PRIORITY */ +inline task* generic_scheduler::consume_proxy( task &proxy ) { + __TBB_ASSERT( is_proxy(proxy), NULL ); + task_proxy &tp = static_cast(proxy); + task *result = tp.extract_task(); + if (!result) { + // Proxy was empty, so it's our responsibility to free it + free_task(tp); + return NULL; + } + GATHER_STATISTIC(++my_counters.proxies_executed); + // Following assertion should be true because TBB 2.0 tasks never specify affinity, and hence are not proxied. + __TBB_ASSERT(is_version_3_task(*result), "backwards compatibility with TBB 2.0 broken"); + // Task affinity has changed. + my_innermost_running_task = result; + result->note_affinity(my_affinity_id); + return result; +} + inline task* generic_scheduler::get_task() { __TBB_ASSERT( is_task_pool_published(), NULL ); task* result = NULL; @@ -885,22 +866,10 @@ retry: poison_pointer( my_arena_slot->task_pool_ptr[T] ); } if( result && is_proxy(*result) ) { - task_proxy &tp = *(task_proxy*)result; - result = tp.extract_task(); - if( !result ) { - // Proxy was empty, so it's our responsibility to free it - free_task(tp); - if ( is_task_pool_published() ) + result = consume_proxy(*result ); + // The task can be grabbed when a thief backs off. As a result, the pool can be reset. + if ( !result && is_task_pool_published() ) goto retry; - __TBB_ASSERT( is_quiescent_local_task_pool_reset(), NULL ); - return NULL; - } - GATHER_STATISTIC( ++my_counters.proxies_executed ); - // Following assertion should be true because TBB 2.0 tasks never specify affinity, and hence are not proxied. - __TBB_ASSERT( is_version_3_task(*result), "backwards compatibility with TBB 2.0 broken" ); - // Task affinity has changed. - my_innermost_running_task = result; - result->note_affinity(my_affinity_id); } __TBB_ASSERT( result || is_quiescent_local_task_pool_reset(), NULL ); return result; @@ -1200,7 +1169,7 @@ void generic_scheduler::cleanup_master( bool needs_wait_workers ) { enough information for the main thread on IA-64 architecture (RSE spill area and memory stack are allocated as two separate discontinuous chunks of memory), and there is no portable way to discern the main and the secondary threads. - Thus for OS X* and IA-64 Linux architecture we use the TBB worker stack size for + Thus for OS X* and IA-64 architecture for Linux* OS we use the TBB worker stack size for all threads and use the current stack top as the stack base. This simplified approach is based on the following assumptions: 1) If the default stack size is insufficient for the user app needs, the diff --git a/src/tbb/scheduler.h b/src/tbb/scheduler.h index fd8d439..e3510f8 100644 --- a/src/tbb/scheduler.h +++ b/src/tbb/scheduler.h @@ -228,6 +228,11 @@ public: // almost every class in TBB uses generic_scheduler In the latter case compacts the pool. **/ task* get_task(); + //! Extract a task from the proxy. + /** Returns the pointer to the extracted task or NULL if the proxy is empty. + In the latter case deallocates the proxy. **/ + task* consume_proxy( task& proxy ); + //! Attempt to get a task from the mailbox. /** Gets a task only if it has not been executed by its sender or a thief that has stolen it from the sender's task pool. Otherwise returns NULL. @@ -325,8 +330,8 @@ public: //! True if the scheduler is on the outermost dispatch level in a worker thread. inline bool worker_outermost_level () const; - //! Returns number of worker threads in the arena this thread belongs to. - unsigned number_of_workers_in_my_arena(); + //! Returns the concurrency limit of the current arena. + unsigned max_threads_in_arena(); #if __TBB_COUNT_TASK_NODES intptr_t get_task_node_count( bool count_arena_workers = false ); @@ -544,9 +549,9 @@ inline bool generic_scheduler::is_worker() { return my_is_worker; } -inline unsigned generic_scheduler::number_of_workers_in_my_arena() { +inline unsigned generic_scheduler::max_threads_in_arena() { __TBB_ASSERT(my_arena, NULL); - return my_arena->my_max_num_workers; + return my_arena->my_num_slots; } //! Return task object to the memory allocator. @@ -648,13 +653,14 @@ inline intptr_t generic_scheduler::effective_reference_priority () const { return !worker_outermost_level() || (my_arena->my_num_workers_allotted < my_arena->num_workers_active() #if __TBB_ENQUEUE_ENFORCED_CONCURRENCY - && my_arena->my_mandatory_mode!=arena_base::global_mandatory + && my_arena->my_concurrency_mode!=arena_base::cm_enforced_global #endif ) ? *my_ref_top_priority : my_arena->my_top_priority; } inline void generic_scheduler::offload_task ( task& t, intptr_t /*priority*/ ) { GATHER_STATISTIC( ++my_counters.prio_tasks_offloaded ); + __TBB_ASSERT( !is_proxy(t), "The proxy task cannot be offloaded" ); __TBB_ASSERT( my_offloaded_task_list_tail_link && !*my_offloaded_task_list_tail_link, NULL ); #if TBB_USE_ASSERT t.prefix().state = task::ready; diff --git a/src/tbb/scheduler_common.h b/src/tbb/scheduler_common.h index 975db09..8cb753a 100644 --- a/src/tbb/scheduler_common.h +++ b/src/tbb/scheduler_common.h @@ -120,6 +120,8 @@ inline void assert_priority_valid ( intptr_t p ) { inline intptr_t& priority ( task& t ) { return t.prefix().context->my_priority; } +#else /* __TBB_TASK_PRIORITY */ +static const intptr_t num_priority_levels = 1; #endif /* __TBB_TASK_PRIORITY */ //! Mutex type for global locks in the scheduler diff --git a/src/tbb/task.cpp b/src/tbb/task.cpp index c9254d4..c314282 100644 --- a/src/tbb/task.cpp +++ b/src/tbb/task.cpp @@ -154,7 +154,7 @@ void allocate_additional_child_of_proxy::free( task& task ) const { //------------------------------------------------------------------------ size_t get_initial_auto_partitioner_divisor() { const size_t X_FACTOR = 4; - return X_FACTOR * (1+governor::local_scheduler()->number_of_workers_in_my_arena()); + return X_FACTOR * governor::local_scheduler()->max_threads_in_arena(); } //------------------------------------------------------------------------ @@ -162,7 +162,7 @@ size_t get_initial_auto_partitioner_divisor() { //------------------------------------------------------------------------ void affinity_partitioner_base_v3::resize( unsigned factor ) { // Check factor to avoid asking for number of workers while there might be no arena. - size_t new_size = factor ? factor*(1+governor::local_scheduler()->number_of_workers_in_my_arena()) : 0; + size_t new_size = factor ? factor*governor::local_scheduler()->max_threads_in_arena() : 0; if( new_size!=my_size ) { if( my_array ) { NFS_Free( my_array ); diff --git a/src/test/harness_defs.h b/src/test/harness_defs.h index fa9082b..0992318 100644 --- a/src/test/harness_defs.h +++ b/src/test/harness_defs.h @@ -102,15 +102,6 @@ // MSVC 2015 does not do compile-time initialization of static variables with constexpr constructors in debug mode #define __TBB_STATIC_CONSTEXPR_INIT_BROKEN (_MSC_VER==1900 && !__INTEL_COMPILER && _DEBUG) -//some compilers do not generate implicitly move constructor and assignment operator, as this feature (r-value reference 3.0) was added later -#if __INTEL_COMPILER - #define __TBB_CPP11_IMPLICIT_MOVE_MEMBERS_GENERATION_BROKEN (__TBB_CPP11_RVALUE_REF_PRESENT && (__INTEL_COMPILER < 1400 || __INTEL_COMPILER == 1600 && __INTEL_COMPILER_UPDATE <= 2)) -#elif __clang__ - #define __TBB_CPP11_IMPLICIT_MOVE_MEMBERS_GENERATION_BROKEN !__has_feature(cxx_implicit_moves) -#else - #define __TBB_CPP11_IMPLICIT_MOVE_MEMBERS_GENERATION_BROKEN (__TBB_CPP11_RVALUE_REF_PRESENT && _MSC_VER && _MSC_VER <=1800) -#endif /* __INTEL_COMPILER */ - #if __GNUC__ && __ANDROID__ #define __TBB_EXCEPTION_TYPE_INFO_BROKEN ( __TBB_GCC_VERSION < 40600 ) #elif _MSC_VER diff --git a/src/test/test_async_msg.cpp b/src/test/test_async_msg.cpp index accef62..1dd5ae5 100644 --- a/src/test/test_async_msg.cpp +++ b/src/test/test_async_msg.cpp @@ -26,6 +26,10 @@ #if __TBB_PREVIEW_ASYNC_MSG +#if _MSC_VER +#pragma warning (disable: 4503) // Suppress "decorated name length exceeded, name was truncated" warning +#endif + #include "tbb/flow_graph.h" #include "tbb/tbb_thread.h" #include "tbb/concurrent_queue.h" diff --git a/src/test/test_atomic.cpp b/src/test/test_atomic.cpp index dcaf532..dce82da 100644 --- a/src/test/test_atomic.cpp +++ b/src/test/test_atomic.cpp @@ -613,8 +613,8 @@ void TestAlignment( const char* name ) { } #if _MSC_VER && !defined(__INTEL_COMPILER) - // unary minus operator applied to unsigned type, result still unsigned - #pragma warning( disable: 4146 ) + #pragma warning( disable: 4146 ) // unary minus operator applied to unsigned type, result still unsigned + #pragma warning( disable: 4334 ) // result of 32-bit shift implicitly converted to 64 bits #endif /** T is an integral type. */ diff --git a/src/test/test_concurrent_priority_queue.cpp b/src/test/test_concurrent_priority_queue.cpp index 3dcd941..ac622e6 100644 --- a/src/test/test_concurrent_priority_queue.cpp +++ b/src/test/test_concurrent_priority_queue.cpp @@ -399,7 +399,10 @@ void TestExceptions() { my_throwing_type::throw_flag = 1; cpq_ex_test_type q; } catch(...) { +#if !(_MSC_VER==1900) ASSERT(false, "FAILED: allocating empty queue should not throw exception.\n"); + // VS2015 warns about the code in this catch block being unreachable +#endif } // Allocate small queue should not throw for reasonably sized type try { diff --git a/src/test/test_concurrent_unordered_common.h b/src/test/test_concurrent_unordered_common.h index 978b9eb..4d820b1 100644 --- a/src/test/test_concurrent_unordered_common.h +++ b/src/test/test_concurrent_unordered_common.h @@ -781,13 +781,14 @@ struct unordered_move_traits_base { }; template -void test_rvalue_ref_support(const char* /*container_name*/){ +void test_rvalue_ref_support(const char* container_name){ TestMoveConstructor(); TestMoveAssignOperator(); #if TBB_USE_EXCEPTIONS TestExceptionSafetyGuaranteesMoveConstructorWithUnEqualAllocatorMemoryFailure(); TestExceptionSafetyGuaranteesMoveConstructorWithUnEqualAllocatorExceptionInElementCtor(); #endif //TBB_USE_EXCEPTIONS + REMARK("passed -- %s move support tests\n", container_name); } #endif //__TBB_CPP11_RVALUE_REF_PRESENT diff --git a/src/test/test_concurrent_vector.cpp b/src/test/test_concurrent_vector.cpp index 20c395e..2b0a8a5 100644 --- a/src/test/test_concurrent_vector.cpp +++ b/src/test/test_concurrent_vector.cpp @@ -927,10 +927,10 @@ void TestSerialGrowByWithMoveIterators(){ namespace test_move_in_shrink_to_fit_helpers { struct dummy : Harness::StateTrackable<>{ int i; - dummy(int an_i) __TBB_NOTHROW : Harness::StateTrackable<>(0), i(an_i) {}; + dummy(int an_i) __TBB_NOTHROW : Harness::StateTrackable<>(0), i(an_i) {} #if __TBB_CPP11_IMPLICIT_MOVE_MEMBERS_GENERATION_BROKEN - dummy(const dummy &src) __TBB_NOTHROW : Harness::StateTrackable<>(src), i(src.i) {}; - dummy(dummy &&src) __TBB_NOTHROW : Harness::StateTrackable<>(std::move(src)), i(src.i) {}; + dummy(const dummy &src) __TBB_NOTHROW : Harness::StateTrackable<>(src), i(src.i) {} + dummy(dummy &&src) __TBB_NOTHROW : Harness::StateTrackable<>(std::move(src)), i(src.i) {} dummy& operator=(dummy &&src) __TBB_NOTHROW { Harness::StateTrackable<>::operator=(std::move(src)); @@ -939,7 +939,7 @@ namespace test_move_in_shrink_to_fit_helpers { } //somehow magically this declaration make std::is_nothrow_move_constructible::value to works correctly on icc14+msvc2013 - ~dummy() __TBB_NOTHROW {}; + ~dummy() __TBB_NOTHROW {} #endif //__TBB_CPP11_IMPLICIT_MOVE_MEMBERS_GENERATION_BROKEN friend bool operator== (const dummy &lhs, const dummy &rhs){ return lhs.i == rhs.i; } }; diff --git a/src/test/test_indexer_node.cpp b/src/test/test_indexer_node.cpp index 606caf4..8c06d40 100644 --- a/src/test/test_indexer_node.cpp +++ b/src/test/test_indexer_node.cpp @@ -25,7 +25,7 @@ // Tests // - #if defined(_MSC_VER) && _MSC_VER < 1600 +#if defined(_MSC_VER) && _MSC_VER < 1600 #pragma warning (disable : 4503) //disabling the "decorated name length exceeded" warning for VS2008 and earlier #endif diff --git a/src/test/test_join_node.cpp b/src/test/test_join_node.cpp index 1e600f7..f7efb2a 100644 --- a/src/test/test_join_node.cpp +++ b/src/test/test_join_node.cpp @@ -230,10 +230,6 @@ void print_my_value(std::string const &i) { REMARK("\"%s\"", i.c_str()); } -#if defined(_MSC_VER) && _MSC_VER < 1600 - #pragma warning (disable : 4503) //disabling the "decorated name length exceeded" warning for VS2008 and earlier -#endif - // // Tests // diff --git a/src/test/test_malloc_compliance.cpp b/src/test/test_malloc_compliance.cpp index 04d15c7..454d707 100644 --- a/src/test/test_malloc_compliance.cpp +++ b/src/test/test_malloc_compliance.cpp @@ -732,7 +732,7 @@ void CMemTest::NULLReturn(UINT MinSize, UINT MaxSize, int total_threads) /* There is a bug in the specific version of GLIBC (2.5-12) shipped with RHEL5 that leads to erroneous working of the test - on Intel64 and IPF systems when setrlimit-related part is enabled. + on Intel(R) 64 and Itanium(R) architecture when setrlimit-related part is enabled. Switching to GLIBC 2.5-18 from RHEL5.1 resolved the issue. */ if (perProcessLimits) diff --git a/src/test/test_malloc_overload.cpp b/src/test/test_malloc_overload.cpp index 14afbec..75be1c8 100644 --- a/src/test/test_malloc_overload.cpp +++ b/src/test/test_malloc_overload.cpp @@ -186,6 +186,11 @@ const uint32_t minLargeObjectSize = fittingSize5 + 1; static void scalableMallocCheckSize(void *object, size_t size) { +#if __APPLE__ && __clang__ && __TBB_CLANG_VERSION == 70300 +// This prevents Clang 703.0.29 under OS X from throwing out the +// calls to new & delete in CheckNewDeleteOverload(). + static void *v = object; +#endif ASSERT(object, NULL); if (size >= minLargeObjectSize) { LargeMemoryBlock *lmb = ((LargeObjectHdr*)object-1)->memoryBlock; @@ -201,10 +206,6 @@ static void scalableMallocCheckSize(void *object, size_t size) #endif } -struct BigStruct { - char f[minLargeObjectSize]; -}; - void CheckStdFuncOverload(void *(*malloc_p)(size_t), void *(*calloc_p)(size_t, size_t), void *(*realloc_p)(void *, size_t), void (*free_p)(void *)) { @@ -307,6 +308,30 @@ void TestZoneOverload() { #define TestZoneOverload() #endif +struct BigStruct { + char f[minLargeObjectSize]; +}; + +void CheckNewDeleteOverload() { + BigStruct *s1, *s2, *s3, *s4; + + s1 = new BigStruct; + scalableMallocCheckSize(s1, sizeof(BigStruct)); + delete s1; + + s2 = new BigStruct[10]; + scalableMallocCheckSize(s2, 10*sizeof(BigStruct)); + delete []s2; + + s3 = new(std::nothrow) BigStruct; + scalableMallocCheckSize(s3, sizeof(BigStruct)); + delete s3; + + s4 = new(std::nothrow) BigStruct[2]; + scalableMallocCheckSize(s4, 2*sizeof(BigStruct)); + delete []s4; +} + int TestMain() { void *ptr, *ptr1; @@ -393,22 +418,7 @@ int TestMain() { #endif CheckFreeAligned(); - BigStruct *s1 = new BigStruct; - scalableMallocCheckSize(s1, sizeof(BigStruct)); - delete s1; - - BigStruct *s2 = new BigStruct[10]; - scalableMallocCheckSize(s2, 10*sizeof(BigStruct)); - delete []s2; - - BigStruct *s3 = new(std::nothrow) BigStruct; - scalableMallocCheckSize(s3, sizeof(BigStruct)); - delete s3; - - BigStruct *s4 = new(std::nothrow) BigStruct[2]; - scalableMallocCheckSize(s4, 2*sizeof(BigStruct)); - delete []s4; - + CheckNewDeleteOverload(); #if _WIN32 std::string stdstring = "dependence on msvcpXX.dll"; ASSERT(strcmp(stdstring.c_str(), "dependence on msvcpXX.dll") == 0, NULL); diff --git a/src/test/test_parallel_invoke.cpp b/src/test/test_parallel_invoke.cpp index dd9c810..83e2773 100644 --- a/src/test/test_parallel_invoke.cpp +++ b/src/test/test_parallel_invoke.cpp @@ -84,7 +84,7 @@ TEST_FUNCTOR(9) #define INIT_TEST function_counter = 0; #define VALIDATE_INVOKE_RUN(number_of_args, test_type) \ - ASSERT( (size_t)function_counter == (size_t)(1 << number_of_args) - 1, "parallel_invoke called with " #number_of_args " arguments didn't process all " #test_type); + ASSERT( size_t(function_counter) == (size_t(1) << number_of_args) - 1, "parallel_invoke called with " #number_of_args " arguments didn't process all " #test_type); // Calls parallel_invoke for different number of arguments // It can be called with and without user context @@ -235,7 +235,7 @@ void TestExceptionHandling() { REMARK (__FUNCTION__); for( size_t n = 2; n <= 10; ++n ) { - for( exception_mask = 1; exception_mask < (size_t) (1 << n); ++exception_mask ) { + for( exception_mask = 1; exception_mask < (size_t(1) << n); ++exception_mask ) { ResetEhGlobals(); TRY(); REMARK("Calling parallel_invoke, number of functions = %d, exception_mask = %d\n", n, exception_mask); diff --git a/src/test/test_task_priority.cpp b/src/test/test_task_priority.cpp index 0898dc3..3196a37 100644 --- a/src/test/test_task_priority.cpp +++ b/src/test/test_task_priority.cpp @@ -298,6 +298,7 @@ void TestPrioritySwitchBetweenTwoMasters () { REPORT_ONCE( "Known issue: TestPrioritySwitchBetweenTwoMasters is skipped for big number of threads\n" ); return; } + tbb::task_scheduler_init init; // keeps the market alive to reduce the amount of TBB warnings REMARK( "Stress tests: %s / %s \n", Low == tbb::priority_low ? "Low" : "Normal", High == tbb::priority_normal ? "Normal" : "High" ); PrepareGlobals( 2 ); for ( int i = 0; i < TestSwitchBetweenMastersRepeats; ++i ) { @@ -401,6 +402,7 @@ void TestPeriodicConcurrentActivities () { void TestPriorityAssertions () { #if TRY_BAD_EXPR_ENABLED && __TBB_TASK_PRIORITY REMARK( "TestPriorityAssertions\n" ); + tbb::task_scheduler_init init; // to avoid autoinit that'd affect subsequent tests tbb::priority_t bad_low_priority = tbb::priority_t( tbb::priority_low - 1 ), bad_high_priority = tbb::priority_t( tbb::priority_high + 1 ); tbb::task_group_context ctx; @@ -546,6 +548,31 @@ void TestSetPriority() { } }//namespace test_propagation +// TODO: consider common helper for empty bodies, e.g. Harness::DummyBody. +struct NestedParFor { + void operator()(int) const { + for (volatile int i = 0; i < 1000; ++i); + } +}; + +struct OuterParFor { + void operator()(int) const { + tbb::affinity_partitioner ap; + tbb::task_group_context ctx; + ctx.set_priority(tbb::priority_high); + tbb::parallel_for(0, 100, NestedParFor(), ap, ctx); + } +}; + +// Test priorities with affinity tasks. +void TestAffinityTasks() { + REMARK("Test priorities with affinity tasks\n"); + tbb::task_scheduler_init init; + tbb::affinity_partitioner ap; + for (int i = 0; i < 10; ++i) + tbb::parallel_for(0, 100, OuterParFor(), ap); +} + namespace regression { // This is a regression test for a bug with task_group_context used from a thread that created its local scheduler but not the implicit arena class TestTGContext { @@ -594,6 +621,7 @@ int RunTests () { TestPrioritySwitchBetweenTwoMasters(); PreemptionActivatorId = 1; TestPrioritySwitchBetweenTwoMasters(); + TestAffinityTasks(); regression::TestTGContextOnNewThread(); return Harness::Done; diff --git a/src/test/test_task_scheduler_init.cpp b/src/test/test_task_scheduler_init.cpp index 3a1c612..c0c27a5 100644 --- a/src/test/test_task_scheduler_init.cpp +++ b/src/test/test_task_scheduler_init.cpp @@ -64,7 +64,7 @@ void InitializeAndTerminate( int maxthread ) { default: { tbb::task_scheduler_init init( threads ); ASSERT(init.is_active(), NULL); - ASSERT(ArenaConcurrency()==threads, NULL); + ASSERT(ArenaConcurrency()==(threads==1)?2:threads, NULL); ASSERT(!test_mandatory_parallelism || Harness::CanReachConcurrencyLevel(threads), NULL); if(i&0x20) tbb::task::enqueue( (*new( tbb::task::allocate_root() ) TaskGenerator(2,6)) ); // a work deferred to workers break; @@ -72,7 +72,7 @@ void InitializeAndTerminate( int maxthread ) { case 0: { tbb::task_scheduler_init init; ASSERT(init.is_active(), NULL); - ASSERT(ArenaConcurrency()==init.default_num_threads(), NULL); + ASSERT(ArenaConcurrency()==(DefaultThreads==1)?2:init.default_num_threads(), NULL); ASSERT(!test_mandatory_parallelism || Harness::CanReachConcurrencyLevel(init.default_num_threads()), NULL); if(i&0x40) tbb::task::enqueue( (*new( tbb::task::allocate_root() ) TaskGenerator(3,5)) ); // a work deferred to workers break; @@ -82,7 +82,7 @@ void InitializeAndTerminate( int maxthread ) { ASSERT(!init.is_active(), "init should not be active; initialization was deferred"); init.initialize( threads ); ASSERT(init.is_active(), NULL); - ASSERT(ArenaConcurrency()==threads, NULL); + ASSERT(ArenaConcurrency()==(threads==1)?2:threads, NULL); ASSERT(!test_mandatory_parallelism || Harness::CanReachConcurrencyLevel(threads), NULL); init.terminate(); ASSERT(!init.is_active(), "init should not be active; it was terminated"); @@ -91,7 +91,7 @@ void InitializeAndTerminate( int maxthread ) { case 2: { tbb::task_scheduler_init init( tbb::task_scheduler_init::automatic ); ASSERT(init.is_active(), NULL); - ASSERT(ArenaConcurrency()==init.default_num_threads(), NULL); + ASSERT(ArenaConcurrency()==(DefaultThreads==1)?2:init.default_num_threads(), NULL); ASSERT(!test_mandatory_parallelism || Harness::CanReachConcurrencyLevel(init.default_num_threads()), NULL); break; } @@ -138,10 +138,9 @@ public: /** The test will fail in particular if task_scheduler_init mistakenly hooks up auto-initialization mechanism. **/ void AssertExplicitInitIsNotSupplanted () { - int hardwareConcurrency = tbb::task_scheduler_init::default_num_threads(); tbb::task_scheduler_init init(1); Harness::ConcurrencyTracker::Reset(); - tbb::parallel_for( Range(0, hardwareConcurrency * 2, 1), ConcurrencyTrackingBody(), tbb::simple_partitioner() ); + tbb::parallel_for( Range(0, DefaultThreads * 2, 1), ConcurrencyTrackingBody(), tbb::simple_partitioner() ); ASSERT( Harness::ConcurrencyTracker::PeakParallelism() == 1, "Manual init provided more threads than requested. See also the comment at the beginning of main()." ); } diff --git a/src/test/test_tbb_version.cpp b/src/test/test_tbb_version.cpp index a70ef91..9d12929 100644 --- a/src/test/test_tbb_version.cpp +++ b/src/test/test_tbb_version.cpp @@ -240,7 +240,7 @@ int main(int argc, char *argv[] ) { void initialize_strings_vector(std::vector * vector) { vector->push_back(string_pair("TBB: VERSION\t\t4.4", required)); // check TBB_VERSION - vector->push_back(string_pair("TBB: INTERFACE VERSION\t9004", required)); // check TBB_INTERFACE_VERSION + vector->push_back(string_pair("TBB: INTERFACE VERSION\t9005", required)); // check TBB_INTERFACE_VERSION vector->push_back(string_pair("TBB: BUILD_DATE", required)); vector->push_back(string_pair("TBB: BUILD_HOST", required)); vector->push_back(string_pair("TBB: BUILD_OS", required));