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 "tm/cpu_task.h"
16 #include <securec.h>
17 #include "dfx/trace_record/ffrt_trace_record.h"
18 #include "dm/dependence_manager.h"
19 
20 #include "internal_inc/osal.h"
21 #include "tm/task_factory.h"
22 #include "util/slab.h"
23 
24 namespace {
25 const int TSD_SIZE = 128;
26 }
27 
28 namespace ffrt {
SetQos(const QoS& newQos)29 void CPUEUTask::SetQos(const QoS& newQos)
30 {
31     if (newQos == qos_inherit) {
32         if (!this->IsRoot()) {
33             this->qos = parent->qos;
34         } else {
35             this->qos = QoS();
36         }
37         FFRT_LOGD("Change task %s QoS %d", label.c_str(), this->qos());
38     } else {
39         this->qos = newQos;
40     }
41 }
42 
FreeMem()43 void CPUEUTask::FreeMem()
44 {
45     BboxCheckAndFreeze();
46     PollerProxy::Instance().GetPoller(qos).ClearCachedEvents(this);
47 #ifdef FFRT_TASK_LOCAL_ENABLE
48     TaskTsdDeconstruct(this);
49 #endif
50     ffrt::TaskFactory::Free(this);
51 }
52 
Execute()53 void CPUEUTask::Execute()
54 {
55     FFRT_LOGD("Execute task[%lu], name[%s]", gid, label.c_str());
56     FFRTTraceRecord::TaskExecute(&(this->executeTime));
57     UpdateState(TaskState::RUNNING);
58     auto f = reinterpret_cast<ffrt_function_header_t*>(func_storage);
59     auto exp = ffrt::SkipStatus::SUBMITTED;
60     if (likely(__atomic_compare_exchange_n(&skipped, &exp, ffrt::SkipStatus::EXECUTED, 0,
61         __ATOMIC_ACQUIRE, __ATOMIC_RELAXED))) {
62         f->exec(f);
63     }
64     f->destroy(f);
65     FFRT_TASKDONE_MARKER(gid);
66     if (!USE_COROUTINE) {
67         this->UpdateState(ffrt::TaskState::EXITED);
68     } else {
69         this->coRoutine->isTaskDone = true;
70     }
71 }
72 
CPUEUTask(const task_attr_private *attr, CPUEUTask *parent, const uint64_t &id, const QoS &qos)73 CPUEUTask::CPUEUTask(const task_attr_private *attr, CPUEUTask *parent, const uint64_t &id,
74     const QoS &qos)
75     : parent(parent), rank(id), qos(qos)
76 {
77     fq_we.task = this;
78     if (attr && !attr->name_.empty()) {
79         label = attr->name_;
80     } else if (IsRoot()) {
81         label = "root";
82     } else if ((parent != nullptr) && parent->IsRoot()) {
83         label = "t" + std::to_string(rank);
84     } else {
85         label = parent->label + "." + std::to_string(rank);
86     }
87     if (!IsRoot()) {
88         FFRT_SUBMIT_MARKER(label, gid);
89     }
90 
91     taskLocal = false;
92     tsd = nullptr;
93     if (attr && attr->taskLocal_) {
94         tsd = (void **)malloc(TSD_SIZE * sizeof(void *));
95         if (unlikely(tsd == nullptr)) {
96             FFRT_LOGE("task local malloc tsd failed");
97             return;
98         }
99         memset_s(tsd, TSD_SIZE * sizeof(void *), 0, TSD_SIZE * sizeof(void *));
100         taskLocal = attr->taskLocal_;
101     }
102     if (attr) {
103         stack_size = std::max(attr->stackSize_, MIN_STACK_SIZE);
104     }
105     FFRT_LOGD("create task name:%s gid=%lu taskLocal:%d", label.c_str(), gid, taskLocal);
106 }
107 } /* namespace ffrt */