• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #ifndef SRC_TRACE_PROCESSOR_IMPORTERS_FTRACE_THREAD_STATE_TRACKER_H_
17 #define SRC_TRACE_PROCESSOR_IMPORTERS_FTRACE_THREAD_STATE_TRACKER_H_
18 
19 #include "src/trace_processor/storage/trace_storage.h"
20 #include "src/trace_processor/types/destructible.h"
21 #include "src/trace_processor/types/trace_processor_context.h"
22 
23 namespace perfetto {
24 namespace trace_processor {
25 
26 // Responsible for filling the Thread State table by analysing sched switches,
27 // waking events and blocking reasons.
28 class ThreadStateTracker : public Destructible {
29  public:
30   explicit ThreadStateTracker(TraceStorage*);
31   ThreadStateTracker(const ThreadStateTracker&) = delete;
32   ThreadStateTracker& operator=(const ThreadStateTracker&) = delete;
33   ~ThreadStateTracker() override;
GetOrCreate(TraceProcessorContext * context)34   static ThreadStateTracker* GetOrCreate(TraceProcessorContext* context) {
35     if (!context->thread_state_tracker) {
36       context->thread_state_tracker.reset(
37           new ThreadStateTracker(context->storage.get()));
38     }
39     return static_cast<ThreadStateTracker*>(
40         context->thread_state_tracker.get());
41   }
42 
43   // Will cause addition of state and update of the previous state for next_utid
44   // and prev_utid.
45   void PushSchedSwitchEvent(int64_t event_ts,
46                             uint32_t cpu,
47                             UniqueTid prev_utid,
48                             StringId prev_state,
49                             UniqueTid next_utid);
50 
51   // Will add a runnable state for utid and close the previously blocked one.
52   void PushWakingEvent(int64_t event_ts, UniqueTid utid, UniqueTid waker_utid);
53 
54   // Will add a runnable state for utid. For a new task there are no previous
55   // states to close.
56   void PushNewTaskEvent(int64_t event_ts, UniqueTid utid, UniqueTid waker_utid);
57 
58   // Updates the current blocked state for utid with blocked reason.
59   void PushBlockedReason(UniqueTid utid,
60                          std::optional<bool> io_wait,
61                          std::optional<StringId> blocked_function);
62 
63  private:
64   void AddOpenState(int64_t ts,
65                     UniqueTid utid,
66                     StringId state,
67                     std::optional<uint32_t> cpu = std::nullopt,
68                     std::optional<UniqueTid> waker_utid = std::nullopt);
69   void ClosePendingState(int64_t end_ts, UniqueTid utid, bool data_loss);
70 
71   bool IsRunning(StringId state);
72   bool IsBlocked(StringId state);
73   bool IsRunnable(StringId state);
74 
HasPreviousRowNumbersForUtid(UniqueTid utid)75   bool HasPreviousRowNumbersForUtid(UniqueTid utid) {
76     return utid < prev_row_numbers_for_thread_.size() &&
77            prev_row_numbers_for_thread_[utid].has_value();
78   }
79 
RowNumToRef(tables::ThreadStateTable::RowNumber row_number)80   tables::ThreadStateTable::RowReference RowNumToRef(
81       tables::ThreadStateTable::RowNumber row_number) {
82     return row_number.ToRowReference(storage_->mutable_thread_state_table());
83   }
84 
85   TraceStorage* const storage_;
86 
87   // Strings
88   StringId running_string_id_;
89   StringId runnable_string_id_;
90 
91   struct RelatedRows {
92     std::optional<tables::ThreadStateTable::RowNumber> last_blocked_row;
93     tables::ThreadStateTable::RowNumber last_row;
94   };
95 
96   std::vector<std::optional<RelatedRows>> prev_row_numbers_for_thread_;
97 };
98 }  // namespace trace_processor
99 }  // namespace perfetto
100 
101 #endif  // SRC_TRACE_PROCESSOR_IMPORTERS_FTRACE_THREAD_STATE_TRACKER_H_
102