1 /*
2  * Copyright (c) 2024 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 
16 #ifndef API_CORE_PERF_INTF_PERFORMANCE_DATA_MANAGER_H
17 #define API_CORE_PERF_INTF_PERFORMANCE_DATA_MANAGER_H
18 
19 #include <cstdint>
20 
21 #include <base/containers/fixed_string.h>
22 #include <base/containers/refcnt_ptr.h>
23 #include <base/containers/string_view.h>
24 #include <base/containers/unordered_map.h>
25 #include <base/containers/vector.h>
26 #include <base/namespace.h>
27 #include <base/util/uid.h>
28 #include <core/namespace.h>
29 #include <core/plugin/intf_interface.h>
30 
CORE_BEGIN_NAMESPACE()31 CORE_BEGIN_NAMESPACE()
32 /** PerformanceDataManager for timings.
33  * Internally synchronized.
34  */
35 class IPerformanceDataManager : public IInterface {
36 public:
37     using Ptr = BASE_NS::refcnt_ptr<IPerformanceDataManager>;
38     static constexpr auto UID = BASE_NS::Uid { "9ce7d517-4b7d-400b-bdc5-f449d93479d8" };
39 
40     static constexpr uint32_t TIMING_DATA_POOL_SIZE { 64u };
41     static constexpr uint32_t TIMING_DATA_NAME_LENGTH { 64u };
42 
43     struct PerformanceTimingData {
44         /** Latest value. */
45         int64_t currentTime { 0 };
46         /** Largest value. */
47         int64_t maxTime { 0 };
48         /** Smallest value. */
49         int64_t minTime { 0 };
50         /** Average of the last TIMING_DATA_POOL_SIZE values. */
51         int64_t averageTime { 0 };
52         /** Sum of the valus. */
53         int64_t totalTime { 0 };
54         /** Max sum of total time values. (Might be used with negative values) */
55         int64_t maxTotalTime { 0 };
56         /** Number of times the data has been updated. */
57         int64_t counter { 0 };
58         /** Array containing the last TIMING_DATA_POOL_SIZE values. */
59         int64_t timings[TIMING_DATA_POOL_SIZE] { 0 };
60     };
61 
62     using NameToPerformanceMap =
63         BASE_NS::unordered_map<BASE_NS::fixed_string<TIMING_DATA_NAME_LENGTH>, PerformanceTimingData>;
64 
65     struct PerformanceData {
66         /** Name of the subcategory. */
67         BASE_NS::fixed_string<TIMING_DATA_NAME_LENGTH> subCategory;
68         /** Data so far gathered for the subcatagory. */
69         NameToPerformanceMap timings;
70     };
71 
72     IPerformanceDataManager(const IPerformanceDataManager&) = delete;
73     IPerformanceDataManager& operator=(const IPerformanceDataManager&) = delete;
74 
75     /** Returns the category to which this performance data belongs to.
76      * @return Name of the category given when calling IPerformanceDataManagerFactory::Get.
77      */
78     virtual BASE_NS::string_view GetCategory() const = 0;
79 
80     using TimerHandle = int64_t;
81 
82     /** Starts measuring time.
83      * @return Handle which is used to stop the measurement.
84      */
85     virtual TimerHandle BeginTimer() = 0;
86 
87     /** Stops measuring time.
88      * @param handle A handle previously returned from BeginTimer.
89      * @return Time elapsed between Begin/EndTimer calls in microseconds.
90      */
91     virtual int64_t EndTimer(TimerHandle handle) = 0;
92 
93     /** Updates performance timing data.
94      * @param subCategory Name of the subcategory.
95      * @param name Name of the data entry.
96      * @param microSeconds Time in microseconds.
97      */
98     virtual void UpdateData(
99         const BASE_NS::string_view subCategory, const BASE_NS::string_view name, const int64_t microSeconds) = 0;
100 
101     /** Resets all performance data gathered for this category. */
102     virtual void ResetData() = 0;
103 
104     /** Remove subcategory data.
105      * @param subCategory A sub category to be removed.
106      */
107     virtual void RemoveData(const BASE_NS::string_view subCategory) = 0;
108 
109     /** Returns the performance data gathered for this category.
110      * @return A list contains a name-timings lookuptable for each subcategory.
111      */
112     virtual BASE_NS::vector<PerformanceData> GetData() const = 0;
113 
114 protected:
115     IPerformanceDataManager() = default;
116     virtual ~IPerformanceDataManager() = default;
117 };
118 
GetName(const IPerformanceDataManager *)119 inline constexpr BASE_NS::string_view GetName(const IPerformanceDataManager*)
120 {
121     return "IPerformanceDataManager";
122 }
123 
124 class IPerformanceDataManagerFactory : public IInterface {
125 public:
126     static constexpr auto UID = BASE_NS::Uid { "58d60acd-a2d2-4f76-a9bb-5cf0a82ccd4f" };
127 
128     /** Get a performance data manager instance for a named category. The category can be any freeformed string.
129      * @param category Name of the category.
130      * @return Pointer to the instance grouping statistics for the given category.
131      */
132     virtual IPerformanceDataManager* Get(const BASE_NS::string_view category) = 0;
133 
134     /** Get performance data managers for all categories.
135      * @return Array of instances.
136      */
137     virtual BASE_NS::vector<IPerformanceDataManager*> GetAllCategories() const = 0;
138 };
139 
GetName(const IPerformanceDataManagerFactory *)140 inline constexpr BASE_NS::string_view GetName(const IPerformanceDataManagerFactory*)
141 {
142     return "IPerformanceDataManagerFactory";
143 }
144 CORE_END_NAMESPACE()
145 
146 #endif // API_CORE_PERF_INTF_PERFORMANCE_DATA_MANAGER_H
147