• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 <atomic>
17 #include <chrono>
18 #include <map>
19 #include <shared_mutex>
20 
21 #include "rs_unmarshal_task_manager.h"
22 
23 #include "platform/common/rs_log.h"
24 
25 namespace OHOS::Rosen {
GetTaskDuration() const26 uint64_t UnmarshalTaskInfo::GetTaskDuration() const
27 {
28     if (state == UnmarshalTaskState::COMPLETED) {
29         return completeTimestamp - invokeTimestamp;
30     } else if (state == UnmarshalTaskState::RUNNING) {
31         return UnmarshalTaskUtil::GetTimestamp() - invokeTimestamp;
32     }
33     return 0;
34 }
35 
Dump() const36 std::string UnmarshalTaskInfo::Dump() const
37 {
38     std::string dumpStr = "{";
39     dumpStr += "state: ";
40     dumpStr += UnmarshalTaskUtil::UnmarshalTaskStateToString(state);
41     dumpStr += ", name: ";
42     dumpStr += name;
43     dumpStr += ", timestamp: [";
44     dumpStr += std::to_string(invokeTimestamp);
45     dumpStr += ", ";
46     dumpStr += std::to_string(completeTimestamp);
47     dumpStr += "], uid: ";
48     dumpStr += std::to_string(uid);
49     dumpStr += "}";
50     return dumpStr;
51 }
52 
53 class RSUnmarshalRunningTaskManager {
54 public:
Clear()55     void Clear()
56     {
57         std::unique_lock<std::shared_mutex> lock { runningTaskMutex_ };
58         runningTasks_.clear();
59     }
60 
Push(UnmarshalTaskInfo info)61     void Push(UnmarshalTaskInfo info)
62     {
63         auto uid = info.uid;
64         std::unique_lock<std::shared_mutex> lock { runningTaskMutex_ };
65         runningTasks_.insert_or_assign(uid, std::move(info));
66     }
67 
Pop(uint64_t uid)68     std::optional<UnmarshalTaskInfo> Pop(uint64_t uid)
69     {
70         std::unique_lock<std::shared_mutex> lock { runningTaskMutex_ };
71         if (auto node = runningTasks_.extract(uid)) {
72             return node.mapped();
73         }
74         return std::nullopt;
75     }
76 
GetLongestTask() const77     std::optional<UnmarshalTaskInfo> GetLongestTask() const
78     {
79         std::shared_lock<std::shared_mutex> lock { runningTaskMutex_ };
80         if (runningTasks_.empty()) {
81             return std::nullopt;
82         }
83         std::optional<UnmarshalTaskInfo> ret;
84         uint64_t maxDuration = 0;
85         for (const auto& [_, info] : runningTasks_) {
86             auto duration = info.GetTaskDuration();
87             if (duration > maxDuration) {
88                 maxDuration = duration;
89                 ret = info;
90             }
91         }
92         return ret;
93     }
94 
Dump() const95     std::string Dump() const
96     {
97         std::string dumpStr = "RSUnmarshalRunningTaskManager Dump : [";
98         {
99             std::shared_lock<std::shared_mutex> lock { runningTaskMutex_ };
100             for (const auto& [_, info] : runningTasks_) {
101                 dumpStr += info.Dump();
102                 dumpStr += ",";
103             }
104         }
105         if (!dumpStr.empty()) {
106             dumpStr.pop_back();
107         }
108         dumpStr += "]";
109         return dumpStr;
110     }
111 
112 private:
113     mutable std::shared_mutex runningTaskMutex_;
114     std::map<uint64_t, UnmarshalTaskInfo> runningTasks_;
115 };
116 
117 class RSUnmarshalCompletedTaskManager {
118 public:
Clear()119     void Clear()
120     {
121         std::unique_lock<std::shared_mutex> lock { completedTaskMutex_ };
122         taskRankingTable_.clear();
123     }
124 
Push(UnmarshalTaskInfo info)125     void Push(UnmarshalTaskInfo info)
126     {
127         auto uid = info.uid;
128         auto duration = info.GetTaskDuration();
129         std::unique_lock<std::shared_mutex> lock { completedTaskMutex_ };
130         taskRankingTable_.insert_or_assign({ duration, uid }, std::move(info));
131     }
132 
Pop()133     std::optional<UnmarshalTaskInfo> Pop()
134     {
135         std::unique_lock<std::shared_mutex> lock { completedTaskMutex_ };
136         if (taskRankingTable_.empty()) {
137             return std::nullopt;
138         }
139         return taskRankingTable_.extract(taskRankingTable_.cbegin()).mapped();
140     }
141 
GetLongestTask() const142     std::optional<UnmarshalTaskInfo> GetLongestTask() const
143     {
144         std::shared_lock<std::shared_mutex> lock { completedTaskMutex_ };
145         if (taskRankingTable_.empty()) {
146             return std::nullopt;
147         }
148         return taskRankingTable_.cbegin()->second;
149     }
150 
Dump() const151     std::string Dump() const
152     {
153         std::string dumpStr = "RSUnmarshalCompletedTaskManager Dump: [";
154         {
155             std::shared_lock<std::shared_mutex> lock { completedTaskMutex_ };
156             for (const auto& [_, info] : taskRankingTable_) {
157                 dumpStr += info.Dump();
158                 dumpStr += ",";
159             }
160         }
161         if (!dumpStr.empty()) {
162             dumpStr.pop_back();
163         }
164         dumpStr += "]";
165         return dumpStr;
166     }
167 
168 private:
169     mutable std::shared_mutex completedTaskMutex_;
170     std::map<std::pair<uint64_t, uint64_t>, UnmarshalTaskInfo, std::greater<>> taskRankingTable_;
171 };
172 
RSUnmarshalTaskManager()173 RSUnmarshalTaskManager::RSUnmarshalTaskManager() : runningTaskMgr_(std::make_unique<RSUnmarshalRunningTaskManager>()),
174     completedTaskMgr_(std::make_unique<RSUnmarshalCompletedTaskManager>())
175 {
176 }
177 
Instance()178 RSUnmarshalTaskManager& RSUnmarshalTaskManager::Instance()
179 {
180     static RSUnmarshalTaskManager mgr;
181     return mgr;
182 }
183 
BeginTask(std::string name)184 uint64_t RSUnmarshalTaskManager::BeginTask(std::string name)
185 {
186     auto uid = GetUid();
187     runningTaskMgr_->Push({
188         .state = UnmarshalTaskState::RUNNING,
189         .name = std::move(name),
190         .invokeTimestamp = UnmarshalTaskUtil::GetTimestamp(),
191         .uid = uid,
192     });
193     return uid;
194 }
195 
EndTask(uint64_t uid)196 void RSUnmarshalTaskManager::EndTask(uint64_t uid)
197 {
198     if (auto taskInfo = runningTaskMgr_->Pop(uid)) {
199         auto& info = taskInfo.value();
200         info.state = UnmarshalTaskState::COMPLETED;
201         info.completeTimestamp = UnmarshalTaskUtil::GetTimestamp();
202         completedTaskMgr_->Push(std::move(info));
203     } else {
204         RS_LOGE("RSUnmarshalTaskManager EndTask Invalid Uid %{public}" PRIu64, uid);
205     }
206 }
207 
Clear()208 void RSUnmarshalTaskManager::Clear()
209 {
210     completedTaskMgr_->Clear();
211 }
212 
GetLongestTask() const213 std::optional<UnmarshalTaskInfo> RSUnmarshalTaskManager::GetLongestTask() const
214 {
215     if (auto completedTask = GetCompletedLongestTask()) {
216         if (auto runningTask = GetRunningLongestTask()) {
217             return (completedTask.value().GetTaskDuration() < runningTask.value().GetTaskDuration()) ?
218                 runningTask : completedTask;
219         }
220         return completedTask;
221     }
222     return GetRunningLongestTask();
223 }
224 
GetRunningLongestTask() const225 std::optional<UnmarshalTaskInfo> RSUnmarshalTaskManager::GetRunningLongestTask() const
226 {
227     return runningTaskMgr_->GetLongestTask();
228 }
229 
GetCompletedLongestTask() const230 std::optional<UnmarshalTaskInfo> RSUnmarshalTaskManager::GetCompletedLongestTask() const
231 {
232     return completedTaskMgr_->GetLongestTask();
233 }
234 
GetUid() const235 uint64_t RSUnmarshalTaskManager::GetUid() const
236 {
237     static std::atomic_uint64_t uid;
238     return uid.fetch_add(1, std::memory_order_relaxed);
239 }
240 
Dump() const241 std::string RSUnmarshalTaskManager::Dump() const
242 {
243     std::string dumpStr = "RunningTasks: ";
244     dumpStr += runningTaskMgr_->Dump();
245     dumpStr += "|| completedTasks: ";
246     dumpStr += completedTaskMgr_->Dump();
247     return dumpStr;
248 }
249 
250 namespace UnmarshalTaskUtil {
UnmarshalTaskStateToString(UnmarshalTaskState state)251 std::string UnmarshalTaskStateToString(UnmarshalTaskState state)
252 {
253     switch (state) {
254         case UnmarshalTaskState::COMPLETED : {
255             return "COMPLETED";
256         }
257         case UnmarshalTaskState::RUNNING : {
258             return "RUNNING";
259         }
260         case UnmarshalTaskState::UNINVOKED : {
261             return "UNINVOKED";
262         }
263         default : {
264             return "UNDEFSTATE";
265         }
266     }
267 }
268 
GetTimestamp()269 uint64_t GetTimestamp()
270 {
271     return std::chrono::duration_cast<std::chrono::milliseconds>(
272         std::chrono::steady_clock::now().time_since_epoch()).count();
273 }
274 } // namespace UnmarshalTaskUtil
275 } // namespace OHOS::Rosen