|
| 1 | +/* |
| 2 | + Copyright (c) 2025 Intel Corporation |
| 3 | + Copyright (c) 2025 UXL Foundation Contributors |
| 4 | +
|
| 5 | + Licensed under the Apache License, Version 2.0 (the "License"); |
| 6 | + you may not use this file except in compliance with the License. |
| 7 | + You may obtain a copy of the License at |
| 8 | +
|
| 9 | + http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | +
|
| 11 | + Unless required by applicable law or agreed to in writing, software |
| 12 | + distributed under the License is distributed on an "AS IS" BASIS, |
| 13 | + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 14 | + See the License for the specific language governing permissions and |
| 15 | + limitations under the License. |
| 16 | +*/ |
| 17 | + |
| 18 | +//! \file test_tbbbind.cpp |
| 19 | +//! \brief Test for TBBbind library, covers [configuration.debug_features] |
| 20 | + |
| 21 | +#define TEST_CUSTOM_ASSERTION_HANDLER_ENABLED 1 |
| 22 | +#if _WIN32 || _WIN64 |
| 23 | +#define _CRT_SECURE_NO_WARNINGS |
| 24 | +#endif |
| 25 | + |
| 26 | +#include "oneapi/tbb/global_control.h" |
| 27 | +#include "oneapi/tbb/task_arena.h" |
| 28 | +#include "common/test.h" |
| 29 | +#include "common/utils_assert.h" |
| 30 | + |
| 31 | +// no need to do it in the test |
| 32 | +#define __TBB_SKIP_DEPENDENCY_SIGNATURE_VERIFICATION 1 |
| 33 | + |
| 34 | +#define DYNAMIC_LINK_FIND_LIB_WITH_TBB_RUNTIME_VERSION 1 |
| 35 | +#include "../../src/tbb/dynamic_link.cpp" |
| 36 | +#include "../../src/tbb/load_tbbbind.h" |
| 37 | + |
| 38 | +#if __TBB_WEAK_SYMBOLS_PRESENT |
| 39 | +#pragma weak __TBB_internal_deallocate_binding_handler |
| 40 | +#endif /* __TBB_WEAK_SYMBOLS_PRESENT */ |
| 41 | + |
| 42 | +namespace tbb { |
| 43 | +namespace detail { |
| 44 | +namespace r1 { |
| 45 | +class binding_handler; |
| 46 | + |
| 47 | +extern "C" { |
| 48 | +void __TBB_internal_deallocate_binding_handler( binding_handler* handler_ptr ); |
| 49 | +} |
| 50 | +}}} |
| 51 | + |
| 52 | +using BindingHandlerType = void (*)(tbb::detail::r1::binding_handler* handler_ptr); |
| 53 | + |
| 54 | +BindingHandlerType GetDeallocateBindingHandler() { |
| 55 | + using namespace tbb::detail::r1; |
| 56 | + |
| 57 | + BindingHandlerType deallocate_binding_handler_ptr; |
| 58 | + |
| 59 | + const dynamic_link_descriptor LinkTable[] = { |
| 60 | + DLD(__TBB_internal_deallocate_binding_handler, deallocate_binding_handler_ptr) |
| 61 | + }; |
| 62 | + |
| 63 | + for (const auto& tbbbind_version : tbbbind_libraries_list) { |
| 64 | + if (dynamic_link(tbbbind_version, LinkTable, |
| 65 | + sizeof(LinkTable) / sizeof(dynamic_link_descriptor), nullptr, |
| 66 | + DYNAMIC_LINK_LOCAL_BINDING)) { |
| 67 | + return deallocate_binding_handler_ptr; |
| 68 | + } |
| 69 | + } |
| 70 | + return nullptr; |
| 71 | +} |
| 72 | + |
| 73 | +// Testing can't be done without TBBbind. |
| 74 | +#if __TBB_SELF_CONTAINED_TBBBIND || __TBB_HWLOC_VALID_ENVIRONMENT |
| 75 | +static bool isTbbBindAvailable() { return true; } |
| 76 | +#else |
| 77 | +static bool isTbbBindAvailable() { return false; } |
| 78 | +#endif |
| 79 | + |
| 80 | +// All assertions in TBBbind are available only in TBB_USE_ASSERT mode. |
| 81 | +#if TBB_USE_ASSERT |
| 82 | +static bool canTestAsserts() { return true; } |
| 83 | +#else |
| 84 | +static bool canTestAsserts() { return false; } |
| 85 | +#endif |
| 86 | + |
| 87 | +// this code hangs in -DBUILD_SHARED_LIBS=OFF case (#1832) |
| 88 | +#if __TBB_DYNAMIC_LOAD_ENABLED |
| 89 | +// Must initialize system_topology and so register assertion handler in TBBbind. |
| 90 | +// The test harness expects TBBBIND status always to be reported as part of TBB_VERSION output, so |
| 91 | +// initialize system_topology even if TBBbind is not available. |
| 92 | +struct Init { |
| 93 | + Init() { |
| 94 | + auto constraints = tbb::task_arena::constraints{}.set_max_threads_per_core(1); |
| 95 | + tbb::task_arena arena( constraints ); |
| 96 | + arena.initialize(); |
| 97 | + } |
| 98 | +} init; |
| 99 | +#endif |
| 100 | + |
| 101 | +// The test relies on an assumption that system_topology::load_tbbbind_shared_object() find |
| 102 | +// same instance of TBBbind as TBB uses internally. |
| 103 | +//! Testing that assertions called inside TBBbind are handled correctly |
| 104 | +//! \brief \ref interface \ref requirement |
| 105 | +TEST_CASE("Using custom assertion handler inside TBBbind" |
| 106 | + * doctest::skip(!isTbbBindAvailable() || !canTestAsserts())) { |
| 107 | + // fills pointers to TBBbind entry points |
| 108 | + BindingHandlerType deallocate_binding_handler = GetDeallocateBindingHandler(); |
| 109 | + REQUIRE_MESSAGE(deallocate_binding_handler != nullptr, |
| 110 | + "Failed to fill deallocate_binding_handler_ptr"); |
| 111 | + |
| 112 | + // we are expecting that deallocate_binding_handler points to TBBbind entry point |
| 113 | + TEST_CUSTOM_ASSERTION_HANDLER(deallocate_binding_handler(nullptr), |
| 114 | + "Trying to deallocate nullptr pointer."); |
| 115 | +} |
0 commit comments