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 
16 #ifndef _SCPU_TASK_H_
17 #define _SCPU_TASK_H_
18 
19 #include "tm/cpu_task.h"
20 
21 namespace ffrt {
22 class SCPUEUTask : public CPUEUTask {
23 public:
24     SCPUEUTask(const task_attr_private *attr, CPUEUTask *parent, const uint64_t &id, const QoS &qos = QoS());
25     std::unordered_set<VersionCtx*> ins;
26     std::unordered_set<VersionCtx*> outs;
27 
28     std::mutex denpenceStatusLock;
29     Denpence denpenceStatus {Denpence::DEPENCE_INIT};
30 
31     union {
32         std::atomic_uint64_t submitDep; // dependency refcnt during task submit
33         std::atomic_uint64_t waitDep; // dependency refcnt during task execute when wait api called
34     } dataRefCnt {0};
35     std::atomic_uint64_t childRefCnt {0}; // unfinished children refcnt
36 
IncDepRef()37     inline void IncDepRef()
38     {
39         ++dataRefCnt.submitDep;
40     }
41     void DecDepRef();
42 
IncChildRef()43     inline void IncChildRef()
44     {
45         ++(static_cast<SCPUEUTask*>(parent)->childRefCnt);
46     }
47     void DecChildRef();
48 
IncWaitDataRef()49     inline void IncWaitDataRef()
50     {
51         ++dataRefCnt.waitDep;
52     }
53     void DecWaitDataRef();
54     void MultiDepenceAdd(Denpence depType);
55     void RecycleTask() override;
56 };
57 
58 class RootTask : public SCPUEUTask {
59 public:
60     RootTask(const task_attr_private* attr, SCPUEUTask* parent, const uint64_t& id,
61         const QoS& qos = QoS()) : SCPUEUTask(attr, parent, id, qos)
62     {
63     }
64 public:
65     bool thread_exit = false;
66 };
67 
68 class RootTaskCtxWrapper {
69 public:
RootTaskCtxWrapper()70     RootTaskCtxWrapper()
71     {
72         task_attr_private task_attr;
73         root = new RootTask{&task_attr, nullptr, 0};
74     }
~RootTaskCtxWrapper()75     ~RootTaskCtxWrapper()
76     {
77         std::unique_lock<decltype(root->mutex_)> lck(root->mutex_);
78         if (root->childRefCnt == 0) {
79             lck.unlock();
80             delete root;
81         } else {
82             root->thread_exit = true;
83         }
84     }
Root()85     CPUEUTask* Root()
86     {
87         return root;
88     }
89 private:
90     RootTask *root = nullptr;
91 };
92 } /* namespace ffrt */
93 #endif
94