• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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