• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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 
17 #ifndef SRC_FTRACE_READER_FTRACE_CONFIG_MUXER_H_
18 #define SRC_FTRACE_READER_FTRACE_CONFIG_MUXER_H_
19 
20 #include "perfetto/ftrace_reader/ftrace_controller.h"
21 #include "src/ftrace_reader/ftrace_procfs.h"
22 
23 namespace perfetto {
24 
25 // Ftrace is a bunch of globaly modifiable persistent state.
26 // Given a number of FtraceConfig's we need to find the best union of all
27 // the settings to make eveyone happy while also watching out for anybody
28 // messing with the ftrace settings at the same time as us.
29 
30 // Specifically FtraceConfigMuxer takes in a *requested* FtraceConfig
31 // (|RequestConfig|), makes a best effort attempt to modify the ftrace
32 // debugfs files to honor those settings without interupting other perfetto
33 // traces already in progress or other users of ftrace, then returns an
34 // FtraceConfigId representing that config or zero on failure.
35 
36 // To see which settings we actually managed to set you can call |GetConfig|
37 // and when you are finished with a config you can signal that with
38 // |RemoveConfig|.
39 class FtraceConfigMuxer {
40  public:
41   // The FtraceConfigMuxer and ProtoTranslationTable
42   // should outlive this instance.
43   FtraceConfigMuxer(FtraceProcfs* ftrace, const ProtoTranslationTable* table);
44   virtual ~FtraceConfigMuxer();
45 
46   // Ask FtraceConfigMuxer to adjust ftrace procfs settings to
47   // match the requested config. Returns an id to manage this
48   // config or zero on failure.
49   // This is best effort. FtraceConfigMuxer may not be able to adjust the
50   // buffer size right now. Events may be missing or there may be extra events
51   // (if you enable an atrace catagory we try to give you the matching events).
52   // If someone else is tracing we won't touch atrace (since it resets the
53   // buffer).
54   // To see the config you ended up with use |GetConfig|.
55   FtraceConfigId RequestConfig(const FtraceConfig& request);
56 
57   // Undo changes for the given config. Returns false iff the id is 0
58   // or already removed.
59   bool RemoveConfig(FtraceConfigId id);
60 
61   // public for testing
SetupClockForTesting(const FtraceConfig & request)62   void SetupClockForTesting(const FtraceConfig& request) {
63     SetupClock(request);
64   }
65 
66   const FtraceConfig* GetConfig(FtraceConfigId id);
67 
68  private:
69   struct FtraceState {
70     std::set<std::string> ftrace_events;
71     std::set<std::string> atrace_categories;
72     std::set<std::string> atrace_apps;
73     bool tracing_on = false;
74     bool atrace_on = false;
75     size_t cpu_buffer_size_pages = 0;
76   };
77 
78   FtraceConfigMuxer(const FtraceConfigMuxer&) = delete;
79   FtraceConfigMuxer& operator=(const FtraceConfigMuxer&) = delete;
80 
81   void SetupClock(const FtraceConfig& request);
82   void SetupBufferSize(const FtraceConfig& request);
83   void UpdateAtrace(const FtraceConfig& request);
84   void DisableAtrace();
85 
86   FtraceConfigId GetNextId();
87 
88   FtraceConfigId last_id_ = 1;
89   FtraceProcfs* ftrace_;
90   const ProtoTranslationTable* table_;
91 
92   FtraceState current_state_;
93   std::map<FtraceConfigId, FtraceConfig> configs_;
94 };
95 
96 std::set<std::string> GetFtraceEvents(const FtraceConfig& request,
97                                       const ProtoTranslationTable*);
98 size_t ComputeCpuBufferSizeInPages(size_t requested_buffer_size_kb);
99 
100 }  // namespace perfetto
101 
102 #endif  // SRC_FTRACE_READER_FTRACE_CONFIG_MUXER_H_
103