Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -556,8 +556,25 @@ if (TARGET TBB::tbb)
tbb_add_test(SUBDIR tbb NAME test_tbb_fork DEPENDENCIES TBB::tbb)
endif()

tbb_add_test(SUBDIR tbb NAME test_tbb_header DEPENDENCIES TBB::tbb)
tbb_add_test(SUBDIR tbb NAME test_tbb_header DEPENDENCIES TBB::tbb TBB::tbbmalloc)
target_sources(test_tbb_header PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/tbb/test_tbb_header_secondary.cpp)

if (TBB_TEST_CXX20_MODULES)
if (CMAKE_VERSION VERSION_LESS 3.28)
message(WARNING "CMake 3.28 or higher is required to use C++20 modules, skipping module test")
elseif (NOT CMAKE_CXX_STANDARD OR CMAKE_CXX_STANDARD LESS 20)
message(WARNING "C++ standard 20 or higher is required, skipping module test")
else()
tbb_add_test(SUBDIR tbb NAME test_tbb_header_module_consumer DEPENDENCIES TBB::tbb TBB::tbbmalloc)
target_sources(test_tbb_header_module_consumer
PUBLIC FILE_SET CXX_MODULES FILES
${CMAKE_CURRENT_SOURCE_DIR}/tbb/test_tbb_header_module.cppm)
set_target_properties(test_tbb_header_module_consumer PROPERTIES
CXX_STANDARD 20
CXX_STANDARD_REQUIRED ON)
endif()
endif()

if (NOT MINGW AND TBB_OPENMP_FLAG AND NOT CMAKE_SYSTEM_PROCESSOR MATCHES "(mips)")
tbb_add_test(SUBDIR tbb NAME test_openmp DEPENDENCIES TBB::tbb)

Expand Down
84 changes: 82 additions & 2 deletions test/tbb/test_tbb_header.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
Copyright (c) 2005-2025 Intel Corporation
Copyright (c) 2025 UXL Foundation Contributors
Copyright (c) 2025-2026 UXL Foundation Contributors

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand All @@ -25,6 +25,8 @@
Most of the checks happen at the compilation or link phases.
**/

#if !__TBB_TEST_MODULE_EXPORT

#if __INTEL_COMPILER && _MSC_VER
#pragma warning(disable : 2586) // decorated name length exceeded, name was truncated
#endif
Expand Down Expand Up @@ -92,8 +94,13 @@
#include "common/test.h"
#endif

static volatile size_t g_sink;
#endif /* !__TBB_TEST_MODULE_EXPORT */

