• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #ifndef API_CORE_PERF_CPU_PERF_SCOPE_H
16 #define API_CORE_PERF_CPU_PERF_SCOPE_H
17 
18 #if (CORE_PERF_ENABLED == 1)
19 
20 #include <base/containers/string.h>
21 #include <base/containers/string_view.h>
22 #include <base/namespace.h>
23 #include <core/implementation_uids.h>
24 #include <core/namespace.h>
25 #include <core/perf/intf_performance_data_manager.h>
26 #include <core/perf/intf_performance_trace.h>
27 #include <core/plugin/intf_class_register.h>
28 
CORE_BEGIN_NAMESPACE()29 CORE_BEGIN_NAMESPACE()
30 
31 // Placeholder interface for disabled paths, disabled path uses static typing so template deducation so basic compiler
32 // can strip the calls.
33 class NullIPerformanceTrace {
34     inline constexpr uintptr_t BeginEvent(const IPerformanceDataManager::Event& location, BASE_NS::string_view text)
35     {
36         return 0;
37     }
38     inline constexpr void EndEvent(uintptr_t eventTag) {}
39     inline constexpr void Message(const char* message, int callstack) {}
40     inline constexpr void Message(const char* message, size_t len, int callstack) {}
41     inline constexpr void AppInfo(const char* name, size_t len) {}
42     inline constexpr void Plot(const char* name, int64_t value) {}
43     inline constexpr void FrameBegin(const char* name) {}
44     inline constexpr void FrameEnd(const char* name) {}
45     inline constexpr void MemAllocNamed(const void* ptr, size_t size, bool secure, const char* name) {}
46     inline constexpr void MemFreeNamed(const void* ptr, bool secure, const char* name) {}
47 };
48 
49 // Setups two code paths, one enabled and one disabled
50 constexpr int PROFILER_ENABLED = 1;
51 constexpr int PROFILER_DISABLED = 0;
52 
53 constexpr uint32_t CORE_PROFILER_DEFAULT_COLOR { 0xff0000 };
54 
55 // Use template specialisation to handle two code paths for enabled and disabled
56 template<int>
57 inline auto* GetTracer();
58 
59 template<>
60 inline auto* GetTracer<PROFILER_ENABLED>()
61 {
62     static IPerformanceTrace* tracer { nullptr };
63     if (!tracer) {
64         if (auto* inst = GetInstance<IPerformanceDataManagerFactory>(UID_PERFORMANCE_FACTORY)) {
65             tracer = inst->GetFirstPerformanceTrace();
66         }
67     }
68 
69     return tracer;
70 }
71 template<>
72 inline auto* GetTracer<PROFILER_DISABLED>()
73 {
74     static NullIPerformanceTrace tracer;
75     return &tracer;
76 }
77 
78 // Use template specialisation to handle two code paths for enabled and disabled
79 template<int>
80 class CpuPerfScopeI;
81 
82 template<>
83 class CpuPerfScopeI<PROFILER_DISABLED> final {
84 public:
CpuPerfScopeI(const BASE_NS::string_view category,const BASE_NS::string_view subCategory,const BASE_NS::string_view name,const IPerformanceDataManager::Event & location)85     inline CpuPerfScopeI(const BASE_NS::string_view category, const BASE_NS::string_view subCategory,
86         const BASE_NS::string_view name, const IPerformanceDataManager::Event& location)
87     {}
Stop()88     inline void Stop() {}
89 };
90 
91 template<>
92 class CpuPerfScopeI<PROFILER_ENABLED> final {
93 public:
CpuPerfScopeI(const BASE_NS::string_view category,const BASE_NS::string_view subCategory,const BASE_NS::string_view name,const IPerformanceDataManager::Event & location)94     CpuPerfScopeI(const BASE_NS::string_view category, const BASE_NS::string_view subCategory,
95         const BASE_NS::string_view name, const IPerformanceDataManager::Event& location)
96         : subCategory_(subCategory), name_(name)
97     {
98         if (auto* inst = GetInstance<IPerformanceDataManagerFactory>(UID_PERFORMANCE_FACTORY); inst) {
99             manager_ = inst->Get(category);
100         }
101 
102         if (manager_) {
103             timerName_ = manager_->BeginTimer();
104             if (auto tracer = GetTracer<PROFILER_ENABLED>()) {
105                 token_ = tracer->BeginEvent(location, name);
106             }
107         }
108     }
~CpuPerfScopeI()109     ~CpuPerfScopeI()
110     {
111         Stop();
112     }
Stop()113     inline void Stop()
114     {
115         if (manager_) {
116             if (auto tracer = GetTracer<PROFILER_ENABLED>()) {
117                 tracer->EndEvent(token_);
118             }
119             manager_->UpdateData(subCategory_, name_, manager_->EndTimer(timerName_));
120             manager_ = nullptr;
121         }
122     }
123 
124 protected:
125     IPerformanceDataManager* manager_ { nullptr };
126     IPerformanceDataManager::TimerHandle timerName_ {};
127     uintptr_t token_ {};
128     BASE_NS::string subCategory_;
129     BASE_NS::string name_;
130 };
131 using CpuPerfScope = CpuPerfScopeI<PROFILER_ENABLED>;
132 
133 template<int N>
134 struct PerformanceTraceSubsystem;
135 
136 template<>
137 struct PerformanceTraceSubsystem<1> {
138     static constexpr bool IsEnabled()
139     {
140         return true;
141     }
142 };
143 
144 using PROFILER_SUBSYSTEM_DEFAULT = PerformanceTraceSubsystem<1>;
145 
146 template<int N>
147 struct PerformanceTraceSeverity {
148     static constexpr bool IsEnabled()
149     {
150         if constexpr (N <= 1000) {
151             return true;
152         } else {
153             return false;
154         }
155     }
156 };
157 
158 using PROFILER_DEFAULT = PerformanceTraceSeverity<1000>; // 1000: size
159 using PROFILER_TRACE = PerformanceTraceSeverity<2000>; // 2000: size
160 
161 template<int z = 0, typename x = PROFILER_SUBSYSTEM_DEFAULT, typename y = PROFILER_DEFAULT>
162 inline constexpr bool PerformanceTraceEnabled()
163 {
164     constexpr bool a = x::IsEnabled() && y::IsEnabled() ? true : false;
165     return a;
166 }
167 
168 template<>
169 inline constexpr bool PerformanceTraceEnabled<0, void, void>()
170 {
171     return PerformanceTraceEnabled<0, PROFILER_SUBSYSTEM_DEFAULT, PROFILER_DEFAULT>();
172 }
173 
174 CORE_END_NAMESPACE()
175 
176 // Helper to concatenate macro values.
177 #define CORE_CONCAT_NOEXP(value0, value1) value0##value1
178 #define CORE_CONCAT(value0, value1) CORE_CONCAT_NOEXP(value0, value1)
179 
180 #define CORE_PROFILER_TOKEN(arg) arg
181 #define CORE_PROFILER_ARGS(...) CORE_NS::PerformanceTraceEnabled<0, ##__VA_ARGS__>()
182 
183 #define CORE_PROFILER_PERF_BEGIN(timerName, category, subCategory, name, color, ...)                                \
184     static constexpr const auto CORE_CONCAT(eventLocation, __LINE__) =                                              \
185         CORE_NS::IPerformanceDataManager::Event { category "::" subCategory, __func__, __FILE__, __LINE__, color }; \
186     CORE_NS::CpuPerfScopeI<CORE_PROFILER_ARGS(__VA_ARGS__)> timerName(                                              \
187         category, subCategory, name, CORE_CONCAT(eventLocation, __LINE__))
188 #define CORE_PROFILER_PERF_END(timerName) timerName.Stop()
189 
190 #define CORE_PROFILER_PERF_SCOPE(category, subCategory, name, color, ...)                                        \
191     static constexpr const auto CORE_CONCAT(eventLocation, __LINE__) = CORE_NS::IPerformanceDataManager::Event { \
192         category "::" subCategory,                                                                               \
193         __func__,                                                                                                \
194         __FILE__,                                                                                                \
195         __LINE__,                                                                                                \
196         color,                                                                                                   \
197     };                                                                                                           \
198     CORE_NS::CpuPerfScopeI<CORE_PROFILER_ARGS(__VA_ARGS__)> CORE_CONCAT(cpuPerfScope_, __LINE__)(                \
199         category, subCategory, name, CORE_CONCAT(eventLocation, __LINE__))
200 
201 #define CORE_PROFILER_SYMBOL(name, value) constexpr const char* name = value
202 
203 #define CORE_PROFILER_APPNAME(txt, size, ...)                                  \
204     if (auto tracer = CORE_NS::GetTracer<CORE_PROFILER_ARGS(__VA_ARGS__)>()) { \
205         tracer->AppInfo(txt, size);                                            \
206     }
207 
208 #define CORE_PROFILER_MESSAGEL(msg, ...)                                       \
209     if (auto tracer = CORE_NS::GetTracer<CORE_PROFILER_ARGS(__VA_ARGS__)>()) { \
210         tracer->Message(msg, 0);                                               \
211     }
212 
213 #define CORE_PROFILER_MESSAGE(msg, size, ...)                                  \
214     if (auto tracer = CORE_NS::GetTracer<CORE_PROFILER_ARGS(__VA_ARGS__)>()) { \
215         tracer->Message(msg, size);                                            \
216     }
217 
218 #define CORE_PROFILER_PLOT(name, val, ...)                                     \
219     if (auto tracer = CORE_NS::GetTracer<CORE_PROFILER_ARGS(__VA_ARGS__)>()) { \
220         tracer->Plot(name, val);                                               \
221     }
222 
223 #define CORE_PROFILER_MARK_GLOBAL_FRAME_CHANGED(...)                           \
224     if (auto tracer = CORE_NS::GetTracer<CORE_PROFILER_ARGS(__VA_ARGS__)>()) { \
225         tracer->GlobalFrameChanged();                                          \
226     }
227 
228 #define CORE_PROFILER_MARK_FRAME_START(name, ...)                              \
229     if (auto tracer = CORE_NS::GetTracer<CORE_PROFILER_ARGS(__VA_ARGS__)>()) { \
230         tracer->FrameBegin(name);                                              \
231     }
232 
233 #define CORE_PROFILER_MARK_FRAME_END(name, ...)                                \
234     if (auto tracer = CORE_NS::GetTracer<CORE_PROFILER_ARGS(__VA_ARGS__)>()) { \
235         tracer->FrameEnd(name);                                                \
236     }
237 
238 #define CORE_PROFILER_ALLOC_N(ptr, size, name, ...)                            \
239     if (auto tracer = CORE_NS::GetTracer<CORE_PROFILER_ARGS(__VA_ARGS__)>()) { \
240         tracer->MemAllocNamed(ptr, size, false, name);                         \
241     }
242 
243 #define CORE_PROFILER_FREE_N(ptr, name, ...)                                   \
244     if (auto tracer = CORE_NS::GetTracer<CORE_PROFILER_ARGS(__VA_ARGS__)>()) { \
245         tracer->MemFreeNamed(ptr, false, name);                                \
246     }
247 
248 #define CORE_CPU_PERF_BEGIN(timerName, category, subCategory, name, color, ...) \
249     CORE_PROFILER_PERF_BEGIN(                                                   \
250         timerName, category, subCategory, name, color, CORE_NS::PROFILER_SUBSYSTEM_DEFAULT, ##__VA_ARGS__)
251 #define CORE_CPU_PERF_END(timerName) CORE_PROFILER_PERF_END(timerName)
252 #define CORE_CPU_PERF_SCOPE(category, subCategory, name, color, ...) \
253     CORE_PROFILER_PERF_SCOPE(category, subCategory, name, color, CORE_NS::PROFILER_SUBSYSTEM_DEFAULT, ##__VA_ARGS__)
254 #else
255 #define CORE_PROFILER_PERF_BEGIN(timerName, category, subCategory, name, color, ...)
256 #define CORE_PROFILER_PERF_END(timerName)
257 #define CORE_PROFILER_PERF_SCOPE(category, subCategory, name, color, ...)
258 #define CORE_PROFILER_SYMBOL(name, value)
259 #define CORE_PROFILER_APPNAME(name, ...)
260 #define CORE_PROFILER_MESSAGEL(msg, ...)
261 #define CORE_PROFILER_MESSAGE(msg, size, ...)
262 #define CORE_PROFILER_PLOT(name, val, ...)
263 #define CORE_PROFILER_MARK_GLOBAL_FRAME_CHANGED(...)
264 #define CORE_PROFILER_MARK_FRAME_START(name, ...)
265 #define CORE_PROFILER_MARK_FRAME_END(name, ...)
266 #define CORE_PROFILER_ALLOC_N(ptr, size, name, ...)
267 #define CORE_PROFILER_FREE_N(ptr, name, ...)
268 #define CORE_CPU_PERF_BEGIN(timerName, category, subCategory, name, ...)
269 #define CORE_CPU_PERF_END(timerName)
270 #define CORE_CPU_PERF_SCOPE(category, subCategory, name, ...)
271 #endif
272 
273 #endif // API_CORE_PERF_CPU_PERF_SCOPE_H
274