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 FFRT_TASK_STATE_HPP
17 #define FFRT_TASK_STATE_HPP
18 
19 #include <array>
20 #include <string_view>
21 #include <functional>
22 #include <mutex>
23 #include <shared_mutex>
24 #include <chrono>
25 
26 namespace ffrt {
27 class CPUEUTask;
28 
29 class TaskState {
30 public:
31     enum State { PENDING, READY, RUNNING, BLOCKED, EXITED, MAX };
32 
33     using Op = typename std::function<bool(CPUEUTask*)>;
34 
35     TaskState() = default;
36 
37     TaskState(const TaskState&) = delete;
38     TaskState(TaskState&&) = delete;
39 
40     TaskState& operator=(const TaskState&) = delete;
41     TaskState& operator=(TaskState&&) = delete;
42 
43     bool operator==(State state) const
44     {
45         return this->curState == state;
46     }
47 
48     bool operator!=(State state) const
49     {
50         return this->curState != state;
51     }
52 
operator()53     State operator()() const
54     {
55         return curState;
56     }
57 
CurState()58     State CurState() const
59     {
60         return curState;
61     }
62 
SetCurState(State state)63     void SetCurState(State state)
64     {
65         curState = state;
66     }
67 
PreState()68     State PreState() const
69     {
70         return preState;
71     }
72 
String()73     const char* String() const
74     {
75         return String(curState);
76     }
77 
WaitingTime()78     uint64_t WaitingTime() const
79     {
80 #if defined(TRACE_TASKSTAT_LOG_ENABLE) && (TRACE_TASKSTAT_LOG_ENABLE == 1)
81         return stat.WaitingTime();
82 #else
83         return 0;
84 #endif
85     }
86 
RunningTime()87     uint64_t RunningTime() const
88     {
89 #if defined(TRACE_TASKSTAT_LOG_ENABLE) && (TRACE_TASKSTAT_LOG_ENABLE == 1)
90         return stat.RunningTime();
91 #else
92         return 0;
93 #endif
94     }
95 
RegisterOps(State state,Op && op)96     static void RegisterOps(State state, Op&& op)
97     {
98         ops[static_cast<size_t>(state)] = op;
99     }
100 
101     static int OnTransition(State state, CPUEUTask* task, Op&& op = Op());
102 
String(State state)103     static const char* String(State state)
104     {
105         static const char* m[] = {"PENDING", "READY", "RUNNING", "BLOCKED", "EXITED", "MAX"};
106 
107         return m[static_cast<size_t>(state)];
108     }
109 
110 private:
111     class TaskStateStat {
112     public:
113         uint64_t WaitingTime() const;
114         uint64_t RunningTime() const;
115 
116         inline void Count(CPUEUTask* task);
117 
118     private:
119         inline void Count(TaskState::State state);
120         inline uint64_t CalcDuration(TaskState::State pre, TaskState::State cur) const;
121 
122         std::array<std::chrono::steady_clock::time_point, static_cast<size_t>(TaskState::State::MAX)> timepoint;
123     };
124 
125 #if defined(TRACE_TASKSTAT_LOG_ENABLE) && (TRACE_TASKSTAT_LOG_ENABLE == 1)
126     TaskStateStat stat;
127 #endif
128 
129     State curState = PENDING;
130     State preState = PENDING;
131 
132     static std::array<Op, static_cast<size_t>(TaskState::MAX)> ops;
133 };
134 } // namespace ffrt
135 
136 #endif
137