// MIT License // // Copyright (c) 2022 Advanced Micro Devices, Inc. All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #pragma once #include "library/components/fwd.hpp" #include "library/defines.hpp" #include "library/runtime.hpp" #include "library/state.hpp" #include "library/timemory.hpp" #include #include #include #include #include namespace omnitrace { namespace component { template using enable_if_t = typename std::enable_if::type; template static auto get_default_functor(tim::type_list) { return [](Tp...) {}; }; // timemory component which calls omnitrace functions // (used in gotcha wrappers) template struct functors : comp::base, void> { using this_type = functors; using base_type = comp::base, void>; using pair_type = std::pair; static constexpr bool begin_supports_cstr = std::is_invocable::value; static constexpr bool end_supports_cstr = std::is_invocable::value; static constexpr bool begin_supports_void = std::is_invocable::value; static constexpr bool end_supports_void = std::is_invocable::value; static void preinit(); static void configure(StartFuncT&& _beg, StopFuncT&& _end); static std::string label(); template 0) && std::is_invocable_v), int> = 0> static auto start(Args&&... _args) { OMNITRACE_SCOPED_THREAD_STATE(ThreadState::Internal); get_functors().first(std::forward(_args)...); } template 0) && std::is_invocable_v), int> = 0> static auto stop(Args&&... _args) { OMNITRACE_SCOPED_THREAD_STATE(ThreadState::Internal); get_functors().second(std::forward(_args)...); } TIMEMORY_DEFAULT_OBJECT(functors) template = 0> void start() { OMNITRACE_SCOPED_THREAD_STATE(ThreadState::Internal); get_functors().first(m_prefix); } template = 0> void stop() { OMNITRACE_SCOPED_THREAD_STATE(ThreadState::Internal); get_functors().second(m_prefix); } template = 0> void start() { OMNITRACE_SCOPED_THREAD_STATE(ThreadState::Internal); get_functors().first(); } template = 0> void stop() { OMNITRACE_SCOPED_THREAD_STATE(ThreadState::Internal); get_functors().second(); } template = 0> void set_prefix(const char* _v) { m_prefix = _v; } private: static bool& is_configured(); static pair_type& get_functors(); private: const char* m_prefix = nullptr; }; template void functors::preinit() { using start_args_t = typename tim::mpl::function_traits::args_type; using stop_args_t = typename tim::mpl::function_traits::args_type; get_functors().first = get_default_functor(start_args_t{}); get_functors().second = get_default_functor(stop_args_t{}); } template void functors::configure(StartFuncT&& _beg, StopFuncT&& _end) { is_configured() = true; get_functors().first = std::forward(_beg); get_functors().second = std::forward(_end); } template std::string functors::label() { return trait::name::value; } template bool& functors::is_configured() { static bool _v = false; return _v; } template typename functors::pair_type& functors::get_functors() { static auto _v = pair_type{}; return _v; } } // namespace component } // namespace omnitrace