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_TRACED_PROBES_FTRACE_FTRACE_THREAD_SYNC_H_ 18 #define SRC_TRACED_PROBES_FTRACE_FTRACE_THREAD_SYNC_H_ 19 20 #include <stdint.h> 21 22 #include <bitset> 23 #include <condition_variable> 24 #include <mutex> 25 26 #include "perfetto/base/utils.h" 27 #include "perfetto/base/weak_ptr.h" 28 29 namespace perfetto { 30 31 namespace base { 32 class TaskRunner; 33 } // namespace base 34 35 class FtraceController; 36 37 // This struct is accessed both by the FtraceController on the main thread and 38 // by the CpuReader(s) on their worker threads. It is used to synchronize 39 // handshakes between FtraceController and CpuReader(s). There is only *ONE* 40 // instance of this state, owned by the FtraceController and shared with all 41 // CpuReader(s). 42 struct FtraceThreadSync { FtraceThreadSyncFtraceThreadSync43 explicit FtraceThreadSync(base::TaskRunner* tr) : task_runner(tr) {} 44 45 // These variables are set upon initialization time and never changed. Can 46 // be accessed outside of the |mutex|. 47 base::TaskRunner* const task_runner; // Where the FtraceController lives. 48 base::WeakPtr<FtraceController> trace_controller_weak; 49 50 // Mutex & condition variable shared by main thread and all per-cpu workers. 51 // All fields below are read and modified holding |mutex|. 52 std::mutex mutex; 53 54 // Used to suspend CpuReader(s) between cycles and to wake them up at the 55 // same time. 56 std::condition_variable cond; 57 58 // |cmd| and |cmd_id| are written only by FtraceController. On each cycle, 59 // FtraceController increases the |cmd_id| monotonic counter and issues the 60 // new command. |cmd_id| is used by the CpuReader(s) to distinguish a new 61 // command from a spurious wakeup. 62 enum Cmd { kRun = 0, kFlush, kQuit }; 63 Cmd cmd = kRun; 64 uint64_t cmd_id = 0; 65 66 // This bitmap is cleared by the FtraceController before every kRun command 67 // and is optionally set by OnDataAvailable() if a CpuReader did fetch any 68 // ftrace data during the read cycle. 69 std::bitset<base::kMaxCpus> cpus_to_drain; 70 71 // This bitmap is cleared by the FtraceController before issuing a kFlush 72 // command and set by each CpuReader after they have completed the flush. 73 std::bitset<base::kMaxCpus> flush_acks; 74 }; 75 76 } // namespace perfetto 77 78 #endif // SRC_TRACED_PROBES_FTRACE_FTRACE_THREAD_SYNC_H_ 79