• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 "cpu_filter.h"
17 #include "process_filter.h"
18 
19 namespace SysTuning {
20 namespace TraceStreamer {
CpuFilter(TraceDataCache * dataCache,const TraceStreamerFilters * filter)21 CpuFilter::CpuFilter(TraceDataCache* dataCache, const TraceStreamerFilters* filter) : FilterBase(dataCache, filter) {}
22 CpuFilter::~CpuFilter() = default;
InsertSwitchEvent(uint64_t ts,uint64_t cpu,uint64_t prevPid,uint64_t prevPior,uint64_t prevState,uint64_t nextPid,uint64_t nextPior)23 void CpuFilter::InsertSwitchEvent(uint64_t ts,
24                                   uint64_t cpu,
25                                   uint64_t prevPid,
26                                   uint64_t prevPior,
27                                   uint64_t prevState,
28                                   uint64_t nextPid,
29                                   uint64_t nextPior)
30 {
31     auto index = traceDataCache_->GetSchedSliceData()->AppendSchedSlice(ts, 0, cpu, nextPid, 0, nextPior);
32 
33     auto prevTidOnCpu = cpuToRowSched_.find(cpu);
34     if (prevTidOnCpu != cpuToRowSched_.end()) {
35         traceDataCache_->GetSchedSliceData()->Update(prevTidOnCpu->second, ts, prevState, prevPior);
36         cpuToRowSched_.at(cpu) = index;
37     } else {
38         cpuToRowSched_.insert(std::make_pair(cpu, index));
39     }
40 
41     if (nextPid) {
42         CheckWakeupEvent(nextPid);
43         auto lastRow = RowOfInternalTidInStateTable(nextPid);
44         if (lastRow != INVALID_UINT64) {
45             traceDataCache_->GetThreadStateData()->UpdateDuration(static_cast<TableRowId>(lastRow), ts);
46         }
47         index =
48             traceDataCache_->GetThreadStateData()->AppendThreadState(ts, INVALID_TIME, cpu, nextPid, TASK_RUNNING);
49         RemberInternalTidInStateTable(nextPid, index, TASK_RUNNING);
50         if (cpuToRowThreadState_.find(cpu) == cpuToRowThreadState_.end()) {
51             cpuToRowThreadState_.insert(std::make_pair(cpu, index));
52         } else {
53             cpuToRowThreadState_.at(cpu) = index;
54         }
55     }
56 
57     if (prevPid) {
58         CheckWakeupEvent(prevPid);
59         auto lastRow = RowOfInternalTidInStateTable(prevPid);
60         if (lastRow != INVALID_UINT64) {
61             traceDataCache_->GetThreadStateData()->UpdateDuration(static_cast<TableRowId>(lastRow), ts);
62             streamFilters_->processFilter_->AddCpuStateCount(prevPid);
63             auto thread = traceDataCache_->GetThreadData(prevPid);
64             if (thread){
65                 thread->switchCount_ = 1;
66             }
67         }
68         auto temp = traceDataCache_->GetThreadStateData()->AppendThreadState(ts, INVALID_TIME, INVALID_CPU,
69                                                                              prevPid, prevState);
70         RemberInternalTidInStateTable(prevPid, temp, prevState);
71     }
72 }
InsertProcessExitEvent(uint64_t ts,uint64_t cpu,uint64_t pid)73 bool CpuFilter::InsertProcessExitEvent(uint64_t ts, uint64_t cpu, uint64_t pid)
74 {
75     UNUSED(cpu);
76     auto thread = traceDataCache_->GetThreadData(static_cast<InternalTid>(pid));
77     if (thread) {
78         thread->endT_ = ts;
79         return true;
80     }
81     return false;
82 }
83 
InsertProcessFreeEvent(uint64_t ts,uint64_t pid)84 bool CpuFilter::InsertProcessFreeEvent(uint64_t ts, uint64_t pid)
85 {
86     auto thread = traceDataCache_->GetThreadData(static_cast<InternalTid>(pid));
87     if (thread) {
88         thread->endT_ = ts;
89         return true;
90     }
91     return false;
92 }
93 
Finish() const94 void CpuFilter::Finish() const
95 {
96     auto size = traceDataCache_->ThreadSize();
97     for (auto i = 0; i < size; i++) {
98         auto thread = traceDataCache_->GetThreadData(i);
99         if (thread->internalPid_ != INVALID_UINT32) {
100             traceDataCache_->GetProcessData(thread->internalPid_)->threadCount_++;
101             traceDataCache_->GetProcessData(thread->internalPid_)->cpuStatesCount_ += thread->cpuStatesCount_;
102             traceDataCache_->GetProcessData(thread->internalPid_)->sliceSize_ += thread->sliceSize_;
103             traceDataCache_->GetProcessData(thread->internalPid_)->switchCount_ += thread->switchCount_;
104             continue;
105         }
106         auto ipid = traceDataCache_->AppendNewProcessData(
107             thread->tid_, traceDataCache_->GetDataFromDict(thread->nameIndex_), thread->startT_);
108         thread->internalPid_ = ipid;
109         traceDataCache_->GetProcessData(thread->internalPid_)->threadCount_++;
110         traceDataCache_->GetProcessData(thread->internalPid_)->cpuStatesCount_ += thread->cpuStatesCount_;
111         traceDataCache_->GetProcessData(thread->internalPid_)->sliceSize_ += thread->sliceSize_;
112         traceDataCache_->GetProcessData(thread->internalPid_)->switchCount_ += thread->switchCount_;
113     }
114     auto threadState = traceDataCache_->GetConstThreadStateData();
115     size = threadState.Size();
116     auto rowData = threadState.ItidsData();
117     for (auto i = 0; i < size; i++) {
118         auto thread = traceDataCache_->GetThreadData(rowData[i]);
119         if (thread->internalPid_ == INVALID_UINT32) {
120             continue;
121         }
122         auto process = traceDataCache_->GetProcessData(thread->internalPid_);
123         traceDataCache_->GetThreadStateData()->UpdateTidAndPid(i, thread->tid_, process->pid_);
124     }
125     auto slice = traceDataCache_->GetConstSchedSliceData();
126     size = slice.Size();
127     for (auto i = 0; i < size; i++) {
128         traceDataCache_->GetSchedSliceData()->AppendInternalPid(
129             traceDataCache_->GetThreadData(slice.InternalTidsData()[i])->internalPid_);
130     }
131     traceDataCache_->OperateDatabase(
132         "update thread set ipid = \
133         (select id from process where \
134         thread.tid = process.pid) where thread.ipid is null;");
135 }
Clear()136 void CpuFilter::Clear()
137 {
138     cpuToRowThreadState_.clear();
139     cpuToRowSched_.clear();
140     lastWakeUpMsg_.clear();
141     internalTidToRowThreadState_.clear();
142 }
InsertWakeupEvent(uint64_t ts,uint64_t internalTid)143 void CpuFilter::InsertWakeupEvent(uint64_t ts, uint64_t internalTid)
144 {
145     uint64_t lastrow = RowOfInternalTidInStateTable(internalTid);
146     auto lastState = StateOfInternalTidInStateTable(internalTid);
147     if (lastState == TASK_RUNNING) {
148         return;
149     }
150     if (lastrow != INVALID_UINT64) {
151         traceDataCache_->GetThreadStateData()->UpdateDuration(static_cast<TableRowId>(lastrow), ts);
152     }
153     auto index = traceDataCache_->GetThreadStateData()->AppendThreadState(ts, INVALID_TIME, INVALID_CPU,
154                                                                           internalTid, TASK_RUNNABLE);
155     RemberInternalTidInStateTable(internalTid, index, TASK_RUNNABLE);
156 }
RemberInternalTidInStateTable(uint64_t uid,uint64_t row,uint64_t state)157 uint64_t CpuFilter::RemberInternalTidInStateTable(uint64_t uid, uint64_t row, uint64_t state)
158 {
159     if (internalTidToRowThreadState_.find(uid) != internalTidToRowThreadState_.end()) {
160         internalTidToRowThreadState_.at(uid) = TPthread{row, state};
161     } else {
162         internalTidToRowThreadState_.insert(std::make_pair(uid, TPthread{row, state}));
163     }
164     return 0;
165 }
RowOfInternalTidInStateTable(uint64_t uid) const166 uint64_t CpuFilter::RowOfInternalTidInStateTable(uint64_t uid) const
167 {
168     auto row = internalTidToRowThreadState_.find(uid);
169     if (row != internalTidToRowThreadState_.end()) {
170         return (*row).second.row_;
171     }
172     return INVALID_UINT64;
173 }
174 
StateOfInternalTidInStateTable(uint64_t uid) const175 uint64_t CpuFilter::StateOfInternalTidInStateTable(uint64_t uid) const
176 {
177     auto row = internalTidToRowThreadState_.find(uid);
178     if (row != internalTidToRowThreadState_.end()) {
179         return (*row).second.state_;
180     }
181     return TASK_INVALID;
182 }
183 
CheckWakeupEvent(uint64_t internalTid)184 void CpuFilter::CheckWakeupEvent(uint64_t internalTid)
185 {
186     return;
187 }
188 } // namespace TraceStreamer
189 } // namespace SysTuning
190