• 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 "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