1484543d1Sopenharmony_ci/*
2484543d1Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
3484543d1Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4484543d1Sopenharmony_ci * you may not use this file except in compliance with the License.
5484543d1Sopenharmony_ci * You may obtain a copy of the License at
6484543d1Sopenharmony_ci *
7484543d1Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8484543d1Sopenharmony_ci *
9484543d1Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10484543d1Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11484543d1Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12484543d1Sopenharmony_ci * See the License for the specific language governing permissions and
13484543d1Sopenharmony_ci * limitations under the License.
14484543d1Sopenharmony_ci */
15484543d1Sopenharmony_ci#include "queue_task.h"
16484543d1Sopenharmony_ci#include "ffrt_trace.h"
17484543d1Sopenharmony_ci#include "dfx/log/ffrt_log_api.h"
18484543d1Sopenharmony_ci#include "c/task.h"
19484543d1Sopenharmony_ci#include "util/slab.h"
20484543d1Sopenharmony_ci
21484543d1Sopenharmony_cinamespace ffrt {
22484543d1Sopenharmony_ciQueueTask::QueueTask(QueueHandler* handler, const task_attr_private* attr, bool insertHead)
23484543d1Sopenharmony_ci    : handler_(handler), insertHead_(insertHead)
24484543d1Sopenharmony_ci{
25484543d1Sopenharmony_ci    type = ffrt_queue_task;
26484543d1Sopenharmony_ci    if (handler) {
27484543d1Sopenharmony_ci        if (attr) {
28484543d1Sopenharmony_ci            label = handler->GetName() + "_" + attr->name_ + "_" + std::to_string(gid);
29484543d1Sopenharmony_ci        } else {
30484543d1Sopenharmony_ci            label = handler->GetName() + "_" + std::to_string(gid);
31484543d1Sopenharmony_ci        }
32484543d1Sopenharmony_ci    }
33484543d1Sopenharmony_ci
34484543d1Sopenharmony_ci    fq_we.task = reinterpret_cast<CPUEUTask*>(this);
35484543d1Sopenharmony_ci    uptime_ = static_cast<uint64_t>(std::chrono::duration_cast<std::chrono::microseconds>(
36484543d1Sopenharmony_ci        std::chrono::steady_clock::now().time_since_epoch()).count());
37484543d1Sopenharmony_ci
38484543d1Sopenharmony_ci    if (attr) {
39484543d1Sopenharmony_ci        delay_ = attr->delay_;
40484543d1Sopenharmony_ci        qos_ = attr->qos_;
41484543d1Sopenharmony_ci        uptime_ += delay_;
42484543d1Sopenharmony_ci        prio_ = attr->prio_;
43484543d1Sopenharmony_ci        stack_size = std::max(attr->stackSize_, MIN_STACK_SIZE);
44484543d1Sopenharmony_ci    }
45484543d1Sopenharmony_ci
46484543d1Sopenharmony_ci    FFRT_LOGD("ctor task [gid=%llu], delay=%lluus, type=%lu, prio=%d", gid, delay_, type, prio_);
47484543d1Sopenharmony_ci}
48484543d1Sopenharmony_ci
49484543d1Sopenharmony_ciQueueTask::~QueueTask()
50484543d1Sopenharmony_ci{
51484543d1Sopenharmony_ci    FFRT_LOGD("dtor task [gid=%llu]", gid);
52484543d1Sopenharmony_ci}
53484543d1Sopenharmony_ci
54484543d1Sopenharmony_civoid QueueTask::Destroy()
55484543d1Sopenharmony_ci{
56484543d1Sopenharmony_ci    // release user func
57484543d1Sopenharmony_ci    auto f = reinterpret_cast<ffrt_function_header_t*>(func_storage);
58484543d1Sopenharmony_ci    f->destroy(f);
59484543d1Sopenharmony_ci    // free serial task object
60484543d1Sopenharmony_ci    DecDeleteRef();
61484543d1Sopenharmony_ci}
62484543d1Sopenharmony_ci
63484543d1Sopenharmony_civoid QueueTask::Notify()
64484543d1Sopenharmony_ci{
65484543d1Sopenharmony_ci    FFRT_SERIAL_QUEUE_TASK_FINISH_MARKER(gid);
66484543d1Sopenharmony_ci    std::unique_lock lock(mutex_);
67484543d1Sopenharmony_ci    isFinished_.store(true);
68484543d1Sopenharmony_ci    if (onWait_) {
69484543d1Sopenharmony_ci        waitCond_.notify_all();
70484543d1Sopenharmony_ci    }
71484543d1Sopenharmony_ci}
72484543d1Sopenharmony_ci
73484543d1Sopenharmony_civoid QueueTask::Execute()
74484543d1Sopenharmony_ci{
75484543d1Sopenharmony_ci    FFRT_LOGD("Execute stask[%lu], name[%s]", gid, label.c_str());
76484543d1Sopenharmony_ci    if (isFinished_.load()) {
77484543d1Sopenharmony_ci        FFRT_LOGE("task [gid=%llu] is complete, no need to execute again", gid);
78484543d1Sopenharmony_ci        return;
79484543d1Sopenharmony_ci    }
80484543d1Sopenharmony_ci
81484543d1Sopenharmony_ci    handler_->Dispatch(this);
82484543d1Sopenharmony_ci    FFRT_TASKDONE_MARKER(gid);
83484543d1Sopenharmony_ci}
84484543d1Sopenharmony_ci
85484543d1Sopenharmony_civoid QueueTask::Wait()
86484543d1Sopenharmony_ci{
87484543d1Sopenharmony_ci    std::unique_lock lock(mutex_);
88484543d1Sopenharmony_ci    onWait_ = true;
89484543d1Sopenharmony_ci    while (!isFinished_.load()) {
90484543d1Sopenharmony_ci        waitCond_.wait(lock);
91484543d1Sopenharmony_ci    }
92484543d1Sopenharmony_ci}
93484543d1Sopenharmony_ci
94484543d1Sopenharmony_civoid QueueTask::FreeMem()
95484543d1Sopenharmony_ci{
96484543d1Sopenharmony_ci    SimpleAllocator<QueueTask>::FreeMem(this);
97484543d1Sopenharmony_ci}
98484543d1Sopenharmony_ci
99484543d1Sopenharmony_ciuint32_t QueueTask::GetQueueId() const
100484543d1Sopenharmony_ci{
101484543d1Sopenharmony_ci    return handler_->GetQueueId();
102484543d1Sopenharmony_ci}
103484543d1Sopenharmony_ci} // namespace ffrt
104