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_utils.h"
17 #include "pasteboard_hilog.h"
18
19 namespace OHOS {
20 namespace MiscServices {
SubmitTask(const FFRTTask & task)21 void FFRTUtils::SubmitTask(const FFRTTask& task)
22 {
23 ffrt::submit(task);
24 }
25
SubmitQueueTasks(const std::vector<FFRTTask> & tasks,FFRTQueue & queue)26 void FFRTUtils::SubmitQueueTasks(const std::vector<FFRTTask>& tasks, FFRTQueue& queue)
27 {
28 if (tasks.empty()) {
29 return;
30 }
31 for (auto task : tasks) {
32 queue.submit(task);
33 }
34 }
35
SubmitDelayTask(FFRTTask & task,uint32_t delayMs,FFRTQueue & queue)36 FFRTHandle FFRTUtils::SubmitDelayTask(FFRTTask& task, uint32_t delayMs, FFRTQueue& queue)
37 {
38 using namespace std::chrono;
39 milliseconds ms(delayMs);
40 microseconds us = duration_cast<microseconds>(ms);
41 return queue.submit_h(task, ffrt::task_attr().delay(us.count()));
42 }
43
SubmitDelayTask(FFRTTask & task,uint32_t delayMs,std::shared_ptr<FFRTQueue> queue)44 FFRTHandle FFRTUtils::SubmitDelayTask(FFRTTask& task, uint32_t delayMs, std::shared_ptr<FFRTQueue> queue)
45 {
46 using namespace std::chrono;
47 milliseconds ms(delayMs);
48 microseconds us = duration_cast<microseconds>(ms);
49 return queue->submit_h(task, ffrt::task_attr().delay(us.count()));
50 }
51
SubmitTimeoutTask(const FFRTTask & task,uint32_t timeoutMs)52 bool FFRTUtils::SubmitTimeoutTask(const FFRTTask& task, uint32_t timeoutMs)
53 {
54 ffrt::future<void> future = ffrt::async(task);
55 auto status = future.wait_for(std::chrono::milliseconds(timeoutMs));
56 return status == ffrt::future_status::ready;
57 }
58
CancelTask(FFRTHandle & handle,FFRTQueue & queue)59 int FFRTUtils::CancelTask(FFRTHandle& handle, FFRTQueue& queue)
60 {
61 return queue.cancel(handle);
62 }
63
CancelTask(FFRTHandle & handle,std::shared_ptr<FFRTQueue> queue)64 int FFRTUtils::CancelTask(FFRTHandle& handle, std::shared_ptr<FFRTQueue> queue)
65 {
66 return queue->cancel(handle);
67 }
68
FFRTTimer()69 FFRTTimer::FFRTTimer(): queue_("ffrt_timer")
70 {
71 }
72
FFRTTimer(const char * timer_name)73 FFRTTimer::FFRTTimer(const char *timer_name): queue_(timer_name)
74 {
75 }
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)106 void FFRTTimer::SetTimer(const std::string &timerId, FFRTTask& task)
107 {
108 mutex_.lock();
109 CancelTimerInner(timerId);
110 ++taskId_[timerId];
111 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "Timer[%{public}s] Add Task[%{public}u]", timerId.c_str(),
112 taskId_[timerId]);
113 FFRTUtils::SubmitTask(task);
114 mutex_.unlock();
115 }
116
SetTimer(const std::string & timerId,FFRTTask & task,uint32_t delayMs)117 void FFRTTimer::SetTimer(const std::string &timerId, FFRTTask& task, uint32_t delayMs)
118 {
119 if (delayMs == 0) {
120 return SetTimer(timerId, task);
121 }
122
123 mutex_.lock();
124 CancelTimerInner(timerId);
125 ++taskId_[timerId];
126 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "Timer[%{public}s] Add Task[%{public}u] with delay = %{public}u",
127 timerId.c_str(), taskId_[timerId], delayMs);
128 handleMap_[timerId] = FFRTUtils::SubmitDelayTask(task, delayMs, queue_);
129 mutex_.unlock();
130 }
131
GetTaskId(const std::string & timerId)132 uint32_t FFRTTimer::GetTaskId(const std::string &timerId)
133 {
134 mutex_.lock();
135 uint32_t id = taskId_[timerId];
136 mutex_.unlock();
137 return id;
138 }
139
140 /* inner functions must be called when mutex_ is locked */
CancelAllTimerInner()141 void FFRTTimer::CancelAllTimerInner()
142 {
143 for (auto &p : handleMap_) {
144 if (p.second != nullptr) {
145 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "Timer[%{public}s] Cancel Task[%{public}u]", p.first.c_str(),
146 taskId_[p.first]);
147 FFRTUtils::CancelTask(p.second, queue_);
148 }
149 }
150 }
151
CancelTimerInner(const std::string & timerId)152 void FFRTTimer::CancelTimerInner(const std::string &timerId)
153 {
154 if (handleMap_[timerId] != nullptr) {
155 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "Timer[%{public}s] Cancel Task[%{public}u]", timerId.c_str(),
156 taskId_[timerId]);
157 FFRTUtils::CancelTask(handleMap_[timerId], queue_);
158 handleMap_[timerId] = nullptr;
159 }
160 }
161 } // namespace MiscServices
162 } // namespace OHOS