#if __TBB_TEST_MODULE_EXPORT
inline volatile size_t g_sink;
#else
static volatile size_t g_sink;
#endif /* __TBB_TEST_MODULE_EXPORT */
#define TestTypeDefinitionPresence( Type ) g_sink = sizeof(tbb::Type);
#define TestTypeDefinitionPresence2(TypeStart, TypeEnd) g_sink = sizeof(tbb::TypeStart,TypeEnd);
#define TestTypeDefinitionPresence3(TypeStart, TypeMid, TypeEnd) g_sink = sizeof(tbb::TypeStart,TypeMid,TypeEnd);
Expand All @@ -114,6 +121,9 @@ struct Body1b { // binary operator for reduction
struct Body1bc { // binary operator for comparison
bool operator() (const int, const int) const { return false; }
};
struct Body1c { // body for function_node<int, int>
int operator() ( int ) const { return 0; }
};
struct Body2 {
Body2 () {}
Body2 ( const Body2&, tbb::split ) {}
Expand All @@ -135,10 +145,15 @@ struct Body3a { // for lambda-friednly parallel_scan
int operator() ( const tbb::blocked_range<int>&, const int, bool ) const { return 0; }
};
struct Msg {};
struct SuspendBody {
void operator()(tbb::task::suspend_point) const {}
};

// Test if all the necessary symbols are exported for the exceptions thrown by TBB.
// Missing exports result either in link error or in runtime assertion failure.
#if !__TBB_TEST_MODULE_EXPORT
#include <stdexcept>
#endif

template <typename E>
void TestExceptionClassExports ( const E& exc, tbb::detail::exception_id eid ) {
Expand All @@ -163,7 +178,11 @@ void TestExceptionClassExports ( const E& exc, tbb::detail::exception_id eid ) {
#endif /* TBB_USE_EXCEPTIONS */
}

#if __TBB_TEST_MODULE_EXPORT
inline void TestExceptionClassesExports () {
#else
static void TestExceptionClassesExports () {
#endif
TestExceptionClassExports( std::bad_alloc(), tbb::detail::exception_id::bad_alloc );
TestExceptionClassExports( tbb::bad_last_alloc(), tbb::detail::exception_id::bad_last_alloc );
TestExceptionClassExports( std::invalid_argument("test"), tbb::detail::exception_id::nonpositive_step );
Expand All @@ -180,18 +199,36 @@ static void TestExceptionClassesExports () {
#if __TBB_CPF_BUILD
// These names are only tested in "preview" configuration
// When a feature becomes fully supported, its names should be moved to the main test
#if __TBB_TEST_MODULE_EXPORT
inline void TestPreviewNames() {
#else
static void TestPreviewNames() {
#endif
TestTypeDefinitionPresence2( concurrent_lru_cache<int, int> );
TestTypeDefinitionPresence( isolated_task_group );
#if TBB_PREVIEW_MEMORY_POOL
TestTypeDefinitionPresence( memory_pool_allocator<int> );
TestTypeDefinitionPresence( memory_pool<std::allocator<int>> );
TestTypeDefinitionPresence( fixed_pool );
#endif
#if __TBB_PREVIEW_TASK_GROUP_EXTENSIONS
TestTypeDefinitionPresence( task_completion_handle );
TestFuncDefinitionPresence( is_inside_task, (), bool );
#endif
#if __TBB_PREVIEW_PARALLEL_PHASE
TestTypeDefinitionPresence( task_arena::leave_policy );
TestTypeDefinitionPresence( task_arena::scoped_parallel_phase );
TestFuncDefinitionPresence( this_task_arena::start_parallel_phase, (), void );
TestFuncDefinitionPresence( this_task_arena::end_parallel_phase, (bool), void );
#endif
}
#endif

#if __TBB_TEST_MODULE_EXPORT
export inline void DefinitionPresence() {
#else
static void DefinitionPresence() {
#endif
TestTypeDefinitionPresence( ext::assertion_handler_type );
TestTypeDefinitionPresence( cache_aligned_allocator<int> );
TestTypeDefinitionPresence( tbb_hash_compare<int> );
Expand All @@ -210,6 +247,10 @@ static void DefinitionPresence() {
TestTypeDefinitionPresence( concurrent_vector<int> );
TestTypeDefinitionPresence( combinable<int> );
TestTypeDefinitionPresence( enumerable_thread_specific<int> );
/* TLS names */
TestTypeDefinitionPresence( flattened2d<tbb::enumerable_thread_specific<std::vector<int>>> );
TestTypeDefinitionPresence( ets_key_usage_type );
TestFuncDefinitionPresence( flatten2d, (const tbb::enumerable_thread_specific<std::vector<int>>&), tbb::flattened2d<tbb::enumerable_thread_specific<std::vector<int>>> );
TestFuncDefinitionPresence( ext::get_assertion_handler, (),
tbb::ext::assertion_handler_type );
TestFuncDefinitionPresence( ext::set_assertion_handler,
Expand Down Expand Up @@ -240,6 +281,12 @@ static void DefinitionPresence() {
TestTypeDefinitionPresence( flow::limiter_node<int> );
TestTypeDefinitionPresence2(flow::indexer_node<int, int> );
TestTypeDefinitionPresence2(flow::composite_node<std::tuple<int>, std::tuple<int> > );
TestTypeDefinitionPresence( flow::graph_node );
TestTypeDefinitionPresence( flow::reset_flags );
TestTypeDefinitionPresence( flow::tag_value );
TestTypeDefinitionPresence( flow::node_priority_t );
TestFuncDefinitionPresence( flow::copy_body<Body1c>, (tbb::flow::function_node<int, int>&), Body1c );
TestFuncDefinitionPresence( flow::cast_to<int>, (tbb::flow::tagged_msg<int, int> const&), const int& );
/* Mutex names */
TestTypeDefinitionPresence( null_mutex );
TestTypeDefinitionPresence( null_rw_mutex );
Expand All @@ -259,6 +306,8 @@ static void DefinitionPresence() {
TestTypeDefinitionPresence( blocked_range3d<int> );
TestTypeDefinitionPresence2( blocked_nd_range<int,4> );
TestTypeDefinitionPresence( collaborative_once_flag );
TestTypeDefinitionPresence( filter_mode );
TestTypeDefinitionPresence( flow_control );
TestFuncDefinitionPresence( collaborative_call_once, (tbb::collaborative_once_flag&, const Body&), void );
TestFuncDefinitionPresence( parallel_invoke, (const Body&, const Body&, const Body&), void );
TestFuncDefinitionPresence( parallel_for_each, (int*, int*, const Body1&), void );
Expand Down Expand Up @@ -288,13 +337,42 @@ static void DefinitionPresence() {
TestTypeDefinitionPresence( task_arena );
TestFuncDefinitionPresence( this_task_arena::current_thread_index, (), int );
TestFuncDefinitionPresence( this_task_arena::max_concurrency, (), int );
TestFuncDefinitionPresence( this_task_arena::isolate, (Body&&), void );
TestFuncDefinitionPresence( this_task_arena::enqueue, (tbb::task_handle&&), void );
TestFuncDefinitionPresence( this_task_arena::enqueue, (Body&&), void );
TestFuncDefinitionPresence( this_task_arena::enqueue, (Body&&, tbb::task_group&), void );
TestFuncDefinitionPresence( create_numa_task_arenas, (tbb::task_arena::constraints, unsigned), std::vector<tbb::task_arena> );
TestTypeDefinitionPresence( core_type_id );
TestFuncDefinitionPresence( info::core_types, (), std::vector<tbb::core_type_id> );
TestFuncDefinitionPresence( info::numa_nodes, (), std::vector<tbb::numa_node_id> );
TestFuncDefinitionPresence( info::default_concurrency, (tbb::numa_node_id), int );
TestTypeDefinitionPresence( task_scheduler_observer );
TestTypeDefinitionPresence( tbb_allocator<int> );
TestTypeDefinitionPresence( tick_count );
TestTypeDefinitionPresence( global_control );
TestTypeDefinitionPresence( task_scheduler_handle );
TestFuncDefinitionPresence( finalize, (tbb::task_scheduler_handle&, const std::nothrow_t&), bool );
#if TBB_USE_EXCEPTIONS
TestFuncDefinitionPresence( finalize, (tbb::task_scheduler_handle&), void );
#endif
TestTypeDefinitionPresence( scalable_allocator<int> );
TestTypeDefinitionPresence( attach );
#if __TBB_CPP17_MEMORY_RESOURCE_PRESENT
/* Allocator resource names */
TestTypeDefinitionPresence( cache_aligned_resource );
TestFuncDefinitionPresence( scalable_memory_resource, (), std::pmr::memory_resource* );
#endif
/* Task group names */
TestTypeDefinitionPresence( task_group_status );
TestFuncDefinitionPresence( is_current_task_group_canceling, (), bool );
TestTypeDefinitionPresence( task_handle );
/* Task names */
TestFuncDefinitionPresence( task::current_context, (), tbb::task_group_context* );
#if __TBB_RESUMABLE_TASKS
TestTypeDefinitionPresence( task::suspend_point );
TestFuncDefinitionPresence( task::resume, (tbb::task::suspend_point), void );
TestFuncDefinitionPresence( task::suspend, (SuspendBody), void );
#endif

#if __TBB_CPF_BUILD
TestPreviewNames();
Expand All @@ -309,6 +387,7 @@ static void DefinitionPresence() {
TestExceptionClassesExports();
}

#if !__TBB_TEST_MODULE_EXPORT
#if __TBB_TEST_SECONDARY
/* This mode is used to produce a secondary object file that is linked with
the main one in order to detect "multiple definition" linker error.
Expand All @@ -330,3 +409,4 @@ TEST_CASE("Test for multiple definition linker error") {
Secondary();
}
#endif
#endif /* !__TBB_TEST_MODULE_EXPORT */
47 changes: 47 additions & 0 deletions test/tbb/test_tbb_header_module.cppm
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
Copyright (c) 2026 UXL Foundation Contributors

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

//! \file test_tbb_header_module.cppm
//! \brief C++20 module interface unit to test TBB public API for TU-local entity exposure
module;
// Preprocessing macros from test_tbb_header.cpp
#if __INTEL_COMPILER && _MSC_VER
#pragma warning(disable : 2586) // decorated name length exceeded, name was truncated
#endif

#ifndef NOMINMAX
#define NOMINMAX
#endif

#define __TBB_NO_IMPLICIT_LINKAGE 1
#define __TBB_TEST_MODULE_EXPORT 1

#define CHECK(x) do { if (!(x)) { std::terminate(); } } while (false)
#define CHECK_MESSAGE(x, y) CHECK(x);

#include "common/config.h"
#include "oneapi/tbb/detail/_config.h"
#include "tbb/tbb.h"

#include <cstddef>
#include <exception>
#include <stdexcept>
#include <tuple>
#include <vector>

export module tbb_header_test;

#include "test_tbb_header.cpp"
26 changes: 26 additions & 0 deletions test/tbb/test_tbb_header_module_consumer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
Copyright (c) 2026 UXL Foundation Contributors

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

//! \file test_tbb_header_module_consumer.cpp
//! \brief Test for [all] specification using C++20 modules

#include "common/test.h"
import tbb_header_test;

//! \brief \ref interface
TEST_CASE("Test for definition presence in module interface") {
DefinitionPresence();
}