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 #include "base/log/ace_performance_monitor.h"
17
18 #include <sstream>
19
20 #include "base/json/json_util.h"
21 #include "base/log/ace_trace.h"
22
23 namespace OHOS::Ace {
24 using namespace std;
25 using namespace std::chrono;
26 namespace {
GetTimePoint(TimePoint & now)27 void GetTimePoint(TimePoint& now)
28 {
29 if (SystemProperties::GetAcePerformanceMonitorEnabled()) {
30 now = steady_clock::now();
31 }
32 }
33 } // namespace
34
ScopedMonitor(MonitorTag tag)35 ScopedMonitor::ScopedMonitor(MonitorTag tag) : tag_(tag)
36 {
37 GetTimePoint(begin_);
38 ArkUIPerfMonitor::GetInstance().SetRecordingStatus(tag_, MonitorStatus::RUNNING);
39 }
40
~ScopedMonitor()41 ScopedMonitor::~ScopedMonitor()
42 {
43 GetTimePoint(end_);
44 ArkUIPerfMonitor::GetInstance().RecordTimeSlice(tag_, duration_cast<nanoseconds>(end_ - begin_).count());
45 }
46
GetInstance()47 ArkUIPerfMonitor& ArkUIPerfMonitor::GetInstance()
48 {
49 static ArkUIPerfMonitor instance;
50 return instance;
51 }
52
ArkUIPerfMonitor()53 ArkUIPerfMonitor::ArkUIPerfMonitor()
54 {
55 InitPerfMonitor();
56 }
57
StartPerf()58 void ArkUIPerfMonitor::StartPerf()
59 {
60 GetTimePoint(begin_);
61 ClearPerfMonitor();
62 }
63
FinishPerf()64 void ArkUIPerfMonitor::FinishPerf()
65 {
66 GetTimePoint(end_);
67 FlushPerfMonitor();
68 ClearPerfMonitor();
69 }
70
RecordTimeSlice(MonitorTag tag,int64_t duration)71 void ArkUIPerfMonitor::RecordTimeSlice(MonitorTag tag, int64_t duration)
72 {
73 SetRecordingStatus(tag, MonitorStatus::IDLE);
74 if (tag == MonitorTag::STATIC_API) {
75 propertyNum_++;
76 if (!monitorStatus_) {
77 return;
78 }
79 timeSlice_[tag] += duration;
80 return;
81 }
82 if (monitorStatus_ == 0) {
83 timeSlice_[tag] += duration;
84 }
85 }
86
RecordStateMgmtNode(int64_t num)87 void ArkUIPerfMonitor::RecordStateMgmtNode(int64_t num)
88 {
89 stateMgmtNodeNum_ += num;
90 }
91
RecordLayoutNode(int64_t num)92 void ArkUIPerfMonitor::RecordLayoutNode(int64_t num)
93 {
94 layoutNodeNum_ += num;
95 }
96
RecordRenderNode(int64_t num)97 void ArkUIPerfMonitor::RecordRenderNode(int64_t num)
98 {
99 renderNodeNum_ += num;
100 }
101
RecordDisplaySyncRate(int32_t displaySyncRate)102 void ArkUIPerfMonitor::RecordDisplaySyncRate(int32_t displaySyncRate)
103 {
104 displaySyncRate_ = displaySyncRate;
105 }
106
SetRecordingStatus(MonitorTag tag,MonitorStatus status)107 void ArkUIPerfMonitor::SetRecordingStatus(MonitorTag tag, MonitorStatus status)
108 {
109 if (tag == MonitorTag::STATIC_API) {
110 return;
111 }
112 switch (status) {
113 case MonitorStatus::RUNNING:
114 ++monitorStatus_;
115 break;
116 case MonitorStatus::IDLE:
117 --monitorStatus_;
118 break;
119 }
120 }
121
InitPerfMonitor()122 void ArkUIPerfMonitor::InitPerfMonitor()
123 {
124 monitorStatus_ = 0;
125 ClearPerfMonitor();
126 }
127
ClearPerfMonitor()128 void ArkUIPerfMonitor::ClearPerfMonitor()
129 {
130 timeSlice_[MonitorTag::COMPONENT_CREATION] = 0;
131 timeSlice_[MonitorTag::COMPONENT_LIFECYCLE] = 0;
132 timeSlice_[MonitorTag::COMPONENT_UPDATE] = 0;
133 timeSlice_[MonitorTag::JS_CALLBACK] = 0;
134 timeSlice_[MonitorTag::STATIC_API] = 0;
135 timeSlice_[MonitorTag::OTHER] = 0;
136 propertyNum_ = 0;
137 stateMgmtNodeNum_ = 0;
138 layoutNodeNum_ = 0;
139 renderNodeNum_ = 0;
140 displaySyncRate_ = 0;
141 }
142
FlushPerfMonitor()143 void ArkUIPerfMonitor::FlushPerfMonitor()
144 {
145 auto total = static_cast<int64_t>(duration_cast<nanoseconds>(end_ - begin_).count());
146 auto frameWork = total - timeSlice_[MonitorTag::COMPONENT_CREATION] - timeSlice_[MonitorTag::COMPONENT_LIFECYCLE] -
147 timeSlice_[MonitorTag::COMPONENT_UPDATE] - timeSlice_[MonitorTag::JS_CALLBACK] +
148 timeSlice_[MonitorTag::STATIC_API] - timeSlice_[MonitorTag::OTHER];
149 #if ORIGIN_PERF_MONITOR
150 auto json = JsonUtil::Create(true);
151 json->Put("state_mgmt", stateMgmtNodeNum_);
152 json->Put("layout", layoutNodeNum_);
153 json->Put("render", renderNodeNum_);
154 json->Put("property", propertyNum_);
155 json->Put("total", total);
156 json->Put("framework", frameWork);
157 json->Put("display_sync_rate", displaySyncRate_);
158 ACE_SCOPED_TRACE("ArkUIPerfMonitor %s", json->ToString().c_str());
159 #else
160 std::ostringstream oss;
161 oss << "{\'state_mgmt\':" << stateMgmtNodeNum_;
162 oss << ",\'layout\':" << layoutNodeNum_;
163 oss << ",\'render\':" << renderNodeNum_;
164 oss << ",\'property\':" << propertyNum_;
165 oss << ",\'total\':" << total;
166 oss << ",\'framework\':" << frameWork;
167 oss << ",\'display_sync_rate\':" << displaySyncRate_;
168 oss << "}";
169 ACE_SCOPED_TRACE("ArkUIPerfMonitor %s", oss.str().c_str());
170 #endif
171 }
172 } // namespace OHOS::Ace
173