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