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 "ffrt/ffrt_utils.h"
17 #include "pasteboard_common.h"
18 #include "pasteboard_hilog.h"
19
20 namespace OHOS {
21 namespace MiscServices {
22 std::unordered_map<std::string, std::shared_ptr<FFRTTimer>> FFRTPool::ffrtPool_;
23 std::mutex FFRTPool::mutex_;
24
SubmitTask(const FFRTTask & task)25 void FFRTUtils::SubmitTask(const FFRTTask &task)
26 {
27 ffrt::submit(task);
28 }
29
SubmitQueueTasks(const std::vector<FFRTTask> & tasks,FFRTQueue & queue)30 void FFRTUtils::SubmitQueueTasks(const std::vector<FFRTTask> &tasks, FFRTQueue &queue)
31 {
32 if (tasks.empty()) {
33 return;
34 }
35 for (const auto &task : tasks) {
36 queue.submit(task);
37 }
38 }
39
SubmitDelayTask(FFRTTask & task,uint32_t delayMs,FFRTQueue & queue)40 FFRTHandle FFRTUtils::SubmitDelayTask(FFRTTask &task, uint32_t delayMs, FFRTQueue &queue)
41 {
42 using namespace std::chrono;
43 milliseconds ms(delayMs);
44 microseconds us = duration_cast<microseconds>(ms);
45 return queue.submit_h(task, ffrt::task_attr().delay(us.count()));
46 }
47
SubmitDelayTask(FFRTTask & task,uint32_t delayMs,std::shared_ptr<FFRTQueue> queue)48 FFRTHandle FFRTUtils::SubmitDelayTask(FFRTTask &task, uint32_t delayMs, std::shared_ptr<FFRTQueue> queue)
49 {
50 using namespace std::chrono;
51 milliseconds ms(delayMs);
52 microseconds us = duration_cast<microseconds>(ms);
53 return queue->submit_h(task, ffrt::task_attr().delay(us.count()));
54 }
55
SubmitTimeoutTask(const FFRTTask & task,uint32_t timeoutMs)56 bool FFRTUtils::SubmitTimeoutTask(const FFRTTask &task, uint32_t timeoutMs)
57 {
58 ffrt::future<void> future = ffrt::async(task);
59 auto status = future.wait_for(std::chrono::milliseconds(timeoutMs));
60 return status == ffrt::future_status::ready;
61 }
62
CancelTask(FFRTHandle & handle,FFRTQueue & queue)63 int FFRTUtils::CancelTask(FFRTHandle &handle, FFRTQueue &queue)
64 {
65 return queue.cancel(handle);
66 }
67
CancelTask(FFRTHandle & handle,std::shared_ptr<FFRTQueue> & queue)68 int FFRTUtils::CancelTask(FFRTHandle &handle, std::shared_ptr<FFRTQueue> &queue)
69 {
70 return queue->cancel(handle);
71 }
72
FFRTTimer()73 FFRTTimer::FFRTTimer() : queue_("ffrt_timer") {}
74
FFRTTimer(const std::string & timerName)75 FFRTTimer::FFRTTimer(const std::string &timerName) : queue_(timerName.c_str()) {}
76
~FFRTTimer()77 FFRTTimer::~FFRTTimer()
78 {
79 Clear();
80 }
81
Clear()82 void FFRTTimer::Clear()
83 {
84 mutex_.lock();
85 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "FFRT Timer Clear");
86 CancelAllTimerInner();
87 handleMap_.clear();
88 taskId_.clear();
89 mutex_.unlock();
90 }
91
CancelAllTimer()92 void FFRTTimer::CancelAllTimer()
93 {
94 mutex_.lock();
95 CancelAllTimerInner();
96 mutex_.unlock();
97 }
98
CancelTimer(const std::string & timerId)99 void FFRTTimer::CancelTimer(const std::string &timerId)
100 {
101 mutex_.lock();
102 CancelTimerInner(timerId);
103 mutex_.unlock();
104 }
105
SetTimer(const std::string & timerId,FFRTTask & task,uint32_t delayMs)106 void FFRTTimer::SetTimer(const std::string &timerId, FFRTTask &task, uint32_t delayMs)
107 {
108 mutex_.lock();
109 CancelTimerInner(timerId);
110 ++taskId_[timerId];
111 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "Timer[%{public}s] Add Task[%{public}u] with delay = %{public}u",
112 PasteBoardCommon::GetAnonymousString(timerId).c_str(), taskId_[timerId], delayMs);
113 if (delayMs == 0) {
114 FFRTUtils::SubmitTask(task);
115 } else {
116 handleMap_[timerId] = FFRTUtils::SubmitDelayTask(task, delayMs, queue_);
117 }
118 mutex_.unlock();
119 }
120
GetTaskId(const std::string & timerId)121 uint32_t FFRTTimer::GetTaskId(const std::string &timerId)
122 {
123 mutex_.lock();
124 uint32_t id = taskId_[timerId];
125 mutex_.unlock();
126 return id;
127 }
128
129 /* inner functions must be called when mutex_ is locked */
CancelAllTimerInner()130 void FFRTTimer::CancelAllTimerInner()
131 {
132 for (auto &p : handleMap_) {
133 if (p.second != nullptr) {
134 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "Timer[%{public}s] Cancel Task[%{public}u]",
135 PasteBoardCommon::GetAnonymousString(p.first).c_str(), taskId_[p.first]);
136 FFRTUtils::CancelTask(p.second, queue_);
137 }
138 }
139 }
140
CancelTimerInner(const std::string & timerId)141 void FFRTTimer::CancelTimerInner(const std::string &timerId)
142 {
143 if (handleMap_[timerId] != nullptr) {
144 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "Timer[%{public}s] Cancel Task[%{public}u]",
145 PasteBoardCommon::GetAnonymousString(timerId).c_str(), taskId_[timerId]);
146 FFRTUtils::CancelTask(handleMap_[timerId], queue_);
147 handleMap_[timerId] = nullptr;
148 }
149 }
150
GetTimer(const std::string & name)151 std::shared_ptr<FFRTTimer> FFRTPool::GetTimer(const std::string &name)
152 {
153 std::lock_guard lock(mutex_);
154 auto iter = ffrtPool_.find(name);
155 if (iter != ffrtPool_.end()) {
156 return iter->second;
157 }
158
159 std::shared_ptr<FFRTTimer> timer = std::make_shared<FFRTTimer>(name);
160 ffrtPool_[name] = timer;
161 return timer;
162 }
163
Clear()164 void FFRTPool::Clear()
165 {
166 std::lock_guard lock(mutex_);
167 ffrtPool_.clear();
168 }
169 } // namespace MiscServices
170 } // namespace OHOS