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 #include "sched/task_state.h"
17 #include "sched/task_manager.h"
18 #include "dfx/log/ffrt_log_api.h"
19 #include "sched/scheduler.h"
20
21 namespace ffrt {
22 std::array<TaskState::Op, static_cast<size_t>(TaskState::MAX)> TaskState::ops;
23
OnTransition(State state,CPUEUTask * task,Op && op)24 int TaskState::OnTransition(State state, CPUEUTask* task, Op&& op)
25 {
26 if (task == nullptr) {
27 FFRT_LOGE("task nullptr");
28 return -1;
29 }
30 if (task->IsRoot()) {
31 FFRT_LOGD("task root no state transition");
32 return 0;
33 }
34
35 if (task->state == TaskState::EXITED) {
36 FFRT_LOGE("task[%s] have finished", task->label.c_str());
37 return -1;
38 }
39
40 task->state.preState = task->state.curState;
41 task->state.curState = state;
42
43 FFRT_LOGD(
44 "task(%s) status: %s -=> %s ", task->label.c_str(), String(task->state.preState), String(task->state.curState));
45
46 #if (TASKSTAT_LOG_ENABLE == 1)
47 task->state.stat.Count(task);
48 #endif
49
50 if (ops[static_cast<size_t>(state)] &&
51 !ops[static_cast<size_t>(state)](task)) {
52 return -1;
53 }
54
55 if (op && !op(task)) {
56 return -1;
57 }
58
59 return 0;
60 }
61
WaitingTime() const62 uint64_t TaskState::TaskStateStat::WaitingTime() const
63 {
64 return CalcDuration(TaskState::READY, TaskState::RUNNING);
65 }
66
RunningTime() const67 uint64_t TaskState::TaskStateStat::RunningTime() const
68 {
69 return CalcDuration(TaskState::RUNNING, TaskState::EXITED);
70 }
71
Count(CPUEUTask * task)72 void TaskState::TaskStateStat::Count(CPUEUTask* task)
73 {
74 Count(task->state.CurState());
75 TaskManager::Instance().TaskStateCount(task);
76 }
77
Count(State state)78 void TaskState::TaskStateStat::Count(State state)
79 {
80 size_t index = static_cast<size_t>(state);
81 switch (state) {
82 case TaskState::READY:
83 if (timepoint[index].time_since_epoch() == std::chrono::steady_clock::duration::zero()) {
84 timepoint[index] = std::chrono::steady_clock::now();
85 }
86 break;
87 case TaskState::MAX:
88 break;
89 default:
90 timepoint[index] = std::chrono::steady_clock::now();
91 break;
92 }
93 }
94
CalcDuration(State pre,State cur) const95 uint64_t TaskState::TaskStateStat::CalcDuration(State pre, State cur) const
96 {
97 return timepoint[static_cast<size_t>(cur)].time_since_epoch() == std::chrono::steady_clock::duration::zero() ?
98 0 :
99 std::chrono::duration_cast<std::chrono::microseconds>(
100 timepoint[static_cast<size_t>(cur)] - timepoint[static_cast<size_t>(pre)])
101 .count();
102 }
103 } // namespace ffrt
104