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 return 0;
32 }
33
34 if (task->state == TaskState::EXITED) {
35 FFRT_LOGE("task[%s] have finished", task->label.c_str());
36 return -1;
37 }
38
39 task->state.preState = task->state.curState;
40 task->state.curState = state;
41
42 #if (TASKSTAT_LOG_ENABLE == 1)
43 task->state.stat.Count(task);
44 #endif
45
46 if (ops[static_cast<size_t>(state)] &&
47 !ops[static_cast<size_t>(state)](task)) {
48 return -1;
49 }
50
51 if (op && !op(task)) {
52 return -1;
53 }
54
55 return 0;
56 }
57
WaitingTime() const58 uint64_t TaskState::TaskStateStat::WaitingTime() const
59 {
60 return CalcDuration(TaskState::READY, TaskState::RUNNING);
61 }
62
RunningTime() const63 uint64_t TaskState::TaskStateStat::RunningTime() const
64 {
65 return CalcDuration(TaskState::RUNNING, TaskState::EXITED);
66 }
67
Count(CPUEUTask * task)68 void TaskState::TaskStateStat::Count(CPUEUTask* task)
69 {
70 Count(task->state.CurState());
71 TaskManager::Instance().TaskStateCount(task);
72 }
73
Count(State state)74 void TaskState::TaskStateStat::Count(State state)
75 {
76 size_t index = static_cast<size_t>(state);
77 switch (state) {
78 case TaskState::READY:
79 if (timepoint[index].time_since_epoch() == std::chrono::steady_clock::duration::zero()) {
80 timepoint[index] = std::chrono::steady_clock::now();
81 }
82 break;
83 case TaskState::MAX:
84 break;
85 default:
86 timepoint[index] = std::chrono::steady_clock::now();
87 break;
88 }
89 }
90
CalcDuration(State pre,State cur) const91 uint64_t TaskState::TaskStateStat::CalcDuration(State pre, State cur) const
92 {
93 return timepoint[static_cast<size_t>(cur)].time_since_epoch() == std::chrono::steady_clock::duration::zero() ?
94 0 :
95 std::chrono::duration_cast<std::chrono::microseconds>(
96 timepoint[static_cast<size_t>(cur)] - timepoint[static_cast<size_t>(pre)])
97 .count();
98 }
99 } // namespace ffrt
100