• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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