xref: /oneTBB/src/tbb/assert_impl.h (revision 7941f880)
151c0b2f7Stbbdev /*
2b15aabb3Stbbdev     Copyright (c) 2005-2021 Intel Corporation
351c0b2f7Stbbdev 
451c0b2f7Stbbdev     Licensed under the Apache License, Version 2.0 (the "License");
551c0b2f7Stbbdev     you may not use this file except in compliance with the License.
651c0b2f7Stbbdev     You may obtain a copy of the License at
751c0b2f7Stbbdev 
851c0b2f7Stbbdev         http://www.apache.org/licenses/LICENSE-2.0
951c0b2f7Stbbdev 
1051c0b2f7Stbbdev     Unless required by applicable law or agreed to in writing, software
1151c0b2f7Stbbdev     distributed under the License is distributed on an "AS IS" BASIS,
1251c0b2f7Stbbdev     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1351c0b2f7Stbbdev     See the License for the specific language governing permissions and
1451c0b2f7Stbbdev     limitations under the License.
1551c0b2f7Stbbdev */
1651c0b2f7Stbbdev 
1751c0b2f7Stbbdev #ifndef __TBB_assert_impl_H
1851c0b2f7Stbbdev #define __TBB_assert_impl_H
1951c0b2f7Stbbdev 
2049e08aacStbbdev #include "oneapi/tbb/detail/_config.h"
218b6f831cStbbdev #include "oneapi/tbb/detail/_utils.h"
2251c0b2f7Stbbdev 
2351c0b2f7Stbbdev #include <cstdio>
2451c0b2f7Stbbdev #include <cstdlib>
2551c0b2f7Stbbdev #include <cstring>
2651c0b2f7Stbbdev #include <cstdarg>
2751c0b2f7Stbbdev #if _MSC_VER && _DEBUG
2851c0b2f7Stbbdev #include <crtdbg.h>
2951c0b2f7Stbbdev #endif
3051c0b2f7Stbbdev 
3151c0b2f7Stbbdev #include <mutex>
3251c0b2f7Stbbdev 
33*7941f880SIlya Isaev #if __TBBMALLOC_BUILD
34*7941f880SIlya Isaev namespace rml { namespace internal {
35*7941f880SIlya Isaev #else
3651c0b2f7Stbbdev namespace tbb {
3751c0b2f7Stbbdev namespace detail {
3851c0b2f7Stbbdev namespace r1 {
39*7941f880SIlya Isaev #endif
4051c0b2f7Stbbdev // TODO: consider extension for formatted error description string
assertion_failure_impl(const char * location,int line,const char * expression,const char * comment)419e15720bStbbdev static void assertion_failure_impl(const char* location, int line, const char* expression, const char* comment) {
42478de5b1Stbbdev 
43478de5b1Stbbdev     std::fprintf(stderr, "Assertion %s failed (located in the %s function, line in file: %d)\n",
44478de5b1Stbbdev         expression, location, line);
45478de5b1Stbbdev 
4651c0b2f7Stbbdev     if (comment) {
4751c0b2f7Stbbdev         std::fprintf(stderr, "Detailed description: %s\n", comment);
4851c0b2f7Stbbdev     }
4951c0b2f7Stbbdev #if _MSC_VER && _DEBUG
509e15720bStbbdev     if (1 == _CrtDbgReport(_CRT_ASSERT, location, line, "tbb_debug.dll", "%s\r\n%s", expression, comment?comment:"")) {
5151c0b2f7Stbbdev         _CrtDbgBreak();
529e15720bStbbdev     } else
539e15720bStbbdev #endif
549e15720bStbbdev     {
5551c0b2f7Stbbdev         std::fflush(stderr);
5651c0b2f7Stbbdev         std::abort();
579e15720bStbbdev     }
5851c0b2f7Stbbdev }
5951c0b2f7Stbbdev 
608b6f831cStbbdev // Do not move the definition into the assertion_failure function because it will require "magic statics".
618b6f831cStbbdev // It will bring a dependency on C++ runtime on some platforms while assert_impl.h is reused in tbbmalloc
628b6f831cStbbdev // that should not depend on C++ runtime
63*7941f880SIlya Isaev static std::atomic<tbb::detail::do_once_state> assertion_state;
648b6f831cStbbdev 
assertion_failure(const char * location,int line,const char * expression,const char * comment)659e15720bStbbdev void __TBB_EXPORTED_FUNC assertion_failure(const char* location, int line, const char* expression, const char* comment) {
668b6f831cStbbdev #if __TBB_MSVC_UNREACHABLE_CODE_IGNORED
678b6f831cStbbdev     // Workaround for erroneous "unreachable code" during assertion throwing using call_once
688b6f831cStbbdev     #pragma warning (push)
698b6f831cStbbdev     #pragma warning (disable: 4702)
708b6f831cStbbdev #endif
718b6f831cStbbdev     // We cannot use std::call_once because it brings a dependency on C++ runtime on some platforms
728b6f831cStbbdev     // while assert_impl.h is reused in tbbmalloc that should not depend on C++ runtime
738b6f831cStbbdev     atomic_do_once([&](){ assertion_failure_impl(location, line, expression, comment); }, assertion_state);
748b6f831cStbbdev #if __TBB_MSVC_UNREACHABLE_CODE_IGNORED
758b6f831cStbbdev     #pragma warning (pop)
768b6f831cStbbdev #endif
7751c0b2f7Stbbdev }
7851c0b2f7Stbbdev 
7951c0b2f7Stbbdev //! Report a runtime warning.
runtime_warning(const char * format,...)8051c0b2f7Stbbdev void runtime_warning( const char* format, ... ) {
8151c0b2f7Stbbdev     char str[1024]; std::memset(str, 0, 1024);
8251c0b2f7Stbbdev     va_list args; va_start(args, format);
8351c0b2f7Stbbdev     vsnprintf( str, 1024-1, format, args);
8451c0b2f7Stbbdev     va_end(args);
8551c0b2f7Stbbdev     fprintf(stderr, "TBB Warning: %s\n", str);
8651c0b2f7Stbbdev }
8751c0b2f7Stbbdev 
88*7941f880SIlya Isaev #if __TBBMALLOC_BUILD
89*7941f880SIlya Isaev }} // namespaces rml::internal
90*7941f880SIlya Isaev #else
9151c0b2f7Stbbdev } // namespace r1
9251c0b2f7Stbbdev } // namespace detail
9351c0b2f7Stbbdev } // namespace tbb
94*7941f880SIlya Isaev #endif
9551c0b2f7Stbbdev 
9651c0b2f7Stbbdev #endif // __TBB_assert_impl_H
9751c0b2f7Stbbdev 
98