• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "tm/task_factory.h"
21 
22 namespace {
23 constexpr uint64_t MIN_SCHED_TIMEOUT = 100000; // 0.1s
24 }
25 namespace ffrt {
QueueTask(QueueHandler * handler,const task_attr_private * attr,bool insertHead)26 QueueTask::QueueTask(QueueHandler* handler, const task_attr_private* attr, bool insertHead)
27     : handler_(handler), insertHead_(insertHead)
28 {
29     type = ffrt_queue_task;
30     if (handler) {
31         if (attr) {
32             label = handler->GetName() + "_" + attr->name_ + "_" + std::to_string(gid);
33         } else {
34             label = handler->GetName() + "_" + std::to_string(gid);
35         }
36     }
37 
38     fq_we.task = reinterpret_cast<CPUEUTask*>(this);
39     uptime_ = static_cast<uint64_t>(std::chrono::duration_cast<std::chrono::microseconds>(
40         std::chrono::steady_clock::now().time_since_epoch()).count());
41 
42     if (attr) {
43         delay_ = attr->delay_;
44         qos_ = attr->qos_;
45         uptime_ += delay_;
46         prio_ = attr->prio_;
47         stack_size = std::max(attr->stackSize_, MIN_STACK_SIZE);
48         if (delay_ && attr->timeout_) {
49             FFRT_LOGW("task [gid=%llu] not support delay and timeout at the same time, timeout ignored", gid);
50         } else if (attr->timeout_) {
51             schedTimeout_ = std::max(attr->timeout_, MIN_SCHED_TIMEOUT); // min 0.1s
52         }
53     }
54 
55     FFRT_LOGD("ctor task [gid=%llu], delay=%lluus, type=%lu, prio=%d, timeout=%luus", gid, delay_, type, prio_,
56         schedTimeout_);
57 }
58 
~QueueTask()59 QueueTask::~QueueTask()
60 {
61     FFRT_LOGD("dtor task [gid=%llu]", gid);
62 }
63 
Destroy()64 void QueueTask::Destroy()
65 {
66     // release user func
67     auto f = reinterpret_cast<ffrt_function_header_t*>(func_storage);
68     f->destroy(f);
69     // free serial task object
70     DecDeleteRef();
71 }
72 
Notify()73 void QueueTask::Notify()
74 {
75     std::unique_lock lock(mutex_);
76     isFinished_.store(true);
77     if (onWait_) {
78         waitCond_.notify_all();
79     }
80 }
81 
Execute()82 void QueueTask::Execute()
83 {
84     IncDeleteRef();
85     FFRT_LOGD("Execute stask[%lu], name[%s]", gid, label.c_str());
86     if (isFinished_.load()) {
87         FFRT_LOGE("task [gid=%llu] is complete, no need to execute again", gid);
88         DecDeleteRef();
89         return;
90     }
91 
92     handler_->Dispatch(this);
93     FFRT_TASKDONE_MARKER(gid);
94     DecDeleteRef();
95 }
96 
Wait()97 void QueueTask::Wait()
98 {
99     std::unique_lock lock(mutex_);
100     onWait_ = true;
101     while (!isFinished_.load()) {
102         waitCond_.wait(lock);
103     }
104 }
105 
FreeMem()106 void QueueTask::FreeMem()
107 {
108     TaskFactory<QueueTask>::Free(this);
109 }
110 
GetQueueId() const111 uint32_t QueueTask::GetQueueId() const
112 {
113     return handler_->GetQueueId();
114 }
115 } // namespace ffrt
116