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