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 #include "queue_task.h"
16 #include "ffrt_trace.h"
17 #include "dfx/log/ffrt_log_api.h"
18 #include "c/task.h"
19 #include "util/slab.h"
20
21 namespace ffrt {
QueueTask(QueueHandler* handler, const task_attr_private* attr, bool insertHead)22 QueueTask::QueueTask(QueueHandler* handler, const task_attr_private* attr, bool insertHead)
23 : handler_(handler), insertHead_(insertHead)
24 {
25 type = ffrt_queue_task;
26 if (handler) {
27 if (attr) {
28 label = handler->GetName() + "_" + attr->name_ + "_" + std::to_string(gid);
29 } else {
30 label = handler->GetName() + "_" + std::to_string(gid);
31 }
32 }
33
34 fq_we.task = reinterpret_cast<CPUEUTask*>(this);
35 uptime_ = static_cast<uint64_t>(std::chrono::duration_cast<std::chrono::microseconds>(
36 std::chrono::steady_clock::now().time_since_epoch()).count());
37
38 if (attr) {
39 delay_ = attr->delay_;
40 qos_ = attr->qos_;
41 uptime_ += delay_;
42 prio_ = attr->prio_;
43 stack_size = std::max(attr->stackSize_, MIN_STACK_SIZE);
44 }
45
46 FFRT_LOGD("ctor task [gid=%llu], delay=%lluus, type=%lu, prio=%d", gid, delay_, type, prio_);
47 }
48
~QueueTask()49 QueueTask::~QueueTask()
50 {
51 FFRT_LOGD("dtor task [gid=%llu]", gid);
52 }
53
Destroy()54 void QueueTask::Destroy()
55 {
56 // release user func
57 auto f = reinterpret_cast<ffrt_function_header_t*>(func_storage);
58 f->destroy(f);
59 // free serial task object
60 DecDeleteRef();
61 }
62
Notify()63 void QueueTask::Notify()
64 {
65 FFRT_SERIAL_QUEUE_TASK_FINISH_MARKER(gid);
66 std::unique_lock lock(mutex_);
67 isFinished_.store(true);
68 if (onWait_) {
69 waitCond_.notify_all();
70 }
71 }
72
Execute()73 void QueueTask::Execute()
74 {
75 FFRT_LOGD("Execute stask[%lu], name[%s]", gid, label.c_str());
76 if (isFinished_.load()) {
77 FFRT_LOGE("task [gid=%llu] is complete, no need to execute again", gid);
78 return;
79 }
80
81 handler_->Dispatch(this);
82 FFRT_TASKDONE_MARKER(gid);
83 }
84
Wait()85 void QueueTask::Wait()
86 {
87 std::unique_lock lock(mutex_);
88 onWait_ = true;
89 while (!isFinished_.load()) {
90 waitCond_.wait(lock);
91 }
92 }
93
FreeMem()94 void QueueTask::FreeMem()
95 {
96 SimpleAllocator<QueueTask>::FreeMem(this);
97 }
98
GetQueueId() const99 uint32_t QueueTask::GetQueueId() const
100 {
101 return handler_->GetQueueId();
102 }
103 } // namespace ffrt
104