1 // Copyright (C) 2019 The Android Open Source Project
2 //
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 // This file is automatically generated by gen_amalgamated. Do not edit.
16
17 // gen_amalgamated: predefined macros
18 #if !defined(GOOGLE_PROTOBUF_NO_RTTI)
19 #define GOOGLE_PROTOBUF_NO_RTTI
20 #endif
21 #if !defined(PERFETTO_IMPLEMENTATION)
22 #define PERFETTO_IMPLEMENTATION
23 #endif
24 #if !defined(GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER)
25 #define GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
26 #endif
27 #include "perfetto.h"
28 // gen_amalgamated begin source: src/base/android_utils.cc
29 // gen_amalgamated begin header: include/perfetto/ext/base/android_utils.h
30 /*
31 * Copyright (C) 2021 The Android Open Source Project
32 *
33 * Licensed under the Apache License, Version 2.0 (the "License");
34 * you may not use this file except in compliance with the License.
35 * You may obtain a copy of the License at
36 *
37 * http://www.apache.org/licenses/LICENSE-2.0
38 *
39 * Unless required by applicable law or agreed to in writing, software
40 * distributed under the License is distributed on an "AS IS" BASIS,
41 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
42 * See the License for the specific language governing permissions and
43 * limitations under the License.
44 */
45
46 #ifndef INCLUDE_PERFETTO_EXT_BASE_ANDROID_UTILS_H_
47 #define INCLUDE_PERFETTO_EXT_BASE_ANDROID_UTILS_H_
48
49 #include <string>
50
51 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
52
53 namespace perfetto {
54 namespace base {
55
56 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
57
58 // Returns the value of the Android system property named `name`. If the
59 // property does not exist, returns an empty string (a non-existing property is
60 // the same as a property with an empty value for this API).
61 std::string GetAndroidProp(const char* name);
62
63 #endif // PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
64
65 } // namespace base
66 } // namespace perfetto
67
68 #endif // INCLUDE_PERFETTO_EXT_BASE_ANDROID_UTILS_H_
69 /*
70 * Copyright (C) 2021 The Android Open Source Project
71 *
72 * Licensed under the Apache License, Version 2.0 (the "License");
73 * you may not use this file except in compliance with the License.
74 * You may obtain a copy of the License at
75 *
76 * http://www.apache.org/licenses/LICENSE-2.0
77 *
78 * Unless required by applicable law or agreed to in writing, software
79 * distributed under the License is distributed on an "AS IS" BASIS,
80 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
81 * See the License for the specific language governing permissions and
82 * limitations under the License.
83 */
84
85 // gen_amalgamated expanded: #include "perfetto/ext/base/android_utils.h"
86
87 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
88
89 #include <string>
90
91 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
92 #include <sys/system_properties.h>
93 #endif
94
95 // gen_amalgamated expanded: #include "perfetto/base/compiler.h"
96 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
97
98 namespace perfetto {
99 namespace base {
100
101 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
102
GetAndroidProp(const char * name)103 std::string GetAndroidProp(const char* name) {
104 std::string ret;
105 #if __ANDROID_API__ >= 26
106 const prop_info* pi = __system_property_find(name);
107 if (!pi) {
108 return ret;
109 }
110 __system_property_read_callback(
111 pi,
112 [](void* dst_void, const char*, const char* value, uint32_t) {
113 std::string& dst = *static_cast<std::string*>(dst_void);
114 dst = value;
115 },
116 &ret);
117 #else // __ANDROID_API__ < 26
118 char value_buf[PROP_VALUE_MAX];
119 int len = __system_property_get(name, value_buf);
120 if (len > 0 && static_cast<size_t>(len) < sizeof(value_buf)) {
121 ret = std::string(value_buf, static_cast<size_t>(len));
122 }
123 #endif
124 return ret;
125 }
126
127 #endif // PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
128
129 } // namespace base
130 } // namespace perfetto
131 // gen_amalgamated begin source: src/base/base64.cc
132 // gen_amalgamated begin header: include/perfetto/ext/base/base64.h
133 // gen_amalgamated begin header: include/perfetto/ext/base/optional.h
134 /*
135 * Copyright (C) 2018 The Android Open Source Project
136 *
137 * Licensed under the Apache License, Version 2.0 (the "License");
138 * you may not use this file except in compliance with the License.
139 * You may obtain a copy of the License at
140 *
141 * http://www.apache.org/licenses/LICENSE-2.0
142 *
143 * Unless required by applicable law or agreed to in writing, software
144 * distributed under the License is distributed on an "AS IS" BASIS,
145 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
146 * See the License for the specific language governing permissions and
147 * limitations under the License.
148 */
149
150 #ifndef INCLUDE_PERFETTO_EXT_BASE_OPTIONAL_H_
151 #define INCLUDE_PERFETTO_EXT_BASE_OPTIONAL_H_
152
153 #include <functional>
154 #include <type_traits>
155 #include <utility>
156
157 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
158
159 namespace perfetto {
160 namespace base {
161
162 // Specification:
163 // http://en.cppreference.com/w/cpp/utility/optional/in_place_t
164 struct in_place_t {};
165
166 // Specification:
167 // http://en.cppreference.com/w/cpp/utility/optional/nullopt_t
168 struct nullopt_t {
nullopt_tperfetto::base::nullopt_t169 constexpr explicit nullopt_t(int) {}
170 };
171
172 // Specification:
173 // http://en.cppreference.com/w/cpp/utility/optional/in_place
174 constexpr in_place_t in_place = {};
175
176 // Specification:
177 // http://en.cppreference.com/w/cpp/utility/optional/nullopt
178 constexpr nullopt_t nullopt(0);
179
180 // Forward declaration, which is referred by following helpers.
181 template <typename T>
182 class Optional;
183
184 namespace internal {
185
186 template <typename T, bool = std::is_trivially_destructible<T>::value>
187 struct OptionalStorageBase {
188 // Initializing |empty_| here instead of using default member initializing
189 // to avoid errors in g++ 4.8.
OptionalStorageBaseperfetto::base::internal::OptionalStorageBase190 constexpr OptionalStorageBase() : empty_('\0') {}
191
192 template <class... Args>
OptionalStorageBaseperfetto::base::internal::OptionalStorageBase193 constexpr explicit OptionalStorageBase(in_place_t, Args&&... args)
194 : is_populated_(true), value_(std::forward<Args>(args)...) {}
195
196 // When T is not trivially destructible we must call its
197 // destructor before deallocating its memory.
198 // Note that this hides the (implicitly declared) move constructor, which
199 // would be used for constexpr move constructor in OptionalStorage<T>.
200 // It is needed iff T is trivially move constructible. However, the current
201 // is_trivially_{copy,move}_constructible implementation requires
202 // is_trivially_destructible (which looks a bug, cf:
203 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51452 and
204 // http://cplusplus.github.io/LWG/lwg-active.html#2116), so it is not
205 // necessary for this case at the moment. Please see also the destructor
206 // comment in "is_trivially_destructible = true" specialization below.
~OptionalStorageBaseperfetto::base::internal::OptionalStorageBase207 ~OptionalStorageBase() {
208 if (is_populated_)
209 value_.~T();
210 }
211
212 template <class... Args>
Initperfetto::base::internal::OptionalStorageBase213 void Init(Args&&... args) {
214 PERFETTO_DCHECK(!is_populated_);
215 ::new (&value_) T(std::forward<Args>(args)...);
216 is_populated_ = true;
217 }
218
219 bool is_populated_ = false;
220 union {
221 // |empty_| exists so that the union will always be initialized, even when
222 // it doesn't contain a value. Union members must be initialized for the
223 // constructor to be 'constexpr'.
224 char empty_;
225 T value_;
226 };
227 };
228
229 template <typename T>
230 struct OptionalStorageBase<T, true /* trivially destructible */> {
231 // Initializing |empty_| here instead of using default member initializing
232 // to avoid errors in g++ 4.8.
OptionalStorageBaseperfetto::base::internal::OptionalStorageBase233 constexpr OptionalStorageBase() : empty_('\0') {}
234
235 template <class... Args>
OptionalStorageBaseperfetto::base::internal::OptionalStorageBase236 constexpr explicit OptionalStorageBase(in_place_t, Args&&... args)
237 : is_populated_(true), value_(std::forward<Args>(args)...) {}
238
239 // When T is trivially destructible (i.e. its destructor does nothing) there
240 // is no need to call it. Implicitly defined destructor is trivial, because
241 // both members (bool and union containing only variants which are trivially
242 // destructible) are trivially destructible.
243 // Explicitly-defaulted destructor is also trivial, but do not use it here,
244 // because it hides the implicit move constructor. It is needed to implement
245 // constexpr move constructor in OptionalStorage iff T is trivially move
246 // constructible. Note that, if T is trivially move constructible, the move
247 // constructor of OptionalStorageBase<T> is also implicitly defined and it is
248 // trivially move constructor. If T is not trivially move constructible,
249 // "not declaring move constructor without destructor declaration" here means
250 // "delete move constructor", which works because any move constructor of
251 // OptionalStorage will not refer to it in that case.
252
253 template <class... Args>
Initperfetto::base::internal::OptionalStorageBase254 void Init(Args&&... args) {
255 PERFETTO_DCHECK(!is_populated_);
256 ::new (&value_) T(std::forward<Args>(args)...);
257 is_populated_ = true;
258 }
259
260 bool is_populated_ = false;
261 union {
262 // |empty_| exists so that the union will always be initialized, even when
263 // it doesn't contain a value. Union members must be initialized for the
264 // constructor to be 'constexpr'.
265 char empty_;
266 T value_;
267 };
268 };
269
270 // Implement conditional constexpr copy and move constructors. These are
271 // constexpr if is_trivially_{copy,move}_constructible<T>::value is true
272 // respectively. If each is true, the corresponding constructor is defined as
273 // "= default;", which generates a constexpr constructor (In this case,
274 // the condition of constexpr-ness is satisfied because the base class also has
275 // compiler generated constexpr {copy,move} constructors). Note that
276 // placement-new is prohibited in constexpr.
277 template <typename T, bool = std::is_trivially_copy_constructible<T>::value>
278 struct OptionalStorage : OptionalStorageBase<T> {
279 // This is no trivially {copy,move} constructible case. Other cases are
280 // defined below as specializations.
281
282 // Accessing the members of template base class requires explicit
283 // declaration.
284 using OptionalStorageBase<T>::is_populated_;
285 using OptionalStorageBase<T>::value_;
286 using OptionalStorageBase<T>::Init;
287
288 // Inherit constructors (specifically, the in_place constructor).
289 using OptionalStorageBase<T>::OptionalStorageBase;
290
291 // User defined constructor deletes the default constructor.
292 // Define it explicitly.
293 OptionalStorage() = default;
294
OptionalStorageperfetto::base::internal::OptionalStorage295 OptionalStorage(const OptionalStorage& other) : OptionalStorageBase<T>() {
296 if (other.is_populated_)
297 Init(other.value_);
298 }
299
OptionalStorageperfetto::base::internal::OptionalStorage300 OptionalStorage(OptionalStorage&& other) noexcept(
301 std::is_nothrow_move_constructible<T>::value) {
302 if (other.is_populated_)
303 Init(std::move(other.value_));
304 }
305 };
306
307 template <typename T>
308 struct OptionalStorage<T, true /* trivially copy constructible */>
309 : OptionalStorageBase<T> {
310 using OptionalStorageBase<T>::is_populated_;
311 using OptionalStorageBase<T>::value_;
312 using OptionalStorageBase<T>::Init;
313 using OptionalStorageBase<T>::OptionalStorageBase;
314
315 OptionalStorage() = default;
316 OptionalStorage(const OptionalStorage& other) = default;
317
OptionalStorageperfetto::base::internal::OptionalStorage318 OptionalStorage(OptionalStorage&& other) noexcept(
319 std::is_nothrow_move_constructible<T>::value) {
320 if (other.is_populated_)
321 Init(std::move(other.value_));
322 }
323 };
324
325 // Base class to support conditionally usable copy-/move- constructors
326 // and assign operators.
327 template <typename T>
328 class OptionalBase {
329 // This class provides implementation rather than public API, so everything
330 // should be hidden. Often we use composition, but we cannot in this case
331 // because of C++ language restriction.
332 protected:
333 constexpr OptionalBase() = default;
334 constexpr OptionalBase(const OptionalBase& other) = default;
335 constexpr OptionalBase(OptionalBase&& other) = default;
336
337 template <class... Args>
OptionalBase(in_place_t,Args &&...args)338 constexpr explicit OptionalBase(in_place_t, Args&&... args)
339 : storage_(in_place, std::forward<Args>(args)...) {}
340
341 // Implementation of converting constructors.
342 template <typename U>
OptionalBase(const OptionalBase<U> & other)343 explicit OptionalBase(const OptionalBase<U>& other) {
344 if (other.storage_.is_populated_)
345 storage_.Init(other.storage_.value_);
346 }
347
348 template <typename U>
OptionalBase(OptionalBase<U> && other)349 explicit OptionalBase(OptionalBase<U>&& other) {
350 if (other.storage_.is_populated_)
351 storage_.Init(std::move(other.storage_.value_));
352 }
353
354 ~OptionalBase() = default;
355
operator =(const OptionalBase & other)356 OptionalBase& operator=(const OptionalBase& other) {
357 CopyAssign(other);
358 return *this;
359 }
360
operator =(OptionalBase && other)361 OptionalBase& operator=(OptionalBase&& other) noexcept(
362 std::is_nothrow_move_assignable<T>::value&&
363 std::is_nothrow_move_constructible<T>::value) {
364 MoveAssign(std::move(other));
365 return *this;
366 }
367
368 template <typename U>
CopyAssign(const OptionalBase<U> & other)369 void CopyAssign(const OptionalBase<U>& other) {
370 if (other.storage_.is_populated_)
371 InitOrAssign(other.storage_.value_);
372 else
373 FreeIfNeeded();
374 }
375
376 template <typename U>
MoveAssign(OptionalBase<U> && other)377 void MoveAssign(OptionalBase<U>&& other) {
378 if (other.storage_.is_populated_)
379 InitOrAssign(std::move(other.storage_.value_));
380 else
381 FreeIfNeeded();
382 }
383
384 template <typename U>
InitOrAssign(U && value)385 void InitOrAssign(U&& value) {
386 if (storage_.is_populated_)
387 storage_.value_ = std::forward<U>(value);
388 else
389 storage_.Init(std::forward<U>(value));
390 }
391
FreeIfNeeded()392 void FreeIfNeeded() {
393 if (!storage_.is_populated_)
394 return;
395 storage_.value_.~T();
396 storage_.is_populated_ = false;
397 }
398
399 // For implementing conversion, allow access to other typed OptionalBase
400 // class.
401 template <typename U>
402 friend class OptionalBase;
403
404 OptionalStorage<T> storage_;
405 };
406
407 // The following {Copy,Move}{Constructible,Assignable} structs are helpers to
408 // implement constructor/assign-operator overloading. Specifically, if T is
409 // is not movable but copyable, Optional<T>'s move constructor should not
410 // participate in overload resolution. This inheritance trick implements that.
411 template <bool is_copy_constructible>
412 struct CopyConstructible {};
413
414 template <>
415 struct CopyConstructible<false> {
416 constexpr CopyConstructible() = default;
417 constexpr CopyConstructible(const CopyConstructible&) = delete;
418 constexpr CopyConstructible(CopyConstructible&&) = default;
419 CopyConstructible& operator=(const CopyConstructible&) = default;
420 CopyConstructible& operator=(CopyConstructible&&) = default;
421 };
422
423 template <bool is_move_constructible>
424 struct MoveConstructible {};
425
426 template <>
427 struct MoveConstructible<false> {
428 constexpr MoveConstructible() = default;
429 constexpr MoveConstructible(const MoveConstructible&) = default;
430 constexpr MoveConstructible(MoveConstructible&&) = delete;
431 MoveConstructible& operator=(const MoveConstructible&) = default;
432 MoveConstructible& operator=(MoveConstructible&&) = default;
433 };
434
435 template <bool is_copy_assignable>
436 struct CopyAssignable {};
437
438 template <>
439 struct CopyAssignable<false> {
440 constexpr CopyAssignable() = default;
441 constexpr CopyAssignable(const CopyAssignable&) = default;
442 constexpr CopyAssignable(CopyAssignable&&) = default;
443 CopyAssignable& operator=(const CopyAssignable&) = delete;
444 CopyAssignable& operator=(CopyAssignable&&) = default;
445 };
446
447 template <bool is_move_assignable>
448 struct MoveAssignable {};
449
450 template <>
451 struct MoveAssignable<false> {
452 constexpr MoveAssignable() = default;
453 constexpr MoveAssignable(const MoveAssignable&) = default;
454 constexpr MoveAssignable(MoveAssignable&&) = default;
455 MoveAssignable& operator=(const MoveAssignable&) = default;
456 MoveAssignable& operator=(MoveAssignable&&) = delete;
457 };
458
459 // Helper to conditionally enable converting constructors and assign operators.
460 template <typename T, typename U>
461 struct IsConvertibleFromOptional
462 : std::integral_constant<
463 bool,
464 std::is_constructible<T, Optional<U>&>::value ||
465 std::is_constructible<T, const Optional<U>&>::value ||
466 std::is_constructible<T, Optional<U>&&>::value ||
467 std::is_constructible<T, const Optional<U>&&>::value ||
468 std::is_convertible<Optional<U>&, T>::value ||
469 std::is_convertible<const Optional<U>&, T>::value ||
470 std::is_convertible<Optional<U>&&, T>::value ||
471 std::is_convertible<const Optional<U>&&, T>::value> {};
472
473 template <typename T, typename U>
474 struct IsAssignableFromOptional
475 : std::integral_constant<
476 bool,
477 IsConvertibleFromOptional<T, U>::value ||
478 std::is_assignable<T&, Optional<U>&>::value ||
479 std::is_assignable<T&, const Optional<U>&>::value ||
480 std::is_assignable<T&, Optional<U>&&>::value ||
481 std::is_assignable<T&, const Optional<U>&&>::value> {};
482
483 // Forward compatibility for C++17.
484 // Introduce one more deeper nested namespace to avoid leaking using std::swap.
485 namespace swappable_impl {
486 using std::swap;
487
488 struct IsSwappableImpl {
489 // Tests if swap can be called. Check<T&>(0) returns true_type iff swap is
490 // available for T. Otherwise, Check's overload resolution falls back to
491 // Check(...) declared below thanks to SFINAE, so returns false_type.
492 template <typename T>
493 static auto Check(int)
494 -> decltype(swap(std::declval<T>(), std::declval<T>()), std::true_type());
495
496 template <typename T>
497 static std::false_type Check(...);
498 };
499 } // namespace swappable_impl
500
501 template <typename T>
502 struct IsSwappable : decltype(swappable_impl::IsSwappableImpl::Check<T&>(0)) {};
503
504 // Forward compatibility for C++20.
505 template <typename T>
506 using RemoveCvRefT =
507 typename std::remove_cv<typename std::remove_reference<T>::type>::type;
508
509 } // namespace internal
510
511 // On Windows, by default, empty-base class optimization does not work,
512 // which means even if the base class is empty struct, it still consumes one
513 // byte for its body. __declspec(empty_bases) enables the optimization.
514 // cf)
515 // https://blogs.msdn.microsoft.com/vcblog/2016/03/30/optimizing-the-layout-of-empty-base-classes-in-vs2015-update-2-3/
516 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) && \
517 !PERFETTO_BUILDFLAG(PERFETTO_COMPILER_GCC)
518 #define OPTIONAL_DECLSPEC_EMPTY_BASES __declspec(empty_bases)
519 #else
520 #define OPTIONAL_DECLSPEC_EMPTY_BASES
521 #endif
522
523 // base::Optional is a Chromium version of the C++17 optional class:
524 // std::optional documentation:
525 // http://en.cppreference.com/w/cpp/utility/optional
526 // Chromium documentation:
527 // https://chromium.googlesource.com/chromium/src/+/master/docs/optional.md
528 //
529 // These are the differences between the specification and the implementation:
530 // - Constructors do not use 'constexpr' as it is a C++14 extension.
531 // - 'constexpr' might be missing in some places for reasons specified locally.
532 // - No exceptions are thrown, because they are banned from Chromium.
533 // Marked noexcept for only move constructor and move assign operators.
534 // - All the non-members are in the 'base' namespace instead of 'std'.
535 //
536 // Note that T cannot have a constructor T(Optional<T>) etc. Optional<T>
537 // PERFETTO_CHECKs T's constructor (specifically via IsConvertibleFromOptional),
538 // and in the PERFETTO_CHECK whether T can be constructible from Optional<T>,
539 // which is recursive so it does not work. As of Feb 2018, std::optional C++17
540 // implementation in both clang and gcc has same limitation. MSVC SFINAE looks
541 // to have different behavior, but anyway it reports an error, too.
542 //
543 // This file is a modified version of optional.h from Chromium at revision
544 // 5e71bd454e60511c1293c0c686544aaa76094424. The changes remove C++14/C++17
545 // specific code and replace with C++11 counterparts.
546 template <typename T>
547 class OPTIONAL_DECLSPEC_EMPTY_BASES Optional
548 : public internal::OptionalBase<T>,
549 public internal::CopyConstructible<std::is_copy_constructible<T>::value>,
550 public internal::MoveConstructible<std::is_move_constructible<T>::value>,
551 public internal::CopyAssignable<std::is_copy_constructible<T>::value &&
552 std::is_copy_assignable<T>::value>,
553 public internal::MoveAssignable<std::is_move_constructible<T>::value &&
554 std::is_move_assignable<T>::value> {
555 public:
556 #undef OPTIONAL_DECLSPEC_EMPTY_BASES
557 using value_type = T;
558
559 // Defer default/copy/move constructor implementation to OptionalBase.
560 constexpr Optional() = default;
561 constexpr Optional(const Optional& other) = default;
562 constexpr Optional(Optional&& other) noexcept(
563 std::is_nothrow_move_constructible<T>::value) = default;
564
Optional(nullopt_t)565 constexpr Optional(nullopt_t) {} // NOLINT(runtime/explicit)
566
567 // Converting copy constructor. "explicit" only if
568 // std::is_convertible<const U&, T>::value is false. It is implemented by
569 // declaring two almost same constructors, but that condition in enable_if_t
570 // is different, so that either one is chosen, thanks to SFINAE.
571 template <typename U,
572 typename std::enable_if<
573 std::is_constructible<T, const U&>::value &&
574 !internal::IsConvertibleFromOptional<T, U>::value &&
575 std::is_convertible<const U&, T>::value,
576 bool>::type = false>
Optional(const Optional<U> & other)577 Optional(const Optional<U>& other) : internal::OptionalBase<T>(other) {}
578
579 template <typename U,
580 typename std::enable_if<
581 std::is_constructible<T, const U&>::value &&
582 !internal::IsConvertibleFromOptional<T, U>::value &&
583 !std::is_convertible<const U&, T>::value,
584 bool>::type = false>
Optional(const Optional<U> & other)585 explicit Optional(const Optional<U>& other)
586 : internal::OptionalBase<T>(other) {}
587
588 // Converting move constructor. Similar to converting copy constructor,
589 // declaring two (explicit and non-explicit) constructors.
590 template <typename U,
591 typename std::enable_if<
592 std::is_constructible<T, U&&>::value &&
593 !internal::IsConvertibleFromOptional<T, U>::value &&
594 std::is_convertible<U&&, T>::value,
595 bool>::type = false>
Optional(Optional<U> && other)596 Optional(Optional<U>&& other) : internal::OptionalBase<T>(std::move(other)) {}
597
598 template <typename U,
599 typename std::enable_if<
600 std::is_constructible<T, U&&>::value &&
601 !internal::IsConvertibleFromOptional<T, U>::value &&
602 !std::is_convertible<U&&, T>::value,
603 bool>::type = false>
Optional(Optional<U> && other)604 explicit Optional(Optional<U>&& other)
605 : internal::OptionalBase<T>(std::move(other)) {}
606
607 template <class... Args>
Optional(in_place_t,Args &&...args)608 constexpr explicit Optional(in_place_t, Args&&... args)
609 : internal::OptionalBase<T>(in_place, std::forward<Args>(args)...) {}
610
611 template <class U,
612 class... Args,
613 class = typename std::enable_if<
614 std::is_constructible<value_type,
615 std::initializer_list<U>&,
616 Args...>::value>::type>
Optional(in_place_t,std::initializer_list<U> il,Args &&...args)617 constexpr explicit Optional(in_place_t,
618 std::initializer_list<U> il,
619 Args&&... args)
620 : internal::OptionalBase<T>(in_place, il, std::forward<Args>(args)...) {}
621
622 // Forward value constructor. Similar to converting constructors,
623 // conditionally explicit.
624 template <
625 typename U = value_type,
626 typename std::enable_if<
627 std::is_constructible<T, U&&>::value &&
628 !std::is_same<internal::RemoveCvRefT<U>, in_place_t>::value &&
629 !std::is_same<internal::RemoveCvRefT<U>, Optional<T>>::value &&
630 std::is_convertible<U&&, T>::value,
631 bool>::type = false>
Optional(U && value)632 constexpr Optional(U&& value)
633 : internal::OptionalBase<T>(in_place, std::forward<U>(value)) {}
634
635 template <
636 typename U = value_type,
637 typename std::enable_if<
638 std::is_constructible<T, U&&>::value &&
639 !std::is_same<internal::RemoveCvRefT<U>, in_place_t>::value &&
640 !std::is_same<internal::RemoveCvRefT<U>, Optional<T>>::value &&
641 !std::is_convertible<U&&, T>::value,
642 bool>::type = false>
Optional(U && value)643 constexpr explicit Optional(U&& value)
644 : internal::OptionalBase<T>(in_place, std::forward<U>(value)) {}
645
646 ~Optional() = default;
647
648 // Defer copy-/move- assign operator implementation to OptionalBase.
649 Optional& operator=(const Optional& other) = default;
650 Optional& operator=(Optional&& other) noexcept(
651 std::is_nothrow_move_assignable<T>::value&&
652 std::is_nothrow_move_constructible<T>::value) = default;
653
operator =(nullopt_t)654 Optional& operator=(nullopt_t) {
655 FreeIfNeeded();
656 return *this;
657 }
658
659 // Perfect-forwarded assignment.
660 template <typename U>
661 typename std::enable_if<
662 !std::is_same<internal::RemoveCvRefT<U>, Optional<T>>::value &&
663 std::is_constructible<T, U>::value &&
664 std::is_assignable<T&, U>::value &&
665 (!std::is_scalar<T>::value ||
666 !std::is_same<typename std::decay<U>::type, T>::value),
667 Optional&>::type
operator =(U && value)668 operator=(U&& value) {
669 InitOrAssign(std::forward<U>(value));
670 return *this;
671 }
672
673 // Copy assign the state of other.
674 template <typename U>
675 typename std::enable_if<!internal::IsAssignableFromOptional<T, U>::value &&
676 std::is_constructible<T, const U&>::value &&
677 std::is_assignable<T&, const U&>::value,
678 Optional&>::type
operator =(const Optional<U> & other)679 operator=(const Optional<U>& other) {
680 CopyAssign(other);
681 return *this;
682 }
683
684 // Move assign the state of other.
685 template <typename U>
686 typename std::enable_if<!internal::IsAssignableFromOptional<T, U>::value &&
687 std::is_constructible<T, U>::value &&
688 std::is_assignable<T&, U>::value,
689 Optional&>::type
operator =(Optional<U> && other)690 operator=(Optional<U>&& other) {
691 MoveAssign(std::move(other));
692 return *this;
693 }
694
operator ->() const695 const T* operator->() const {
696 PERFETTO_DCHECK(storage_.is_populated_);
697 return &storage_.value_;
698 }
699
operator ->()700 T* operator->() {
701 PERFETTO_DCHECK(storage_.is_populated_);
702 return &storage_.value_;
703 }
704
operator *() const705 const T& operator*() const& {
706 PERFETTO_DCHECK(storage_.is_populated_);
707 return storage_.value_;
708 }
709
operator *()710 T& operator*() & {
711 PERFETTO_DCHECK(storage_.is_populated_);
712 return storage_.value_;
713 }
714
operator *() const715 const T&& operator*() const&& {
716 PERFETTO_DCHECK(storage_.is_populated_);
717 return std::move(storage_.value_);
718 }
719
operator *()720 T&& operator*() && {
721 PERFETTO_DCHECK(storage_.is_populated_);
722 return std::move(storage_.value_);
723 }
724
operator bool() const725 constexpr explicit operator bool() const { return storage_.is_populated_; }
726
has_value() const727 constexpr bool has_value() const { return storage_.is_populated_; }
728
value()729 T& value() & {
730 PERFETTO_CHECK(storage_.is_populated_);
731 return storage_.value_;
732 }
733
value() const734 const T& value() const& {
735 PERFETTO_CHECK(storage_.is_populated_);
736 return storage_.value_;
737 }
738
value()739 T&& value() && {
740 PERFETTO_CHECK(storage_.is_populated_);
741 return std::move(storage_.value_);
742 }
743
value() const744 const T&& value() const&& {
745 PERFETTO_CHECK(storage_.is_populated_);
746 return std::move(storage_.value_);
747 }
748
749 template <class U>
value_or(U && default_value) const750 constexpr T value_or(U&& default_value) const& {
751 static_assert(std::is_convertible<U, T>::value,
752 "U must be convertible to T");
753 return storage_.is_populated_
754 ? storage_.value_
755 : static_cast<T>(std::forward<U>(default_value));
756 }
757
758 template <class U>
value_or(U && default_value)759 T value_or(U&& default_value) && {
760 static_assert(std::is_convertible<U, T>::value,
761 "U must be convertible to T");
762 return storage_.is_populated_
763 ? std::move(storage_.value_)
764 : static_cast<T>(std::forward<U>(default_value));
765 }
766
swap(Optional & other)767 void swap(Optional& other) {
768 if (!storage_.is_populated_ && !other.storage_.is_populated_)
769 return;
770
771 if (storage_.is_populated_ != other.storage_.is_populated_) {
772 if (storage_.is_populated_) {
773 other.storage_.Init(std::move(storage_.value_));
774 FreeIfNeeded();
775 } else {
776 storage_.Init(std::move(other.storage_.value_));
777 other.FreeIfNeeded();
778 }
779 return;
780 }
781
782 PERFETTO_DCHECK(storage_.is_populated_ && other.storage_.is_populated_);
783 using std::swap;
784 swap(**this, *other);
785 }
786
reset()787 void reset() { FreeIfNeeded(); }
788
789 template <class... Args>
emplace(Args &&...args)790 T& emplace(Args&&... args) {
791 FreeIfNeeded();
792 storage_.Init(std::forward<Args>(args)...);
793 return storage_.value_;
794 }
795
796 template <class U, class... Args>
797 typename std::enable_if<
798 std::is_constructible<T, std::initializer_list<U>&, Args&&...>::value,
799 T&>::type
emplace(std::initializer_list<U> il,Args &&...args)800 emplace(std::initializer_list<U> il, Args&&... args) {
801 FreeIfNeeded();
802 storage_.Init(il, std::forward<Args>(args)...);
803 return storage_.value_;
804 }
805
806 private:
807 // Accessing template base class's protected member needs explicit
808 // declaration to do so.
809 using internal::OptionalBase<T>::CopyAssign;
810 using internal::OptionalBase<T>::FreeIfNeeded;
811 using internal::OptionalBase<T>::InitOrAssign;
812 using internal::OptionalBase<T>::MoveAssign;
813 using internal::OptionalBase<T>::storage_;
814 };
815
816 // Here after defines comparation operators. The definition follows
817 // http://en.cppreference.com/w/cpp/utility/optional/operator_cmp
818 // while bool() casting is replaced by has_value() to meet the chromium
819 // style guide.
820 template <class T, class U>
operator ==(const Optional<T> & lhs,const Optional<U> & rhs)821 bool operator==(const Optional<T>& lhs, const Optional<U>& rhs) {
822 if (lhs.has_value() != rhs.has_value())
823 return false;
824 if (!lhs.has_value())
825 return true;
826 return *lhs == *rhs;
827 }
828
829 template <class T, class U>
operator !=(const Optional<T> & lhs,const Optional<U> & rhs)830 bool operator!=(const Optional<T>& lhs, const Optional<U>& rhs) {
831 if (lhs.has_value() != rhs.has_value())
832 return true;
833 if (!lhs.has_value())
834 return false;
835 return *lhs != *rhs;
836 }
837
838 template <class T, class U>
operator <(const Optional<T> & lhs,const Optional<U> & rhs)839 bool operator<(const Optional<T>& lhs, const Optional<U>& rhs) {
840 if (!rhs.has_value())
841 return false;
842 if (!lhs.has_value())
843 return true;
844 return *lhs < *rhs;
845 }
846
847 template <class T, class U>
operator <=(const Optional<T> & lhs,const Optional<U> & rhs)848 bool operator<=(const Optional<T>& lhs, const Optional<U>& rhs) {
849 if (!lhs.has_value())
850 return true;
851 if (!rhs.has_value())
852 return false;
853 return *lhs <= *rhs;
854 }
855
856 template <class T, class U>
operator >(const Optional<T> & lhs,const Optional<U> & rhs)857 bool operator>(const Optional<T>& lhs, const Optional<U>& rhs) {
858 if (!lhs.has_value())
859 return false;
860 if (!rhs.has_value())
861 return true;
862 return *lhs > *rhs;
863 }
864
865 template <class T, class U>
operator >=(const Optional<T> & lhs,const Optional<U> & rhs)866 bool operator>=(const Optional<T>& lhs, const Optional<U>& rhs) {
867 if (!rhs.has_value())
868 return true;
869 if (!lhs.has_value())
870 return false;
871 return *lhs >= *rhs;
872 }
873
874 template <class T>
operator ==(const Optional<T> & opt,nullopt_t)875 constexpr bool operator==(const Optional<T>& opt, nullopt_t) {
876 return !opt;
877 }
878
879 template <class T>
operator ==(nullopt_t,const Optional<T> & opt)880 constexpr bool operator==(nullopt_t, const Optional<T>& opt) {
881 return !opt;
882 }
883
884 template <class T>
operator !=(const Optional<T> & opt,nullopt_t)885 constexpr bool operator!=(const Optional<T>& opt, nullopt_t) {
886 return opt.has_value();
887 }
888
889 template <class T>
operator !=(nullopt_t,const Optional<T> & opt)890 constexpr bool operator!=(nullopt_t, const Optional<T>& opt) {
891 return opt.has_value();
892 }
893
894 template <class T>
operator <(const Optional<T> &,nullopt_t)895 constexpr bool operator<(const Optional<T>&, nullopt_t) {
896 return false;
897 }
898
899 template <class T>
operator <(nullopt_t,const Optional<T> & opt)900 constexpr bool operator<(nullopt_t, const Optional<T>& opt) {
901 return opt.has_value();
902 }
903
904 template <class T>
operator <=(const Optional<T> & opt,nullopt_t)905 constexpr bool operator<=(const Optional<T>& opt, nullopt_t) {
906 return !opt;
907 }
908
909 template <class T>
operator <=(nullopt_t,const Optional<T> &)910 constexpr bool operator<=(nullopt_t, const Optional<T>&) {
911 return true;
912 }
913
914 template <class T>
operator >(const Optional<T> & opt,nullopt_t)915 constexpr bool operator>(const Optional<T>& opt, nullopt_t) {
916 return opt.has_value();
917 }
918
919 template <class T>
operator >(nullopt_t,const Optional<T> &)920 constexpr bool operator>(nullopt_t, const Optional<T>&) {
921 return false;
922 }
923
924 template <class T>
operator >=(const Optional<T> &,nullopt_t)925 constexpr bool operator>=(const Optional<T>&, nullopt_t) {
926 return true;
927 }
928
929 template <class T>
operator >=(nullopt_t,const Optional<T> & opt)930 constexpr bool operator>=(nullopt_t, const Optional<T>& opt) {
931 return !opt;
932 }
933
934 template <class T, class U>
operator ==(const Optional<T> & opt,const U & value)935 constexpr bool operator==(const Optional<T>& opt, const U& value) {
936 return opt.has_value() ? *opt == value : false;
937 }
938
939 template <class T, class U>
operator ==(const U & value,const Optional<T> & opt)940 constexpr bool operator==(const U& value, const Optional<T>& opt) {
941 return opt.has_value() ? value == *opt : false;
942 }
943
944 template <class T, class U>
operator !=(const Optional<T> & opt,const U & value)945 constexpr bool operator!=(const Optional<T>& opt, const U& value) {
946 return opt.has_value() ? *opt != value : true;
947 }
948
949 template <class T, class U>
operator !=(const U & value,const Optional<T> & opt)950 constexpr bool operator!=(const U& value, const Optional<T>& opt) {
951 return opt.has_value() ? value != *opt : true;
952 }
953
954 template <class T, class U>
operator <(const Optional<T> & opt,const U & value)955 constexpr bool operator<(const Optional<T>& opt, const U& value) {
956 return opt.has_value() ? *opt < value : true;
957 }
958
959 template <class T, class U>
operator <(const U & value,const Optional<T> & opt)960 constexpr bool operator<(const U& value, const Optional<T>& opt) {
961 return opt.has_value() ? value < *opt : false;
962 }
963
964 template <class T, class U>
operator <=(const Optional<T> & opt,const U & value)965 constexpr bool operator<=(const Optional<T>& opt, const U& value) {
966 return opt.has_value() ? *opt <= value : true;
967 }
968
969 template <class T, class U>
operator <=(const U & value,const Optional<T> & opt)970 constexpr bool operator<=(const U& value, const Optional<T>& opt) {
971 return opt.has_value() ? value <= *opt : false;
972 }
973
974 template <class T, class U>
operator >(const Optional<T> & opt,const U & value)975 constexpr bool operator>(const Optional<T>& opt, const U& value) {
976 return opt.has_value() ? *opt > value : false;
977 }
978
979 template <class T, class U>
operator >(const U & value,const Optional<T> & opt)980 constexpr bool operator>(const U& value, const Optional<T>& opt) {
981 return opt.has_value() ? value > *opt : true;
982 }
983
984 template <class T, class U>
operator >=(const Optional<T> & opt,const U & value)985 constexpr bool operator>=(const Optional<T>& opt, const U& value) {
986 return opt.has_value() ? *opt >= value : false;
987 }
988
989 template <class T, class U>
operator >=(const U & value,const Optional<T> & opt)990 constexpr bool operator>=(const U& value, const Optional<T>& opt) {
991 return opt.has_value() ? value >= *opt : true;
992 }
993
994 template <class T>
make_optional(T && value)995 constexpr Optional<typename std::decay<T>::type> make_optional(T&& value) {
996 return Optional<typename std::decay<T>::type>(std::forward<T>(value));
997 }
998
999 template <class T, class... Args>
make_optional(Args &&...args)1000 constexpr Optional<T> make_optional(Args&&... args) {
1001 return Optional<T>(in_place, std::forward<Args>(args)...);
1002 }
1003
1004 template <class T, class U, class... Args>
make_optional(std::initializer_list<U> il,Args &&...args)1005 constexpr Optional<T> make_optional(std::initializer_list<U> il,
1006 Args&&... args) {
1007 return Optional<T>(in_place, il, std::forward<Args>(args)...);
1008 }
1009
1010 // Partial specialization for a function template is not allowed. Also, it is
1011 // not allowed to add overload function to std namespace, while it is allowed
1012 // to specialize the template in std. Thus, swap() (kind of) overloading is
1013 // defined in base namespace, instead.
1014 template <class T>
1015 typename std::enable_if<std::is_move_constructible<T>::value &&
1016 internal::IsSwappable<T>::value>::type
swap(Optional<T> & lhs,Optional<T> & rhs)1017 swap(Optional<T>& lhs, Optional<T>& rhs) {
1018 lhs.swap(rhs);
1019 }
1020
1021 } // namespace base
1022 } // namespace perfetto
1023
1024 template <class T>
1025 struct std::hash<perfetto::base::Optional<T>> {
operator ()std::hash1026 size_t operator()(const perfetto::base::Optional<T>& opt) const {
1027 return opt == perfetto::base::nullopt ? 0 : std::hash<T>()(*opt);
1028 }
1029 };
1030
1031 #endif // INCLUDE_PERFETTO_EXT_BASE_OPTIONAL_H_
1032 // gen_amalgamated begin header: include/perfetto/ext/base/string_view.h
1033 // gen_amalgamated begin header: include/perfetto/ext/base/hash.h
1034 /*
1035 * Copyright (C) 2019 The Android Open Source Project
1036 *
1037 * Licensed under the Apache License, Version 2.0 (the "License");
1038 * you may not use this file except in compliance with the License.
1039 * You may obtain a copy of the License at
1040 *
1041 * http://www.apache.org/licenses/LICENSE-2.0
1042 *
1043 * Unless required by applicable law or agreed to in writing, software
1044 * distributed under the License is distributed on an "AS IS" BASIS,
1045 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1046 * See the License for the specific language governing permissions and
1047 * limitations under the License.
1048 */
1049
1050 #ifndef INCLUDE_PERFETTO_EXT_BASE_HASH_H_
1051 #define INCLUDE_PERFETTO_EXT_BASE_HASH_H_
1052
1053 #include <stddef.h>
1054 #include <stdint.h>
1055 #include <type_traits>
1056
1057 namespace perfetto {
1058 namespace base {
1059
1060 // A helper class which computes a 64-bit hash of the input data.
1061 // The algorithm used is FNV-1a as it is fast and easy to implement and has
1062 // relatively few collisions.
1063 // WARNING: This hash function should not be used for any cryptographic purpose.
1064 class Hash {
1065 public:
1066 // Creates an empty hash object
Hash()1067 Hash() {}
1068
1069 // Hashes a numeric value.
1070 template <
1071 typename T,
1072 typename std::enable_if<std::is_arithmetic<T>::value, bool>::type = true>
Update(T data)1073 void Update(T data) {
1074 Update(reinterpret_cast<const char*>(&data), sizeof(data));
1075 }
1076
1077 // Hashes a byte array.
Update(const char * data,size_t size)1078 void Update(const char* data, size_t size) {
1079 for (size_t i = 0; i < size; i++) {
1080 result_ ^= static_cast<uint8_t>(data[i]);
1081 result_ *= kFnv1a64Prime;
1082 }
1083 }
1084
digest()1085 uint64_t digest() { return result_; }
1086
1087 private:
1088 static constexpr uint64_t kFnv1a64OffsetBasis = 0xcbf29ce484222325;
1089 static constexpr uint64_t kFnv1a64Prime = 0x100000001b3;
1090
1091 uint64_t result_ = kFnv1a64OffsetBasis;
1092 };
1093
1094 // This is for using already-hashed key into std::unordered_map and avoid the
1095 // cost of re-hashing. Example:
1096 // unordered_map<uint64_t, Value, AlreadyHashed> my_map.
1097 template <typename T>
1098 struct AlreadyHashed {
operator ()perfetto::base::AlreadyHashed1099 size_t operator()(const T& x) const { return static_cast<size_t>(x); }
1100 };
1101
1102 } // namespace base
1103 } // namespace perfetto
1104
1105 #endif // INCLUDE_PERFETTO_EXT_BASE_HASH_H_
1106 /*
1107 * Copyright (C) 2018 The Android Open Source Project
1108 *
1109 * Licensed under the Apache License, Version 2.0 (the "License");
1110 * you may not use this file except in compliance with the License.
1111 * You may obtain a copy of the License at
1112 *
1113 * http://www.apache.org/licenses/LICENSE-2.0
1114 *
1115 * Unless required by applicable law or agreed to in writing, software
1116 * distributed under the License is distributed on an "AS IS" BASIS,
1117 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1118 * See the License for the specific language governing permissions and
1119 * limitations under the License.
1120 */
1121
1122 #ifndef INCLUDE_PERFETTO_EXT_BASE_STRING_VIEW_H_
1123 #define INCLUDE_PERFETTO_EXT_BASE_STRING_VIEW_H_
1124
1125 #include <string.h>
1126
1127 #include <algorithm>
1128 #include <string>
1129
1130 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
1131 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
1132 // gen_amalgamated expanded: #include "perfetto/ext/base/hash.h"
1133
1134 namespace perfetto {
1135 namespace base {
1136
1137 // A string-like object that refers to a non-owned piece of memory.
1138 // Strings are internally NOT null terminated.
1139 class StringView {
1140 public:
1141 static constexpr size_t npos = static_cast<size_t>(-1);
1142
StringView()1143 StringView() : data_(nullptr), size_(0) {}
1144 StringView(const StringView&) = default;
1145 StringView& operator=(const StringView&) = default;
StringView(const char * data,size_t size)1146 StringView(const char* data, size_t size) : data_(data), size_(size) {
1147 PERFETTO_DCHECK(size == 0 || data != nullptr);
1148 }
1149
1150 // Allow implicit conversion from any class that has a |data| and |size| field
1151 // and has the kConvertibleToStringView trait (e.g., protozero::ConstChars).
1152 template <typename T, typename = std::enable_if<T::kConvertibleToStringView>>
StringView(const T & x)1153 StringView(const T& x) : StringView(x.data, x.size) {
1154 PERFETTO_DCHECK(x.size == 0 || x.data != nullptr);
1155 }
1156
1157 // Creates a StringView from a null-terminated C string.
1158 // Deliberately not "explicit".
StringView(const char * cstr)1159 StringView(const char* cstr) : data_(cstr), size_(strlen(cstr)) {
1160 PERFETTO_DCHECK(cstr != nullptr);
1161 }
1162
1163 // This instead has to be explicit, as creating a StringView out of a
1164 // std::string can be subtle.
StringView(const std::string & str)1165 explicit StringView(const std::string& str)
1166 : data_(str.data()), size_(str.size()) {}
1167
empty() const1168 bool empty() const { return size_ == 0; }
size() const1169 size_t size() const { return size_; }
data() const1170 const char* data() const { return data_; }
begin() const1171 const char* begin() const { return data_; }
end() const1172 const char* end() const { return data_ + size_; }
1173
at(size_t pos) const1174 char at(size_t pos) const {
1175 PERFETTO_DCHECK(pos < size_);
1176 return data_[pos];
1177 }
1178
find(char c,size_t start_pos=0) const1179 size_t find(char c, size_t start_pos = 0) const {
1180 for (size_t i = start_pos; i < size_; ++i) {
1181 if (data_[i] == c)
1182 return i;
1183 }
1184 return npos;
1185 }
1186
find(const StringView & str,size_t start_pos=0) const1187 size_t find(const StringView& str, size_t start_pos = 0) const {
1188 if (start_pos > size())
1189 return npos;
1190 auto it = std::search(begin() + start_pos, end(), str.begin(), str.end());
1191 size_t pos = static_cast<size_t>(it - begin());
1192 return pos + str.size() <= size() ? pos : npos;
1193 }
1194
find(const char * str,size_t start_pos=0) const1195 size_t find(const char* str, size_t start_pos = 0) const {
1196 return find(StringView(str), start_pos);
1197 }
1198
rfind(char c) const1199 size_t rfind(char c) const {
1200 for (size_t i = size_; i > 0; --i) {
1201 if (data_[i - 1] == c)
1202 return i - 1;
1203 }
1204 return npos;
1205 }
1206
substr(size_t pos,size_t count=npos) const1207 StringView substr(size_t pos, size_t count = npos) const {
1208 if (pos >= size_)
1209 return StringView("", 0);
1210 size_t rcount = std::min(count, size_ - pos);
1211 return StringView(data_ + pos, rcount);
1212 }
1213
CaseInsensitiveEq(const StringView & other) const1214 bool CaseInsensitiveEq(const StringView& other) const {
1215 if (size() != other.size())
1216 return false;
1217 if (size() == 0)
1218 return true;
1219 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
1220 return _strnicmp(data(), other.data(), size()) == 0;
1221 #else
1222 return strncasecmp(data(), other.data(), size()) == 0;
1223 #endif
1224 }
1225
StartsWith(const StringView & other)1226 bool StartsWith(const StringView& other) {
1227 if (other.size() == 0)
1228 return true;
1229 if (size() == 0)
1230 return false;
1231 if (other.size() > size())
1232 return false;
1233 for (uint32_t i = 0; i < other.size(); ++i) {
1234 if (at(i) != other.at(i))
1235 return false;
1236 }
1237 return true;
1238 }
1239
ToStdString() const1240 std::string ToStdString() const {
1241 return size_ == 0 ? "" : std::string(data_, size_);
1242 }
1243
Hash() const1244 uint64_t Hash() const {
1245 base::Hash hasher;
1246 hasher.Update(data_, size_);
1247 return hasher.digest();
1248 }
1249
1250 private:
1251 const char* data_ = nullptr;
1252 size_t size_ = 0;
1253 };
1254
operator ==(const StringView & x,const StringView & y)1255 inline bool operator==(const StringView& x, const StringView& y) {
1256 if (x.size() != y.size())
1257 return false;
1258 if (x.size() == 0)
1259 return true;
1260 return memcmp(x.data(), y.data(), x.size()) == 0;
1261 }
1262
operator !=(const StringView & x,const StringView & y)1263 inline bool operator!=(const StringView& x, const StringView& y) {
1264 return !(x == y);
1265 }
1266
operator <(const StringView & x,const StringView & y)1267 inline bool operator<(const StringView& x, const StringView& y) {
1268 auto size = std::min(x.size(), y.size());
1269 if (size == 0)
1270 return x.size() < y.size();
1271 int result = memcmp(x.data(), y.data(), size);
1272 return result < 0 || (result == 0 && x.size() < y.size());
1273 }
1274
operator >=(const StringView & x,const StringView & y)1275 inline bool operator>=(const StringView& x, const StringView& y) {
1276 return !(x < y);
1277 }
1278
operator >(const StringView & x,const StringView & y)1279 inline bool operator>(const StringView& x, const StringView& y) {
1280 return y < x;
1281 }
1282
operator <=(const StringView & x,const StringView & y)1283 inline bool operator<=(const StringView& x, const StringView& y) {
1284 return !(y < x);
1285 }
1286
1287 } // namespace base
1288 } // namespace perfetto
1289
1290 template <>
1291 struct std::hash<::perfetto::base::StringView> {
operator ()std::hash1292 size_t operator()(const ::perfetto::base::StringView& sv) const {
1293 return static_cast<size_t>(sv.Hash());
1294 }
1295 };
1296
1297 #endif // INCLUDE_PERFETTO_EXT_BASE_STRING_VIEW_H_
1298 // gen_amalgamated begin header: include/perfetto/ext/base/utils.h
1299 /*
1300 * Copyright (C) 2017 The Android Open Source Project
1301 *
1302 * Licensed under the Apache License, Version 2.0 (the "License");
1303 * you may not use this file except in compliance with the License.
1304 * You may obtain a copy of the License at
1305 *
1306 * http://www.apache.org/licenses/LICENSE-2.0
1307 *
1308 * Unless required by applicable law or agreed to in writing, software
1309 * distributed under the License is distributed on an "AS IS" BASIS,
1310 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1311 * See the License for the specific language governing permissions and
1312 * limitations under the License.
1313 */
1314
1315 #ifndef INCLUDE_PERFETTO_EXT_BASE_UTILS_H_
1316 #define INCLUDE_PERFETTO_EXT_BASE_UTILS_H_
1317
1318 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
1319 // gen_amalgamated expanded: #include "perfetto/base/compiler.h"
1320
1321 #include <errno.h>
1322 #include <stddef.h>
1323 #include <stdint.h>
1324 #include <stdlib.h>
1325 #include <sys/types.h>
1326
1327 #include <atomic>
1328 #include <functional>
1329 #include <memory>
1330 #include <string>
1331
1332 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
1333 // Even if Windows has errno.h, the all syscall-restart behavior does not apply.
1334 // Trying to handle EINTR can cause more harm than good if errno is left stale.
1335 // Chromium does the same.
1336 #define PERFETTO_EINTR(x) (x)
1337 #else
1338 #define PERFETTO_EINTR(x) \
1339 ([&] { \
1340 decltype(x) eintr_wrapper_result; \
1341 do { \
1342 eintr_wrapper_result = (x); \
1343 } while (eintr_wrapper_result == -1 && errno == EINTR); \
1344 return eintr_wrapper_result; \
1345 }())
1346 #endif
1347
1348 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
1349 using uid_t = unsigned int;
1350 #if !PERFETTO_BUILDFLAG(PERFETTO_COMPILER_GCC)
1351 using pid_t = unsigned int;
1352 #endif
1353 #if defined(_WIN64)
1354 using ssize_t = int64_t;
1355 #else
1356 using ssize_t = long;
1357 #endif
1358 #endif
1359
1360 namespace perfetto {
1361 namespace base {
1362
1363 constexpr uid_t kInvalidUid = static_cast<uid_t>(-1);
1364 constexpr pid_t kInvalidPid = static_cast<pid_t>(-1);
1365
1366 // Do not add new usages of kPageSize, consider using GetSysPageSize() below.
1367 // TODO(primiano): over time the semantic of kPageSize became too ambiguous.
1368 // Strictly speaking, this constant is incorrect on some new devices where the
1369 // page size can be 16K (e.g., crbug.com/1116576). Unfortunately too much code
1370 // ended up depending on kPageSize for purposes that are not strictly related
1371 // with the kernel's mm subsystem.
1372 constexpr size_t kPageSize = 4096;
1373
1374 // Returns the system's page size. Use this when dealing with mmap, madvise and
1375 // similar mm-related syscalls.
1376 uint32_t GetSysPageSize();
1377
1378 template <typename T>
ArraySize(const T & array)1379 constexpr size_t ArraySize(const T& array) {
1380 return sizeof(array) / sizeof(array[0]);
1381 }
1382
1383 // Function object which invokes 'free' on its parameter, which must be
1384 // a pointer. Can be used to store malloc-allocated pointers in std::unique_ptr:
1385 //
1386 // std::unique_ptr<int, base::FreeDeleter> foo_ptr(
1387 // static_cast<int*>(malloc(sizeof(int))));
1388 struct FreeDeleter {
operator ()perfetto::base::FreeDeleter1389 inline void operator()(void* ptr) const { free(ptr); }
1390 };
1391
1392 template <typename T>
AssumeLittleEndian(T value)1393 constexpr T AssumeLittleEndian(T value) {
1394 #if !PERFETTO_IS_LITTLE_ENDIAN()
1395 static_assert(false, "Unimplemented on big-endian archs");
1396 #endif
1397 return value;
1398 }
1399
1400 // Round up |size| to a multiple of |alignment| (must be a power of two).
1401 template <size_t alignment>
AlignUp(size_t size)1402 constexpr size_t AlignUp(size_t size) {
1403 static_assert((alignment & (alignment - 1)) == 0, "alignment must be a pow2");
1404 return (size + alignment - 1) & ~(alignment - 1);
1405 }
1406
IsAgain(int err)1407 inline bool IsAgain(int err) {
1408 return err == EAGAIN || err == EWOULDBLOCK;
1409 }
1410
1411 // setenv(2)-equivalent. Deals with Windows vs Posix discrepancies.
1412 void SetEnv(const std::string& key, const std::string& value);
1413
1414 // Calls mallopt(M_PURGE, 0) on Android. Does nothing on other platforms.
1415 // This forces the allocator to release freed memory. This is used to work
1416 // around various Scudo inefficiencies. See b/170217718.
1417 void MaybeReleaseAllocatorMemToOS();
1418
1419 // geteuid() on POSIX OSes, returns 0 on Windows (See comment in utils.cc).
1420 uid_t GetCurrentUserId();
1421
1422 // Forks the process.
1423 // Parent: prints the PID of the child, calls |parent_cb| and exits from the
1424 // process with its return value.
1425 // Child: redirects stdio onto /dev/null, chdirs into / and returns.
1426 void Daemonize(std::function<int()> parent_cb);
1427
1428 // Returns the path of the current executable, e.g. /foo/bar/exe.
1429 std::string GetCurExecutablePath();
1430
1431 // Returns the directory where the current executable lives in, e.g. /foo/bar.
1432 // This is independent of cwd().
1433 std::string GetCurExecutableDir();
1434
1435 // Memory returned by AlignedAlloc() must be freed via AlignedFree() not just
1436 // free. It makes a difference on Windows where _aligned_malloc() and
1437 // _aligned_free() must be paired.
1438 // Prefer using the AlignedAllocTyped() below which takes care of the pairing.
1439 void* AlignedAlloc(size_t alignment, size_t size);
1440 void AlignedFree(void*);
1441
1442 // A RAII version of the above, which takes care of pairing Aligned{Alloc,Free}.
1443 template <typename T>
1444 struct AlignedDeleter {
operator ()perfetto::base::AlignedDeleter1445 inline void operator()(T* ptr) const { AlignedFree(ptr); }
1446 };
1447
1448 // The remove_extent<T> here and below is to allow defining unique_ptr<T[]>.
1449 // As per https://en.cppreference.com/w/cpp/memory/unique_ptr the Deleter takes
1450 // always a T*, not a T[]*.
1451 template <typename T>
1452 using AlignedUniquePtr =
1453 std::unique_ptr<T, AlignedDeleter<typename std::remove_extent<T>::type>>;
1454
1455 template <typename T>
AlignedAllocTyped(size_t n_membs)1456 AlignedUniquePtr<T> AlignedAllocTyped(size_t n_membs) {
1457 using TU = typename std::remove_extent<T>::type;
1458 return AlignedUniquePtr<T>(
1459 static_cast<TU*>(AlignedAlloc(alignof(TU), sizeof(TU) * n_membs)));
1460 }
1461
1462 // A RAII wrapper to invoke a function when leaving a function/scope.
1463 template <typename Func>
1464 class OnScopeExitWrapper {
1465 public:
OnScopeExitWrapper(Func f)1466 explicit OnScopeExitWrapper(Func f) : f_(std::move(f)), active_(true) {}
OnScopeExitWrapper(OnScopeExitWrapper && other)1467 OnScopeExitWrapper(OnScopeExitWrapper&& other) noexcept
1468 : f_(std::move(other.f_)), active_(other.active_) {
1469 other.active_ = false;
1470 }
~OnScopeExitWrapper()1471 ~OnScopeExitWrapper() {
1472 if (active_)
1473 f_();
1474 }
1475
1476 private:
1477 Func f_;
1478 bool active_;
1479 };
1480
1481 template <typename Func>
OnScopeExit(Func f)1482 PERFETTO_WARN_UNUSED_RESULT OnScopeExitWrapper<Func> OnScopeExit(Func f) {
1483 return OnScopeExitWrapper<Func>(std::move(f));
1484 }
1485
1486 // Returns a xxd-style hex dump (hex + ascii chars) of the input data.
1487 std::string HexDump(const void* data, size_t len, size_t bytes_per_line = 16);
HexDump(const std::string & data,size_t bytes_per_line=16)1488 inline std::string HexDump(const std::string& data,
1489 size_t bytes_per_line = 16) {
1490 return HexDump(data.data(), data.size(), bytes_per_line);
1491 }
1492
1493 } // namespace base
1494 } // namespace perfetto
1495
1496 #endif // INCLUDE_PERFETTO_EXT_BASE_UTILS_H_
1497 /*
1498 * Copyright (C) 2021 The Android Open Source Project
1499 *
1500 * Licensed under the Apache License, Version 2.0 (the "License");
1501 * you may not use this file except in compliance with the License.
1502 * You may obtain a copy of the License at
1503 *
1504 * http://www.apache.org/licenses/LICENSE-2.0
1505 *
1506 * Unless required by applicable law or agreed to in writing, software
1507 * distributed under the License is distributed on an "AS IS" BASIS,
1508 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1509 * See the License for the specific language governing permissions and
1510 * limitations under the License.
1511 */
1512
1513 #ifndef INCLUDE_PERFETTO_EXT_BASE_BASE64_H_
1514 #define INCLUDE_PERFETTO_EXT_BASE_BASE64_H_
1515
1516 #include <string>
1517
1518 // gen_amalgamated expanded: #include "perfetto/ext/base/optional.h"
1519 // gen_amalgamated expanded: #include "perfetto/ext/base/string_view.h"
1520 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h" // For ssize_t.
1521
1522 namespace perfetto {
1523 namespace base {
1524
1525 // Returns the length of the destination string (included '=' padding).
1526 // Does NOT include the size of the string null terminator.
Base64EncSize(size_t src_size)1527 inline size_t Base64EncSize(size_t src_size) {
1528 return (src_size + 2) / 3 * 4;
1529 }
1530
1531 // Returns the upper bound on the length of the destination buffer.
1532 // The actual decoded length might be <= the number returned here.
Base64DecSize(size_t src_size)1533 inline size_t Base64DecSize(size_t src_size) {
1534 return (src_size + 3) / 4 * 3;
1535 }
1536
1537 // Does NOT null-terminate |dst|.
1538 ssize_t Base64Encode(const void* src,
1539 size_t src_size,
1540 char* dst,
1541 size_t dst_size);
1542
1543 std::string Base64Encode(const void* src, size_t src_size);
1544
Base64Encode(StringView sv)1545 inline std::string Base64Encode(StringView sv) {
1546 return Base64Encode(sv.data(), sv.size());
1547 }
1548
1549 // Returns -1 in case of failure.
1550 ssize_t Base64Decode(const char* src,
1551 size_t src_size,
1552 uint8_t* dst,
1553 size_t dst_size);
1554
1555 Optional<std::string> Base64Decode(const char* src, size_t src_size);
1556
Base64Decode(StringView sv)1557 inline Optional<std::string> Base64Decode(StringView sv) {
1558 return Base64Decode(sv.data(), sv.size());
1559 }
1560
1561 } // namespace base
1562 } // namespace perfetto
1563
1564 #endif // INCLUDE_PERFETTO_EXT_BASE_BASE64_H_
1565 /*
1566 * Copyright (C) 2021 The Android Open Source Project
1567 *
1568 * Licensed under the Apache License, Version 2.0 (the "License");
1569 * you may not use this file except in compliance with the License.
1570 * You may obtain a copy of the License at
1571 *
1572 * http://www.apache.org/licenses/LICENSE-2.0
1573 *
1574 * Unless required by applicable law or agreed to in writing, software
1575 * distributed under the License is distributed on an "AS IS" BASIS,
1576 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1577 * See the License for the specific language governing permissions and
1578 * limitations under the License.
1579 */
1580
1581 // gen_amalgamated expanded: #include "perfetto/ext/base/base64.h"
1582
1583 namespace perfetto {
1584 namespace base {
1585
1586 namespace {
1587
1588 constexpr char kPadding = '=';
1589
1590 constexpr char kEncTable[] =
1591 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1592 static_assert(sizeof(kEncTable) == (1u << 6) + sizeof('\0'), "Bad table size");
1593
1594 // Maps an ASCII character to its 6-bit value. It only contains translations
1595 // from '+' to 'z'. Supports the standard (+/) and URL-safe (-_) alphabets.
1596 constexpr uint8_t kX = 0xff; // Value used for invalid characters
1597 constexpr uint8_t kDecTable[] = {
1598 62, kX, 62, kX, 63, 52, 53, 54, 55, 56, // 00 - 09
1599 57, 58, 59, 60, 61, kX, kX, kX, 0, kX, // 10 - 19
1600 kX, kX, 0, 1, 2, 3, 4, 5, 6, 7, // 20 - 29
1601 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, // 30 - 39
1602 18, 19, 20, 21, 22, 23, 24, 25, kX, kX, // 40 - 49
1603 kX, kX, 63, kX, 26, 27, 28, 29, 30, 31, // 50 - 59
1604 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, // 60 - 69
1605 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // 70 - 79
1606 };
1607 constexpr char kMinDecChar = '+';
1608 constexpr char kMaxDecChar = 'z';
1609 static_assert(kMaxDecChar - kMinDecChar <= sizeof(kDecTable), "Bad table size");
1610
DecodeChar(char c)1611 inline uint8_t DecodeChar(char c) {
1612 if (c < kMinDecChar || c > kMaxDecChar)
1613 return kX;
1614 return kDecTable[c - kMinDecChar];
1615 }
1616
1617 } // namespace
1618
Base64Encode(const void * src,size_t src_size,char * dst,size_t dst_size)1619 ssize_t Base64Encode(const void* src,
1620 size_t src_size,
1621 char* dst,
1622 size_t dst_size) {
1623 const size_t padded_dst_size = Base64EncSize(src_size);
1624 if (dst_size < padded_dst_size)
1625 return -1; // Not enough space in output.
1626
1627 const uint8_t* rd = static_cast<const uint8_t*>(src);
1628 const uint8_t* const end = rd + src_size;
1629 size_t wr_size = 0;
1630 while (rd < end) {
1631 uint8_t s[3]{};
1632 s[0] = *(rd++);
1633 dst[wr_size++] = kEncTable[s[0] >> 2];
1634
1635 uint8_t carry0 = static_cast<uint8_t>((s[0] & 0x03) << 4);
1636 if (PERFETTO_LIKELY(rd < end)) {
1637 s[1] = *(rd++);
1638 dst[wr_size++] = kEncTable[carry0 | (s[1] >> 4)];
1639 } else {
1640 dst[wr_size++] = kEncTable[carry0];
1641 dst[wr_size++] = kPadding;
1642 dst[wr_size++] = kPadding;
1643 break;
1644 }
1645
1646 uint8_t carry1 = static_cast<uint8_t>((s[1] & 0x0f) << 2);
1647 if (PERFETTO_LIKELY(rd < end)) {
1648 s[2] = *(rd++);
1649 dst[wr_size++] = kEncTable[carry1 | (s[2] >> 6)];
1650 } else {
1651 dst[wr_size++] = kEncTable[carry1];
1652 dst[wr_size++] = kPadding;
1653 break;
1654 }
1655
1656 dst[wr_size++] = kEncTable[s[2] & 0x3f];
1657 }
1658 PERFETTO_DCHECK(wr_size == padded_dst_size);
1659 return static_cast<ssize_t>(padded_dst_size);
1660 }
1661
Base64Encode(const void * src,size_t src_size)1662 std::string Base64Encode(const void* src, size_t src_size) {
1663 std::string dst;
1664 dst.resize(Base64EncSize(src_size));
1665 auto res = Base64Encode(src, src_size, &dst[0], dst.size());
1666 PERFETTO_CHECK(res == static_cast<ssize_t>(dst.size()));
1667 return dst;
1668 }
1669
Base64Decode(const char * src,size_t src_size,uint8_t * dst,size_t dst_size)1670 ssize_t Base64Decode(const char* src,
1671 size_t src_size,
1672 uint8_t* dst,
1673 size_t dst_size) {
1674 const size_t min_dst_size = Base64DecSize(src_size);
1675 if (dst_size < min_dst_size)
1676 return -1;
1677
1678 const char* rd = src;
1679 const char* const end = src + src_size;
1680 size_t wr_size = 0;
1681
1682 char s[4]{};
1683 while (rd < end) {
1684 uint8_t d[4];
1685 for (uint32_t j = 0; j < 4; j++) {
1686 // Padding is only feasible for the last 2 chars of each group of 4.
1687 s[j] = rd < end ? *(rd++) : (j < 2 ? '\0' : kPadding);
1688 d[j] = DecodeChar(s[j]);
1689 if (d[j] == kX)
1690 return -1; // Invalid input char.
1691 }
1692 dst[wr_size] = static_cast<uint8_t>((d[0] << 2) | (d[1] >> 4));
1693 dst[wr_size + 1] = static_cast<uint8_t>((d[1] << 4) | (d[2] >> 2));
1694 dst[wr_size + 2] = static_cast<uint8_t>((d[2] << 6) | (d[3]));
1695 wr_size += 3;
1696 }
1697
1698 PERFETTO_CHECK(wr_size <= dst_size);
1699 wr_size -= (s[3] == kPadding ? 1 : 0) + (s[2] == kPadding ? 1 : 0);
1700 return static_cast<ssize_t>(wr_size);
1701 }
1702
Base64Decode(const char * src,size_t src_size)1703 Optional<std::string> Base64Decode(const char* src, size_t src_size) {
1704 std::string dst;
1705 dst.resize(Base64DecSize(src_size));
1706 auto res = Base64Decode(src, src_size, reinterpret_cast<uint8_t*>(&dst[0]),
1707 dst.size());
1708 if (res < 0)
1709 return nullopt; // Decoding error.
1710
1711 PERFETTO_CHECK(res <= static_cast<ssize_t>(dst.size()));
1712 dst.resize(static_cast<size_t>(res));
1713 return base::make_optional(dst);
1714 }
1715
1716 } // namespace base
1717 } // namespace perfetto
1718 // gen_amalgamated begin source: src/base/crash_keys.cc
1719 // gen_amalgamated begin header: include/perfetto/ext/base/crash_keys.h
1720 /*
1721 * Copyright (C) 2021 The Android Open Source Project
1722 *
1723 * Licensed under the Apache License, Version 2.0 (the "License");
1724 * you may not use this file except in compliance with the License.
1725 * You may obtain a copy of the License at
1726 *
1727 * http://www.apache.org/licenses/LICENSE-2.0
1728 *
1729 * Unless required by applicable law or agreed to in writing, software
1730 * distributed under the License is distributed on an "AS IS" BASIS,
1731 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1732 * See the License for the specific language governing permissions and
1733 * limitations under the License.
1734 */
1735
1736 #ifndef INCLUDE_PERFETTO_EXT_BASE_CRASH_KEYS_H_
1737 #define INCLUDE_PERFETTO_EXT_BASE_CRASH_KEYS_H_
1738
1739 #include <algorithm>
1740 #include <atomic>
1741
1742 #include <stdint.h>
1743 #include <string.h>
1744
1745 // gen_amalgamated expanded: #include "perfetto/base/compiler.h"
1746 // gen_amalgamated expanded: #include "perfetto/ext/base/string_view.h"
1747
1748 // Crash keys are very simple global variables with static-storage that
1749 // are reported on crash time for managed crashes (CHECK/FATAL/Watchdog).
1750 // - Translation units can define a CrashKey and register it at some point
1751 // during initialization.
1752 // - CrashKey instances must be long-lived. They should really be just global
1753 // static variable in the anonymous namespace.
1754 // Example:
1755 // subsystem_1.cc
1756 // CrashKey g_client_id("ipc_client_id");
1757 // ...
1758 // OnIpcReceived(client_id) {
1759 // g_client_id.Set(client_id);
1760 // ... // Process the IPC
1761 // g_client_id.Clear();
1762 // }
1763 // Or equivalently:
1764 // OnIpcReceived(client_id) {
1765 // auto scoped_key = g_client_id.SetScoped(client_id);
1766 // ... // Process the IPC
1767 // }
1768 //
1769 // If a crash happens while processing the IPC, the crash report will
1770 // have a line "ipc_client_id: 42".
1771 //
1772 // Thread safety considerations:
1773 // CrashKeys can be registered and set/cleared from any thread.
1774 // There is no compelling use-case to have full acquire/release consistency when
1775 // setting a key. This means that if a thread crashes immediately after a
1776 // crash key has been set on another thread, the value printed on the crash
1777 // report could be incomplete. The code guarantees defined behavior and does
1778 // not rely on null-terminated string (in the worst case 32 bytes of random
1779 // garbage will be printed out).
1780
1781 // The tests live in logging_unittest.cc.
1782
1783 namespace perfetto {
1784 namespace base {
1785
1786 constexpr size_t kCrashKeyMaxStrSize = 32;
1787
1788 // CrashKey instances must be long lived
1789 class CrashKey {
1790 public:
1791 class ScopedClear {
1792 public:
ScopedClear(CrashKey * k)1793 explicit ScopedClear(CrashKey* k) : key_(k) {}
~ScopedClear()1794 ~ScopedClear() {
1795 if (key_)
1796 key_->Clear();
1797 }
1798 ScopedClear(const ScopedClear&) = delete;
1799 ScopedClear& operator=(const ScopedClear&) = delete;
1800 ScopedClear& operator=(ScopedClear&&) = delete;
ScopedClear(ScopedClear && other)1801 ScopedClear(ScopedClear&& other) noexcept : key_(other.key_) {
1802 other.key_ = nullptr;
1803 }
1804
1805 private:
1806 CrashKey* key_;
1807 };
1808
1809 // constexpr so it can be used in the anon namespace without requiring a
1810 // global constructor.
1811 // |name| must be a long-lived string.
CrashKey(const char * name)1812 constexpr explicit CrashKey(const char* name)
1813 : registered_{}, type_(Type::kUnset), name_(name), str_value_{} {}
1814 CrashKey(const CrashKey&) = delete;
1815 CrashKey& operator=(const CrashKey&) = delete;
1816 CrashKey(CrashKey&&) = delete;
1817 CrashKey& operator=(CrashKey&&) = delete;
1818
1819 enum class Type : uint8_t { kUnset = 0, kInt, kStr };
1820
Clear()1821 void Clear() {
1822 int_value_.store(0, std::memory_order_relaxed);
1823 type_.store(Type::kUnset, std::memory_order_relaxed);
1824 }
1825
Set(int64_t value)1826 void Set(int64_t value) {
1827 int_value_.store(value, std::memory_order_relaxed);
1828 type_.store(Type::kInt, std::memory_order_relaxed);
1829 if (PERFETTO_UNLIKELY(!registered_.load(std::memory_order_relaxed)))
1830 Register();
1831 }
1832
Set(StringView sv)1833 void Set(StringView sv) {
1834 size_t len = std::min(sv.size(), sizeof(str_value_) - 1);
1835 for (size_t i = 0; i < len; ++i)
1836 str_value_[i].store(sv.data()[i], std::memory_order_relaxed);
1837 str_value_[len].store('\0', std::memory_order_relaxed);
1838 type_.store(Type::kStr, std::memory_order_relaxed);
1839 if (PERFETTO_UNLIKELY(!registered_.load(std::memory_order_relaxed)))
1840 Register();
1841 }
1842
SetScoped(int64_t value)1843 ScopedClear SetScoped(int64_t value) PERFETTO_WARN_UNUSED_RESULT {
1844 Set(value);
1845 return ScopedClear(this);
1846 }
1847
SetScoped(StringView sv)1848 ScopedClear SetScoped(StringView sv) PERFETTO_WARN_UNUSED_RESULT {
1849 Set(sv);
1850 return ScopedClear(this);
1851 }
1852
1853 void Register();
1854
int_value() const1855 int64_t int_value() const {
1856 return int_value_.load(std::memory_order_relaxed);
1857 }
1858 size_t ToString(char* dst, size_t len);
1859
1860 private:
1861 std::atomic<bool> registered_;
1862 std::atomic<Type> type_;
1863 const char* const name_;
1864 union {
1865 std::atomic<char> str_value_[kCrashKeyMaxStrSize];
1866 std::atomic<int64_t> int_value_;
1867 };
1868 };
1869
1870 // Fills |dst| with a string containing one line for each crash key
1871 // (excluding the unset ones).
1872 // Returns number of chars written, without counting the NUL terminator.
1873 // This is used in logging.cc when emitting the crash report abort message.
1874 size_t SerializeCrashKeys(char* dst, size_t len);
1875
1876 void UnregisterAllCrashKeysForTesting();
1877
1878 } // namespace base
1879 } // namespace perfetto
1880
1881 #endif // INCLUDE_PERFETTO_EXT_BASE_CRASH_KEYS_H_
1882 // gen_amalgamated begin header: include/perfetto/ext/base/string_utils.h
1883 /*
1884 * Copyright (C) 2018 The Android Open Source Project
1885 *
1886 * Licensed under the Apache License, Version 2.0 (the "License");
1887 * you may not use this file except in compliance with the License.
1888 * You may obtain a copy of the License at
1889 *
1890 * http://www.apache.org/licenses/LICENSE-2.0
1891 *
1892 * Unless required by applicable law or agreed to in writing, software
1893 * distributed under the License is distributed on an "AS IS" BASIS,
1894 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1895 * See the License for the specific language governing permissions and
1896 * limitations under the License.
1897 */
1898
1899 #ifndef INCLUDE_PERFETTO_EXT_BASE_STRING_UTILS_H_
1900 #define INCLUDE_PERFETTO_EXT_BASE_STRING_UTILS_H_
1901
1902 #include <stdarg.h>
1903 #include <stdlib.h>
1904 #include <string.h>
1905
1906 #include <cinttypes>
1907 #include <string>
1908 #include <vector>
1909
1910 // gen_amalgamated expanded: #include "perfetto/ext/base/optional.h"
1911 // gen_amalgamated expanded: #include "perfetto/ext/base/string_view.h"
1912
1913 namespace perfetto {
1914 namespace base {
1915
Lowercase(char c)1916 inline char Lowercase(char c) {
1917 return ('A' <= c && c <= 'Z') ? static_cast<char>(c - ('A' - 'a')) : c;
1918 }
1919
Uppercase(char c)1920 inline char Uppercase(char c) {
1921 return ('a' <= c && c <= 'z') ? static_cast<char>(c + ('A' - 'a')) : c;
1922 }
1923
CStringToUInt32(const char * s,int base=10)1924 inline Optional<uint32_t> CStringToUInt32(const char* s, int base = 10) {
1925 char* endptr = nullptr;
1926 auto value = static_cast<uint32_t>(strtoul(s, &endptr, base));
1927 return (*s && !*endptr) ? base::make_optional(value) : base::nullopt;
1928 }
1929
CStringToInt32(const char * s,int base=10)1930 inline Optional<int32_t> CStringToInt32(const char* s, int base = 10) {
1931 char* endptr = nullptr;
1932 auto value = static_cast<int32_t>(strtol(s, &endptr, base));
1933 return (*s && !*endptr) ? base::make_optional(value) : base::nullopt;
1934 }
1935
1936 // Note: it saturates to 7fffffffffffffff if parsing a hex number >= 0x8000...
CStringToInt64(const char * s,int base=10)1937 inline Optional<int64_t> CStringToInt64(const char* s, int base = 10) {
1938 char* endptr = nullptr;
1939 auto value = static_cast<int64_t>(strtoll(s, &endptr, base));
1940 return (*s && !*endptr) ? base::make_optional(value) : base::nullopt;
1941 }
1942
CStringToUInt64(const char * s,int base=10)1943 inline Optional<uint64_t> CStringToUInt64(const char* s, int base = 10) {
1944 char* endptr = nullptr;
1945 auto value = static_cast<uint64_t>(strtoull(s, &endptr, base));
1946 return (*s && !*endptr) ? base::make_optional(value) : base::nullopt;
1947 }
1948
1949 double StrToD(const char* nptr, char** endptr);
1950
CStringToDouble(const char * s)1951 inline Optional<double> CStringToDouble(const char* s) {
1952 char* endptr = nullptr;
1953 double value = StrToD(s, &endptr);
1954 Optional<double> result(base::nullopt);
1955 if (*s != '\0' && *endptr == '\0')
1956 result = value;
1957 return result;
1958 }
1959
StringToUInt32(const std::string & s,int base=10)1960 inline Optional<uint32_t> StringToUInt32(const std::string& s, int base = 10) {
1961 return CStringToUInt32(s.c_str(), base);
1962 }
1963
StringToInt32(const std::string & s,int base=10)1964 inline Optional<int32_t> StringToInt32(const std::string& s, int base = 10) {
1965 return CStringToInt32(s.c_str(), base);
1966 }
1967
StringToUInt64(const std::string & s,int base=10)1968 inline Optional<uint64_t> StringToUInt64(const std::string& s, int base = 10) {
1969 return CStringToUInt64(s.c_str(), base);
1970 }
1971
StringToInt64(const std::string & s,int base=10)1972 inline Optional<int64_t> StringToInt64(const std::string& s, int base = 10) {
1973 return CStringToInt64(s.c_str(), base);
1974 }
1975
StringToDouble(const std::string & s)1976 inline Optional<double> StringToDouble(const std::string& s) {
1977 return CStringToDouble(s.c_str());
1978 }
1979
1980 bool StartsWith(const std::string& str, const std::string& prefix);
1981 bool EndsWith(const std::string& str, const std::string& suffix);
1982 bool StartsWithAny(const std::string& str,
1983 const std::vector<std::string>& prefixes);
1984 bool Contains(const std::string& haystack, const std::string& needle);
1985 bool Contains(const std::string& haystack, char needle);
1986 size_t Find(const StringView& needle, const StringView& haystack);
1987 bool CaseInsensitiveEqual(const std::string& first, const std::string& second);
1988 std::string Join(const std::vector<std::string>& parts,
1989 const std::string& delim);
1990 std::vector<std::string> SplitString(const std::string& text,
1991 const std::string& delimiter);
1992 std::string StripPrefix(const std::string& str, const std::string& prefix);
1993 std::string StripSuffix(const std::string& str, const std::string& suffix);
1994 std::string ToLower(const std::string& str);
1995 std::string ToUpper(const std::string& str);
1996 std::string StripChars(const std::string& str,
1997 const std::string& chars,
1998 char replacement);
1999 std::string ToHex(const char* data, size_t size);
ToHex(const std::string & s)2000 inline std::string ToHex(const std::string& s) {
2001 return ToHex(s.c_str(), s.size());
2002 }
2003 std::string IntToHexString(uint32_t number);
2004 std::string Uint64ToHexString(uint64_t number);
2005 std::string Uint64ToHexStringNoPrefix(uint64_t number);
2006 std::string ReplaceAll(std::string str,
2007 const std::string& to_replace,
2008 const std::string& replacement);
2009 std::string TrimLeading(const std::string& str);
2010
2011 // A BSD-style strlcpy without the return value.
2012 // Copies at most |dst_size|-1 characters. Unlike strncpy, it always \0
2013 // terminates |dst|, as long as |dst_size| is not 0.
2014 // Unlike strncpy and like strlcpy it does not zero-pad the rest of |dst|.
2015 // Returns nothing. The BSD strlcpy returns the size of |src|, which might
2016 // be > |dst_size|. Anecdotal experience suggests people assume the return value
2017 // is the number of bytes written in |dst|. That assumption can lead to
2018 // dangerous bugs.
2019 // In order to avoid being subtly uncompliant with strlcpy AND avoid misuse,
2020 // the choice here is to return nothing.
StringCopy(char * dst,const char * src,size_t dst_size)2021 inline void StringCopy(char* dst, const char* src, size_t dst_size) {
2022 for (size_t i = 0; i < dst_size; ++i) {
2023 if ((dst[i] = src[i]) == '\0') {
2024 return; // We hit and copied the null terminator.
2025 }
2026 }
2027
2028 // We were left off at dst_size. We over copied 1 byte. Null terminate.
2029 if (PERFETTO_LIKELY(dst_size > 0))
2030 dst[dst_size - 1] = 0;
2031 }
2032
2033 // Like snprintf() but returns the number of chars *actually* written (without
2034 // counting the null terminator) NOT "the number of chars which would have been
2035 // written to the final string if enough space had been available".
2036 // This should be used in almost all cases when the caller uses the return value
2037 // of snprintf(). If the return value is not used, there is no benefit in using
2038 // this wrapper, as this just calls snprintf() and mangles the return value.
2039 // It always null-terminates |dst| (even in case of errors), unless
2040 // |dst_size| == 0.
2041 // Examples:
2042 // SprintfTrunc(x, 4, "123whatever"): returns 3 and writes "123\0".
2043 // SprintfTrunc(x, 4, "123"): returns 3 and writes "123\0".
2044 // SprintfTrunc(x, 3, "123"): returns 2 and writes "12\0".
2045 // SprintfTrunc(x, 2, "123"): returns 1 and writes "1\0".
2046 // SprintfTrunc(x, 1, "123"): returns 0 and writes "\0".
2047 // SprintfTrunc(x, 0, "123"): returns 0 and writes nothing.
2048 // NOTE: This means that the caller has no way to tell when truncation happens
2049 // vs the edge case of *just* fitting in the buffer.
2050 size_t SprintfTrunc(char* dst, size_t dst_size, const char* fmt, ...)
2051 PERFETTO_PRINTF_FORMAT(3, 4);
2052
2053 // A helper class to facilitate construction and usage of write-once stack
2054 // strings.
2055 // Example usage:
2056 // StackString<32> x("format %d %s", 42, string_arg);
2057 // TakeString(x.c_str() | x.string_view() | x.ToStdString());
2058 // Rather than char x[32] + sprintf.
2059 // Advantages:
2060 // - Avoids useless zero-fills caused by people doing `char buf[32] {}` (mainly
2061 // by fearing unknown snprintf failure modes).
2062 // - Makes the code more robust in case of snprintf truncations (len() and
2063 // string_view() will return the truncated length, unlike snprintf).
2064 template <size_t N>
2065 class StackString {
2066 public:
2067 explicit PERFETTO_PRINTF_FORMAT(/* 1=this */ 2, 3)
StackString(const char * fmt,...)2068 StackString(const char* fmt, ...) {
2069 buf_[0] = '\0';
2070 va_list args;
2071 va_start(args, fmt);
2072 int res = vsnprintf(buf_, sizeof(buf_), fmt, args);
2073 va_end(args);
2074 buf_[sizeof(buf_) - 1] = '\0';
2075 len_ = res < 0 ? 0 : std::min(static_cast<size_t>(res), sizeof(buf_) - 1);
2076 }
2077
string_view() const2078 StringView string_view() const { return StringView(buf_, len_); }
ToStdString() const2079 std::string ToStdString() const { return std::string(buf_, len_); }
c_str() const2080 const char* c_str() const { return buf_; }
len() const2081 size_t len() const { return len_; }
2082
2083 private:
2084 char buf_[N];
2085 size_t len_ = 0; // Does not include the \0.
2086 };
2087
2088 } // namespace base
2089 } // namespace perfetto
2090
2091 #endif // INCLUDE_PERFETTO_EXT_BASE_STRING_UTILS_H_
2092 /*
2093 * Copyright (C) 2021 The Android Open Source Project
2094 *
2095 * Licensed under the Apache License, Version 2.0 (the "License");
2096 * you may not use this file except in compliance with the License.
2097 * You may obtain a copy of the License at
2098 *
2099 * http://www.apache.org/licenses/LICENSE-2.0
2100 *
2101 * Unless required by applicable law or agreed to in writing, software
2102 * distributed under the License is distributed on an "AS IS" BASIS,
2103 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2104 * See the License for the specific language governing permissions and
2105 * limitations under the License.
2106 */
2107
2108 // gen_amalgamated expanded: #include "perfetto/ext/base/crash_keys.h"
2109
2110 #include <string.h>
2111
2112 #include <atomic>
2113 #include <cinttypes>
2114
2115 // gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
2116
2117 namespace perfetto {
2118 namespace base {
2119
2120 namespace {
2121
2122 constexpr size_t kMaxKeys = 32;
2123
2124 std::atomic<CrashKey*> g_keys[kMaxKeys]{};
2125 std::atomic<uint32_t> g_num_keys{};
2126 } // namespace
2127
Register()2128 void CrashKey::Register() {
2129 // If doesn't matter if we fail below. If there are no slots left, don't
2130 // keep trying re-registering on every Set(), the outcome won't change.
2131
2132 // If two threads raced on the Register(), avoid registering the key twice.
2133 if (registered_.exchange(true))
2134 return;
2135
2136 uint32_t slot = g_num_keys.fetch_add(1);
2137 if (slot >= kMaxKeys) {
2138 PERFETTO_LOG("Too many crash keys registered");
2139 return;
2140 }
2141 g_keys[slot].store(this);
2142 }
2143
2144 // Returns the number of chars written, without counting the \0.
ToString(char * dst,size_t len)2145 size_t CrashKey::ToString(char* dst, size_t len) {
2146 if (len > 0)
2147 *dst = '\0';
2148 switch (type_.load(std::memory_order_relaxed)) {
2149 case Type::kUnset:
2150 break;
2151 case Type::kInt:
2152 return SprintfTrunc(dst, len, "%s: %" PRId64 "\n", name_,
2153 int_value_.load(std::memory_order_relaxed));
2154 case Type::kStr:
2155 char buf[sizeof(str_value_)];
2156 for (size_t i = 0; i < sizeof(str_value_); i++)
2157 buf[i] = str_value_[i].load(std::memory_order_relaxed);
2158
2159 // Don't assume |str_value_| is properly null-terminated.
2160 return SprintfTrunc(dst, len, "%s: %.*s\n", name_, int(sizeof(buf)), buf);
2161 }
2162 return 0;
2163 }
2164
UnregisterAllCrashKeysForTesting()2165 void UnregisterAllCrashKeysForTesting() {
2166 g_num_keys.store(0);
2167 for (auto& key : g_keys)
2168 key.store(nullptr);
2169 }
2170
SerializeCrashKeys(char * dst,size_t len)2171 size_t SerializeCrashKeys(char* dst, size_t len) {
2172 size_t written = 0;
2173 uint32_t num_keys = g_num_keys.load();
2174 if (len > 0)
2175 *dst = '\0';
2176 for (uint32_t i = 0; i < num_keys && written < len; i++) {
2177 CrashKey* key = g_keys[i].load();
2178 if (!key)
2179 continue; // Can happen if we hit this between the add and the store.
2180 written += key->ToString(dst + written, len - written);
2181 }
2182 PERFETTO_DCHECK(written <= len);
2183 PERFETTO_DCHECK(len == 0 || dst[written] == '\0');
2184 return written;
2185 }
2186
2187 } // namespace base
2188 } // namespace perfetto
2189 // gen_amalgamated begin source: src/base/ctrl_c_handler.cc
2190 // gen_amalgamated begin header: include/perfetto/ext/base/ctrl_c_handler.h
2191 /*
2192 * Copyright (C) 2021 The Android Open Source Project
2193 *
2194 * Licensed under the Apache License, Version 2.0 (the "License");
2195 * you may not use this file except in compliance with the License.
2196 * You may obtain a copy of the License at
2197 *
2198 * http://www.apache.org/licenses/LICENSE-2.0
2199 *
2200 * Unless required by applicable law or agreed to in writing, software
2201 * distributed under the License is distributed on an "AS IS" BASIS,
2202 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2203 * See the License for the specific language governing permissions and
2204 * limitations under the License.
2205 */
2206
2207 #ifndef INCLUDE_PERFETTO_EXT_BASE_CTRL_C_HANDLER_H_
2208 #define INCLUDE_PERFETTO_EXT_BASE_CTRL_C_HANDLER_H_
2209
2210 namespace perfetto {
2211 namespace base {
2212
2213 // On Linux/Android/Mac: installs SIGINT + SIGTERM signal handlers.
2214 // On Windows: installs a SetConsoleCtrlHandler() handler.
2215 // The passed handler must be async safe.
2216 using CtrlCHandlerFunction = void (*)();
2217 void InstallCtrCHandler(CtrlCHandlerFunction);
2218
2219 } // namespace base
2220 } // namespace perfetto
2221
2222 #endif // INCLUDE_PERFETTO_EXT_BASE_CTRL_C_HANDLER_H_
2223 /*
2224 * Copyright (C) 2021 The Android Open Source Project
2225 *
2226 * Licensed under the Apache License, Version 2.0 (the "License");
2227 * you may not use this file except in compliance with the License.
2228 * You may obtain a copy of the License at
2229 *
2230 * http://www.apache.org/licenses/LICENSE-2.0
2231 *
2232 * Unless required by applicable law or agreed to in writing, software
2233 * distributed under the License is distributed on an "AS IS" BASIS,
2234 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2235 * See the License for the specific language governing permissions and
2236 * limitations under the License.
2237 */
2238
2239 // gen_amalgamated expanded: #include "perfetto/ext/base/ctrl_c_handler.h"
2240
2241 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
2242 // gen_amalgamated expanded: #include "perfetto/base/compiler.h"
2243 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
2244
2245 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
2246 #include <Windows.h>
2247 #include <io.h>
2248 #else
2249 #include <signal.h>
2250 #include <unistd.h>
2251 #endif
2252
2253 namespace perfetto {
2254 namespace base {
2255
2256 namespace {
2257 CtrlCHandlerFunction g_handler = nullptr;
2258 }
2259
InstallCtrCHandler(CtrlCHandlerFunction handler)2260 void InstallCtrCHandler(CtrlCHandlerFunction handler) {
2261 PERFETTO_CHECK(g_handler == nullptr);
2262 g_handler = handler;
2263
2264 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
2265 auto trampoline = [](DWORD type) -> int {
2266 if (type == CTRL_C_EVENT) {
2267 g_handler();
2268 return true;
2269 }
2270 return false;
2271 };
2272 ::SetConsoleCtrlHandler(trampoline, true);
2273 #elif PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
2274 PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
2275 PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
2276 // Setup signal handler.
2277 struct sigaction sa {};
2278
2279 // Glibc headers for sa_sigaction trigger this.
2280 #pragma GCC diagnostic push
2281 #if defined(__clang__)
2282 #pragma GCC diagnostic ignored "-Wdisabled-macro-expansion"
2283 #endif
2284 sa.sa_handler = [](int) { g_handler(); };
2285 sa.sa_flags = static_cast<decltype(sa.sa_flags)>(SA_RESETHAND | SA_RESTART);
2286 #pragma GCC diagnostic pop
2287 sigaction(SIGINT, &sa, nullptr);
2288 sigaction(SIGTERM, &sa, nullptr);
2289 #else
2290 // Do nothing on NaCL and Fuchsia.
2291 ignore_result(handler);
2292 #endif
2293 }
2294
2295 } // namespace base
2296 } // namespace perfetto
2297 // gen_amalgamated begin source: src/base/event_fd.cc
2298 // gen_amalgamated begin header: include/perfetto/ext/base/event_fd.h
2299 // gen_amalgamated begin header: include/perfetto/base/platform_handle.h
2300 /*
2301 * Copyright (C) 2020 The Android Open Source Project
2302 *
2303 * Licensed under the Apache License, Version 2.0 (the "License");
2304 * you may not use this file except in compliance with the License.
2305 * You may obtain a copy of the License at
2306 *
2307 * http://www.apache.org/licenses/LICENSE-2.0
2308 *
2309 * Unless required by applicable law or agreed to in writing, software
2310 * distributed under the License is distributed on an "AS IS" BASIS,
2311 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2312 * See the License for the specific language governing permissions and
2313 * limitations under the License.
2314 */
2315
2316 #ifndef INCLUDE_PERFETTO_BASE_PLATFORM_HANDLE_H_
2317 #define INCLUDE_PERFETTO_BASE_PLATFORM_HANDLE_H_
2318
2319 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
2320
2321 namespace perfetto {
2322 namespace base {
2323
2324 // PlatformHandle should be used only for types that are HANDLE(s) in Windows.
2325 // It should NOT be used to blanket-replace "int fd" in the codebase.
2326 // Windows has two types of "handles", which, in UNIX-land, both map to int:
2327 // 1. File handles returned by the posix-compatibility API like _open().
2328 // These are just int(s) and should stay such, because all the posix-like API
2329 // in Windows.h take an int, not a HANDLE.
2330 // 2. Handles returned by old-school WINAPI like CreateFile, CreateEvent etc.
2331 // These are proper HANDLE(s). PlatformHandle should be used here.
2332 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
2333 // Windows.h typedefs HANDLE to void*. We use void* here to avoid leaking
2334 // Windows.h through our headers.
2335 using PlatformHandle = void*;
2336
2337 // On Windows both nullptr and 0xffff... (INVALID_HANDLE_VALUE) are invalid.
2338 struct PlatformHandleChecker {
IsValidperfetto::base::PlatformHandleChecker2339 static inline bool IsValid(PlatformHandle h) {
2340 return h && h != reinterpret_cast<PlatformHandle>(-1);
2341 }
2342 };
2343 #else
2344 using PlatformHandle = int;
2345 struct PlatformHandleChecker {
2346 static inline bool IsValid(PlatformHandle h) { return h >= 0; }
2347 };
2348 #endif
2349
2350 // The definition of this lives in base/file_utils.cc (to avoid creating an
2351 // extra build edge for a one liner). This is really an alias for close() (UNIX)
2352 // CloseHandle() (Windows). THe indirection layer is just to avoid leaking
2353 // system headers like Windows.h through perfetto headers.
2354 // Thre return value is always UNIX-style: 0 on success, -1 on failure.
2355 int ClosePlatformHandle(PlatformHandle);
2356
2357 } // namespace base
2358 } // namespace perfetto
2359
2360 #endif // INCLUDE_PERFETTO_BASE_PLATFORM_HANDLE_H_
2361 // gen_amalgamated begin header: include/perfetto/ext/base/scoped_file.h
2362 /*
2363 * Copyright (C) 2017 The Android Open Source Project
2364 *
2365 * Licensed under the Apache License, Version 2.0 (the "License");
2366 * you may not use this file except in compliance with the License.
2367 * You may obtain a copy of the License at
2368 *
2369 * http://www.apache.org/licenses/LICENSE-2.0
2370 *
2371 * Unless required by applicable law or agreed to in writing, software
2372 * distributed under the License is distributed on an "AS IS" BASIS,
2373 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2374 * See the License for the specific language governing permissions and
2375 * limitations under the License.
2376 */
2377
2378 #ifndef INCLUDE_PERFETTO_EXT_BASE_SCOPED_FILE_H_
2379 #define INCLUDE_PERFETTO_EXT_BASE_SCOPED_FILE_H_
2380
2381 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
2382
2383 #include <stdio.h>
2384
2385 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
2386 #include <dirent.h> // For DIR* / opendir().
2387 #endif
2388
2389 #include <string>
2390
2391 // gen_amalgamated expanded: #include "perfetto/base/export.h"
2392 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
2393 // gen_amalgamated expanded: #include "perfetto/base/platform_handle.h"
2394
2395 namespace perfetto {
2396 namespace base {
2397
2398 namespace internal {
2399 // Used for the most common cases of ScopedResource where there is only one
2400 // invalid value.
2401 template <typename T, T InvalidValue>
2402 struct DefaultValidityChecker {
IsValidperfetto::base::internal::DefaultValidityChecker2403 static bool IsValid(T t) { return t != InvalidValue; }
2404 };
2405 } // namespace internal
2406
2407 // RAII classes for auto-releasing fds and dirs.
2408 // if T is a pointer type, InvalidValue must be nullptr. Doing otherwise
2409 // causes weird unexpected behaviors (See https://godbolt.org/z/5nGMW4).
2410 template <typename T,
2411 int (*CloseFunction)(T),
2412 T InvalidValue,
2413 bool CheckClose = true,
2414 class Checker = internal::DefaultValidityChecker<T, InvalidValue>>
2415 class PERFETTO_EXPORT ScopedResource {
2416 public:
2417 using ValidityChecker = Checker;
2418 static constexpr T kInvalid = InvalidValue;
2419
ScopedResource(T t=InvalidValue)2420 explicit ScopedResource(T t = InvalidValue) : t_(t) {}
ScopedResource(ScopedResource && other)2421 ScopedResource(ScopedResource&& other) noexcept {
2422 t_ = other.t_;
2423 other.t_ = InvalidValue;
2424 }
operator =(ScopedResource && other)2425 ScopedResource& operator=(ScopedResource&& other) {
2426 reset(other.t_);
2427 other.t_ = InvalidValue;
2428 return *this;
2429 }
get() const2430 T get() const { return t_; }
operator *() const2431 T operator*() const { return t_; }
operator bool() const2432 explicit operator bool() const { return Checker::IsValid(t_); }
reset(T r=InvalidValue)2433 void reset(T r = InvalidValue) {
2434 if (Checker::IsValid(t_)) {
2435 int res = CloseFunction(t_);
2436 if (CheckClose)
2437 PERFETTO_CHECK(res == 0);
2438 }
2439 t_ = r;
2440 }
release()2441 T release() {
2442 T t = t_;
2443 t_ = InvalidValue;
2444 return t;
2445 }
~ScopedResource()2446 ~ScopedResource() { reset(InvalidValue); }
2447
2448 private:
2449 ScopedResource(const ScopedResource&) = delete;
2450 ScopedResource& operator=(const ScopedResource&) = delete;
2451 T t_;
2452 };
2453
2454 // Declared in file_utils.h. Forward declared to avoid #include cycles.
2455 int PERFETTO_EXPORT CloseFile(int fd);
2456
2457 // Use this for file resources obtained via open() and similar APIs.
2458 using ScopedFile = ScopedResource<int, CloseFile, -1>;
2459 using ScopedFstream = ScopedResource<FILE*, fclose, nullptr>;
2460
2461 // Use this for resources that are HANDLE on Windows. See comments in
2462 // platform_handle.h
2463 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
2464 using ScopedPlatformHandle = ScopedResource<PlatformHandle,
2465 ClosePlatformHandle,
2466 /*InvalidValue=*/nullptr,
2467 /*CheckClose=*/true,
2468 PlatformHandleChecker>;
2469 #else
2470 // On non-windows systems we alias ScopedPlatformHandle to ScopedFile because
2471 // they are really the same. This is to allow assignments between the two in
2472 // Linux-specific code paths that predate ScopedPlatformHandle.
2473 static_assert(std::is_same<int, PlatformHandle>::value, "");
2474 using ScopedPlatformHandle = ScopedFile;
2475
2476 // DIR* does not exist on Windows.
2477 using ScopedDir = ScopedResource<DIR*, closedir, nullptr>;
2478 #endif
2479
2480 } // namespace base
2481 } // namespace perfetto
2482
2483 #endif // INCLUDE_PERFETTO_EXT_BASE_SCOPED_FILE_H_
2484 /*
2485 * Copyright (C) 2018 The Android Open Source Project
2486 *
2487 * Licensed under the Apache License, Version 2.0 (the "License");
2488 * you may not use this file except in compliance with the License.
2489 * You may obtain a copy of the License at
2490 *
2491 * http://www.apache.org/licenses/LICENSE-2.0
2492 *
2493 * Unless required by applicable law or agreed to in writing, software
2494 * distributed under the License is distributed on an "AS IS" BASIS,
2495 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2496 * See the License for the specific language governing permissions and
2497 * limitations under the License.
2498 */
2499
2500 #ifndef INCLUDE_PERFETTO_EXT_BASE_EVENT_FD_H_
2501 #define INCLUDE_PERFETTO_EXT_BASE_EVENT_FD_H_
2502
2503 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
2504 // gen_amalgamated expanded: #include "perfetto/base/platform_handle.h"
2505 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
2506
2507 namespace perfetto {
2508 namespace base {
2509
2510 // A waitable event that can be used with poll/select.
2511 // This is really a wrapper around eventfd_create with a pipe-based fallback
2512 // for other platforms where eventfd is not supported.
2513 class EventFd {
2514 public:
2515 EventFd();
2516 ~EventFd();
2517 EventFd(EventFd&&) noexcept = default;
2518 EventFd& operator=(EventFd&&) = default;
2519
2520 // The non-blocking file descriptor that can be polled to wait for the event.
fd() const2521 PlatformHandle fd() const { return event_handle_.get(); }
2522
2523 // Can be called from any thread.
2524 void Notify();
2525
2526 // Can be called from any thread. If more Notify() are queued a Clear() call
2527 // can clear all of them (up to 16 per call).
2528 void Clear();
2529
2530 private:
2531 // The eventfd, when eventfd is supported, otherwise this is the read end of
2532 // the pipe for fallback mode.
2533 ScopedPlatformHandle event_handle_;
2534
2535 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) && \
2536 !PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && \
2537 !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
2538 // On Mac and other non-Linux UNIX platforms a pipe-based fallback is used.
2539 // The write end of the wakeup pipe.
2540 ScopedFile write_fd_;
2541 #endif
2542 };
2543
2544 } // namespace base
2545 } // namespace perfetto
2546
2547 #endif // INCLUDE_PERFETTO_EXT_BASE_EVENT_FD_H_
2548 // gen_amalgamated begin header: include/perfetto/ext/base/pipe.h
2549 /*
2550 * Copyright (C) 2018 The Android Open Source Project
2551 *
2552 * Licensed under the Apache License, Version 2.0 (the "License");
2553 * you may not use this file except in compliance with the License.
2554 * You may obtain a copy of the License at
2555 *
2556 * http://www.apache.org/licenses/LICENSE-2.0
2557 *
2558 * Unless required by applicable law or agreed to in writing, software
2559 * distributed under the License is distributed on an "AS IS" BASIS,
2560 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2561 * See the License for the specific language governing permissions and
2562 * limitations under the License.
2563 */
2564
2565 #ifndef INCLUDE_PERFETTO_EXT_BASE_PIPE_H_
2566 #define INCLUDE_PERFETTO_EXT_BASE_PIPE_H_
2567
2568 // gen_amalgamated expanded: #include "perfetto/base/platform_handle.h"
2569 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
2570
2571 namespace perfetto {
2572 namespace base {
2573
2574 class Pipe {
2575 public:
2576 enum Flags {
2577 kBothBlock = 0,
2578 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
2579 kBothNonBlock,
2580 kRdNonBlock,
2581 kWrNonBlock,
2582 #endif
2583 };
2584
2585 static Pipe Create(Flags = kBothBlock);
2586
2587 Pipe();
2588 Pipe(Pipe&&) noexcept;
2589 Pipe& operator=(Pipe&&);
2590
2591 ScopedPlatformHandle rd;
2592 ScopedPlatformHandle wr;
2593 };
2594
2595 } // namespace base
2596 } // namespace perfetto
2597
2598 #endif // INCLUDE_PERFETTO_EXT_BASE_PIPE_H_
2599 /*
2600 * Copyright (C) 2018 The Android Open Source Project
2601 *
2602 * Licensed under the Apache License, Version 2.0 (the "License");
2603 * you may not use this file except in compliance with the License.
2604 * You may obtain a copy of the License at
2605 *
2606 * http://www.apache.org/licenses/LICENSE-2.0
2607 *
2608 * Unless required by applicable law or agreed to in writing, software
2609 * distributed under the License is distributed on an "AS IS" BASIS,
2610 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2611 * See the License for the specific language governing permissions and
2612 * limitations under the License.
2613 */
2614
2615 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
2616
2617 #include <errno.h>
2618 #include <stdint.h>
2619
2620 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
2621 #include <Windows.h>
2622 #include <synchapi.h>
2623 #elif PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
2624 PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
2625 #include <sys/eventfd.h>
2626 #include <unistd.h>
2627 #else // Mac, Fuchsia and other non-Linux UNIXes
2628 #include <unistd.h>
2629 #endif
2630
2631 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
2632 // gen_amalgamated expanded: #include "perfetto/ext/base/event_fd.h"
2633 // gen_amalgamated expanded: #include "perfetto/ext/base/pipe.h"
2634 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
2635
2636 namespace perfetto {
2637 namespace base {
2638
2639 EventFd::~EventFd() = default;
2640
2641 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
EventFd()2642 EventFd::EventFd() {
2643 event_handle_.reset(
2644 CreateEventA(/*lpEventAttributes=*/nullptr, /*bManualReset=*/true,
2645 /*bInitialState=*/false, /*bInitialState=*/nullptr));
2646 }
2647
Notify()2648 void EventFd::Notify() {
2649 if (!SetEvent(event_handle_.get())) // 0: fail, !0: success, unlike UNIX.
2650 PERFETTO_DFATAL("EventFd::Notify()");
2651 }
2652
Clear()2653 void EventFd::Clear() {
2654 if (!ResetEvent(event_handle_.get())) // 0: fail, !0: success, unlike UNIX.
2655 PERFETTO_DFATAL("EventFd::Clear()");
2656 }
2657
2658 #elif PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
2659 PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
2660
EventFd()2661 EventFd::EventFd() {
2662 event_handle_.reset(eventfd(/*initval=*/0, EFD_CLOEXEC | EFD_NONBLOCK));
2663 PERFETTO_CHECK(event_handle_);
2664 }
2665
Notify()2666 void EventFd::Notify() {
2667 const uint64_t value = 1;
2668 ssize_t ret = write(event_handle_.get(), &value, sizeof(value));
2669 if (ret <= 0 && errno != EAGAIN)
2670 PERFETTO_DFATAL("EventFd::Notify()");
2671 }
2672
Clear()2673 void EventFd::Clear() {
2674 uint64_t value;
2675 ssize_t ret = read(event_handle_.get(), &value, sizeof(value));
2676 if (ret <= 0 && errno != EAGAIN)
2677 PERFETTO_DFATAL("EventFd::Clear()");
2678 }
2679
2680 #else
2681
EventFd()2682 EventFd::EventFd() {
2683 // Make the pipe non-blocking so that we never block the waking thread (either
2684 // the main thread or another one) when scheduling a wake-up.
2685 Pipe pipe = Pipe::Create(Pipe::kBothNonBlock);
2686 event_handle_ = ScopedPlatformHandle(std::move(pipe.rd).release());
2687 write_fd_ = std::move(pipe.wr);
2688 }
2689
Notify()2690 void EventFd::Notify() {
2691 const uint64_t value = 1;
2692 ssize_t ret = write(write_fd_.get(), &value, sizeof(uint8_t));
2693 if (ret <= 0 && errno != EAGAIN)
2694 PERFETTO_DFATAL("EventFd::Notify()");
2695 }
2696
Clear()2697 void EventFd::Clear() {
2698 // Drain the byte(s) written to the wake-up pipe. We can potentially read
2699 // more than one byte if several wake-ups have been scheduled.
2700 char buffer[16];
2701 ssize_t ret = read(event_handle_.get(), &buffer[0], sizeof(buffer));
2702 if (ret <= 0 && errno != EAGAIN)
2703 PERFETTO_DFATAL("EventFd::Clear()");
2704 }
2705 #endif
2706
2707 } // namespace base
2708 } // namespace perfetto
2709 // gen_amalgamated begin source: src/base/file_utils.cc
2710 // gen_amalgamated begin header: include/perfetto/ext/base/file_utils.h
2711 // gen_amalgamated begin header: include/perfetto/base/status.h
2712 /*
2713 * Copyright (C) 2019 The Android Open Source Project
2714 *
2715 * Licensed under the Apache License, Version 2.0 (the "License");
2716 * you may not use this file except in compliance with the License.
2717 * You may obtain a copy of the License at
2718 *
2719 * http://www.apache.org/licenses/LICENSE-2.0
2720 *
2721 * Unless required by applicable law or agreed to in writing, software
2722 * distributed under the License is distributed on an "AS IS" BASIS,
2723 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2724 * See the License for the specific language governing permissions and
2725 * limitations under the License.
2726 */
2727
2728 #ifndef INCLUDE_PERFETTO_BASE_STATUS_H_
2729 #define INCLUDE_PERFETTO_BASE_STATUS_H_
2730
2731 #include <string>
2732
2733 // gen_amalgamated expanded: #include "perfetto/base/compiler.h"
2734 // gen_amalgamated expanded: #include "perfetto/base/export.h"
2735 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
2736
2737 namespace perfetto {
2738 namespace base {
2739
2740 // Represents either the success or the failure message of a function.
2741 // This can used as the return type of functions which would usually return an
2742 // bool for success or int for errno but also wants to add some string context
2743 // (ususally for logging).
2744 class PERFETTO_EXPORT Status {
2745 public:
Status()2746 Status() : ok_(true) {}
Status(std::string msg)2747 explicit Status(std::string msg) : ok_(false), message_(std::move(msg)) {
2748 PERFETTO_CHECK(!message_.empty());
2749 }
2750
2751 // Copy operations.
2752 Status(const Status&) = default;
2753 Status& operator=(const Status&) = default;
2754
2755 // Move operations. The moved-from state is valid but unspecified.
2756 Status(Status&&) noexcept = default;
2757 Status& operator=(Status&&) = default;
2758
ok() const2759 bool ok() const { return ok_; }
2760
2761 // When ok() is false this returns the error message. Returns the empty string
2762 // otherwise.
message() const2763 const std::string& message() const { return message_; }
c_message() const2764 const char* c_message() const { return message_.c_str(); }
2765
2766 private:
2767 bool ok_ = false;
2768 std::string message_;
2769 };
2770
2771 // Returns a status object which represents the Ok status.
OkStatus()2772 inline Status OkStatus() {
2773 return Status();
2774 }
2775
2776 PERFETTO_PRINTF_FORMAT(1, 2) Status ErrStatus(const char* format, ...);
2777
2778 } // namespace base
2779 } // namespace perfetto
2780
2781 #endif // INCLUDE_PERFETTO_BASE_STATUS_H_
2782 /*
2783 * Copyright (C) 2018 The Android Open Source Project
2784 *
2785 * Licensed under the Apache License, Version 2.0 (the "License");
2786 * you may not use this file except in compliance with the License.
2787 * You may obtain a copy of the License at
2788 *
2789 * http://www.apache.org/licenses/LICENSE-2.0
2790 *
2791 * Unless required by applicable law or agreed to in writing, software
2792 * distributed under the License is distributed on an "AS IS" BASIS,
2793 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2794 * See the License for the specific language governing permissions and
2795 * limitations under the License.
2796 */
2797
2798 #ifndef INCLUDE_PERFETTO_EXT_BASE_FILE_UTILS_H_
2799 #define INCLUDE_PERFETTO_EXT_BASE_FILE_UTILS_H_
2800
2801 #include <fcntl.h> // For mode_t & O_RDONLY/RDWR. Exists also on Windows.
2802 #include <stddef.h>
2803
2804 #include <string>
2805 #include <vector>
2806
2807 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
2808 // gen_amalgamated expanded: #include "perfetto/base/export.h"
2809 // gen_amalgamated expanded: #include "perfetto/base/status.h"
2810 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
2811 // gen_amalgamated expanded: #include "perfetto/ext/base/optional.h"
2812 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
2813
2814 namespace perfetto {
2815 namespace base {
2816
2817 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
2818 using FileOpenMode = int;
2819 #else
2820 using FileOpenMode = mode_t;
2821 #endif
2822
2823 constexpr FileOpenMode kFileModeInvalid = static_cast<FileOpenMode>(-1);
2824
2825 bool ReadPlatformHandle(PlatformHandle, std::string* out);
2826 bool ReadFileDescriptor(int fd, std::string* out);
2827 bool ReadFileStream(FILE* f, std::string* out);
2828 bool ReadFile(const std::string& path, std::string* out);
2829
2830 // A wrapper around read(2). It deals with Linux vs Windows includes. It also
2831 // deals with handling EINTR. Has the same semantics of UNIX's read(2).
2832 ssize_t Read(int fd, void* dst, size_t dst_size);
2833
2834 // Call write until all data is written or an error is detected.
2835 //
2836 // man 2 write:
2837 // If a write() is interrupted by a signal handler before any bytes are
2838 // written, then the call fails with the error EINTR; if it is
2839 // interrupted after at least one byte has been written, the call
2840 // succeeds, and returns the number of bytes written.
2841 ssize_t WriteAll(int fd, const void* buf, size_t count);
2842
2843 ssize_t WriteAllHandle(PlatformHandle, const void* buf, size_t count);
2844
2845 ScopedFile OpenFile(const std::string& path,
2846 int flags,
2847 FileOpenMode = kFileModeInvalid);
2848
2849 // This is an alias for close(). It's to avoid leaking Windows.h in headers.
2850 // Exported because ScopedFile is used in the /include/ext API by Chromium
2851 // component builds.
2852 int PERFETTO_EXPORT CloseFile(int fd);
2853
2854 bool FlushFile(int fd);
2855
2856 // Returns true if mkdir succeeds, false if it fails (see errno in that case).
2857 bool Mkdir(const std::string& path);
2858
2859 // Calls rmdir() on UNIX, _rmdir() on Windows.
2860 bool Rmdir(const std::string& path);
2861
2862 // Wrapper around access(path, F_OK).
2863 bool FileExists(const std::string& path);
2864
2865 // Gets the extension for a filename. If the file has two extensions, returns
2866 // only the last one (foo.pb.gz => .gz). Returns empty string if there is no
2867 // extension.
2868 std::string GetFileExtension(const std::string& filename);
2869
2870 // Puts the path to all files under |dir_path| in |output|, recursively walking
2871 // subdirectories. File paths are relative to |dir_path|. Only files are
2872 // included, not directories. Path separator is always '/', even on windows (not
2873 // '\').
2874 base::Status ListFilesRecursive(const std::string& dir_path,
2875 std::vector<std::string>& output);
2876
2877 // Returns the size of the file at `path` or nullopt in case of error.
2878 Optional<size_t> GetFileSize(const std::string& path);
2879
2880 } // namespace base
2881 } // namespace perfetto
2882
2883 #endif // INCLUDE_PERFETTO_EXT_BASE_FILE_UTILS_H_
2884 /*
2885 * Copyright (C) 2018 The Android Open Source Project
2886 *
2887 * Licensed under the Apache License, Version 2.0 (the "License");
2888 * you may not use this file except in compliance with the License.
2889 * You may obtain a copy of the License at
2890 *
2891 * http://www.apache.org/licenses/LICENSE-2.0
2892 *
2893 * Unless required by applicable law or agreed to in writing, software
2894 * distributed under the License is distributed on an "AS IS" BASIS,
2895 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2896 * See the License for the specific language governing permissions and
2897 * limitations under the License.
2898 */
2899
2900 // gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
2901
2902 #include <sys/stat.h>
2903 #include <sys/types.h>
2904
2905 #include <algorithm>
2906 #include <deque>
2907 #include <string>
2908 #include <vector>
2909
2910 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
2911 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
2912 // gen_amalgamated expanded: #include "perfetto/base/platform_handle.h"
2913 // gen_amalgamated expanded: #include "perfetto/base/status.h"
2914 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
2915 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
2916
2917 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
2918 #include <Windows.h>
2919 #include <direct.h>
2920 #include <io.h>
2921 #else
2922 #include <dirent.h>
2923 #include <unistd.h>
2924 #endif
2925
2926 namespace perfetto {
2927 namespace base {
2928 namespace {
2929 constexpr size_t kBufSize = 2048;
2930 } // namespace
2931
Read(int fd,void * dst,size_t dst_size)2932 ssize_t Read(int fd, void* dst, size_t dst_size) {
2933 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
2934 return _read(fd, dst, static_cast<unsigned>(dst_size));
2935 #else
2936 return PERFETTO_EINTR(read(fd, dst, dst_size));
2937 #endif
2938 }
2939
ReadFileDescriptor(int fd,std::string * out)2940 bool ReadFileDescriptor(int fd, std::string* out) {
2941 // Do not override existing data in string.
2942 size_t i = out->size();
2943
2944 struct stat buf {};
2945 if (fstat(fd, &buf) != -1) {
2946 if (buf.st_size > 0)
2947 out->resize(i + static_cast<size_t>(buf.st_size));
2948 }
2949
2950 ssize_t bytes_read;
2951 for (;;) {
2952 if (out->size() < i + kBufSize)
2953 out->resize(out->size() + kBufSize);
2954
2955 bytes_read = Read(fd, &((*out)[i]), kBufSize);
2956 if (bytes_read > 0) {
2957 i += static_cast<size_t>(bytes_read);
2958 } else {
2959 out->resize(i);
2960 return bytes_read == 0;
2961 }
2962 }
2963 }
2964
ReadPlatformHandle(PlatformHandle h,std::string * out)2965 bool ReadPlatformHandle(PlatformHandle h, std::string* out) {
2966 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
2967 // Do not override existing data in string.
2968 size_t i = out->size();
2969
2970 for (;;) {
2971 if (out->size() < i + kBufSize)
2972 out->resize(out->size() + kBufSize);
2973 DWORD bytes_read = 0;
2974 auto res = ::ReadFile(h, &((*out)[i]), kBufSize, &bytes_read, nullptr);
2975 if (res && bytes_read > 0) {
2976 i += static_cast<size_t>(bytes_read);
2977 } else {
2978 out->resize(i);
2979 const bool is_eof = res && bytes_read == 0;
2980 auto err = res ? 0 : GetLastError();
2981 // The "Broken pipe" error on Windows is slighly different than Unix:
2982 // On Unix: a "broken pipe" error can happen only on the writer side. On
2983 // the reader there is no broken pipe, just a EOF.
2984 // On windows: the reader also sees a broken pipe error.
2985 // Here we normalize on the Unix behavior, treating broken pipe as EOF.
2986 return is_eof || err == ERROR_BROKEN_PIPE;
2987 }
2988 }
2989 #else
2990 return ReadFileDescriptor(h, out);
2991 #endif
2992 }
2993
ReadFileStream(FILE * f,std::string * out)2994 bool ReadFileStream(FILE* f, std::string* out) {
2995 return ReadFileDescriptor(fileno(f), out);
2996 }
2997
ReadFile(const std::string & path,std::string * out)2998 bool ReadFile(const std::string& path, std::string* out) {
2999 base::ScopedFile fd = base::OpenFile(path, O_RDONLY);
3000 if (!fd)
3001 return false;
3002
3003 return ReadFileDescriptor(*fd, out);
3004 }
3005
WriteAll(int fd,const void * buf,size_t count)3006 ssize_t WriteAll(int fd, const void* buf, size_t count) {
3007 size_t written = 0;
3008 while (written < count) {
3009 // write() on windows takes an unsigned int size.
3010 uint32_t bytes_left = static_cast<uint32_t>(
3011 std::min(count - written, static_cast<size_t>(UINT32_MAX)));
3012 ssize_t wr = PERFETTO_EINTR(
3013 write(fd, static_cast<const char*>(buf) + written, bytes_left));
3014 if (wr == 0)
3015 break;
3016 if (wr < 0)
3017 return wr;
3018 written += static_cast<size_t>(wr);
3019 }
3020 return static_cast<ssize_t>(written);
3021 }
3022
WriteAllHandle(PlatformHandle h,const void * buf,size_t count)3023 ssize_t WriteAllHandle(PlatformHandle h, const void* buf, size_t count) {
3024 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
3025 DWORD wsize = 0;
3026 if (::WriteFile(h, buf, static_cast<DWORD>(count), &wsize, nullptr)) {
3027 return wsize;
3028 } else {
3029 return -1;
3030 }
3031 #else
3032 return WriteAll(h, buf, count);
3033 #endif
3034 }
3035
FlushFile(int fd)3036 bool FlushFile(int fd) {
3037 PERFETTO_DCHECK(fd != 0);
3038 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
3039 PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
3040 return !PERFETTO_EINTR(fdatasync(fd));
3041 #elif PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
3042 return !PERFETTO_EINTR(_commit(fd));
3043 #else
3044 return !PERFETTO_EINTR(fsync(fd));
3045 #endif
3046 }
3047
Mkdir(const std::string & path)3048 bool Mkdir(const std::string& path) {
3049 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
3050 return _mkdir(path.c_str()) == 0;
3051 #else
3052 return mkdir(path.c_str(), 0755) == 0;
3053 #endif
3054 }
3055
Rmdir(const std::string & path)3056 bool Rmdir(const std::string& path) {
3057 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
3058 return _rmdir(path.c_str()) == 0;
3059 #else
3060 return rmdir(path.c_str()) == 0;
3061 #endif
3062 }
3063
CloseFile(int fd)3064 int CloseFile(int fd) {
3065 return close(fd);
3066 }
3067
OpenFile(const std::string & path,int flags,FileOpenMode mode)3068 ScopedFile OpenFile(const std::string& path, int flags, FileOpenMode mode) {
3069 PERFETTO_DCHECK((flags & O_CREAT) == 0 || mode != kFileModeInvalid);
3070 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
3071 // Always use O_BINARY on Windows, to avoid silly EOL translations.
3072 ScopedFile fd(_open(path.c_str(), flags | O_BINARY, mode));
3073 #else
3074 // Always open a ScopedFile with O_CLOEXEC so we can safely fork and exec.
3075 ScopedFile fd(open(path.c_str(), flags | O_CLOEXEC, mode));
3076 #endif
3077 return fd;
3078 }
3079
FileExists(const std::string & path)3080 bool FileExists(const std::string& path) {
3081 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
3082 return _access(path.c_str(), 0) == 0;
3083 #else
3084 return access(path.c_str(), F_OK) == 0;
3085 #endif
3086 }
3087
3088 // Declared in base/platform_handle.h.
ClosePlatformHandle(PlatformHandle handle)3089 int ClosePlatformHandle(PlatformHandle handle) {
3090 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
3091 // Make the return value UNIX-style.
3092 return CloseHandle(handle) ? 0 : -1;
3093 #else
3094 return close(handle);
3095 #endif
3096 }
3097
ListFilesRecursive(const std::string & dir_path,std::vector<std::string> & output)3098 base::Status ListFilesRecursive(const std::string& dir_path,
3099 std::vector<std::string>& output) {
3100 std::string root_dir_path = dir_path;
3101 if (root_dir_path.back() == '\\') {
3102 root_dir_path.back() = '/';
3103 } else if (root_dir_path.back() != '/') {
3104 root_dir_path.push_back('/');
3105 }
3106
3107 // dir_queue contains full paths to the directories. The paths include the
3108 // root_dir_path at the beginning and the trailing slash at the end.
3109 std::deque<std::string> dir_queue;
3110 dir_queue.push_back(root_dir_path);
3111
3112 while (!dir_queue.empty()) {
3113 const std::string cur_dir = std::move(dir_queue.front());
3114 dir_queue.pop_front();
3115 #if PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
3116 return base::ErrStatus("ListFilesRecursive not supported yet");
3117 #elif PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
3118 std::string glob_path = cur_dir + "*";
3119 // + 1 because we also have to count the NULL terminator.
3120 if (glob_path.length() + 1 > MAX_PATH)
3121 return base::ErrStatus("Directory path %s is too long", dir_path.c_str());
3122 WIN32_FIND_DATAA ffd;
3123
3124 base::ScopedResource<HANDLE, FindClose, nullptr, false,
3125 base::PlatformHandleChecker>
3126 hFind(FindFirstFileA(glob_path.c_str(), &ffd));
3127 if (!hFind) {
3128 // For empty directories, there should be at least one entry '.'.
3129 // If FindFirstFileA returns INVALID_HANDLE_VALUE, this means directory
3130 // couldn't be accessed.
3131 return base::ErrStatus("Failed to open directory %s", cur_dir.c_str());
3132 }
3133 do {
3134 if (strcmp(ffd.cFileName, ".") == 0 || strcmp(ffd.cFileName, "..") == 0)
3135 continue;
3136 if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
3137 std::string subdir_path = cur_dir + ffd.cFileName + '/';
3138 dir_queue.push_back(subdir_path);
3139 } else {
3140 const std::string full_path = cur_dir + ffd.cFileName;
3141 PERFETTO_CHECK(full_path.length() > root_dir_path.length());
3142 output.push_back(full_path.substr(root_dir_path.length()));
3143 }
3144 } while (FindNextFileA(*hFind, &ffd));
3145 #else
3146 ScopedDir dir = ScopedDir(opendir(cur_dir.c_str()));
3147 if (!dir) {
3148 return base::ErrStatus("Failed to open directory %s", cur_dir.c_str());
3149 }
3150 for (auto* dirent = readdir(dir.get()); dirent != nullptr;
3151 dirent = readdir(dir.get())) {
3152 if (strcmp(dirent->d_name, ".") == 0 ||
3153 strcmp(dirent->d_name, "..") == 0) {
3154 continue;
3155 }
3156 if (dirent->d_type == DT_DIR) {
3157 dir_queue.push_back(cur_dir + dirent->d_name + '/');
3158 } else if (dirent->d_type == DT_REG) {
3159 const std::string full_path = cur_dir + dirent->d_name;
3160 PERFETTO_CHECK(full_path.length() > root_dir_path.length());
3161 output.push_back(full_path.substr(root_dir_path.length()));
3162 }
3163 }
3164 #endif
3165 }
3166 return base::OkStatus();
3167 }
3168
GetFileExtension(const std::string & filename)3169 std::string GetFileExtension(const std::string& filename) {
3170 auto ext_idx = filename.rfind('.');
3171 if (ext_idx == std::string::npos)
3172 return std::string();
3173 return filename.substr(ext_idx);
3174 }
3175
GetFileSize(const std::string & file_path)3176 base::Optional<size_t> GetFileSize(const std::string& file_path) {
3177 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
3178 HANDLE file =
3179 CreateFileA(file_path.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr,
3180 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
3181 if (file == INVALID_HANDLE_VALUE) {
3182 return nullopt;
3183 }
3184 LARGE_INTEGER file_size;
3185 file_size.QuadPart = 0;
3186 BOOL ok = GetFileSizeEx(file, &file_size);
3187 CloseHandle(file);
3188 if (!ok) {
3189 return nullopt;
3190 }
3191 return static_cast<size_t>(file_size.QuadPart);
3192 #else
3193 base::ScopedFile fd(base::OpenFile(file_path, O_RDONLY | O_CLOEXEC));
3194 if (!fd) {
3195 return nullopt;
3196 }
3197 struct stat buf{};
3198 if (fstat(*fd, &buf) == -1) {
3199 return nullopt;
3200 }
3201 return static_cast<size_t>(buf.st_size);
3202 #endif
3203 }
3204
3205 } // namespace base
3206 } // namespace perfetto
3207 // gen_amalgamated begin source: src/base/getopt_compat.cc
3208 // gen_amalgamated begin header: include/perfetto/ext/base/getopt_compat.h
3209 /*
3210 * Copyright (C) 2021 The Android Open Source Project
3211 *
3212 * Licensed under the Apache License, Version 2.0 (the "License");
3213 * you may not use this file except in compliance with the License.
3214 * You may obtain a copy of the License at
3215 *
3216 * http://www.apache.org/licenses/LICENSE-2.0
3217 *
3218 * Unless required by applicable law or agreed to in writing, software
3219 * distributed under the License is distributed on an "AS IS" BASIS,
3220 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3221 * See the License for the specific language governing permissions and
3222 * limitations under the License.
3223 */
3224
3225 #ifndef INCLUDE_PERFETTO_EXT_BASE_GETOPT_COMPAT_H_
3226 #define INCLUDE_PERFETTO_EXT_BASE_GETOPT_COMPAT_H_
3227
3228 #include <cstddef> // For std::nullptr_t
3229
3230 // No translation units other than base/getopt.h and getopt_compat_unittest.cc
3231 // should directly include this file. Use base/getopt.h instead.
3232
3233 namespace perfetto {
3234 namespace base {
3235 namespace getopt_compat {
3236
3237 // A tiny getopt() replacement for Windows, which doesn't have <getopt.h>.
3238 // This implementation is based on the subset of features that we use in the
3239 // Perfetto codebase. It doesn't even try to deal with the full surface of GNU's
3240 // getopt().
3241 // Limitations:
3242 // - getopt_long_only() is not supported.
3243 // - optional_argument is not supported. That is extremely subtle and caused us
3244 // problems in the past with GNU's getopt.
3245 // - It does not reorder non-option arguments. It behaves like MacOS getopt, or
3246 // GNU's when POSIXLY_CORRECT=1.
3247 // - Doesn't expose optopt or opterr.
3248 // - option.flag and longindex are not supported and must be nullptr.
3249
3250 enum {
3251 no_argument = 0,
3252 required_argument = 1,
3253 };
3254
3255 struct option {
3256 const char* name;
3257 int has_arg;
3258 std::nullptr_t flag; // Only nullptr is supported.
3259 int val;
3260 };
3261
3262 extern char* optarg;
3263 extern int optind;
3264 extern int optopt;
3265 extern int opterr;
3266
3267 int getopt_long(int argc,
3268 char** argv,
3269 const char* shortopts,
3270 const option* longopts,
3271 std::nullptr_t /*longindex is not supported*/);
3272
3273 int getopt(int argc, char** argv, const char* shortopts);
3274
3275 } // namespace getopt_compat
3276 } // namespace base
3277 } // namespace perfetto
3278
3279 #endif // INCLUDE_PERFETTO_EXT_BASE_GETOPT_COMPAT_H_
3280 /*
3281 * Copyright (C) 2021 The Android Open Source Project
3282 *
3283 * Licensed under the Apache License, Version 2.0 (the "License");
3284 * you may not use this file except in compliance with the License.
3285 * You may obtain a copy of the License at
3286 *
3287 * http://www.apache.org/licenses/LICENSE-2.0
3288 *
3289 * Unless required by applicable law or agreed to in writing, software
3290 * distributed under the License is distributed on an "AS IS" BASIS,
3291 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3292 * See the License for the specific language governing permissions and
3293 * limitations under the License.
3294 */
3295
3296 // gen_amalgamated expanded: #include "perfetto/ext/base/getopt_compat.h"
3297
3298 #include <stdio.h>
3299 #include <stdlib.h>
3300 #include <string.h>
3301
3302 #include <vector>
3303
3304 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
3305
3306 namespace perfetto {
3307 namespace base {
3308 namespace getopt_compat {
3309
3310 char* optarg = nullptr;
3311 int optind = 0;
3312 int optopt = 0;
3313 int opterr = 1;
3314
3315 namespace {
3316
3317 char* nextchar = nullptr;
3318
LookupLongOpt(const std::vector<option> & opts,const char * name,size_t len)3319 const option* LookupLongOpt(const std::vector<option>& opts,
3320 const char* name,
3321 size_t len) {
3322 for (const option& opt : opts) {
3323 if (strncmp(opt.name, name, len) == 0 && strlen(opt.name) == len)
3324 return &opt;
3325 }
3326 return nullptr;
3327 }
3328
LookupShortOpt(const std::vector<option> & opts,char c)3329 const option* LookupShortOpt(const std::vector<option>& opts, char c) {
3330 for (const option& opt : opts) {
3331 if (!*opt.name && opt.val == c)
3332 return &opt;
3333 }
3334 return nullptr;
3335 }
3336
ParseOpts(const char * shortopts,const option * longopts,std::vector<option> * res)3337 bool ParseOpts(const char* shortopts,
3338 const option* longopts,
3339 std::vector<option>* res) {
3340 // Parse long options first.
3341 for (const option* lopt = longopts; lopt && lopt->name; lopt++) {
3342 PERFETTO_CHECK(lopt->flag == nullptr);
3343 PERFETTO_CHECK(lopt->has_arg == no_argument ||
3344 lopt->has_arg == required_argument);
3345 res->emplace_back(*lopt);
3346 }
3347
3348 // Merge short options.
3349 for (const char* sopt = shortopts; sopt && *sopt;) {
3350 const size_t idx = static_cast<size_t>(sopt - shortopts);
3351 char c = *sopt++;
3352 bool valid = (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
3353 (c >= '0' && c <= '9');
3354 if (!valid) {
3355 fprintf(stderr,
3356 "Error parsing shortopts. Unexpected char '%c' at offset %zu\n",
3357 c, idx);
3358 return false;
3359 }
3360 res->emplace_back();
3361 option& opt = res->back();
3362 opt.name = "";
3363 opt.val = c;
3364 opt.has_arg = no_argument;
3365 if (*sopt == ':') {
3366 opt.has_arg = required_argument;
3367 ++sopt;
3368 }
3369 }
3370 return true;
3371 }
3372
3373 } // namespace
3374
getopt_long(int argc,char ** argv,const char * shortopts,const option * longopts,std::nullptr_t)3375 int getopt_long(int argc,
3376 char** argv,
3377 const char* shortopts,
3378 const option* longopts,
3379 std::nullptr_t /*longind*/) {
3380 std::vector<option> opts;
3381 optarg = nullptr;
3382
3383 if (optind == 0)
3384 optind = 1;
3385
3386 if (optind >= argc)
3387 return -1;
3388
3389 if (!ParseOpts(shortopts, longopts, &opts))
3390 return '?';
3391
3392 char* arg = argv[optind];
3393 optopt = 0;
3394
3395 if (!nextchar) {
3396 // If |nextchar| is null we are NOT in the middle of a short option and we
3397 // should parse the next argv.
3398 if (strncmp(arg, "--", 2) == 0 && strlen(arg) > 2) {
3399 // A --long option.
3400 arg += 2;
3401 char* sep = strchr(arg, '=');
3402 optind++;
3403
3404 size_t len = sep ? static_cast<size_t>(sep - arg) : strlen(arg);
3405 const option* opt = LookupLongOpt(opts, arg, len);
3406
3407 if (!opt) {
3408 if (opterr)
3409 fprintf(stderr, "unrecognized option '--%s'\n", arg);
3410 return '?';
3411 }
3412
3413 optopt = opt->val;
3414 if (opt->has_arg == no_argument) {
3415 if (sep) {
3416 fprintf(stderr, "option '--%s' doesn't allow an argument\n", arg);
3417 return '?';
3418 } else {
3419 return opt->val;
3420 }
3421 } else if (opt->has_arg == required_argument) {
3422 if (sep) {
3423 optarg = sep + 1;
3424 return opt->val;
3425 } else if (optind >= argc) {
3426 if (opterr)
3427 fprintf(stderr, "option '--%s' requires an argument\n", arg);
3428 return '?';
3429 } else {
3430 optarg = argv[optind++];
3431 return opt->val;
3432 }
3433 }
3434 // has_arg must be either |no_argument| or |required_argument|. We
3435 // shoulnd't get here unless the check in ParseOpts() has a bug.
3436 PERFETTO_CHECK(false);
3437 } // if (arg ~= "--*").
3438
3439 if (strlen(arg) > 1 && arg[0] == '-' && arg[1] != '-') {
3440 // A sequence of short options. Parsing logic continues below.
3441 nextchar = &arg[1];
3442 }
3443 } // if(!nextchar)
3444
3445 if (nextchar) {
3446 // At this point either:
3447 // 1. This is the first char of a sequence of short options, and we fell
3448 // through here from the lines above.
3449 // 2. This is the N (>1) char of a sequence of short options, and we got
3450 // here from a new getopt() call to getopt().
3451 const char cur_char = *nextchar;
3452 PERFETTO_CHECK(cur_char != '\0');
3453
3454 // Advance the option char in any case, before we start reasoning on them.
3455 // if we got to the end of the "-abc" sequence, increment optind so the next
3456 // getopt() call resumes from the next argv argument.
3457 if (*(++nextchar) == '\0') {
3458 nextchar = nullptr;
3459 ++optind;
3460 }
3461
3462 const option* opt = LookupShortOpt(opts, cur_char);
3463 optopt = cur_char;
3464 if (!opt) {
3465 if (opterr)
3466 fprintf(stderr, "invalid option -- '%c'\n", cur_char);
3467 return '?';
3468 }
3469 if (opt->has_arg == no_argument) {
3470 return cur_char;
3471 } else if (opt->has_arg == required_argument) {
3472 // This is a subtle getopt behavior. Say you call `tar -fx`, there are
3473 // two cases:
3474 // 1. If 'f' is no_argument then 'x' (and anything else after) is
3475 // interpreted as an independent argument (like `tar -f -x`).
3476 // 2. If 'f' is required_argument, than everything else after the 'f'
3477 // is interpreted as the option argument (like `tar -f x`)
3478 if (!nextchar) {
3479 // Case 1.
3480 if (optind >= argc) {
3481 if (opterr)
3482 fprintf(stderr, "option requires an argument -- '%c'\n", cur_char);
3483 return '?';
3484 } else {
3485 optarg = argv[optind++];
3486 return cur_char;
3487 }
3488 } else {
3489 // Case 2.
3490 optarg = nextchar;
3491 nextchar = nullptr;
3492 optind++;
3493 return cur_char;
3494 }
3495 }
3496 PERFETTO_CHECK(false);
3497 } // if (nextchar)
3498
3499 // If we get here, we found the first non-option argument. Stop here.
3500
3501 if (strcmp(arg, "--") == 0)
3502 optind++;
3503
3504 return -1;
3505 }
3506
getopt(int argc,char ** argv,const char * shortopts)3507 int getopt(int argc, char** argv, const char* shortopts) {
3508 return getopt_long(argc, argv, shortopts, nullptr, nullptr);
3509 }
3510
3511 } // namespace getopt_compat
3512 } // namespace base
3513 } // namespace perfetto
3514 // gen_amalgamated begin source: src/base/logging.cc
3515 // gen_amalgamated begin header: src/base/log_ring_buffer.h
3516 // gen_amalgamated begin header: include/perfetto/ext/base/thread_annotations.h
3517 /*
3518 * Copyright (C) 2019 The Android Open Source Project
3519 *
3520 * Licensed under the Apache License, Version 2.0 (the "License");
3521 * you may not use this file except in compliance with the License.
3522 * You may obtain a copy of the License at
3523 *
3524 * http://www.apache.org/licenses/LICENSE-2.0
3525 *
3526 * Unless required by applicable law or agreed to in writing, software
3527 * distributed under the License is distributed on an "AS IS" BASIS,
3528 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3529 * See the License for the specific language governing permissions and
3530 * limitations under the License.
3531 */
3532
3533 #ifndef INCLUDE_PERFETTO_EXT_BASE_THREAD_ANNOTATIONS_H_
3534 #define INCLUDE_PERFETTO_EXT_BASE_THREAD_ANNOTATIONS_H_
3535
3536 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
3537
3538 // Windows TSAN doesn't currently support these annotations.
3539 #if defined(THREAD_SANITIZER) && !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
3540 extern "C" {
3541 void AnnotateBenignRaceSized(const char* file,
3542 int line,
3543 unsigned long address,
3544 unsigned long size,
3545 const char* description);
3546 }
3547
3548 #define PERFETTO_ANNOTATE_BENIGN_RACE_SIZED(pointer, size, description) \
3549 AnnotateBenignRaceSized(__FILE__, __LINE__, \
3550 reinterpret_cast<unsigned long>(pointer), size, \
3551 description);
3552 #else // defined(ADDRESS_SANITIZER)
3553 #define PERFETTO_ANNOTATE_BENIGN_RACE_SIZED(pointer, size, description)
3554 #endif // defined(ADDRESS_SANITIZER)
3555
3556 #endif // INCLUDE_PERFETTO_EXT_BASE_THREAD_ANNOTATIONS_H_
3557 /*
3558 * Copyright (C) 2021 The Android Open Source Project
3559 *
3560 * Licensed under the Apache License, Version 2.0 (the "License");
3561 * you may not use this file except in compliance with the License.
3562 * You may obtain a copy of the License at
3563 *
3564 * http://www.apache.org/licenses/LICENSE-2.0
3565 *
3566 * Unless required by applicable law or agreed to in writing, software
3567 * distributed under the License is distributed on an "AS IS" BASIS,
3568 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3569 * See the License for the specific language governing permissions and
3570 * limitations under the License.
3571 */
3572
3573 #ifndef SRC_BASE_LOG_RING_BUFFER_H_
3574 #define SRC_BASE_LOG_RING_BUFFER_H_
3575
3576 #include <stddef.h>
3577 #include <stdio.h>
3578
3579 #include <array>
3580 #include <atomic>
3581
3582 // gen_amalgamated expanded: #include "perfetto/ext/base/string_view.h"
3583 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_annotations.h"
3584
3585 namespace perfetto {
3586 namespace base {
3587
3588 // Defined out of line because a static constexpr requires static storage if
3589 // ODR-used, not worth adding a .cc file just for tests.
3590 constexpr size_t kLogRingBufEntries = 8;
3591 constexpr size_t kLogRingBufMsgLen = 256;
3592
3593 // A static non-allocating ring-buffer to hold the most recent log events.
3594 // This class is really an implementation detail of logging.cc. The only reason
3595 // why is fully defined in a dedicated header is for allowing unittesting,
3596 // without leaking extra headers into logging.h (which is a high-fanout header).
3597 // This is used to report the last logs in a crash report when a CHECK/FATAL
3598 // is encountered.
3599 // This class has just an Append() method to insert events into the buffer and
3600 // a Read() to read the events in FIFO order. Read() is non-destructive.
3601 //
3602 // Thread safety considerations:
3603 // - The Append() method can be called concurrently by several threads, unless
3604 // there are > kLogRingBufEntries concurrent threads. Even if that happens,
3605 // case some events will contain a mix of strings but the behavior of
3606 // futher Append() and Read() is still defined.
3607 // - The Read() method is not thread safe but it's fine in practice. Even if
3608 // it's called concurrently with other Append(), it only causes some partial
3609 // events to be emitted in output.
3610 // In both cases, we never rely purely on \0, all operations are size-bound.
3611 //
3612 // See logging_unittest.cc for tests.
3613 class LogRingBuffer {
3614 public:
3615 LogRingBuffer() = default;
3616 LogRingBuffer(const LogRingBuffer&) = delete;
3617 LogRingBuffer& operator=(const LogRingBuffer&) = delete;
3618 LogRingBuffer(LogRingBuffer&&) = delete;
3619 LogRingBuffer& operator=(LogRingBuffer&&) = delete;
3620
3621 // This takes three arguments because it fits its only caller (logging.cc).
3622 // The args are just concatenated together (plus one space before the msg).
Append(StringView tstamp,StringView source,StringView log_msg)3623 void Append(StringView tstamp, StringView source, StringView log_msg) {
3624 // Reserve atomically a slot in the ring buffer, so any concurrent Append()
3625 // won't overlap (unless too many concurrent Append() happen together).
3626 // There is no strict synchronization here, |event_slot_| is atomic only for
3627 // the sake of avoiding colliding on the same slot but does NOT guarantee
3628 // full consistency and integrity of the log messages written in each slot.
3629 // A release-store (or acq+rel) won't be enough for full consistency. Two
3630 // threads that race on Append() and take the N+1 and N+2 slots could finish
3631 // the write in reverse order. So Read() would need to synchronize with
3632 // something else (either a per-slot atomic flag or with a second atomic
3633 // counter which is incremented after the snprintf). Both options increase
3634 // the cost of Append() with no huge benefits (90% of the perfetto services
3635 // where we use it is single thread, and the log ring buffer is disabled
3636 // on non-standalone builds like the SDK).
3637 uint32_t slot = event_slot_.fetch_add(1, std::memory_order_relaxed);
3638 slot = slot % kLogRingBufEntries;
3639
3640 char* const msg = events_[slot];
3641 PERFETTO_ANNOTATE_BENIGN_RACE_SIZED(msg, kLogRingBufMsgLen,
3642 "see comments in log_ring_buffer.h")
3643 snprintf(msg, kLogRingBufMsgLen, "%.*s%.*s %.*s",
3644 static_cast<int>(tstamp.size()), tstamp.data(),
3645 static_cast<int>(source.size()), source.data(),
3646 static_cast<int>(log_msg.size()), log_msg.data());
3647 }
3648
3649 // Reads back the buffer in FIFO order, up to |len - 1| characters at most
3650 // (the -1 is because a NUL terminator is always appended, unless |len| == 0).
3651 // The string written in |dst| is guaranteed to be NUL-terminated, even if
3652 // |len| < buffer contents length.
3653 // Returns the number of bytes written in output, excluding the \0 terminator.
Read(char * dst,size_t len)3654 size_t Read(char* dst, size_t len) {
3655 if (len == 0)
3656 return 0;
3657 // This is a relaxed-load because we don't need to fully synchronize on the
3658 // writing path for the reasons described in the fetch_add() above.
3659 const uint32_t event_slot = event_slot_.load(std::memory_order_relaxed);
3660 size_t dst_written = 0;
3661 for (uint32_t pos = 0; pos < kLogRingBufEntries; ++pos) {
3662 const uint32_t slot = (event_slot + pos) % kLogRingBufEntries;
3663 const char* src = events_[slot];
3664 if (*src == '\0')
3665 continue; // Empty slot. Skip.
3666 char* const wptr = dst + dst_written;
3667 // |src| might not be null terminated. This can happen if some
3668 // thread-race happened. Limit the copy length.
3669 const size_t limit = std::min(len - dst_written, kLogRingBufMsgLen);
3670 for (size_t i = 0; i < limit; ++i) {
3671 const char c = src[i];
3672 ++dst_written;
3673 if (c == '\0' || i == limit - 1) {
3674 wptr[i] = '\n';
3675 break;
3676 }
3677 // Skip non-printable ASCII characters to avoid confusing crash reports.
3678 // Note that this deliberately mangles \n. Log messages should not have
3679 // a \n in the middle and are NOT \n terminated. The trailing \n between
3680 // each line is appended by the if () branch above.
3681 const bool is_printable = c >= ' ' && c <= '~';
3682 wptr[i] = is_printable ? c : '?';
3683 }
3684 }
3685 // Ensure that the output string is null-terminated.
3686 PERFETTO_DCHECK(dst_written <= len);
3687 if (dst_written == len) {
3688 // In case of truncation we replace the last char with \0. But the return
3689 // value is the number of chars without \0, hence the --.
3690 dst[--dst_written] = '\0';
3691 } else {
3692 dst[dst_written] = '\0';
3693 }
3694 return dst_written;
3695 }
3696
3697 private:
3698 using EventBuf = char[kLogRingBufMsgLen];
3699 EventBuf events_[kLogRingBufEntries]{};
3700
3701 static_assert((kLogRingBufEntries & (kLogRingBufEntries - 1)) == 0,
3702 "kLogRingBufEntries must be a power of two");
3703
3704 // A monotonically increasing counter incremented on each event written.
3705 // It determines which of the kLogRingBufEntries indexes in |events_| should
3706 // be used next.
3707 // It grows >> kLogRingBufEntries, it's supposed to be always used
3708 // mod(kLogRingBufEntries). A static_assert in the .cc file ensures that
3709 // kLogRingBufEntries is a power of two so wraps are aligned.
3710 std::atomic<uint32_t> event_slot_{};
3711 };
3712
3713 } // namespace base
3714 } // namespace perfetto
3715
3716 #endif // SRC_BASE_LOG_RING_BUFFER_H_
3717 /*
3718 * Copyright (C) 2019 The Android Open Source Project
3719 *
3720 * Licensed under the Apache License, Version 2.0 (the "License");
3721 * you may not use this file except in compliance with the License.
3722 * You may obtain a copy of the License at
3723 *
3724 * http://www.apache.org/licenses/LICENSE-2.0
3725 *
3726 * Unless required by applicable law or agreed to in writing, software
3727 * distributed under the License is distributed on an "AS IS" BASIS,
3728 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3729 * See the License for the specific language governing permissions and
3730 * limitations under the License.
3731 */
3732
3733 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
3734
3735 #include <stdarg.h>
3736 #include <stdio.h>
3737
3738 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
3739 #include <unistd.h> // For isatty()
3740 #endif
3741
3742 #include <atomic>
3743 #include <memory>
3744
3745 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
3746 // gen_amalgamated expanded: #include "perfetto/base/time.h"
3747 // gen_amalgamated expanded: #include "perfetto/ext/base/crash_keys.h"
3748 // gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
3749 // gen_amalgamated expanded: #include "perfetto/ext/base/string_view.h"
3750 // gen_amalgamated expanded: #include "src/base/log_ring_buffer.h"
3751
3752 #if PERFETTO_ENABLE_LOG_RING_BUFFER() && PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
3753 #include <android/set_abort_message.h>
3754 #endif
3755
3756 namespace perfetto {
3757 namespace base {
3758
3759 namespace {
3760 const char kReset[] = "\x1b[0m";
3761 const char kDefault[] = "\x1b[39m";
3762 const char kDim[] = "\x1b[2m";
3763 const char kRed[] = "\x1b[31m";
3764 const char kBoldGreen[] = "\x1b[1m\x1b[32m";
3765 const char kLightGray[] = "\x1b[90m";
3766
3767 std::atomic<LogMessageCallback> g_log_callback{};
3768
3769 #if PERFETTO_BUILDFLAG(PERFETTO_STDERR_CRASH_DUMP)
3770 // __attribute__((constructor)) causes a static initializer that automagically
3771 // early runs this function before the main().
InitDebugCrashReporter()3772 void PERFETTO_EXPORT __attribute__((constructor)) InitDebugCrashReporter() {
3773 // This function is defined in debug_crash_stack_trace.cc.
3774 // The dynamic initializer is in logging.cc because logging.cc is included
3775 // in virtually any target that depends on base. Having it in
3776 // debug_crash_stack_trace.cc would require figuring out -Wl,whole-archive
3777 // which is not worth it.
3778 EnableStacktraceOnCrashForDebug();
3779 }
3780 #endif
3781
3782 #if PERFETTO_ENABLE_LOG_RING_BUFFER()
3783 LogRingBuffer g_log_ring_buffer{};
3784
3785 // This is global to avoid allocating memory or growing too much the stack
3786 // in MaybeSerializeLastLogsForCrashReporting(), which is called from
3787 // arbitrary code paths hitting PERFETTO_CHECK()/FATAL().
3788 char g_crash_buf[kLogRingBufEntries * kLogRingBufMsgLen];
3789 #endif
3790
3791 } // namespace
3792
SetLogMessageCallback(LogMessageCallback callback)3793 void SetLogMessageCallback(LogMessageCallback callback) {
3794 g_log_callback.store(callback, std::memory_order_relaxed);
3795 }
3796
LogMessage(LogLev level,const char * fname,int line,const char * fmt,...)3797 void LogMessage(LogLev level,
3798 const char* fname,
3799 int line,
3800 const char* fmt,
3801 ...) {
3802 char stack_buf[512];
3803 std::unique_ptr<char[]> large_buf;
3804 char* log_msg = &stack_buf[0];
3805 size_t log_msg_len = 0;
3806
3807 // By default use a stack allocated buffer because most log messages are quite
3808 // short. In rare cases they can be larger (e.g. --help). In those cases we
3809 // pay the cost of allocating the buffer on the heap.
3810 for (size_t max_len = sizeof(stack_buf);;) {
3811 va_list args;
3812 va_start(args, fmt);
3813 int res = vsnprintf(log_msg, max_len, fmt, args);
3814 va_end(args);
3815
3816 // If for any reason the print fails, overwrite the message but still print
3817 // it. The code below will attach the filename and line, which is still
3818 // useful.
3819 if (res < 0) {
3820 snprintf(log_msg, max_len, "%s", "[printf format error]");
3821 break;
3822 }
3823
3824 // if res == max_len, vsnprintf saturated the input buffer. Retry with a
3825 // larger buffer in that case (within reasonable limits).
3826 if (res < static_cast<int>(max_len) || max_len >= 128 * 1024) {
3827 // In case of truncation vsnprintf returns the len that "would have been
3828 // written if the string was longer", not the actual chars written.
3829 log_msg_len = std::min(static_cast<size_t>(res), max_len - 1);
3830 break;
3831 }
3832 max_len *= 4;
3833 large_buf.reset(new char[max_len]);
3834 log_msg = &large_buf[0];
3835 }
3836
3837 LogMessageCallback cb = g_log_callback.load(std::memory_order_relaxed);
3838 if (cb) {
3839 cb({level, line, fname, log_msg});
3840 return;
3841 }
3842
3843 const char* color = kDefault;
3844 switch (level) {
3845 case kLogDebug:
3846 color = kDim;
3847 break;
3848 case kLogInfo:
3849 color = kDefault;
3850 break;
3851 case kLogImportant:
3852 color = kBoldGreen;
3853 break;
3854 case kLogError:
3855 color = kRed;
3856 break;
3857 }
3858
3859 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) && \
3860 !PERFETTO_BUILDFLAG(PERFETTO_OS_WASM) && \
3861 !PERFETTO_BUILDFLAG(PERFETTO_CHROMIUM_BUILD)
3862 static const bool use_colors = isatty(STDERR_FILENO);
3863 #else
3864 static const bool use_colors = false;
3865 #endif
3866
3867 // Formats file.cc:line as a space-padded fixed width string. If the file name
3868 // |fname| is too long, truncate it on the left-hand side.
3869 StackString<10> line_str("%d", line);
3870
3871 // 24 will be the width of the file.cc:line column in the log event.
3872 static constexpr size_t kMaxNameAndLine = 24;
3873 size_t fname_len = strlen(fname);
3874 size_t fname_max = kMaxNameAndLine - line_str.len() - 2; // 2 = ':' + '\0'.
3875 size_t fname_offset = fname_len <= fname_max ? 0 : fname_len - fname_max;
3876 StackString<kMaxNameAndLine> file_and_line(
3877 "%*s:%s", static_cast<int>(fname_max), &fname[fname_offset],
3878 line_str.c_str());
3879
3880 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
3881 // Logcat has already timestamping, don't re-emit it.
3882 __android_log_print(ANDROID_LOG_DEBUG + level, "perfetto", "%s %s",
3883 file_and_line.c_str(), log_msg);
3884 #endif
3885
3886 // When printing on stderr, print also the timestamp. We don't really care
3887 // about the actual time. We just need some reference clock that can be used
3888 // to correlated events across differrent processses (e.g. traced and
3889 // traced_probes). The wall time % 1000 is good enough.
3890 uint32_t t_ms = static_cast<uint32_t>(GetWallTimeMs().count());
3891 uint32_t t_sec = t_ms / 1000;
3892 t_ms -= t_sec * 1000;
3893 t_sec = t_sec % 1000;
3894 StackString<32> timestamp("[%03u.%03u] ", t_sec, t_ms);
3895
3896 if (use_colors) {
3897 fprintf(stderr, "%s%s%s%s %s%s%s\n", kLightGray, timestamp.c_str(),
3898 file_and_line.c_str(), kReset, color, log_msg, kReset);
3899 } else {
3900 fprintf(stderr, "%s%s %s\n", timestamp.c_str(), file_and_line.c_str(),
3901 log_msg);
3902 }
3903
3904 #if PERFETTO_ENABLE_LOG_RING_BUFFER()
3905 // Append the message to the ring buffer for crash reporting postmortems.
3906 StringView timestamp_sv = timestamp.string_view();
3907 StringView file_and_line_sv = file_and_line.string_view();
3908 StringView log_msg_sv(log_msg, static_cast<size_t>(log_msg_len));
3909 g_log_ring_buffer.Append(timestamp_sv, file_and_line_sv, log_msg_sv);
3910 #else
3911 ignore_result(log_msg_len);
3912 #endif
3913 }
3914
3915 #if PERFETTO_ENABLE_LOG_RING_BUFFER()
MaybeSerializeLastLogsForCrashReporting()3916 void MaybeSerializeLastLogsForCrashReporting() {
3917 // Keep this function minimal. This is called from the watchdog thread, often
3918 // when the system is thrashing.
3919
3920 // This is racy because two threads could hit a CHECK/FATAL at the same time.
3921 // But if that happens we have bigger problems, not worth designing around it.
3922 // The behaviour is still defined in the race case (the string attached to
3923 // the crash report will contain a mixture of log strings).
3924 size_t wr = 0;
3925 wr += SerializeCrashKeys(&g_crash_buf[wr], sizeof(g_crash_buf) - wr);
3926 wr += g_log_ring_buffer.Read(&g_crash_buf[wr], sizeof(g_crash_buf) - wr);
3927
3928 // Read() null-terminates the string properly. This is just to avoid UB when
3929 // two threads race on each other (T1 writes a shorter string, T2
3930 // overwrites the \0 writing a longer string. T1 continues here before T2
3931 // finishes writing the longer string with the \0 -> boom.
3932 g_crash_buf[sizeof(g_crash_buf) - 1] = '\0';
3933
3934 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
3935 // android_set_abort_message() will cause debuggerd to report the message
3936 // in the tombstone and in the crash log in logcat.
3937 // NOTE: android_set_abort_message() can be called only once. This should
3938 // be called only when we are sure we are about to crash.
3939 android_set_abort_message(g_crash_buf);
3940 #else
3941 // Print out the message on stderr on Linux/Mac/Win.
3942 fputs("\n-----BEGIN PERFETTO PRE-CRASH LOG-----\n", stderr);
3943 fputs(g_crash_buf, stderr);
3944 fputs("\n-----END PERFETTO PRE-CRASH LOG-----\n", stderr);
3945 #endif
3946 }
3947 #endif // PERFETTO_ENABLE_LOG_RING_BUFFER
3948
3949 } // namespace base
3950 } // namespace perfetto
3951 // gen_amalgamated begin source: src/base/metatrace.cc
3952 // gen_amalgamated begin header: include/perfetto/ext/base/metatrace.h
3953 // gen_amalgamated begin header: include/perfetto/ext/base/metatrace_events.h
3954 /*
3955 * Copyright (C) 2019 The Android Open Source Project
3956 *
3957 * Licensed under the Apache License, Version 2.0 (the "License");
3958 * you may not use this file except in compliance with the License.
3959 * You may obtain a copy of the License at
3960 *
3961 * http://www.apache.org/licenses/LICENSE-2.0
3962 *
3963 * Unless required by applicable law or agreed to in writing, software
3964 * distributed under the License is distributed on an "AS IS" BASIS,
3965 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3966 * See the License for the specific language governing permissions and
3967 * limitations under the License.
3968 */
3969
3970 #ifndef INCLUDE_PERFETTO_EXT_BASE_METATRACE_EVENTS_H_
3971 #define INCLUDE_PERFETTO_EXT_BASE_METATRACE_EVENTS_H_
3972
3973 #include <stdint.h>
3974
3975 namespace perfetto {
3976 namespace metatrace {
3977
3978 enum Tags : uint32_t {
3979 TAG_NONE = 0,
3980 TAG_ANY = uint32_t(-1),
3981 TAG_FTRACE = 1 << 0,
3982 TAG_PROC_POLLERS = 1 << 1,
3983 TAG_TRACE_WRITER = 1 << 2,
3984 TAG_TRACE_SERVICE = 1 << 3,
3985 TAG_PRODUCER = 1 << 4,
3986 };
3987
3988 // The macros below generate matching enums and arrays of string literals.
3989 // This is to avoid maintaining string maps manually.
3990
3991 // clang-format off
3992
3993 // DO NOT remove or reshuffle items in this list, only append. The ID of these
3994 // events are an ABI, the trace processor relies on these to open old traces.
3995 #define PERFETTO_METATRACE_EVENTS(F) \
3996 F(EVENT_ZERO_UNUSED), \
3997 F(FTRACE_CPU_READER_READ), /*unused*/ \
3998 F(FTRACE_DRAIN_CPUS), /*unused*/ \
3999 F(FTRACE_UNBLOCK_READERS), /*unused*/ \
4000 F(FTRACE_CPU_READ_NONBLOCK), /*unused*/ \
4001 F(FTRACE_CPU_READ_BLOCK), /*unused*/ \
4002 F(FTRACE_CPU_SPLICE_NONBLOCK), /*unused*/ \
4003 F(FTRACE_CPU_SPLICE_BLOCK), /*unused*/ \
4004 F(FTRACE_CPU_WAIT_CMD), /*unused*/ \
4005 F(FTRACE_CPU_RUN_CYCLE), /*unused*/ \
4006 F(FTRACE_CPU_FLUSH), \
4007 F(FTRACE_CPU_DRAIN), /*unused*/ \
4008 F(READ_SYS_STATS), \
4009 F(PS_WRITE_ALL_PROCESSES), \
4010 F(PS_ON_PIDS), \
4011 F(PS_ON_RENAME_PIDS), \
4012 F(PS_WRITE_ALL_PROCESS_STATS), \
4013 F(TRACE_WRITER_COMMIT_STARTUP_WRITER_BATCH), \
4014 F(FTRACE_READ_TICK), \
4015 F(FTRACE_CPU_READ_CYCLE), \
4016 F(FTRACE_CPU_READ_BATCH), \
4017 F(KALLSYMS_PARSE), \
4018 F(PROFILER_READ_TICK), \
4019 F(PROFILER_READ_CPU), \
4020 F(PROFILER_UNWIND_TICK), \
4021 F(PROFILER_UNWIND_SAMPLE), \
4022 F(PROFILER_UNWIND_INITIAL_ATTEMPT), \
4023 F(PROFILER_UNWIND_ATTEMPT), \
4024 F(PROFILER_MAPS_PARSE), \
4025 F(PROFILER_MAPS_REPARSE), \
4026 F(PROFILER_UNWIND_CACHE_CLEAR)
4027
4028 // Append only, see above.
4029 //
4030 // Values that aren't used as counters:
4031 // * FTRACE_SERVICE_COMMIT_DATA is a bit-packed representation of an event, see
4032 // tracing_service_impl.cc for the format.
4033 // * PROFILER_UNWIND_CURRENT_PID represents the PID that is being unwound.
4034 //
4035 #define PERFETTO_METATRACE_COUNTERS(F) \
4036 F(COUNTER_ZERO_UNUSED),\
4037 F(FTRACE_PAGES_DRAINED), \
4038 F(PS_PIDS_SCANNED), \
4039 F(TRACE_SERVICE_COMMIT_DATA), \
4040 F(PROFILER_UNWIND_QUEUE_SZ), \
4041 F(PROFILER_UNWIND_CURRENT_PID)
4042
4043 // clang-format on
4044
4045 #define PERFETTO_METATRACE_IDENTITY(name) name
4046 #define PERFETTO_METATRACE_TOSTRING(name) #name
4047
4048 enum Events : uint16_t {
4049 PERFETTO_METATRACE_EVENTS(PERFETTO_METATRACE_IDENTITY),
4050 EVENTS_MAX
4051 };
4052 constexpr char const* kEventNames[] = {
4053 PERFETTO_METATRACE_EVENTS(PERFETTO_METATRACE_TOSTRING)};
4054
4055 enum Counters : uint16_t {
4056 PERFETTO_METATRACE_COUNTERS(PERFETTO_METATRACE_IDENTITY),
4057 COUNTERS_MAX
4058 };
4059 constexpr char const* kCounterNames[] = {
4060 PERFETTO_METATRACE_COUNTERS(PERFETTO_METATRACE_TOSTRING)};
4061
SuppressUnusedVarsInAmalgamatedBuild()4062 inline void SuppressUnusedVarsInAmalgamatedBuild() {
4063 (void)kCounterNames;
4064 (void)kEventNames;
4065 }
4066
4067 } // namespace metatrace
4068 } // namespace perfetto
4069
4070 #endif // INCLUDE_PERFETTO_EXT_BASE_METATRACE_EVENTS_H_
4071 /*
4072 * Copyright (C) 2019 The Android Open Source Project
4073 *
4074 * Licensed under the Apache License, Version 2.0 (the "License");
4075 * you may not use this file except in compliance with the License.
4076 * You may obtain a copy of the License at
4077 *
4078 * http://www.apache.org/licenses/LICENSE-2.0
4079 *
4080 * Unless required by applicable law or agreed to in writing, software
4081 * distributed under the License is distributed on an "AS IS" BASIS,
4082 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4083 * See the License for the specific language governing permissions and
4084 * limitations under the License.
4085 */
4086
4087 #ifndef INCLUDE_PERFETTO_EXT_BASE_METATRACE_H_
4088 #define INCLUDE_PERFETTO_EXT_BASE_METATRACE_H_
4089
4090 #include <array>
4091 #include <atomic>
4092 #include <functional>
4093 #include <string>
4094
4095 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
4096 // gen_amalgamated expanded: #include "perfetto/base/thread_utils.h"
4097 // gen_amalgamated expanded: #include "perfetto/base/time.h"
4098 // gen_amalgamated expanded: #include "perfetto/ext/base/metatrace_events.h"
4099 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
4100
4101 // A facility to trace execution of the perfetto codebase itself.
4102 // The meta-tracing framework is organized into three layers:
4103 //
4104 // 1. A static ring-buffer in base/ (this file) that supports concurrent writes
4105 // and a single reader.
4106 // The responsibility of this layer is to store events and counters as
4107 // efficiently as possible without re-entering any tracing code.
4108 // This is really a static-storage-based ring-buffer based on a POD array.
4109 // This layer does NOT deal with serializing the meta-trace buffer.
4110 // It posts a task when it's half full and expects something outside of
4111 // base/ to drain the ring-buffer and serialize it, eventually writing it
4112 // into the trace itself, before it gets 100% full.
4113 //
4114 // 2. A class in tracing/core which takes care of serializing the meta-trace
4115 // buffer into the trace using a TraceWriter. See metatrace_writer.h .
4116 //
4117 // 3. A data source in traced_probes that, when be enabled via the trace config,
4118 // injects metatrace events into the trace. See metatrace_data_source.h .
4119 //
4120 // The available events and tags are defined in metatrace_events.h .
4121
4122 namespace perfetto {
4123
4124 namespace base {
4125 class TaskRunner;
4126 } // namespace base
4127
4128 namespace metatrace {
4129
4130 // Meta-tracing is organized in "tags" that can be selectively enabled. This is
4131 // to enable meta-tracing only of one sub-system. This word has one "enabled"
4132 // bit for each tag. 0 -> meta-tracing off.
4133 extern std::atomic<uint32_t> g_enabled_tags;
4134
4135 // Time of the Enable() call. Used as a reference for keeping delta timestmaps
4136 // in Record.
4137 extern std::atomic<uint64_t> g_enabled_timestamp;
4138
4139 // Enables meta-tracing for one or more tags. Once enabled it will discard any
4140 // further Enable() calls and return false until disabled,
4141 // |read_task| is a closure that will be called enqueued |task_runner| when the
4142 // meta-tracing ring buffer is half full. The task is expected to read the ring
4143 // buffer using RingBuffer::GetReadIterator() and serialize the contents onto a
4144 // file or into the trace itself.
4145 // Must be called on the |task_runner| passed.
4146 // |task_runner| must have static lifetime.
4147 bool Enable(std::function<void()> read_task, base::TaskRunner*, uint32_t tags);
4148
4149 // Disables meta-tracing.
4150 // Must be called on the same |task_runner| as Enable().
4151 void Disable();
4152
TraceTimeNowNs()4153 inline uint64_t TraceTimeNowNs() {
4154 return static_cast<uint64_t>(base::GetBootTimeNs().count());
4155 }
4156
4157 // Returns a relaxed view of whether metatracing is enabled for the given tag.
4158 // Useful for skipping unnecessary argument computation if metatracing is off.
IsEnabled(uint32_t tag)4159 inline bool IsEnabled(uint32_t tag) {
4160 auto enabled_tags = g_enabled_tags.load(std::memory_order_relaxed);
4161 return PERFETTO_UNLIKELY((enabled_tags & tag) != 0);
4162 }
4163
4164 // Holds the data for a metatrace event or counter.
4165 struct Record {
4166 static constexpr uint16_t kTypeMask = 0x8000;
4167 static constexpr uint16_t kTypeCounter = 0x8000;
4168 static constexpr uint16_t kTypeEvent = 0;
4169
timestamp_nsperfetto::metatrace::Record4170 uint64_t timestamp_ns() const {
4171 auto base_ns = g_enabled_timestamp.load(std::memory_order_relaxed);
4172 PERFETTO_DCHECK(base_ns);
4173 return base_ns + ((static_cast<uint64_t>(timestamp_ns_high) << 32) |
4174 timestamp_ns_low);
4175 }
4176
set_timestampperfetto::metatrace::Record4177 void set_timestamp(uint64_t ts) {
4178 auto t_start = g_enabled_timestamp.load(std::memory_order_relaxed);
4179 uint64_t diff = ts - t_start;
4180 PERFETTO_DCHECK(diff < (1ull << 48));
4181 timestamp_ns_low = static_cast<uint32_t>(diff);
4182 timestamp_ns_high = static_cast<uint16_t>(diff >> 32);
4183 }
4184
4185 // We can't just memset() this class because on MSVC std::atomic<> is not
4186 // trivially constructible anymore. Also std::atomic<> has a deleted copy
4187 // constructor so we cant just do "*this = Record()" either.
4188 // See http://bit.ly/339Jlzd .
clearperfetto::metatrace::Record4189 void clear() {
4190 this->~Record();
4191 new (this) Record();
4192 }
4193
4194 // This field holds the type (counter vs event) in the MSB and event ID (as
4195 // defined in metatrace_events.h) in the lowest 15 bits. It is also used also
4196 // as a linearization point: this is always written after all the other
4197 // fields with a release-store. This is so the reader can determine whether it
4198 // can safely process the other event fields after a load-acquire.
4199 std::atomic<uint16_t> type_and_id{};
4200
4201 // Timestamp is stored as a 48-bits value diffed against g_enabled_timestamp.
4202 // This gives us 78 hours from Enabled().
4203 uint16_t timestamp_ns_high = 0;
4204 uint32_t timestamp_ns_low = 0;
4205
4206 uint32_t thread_id = 0;
4207
4208 union {
4209 // Only one of the two elements can be zero initialized, clang complains
4210 // about "initializing multiple members of union" otherwise.
4211 uint32_t duration_ns = 0; // If type == event.
4212 int32_t counter_value; // If type == counter.
4213 };
4214 };
4215
4216 // Hold the meta-tracing data into a statically allocated array.
4217 // This class uses static storage (as opposite to being a singleton) to:
4218 // - Have the guarantee of always valid storage, so that meta-tracing can be
4219 // safely used in any part of the codebase, including base/ itself.
4220 // - Avoid barriers that thread-safe static locals would require.
4221 class RingBuffer {
4222 public:
4223 static constexpr size_t kCapacity = 4096; // 4096 * 16 bytes = 64K.
4224
4225 // This iterator is not idempotent and will bump the read index in the buffer
4226 // at the end of the reads. There can be only one reader at any time.
4227 // Usage: for (auto it = RingBuffer::GetReadIterator(); it; ++it) { it->... }
4228 class ReadIterator {
4229 public:
ReadIterator(ReadIterator && other)4230 ReadIterator(ReadIterator&& other) {
4231 PERFETTO_DCHECK(other.valid_);
4232 cur_ = other.cur_;
4233 end_ = other.end_;
4234 valid_ = other.valid_;
4235 other.valid_ = false;
4236 }
4237
~ReadIterator()4238 ~ReadIterator() {
4239 if (!valid_)
4240 return;
4241 PERFETTO_DCHECK(cur_ >= RingBuffer::rd_index_);
4242 PERFETTO_DCHECK(cur_ <= RingBuffer::wr_index_);
4243 RingBuffer::rd_index_.store(cur_, std::memory_order_release);
4244 }
4245
operator bool() const4246 explicit operator bool() const { return cur_ < end_; }
operator ->() const4247 const Record* operator->() const { return RingBuffer::At(cur_); }
operator *() const4248 const Record& operator*() const { return *operator->(); }
4249
4250 // This is for ++it. it++ is deliberately not supported.
operator ++()4251 ReadIterator& operator++() {
4252 PERFETTO_DCHECK(cur_ < end_);
4253 // Once a record has been read, mark it as free clearing its type_and_id,
4254 // so if we encounter it in another read iteration while being written
4255 // we know it's not fully written yet.
4256 // The memory_order_relaxed below is enough because:
4257 // - The reader is single-threaded and doesn't re-read the same records.
4258 // - Before starting a read batch, the reader has an acquire barrier on
4259 // |rd_index_|.
4260 // - After terminating a read batch, the ~ReadIterator dtor updates the
4261 // |rd_index_| with a release-store.
4262 // - Reader and writer are typically kCapacity/2 apart. So unless an
4263 // overrun happens a writer won't reuse a newly released record any time
4264 // soon. If an overrun happens, everything is busted regardless.
4265 At(cur_)->type_and_id.store(0, std::memory_order_relaxed);
4266 ++cur_;
4267 return *this;
4268 }
4269
4270 private:
4271 friend class RingBuffer;
ReadIterator(uint64_t begin,uint64_t end)4272 ReadIterator(uint64_t begin, uint64_t end)
4273 : cur_(begin), end_(end), valid_(true) {}
4274 ReadIterator& operator=(const ReadIterator&) = delete;
4275 ReadIterator(const ReadIterator&) = delete;
4276
4277 uint64_t cur_;
4278 uint64_t end_;
4279 bool valid_;
4280 };
4281
At(uint64_t index)4282 static Record* At(uint64_t index) {
4283 // Doesn't really have to be pow2, but if not the compiler will emit
4284 // arithmetic operations to compute the modulo instead of a bitwise AND.
4285 static_assert(!(kCapacity & (kCapacity - 1)), "kCapacity must be pow2");
4286 PERFETTO_DCHECK(index >= rd_index_);
4287 PERFETTO_DCHECK(index <= wr_index_);
4288 return &records_[index % kCapacity];
4289 }
4290
4291 // Must be called on the same task runner passed to Enable()
GetReadIterator()4292 static ReadIterator GetReadIterator() {
4293 PERFETTO_DCHECK(RingBuffer::IsOnValidTaskRunner());
4294 return ReadIterator(rd_index_.load(std::memory_order_acquire),
4295 wr_index_.load(std::memory_order_acquire));
4296 }
4297
4298 static Record* AppendNewRecord();
4299 static void Reset();
4300
has_overruns()4301 static bool has_overruns() {
4302 return has_overruns_.load(std::memory_order_acquire);
4303 }
4304
4305 // Can temporarily return a value >= kCapacity but is eventually consistent.
4306 // This would happen in case of overruns until threads hit the --wr_index_
4307 // in AppendNewRecord().
GetSizeForTesting()4308 static uint64_t GetSizeForTesting() {
4309 auto wr_index = wr_index_.load(std::memory_order_relaxed);
4310 auto rd_index = rd_index_.load(std::memory_order_relaxed);
4311 PERFETTO_DCHECK(wr_index >= rd_index);
4312 return wr_index - rd_index;
4313 }
4314
4315 private:
4316 friend class ReadIterator;
4317
4318 // Returns true if the caller is on the task runner passed to Enable().
4319 // Used only for DCHECKs.
4320 static bool IsOnValidTaskRunner();
4321
4322 static std::array<Record, kCapacity> records_;
4323 static std::atomic<bool> read_task_queued_;
4324 static std::atomic<uint64_t> wr_index_;
4325 static std::atomic<uint64_t> rd_index_;
4326 static std::atomic<bool> has_overruns_;
4327 static Record bankruptcy_record_; // Used in case of overruns.
4328 };
4329
TraceCounter(uint32_t tag,uint16_t id,int32_t value)4330 inline void TraceCounter(uint32_t tag, uint16_t id, int32_t value) {
4331 // memory_order_relaxed is okay because the storage has static lifetime.
4332 // It is safe to accidentally log an event soon after disabling.
4333 auto enabled_tags = g_enabled_tags.load(std::memory_order_relaxed);
4334 if (PERFETTO_LIKELY((enabled_tags & tag) == 0))
4335 return;
4336 Record* record = RingBuffer::AppendNewRecord();
4337 record->thread_id = static_cast<uint32_t>(base::GetThreadId());
4338 record->set_timestamp(TraceTimeNowNs());
4339 record->counter_value = value;
4340 record->type_and_id.store(Record::kTypeCounter | id,
4341 std::memory_order_release);
4342 }
4343
4344 class ScopedEvent {
4345 public:
ScopedEvent(uint32_t tag,uint16_t event_id)4346 ScopedEvent(uint32_t tag, uint16_t event_id) {
4347 auto enabled_tags = g_enabled_tags.load(std::memory_order_relaxed);
4348 if (PERFETTO_LIKELY((enabled_tags & tag) == 0))
4349 return;
4350 event_id_ = event_id;
4351 record_ = RingBuffer::AppendNewRecord();
4352 record_->thread_id = static_cast<uint32_t>(base::GetThreadId());
4353 record_->set_timestamp(TraceTimeNowNs());
4354 }
4355
~ScopedEvent()4356 ~ScopedEvent() {
4357 if (PERFETTO_LIKELY(!record_))
4358 return;
4359 auto now = TraceTimeNowNs();
4360 record_->duration_ns = static_cast<uint32_t>(now - record_->timestamp_ns());
4361 record_->type_and_id.store(Record::kTypeEvent | event_id_,
4362 std::memory_order_release);
4363 }
4364
4365 private:
4366 Record* record_ = nullptr;
4367 uint16_t event_id_ = 0;
4368 ScopedEvent(const ScopedEvent&) = delete;
4369 ScopedEvent& operator=(const ScopedEvent&) = delete;
4370 };
4371
4372 // Boilerplate to derive a unique variable name for the event.
4373 #define PERFETTO_METATRACE_UID2(a, b) a##b
4374 #define PERFETTO_METATRACE_UID(x) PERFETTO_METATRACE_UID2(metatrace_, x)
4375
4376 #define PERFETTO_METATRACE_SCOPED(TAG, ID) \
4377 ::perfetto::metatrace::ScopedEvent PERFETTO_METATRACE_UID(__COUNTER__)( \
4378 ::perfetto::metatrace::TAG, ::perfetto::metatrace::ID)
4379
4380 #define PERFETTO_METATRACE_COUNTER(TAG, ID, VALUE) \
4381 ::perfetto::metatrace::TraceCounter(::perfetto::metatrace::TAG, \
4382 ::perfetto::metatrace::ID, \
4383 static_cast<int32_t>(VALUE))
4384
4385 } // namespace metatrace
4386 } // namespace perfetto
4387
4388 #endif // INCLUDE_PERFETTO_EXT_BASE_METATRACE_H_
4389 // gen_amalgamated begin header: include/perfetto/base/task_runner.h
4390 /*
4391 * Copyright (C) 2017 The Android Open Source Project
4392 *
4393 * Licensed under the Apache License, Version 2.0 (the "License");
4394 * you may not use this file except in compliance with the License.
4395 * You may obtain a copy of the License at
4396 *
4397 * http://www.apache.org/licenses/LICENSE-2.0
4398 *
4399 * Unless required by applicable law or agreed to in writing, software
4400 * distributed under the License is distributed on an "AS IS" BASIS,
4401 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4402 * See the License for the specific language governing permissions and
4403 * limitations under the License.
4404 */
4405
4406 #ifndef INCLUDE_PERFETTO_BASE_TASK_RUNNER_H_
4407 #define INCLUDE_PERFETTO_BASE_TASK_RUNNER_H_
4408
4409 #include <stdint.h>
4410
4411 #include <functional>
4412
4413 // gen_amalgamated expanded: #include "perfetto/base/export.h"
4414 // gen_amalgamated expanded: #include "perfetto/base/platform_handle.h"
4415
4416 namespace perfetto {
4417 namespace base {
4418
4419 // A generic interface to allow the library clients to interleave the execution
4420 // of the tracing internals in their runtime environment.
4421 // The expectation is that all tasks, which are queued either via PostTask() or
4422 // AddFileDescriptorWatch(), are executed on the same sequence (either on the
4423 // same thread, or on a thread pool that gives sequencing guarantees).
4424 //
4425 // Tasks are never executed synchronously inside PostTask and there is a full
4426 // memory barrier between tasks.
4427 //
4428 // All methods of this interface can be called from any thread.
4429 class PERFETTO_EXPORT TaskRunner {
4430 public:
4431 virtual ~TaskRunner();
4432
4433 // Schedule a task for immediate execution. Immediate tasks are always
4434 // executed in the order they are posted. Can be called from any thread.
4435 virtual void PostTask(std::function<void()>) = 0;
4436
4437 // Schedule a task for execution after |delay_ms|. Note that there is no
4438 // strict ordering guarantee between immediate and delayed tasks. Can be
4439 // called from any thread.
4440 virtual void PostDelayedTask(std::function<void()>, uint32_t delay_ms) = 0;
4441
4442 // Schedule a task to run when the handle becomes readable. The same handle
4443 // can only be monitored by one function. Note that this function only needs
4444 // to be implemented on platforms where the built-in ipc framework is used.
4445 // Can be called from any thread.
4446 // TODO(skyostil): Refactor this out of the shared interface.
4447 virtual void AddFileDescriptorWatch(PlatformHandle,
4448 std::function<void()>) = 0;
4449
4450 // Remove a previously scheduled watch for the handle. If this is run on the
4451 // target thread of this TaskRunner, guarantees that the task registered to
4452 // this handle will not be executed after this function call.
4453 // Can be called from any thread.
4454 virtual void RemoveFileDescriptorWatch(PlatformHandle) = 0;
4455
4456 // Checks if the current thread is the same thread where the TaskRunner's task
4457 // run. This allows single threaded task runners (like the ones used in
4458 // perfetto) to inform the caller that anything posted will run on the same
4459 // thread/sequence. This can allow some callers to skip PostTask and instead
4460 // directly execute the code. Can be called from any thread.
4461 virtual bool RunsTasksOnCurrentThread() const = 0;
4462 };
4463
4464 } // namespace base
4465 } // namespace perfetto
4466
4467 #endif // INCLUDE_PERFETTO_BASE_TASK_RUNNER_H_
4468 /*
4469 * Copyright (C) 2018 The Android Open Source Project
4470 *
4471 * Licensed under the Apache License, Version 2.0 (the "License");
4472 * you may not use this file except in compliance with the License.
4473 * You may obtain a copy of the License at
4474 *
4475 * http://www.apache.org/licenses/LICENSE-2.0
4476 *
4477 * Unless required by applicable law or agreed to in writing, software
4478 * distributed under the License is distributed on an "AS IS" BASIS,
4479 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4480 * See the License for the specific language governing permissions and
4481 * limitations under the License.
4482 */
4483
4484 // gen_amalgamated expanded: #include "perfetto/ext/base/metatrace.h"
4485
4486 // gen_amalgamated expanded: #include "perfetto/base/compiler.h"
4487 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
4488 // gen_amalgamated expanded: #include "perfetto/base/time.h"
4489 // gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
4490 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_annotations.h"
4491
4492 namespace perfetto {
4493 namespace metatrace {
4494
4495 std::atomic<uint32_t> g_enabled_tags{0};
4496 std::atomic<uint64_t> g_enabled_timestamp{0};
4497
4498 // static members
4499 constexpr size_t RingBuffer::kCapacity;
4500 std::array<Record, RingBuffer::kCapacity> RingBuffer::records_;
4501 std::atomic<bool> RingBuffer::read_task_queued_;
4502 std::atomic<uint64_t> RingBuffer::wr_index_;
4503 std::atomic<uint64_t> RingBuffer::rd_index_;
4504 std::atomic<bool> RingBuffer::has_overruns_;
4505 Record RingBuffer::bankruptcy_record_;
4506
4507 constexpr uint16_t Record::kTypeMask;
4508 constexpr uint16_t Record::kTypeCounter;
4509 constexpr uint16_t Record::kTypeEvent;
4510
4511 namespace {
4512
4513 // std::function<> is not trivially de/constructible. This struct wraps it in a
4514 // heap-allocated struct to avoid static initializers.
4515 struct Delegate {
GetInstanceperfetto::metatrace::__anon3c415f210f11::Delegate4516 static Delegate* GetInstance() {
4517 static Delegate* instance = new Delegate();
4518 return instance;
4519 }
4520
4521 base::TaskRunner* task_runner = nullptr;
4522 std::function<void()> read_task;
4523 };
4524
4525 } // namespace
4526
Enable(std::function<void ()> read_task,base::TaskRunner * task_runner,uint32_t tags)4527 bool Enable(std::function<void()> read_task,
4528 base::TaskRunner* task_runner,
4529 uint32_t tags) {
4530 PERFETTO_DCHECK(read_task);
4531 PERFETTO_DCHECK(task_runner->RunsTasksOnCurrentThread());
4532 if (g_enabled_tags.load(std::memory_order_acquire))
4533 return false;
4534
4535 Delegate* dg = Delegate::GetInstance();
4536 dg->task_runner = task_runner;
4537 dg->read_task = std::move(read_task);
4538 RingBuffer::Reset();
4539 g_enabled_timestamp.store(TraceTimeNowNs(), std::memory_order_relaxed);
4540 g_enabled_tags.store(tags, std::memory_order_release);
4541 return true;
4542 }
4543
Disable()4544 void Disable() {
4545 g_enabled_tags.store(0, std::memory_order_release);
4546 Delegate* dg = Delegate::GetInstance();
4547 PERFETTO_DCHECK(!dg->task_runner ||
4548 dg->task_runner->RunsTasksOnCurrentThread());
4549 dg->task_runner = nullptr;
4550 dg->read_task = nullptr;
4551 }
4552
4553 // static
Reset()4554 void RingBuffer::Reset() {
4555 bankruptcy_record_.clear();
4556 for (Record& record : records_)
4557 record.clear();
4558 wr_index_ = 0;
4559 rd_index_ = 0;
4560 has_overruns_ = false;
4561 read_task_queued_ = false;
4562 }
4563
4564 // static
AppendNewRecord()4565 Record* RingBuffer::AppendNewRecord() {
4566 auto wr_index = wr_index_.fetch_add(1, std::memory_order_acq_rel);
4567
4568 // rd_index can only monotonically increase, we don't care if we read an
4569 // older value, we'll just hit the slow-path a bit earlier if it happens.
4570 auto rd_index = rd_index_.load(std::memory_order_relaxed);
4571
4572 PERFETTO_DCHECK(wr_index >= rd_index);
4573 auto size = wr_index - rd_index;
4574 if (PERFETTO_LIKELY(size < kCapacity / 2))
4575 return At(wr_index);
4576
4577 // Slow-path: Enqueue the read task and handle overruns.
4578 bool expected = false;
4579 if (RingBuffer::read_task_queued_.compare_exchange_strong(expected, true)) {
4580 Delegate* dg = Delegate::GetInstance();
4581 if (dg->task_runner) {
4582 dg->task_runner->PostTask([] {
4583 // Meta-tracing might have been disabled in the meantime.
4584 auto read_task = Delegate::GetInstance()->read_task;
4585 if (read_task)
4586 read_task();
4587 RingBuffer::read_task_queued_ = false;
4588 });
4589 }
4590 }
4591
4592 if (PERFETTO_LIKELY(size < kCapacity))
4593 return At(wr_index);
4594
4595 has_overruns_.store(true, std::memory_order_release);
4596 wr_index_.fetch_sub(1, std::memory_order_acq_rel);
4597
4598 // In the case of overflows, threads will race writing on the same memory
4599 // location and TSan will rightly complain. This is fine though because nobody
4600 // will read the bankruptcy record and it's designed to contain garbage.
4601 PERFETTO_ANNOTATE_BENIGN_RACE_SIZED(&bankruptcy_record_, sizeof(Record),
4602 "nothing reads bankruptcy_record_")
4603 return &bankruptcy_record_;
4604 }
4605
4606 // static
IsOnValidTaskRunner()4607 bool RingBuffer::IsOnValidTaskRunner() {
4608 auto* task_runner = Delegate::GetInstance()->task_runner;
4609 return task_runner && task_runner->RunsTasksOnCurrentThread();
4610 }
4611
4612 } // namespace metatrace
4613 } // namespace perfetto
4614 // gen_amalgamated begin source: src/base/paged_memory.cc
4615 // gen_amalgamated begin header: include/perfetto/ext/base/paged_memory.h
4616 // gen_amalgamated begin header: include/perfetto/ext/base/container_annotations.h
4617 /*
4618 * Copyright (C) 2018 The Android Open Source Project
4619 *
4620 * Licensed under the Apache License, Version 2.0 (the "License");
4621 * you may not use this file except in compliance with the License.
4622 * You may obtain a copy of the License at
4623 *
4624 * http://www.apache.org/licenses/LICENSE-2.0
4625 *
4626 * Unless required by applicable law or agreed to in writing, software
4627 * distributed under the License is distributed on an "AS IS" BASIS,
4628 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4629 * See the License for the specific language governing permissions and
4630 * limitations under the License.
4631 */
4632
4633 #ifndef INCLUDE_PERFETTO_EXT_BASE_CONTAINER_ANNOTATIONS_H_
4634 #define INCLUDE_PERFETTO_EXT_BASE_CONTAINER_ANNOTATIONS_H_
4635
4636 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
4637
4638 // Windows ASAN doesn't currently support these annotations.
4639 #if defined(ADDRESS_SANITIZER) && !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) && \
4640 !defined(ADDRESS_SANITIZER_WITHOUT_INSTRUMENTATION)
4641
4642 #define ANNOTATE_NEW_BUFFER(buffer, capacity, new_size) \
4643 if (buffer) { \
4644 __sanitizer_annotate_contiguous_container(buffer, (buffer) + (capacity), \
4645 (buffer) + (capacity), \
4646 (buffer) + (new_size)); \
4647 }
4648 #define ANNOTATE_DELETE_BUFFER(buffer, capacity, old_size) \
4649 if (buffer) { \
4650 __sanitizer_annotate_contiguous_container(buffer, (buffer) + (capacity), \
4651 (buffer) + (old_size), \
4652 (buffer) + (capacity)); \
4653 }
4654 #define ANNOTATE_CHANGE_SIZE(buffer, capacity, old_size, new_size) \
4655 if (buffer) { \
4656 __sanitizer_annotate_contiguous_container(buffer, (buffer) + (capacity), \
4657 (buffer) + (old_size), \
4658 (buffer) + (new_size)); \
4659 }
4660 #define ANNOTATE_CHANGE_CAPACITY(buffer, old_capacity, buffer_size, \
4661 new_capacity) \
4662 ANNOTATE_DELETE_BUFFER(buffer, old_capacity, buffer_size); \
4663 ANNOTATE_NEW_BUFFER(buffer, new_capacity, buffer_size);
4664 // Annotations require buffers to begin on an 8-byte boundary.
4665 #else // defined(ADDRESS_SANITIZER)
4666 #define ANNOTATE_NEW_BUFFER(buffer, capacity, new_size)
4667 #define ANNOTATE_DELETE_BUFFER(buffer, capacity, old_size)
4668 #define ANNOTATE_CHANGE_SIZE(buffer, capacity, old_size, new_size)
4669 #define ANNOTATE_CHANGE_CAPACITY(buffer, old_capacity, buffer_size, \
4670 new_capacity)
4671 #endif // defined(ADDRESS_SANITIZER)
4672
4673 #endif // INCLUDE_PERFETTO_EXT_BASE_CONTAINER_ANNOTATIONS_H_
4674 /*
4675 * Copyright (C) 2017 The Android Open Source Project
4676 *
4677 * Licensed under the Apache License, Version 2.0 (the "License");
4678 * you may not use this file except in compliance with the License.
4679 * You may obtain a copy of the License at
4680 *
4681 * http://www.apache.org/licenses/LICENSE-2.0
4682 *
4683 * Unless required by applicable law or agreed to in writing, software
4684 * distributed under the License is distributed on an "AS IS" BASIS,
4685 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4686 * See the License for the specific language governing permissions and
4687 * limitations under the License.
4688 */
4689
4690 #ifndef INCLUDE_PERFETTO_EXT_BASE_PAGED_MEMORY_H_
4691 #define INCLUDE_PERFETTO_EXT_BASE_PAGED_MEMORY_H_
4692
4693 #include <memory>
4694
4695 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
4696 // gen_amalgamated expanded: #include "perfetto/ext/base/container_annotations.h"
4697
4698 // We need to track the committed size on windows and when ASAN is enabled.
4699 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) || defined(ADDRESS_SANITIZER)
4700 #define TRACK_COMMITTED_SIZE() 1
4701 #else
4702 #define TRACK_COMMITTED_SIZE() 0
4703 #endif
4704
4705 namespace perfetto {
4706 namespace base {
4707
4708 class PagedMemory {
4709 public:
4710 // Initializes an invalid PagedMemory pointing to nullptr.
4711 PagedMemory();
4712
4713 ~PagedMemory();
4714
4715 PagedMemory(PagedMemory&& other) noexcept;
4716 PagedMemory& operator=(PagedMemory&& other);
4717
4718 enum AllocationFlags {
4719 // By default, Allocate() crashes if the underlying mmap fails (e.g., if out
4720 // of virtual address space). When this flag is provided, an invalid
4721 // PagedMemory pointing to nullptr is returned in this case instead.
4722 kMayFail = 1 << 0,
4723
4724 // By default, Allocate() commits the allocated memory immediately. When
4725 // this flag is provided, the memory virtual address space may only be
4726 // reserved and the user should call EnsureCommitted() before writing to
4727 // memory addresses.
4728 kDontCommit = 1 << 1,
4729 };
4730
4731 // Allocates |size| bytes using mmap(MAP_ANONYMOUS). The returned memory is
4732 // guaranteed to be page-aligned and guaranteed to be zeroed.
4733 // For |flags|, see the AllocationFlags enum above.
4734 static PagedMemory Allocate(size_t size, int flags = 0);
4735
4736 // Hint to the OS that the memory range is not needed and can be discarded.
4737 // The memory remains accessible and its contents may be retained, or they
4738 // may be zeroed. This function may be a NOP on some platforms. Returns true
4739 // if implemented.
4740 bool AdviseDontNeed(void* p, size_t size);
4741
4742 // Ensures that at least the first |committed_size| bytes of the allocated
4743 // memory region are committed. The implementation may commit memory in larger
4744 // chunks above |committed_size|. Crashes if the memory couldn't be committed.
4745 #if TRACK_COMMITTED_SIZE()
4746 void EnsureCommitted(size_t committed_size);
4747 #else // TRACK_COMMITTED_SIZE()
EnsureCommitted(size_t)4748 void EnsureCommitted(size_t /*committed_size*/) {}
4749 #endif // TRACK_COMMITTED_SIZE()
4750
Get() const4751 inline void* Get() const noexcept { return p_; }
IsValid() const4752 inline bool IsValid() const noexcept { return !!p_; }
size() const4753 inline size_t size() const noexcept { return size_; }
4754
4755 private:
4756 PagedMemory(char* p, size_t size);
4757
4758 PagedMemory(const PagedMemory&) = delete;
4759 // Defaulted for implementation of move constructor + assignment.
4760 PagedMemory& operator=(const PagedMemory&) = default;
4761
4762 char* p_ = nullptr;
4763
4764 // The size originally passed to Allocate(). The actual virtual memory
4765 // reservation will be larger due to: (i) guard pages; (ii) rounding up to
4766 // the system page size.
4767 size_t size_ = 0;
4768
4769 #if TRACK_COMMITTED_SIZE()
4770 size_t committed_size_ = 0u;
4771 #endif // TRACK_COMMITTED_SIZE()
4772 };
4773
4774 } // namespace base
4775 } // namespace perfetto
4776
4777 #endif // INCLUDE_PERFETTO_EXT_BASE_PAGED_MEMORY_H_
4778 /*
4779 * Copyright (C) 2017 The Android Open Source Project
4780 *
4781 * Licensed under the Apache License, Version 2.0 (the "License");
4782 * you may not use this file except in compliance with the License.
4783 * You may obtain a copy of the License at
4784 *
4785 * http://www.apache.org/licenses/LICENSE-2.0
4786 *
4787 * Unless required by applicable law or agreed to in writing, software
4788 * distributed under the License is distributed on an "AS IS" BASIS,
4789 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4790 * See the License for the specific language governing permissions and
4791 * limitations under the License.
4792 */
4793
4794 // gen_amalgamated expanded: #include "perfetto/ext/base/paged_memory.h"
4795
4796 #include <algorithm>
4797 #include <cmath>
4798
4799 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
4800 #include <Windows.h>
4801 #else // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
4802 #include <sys/mman.h>
4803 #endif // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
4804
4805 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
4806 // gen_amalgamated expanded: #include "perfetto/ext/base/container_annotations.h"
4807 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
4808
4809 namespace perfetto {
4810 namespace base {
4811
4812 namespace {
4813
4814 #if TRACK_COMMITTED_SIZE()
4815 constexpr size_t kCommitChunkSize = 4 * 1024 * 1024; // 4MB
4816 #endif
4817
RoundUpToSysPageSize(size_t req_size)4818 size_t RoundUpToSysPageSize(size_t req_size) {
4819 const size_t page_size = GetSysPageSize();
4820 return (req_size + page_size - 1) & ~(page_size - 1);
4821 }
4822
GuardSize()4823 size_t GuardSize() {
4824 return GetSysPageSize();
4825 }
4826
4827 } // namespace
4828
4829 // static
Allocate(size_t req_size,int flags)4830 PagedMemory PagedMemory::Allocate(size_t req_size, int flags) {
4831 size_t rounded_up_size = RoundUpToSysPageSize(req_size);
4832 PERFETTO_CHECK(rounded_up_size >= req_size);
4833 size_t outer_size = rounded_up_size + GuardSize() * 2;
4834 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
4835 void* ptr = VirtualAlloc(nullptr, outer_size, MEM_RESERVE, PAGE_NOACCESS);
4836 if (!ptr && (flags & kMayFail))
4837 return PagedMemory();
4838 PERFETTO_CHECK(ptr);
4839 char* usable_region = reinterpret_cast<char*>(ptr) + GuardSize();
4840 #else // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
4841 void* ptr = mmap(nullptr, outer_size, PROT_READ | PROT_WRITE,
4842 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
4843 if (ptr == MAP_FAILED && (flags & kMayFail))
4844 return PagedMemory();
4845 PERFETTO_CHECK(ptr && ptr != MAP_FAILED);
4846 char* usable_region = reinterpret_cast<char*>(ptr) + GuardSize();
4847 int res = mprotect(ptr, GuardSize(), PROT_NONE);
4848 res |= mprotect(usable_region + rounded_up_size, GuardSize(), PROT_NONE);
4849 PERFETTO_CHECK(res == 0);
4850 #endif // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
4851
4852 auto memory = PagedMemory(usable_region, req_size);
4853 #if TRACK_COMMITTED_SIZE()
4854 size_t initial_commit = req_size;
4855 if (flags & kDontCommit)
4856 initial_commit = std::min(initial_commit, kCommitChunkSize);
4857 memory.EnsureCommitted(initial_commit);
4858 #endif // TRACK_COMMITTED_SIZE()
4859 return memory;
4860 }
4861
PagedMemory()4862 PagedMemory::PagedMemory() {}
4863
4864 // clang-format off
PagedMemory(char * p,size_t size)4865 PagedMemory::PagedMemory(char* p, size_t size) : p_(p), size_(size) {
4866 ANNOTATE_NEW_BUFFER(p_, size_, committed_size_)
4867 }
4868
PagedMemory(PagedMemory && other)4869 PagedMemory::PagedMemory(PagedMemory&& other) noexcept {
4870 *this = other;
4871 other.p_ = nullptr;
4872 }
4873 // clang-format on
4874
operator =(PagedMemory && other)4875 PagedMemory& PagedMemory::operator=(PagedMemory&& other) {
4876 this->~PagedMemory();
4877 new (this) PagedMemory(std::move(other));
4878 return *this;
4879 }
4880
~PagedMemory()4881 PagedMemory::~PagedMemory() {
4882 if (!p_)
4883 return;
4884 PERFETTO_CHECK(size_);
4885 char* start = p_ - GuardSize();
4886 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
4887 BOOL res = VirtualFree(start, 0, MEM_RELEASE);
4888 PERFETTO_CHECK(res != 0);
4889 #else // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
4890 const size_t outer_size = RoundUpToSysPageSize(size_) + GuardSize() * 2;
4891 int res = munmap(start, outer_size);
4892 PERFETTO_CHECK(res == 0);
4893 #endif // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
4894 ANNOTATE_DELETE_BUFFER(p_, size_, committed_size_)
4895 }
4896
AdviseDontNeed(void * p,size_t size)4897 bool PagedMemory::AdviseDontNeed(void* p, size_t size) {
4898 PERFETTO_DCHECK(p_);
4899 PERFETTO_DCHECK(p >= p_);
4900 PERFETTO_DCHECK(static_cast<char*>(p) + size <= p_ + size_);
4901 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) || PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
4902 // Discarding pages on Windows has more CPU cost than is justified for the
4903 // possible memory savings.
4904 return false;
4905 #else // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) ||
4906 // PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
4907 // http://man7.org/linux/man-pages/man2/madvise.2.html
4908 int res = madvise(p, size, MADV_DONTNEED);
4909 PERFETTO_DCHECK(res == 0);
4910 return true;
4911 #endif // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) ||
4912 // PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
4913 }
4914
4915 #if TRACK_COMMITTED_SIZE()
EnsureCommitted(size_t committed_size)4916 void PagedMemory::EnsureCommitted(size_t committed_size) {
4917 PERFETTO_DCHECK(committed_size > 0u);
4918 PERFETTO_DCHECK(committed_size <= size_);
4919 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
4920 if (committed_size_ >= committed_size)
4921 return;
4922 // Rounding up.
4923 size_t delta = committed_size - committed_size_;
4924 size_t num_additional_chunks =
4925 (delta + kCommitChunkSize - 1) / kCommitChunkSize;
4926 PERFETTO_DCHECK(num_additional_chunks * kCommitChunkSize >= delta);
4927 // Don't commit more than the total size.
4928 size_t commit_size = std::min(num_additional_chunks * kCommitChunkSize,
4929 size_ - committed_size_);
4930 void* res = VirtualAlloc(p_ + committed_size_, commit_size, MEM_COMMIT,
4931 PAGE_READWRITE);
4932 PERFETTO_CHECK(res);
4933 ANNOTATE_CHANGE_SIZE(p_, size_, committed_size_,
4934 committed_size_ + commit_size)
4935 committed_size_ += commit_size;
4936 #else // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
4937 // mmap commits automatically as needed, so we only track here for ASAN.
4938 committed_size = std::max(committed_size_, committed_size);
4939 ANNOTATE_CHANGE_SIZE(p_, size_, committed_size_, committed_size)
4940 committed_size_ = committed_size;
4941 #endif // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
4942 }
4943 #endif // TRACK_COMMITTED_SIZE()
4944
4945 } // namespace base
4946 } // namespace perfetto
4947 // gen_amalgamated begin source: src/base/periodic_task.cc
4948 // gen_amalgamated begin header: include/perfetto/ext/base/periodic_task.h
4949 // gen_amalgamated begin header: include/perfetto/ext/base/thread_checker.h
4950 /*
4951 * Copyright (C) 2017 The Android Open Source Project
4952 *
4953 * Licensed under the Apache License, Version 2.0 (the "License");
4954 * you may not use this file except in compliance with the License.
4955 * You may obtain a copy of the License at
4956 *
4957 * http://www.apache.org/licenses/LICENSE-2.0
4958 *
4959 * Unless required by applicable law or agreed to in writing, software
4960 * distributed under the License is distributed on an "AS IS" BASIS,
4961 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4962 * See the License for the specific language governing permissions and
4963 * limitations under the License.
4964 */
4965
4966 #ifndef INCLUDE_PERFETTO_EXT_BASE_THREAD_CHECKER_H_
4967 #define INCLUDE_PERFETTO_EXT_BASE_THREAD_CHECKER_H_
4968
4969 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
4970
4971 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
4972 #include <pthread.h>
4973 #endif
4974 #include <atomic>
4975
4976 // gen_amalgamated expanded: #include "perfetto/base/export.h"
4977 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
4978 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
4979
4980 namespace perfetto {
4981 namespace base {
4982
4983 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
4984 using ThreadID = unsigned long;
4985 #else
4986 using ThreadID = pthread_t;
4987 #endif
4988
4989 class PERFETTO_EXPORT ThreadChecker {
4990 public:
4991 ThreadChecker();
4992 ~ThreadChecker();
4993 ThreadChecker(const ThreadChecker&);
4994 ThreadChecker& operator=(const ThreadChecker&);
4995 bool CalledOnValidThread() const PERFETTO_WARN_UNUSED_RESULT;
4996 void DetachFromThread();
4997
4998 private:
4999 mutable std::atomic<ThreadID> thread_id_;
5000 };
5001
5002 #if PERFETTO_DCHECK_IS_ON() && !PERFETTO_BUILDFLAG(PERFETTO_CHROMIUM_BUILD)
5003 // TODO(primiano) Use Chromium's thread checker in Chromium.
5004 #define PERFETTO_THREAD_CHECKER(name) base::ThreadChecker name;
5005 #define PERFETTO_DCHECK_THREAD(name) \
5006 PERFETTO_DCHECK((name).CalledOnValidThread())
5007 #define PERFETTO_DETACH_FROM_THREAD(name) (name).DetachFromThread()
5008 #else
5009 #define PERFETTO_THREAD_CHECKER(name)
5010 #define PERFETTO_DCHECK_THREAD(name)
5011 #define PERFETTO_DETACH_FROM_THREAD(name)
5012 #endif // PERFETTO_DCHECK_IS_ON()
5013
5014 } // namespace base
5015 } // namespace perfetto
5016
5017 #endif // INCLUDE_PERFETTO_EXT_BASE_THREAD_CHECKER_H_
5018 // gen_amalgamated begin header: include/perfetto/ext/base/weak_ptr.h
5019 /*
5020 * Copyright (C) 2017 The Android Open Source Project
5021 *
5022 * Licensed under the Apache License, Version 2.0 (the "License");
5023 * you may not use this file except in compliance with the License.
5024 * You may obtain a copy of the License at
5025 *
5026 * http://www.apache.org/licenses/LICENSE-2.0
5027 *
5028 * Unless required by applicable law or agreed to in writing, software
5029 * distributed under the License is distributed on an "AS IS" BASIS,
5030 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5031 * See the License for the specific language governing permissions and
5032 * limitations under the License.
5033 */
5034
5035 #ifndef INCLUDE_PERFETTO_EXT_BASE_WEAK_PTR_H_
5036 #define INCLUDE_PERFETTO_EXT_BASE_WEAK_PTR_H_
5037
5038 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_checker.h"
5039
5040 #include <memory>
5041
5042 namespace perfetto {
5043 namespace base {
5044
5045 // A simple WeakPtr for single-threaded cases.
5046 // Generally keep the WeakPtrFactory as last fields in classes: it makes the
5047 // WeakPtr(s) invalidate as first thing in the class dtor.
5048 // Usage:
5049 // class MyClass {
5050 // MyClass() : weak_factory_(this) {}
5051 // WeakPtr<MyClass> GetWeakPtr() { return weak_factory_.GetWeakPtr(); }
5052 //
5053 // private:
5054 // WeakPtrFactory<MyClass> weak_factory_;
5055 // }
5056 //
5057 // int main() {
5058 // std::unique_ptr<MyClass> foo(new MyClass);
5059 // auto wptr = foo.GetWeakPtr();
5060 // ASSERT_TRUE(wptr);
5061 // ASSERT_EQ(foo.get(), wptr->get());
5062 // foo.reset();
5063 // ASSERT_FALSE(wptr);
5064 // ASSERT_EQ(nullptr, wptr->get());
5065 // }
5066
5067 template <typename T>
5068 class WeakPtrFactory; // Forward declaration, defined below.
5069
5070 template <typename T>
5071 class WeakPtr {
5072 public:
WeakPtr()5073 WeakPtr() {}
5074 WeakPtr(const WeakPtr&) = default;
5075 WeakPtr& operator=(const WeakPtr&) = default;
5076 WeakPtr(WeakPtr&&) = default;
5077 WeakPtr& operator=(WeakPtr&&) = default;
5078
get() const5079 T* get() const {
5080 PERFETTO_DCHECK_THREAD(thread_checker);
5081 return handle_ ? *handle_.get() : nullptr;
5082 }
operator ->() const5083 T* operator->() const { return get(); }
operator *() const5084 T& operator*() const { return *get(); }
5085
operator bool() const5086 explicit operator bool() const { return !!get(); }
5087
5088 private:
5089 friend class WeakPtrFactory<T>;
WeakPtr(const std::shared_ptr<T * > & handle)5090 explicit WeakPtr(const std::shared_ptr<T*>& handle) : handle_(handle) {}
5091
5092 std::shared_ptr<T*> handle_;
5093 PERFETTO_THREAD_CHECKER(thread_checker)
5094 };
5095
5096 template <typename T>
5097 class WeakPtrFactory {
5098 public:
WeakPtrFactory(T * owner)5099 explicit WeakPtrFactory(T* owner)
5100 : weak_ptr_(std::shared_ptr<T*>(new T* {owner})) {
5101 PERFETTO_DCHECK_THREAD(thread_checker);
5102 }
5103
~WeakPtrFactory()5104 ~WeakPtrFactory() {
5105 PERFETTO_DCHECK_THREAD(thread_checker);
5106 *(weak_ptr_.handle_.get()) = nullptr;
5107 }
5108
5109 // Can be safely called on any thread, since it simply copies |weak_ptr_|.
5110 // Note that any accesses to the returned pointer need to be made on the
5111 // thread that created/reset the factory.
GetWeakPtr() const5112 WeakPtr<T> GetWeakPtr() const { return weak_ptr_; }
5113
5114 // Reset the factory to a new owner & thread. May only be called before any
5115 // weak pointers were passed out. Future weak pointers will be valid on the
5116 // calling thread.
Reset(T * owner)5117 void Reset(T* owner) {
5118 // Reset thread checker to current thread.
5119 PERFETTO_DETACH_FROM_THREAD(thread_checker);
5120 PERFETTO_DCHECK_THREAD(thread_checker);
5121
5122 // We should not have passed out any weak pointers yet at this point.
5123 PERFETTO_DCHECK(weak_ptr_.handle_.use_count() == 1);
5124
5125 weak_ptr_ = WeakPtr<T>(std::shared_ptr<T*>(new T* {owner}));
5126 }
5127
5128 private:
5129 WeakPtrFactory(const WeakPtrFactory&) = delete;
5130 WeakPtrFactory& operator=(const WeakPtrFactory&) = delete;
5131
5132 WeakPtr<T> weak_ptr_;
5133 PERFETTO_THREAD_CHECKER(thread_checker)
5134 };
5135
5136 } // namespace base
5137 } // namespace perfetto
5138
5139 #endif // INCLUDE_PERFETTO_EXT_BASE_WEAK_PTR_H_
5140 /*
5141 * Copyright (C) 2021 The Android Open Source Project
5142 *
5143 * Licensed under the Apache License, Version 2.0 (the "License");
5144 * you may not use this file except in compliance with the License.
5145 * You may obtain a copy of the License at
5146 *
5147 * http://www.apache.org/licenses/LICENSE-2.0
5148 *
5149 * Unless required by applicable law or agreed to in writing, software
5150 * distributed under the License is distributed on an "AS IS" BASIS,
5151 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5152 * See the License for the specific language governing permissions and
5153 * limitations under the License.
5154 */
5155
5156 #ifndef INCLUDE_PERFETTO_EXT_BASE_PERIODIC_TASK_H_
5157 #define INCLUDE_PERFETTO_EXT_BASE_PERIODIC_TASK_H_
5158
5159 #include <functional>
5160
5161 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
5162 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_checker.h"
5163 // gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
5164
5165 namespace perfetto {
5166 namespace base {
5167
5168 class TaskRunner;
5169
5170 // A periodic task utility class. It wraps the logic necessary to do periodic
5171 // tasks using a TaskRunner, taking care of subtleties like ensuring that
5172 // outstanding tasks are cancelled after reset/dtor.
5173 // Tasks are aligned on wall time, this is to ensure that when using multiple
5174 // periodic tasks, they happen at the same time, minimizing wakeups.
5175 // On Linux/Android it also supports suspend-aware mode (via timerfd). On other
5176 // operating systems it falls back to PostDelayedTask, which is not
5177 // suspend-aware.
5178 // TODO(primiano): this should probably become a periodic timer scheduler, so we
5179 // can use one FD for everything rather than one FD per task. For now we take
5180 // the hit of a FD-per-task to keep this low-risk.
5181 class PeriodicTask {
5182 public:
5183 explicit PeriodicTask(base::TaskRunner*);
5184 ~PeriodicTask(); // Calls Reset().
5185
5186 struct Args {
5187 uint32_t period_ms = 0;
5188 std::function<void()> task = nullptr;
5189 bool start_first_task_immediately = false;
5190 bool use_suspend_aware_timer = false;
5191 };
5192
5193 void Start(Args);
5194
5195 // Safe to be called multiple times, even without calling Start():
5196 void Reset();
5197
5198 // No copy or move. WeakPtr-wrapped pointers to |this| are posted on the
5199 // task runner, this class is not easily movable.
5200 PeriodicTask(const PeriodicTask&) = delete;
5201 PeriodicTask& operator=(const PeriodicTask&) = delete;
5202 PeriodicTask(PeriodicTask&&) = delete;
5203 PeriodicTask& operator=(PeriodicTask&&) = delete;
5204
timer_fd_for_testing()5205 base::PlatformHandle timer_fd_for_testing() { return *timer_fd_; }
5206
5207 private:
5208 static void RunTaskAndPostNext(base::WeakPtr<PeriodicTask>,
5209 uint32_t generation);
5210 void PostNextTask();
5211 void ResetTimerFd();
5212
5213 base::TaskRunner* const task_runner_;
5214 Args args_;
5215 uint32_t generation_ = 0;
5216 base::ScopedPlatformHandle timer_fd_;
5217
5218 PERFETTO_THREAD_CHECKER(thread_checker_)
5219 base::WeakPtrFactory<PeriodicTask> weak_ptr_factory_; // Keep last.
5220 };
5221
5222 } // namespace base
5223 } // namespace perfetto
5224
5225 #endif // INCLUDE_PERFETTO_EXT_BASE_PERIODIC_TASK_H_
5226 /*
5227 * Copyright (C) 2021 The Android Open Source Project
5228 *
5229 * Licensed under the Apache License, Version 2.0 (the "License");
5230 * you may not use this file except in compliance with the License.
5231 * You may obtain a copy of the License at
5232 *
5233 * http://www.apache.org/licenses/LICENSE-2.0
5234 *
5235 * Unless required by applicable law or agreed to in writing, software
5236 * distributed under the License is distributed on an "AS IS" BASIS,
5237 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5238 * See the License for the specific language governing permissions and
5239 * limitations under the License.
5240 */
5241
5242 // gen_amalgamated expanded: #include "perfetto/ext/base/periodic_task.h"
5243
5244 #include <limits>
5245
5246 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
5247 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
5248 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
5249 // gen_amalgamated expanded: #include "perfetto/base/time.h"
5250 // gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
5251
5252 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
5253 (PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && __ANDROID_API__ >= 19)
5254 #include <sys/timerfd.h>
5255 #endif
5256
5257 namespace perfetto {
5258 namespace base {
5259
5260 namespace {
CreateTimerFd(uint32_t period_ms)5261 base::ScopedPlatformHandle CreateTimerFd(uint32_t period_ms) {
5262 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
5263 (PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && __ANDROID_API__ >= 19)
5264 base::ScopedPlatformHandle tfd(
5265 timerfd_create(CLOCK_BOOTTIME, TFD_CLOEXEC | TFD_NONBLOCK));
5266 // The initial phase, aligned on wall clock.
5267 uint32_t phase_ms =
5268 period_ms -
5269 static_cast<uint32_t>(base::GetBootTimeNs().count() % period_ms);
5270 struct itimerspec its {};
5271 // The "1 +" is to make sure that we never pass a zero it_value in the
5272 // unlikely case of phase_ms being 0. That would cause the timer to be
5273 // considered disarmed by timerfd_settime.
5274 its.it_value.tv_sec = static_cast<time_t>(phase_ms / 1000u);
5275 its.it_value.tv_nsec = 1 + static_cast<long>((phase_ms % 1000u) * 1000000u);
5276 its.it_interval.tv_sec = static_cast<time_t>(period_ms / 1000u);
5277 its.it_interval.tv_nsec = static_cast<long>((period_ms % 1000u) * 1000000u);
5278 if (timerfd_settime(*tfd, 0, &its, nullptr) < 0)
5279 return base::ScopedPlatformHandle();
5280 return tfd;
5281 #else
5282 base::ignore_result(period_ms);
5283 return base::ScopedPlatformHandle();
5284 #endif
5285 }
5286 } // namespace
5287
PeriodicTask(base::TaskRunner * task_runner)5288 PeriodicTask::PeriodicTask(base::TaskRunner* task_runner)
5289 : task_runner_(task_runner), weak_ptr_factory_(this) {}
5290
~PeriodicTask()5291 PeriodicTask::~PeriodicTask() {
5292 Reset();
5293 }
5294
Start(Args args)5295 void PeriodicTask::Start(Args args) {
5296 PERFETTO_DCHECK_THREAD(thread_checker_);
5297 Reset();
5298 if (args.period_ms == 0 || !args.task) {
5299 PERFETTO_DCHECK(args.period_ms > 0);
5300 PERFETTO_DCHECK(args.task);
5301 return;
5302 }
5303 args_ = std::move(args);
5304 if (args_.use_suspend_aware_timer) {
5305 timer_fd_ = CreateTimerFd(args_.period_ms);
5306 if (timer_fd_) {
5307 auto weak_this = weak_ptr_factory_.GetWeakPtr();
5308 task_runner_->AddFileDescriptorWatch(
5309 *timer_fd_,
5310 std::bind(PeriodicTask::RunTaskAndPostNext, weak_this, generation_));
5311 } else {
5312 PERFETTO_DPLOG("timerfd not supported, falling back on PostDelayedTask");
5313 }
5314 } // if (use_suspend_aware_timer).
5315
5316 if (!timer_fd_)
5317 PostNextTask();
5318
5319 if (args_.start_first_task_immediately)
5320 args_.task();
5321 }
5322
PostNextTask()5323 void PeriodicTask::PostNextTask() {
5324 PERFETTO_DCHECK_THREAD(thread_checker_);
5325 PERFETTO_DCHECK(args_.period_ms > 0);
5326 PERFETTO_DCHECK(!timer_fd_);
5327 uint32_t delay_ms =
5328 args_.period_ms -
5329 static_cast<uint32_t>(base::GetWallTimeMs().count() % args_.period_ms);
5330 auto weak_this = weak_ptr_factory_.GetWeakPtr();
5331 task_runner_->PostDelayedTask(
5332 std::bind(PeriodicTask::RunTaskAndPostNext, weak_this, generation_),
5333 delay_ms);
5334 }
5335
5336 // static
5337 // This function can be called in two ways (both from the TaskRunner):
5338 // 1. When using a timerfd, this task is registered as a FD watch.
5339 // 2. When using PostDelayedTask, this is the task posted on the TaskRunner.
RunTaskAndPostNext(base::WeakPtr<PeriodicTask> thiz,uint32_t generation)5340 void PeriodicTask::RunTaskAndPostNext(base::WeakPtr<PeriodicTask> thiz,
5341 uint32_t generation) {
5342 if (!thiz || !thiz->args_.task || generation != thiz->generation_)
5343 return; // Destroyed or Reset() in the meanwhile.
5344 PERFETTO_DCHECK_THREAD(thiz->thread_checker_);
5345 if (thiz->timer_fd_) {
5346 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
5347 PERFETTO_FATAL("timerfd for periodic tasks unsupported on Windows");
5348 #else
5349 // If we are using a timerfd there is no need to repeatedly call
5350 // PostDelayedTask(). The kernel will wakeup the timer fd periodically. We
5351 // just need to read() it.
5352 uint64_t ignored = 0;
5353 errno = 0;
5354 auto rsize = base::Read(*thiz->timer_fd_, &ignored, sizeof(&ignored));
5355 if (rsize != sizeof(uint64_t)) {
5356 if (errno == EAGAIN)
5357 return; // A spurious wakeup. Rare, but can happen, just ignore.
5358 PERFETTO_PLOG("read(timerfd) failed, falling back on PostDelayedTask");
5359 thiz->ResetTimerFd();
5360 }
5361 #endif
5362 }
5363 // The repetition of the if() is to deal with the ResetTimerFd() case above.
5364 if (!thiz->timer_fd_) {
5365 thiz->PostNextTask();
5366 }
5367 // Create a copy of the task in the unlikely event that the task ends up
5368 // up destroying the PeriodicTask object or calling Reset() on it. That would
5369 // cause a reset of the args_.task itself, which would invalidate the task
5370 // bind state while we are invoking it.
5371 auto task = thiz->args_.task;
5372 task();
5373 }
5374
Reset()5375 void PeriodicTask::Reset() {
5376 PERFETTO_DCHECK_THREAD(thread_checker_);
5377 ++generation_;
5378 args_ = Args();
5379 PERFETTO_DCHECK(!args_.task);
5380 ResetTimerFd();
5381 }
5382
ResetTimerFd()5383 void PeriodicTask::ResetTimerFd() {
5384 if (!timer_fd_)
5385 return;
5386 task_runner_->RemoveFileDescriptorWatch(*timer_fd_);
5387 timer_fd_.reset();
5388 }
5389
5390 } // namespace base
5391 } // namespace perfetto
5392 // gen_amalgamated begin source: src/base/pipe.cc
5393 /*
5394 * Copyright (C) 2018 The Android Open Source Project
5395 *
5396 * Licensed under the Apache License, Version 2.0 (the "License");
5397 * you may not use this file except in compliance with the License.
5398 * You may obtain a copy of the License at
5399 *
5400 * http://www.apache.org/licenses/LICENSE-2.0
5401 *
5402 * Unless required by applicable law or agreed to in writing, software
5403 * distributed under the License is distributed on an "AS IS" BASIS,
5404 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5405 * See the License for the specific language governing permissions and
5406 * limitations under the License.
5407 */
5408
5409 // gen_amalgamated expanded: #include "perfetto/ext/base/pipe.h"
5410
5411 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
5412
5413 #include <fcntl.h> // For O_BINARY (Windows) and F_SETxx (UNIX)
5414
5415 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
5416 #include <Windows.h>
5417 #include <namedpipeapi.h>
5418 #else
5419 #include <sys/types.h>
5420 #include <unistd.h>
5421 #endif
5422
5423 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
5424
5425 namespace perfetto {
5426 namespace base {
5427
5428 Pipe::Pipe() = default;
5429 Pipe::Pipe(Pipe&&) noexcept = default;
5430 Pipe& Pipe::operator=(Pipe&&) = default;
5431
Create(Flags flags)5432 Pipe Pipe::Create(Flags flags) {
5433 PlatformHandle fds[2];
5434 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
5435 PERFETTO_CHECK(::CreatePipe(&fds[0], &fds[1], /*lpPipeAttributes=*/nullptr,
5436 0 /*default size*/));
5437 #else
5438 PERFETTO_CHECK(pipe(fds) == 0);
5439 PERFETTO_CHECK(fcntl(fds[0], F_SETFD, FD_CLOEXEC) == 0);
5440 PERFETTO_CHECK(fcntl(fds[1], F_SETFD, FD_CLOEXEC) == 0);
5441 #endif
5442 Pipe p;
5443 p.rd.reset(fds[0]);
5444 p.wr.reset(fds[1]);
5445
5446 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
5447 if (flags == kBothNonBlock || flags == kRdNonBlock) {
5448 int cur_flags = fcntl(*p.rd, F_GETFL, 0);
5449 PERFETTO_CHECK(cur_flags >= 0);
5450 PERFETTO_CHECK(fcntl(*p.rd, F_SETFL, cur_flags | O_NONBLOCK) == 0);
5451 }
5452
5453 if (flags == kBothNonBlock || flags == kWrNonBlock) {
5454 int cur_flags = fcntl(*p.wr, F_GETFL, 0);
5455 PERFETTO_CHECK(cur_flags >= 0);
5456 PERFETTO_CHECK(fcntl(*p.wr, F_SETFL, cur_flags | O_NONBLOCK) == 0);
5457 }
5458 #else
5459 PERFETTO_CHECK(flags == kBothBlock);
5460 #endif
5461 return p;
5462 }
5463
5464 } // namespace base
5465 } // namespace perfetto
5466 // gen_amalgamated begin source: src/base/status.cc
5467 /*
5468 * Copyright (C) 2020 The Android Open Source Project
5469 *
5470 * Licensed under the Apache License, Version 2.0 (the "License");
5471 * you may not use this file except in compliance with the License.
5472 * You may obtain a copy of the License at
5473 *
5474 * http://www.apache.org/licenses/LICENSE-2.0
5475 *
5476 * Unless required by applicable law or agreed to in writing, software
5477 * distributed under the License is distributed on an "AS IS" BASIS,
5478 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5479 * See the License for the specific language governing permissions and
5480 * limitations under the License.
5481 */
5482
5483 // gen_amalgamated expanded: #include "perfetto/base/status.h"
5484
5485 #include <stdarg.h>
5486
5487 namespace perfetto {
5488 namespace base {
5489
ErrStatus(const char * format,...)5490 Status ErrStatus(const char* format, ...) {
5491 char buffer[1024];
5492 va_list ap;
5493 va_start(ap, format);
5494 vsnprintf(buffer, sizeof(buffer), format, ap);
5495 va_end(ap);
5496 Status status(buffer);
5497 return status;
5498 }
5499
5500 } // namespace base
5501 } // namespace perfetto
5502 // gen_amalgamated begin source: src/base/string_splitter.cc
5503 // gen_amalgamated begin header: include/perfetto/ext/base/string_splitter.h
5504 /*
5505 * Copyright (C) 2018 The Android Open Source Project
5506 *
5507 * Licensed under the Apache License, Version 2.0 (the "License");
5508 * you may not use this file except in compliance with the License.
5509 * You may obtain a copy of the License at
5510 *
5511 * http://www.apache.org/licenses/LICENSE-2.0
5512 *
5513 * Unless required by applicable law or agreed to in writing, software
5514 * distributed under the License is distributed on an "AS IS" BASIS,
5515 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5516 * See the License for the specific language governing permissions and
5517 * limitations under the License.
5518 */
5519
5520 #ifndef INCLUDE_PERFETTO_EXT_BASE_STRING_SPLITTER_H_
5521 #define INCLUDE_PERFETTO_EXT_BASE_STRING_SPLITTER_H_
5522
5523 #include <string>
5524
5525 namespace perfetto {
5526 namespace base {
5527
5528 // C++ version of strtok(). Splits a string without making copies or any heap
5529 // allocations. Destructs the original string passed in input.
5530 // Supports the special case of using \0 as a delimiter.
5531 // The token returned in output are valid as long as the input string is valid.
5532 class StringSplitter {
5533 public:
5534 // Can take ownership of the string if passed via std::move(), e.g.:
5535 // StringSplitter(std::move(str), '\n');
5536 StringSplitter(std::string, char delimiter);
5537
5538 // Splits a C-string. The input string will be forcefully null-terminated (so
5539 // str[size - 1] should be == '\0' or the last char will be truncated).
5540 StringSplitter(char* str, size_t size, char delimiter);
5541
5542 // Splits the current token from an outer StringSplitter instance. This is to
5543 // chain splitters as follows:
5544 // for (base::StringSplitter lines(x, '\n'); ss.Next();)
5545 // for (base::StringSplitter words(&lines, ' '); words.Next();)
5546 StringSplitter(StringSplitter*, char delimiter);
5547
5548 // Returns true if a token is found (in which case it will be stored in
5549 // cur_token()), false if no more tokens are found.
5550 bool Next();
5551
5552 // Returns the current token iff last call to Next() returned true. In this
5553 // case it guarantees that the returned string is always null terminated.
5554 // In all other cases (before the 1st call to Next() and after Next() returns
5555 // false) returns nullptr.
cur_token()5556 char* cur_token() { return cur_; }
5557
5558 // Returns the length of the current token (excluding the null terminator).
cur_token_size() const5559 size_t cur_token_size() const { return cur_size_; }
5560
5561 private:
5562 StringSplitter(const StringSplitter&) = delete;
5563 StringSplitter& operator=(const StringSplitter&) = delete;
5564 void Initialize(char* str, size_t size);
5565
5566 std::string str_;
5567 char* cur_;
5568 size_t cur_size_;
5569 char* next_;
5570 char* end_; // STL-style, points one past the last char.
5571 const char delimiter_;
5572 };
5573
5574 } // namespace base
5575 } // namespace perfetto
5576
5577 #endif // INCLUDE_PERFETTO_EXT_BASE_STRING_SPLITTER_H_
5578 /*
5579 * Copyright (C) 2018 The Android Open Source Project
5580 *
5581 * Licensed under the Apache License, Version 2.0 (the "License");
5582 * you may not use this file except in compliance with the License.
5583 * You may obtain a copy of the License at
5584 *
5585 * http://www.apache.org/licenses/LICENSE-2.0
5586 *
5587 * Unless required by applicable law or agreed to in writing, software
5588 * distributed under the License is distributed on an "AS IS" BASIS,
5589 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5590 * See the License for the specific language governing permissions and
5591 * limitations under the License.
5592 */
5593
5594 // gen_amalgamated expanded: #include "perfetto/ext/base/string_splitter.h"
5595
5596 #include <utility>
5597
5598 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
5599
5600 namespace perfetto {
5601 namespace base {
5602
StringSplitter(std::string str,char delimiter)5603 StringSplitter::StringSplitter(std::string str, char delimiter)
5604 : str_(std::move(str)), delimiter_(delimiter) {
5605 // It's legal to access str[str.size()] in C++11 (it always returns \0),
5606 // hence the +1 (which becomes just size() after the -1 in Initialize()).
5607 Initialize(&str_[0], str_.size() + 1);
5608 }
5609
StringSplitter(char * str,size_t size,char delimiter)5610 StringSplitter::StringSplitter(char* str, size_t size, char delimiter)
5611 : delimiter_(delimiter) {
5612 Initialize(str, size);
5613 }
5614
StringSplitter(StringSplitter * outer,char delimiter)5615 StringSplitter::StringSplitter(StringSplitter* outer, char delimiter)
5616 : delimiter_(delimiter) {
5617 Initialize(outer->cur_token(), outer->cur_token_size() + 1);
5618 }
5619
Initialize(char * str,size_t size)5620 void StringSplitter::Initialize(char* str, size_t size) {
5621 PERFETTO_DCHECK(!size || str);
5622 next_ = str;
5623 end_ = str + size;
5624 cur_ = nullptr;
5625 cur_size_ = 0;
5626 if (size)
5627 next_[size - 1] = '\0';
5628 }
5629
Next()5630 bool StringSplitter::Next() {
5631 for (; next_ < end_; next_++) {
5632 if (*next_ == delimiter_)
5633 continue;
5634 cur_ = next_;
5635 for (;; next_++) {
5636 if (*next_ == delimiter_) {
5637 cur_size_ = static_cast<size_t>(next_ - cur_);
5638 *(next_++) = '\0';
5639 break;
5640 }
5641 if (*next_ == '\0') {
5642 cur_size_ = static_cast<size_t>(next_ - cur_);
5643 next_ = end_;
5644 break;
5645 }
5646 }
5647 if (*cur_)
5648 return true;
5649 break;
5650 }
5651 cur_ = nullptr;
5652 cur_size_ = 0;
5653 return false;
5654 }
5655
5656 } // namespace base
5657 } // namespace perfetto
5658 // gen_amalgamated begin source: src/base/string_utils.cc
5659 /*
5660 * Copyright (C) 2018 The Android Open Source Project
5661 *
5662 * Licensed under the Apache License, Version 2.0 (the "License");
5663 * you may not use this file except in compliance with the License.
5664 * You may obtain a copy of the License at
5665 *
5666 * http://www.apache.org/licenses/LICENSE-2.0
5667 *
5668 * Unless required by applicable law or agreed to in writing, software
5669 * distributed under the License is distributed on an "AS IS" BASIS,
5670 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5671 * See the License for the specific language governing permissions and
5672 * limitations under the License.
5673 */
5674
5675 // gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
5676
5677 #include <locale.h>
5678 #include <stdarg.h>
5679 #include <string.h>
5680
5681 #include <algorithm>
5682
5683 #if PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
5684 #include <xlocale.h>
5685 #endif
5686
5687 #include <cinttypes>
5688
5689 // gen_amalgamated expanded: #include "perfetto/base/compiler.h"
5690 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
5691
5692 namespace perfetto {
5693 namespace base {
5694
5695 // Locale-independant as possible version of strtod.
StrToD(const char * nptr,char ** endptr)5696 double StrToD(const char* nptr, char** endptr) {
5697 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
5698 PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
5699 PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
5700 static auto c_locale = newlocale(LC_ALL, "C", nullptr);
5701 return strtod_l(nptr, endptr, c_locale);
5702 #else
5703 return strtod(nptr, endptr);
5704 #endif
5705 }
5706
StartsWith(const std::string & str,const std::string & prefix)5707 bool StartsWith(const std::string& str, const std::string& prefix) {
5708 return str.compare(0, prefix.length(), prefix) == 0;
5709 }
5710
StartsWithAny(const std::string & str,const std::vector<std::string> & prefixes)5711 bool StartsWithAny(const std::string& str,
5712 const std::vector<std::string>& prefixes) {
5713 return std::any_of(
5714 prefixes.begin(), prefixes.end(),
5715 [&str](const std::string& prefix) { return StartsWith(str, prefix); });
5716 }
5717
EndsWith(const std::string & str,const std::string & suffix)5718 bool EndsWith(const std::string& str, const std::string& suffix) {
5719 if (suffix.size() > str.size())
5720 return false;
5721 return str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
5722 }
5723
Contains(const std::string & haystack,const std::string & needle)5724 bool Contains(const std::string& haystack, const std::string& needle) {
5725 return haystack.find(needle) != std::string::npos;
5726 }
5727
Contains(const std::string & haystack,const char needle)5728 bool Contains(const std::string& haystack, const char needle) {
5729 return haystack.find(needle) != std::string::npos;
5730 }
5731
Find(const StringView & needle,const StringView & haystack)5732 size_t Find(const StringView& needle, const StringView& haystack) {
5733 if (needle.empty())
5734 return 0;
5735 if (needle.size() > haystack.size())
5736 return std::string::npos;
5737 for (size_t i = 0; i < haystack.size() - (needle.size() - 1); ++i) {
5738 if (strncmp(haystack.data() + i, needle.data(), needle.size()) == 0)
5739 return i;
5740 }
5741 return std::string::npos;
5742 }
5743
CaseInsensitiveEqual(const std::string & first,const std::string & second)5744 bool CaseInsensitiveEqual(const std::string& first, const std::string& second) {
5745 return first.size() == second.size() &&
5746 std::equal(
5747 first.begin(), first.end(), second.begin(),
5748 [](char a, char b) { return Lowercase(a) == Lowercase(b); });
5749 }
5750
Join(const std::vector<std::string> & parts,const std::string & delim)5751 std::string Join(const std::vector<std::string>& parts,
5752 const std::string& delim) {
5753 std::string acc;
5754 for (size_t i = 0; i < parts.size(); ++i) {
5755 acc += parts[i];
5756 if (i + 1 != parts.size()) {
5757 acc += delim;
5758 }
5759 }
5760 return acc;
5761 }
5762
SplitString(const std::string & text,const std::string & delimiter)5763 std::vector<std::string> SplitString(const std::string& text,
5764 const std::string& delimiter) {
5765 PERFETTO_CHECK(!delimiter.empty());
5766
5767 std::vector<std::string> output;
5768 size_t start = 0;
5769 size_t next;
5770 for (;;) {
5771 next = std::min(text.find(delimiter, start), text.size());
5772 if (next > start)
5773 output.emplace_back(&text[start], next - start);
5774 start = next + delimiter.size();
5775 if (start >= text.size())
5776 break;
5777 }
5778 return output;
5779 }
5780
StripPrefix(const std::string & str,const std::string & prefix)5781 std::string StripPrefix(const std::string& str, const std::string& prefix) {
5782 return StartsWith(str, prefix) ? str.substr(prefix.size()) : str;
5783 }
5784
StripSuffix(const std::string & str,const std::string & suffix)5785 std::string StripSuffix(const std::string& str, const std::string& suffix) {
5786 return EndsWith(str, suffix) ? str.substr(0, str.size() - suffix.size())
5787 : str;
5788 }
5789
ToUpper(const std::string & str)5790 std::string ToUpper(const std::string& str) {
5791 // Don't use toupper(), it depends on the locale.
5792 std::string res(str);
5793 auto end = res.end();
5794 for (auto c = res.begin(); c != end; ++c)
5795 *c = Uppercase(*c);
5796 return res;
5797 }
5798
ToLower(const std::string & str)5799 std::string ToLower(const std::string& str) {
5800 // Don't use tolower(), it depends on the locale.
5801 std::string res(str);
5802 auto end = res.end();
5803 for (auto c = res.begin(); c != end; ++c)
5804 *c = Lowercase(*c);
5805 return res;
5806 }
5807
ToHex(const char * data,size_t size)5808 std::string ToHex(const char* data, size_t size) {
5809 std::string hex(2 * size + 1, 'x');
5810 for (size_t i = 0; i < size; ++i) {
5811 // snprintf prints 3 characters, the two hex digits and a null byte. As we
5812 // write left to right, we keep overwriting the nullbytes, except for the
5813 // last call to snprintf.
5814 snprintf(&(hex[2 * i]), 3, "%02hhx", data[i]);
5815 }
5816 // Remove the trailing nullbyte produced by the last snprintf.
5817 hex.resize(2 * size);
5818 return hex;
5819 }
5820
IntToHexString(uint32_t number)5821 std::string IntToHexString(uint32_t number) {
5822 size_t max_size = 11; // Max uint32 is 0xFFFFFFFF + 1 for null byte.
5823 std::string buf;
5824 buf.resize(max_size);
5825 size_t final_len = SprintfTrunc(&buf[0], max_size, "0x%02x", number);
5826 buf.resize(static_cast<size_t>(final_len)); // Cuts off the final null byte.
5827 return buf;
5828 }
5829
Uint64ToHexString(uint64_t number)5830 std::string Uint64ToHexString(uint64_t number) {
5831 return "0x" + Uint64ToHexStringNoPrefix(number);
5832 }
5833
Uint64ToHexStringNoPrefix(uint64_t number)5834 std::string Uint64ToHexStringNoPrefix(uint64_t number) {
5835 size_t max_size = 17; // Max uint64 is FFFFFFFFFFFFFFFF + 1 for null byte.
5836 std::string buf;
5837 buf.resize(max_size);
5838 size_t final_len = SprintfTrunc(&buf[0], max_size, "%" PRIx64 "", number);
5839 buf.resize(static_cast<size_t>(final_len)); // Cuts off the final null byte.
5840 return buf;
5841 }
5842
StripChars(const std::string & str,const std::string & chars,char replacement)5843 std::string StripChars(const std::string& str,
5844 const std::string& chars,
5845 char replacement) {
5846 std::string res(str);
5847 const char* start = res.c_str();
5848 const char* remove = chars.c_str();
5849 for (const char* c = strpbrk(start, remove); c; c = strpbrk(c + 1, remove))
5850 res[static_cast<uintptr_t>(c - start)] = replacement;
5851 return res;
5852 }
5853
ReplaceAll(std::string str,const std::string & to_replace,const std::string & replacement)5854 std::string ReplaceAll(std::string str,
5855 const std::string& to_replace,
5856 const std::string& replacement) {
5857 PERFETTO_CHECK(!to_replace.empty());
5858 size_t pos = 0;
5859 while ((pos = str.find(to_replace, pos)) != std::string::npos) {
5860 str.replace(pos, to_replace.length(), replacement);
5861 pos += replacement.length();
5862 }
5863 return str;
5864 }
5865
TrimLeading(const std::string & str)5866 std::string TrimLeading(const std::string& str) {
5867 size_t idx = str.find_first_not_of(' ');
5868 return idx == std::string::npos ? str : str.substr(idx);
5869 }
5870
SprintfTrunc(char * dst,size_t dst_size,const char * fmt,...)5871 size_t SprintfTrunc(char* dst, size_t dst_size, const char* fmt, ...) {
5872 if (PERFETTO_UNLIKELY(dst_size) == 0)
5873 return 0;
5874
5875 va_list args;
5876 va_start(args, fmt);
5877 int src_size = vsnprintf(dst, dst_size, fmt, args);
5878 va_end(args);
5879
5880 if (PERFETTO_UNLIKELY(src_size) <= 0) {
5881 dst[0] = '\0';
5882 return 0;
5883 }
5884
5885 size_t res;
5886 if (PERFETTO_LIKELY(src_size < static_cast<int>(dst_size))) {
5887 // Most common case.
5888 res = static_cast<size_t>(src_size);
5889 } else {
5890 // Truncation case.
5891 res = dst_size - 1;
5892 }
5893
5894 PERFETTO_DCHECK(res < dst_size);
5895 PERFETTO_DCHECK(dst[res] == '\0');
5896 return res;
5897 }
5898
5899 } // namespace base
5900 } // namespace perfetto
5901 // gen_amalgamated begin source: src/base/string_view.cc
5902 /*
5903 * Copyright (C) 2019 The Android Open Source Project
5904 *
5905 * Licensed under the Apache License, Version 2.0 (the "License");
5906 * you may not use this file except in compliance with the License.
5907 * You may obtain a copy of the License at
5908 *
5909 * http://www.apache.org/licenses/LICENSE-2.0
5910 *
5911 * Unless required by applicable law or agreed to in writing, software
5912 * distributed under the License is distributed on an "AS IS" BASIS,
5913 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5914 * See the License for the specific language governing permissions and
5915 * limitations under the License.
5916 */
5917
5918 // gen_amalgamated expanded: #include "perfetto/ext/base/string_view.h"
5919
5920 namespace perfetto {
5921 namespace base {
5922
5923 // static
5924 constexpr size_t StringView::npos;
5925
5926 } // namespace base
5927 } // namespace perfetto
5928 // gen_amalgamated begin source: src/base/temp_file.cc
5929 // gen_amalgamated begin header: include/perfetto/ext/base/temp_file.h
5930 /*
5931 * Copyright (C) 2018 The Android Open Source Project
5932 *
5933 * Licensed under the Apache License, Version 2.0 (the "License");
5934 * you may not use this file except in compliance with the License.
5935 * You may obtain a copy of the License at
5936 *
5937 * http://www.apache.org/licenses/LICENSE-2.0
5938 *
5939 * Unless required by applicable law or agreed to in writing, software
5940 * distributed under the License is distributed on an "AS IS" BASIS,
5941 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5942 * See the License for the specific language governing permissions and
5943 * limitations under the License.
5944 */
5945
5946 #ifndef INCLUDE_PERFETTO_EXT_BASE_TEMP_FILE_H_
5947 #define INCLUDE_PERFETTO_EXT_BASE_TEMP_FILE_H_
5948
5949 #include <string>
5950
5951 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
5952
5953 namespace perfetto {
5954 namespace base {
5955
5956 std::string GetSysTempDir();
5957
5958 class TempFile {
5959 public:
5960 static TempFile CreateUnlinked();
5961 static TempFile Create();
5962
5963 TempFile(TempFile&&) noexcept;
5964 TempFile& operator=(TempFile&&);
5965 ~TempFile();
5966
path() const5967 const std::string& path() const { return path_; }
fd() const5968 int fd() const { return *fd_; }
operator *() const5969 int operator*() const { return *fd_; }
5970
5971 // Unlinks the file from the filesystem but keeps the fd() open.
5972 // It is safe to call this multiple times.
5973 void Unlink();
5974
5975 // Releases the underlying file descriptor. Will unlink the file from the
5976 // filesystem if it was created via CreateUnlinked().
5977 ScopedFile ReleaseFD();
5978
5979 private:
5980 TempFile();
5981 TempFile(const TempFile&) = delete;
5982 TempFile& operator=(const TempFile&) = delete;
5983
5984 ScopedFile fd_;
5985 std::string path_;
5986 };
5987
5988 class TempDir {
5989 public:
5990 static TempDir Create();
5991
5992 TempDir(TempDir&&) noexcept;
5993 TempDir& operator=(TempDir&&);
5994 ~TempDir();
5995
path() const5996 const std::string& path() const { return path_; }
5997
5998 private:
5999 TempDir();
6000 TempDir(const TempDir&) = delete;
6001 TempDir& operator=(const TempDir&) = delete;
6002
6003 std::string path_;
6004 };
6005
6006 } // namespace base
6007 } // namespace perfetto
6008
6009 #endif // INCLUDE_PERFETTO_EXT_BASE_TEMP_FILE_H_
6010 /*
6011 * Copyright (C) 2018 The Android Open Source Project
6012 *
6013 * Licensed under the Apache License, Version 2.0 (the "License");
6014 * you may not use this file except in compliance with the License.
6015 * You may obtain a copy of the License at
6016 *
6017 * http://www.apache.org/licenses/LICENSE-2.0
6018 *
6019 * Unless required by applicable law or agreed to in writing, software
6020 * distributed under the License is distributed on an "AS IS" BASIS,
6021 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6022 * See the License for the specific language governing permissions and
6023 * limitations under the License.
6024 */
6025
6026 // gen_amalgamated expanded: #include "perfetto/ext/base/temp_file.h"
6027
6028 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
6029
6030 #include <stdio.h>
6031 #include <stdlib.h>
6032 #include <string.h>
6033
6034 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
6035 #include <Windows.h>
6036 #include <direct.h>
6037 #include <fileapi.h>
6038 #include <io.h>
6039 #else
6040 #include <unistd.h>
6041 #endif
6042
6043 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
6044 // gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
6045 // gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
6046
6047 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
6048 namespace {
GetTempName()6049 std::string GetTempName() {
6050 char name[] = "perfetto-XXXXXX";
6051 PERFETTO_CHECK(_mktemp_s(name, sizeof(name)) == 0);
6052 return name;
6053 }
6054 } // namespace
6055 #endif
6056
6057 namespace perfetto {
6058 namespace base {
6059
GetSysTempDir()6060 std::string GetSysTempDir() {
6061 const char* tmpdir = nullptr;
6062 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
6063 if ((tmpdir = getenv("TMP")))
6064 return tmpdir;
6065 if ((tmpdir = getenv("TEMP")))
6066 return tmpdir;
6067 return "C:\\TEMP";
6068 #else
6069 if ((tmpdir = getenv("TMPDIR")))
6070 return base::StripSuffix(tmpdir, "/");
6071 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
6072 return "/data/local/tmp";
6073 #else
6074 return "/tmp";
6075 #endif // !OS_ANDROID
6076 #endif // !OS_WIN
6077 }
6078
6079 // static
Create()6080 TempFile TempFile::Create() {
6081 TempFile temp_file;
6082 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
6083 temp_file.path_ = GetSysTempDir() + "\\" + GetTempName();
6084 // Several tests want to read-back the temp file while still open. On Windows,
6085 // that requires FILE_SHARE_READ. FILE_SHARE_READ is NOT settable when using
6086 // the POSIX-compat equivalent function _open(). Hence the CreateFileA +
6087 // _open_osfhandle dance here.
6088 HANDLE h =
6089 ::CreateFileA(temp_file.path_.c_str(), GENERIC_READ | GENERIC_WRITE,
6090 FILE_SHARE_DELETE | FILE_SHARE_READ, nullptr, CREATE_ALWAYS,
6091 FILE_ATTRIBUTE_TEMPORARY, nullptr);
6092 PERFETTO_CHECK(PlatformHandleChecker::IsValid(h));
6093 // According to MSDN, when using _open_osfhandle the caller must not call
6094 // CloseHandle(). Ownership is moved to the file descriptor, which then needs
6095 // to be closed with just with _close().
6096 temp_file.fd_.reset(_open_osfhandle(reinterpret_cast<intptr_t>(h), 0));
6097 #else
6098 temp_file.path_ = GetSysTempDir() + "/perfetto-XXXXXXXX";
6099 temp_file.fd_.reset(mkstemp(&temp_file.path_[0]));
6100 #endif
6101 if (PERFETTO_UNLIKELY(!temp_file.fd_)) {
6102 PERFETTO_FATAL("Could not create temp file %s", temp_file.path_.c_str());
6103 }
6104 return temp_file;
6105 }
6106
6107 // static
CreateUnlinked()6108 TempFile TempFile::CreateUnlinked() {
6109 TempFile temp_file = TempFile::Create();
6110 temp_file.Unlink();
6111 return temp_file;
6112 }
6113
6114 TempFile::TempFile() = default;
6115
~TempFile()6116 TempFile::~TempFile() {
6117 Unlink();
6118 }
6119
ReleaseFD()6120 ScopedFile TempFile::ReleaseFD() {
6121 Unlink();
6122 return std::move(fd_);
6123 }
6124
Unlink()6125 void TempFile::Unlink() {
6126 if (path_.empty())
6127 return;
6128 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
6129 // If the FD is still open DeleteFile will mark the file as pending deletion
6130 // and delete it only when the process exists.
6131 PERFETTO_CHECK(DeleteFileA(path_.c_str()));
6132 #else
6133 PERFETTO_CHECK(unlink(path_.c_str()) == 0);
6134 #endif
6135 path_.clear();
6136 }
6137
6138 TempFile::TempFile(TempFile&&) noexcept = default;
6139 TempFile& TempFile::operator=(TempFile&&) = default;
6140
6141 // static
Create()6142 TempDir TempDir::Create() {
6143 TempDir temp_dir;
6144 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
6145 temp_dir.path_ = GetSysTempDir() + "\\" + GetTempName();
6146 PERFETTO_CHECK(_mkdir(temp_dir.path_.c_str()) == 0);
6147 #else
6148 temp_dir.path_ = GetSysTempDir() + "/perfetto-XXXXXXXX";
6149 PERFETTO_CHECK(mkdtemp(&temp_dir.path_[0]));
6150 #endif
6151 return temp_dir;
6152 }
6153
6154 TempDir::TempDir() = default;
6155 TempDir::TempDir(TempDir&&) noexcept = default;
6156 TempDir& TempDir::operator=(TempDir&&) = default;
6157
~TempDir()6158 TempDir::~TempDir() {
6159 if (path_.empty())
6160 return; // For objects that get std::move()d.
6161 PERFETTO_CHECK(Rmdir(path_));
6162 }
6163
6164 } // namespace base
6165 } // namespace perfetto
6166 // gen_amalgamated begin source: src/base/thread_checker.cc
6167 /*
6168 * Copyright (C) 2017 The Android Open Source Project
6169 *
6170 * Licensed under the Apache License, Version 2.0 (the "License");
6171 * you may not use this file except in compliance with the License.
6172 * You may obtain a copy of the License at
6173 *
6174 * http://www.apache.org/licenses/LICENSE-2.0
6175 *
6176 * Unless required by applicable law or agreed to in writing, software
6177 * distributed under the License is distributed on an "AS IS" BASIS,
6178 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6179 * See the License for the specific language governing permissions and
6180 * limitations under the License.
6181 */
6182
6183 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_checker.h"
6184
6185 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
6186 #include <Windows.h>
6187 #endif
6188
6189 namespace perfetto {
6190 namespace base {
6191
6192 namespace {
6193 constexpr ThreadID kDetached{};
6194
CurrentThreadId()6195 ThreadID CurrentThreadId() {
6196 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
6197 return ::GetCurrentThreadId();
6198 #else
6199 return pthread_self();
6200 #endif
6201 }
6202 } // namespace
6203
ThreadChecker()6204 ThreadChecker::ThreadChecker() {
6205 thread_id_.store(CurrentThreadId());
6206 }
6207
6208 ThreadChecker::~ThreadChecker() = default;
6209
ThreadChecker(const ThreadChecker & other)6210 ThreadChecker::ThreadChecker(const ThreadChecker& other) {
6211 thread_id_ = other.thread_id_.load();
6212 }
6213
operator =(const ThreadChecker & other)6214 ThreadChecker& ThreadChecker::operator=(const ThreadChecker& other) {
6215 thread_id_ = other.thread_id_.load();
6216 return *this;
6217 }
6218
CalledOnValidThread() const6219 bool ThreadChecker::CalledOnValidThread() const {
6220 auto self = CurrentThreadId();
6221
6222 // Will re-attach if previously detached using DetachFromThread().
6223 auto prev_value = kDetached;
6224 if (thread_id_.compare_exchange_strong(prev_value, self))
6225 return true;
6226 return prev_value == self;
6227 }
6228
DetachFromThread()6229 void ThreadChecker::DetachFromThread() {
6230 thread_id_.store(kDetached);
6231 }
6232
6233 } // namespace base
6234 } // namespace perfetto
6235 // gen_amalgamated begin source: src/base/time.cc
6236 /*
6237 * Copyright (C) 2018 The Android Open Source Project
6238 *
6239 * Licensed under the Apache License, Version 2.0 (the "License");
6240 * you may not use this file except in compliance with the License.
6241 * You may obtain a copy of the License at
6242 *
6243 * http://www.apache.org/licenses/LICENSE-2.0
6244 *
6245 * Unless required by applicable law or agreed to in writing, software
6246 * distributed under the License is distributed on an "AS IS" BASIS,
6247 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6248 * See the License for the specific language governing permissions and
6249 * limitations under the License.
6250 */
6251
6252 // gen_amalgamated expanded: #include "perfetto/base/time.h"
6253
6254 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
6255 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
6256
6257 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
6258 #include <Windows.h>
6259 #else
6260 #include <unistd.h>
6261 #endif
6262
6263 namespace perfetto {
6264 namespace base {
6265
6266 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
6267
GetWallTimeNs()6268 TimeNanos GetWallTimeNs() {
6269 LARGE_INTEGER freq;
6270 ::QueryPerformanceFrequency(&freq);
6271 LARGE_INTEGER counter;
6272 ::QueryPerformanceCounter(&counter);
6273 double elapsed_nanoseconds = (1e9 * static_cast<double>(counter.QuadPart)) /
6274 static_cast<double>(freq.QuadPart);
6275 return TimeNanos(static_cast<uint64_t>(elapsed_nanoseconds));
6276 }
6277
GetThreadCPUTimeNs()6278 TimeNanos GetThreadCPUTimeNs() {
6279 FILETIME dummy, kernel_ftime, user_ftime;
6280 ::GetThreadTimes(GetCurrentThread(), &dummy, &dummy, &kernel_ftime,
6281 &user_ftime);
6282 uint64_t kernel_time = kernel_ftime.dwHighDateTime * 0x100000000 +
6283 kernel_ftime.dwLowDateTime;
6284 uint64_t user_time = user_ftime.dwHighDateTime * 0x100000000 +
6285 user_ftime.dwLowDateTime;
6286
6287 return TimeNanos((kernel_time + user_time) * 100);
6288 }
6289
SleepMicroseconds(unsigned interval_us)6290 void SleepMicroseconds(unsigned interval_us) {
6291 // The Windows Sleep function takes a millisecond count. Round up so that
6292 // short sleeps don't turn into a busy wait. Note that the sleep granularity
6293 // on Windows can dynamically vary from 1 ms to ~16 ms, so don't count on this
6294 // being a short sleep.
6295 ::Sleep(static_cast<DWORD>((interval_us + 999) / 1000));
6296 }
6297
6298 #else // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
6299
6300 void SleepMicroseconds(unsigned interval_us) {
6301 ::usleep(static_cast<useconds_t>(interval_us));
6302 }
6303
6304 #endif // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
6305
GetTimeFmt(const std::string & fmt)6306 std::string GetTimeFmt(const std::string& fmt) {
6307 time_t raw_time;
6308 time(&raw_time);
6309 struct tm* local_tm;
6310 local_tm = localtime(&raw_time);
6311 char buf[128];
6312 PERFETTO_CHECK(strftime(buf, 80, fmt.c_str(), local_tm) > 0);
6313 return buf;
6314 }
6315
6316 } // namespace base
6317 } // namespace perfetto
6318 // gen_amalgamated begin source: src/base/utils.cc
6319 /*
6320 * Copyright (C) 2020 The Android Open Source Project
6321 *
6322 * Licensed under the Apache License, Version 2.0 (the "License");
6323 * you may not use this file except in compliance with the License.
6324 * You may obtain a copy of the License at
6325 *
6326 * http://www.apache.org/licenses/LICENSE-2.0
6327 *
6328 * Unless required by applicable law or agreed to in writing, software
6329 * distributed under the License is distributed on an "AS IS" BASIS,
6330 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6331 * See the License for the specific language governing permissions and
6332 * limitations under the License.
6333 */
6334
6335 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
6336
6337 #include <string>
6338
6339 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
6340 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
6341 // gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
6342
6343 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
6344 PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
6345 PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE) || \
6346 PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
6347 #include <limits.h>
6348 #include <stdlib.h> // For _exit()
6349 #include <unistd.h> // For getpagesize() and geteuid() & fork()
6350 #endif
6351
6352 #if PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
6353 #include <mach-o/dyld.h>
6354 #include <mach/vm_page_size.h>
6355 #endif
6356
6357 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
6358 #include <Windows.h>
6359 #include <io.h>
6360 #include <malloc.h> // For _aligned_malloc().
6361 #endif
6362
6363 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
6364 #include <dlfcn.h>
6365 #include <malloc.h>
6366
6367 #ifdef M_PURGE
6368 #define PERFETTO_M_PURGE M_PURGE
6369 #else
6370 // Only available in in-tree builds and on newer SDKs.
6371 #define PERFETTO_M_PURGE -101
6372 #endif // M_PURGE
6373
6374 namespace {
6375 extern "C" {
6376 using MalloptType = void (*)(int, int);
6377 }
6378 } // namespace
6379 #endif // OS_ANDROID
6380
6381 namespace {
6382
6383 #if PERFETTO_BUILDFLAG(PERFETTO_X64_CPU_OPT)
6384
6385 // Preserve the %rbx register via %rdi to work around a clang bug
6386 // https://bugs.llvm.org/show_bug.cgi?id=17907 (%rbx in an output constraint
6387 // is not considered a clobbered register).
6388 #define PERFETTO_GETCPUID(a, b, c, d, a_inp, c_inp) \
6389 asm("mov %%rbx, %%rdi\n" \
6390 "cpuid\n" \
6391 "xchg %%rdi, %%rbx\n" \
6392 : "=a"(a), "=D"(b), "=c"(c), "=d"(d) \
6393 : "a"(a_inp), "2"(c_inp))
6394
GetXCR0EAX()6395 uint32_t GetXCR0EAX() {
6396 uint32_t eax = 0, edx = 0;
6397 asm("xgetbv" : "=a"(eax), "=d"(edx) : "c"(0));
6398 return eax;
6399 }
6400
6401 // If we are building with -msse4 check that the CPU actually supports it.
6402 // This file must be kept in sync with gn/standalone/BUILD.gn.
CheckCpuOptimizations()6403 void PERFETTO_EXPORT __attribute__((constructor)) CheckCpuOptimizations() {
6404 uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
6405 PERFETTO_GETCPUID(eax, ebx, ecx, edx, 1, 0);
6406
6407 static constexpr uint64_t xcr0_xmm_mask = 0x2;
6408 static constexpr uint64_t xcr0_ymm_mask = 0x4;
6409 static constexpr uint64_t xcr0_avx_mask = xcr0_xmm_mask | xcr0_ymm_mask;
6410
6411 const bool have_popcnt = ecx & (1u << 23);
6412 const bool have_sse4_2 = ecx & (1u << 20);
6413 const bool have_avx =
6414 // Does the OS save/restore XMM and YMM state?
6415 ((GetXCR0EAX() & xcr0_avx_mask) == xcr0_avx_mask) &&
6416 (ecx & (1u << 27)) && // OS support XGETBV.
6417 (ecx & (1u << 28)); // AVX supported in hardware
6418
6419 if (!have_sse4_2 || !have_popcnt || !have_avx) {
6420 fprintf(
6421 stderr,
6422 "This executable requires a cpu that supports SSE4.2 and AVX2.\n"
6423 "Rebuild with enable_perfetto_x64_cpu_opt=false (ebx=%x, ecx=%x).\n",
6424 ebx, ecx);
6425 _exit(126);
6426 }
6427 }
6428 #endif
6429
6430 } // namespace
6431
6432 namespace perfetto {
6433 namespace base {
6434
MaybeReleaseAllocatorMemToOS()6435 void MaybeReleaseAllocatorMemToOS() {
6436 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
6437 // mallopt() on Android requires SDK level 26. Many targets and embedders
6438 // still depend on a lower SDK level. Given mallopt() is a quite simple API,
6439 // use reflection to do this rather than bumping the SDK level for all
6440 // embedders. This keeps the behavior of standalone builds aligned with
6441 // in-tree builds.
6442 static MalloptType mallopt_fn =
6443 reinterpret_cast<MalloptType>(dlsym(RTLD_DEFAULT, "mallopt"));
6444 if (!mallopt_fn)
6445 return;
6446 mallopt_fn(PERFETTO_M_PURGE, 0);
6447 #endif
6448 }
6449
GetSysPageSize()6450 uint32_t GetSysPageSize() {
6451 ignore_result(kPageSize); // Just to keep the amalgamated build happy.
6452 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
6453 PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
6454 static std::atomic<uint32_t> page_size{0};
6455 // This function might be called in hot paths. Avoid calling getpagesize() all
6456 // the times, in many implementations getpagesize() calls sysconf() which is
6457 // not cheap.
6458 uint32_t cached_value = page_size.load(std::memory_order_relaxed);
6459 if (PERFETTO_UNLIKELY(cached_value == 0)) {
6460 cached_value = static_cast<uint32_t>(getpagesize());
6461 page_size.store(cached_value, std::memory_order_relaxed);
6462 }
6463 return cached_value;
6464 #elif PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
6465 return static_cast<uint32_t>(vm_page_size);
6466 #else
6467 return 4096;
6468 #endif
6469 }
6470
GetCurrentUserId()6471 uid_t GetCurrentUserId() {
6472 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
6473 PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
6474 PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
6475 return geteuid();
6476 #else
6477 // TODO(primiano): On Windows we could hash the current user SID and derive a
6478 // numeric user id [1]. It is not clear whether we need that. Right now that
6479 // would not bring any benefit. Returning 0 unil we can prove we need it.
6480 // [1]:https://android-review.googlesource.com/c/platform/external/perfetto/+/1513879/25/src/base/utils.cc
6481 return 0;
6482 #endif
6483 }
6484
SetEnv(const std::string & key,const std::string & value)6485 void SetEnv(const std::string& key, const std::string& value) {
6486 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
6487 PERFETTO_CHECK(::_putenv_s(key.c_str(), value.c_str()) == 0);
6488 #else
6489 PERFETTO_CHECK(::setenv(key.c_str(), value.c_str(), /*overwrite=*/true) == 0);
6490 #endif
6491 }
6492
Daemonize(std::function<int ()> parent_cb)6493 void Daemonize(std::function<int()> parent_cb) {
6494 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
6495 PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
6496 PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
6497 pid_t pid;
6498 switch (pid = fork()) {
6499 case -1:
6500 PERFETTO_FATAL("fork");
6501 case 0: {
6502 PERFETTO_CHECK(setsid() != -1);
6503 base::ignore_result(chdir("/"));
6504 base::ScopedFile null = base::OpenFile("/dev/null", O_RDONLY);
6505 PERFETTO_CHECK(null);
6506 PERFETTO_CHECK(dup2(*null, STDIN_FILENO) != -1);
6507 PERFETTO_CHECK(dup2(*null, STDOUT_FILENO) != -1);
6508 PERFETTO_CHECK(dup2(*null, STDERR_FILENO) != -1);
6509 // Do not accidentally close stdin/stdout/stderr.
6510 if (*null <= 2)
6511 null.release();
6512 break;
6513 }
6514 default:
6515 printf("%d\n", pid);
6516 int err = parent_cb();
6517 exit(err);
6518 }
6519 #else
6520 // Avoid -Wunreachable warnings.
6521 if (reinterpret_cast<intptr_t>(&Daemonize) != 16)
6522 PERFETTO_FATAL("--background is only supported on Linux/Android/Mac");
6523 ignore_result(parent_cb);
6524 #endif // OS_WIN
6525 }
6526
GetCurExecutablePath()6527 std::string GetCurExecutablePath() {
6528 std::string self_path;
6529 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
6530 PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
6531 PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
6532 char buf[PATH_MAX];
6533 ssize_t size = readlink("/proc/self/exe", buf, sizeof(buf));
6534 PERFETTO_CHECK(size != -1);
6535 // readlink does not null terminate.
6536 self_path = std::string(buf, static_cast<size_t>(size));
6537 #elif PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
6538 uint32_t size = 0;
6539 PERFETTO_CHECK(_NSGetExecutablePath(nullptr, &size));
6540 self_path.resize(size);
6541 PERFETTO_CHECK(_NSGetExecutablePath(&self_path[0], &size) == 0);
6542 #elif PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
6543 char buf[MAX_PATH];
6544 auto len = ::GetModuleFileNameA(nullptr /*current*/, buf, sizeof(buf));
6545 self_path = std::string(buf, len);
6546 #else
6547 PERFETTO_FATAL(
6548 "GetCurExecutableDir() not implemented on the current platform");
6549 #endif
6550 return self_path;
6551 }
6552
GetCurExecutableDir()6553 std::string GetCurExecutableDir() {
6554 auto path = GetCurExecutablePath();
6555 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
6556 // Paths in Windows can have both kinds of slashes (mingw vs msvc).
6557 path = path.substr(0, path.find_last_of('\\'));
6558 #endif
6559 path = path.substr(0, path.find_last_of('/'));
6560 return path;
6561 }
6562
AlignedAlloc(size_t alignment,size_t size)6563 void* AlignedAlloc(size_t alignment, size_t size) {
6564 void* res = nullptr;
6565 alignment = AlignUp<sizeof(void*)>(alignment); // At least pointer size.
6566 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
6567 // Window's _aligned_malloc() has a nearly identically signature to Unix's
6568 // aligned_alloc() but its arguments are obviously swapped.
6569 res = _aligned_malloc(size, alignment);
6570 #else
6571 // aligned_alloc() has been introduced in Android only in API 28.
6572 // Also NaCl and Fuchsia seems to have only posix_memalign().
6573 ignore_result(posix_memalign(&res, alignment, size));
6574 #endif
6575 PERFETTO_CHECK(res);
6576 return res;
6577 }
6578
AlignedFree(void * ptr)6579 void AlignedFree(void* ptr) {
6580 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
6581 _aligned_free(ptr); // MSDN says it is fine to pass nullptr.
6582 #else
6583 free(ptr);
6584 #endif
6585 }
6586
HexDump(const void * data_void,size_t len,size_t bytes_per_line)6587 std::string HexDump(const void* data_void, size_t len, size_t bytes_per_line) {
6588 const char* data = reinterpret_cast<const char*>(data_void);
6589 std::string res;
6590 static const size_t kPadding = bytes_per_line * 3 + 12;
6591 std::unique_ptr<char[]> line(new char[bytes_per_line * 4 + 128]);
6592 for (size_t i = 0; i < len; i += bytes_per_line) {
6593 char* wptr = line.get();
6594 wptr += sprintf(wptr, "%08zX: ", i);
6595 for (size_t j = i; j < i + bytes_per_line && j < len; j++)
6596 wptr += sprintf(wptr, "%02X ", static_cast<unsigned>(data[j]) & 0xFF);
6597 for (size_t j = static_cast<size_t>(wptr - line.get()); j < kPadding; ++j)
6598 *(wptr++) = ' ';
6599 for (size_t j = i; j < i + bytes_per_line && j < len; j++) {
6600 char c = data[j];
6601 *(wptr++) = (c >= 32 && c < 127) ? c : '.';
6602 }
6603 *(wptr++) = '\n';
6604 *(wptr++) = '\0';
6605 res.append(line.get());
6606 }
6607 return res;
6608 }
6609
6610 } // namespace base
6611 } // namespace perfetto
6612 // gen_amalgamated begin source: src/base/uuid.cc
6613 // gen_amalgamated begin header: include/perfetto/ext/base/uuid.h
6614 /*
6615 * Copyright (C) 2019 The Android Open Source Project
6616 *
6617 * Licensed under the Apache License, Version 2.0 (the "License");
6618 * you may not use this file except in compliance with the License.
6619 * You may obtain a copy of the License at
6620 *
6621 * http://www.apache.org/licenses/LICENSE-2.0
6622 *
6623 * Unless required by applicable law or agreed to in writing, software
6624 * distributed under the License is distributed on an "AS IS" BASIS,
6625 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6626 * See the License for the specific language governing permissions and
6627 * limitations under the License.
6628 */
6629
6630 #ifndef INCLUDE_PERFETTO_EXT_BASE_UUID_H_
6631 #define INCLUDE_PERFETTO_EXT_BASE_UUID_H_
6632
6633 #include <array>
6634 #include <string>
6635
6636 // gen_amalgamated expanded: #include "perfetto/ext/base/optional.h"
6637
6638 namespace perfetto {
6639 namespace base {
6640
6641 class Uuid {
6642 public:
6643 explicit Uuid(const std::string& s);
6644 explicit Uuid(int64_t lsb, int64_t msb);
6645 Uuid();
6646
data()6647 std::array<uint8_t, 16>* data() { return &data_; }
data() const6648 const std::array<uint8_t, 16>* data() const { return &data_; }
6649
operator ==(const Uuid & other) const6650 bool operator==(const Uuid& other) const { return data_ == other.data_; }
6651
operator !=(const Uuid & other) const6652 bool operator!=(const Uuid& other) const { return !(*this == other); }
6653
msb() const6654 int64_t msb() const {
6655 int64_t result;
6656 memcpy(&result, data_.data() + 8, 8);
6657 return result;
6658 }
6659
lsb() const6660 int64_t lsb() const {
6661 int64_t result;
6662 memcpy(&result, data_.data(), 8);
6663 return result;
6664 }
6665
set_lsb_msb(int64_t lsb,int64_t msb)6666 void set_lsb_msb(int64_t lsb, int64_t msb) {
6667 set_lsb(lsb);
6668 set_msb(msb);
6669 }
set_msb(int64_t msb)6670 void set_msb(int64_t msb) { memcpy(data_.data() + 8, &msb, 8); }
set_lsb(int64_t lsb)6671 void set_lsb(int64_t lsb) { memcpy(data_.data(), &lsb, 8); }
6672
6673 std::string ToString() const;
6674 std::string ToPrettyString() const;
6675
6676 private:
6677 std::array<uint8_t, 16> data_{};
6678 };
6679
6680 Uuid Uuidv4();
6681
6682 } // namespace base
6683 } // namespace perfetto
6684
6685 #endif // INCLUDE_PERFETTO_EXT_BASE_UUID_H_
6686 /*
6687 * Copyright (C) 2019 The Android Open Source Project
6688 *
6689 * Licensed under the Apache License, Version 2.0 (the "License");
6690 * you may not use this file except in compliance with the License.
6691 * You may obtain a copy of the License at
6692 *
6693 * http://www.apache.org/licenses/LICENSE-2.0
6694 *
6695 * Unless required by applicable law or agreed to in writing, software
6696 * distributed under the License is distributed on an "AS IS" BASIS,
6697 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6698 * See the License for the specific language governing permissions and
6699 * limitations under the License.
6700 */
6701
6702 // gen_amalgamated expanded: #include "perfetto/ext/base/uuid.h"
6703
6704 #include <random>
6705
6706 // gen_amalgamated expanded: #include "perfetto/base/time.h"
6707
6708 namespace perfetto {
6709 namespace base {
6710 namespace {
6711
6712 constexpr char kHexmap[] = {'0', '1', '2', '3', '4', '5', '6', '7',
6713 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
6714 } // namespace
6715
6716 // See https://www.ietf.org/rfc/rfc4122.txt
Uuidv4()6717 Uuid Uuidv4() {
6718 static std::minstd_rand rng(static_cast<uint32_t>(GetBootTimeNs().count()));
6719 Uuid uuid;
6720 auto& data = *uuid.data();
6721
6722 for (size_t i = 0; i < 16; ++i)
6723 data[i] = static_cast<uint8_t>(rng());
6724
6725 // version:
6726 data[6] = (data[6] & 0x0f) | 0x40;
6727 // clock_seq_hi_and_reserved:
6728 data[8] = (data[8] & 0x3f) | 0x80;
6729
6730 return uuid;
6731 }
6732
Uuid()6733 Uuid::Uuid() {}
6734
Uuid(const std::string & s)6735 Uuid::Uuid(const std::string& s) {
6736 PERFETTO_CHECK(s.size() == data_.size());
6737 memcpy(data_.data(), s.data(), s.size());
6738 }
6739
Uuid(int64_t lsb,int64_t msb)6740 Uuid::Uuid(int64_t lsb, int64_t msb) {
6741 set_lsb_msb(lsb, msb);
6742 }
6743
ToString() const6744 std::string Uuid::ToString() const {
6745 return std::string(reinterpret_cast<const char*>(data_.data()), data_.size());
6746 }
6747
ToPrettyString() const6748 std::string Uuid::ToPrettyString() const {
6749 std::string s(data_.size() * 2 + 4, '-');
6750 // Format is 123e4567-e89b-12d3-a456-426655443322.
6751 size_t j = 0;
6752 for (size_t i = 0; i < data_.size(); ++i) {
6753 if (i == 4 || i == 6 || i == 8 || i == 10)
6754 j++;
6755 s[2 * i + j] = kHexmap[(data_[data_.size() - i - 1] & 0xf0) >> 4];
6756 s[2 * i + 1 + j] = kHexmap[(data_[data_.size() - i - 1] & 0x0f)];
6757 }
6758 return s;
6759 }
6760
6761 } // namespace base
6762 } // namespace perfetto
6763 // gen_amalgamated begin source: src/base/version.cc
6764 // gen_amalgamated begin header: include/perfetto/ext/base/version.h
6765 /*
6766 * Copyright (C) 2020 The Android Open Source Project
6767 *
6768 * Licensed under the Apache License, Version 2.0 (the "License");
6769 * you may not use this file except in compliance with the License.
6770 * You may obtain a copy of the License at
6771 *
6772 * http://www.apache.org/licenses/LICENSE-2.0
6773 *
6774 * Unless required by applicable law or agreed to in writing, software
6775 * distributed under the License is distributed on an "AS IS" BASIS,
6776 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6777 * See the License for the specific language governing permissions and
6778 * limitations under the License.
6779 */
6780
6781 #ifndef INCLUDE_PERFETTO_EXT_BASE_VERSION_H_
6782 #define INCLUDE_PERFETTO_EXT_BASE_VERSION_H_
6783
6784 namespace perfetto {
6785 namespace base {
6786
6787 // The returned pointer is a static string is safe to pass around.
6788 const char* GetVersionString();
6789
6790 } // namespace base
6791 } // namespace perfetto
6792
6793 #endif // INCLUDE_PERFETTO_EXT_BASE_VERSION_H_
6794 // gen_amalgamated begin header: gen/perfetto_version.gen.h
6795 // Generated by write_version_header.py
6796
6797 #ifndef GEN_PERFETTO_VERSION_GEN_H_
6798 #define GEN_PERFETTO_VERSION_GEN_H_
6799
6800 #define PERFETTO_VERSION_STRING() "v22.1-fa9722821"
6801 #define PERFETTO_VERSION_SCM_REVISION() "fa97228215c6c58574fbd64ac92487c31c9a4d73"
6802
6803 #endif // GEN_PERFETTO_VERSION_GEN_H_
6804 /*
6805 * Copyright (C) 2020 The Android Open Source Project
6806 *
6807 * Licensed under the Apache License, Version 2.0 (the "License");
6808 * you may not use this file except in compliance with the License.
6809 * You may obtain a copy of the License at
6810 *
6811 * http://www.apache.org/licenses/LICENSE-2.0
6812 *
6813 * Unless required by applicable law or agreed to in writing, software
6814 * distributed under the License is distributed on an "AS IS" BASIS,
6815 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6816 * See the License for the specific language governing permissions and
6817 * limitations under the License.
6818 */
6819
6820 // gen_amalgamated expanded: #include "perfetto/ext/base/version.h"
6821
6822 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
6823
6824 #include <stdio.h>
6825
6826 #if PERFETTO_BUILDFLAG(PERFETTO_VERSION_GEN)
6827 // gen_amalgamated expanded: #include "perfetto_version.gen.h"
6828 #else
6829 #define PERFETTO_VERSION_STRING() "v0.0"
6830 #define PERFETTO_VERSION_SCM_REVISION() "unknown"
6831 #endif
6832
6833 namespace perfetto {
6834 namespace base {
6835
GetVersionString()6836 const char* GetVersionString() {
6837 static const char* version_str = [] {
6838 static constexpr size_t kMaxLen = 256;
6839 char* version = new char[kMaxLen + 1];
6840 snprintf(version, kMaxLen, "Perfetto %s (%s)", PERFETTO_VERSION_STRING(),
6841 PERFETTO_VERSION_SCM_REVISION());
6842 return version;
6843 }();
6844 return version_str;
6845 }
6846
6847 } // namespace base
6848 } // namespace perfetto
6849 // gen_amalgamated begin source: src/base/virtual_destructors.cc
6850 /*
6851 * Copyright (C) 2017 The Android Open Source Project
6852 *
6853 * Licensed under the Apache License, Version 2.0 (the "License");
6854 * you may not use this file except in compliance with the License.
6855 * You may obtain a copy of the License at
6856 *
6857 * http://www.apache.org/licenses/LICENSE-2.0
6858 *
6859 * Unless required by applicable law or agreed to in writing, software
6860 * distributed under the License is distributed on an "AS IS" BASIS,
6861 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6862 * See the License for the specific language governing permissions and
6863 * limitations under the License.
6864 */
6865
6866 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
6867
6868 // This translation unit contains the definitions for the destructor of pure
6869 // virtual interfaces for the current build target. The alternative would be
6870 // introducing a one-liner .cc file for each pure virtual interface, which is
6871 // overkill. This is for compliance with -Wweak-vtables.
6872
6873 namespace perfetto {
6874 namespace base {
6875
6876 TaskRunner::~TaskRunner() = default;
6877
6878 } // namespace base
6879 } // namespace perfetto
6880 // gen_amalgamated begin source: src/base/waitable_event.cc
6881 // gen_amalgamated begin header: include/perfetto/ext/base/waitable_event.h
6882 /*
6883 * Copyright (C) 2019 The Android Open Source Project
6884 *
6885 * Licensed under the Apache License, Version 2.0 (the "License");
6886 * you may not use this file except in compliance with the License.
6887 * You may obtain a copy of the License at
6888 *
6889 * http://www.apache.org/licenses/LICENSE-2.0
6890 *
6891 * Unless required by applicable law or agreed to in writing, software
6892 * distributed under the License is distributed on an "AS IS" BASIS,
6893 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6894 * See the License for the specific language governing permissions and
6895 * limitations under the License.
6896 */
6897
6898 #ifndef INCLUDE_PERFETTO_EXT_BASE_WAITABLE_EVENT_H_
6899 #define INCLUDE_PERFETTO_EXT_BASE_WAITABLE_EVENT_H_
6900
6901 #include <condition_variable>
6902 #include <mutex>
6903
6904 namespace perfetto {
6905 namespace base {
6906
6907 // A waitable event for cross-thread synchronization.
6908 // All methods on this class can be called from any thread.
6909 class WaitableEvent {
6910 public:
6911 WaitableEvent();
6912 ~WaitableEvent();
6913 WaitableEvent(const WaitableEvent&) = delete;
6914 WaitableEvent operator=(const WaitableEvent&) = delete;
6915
6916 // Synchronously block until the event is notified.
6917 void Wait();
6918
6919 // Signal the event, waking up blocked waiters.
6920 void Notify();
6921
6922 private:
6923 std::mutex mutex_;
6924 std::condition_variable event_;
6925 bool notified_ = false;
6926 };
6927
6928 } // namespace base
6929 } // namespace perfetto
6930
6931 #endif // INCLUDE_PERFETTO_EXT_BASE_WAITABLE_EVENT_H_
6932 /*
6933 * Copyright (C) 2019 The Android Open Source Project
6934 *
6935 * Licensed under the Apache License, Version 2.0 (the "License");
6936 * you may not use this file except in compliance with the License.
6937 * You may obtain a copy of the License at
6938 *
6939 * http://www.apache.org/licenses/LICENSE-2.0
6940 *
6941 * Unless required by applicable law or agreed to in writing, software
6942 * distributed under the License is distributed on an "AS IS" BASIS,
6943 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6944 * See the License for the specific language governing permissions and
6945 * limitations under the License.
6946 */
6947
6948 // gen_amalgamated expanded: #include "perfetto/ext/base/waitable_event.h"
6949
6950 namespace perfetto {
6951 namespace base {
6952
6953 WaitableEvent::WaitableEvent() = default;
6954 WaitableEvent::~WaitableEvent() = default;
6955
Wait()6956 void WaitableEvent::Wait() {
6957 std::unique_lock<std::mutex> lock(mutex_);
6958 return event_.wait(lock, [this] { return notified_; });
6959 }
6960
Notify()6961 void WaitableEvent::Notify() {
6962 std::unique_lock<std::mutex> lock(mutex_);
6963 notified_ = true;
6964 event_.notify_all();
6965 }
6966
6967 } // namespace base
6968 } // namespace perfetto
6969 // gen_amalgamated begin source: src/base/watchdog_posix.cc
6970 // gen_amalgamated begin header: include/perfetto/ext/base/watchdog.h
6971 // gen_amalgamated begin header: include/perfetto/ext/base/watchdog_noop.h
6972 /*
6973 * Copyright (C) 2018 The Android Open Source Project
6974 *
6975 * Licensed under the Apache License, Version 2.0 (the "License");
6976 * you may not use this file except in compliance with the License.
6977 * You may obtain a copy of the License at
6978 *
6979 * http://www.apache.org/licenses/LICENSE-2.0
6980 *
6981 * Unless required by applicable law or agreed to in writing, software
6982 * distributed under the License is distributed on an "AS IS" BASIS,
6983 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6984 * See the License for the specific language governing permissions and
6985 * limitations under the License.
6986 */
6987
6988 #ifndef INCLUDE_PERFETTO_EXT_BASE_WATCHDOG_NOOP_H_
6989 #define INCLUDE_PERFETTO_EXT_BASE_WATCHDOG_NOOP_H_
6990
6991 #include <stdint.h>
6992
6993 namespace perfetto {
6994 namespace base {
6995
6996 enum class WatchdogCrashReason; // Defined in watchdog.h.
6997
6998 class Watchdog {
6999 public:
7000 class Timer {
7001 public:
7002 // Define an empty dtor to avoid "unused variable" errors on the call site.
Timer()7003 Timer() {}
Timer(const Timer &)7004 Timer(const Timer&) {}
~Timer()7005 ~Timer() {}
7006 };
GetInstance()7007 static Watchdog* GetInstance() {
7008 static Watchdog* watchdog = new Watchdog();
7009 return watchdog;
7010 }
CreateFatalTimer(uint32_t,WatchdogCrashReason)7011 Timer CreateFatalTimer(uint32_t /*ms*/, WatchdogCrashReason) {
7012 return Timer();
7013 }
Start()7014 void Start() {}
SetMemoryLimit(uint64_t,uint32_t)7015 void SetMemoryLimit(uint64_t /*bytes*/, uint32_t /*window_ms*/) {}
SetCpuLimit(uint32_t,uint32_t)7016 void SetCpuLimit(uint32_t /*percentage*/, uint32_t /*window_ms*/) {}
7017 };
7018
7019 } // namespace base
7020 } // namespace perfetto
7021
7022 #endif // INCLUDE_PERFETTO_EXT_BASE_WATCHDOG_NOOP_H_
7023 /*
7024 * Copyright (C) 2018 The Android Open Source Project
7025 *
7026 * Licensed under the Apache License, Version 2.0 (the "License");
7027 * you may not use this file except in compliance with the License.
7028 * You may obtain a copy of the License at
7029 *
7030 * http://www.apache.org/licenses/LICENSE-2.0
7031 *
7032 * Unless required by applicable law or agreed to in writing, software
7033 * distributed under the License is distributed on an "AS IS" BASIS,
7034 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
7035 * See the License for the specific language governing permissions and
7036 * limitations under the License.
7037 */
7038
7039 #ifndef INCLUDE_PERFETTO_EXT_BASE_WATCHDOG_H_
7040 #define INCLUDE_PERFETTO_EXT_BASE_WATCHDOG_H_
7041
7042 #include <functional>
7043
7044 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
7045
7046 // The POSIX watchdog is only supported on Linux and Android in non-embedder
7047 // builds.
7048 #if PERFETTO_BUILDFLAG(PERFETTO_WATCHDOG)
7049 // gen_amalgamated expanded: #include "perfetto/ext/base/watchdog_posix.h"
7050 #else
7051 // gen_amalgamated expanded: #include "perfetto/ext/base/watchdog_noop.h"
7052 #endif
7053
7054 namespace perfetto {
7055 namespace base {
7056
7057 // Used only to add more details to crash reporting.
7058 enum class WatchdogCrashReason {
7059 kUnspecified = 0,
7060 kCpuGuardrail = 1,
7061 kMemGuardrail = 2,
7062 kTaskRunnerHung = 3,
7063 kTraceDidntStop = 4,
7064 };
7065
7066 // Make the limits more relaxed on desktop, where multi-GB traces are likely.
7067 // Multi-GB traces can take bursts of cpu time to write into disk at the end of
7068 // the trace.
7069 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
7070 constexpr uint32_t kWatchdogDefaultCpuLimit = 75;
7071 constexpr uint32_t kWatchdogDefaultCpuWindow = 5 * 60 * 1000; // 5 minutes.
7072 #else
7073 constexpr uint32_t kWatchdogDefaultCpuLimit = 90;
7074 constexpr uint32_t kWatchdogDefaultCpuWindow = 10 * 60 * 1000; // 10 minutes.
7075 #endif
7076
7077 // The default memory margin we give to our processes. This is used as as a
7078 // constant to put on top of the trace buffers.
7079 constexpr uint64_t kWatchdogDefaultMemorySlack = 32 * 1024 * 1024; // 32 MiB.
7080 constexpr uint32_t kWatchdogDefaultMemoryWindow = 30 * 1000; // 30 seconds.
7081
RunTaskWithWatchdogGuard(const std::function<void ()> & task)7082 inline void RunTaskWithWatchdogGuard(const std::function<void()>& task) {
7083 // Maximum time a single task can take in a TaskRunner before the
7084 // program suicides.
7085 constexpr int64_t kWatchdogMillis = 30000; // 30s
7086
7087 Watchdog::Timer handle = base::Watchdog::GetInstance()->CreateFatalTimer(
7088 kWatchdogMillis, WatchdogCrashReason::kTaskRunnerHung);
7089 task();
7090
7091 // Suppress unused variable warnings in the client library amalgamated build.
7092 (void)kWatchdogDefaultCpuLimit;
7093 (void)kWatchdogDefaultCpuWindow;
7094 (void)kWatchdogDefaultMemorySlack;
7095 (void)kWatchdogDefaultMemoryWindow;
7096 }
7097
7098 } // namespace base
7099 } // namespace perfetto
7100
7101 #endif // INCLUDE_PERFETTO_EXT_BASE_WATCHDOG_H_
7102 /*
7103 * Copyright (C) 2018 The Android Open Source Project
7104 *
7105 * Licensed under the Apache License, Version 2.0 (the "License");
7106 * you may not use this file except in compliance with the License.
7107 * You may obtain a copy of the License at
7108 *
7109 * http://www.apache.org/licenses/LICENSE-2.0
7110 *
7111 * Unless required by applicable law or agreed to in writing, software
7112 * distributed under the License is distributed on an "AS IS" BASIS,
7113 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
7114 * See the License for the specific language governing permissions and
7115 * limitations under the License.
7116 */
7117
7118 // gen_amalgamated expanded: #include "perfetto/ext/base/watchdog.h"
7119
7120 #if PERFETTO_BUILDFLAG(PERFETTO_WATCHDOG)
7121
7122 #include <fcntl.h>
7123 #include <poll.h>
7124 #include <signal.h>
7125 #include <stdint.h>
7126 #include <stdlib.h>
7127 #include <sys/syscall.h>
7128 #include <sys/timerfd.h>
7129 #include <unistd.h>
7130
7131 #include <algorithm>
7132 #include <cinttypes>
7133 #include <fstream>
7134 #include <thread>
7135
7136 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
7137 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
7138 // gen_amalgamated expanded: #include "perfetto/base/thread_utils.h"
7139 // gen_amalgamated expanded: #include "perfetto/base/time.h"
7140 // gen_amalgamated expanded: #include "perfetto/ext/base/crash_keys.h"
7141 // gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
7142 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
7143 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
7144
7145 namespace perfetto {
7146 namespace base {
7147
7148 namespace {
7149
7150 constexpr uint32_t kDefaultPollingInterval = 30 * 1000;
7151
7152 base::CrashKey g_crash_key_reason("wdog_reason");
7153
7154 // TODO(primiano): for debugging b/191600928. Remove in Jan 2022.
7155 base::CrashKey g_crash_key_mono("wdog_mono");
7156 base::CrashKey g_crash_key_boot("wdog_boot");
7157
IsMultipleOf(uint32_t number,uint32_t divisor)7158 bool IsMultipleOf(uint32_t number, uint32_t divisor) {
7159 return number >= divisor && number % divisor == 0;
7160 }
7161
MeanForArray(const uint64_t array[],size_t size)7162 double MeanForArray(const uint64_t array[], size_t size) {
7163 uint64_t total = 0;
7164 for (size_t i = 0; i < size; i++) {
7165 total += array[i];
7166 }
7167 return static_cast<double>(total / size);
7168 }
7169
7170 } // namespace
7171
ReadProcStat(int fd,ProcStat * out)7172 bool ReadProcStat(int fd, ProcStat* out) {
7173 char c[512];
7174 size_t c_pos = 0;
7175 while (c_pos < sizeof(c) - 1) {
7176 ssize_t rd = PERFETTO_EINTR(read(fd, c + c_pos, sizeof(c) - c_pos));
7177 if (rd < 0) {
7178 PERFETTO_ELOG("Failed to read stat file to enforce resource limits.");
7179 return false;
7180 }
7181 if (rd == 0)
7182 break;
7183 c_pos += static_cast<size_t>(rd);
7184 }
7185 PERFETTO_CHECK(c_pos < sizeof(c));
7186 c[c_pos] = '\0';
7187
7188 if (sscanf(c,
7189 "%*d %*s %*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u %lu "
7190 "%lu %*d %*d %*d %*d %*d %*d %*u %*u %ld",
7191 &out->utime, &out->stime, &out->rss_pages) != 3) {
7192 PERFETTO_ELOG("Invalid stat format: %s", c);
7193 return false;
7194 }
7195 return true;
7196 }
7197
Watchdog(uint32_t polling_interval_ms)7198 Watchdog::Watchdog(uint32_t polling_interval_ms)
7199 : polling_interval_ms_(polling_interval_ms) {}
7200
~Watchdog()7201 Watchdog::~Watchdog() {
7202 if (!thread_.joinable()) {
7203 PERFETTO_DCHECK(!enabled_);
7204 return;
7205 }
7206 PERFETTO_DCHECK(enabled_);
7207 enabled_ = false;
7208
7209 // Rearm the timer to 1ns from now. This will cause the watchdog thread to
7210 // wakeup from the poll() and see |enabled_| == false.
7211 // This code path is used only in tests. In production code the watchdog is
7212 // a singleton and is never destroyed.
7213 struct itimerspec ts {};
7214 ts.it_value.tv_sec = 0;
7215 ts.it_value.tv_nsec = 1;
7216 timerfd_settime(*timer_fd_, /*flags=*/0, &ts, nullptr);
7217
7218 thread_.join();
7219 }
7220
GetInstance()7221 Watchdog* Watchdog::GetInstance() {
7222 static Watchdog* watchdog = new Watchdog(kDefaultPollingInterval);
7223 return watchdog;
7224 }
7225
7226 // Can be called from any thread.
CreateFatalTimer(uint32_t ms,WatchdogCrashReason crash_reason)7227 Watchdog::Timer Watchdog::CreateFatalTimer(uint32_t ms,
7228 WatchdogCrashReason crash_reason) {
7229 if (!enabled_.load(std::memory_order_relaxed))
7230 return Watchdog::Timer(this, 0, crash_reason);
7231
7232 return Watchdog::Timer(this, ms, crash_reason);
7233 }
7234
7235 // Can be called from any thread.
AddFatalTimer(TimerData timer)7236 void Watchdog::AddFatalTimer(TimerData timer) {
7237 std::lock_guard<std::mutex> guard(mutex_);
7238 timers_.emplace_back(std::move(timer));
7239 RearmTimerFd_Locked();
7240 }
7241
7242 // Can be called from any thread.
RemoveFatalTimer(TimerData timer)7243 void Watchdog::RemoveFatalTimer(TimerData timer) {
7244 std::lock_guard<std::mutex> guard(mutex_);
7245 for (auto it = timers_.begin(); it != timers_.end(); it++) {
7246 if (*it == timer) {
7247 timers_.erase(it);
7248 break; // Remove only one. Doesn't matter which one.
7249 }
7250 }
7251 RearmTimerFd_Locked();
7252 }
7253
RearmTimerFd_Locked()7254 void Watchdog::RearmTimerFd_Locked() {
7255 if (!enabled_)
7256 return;
7257 auto it = std::min_element(timers_.begin(), timers_.end());
7258
7259 // We use one timerfd to handle all the oustanding |timers_|. Keep it armed
7260 // to the task expiring soonest.
7261 struct itimerspec ts {};
7262 if (it != timers_.end()) {
7263 ts.it_value = ToPosixTimespec(it->deadline);
7264 }
7265 // If |timers_| is empty (it == end()) |ts.it_value| will remain
7266 // zero-initialized and that will disarm the timer in the call below.
7267 int res = timerfd_settime(*timer_fd_, TFD_TIMER_ABSTIME, &ts, nullptr);
7268 PERFETTO_DCHECK(res == 0);
7269 }
7270
Start()7271 void Watchdog::Start() {
7272 std::lock_guard<std::mutex> guard(mutex_);
7273 if (thread_.joinable()) {
7274 PERFETTO_DCHECK(enabled_);
7275 } else {
7276 PERFETTO_DCHECK(!enabled_);
7277
7278 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
7279 PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
7280 // Kick the thread to start running but only on Android or Linux.
7281 timer_fd_.reset(
7282 timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK));
7283 if (!timer_fd_) {
7284 PERFETTO_PLOG(
7285 "timerfd_create failed, the Perfetto watchdog is not available");
7286 return;
7287 }
7288 enabled_ = true;
7289 RearmTimerFd_Locked(); // Deal with timers created before Start().
7290 thread_ = std::thread(&Watchdog::ThreadMain, this);
7291 #endif
7292 }
7293 }
7294
SetMemoryLimit(uint64_t bytes,uint32_t window_ms)7295 void Watchdog::SetMemoryLimit(uint64_t bytes, uint32_t window_ms) {
7296 // Update the fields under the lock.
7297 std::lock_guard<std::mutex> guard(mutex_);
7298
7299 PERFETTO_CHECK(IsMultipleOf(window_ms, polling_interval_ms_) || bytes == 0);
7300
7301 size_t size = bytes == 0 ? 0 : window_ms / polling_interval_ms_ + 1;
7302 memory_window_bytes_.Reset(size);
7303 memory_limit_bytes_ = bytes;
7304 }
7305
SetCpuLimit(uint32_t percentage,uint32_t window_ms)7306 void Watchdog::SetCpuLimit(uint32_t percentage, uint32_t window_ms) {
7307 std::lock_guard<std::mutex> guard(mutex_);
7308
7309 PERFETTO_CHECK(percentage <= 100);
7310 PERFETTO_CHECK(IsMultipleOf(window_ms, polling_interval_ms_) ||
7311 percentage == 0);
7312
7313 size_t size = percentage == 0 ? 0 : window_ms / polling_interval_ms_ + 1;
7314 cpu_window_time_ticks_.Reset(size);
7315 cpu_limit_percentage_ = percentage;
7316 }
7317
ThreadMain()7318 void Watchdog::ThreadMain() {
7319 // Register crash keys explicitly to avoid running out of slots at crash time.
7320 g_crash_key_reason.Register();
7321 g_crash_key_boot.Register();
7322 g_crash_key_mono.Register();
7323
7324 base::ScopedFile stat_fd(base::OpenFile("/proc/self/stat", O_RDONLY));
7325 if (!stat_fd) {
7326 PERFETTO_ELOG("Failed to open stat file to enforce resource limits.");
7327 return;
7328 }
7329
7330 PERFETTO_DCHECK(timer_fd_);
7331
7332 constexpr uint8_t kFdCount = 1;
7333 struct pollfd fds[kFdCount]{};
7334 fds[0].fd = *timer_fd_;
7335 fds[0].events = POLLIN;
7336
7337 for (;;) {
7338 // We use the poll() timeout to drive the periodic ticks for the cpu/memory
7339 // checks. The only other case when the poll() unblocks is when we crash
7340 // (or have to quit via enabled_ == false, but that happens only in tests).
7341 auto ret = poll(fds, kFdCount, static_cast<int>(polling_interval_ms_));
7342 if (!enabled_)
7343 return;
7344 if (ret < 0) {
7345 if (errno == ENOMEM || errno == EINTR) {
7346 // Should happen extremely rarely.
7347 std::this_thread::sleep_for(std::chrono::milliseconds(100));
7348 continue;
7349 }
7350 PERFETTO_FATAL("watchdog poll() failed");
7351 }
7352
7353 // If we get here either:
7354 // 1. poll() timed out, in which case we should process cpu/mem guardrails.
7355 // 2. A timer expired, in which case we shall crash.
7356
7357 uint64_t expired = 0; // Must be exactly 8 bytes.
7358 auto res = PERFETTO_EINTR(read(*timer_fd_, &expired, sizeof(expired)));
7359 PERFETTO_DCHECK((res < 0 && (errno == EAGAIN)) ||
7360 (res == sizeof(expired) && expired > 0));
7361 const auto now = GetWallTimeMs();
7362
7363 // Check if any of the timers expired.
7364 int tid_to_kill = 0;
7365 WatchdogCrashReason crash_reason{};
7366 std::unique_lock<std::mutex> guard(mutex_);
7367 for (const auto& timer : timers_) {
7368 if (now >= timer.deadline) {
7369 tid_to_kill = timer.thread_id;
7370 crash_reason = timer.crash_reason;
7371 break;
7372 }
7373 }
7374 guard.unlock();
7375
7376 if (tid_to_kill)
7377 SerializeLogsAndKillThread(tid_to_kill, crash_reason);
7378
7379 // Check CPU and memory guardrails (if enabled).
7380 lseek(stat_fd.get(), 0, SEEK_SET);
7381 ProcStat stat;
7382 if (!ReadProcStat(stat_fd.get(), &stat))
7383 continue;
7384 uint64_t cpu_time = stat.utime + stat.stime;
7385 uint64_t rss_bytes =
7386 static_cast<uint64_t>(stat.rss_pages) * base::GetSysPageSize();
7387
7388 bool threshold_exceeded = false;
7389 guard.lock();
7390 if (CheckMemory_Locked(rss_bytes)) {
7391 threshold_exceeded = true;
7392 crash_reason = WatchdogCrashReason::kMemGuardrail;
7393 } else if (CheckCpu_Locked(cpu_time)) {
7394 threshold_exceeded = true;
7395 crash_reason = WatchdogCrashReason::kCpuGuardrail;
7396 }
7397 guard.unlock();
7398
7399 if (threshold_exceeded)
7400 SerializeLogsAndKillThread(getpid(), crash_reason);
7401 }
7402 }
7403
SerializeLogsAndKillThread(int tid,WatchdogCrashReason crash_reason)7404 void Watchdog::SerializeLogsAndKillThread(int tid,
7405 WatchdogCrashReason crash_reason) {
7406 g_crash_key_reason.Set(static_cast<int>(crash_reason));
7407 g_crash_key_boot.Set(base::GetBootTimeS().count());
7408 g_crash_key_mono.Set(base::GetWallTimeS().count());
7409
7410 // We are about to die. Serialize the logs into the crash buffer so the
7411 // debuggerd crash handler picks them up and attaches to the bugreport.
7412 // In the case of a PERFETTO_CHECK/PERFETTO_FATAL this is done in logging.h.
7413 // But in the watchdog case, we don't hit that codepath and must do ourselves.
7414 MaybeSerializeLastLogsForCrashReporting();
7415
7416 // Send a SIGABRT to the thread that armed the timer. This is to see the
7417 // callstack of the thread that is stuck in a long task rather than the
7418 // watchdog thread.
7419 if (syscall(__NR_tgkill, getpid(), tid, SIGABRT) < 0) {
7420 // At this point the process must die. If for any reason the tgkill doesn't
7421 // work (e.g. the thread has disappeared), force a crash from here.
7422 abort();
7423 }
7424
7425 if (disable_kill_failsafe_for_testing_)
7426 return;
7427
7428 // The tgkill() above will take some milliseconds to cause a crash, as it
7429 // involves the kernel to queue the SIGABRT on the target thread (often the
7430 // main thread, which is != watchdog thread) and do a scheduling round.
7431 // If something goes wrong though (the target thread has signals masked or
7432 // is stuck in an uninterruptible+wakekill syscall) force quit from this
7433 // thread.
7434 std::this_thread::sleep_for(std::chrono::seconds(10));
7435 abort();
7436 }
7437
CheckMemory_Locked(uint64_t rss_bytes)7438 bool Watchdog::CheckMemory_Locked(uint64_t rss_bytes) {
7439 if (memory_limit_bytes_ == 0)
7440 return false;
7441
7442 // Add the current stat value to the ring buffer and check that the mean
7443 // remains under our threshold.
7444 if (memory_window_bytes_.Push(rss_bytes)) {
7445 if (memory_window_bytes_.Mean() >
7446 static_cast<double>(memory_limit_bytes_)) {
7447 PERFETTO_ELOG(
7448 "Memory watchdog trigger. Memory window of %f bytes is above the "
7449 "%" PRIu64 " bytes limit.",
7450 memory_window_bytes_.Mean(), memory_limit_bytes_);
7451 return true;
7452 }
7453 }
7454 return false;
7455 }
7456
CheckCpu_Locked(uint64_t cpu_time)7457 bool Watchdog::CheckCpu_Locked(uint64_t cpu_time) {
7458 if (cpu_limit_percentage_ == 0)
7459 return false;
7460
7461 // Add the cpu time to the ring buffer.
7462 if (cpu_window_time_ticks_.Push(cpu_time)) {
7463 // Compute the percentage over the whole window and check that it remains
7464 // under the threshold.
7465 uint64_t difference_ticks = cpu_window_time_ticks_.NewestWhenFull() -
7466 cpu_window_time_ticks_.OldestWhenFull();
7467 double window_interval_ticks =
7468 (static_cast<double>(WindowTimeForRingBuffer(cpu_window_time_ticks_)) /
7469 1000.0) *
7470 static_cast<double>(sysconf(_SC_CLK_TCK));
7471 double percentage = static_cast<double>(difference_ticks) /
7472 static_cast<double>(window_interval_ticks) * 100;
7473 if (percentage > cpu_limit_percentage_) {
7474 PERFETTO_ELOG("CPU watchdog trigger. %f%% CPU use is above the %" PRIu32
7475 "%% CPU limit.",
7476 percentage, cpu_limit_percentage_);
7477 return true;
7478 }
7479 }
7480 return false;
7481 }
7482
WindowTimeForRingBuffer(const WindowedInterval & window)7483 uint32_t Watchdog::WindowTimeForRingBuffer(const WindowedInterval& window) {
7484 return static_cast<uint32_t>(window.size() - 1) * polling_interval_ms_;
7485 }
7486
Push(uint64_t sample)7487 bool Watchdog::WindowedInterval::Push(uint64_t sample) {
7488 // Add the sample to the current position in the ring buffer.
7489 buffer_[position_] = sample;
7490
7491 // Update the position with next one circularily.
7492 position_ = (position_ + 1) % size_;
7493
7494 // Set the filled flag the first time we wrap.
7495 filled_ = filled_ || position_ == 0;
7496 return filled_;
7497 }
7498
Mean() const7499 double Watchdog::WindowedInterval::Mean() const {
7500 return MeanForArray(buffer_.get(), size_);
7501 }
7502
Clear()7503 void Watchdog::WindowedInterval::Clear() {
7504 position_ = 0;
7505 buffer_.reset(new uint64_t[size_]());
7506 }
7507
Reset(size_t new_size)7508 void Watchdog::WindowedInterval::Reset(size_t new_size) {
7509 position_ = 0;
7510 size_ = new_size;
7511 buffer_.reset(new_size == 0 ? nullptr : new uint64_t[new_size]());
7512 }
7513
Timer(Watchdog * watchdog,uint32_t ms,WatchdogCrashReason crash_reason)7514 Watchdog::Timer::Timer(Watchdog* watchdog,
7515 uint32_t ms,
7516 WatchdogCrashReason crash_reason)
7517 : watchdog_(watchdog) {
7518 if (!ms)
7519 return; // No-op timer created when the watchdog is disabled.
7520 timer_data_.deadline = GetWallTimeMs() + std::chrono::milliseconds(ms);
7521 timer_data_.thread_id = GetThreadId();
7522 timer_data_.crash_reason = crash_reason;
7523 PERFETTO_DCHECK(watchdog_);
7524 watchdog_->AddFatalTimer(timer_data_);
7525 }
7526
~Timer()7527 Watchdog::Timer::~Timer() {
7528 if (timer_data_.deadline.count())
7529 watchdog_->RemoveFatalTimer(timer_data_);
7530 }
7531
Timer(Timer && other)7532 Watchdog::Timer::Timer(Timer&& other) noexcept {
7533 watchdog_ = std::move(other.watchdog_);
7534 other.watchdog_ = nullptr;
7535 timer_data_ = std::move(other.timer_data_);
7536 other.timer_data_ = TimerData();
7537 }
7538
7539 } // namespace base
7540 } // namespace perfetto
7541
7542 #endif // PERFETTO_BUILDFLAG(PERFETTO_WATCHDOG)
7543 // gen_amalgamated begin source: src/base/thread_task_runner.cc
7544 // gen_amalgamated begin header: include/perfetto/ext/base/thread_task_runner.h
7545 // gen_amalgamated begin header: include/perfetto/ext/base/unix_task_runner.h
7546 /*
7547 * Copyright (C) 2017 The Android Open Source Project
7548 *
7549 * Licensed under the Apache License, Version 2.0 (the "License");
7550 * you may not use this file except in compliance with the License.
7551 * You may obtain a copy of the License at
7552 *
7553 * http://www.apache.org/licenses/LICENSE-2.0
7554 *
7555 * Unless required by applicable law or agreed to in writing, software
7556 * distributed under the License is distributed on an "AS IS" BASIS,
7557 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
7558 * See the License for the specific language governing permissions and
7559 * limitations under the License.
7560 */
7561
7562 #ifndef INCLUDE_PERFETTO_EXT_BASE_UNIX_TASK_RUNNER_H_
7563 #define INCLUDE_PERFETTO_EXT_BASE_UNIX_TASK_RUNNER_H_
7564
7565 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
7566 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
7567 // gen_amalgamated expanded: #include "perfetto/base/thread_utils.h"
7568 // gen_amalgamated expanded: #include "perfetto/base/time.h"
7569 // gen_amalgamated expanded: #include "perfetto/ext/base/event_fd.h"
7570 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
7571 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_checker.h"
7572
7573 #include <chrono>
7574 #include <deque>
7575 #include <map>
7576 #include <mutex>
7577 #include <vector>
7578
7579 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
7580 #include <poll.h>
7581 #endif
7582
7583 namespace perfetto {
7584 namespace base {
7585
7586 // Runs a task runner on the current thread.
7587 //
7588 // Implementation note: we currently assume (and enforce in debug builds) that
7589 // Run() is called from the thread that constructed the UnixTaskRunner. This is
7590 // not strictly necessary, and we could instead track the thread that invokes
7591 // Run(). However, a related property that *might* be important to enforce is
7592 // that the destructor runs on the task-running thread. Otherwise, if there are
7593 // still-pending tasks at the time of destruction, we would destroy those
7594 // outside of the task thread (which might be unexpected to the caller). On the
7595 // other hand, the std::function task interface discourages use of any
7596 // resource-owning tasks (as the callable needs to be copyable), so this might
7597 // not be important in practice.
7598 //
7599 // TODO(rsavitski): consider adding a thread-check in the destructor, after
7600 // auditing existing usages.
7601 // TODO(primiano): rename this to TaskRunnerImpl. The "Unix" part is misleading
7602 // now as it supports also Windows.
7603 class UnixTaskRunner : public TaskRunner {
7604 public:
7605 UnixTaskRunner();
7606 ~UnixTaskRunner() override;
7607
7608 // Start executing tasks. Doesn't return until Quit() is called. Run() may be
7609 // called multiple times on the same task runner.
7610 void Run();
7611 void Quit();
7612
7613 // Checks whether there are any pending immediate tasks to run. Note that
7614 // delayed tasks don't count even if they are due to run.
7615 bool IsIdleForTesting();
7616
7617 // TaskRunner implementation:
7618 void PostTask(std::function<void()>) override;
7619 void PostDelayedTask(std::function<void()>, uint32_t delay_ms) override;
7620 void AddFileDescriptorWatch(PlatformHandle, std::function<void()>) override;
7621 void RemoveFileDescriptorWatch(PlatformHandle) override;
7622 bool RunsTasksOnCurrentThread() const override;
7623
7624 // Returns true if the task runner is quitting, or has quit and hasn't been
7625 // restarted since. Exposed primarily for ThreadTaskRunner, not necessary for
7626 // normal use of this class.
7627 bool QuitCalled();
7628
7629 private:
7630 void WakeUp();
7631 void UpdateWatchTasksLocked();
7632 int GetDelayMsToNextTaskLocked() const;
7633 void RunImmediateAndDelayedTask();
7634 void PostFileDescriptorWatches(uint64_t windows_wait_result);
7635 void RunFileDescriptorWatch(PlatformHandle);
7636
7637 ThreadChecker thread_checker_;
7638 PlatformThreadId created_thread_id_ = GetThreadId();
7639
7640 EventFd event_;
7641
7642 // The array of fds/handles passed to poll(2) / WaitForMultipleObjects().
7643 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
7644 std::vector<PlatformHandle> poll_fds_;
7645 #else
7646 std::vector<struct pollfd> poll_fds_;
7647 #endif
7648
7649 // --- Begin lock-protected members ---
7650
7651 std::mutex lock_;
7652
7653 std::deque<std::function<void()>> immediate_tasks_;
7654 std::multimap<TimeMillis, std::function<void()>> delayed_tasks_;
7655 bool quit_ = false;
7656
7657 struct WatchTask {
7658 std::function<void()> callback;
7659 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
7660 // On UNIX systems we make the FD number negative in |poll_fds_| to avoid
7661 // polling it again until the queued task runs. On Windows we can't do that.
7662 // Instead we keep track of its state here.
7663 bool pending = false;
7664 #else
7665 size_t poll_fd_index; // Index into |poll_fds_|.
7666 #endif
7667 };
7668
7669 std::map<PlatformHandle, WatchTask> watch_tasks_;
7670 bool watch_tasks_changed_ = false;
7671
7672 // --- End lock-protected members ---
7673 };
7674
7675 } // namespace base
7676 } // namespace perfetto
7677
7678 #endif // INCLUDE_PERFETTO_EXT_BASE_UNIX_TASK_RUNNER_H_
7679 /*
7680 * Copyright (C) 2019 The Android Open Source Project
7681 *
7682 * Licensed under the Apache License, Version 2.0 (the "License");
7683 * you may not use this file except in compliance with the License.
7684 * You may obtain a copy of the License at
7685 *
7686 * http://www.apache.org/licenses/LICENSE-2.0
7687 *
7688 * Unless required by applicable law or agreed to in writing, software
7689 * distributed under the License is distributed on an "AS IS" BASIS,
7690 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
7691 * See the License for the specific language governing permissions and
7692 * limitations under the License.
7693 */
7694
7695 #ifndef INCLUDE_PERFETTO_EXT_BASE_THREAD_TASK_RUNNER_H_
7696 #define INCLUDE_PERFETTO_EXT_BASE_THREAD_TASK_RUNNER_H_
7697
7698 #include <functional>
7699 #include <thread>
7700
7701 // gen_amalgamated expanded: #include "perfetto/ext/base/unix_task_runner.h"
7702
7703 namespace perfetto {
7704 namespace base {
7705
7706 // A UnixTaskRunner backed by a dedicated task thread. Shuts down the runner and
7707 // joins the thread upon destruction. Can be moved to transfer ownership.
7708 //
7709 // Guarantees that:
7710 // * the UnixTaskRunner will be constructed and destructed on the task thread.
7711 // * the task thread will live for the lifetime of the UnixTaskRunner.
7712 //
7713 class PERFETTO_EXPORT ThreadTaskRunner : public TaskRunner {
7714 public:
CreateAndStart(const std::string & name="")7715 static ThreadTaskRunner CreateAndStart(const std::string& name = "") {
7716 return ThreadTaskRunner(name);
7717 }
7718
7719 ThreadTaskRunner(const ThreadTaskRunner&) = delete;
7720 ThreadTaskRunner& operator=(const ThreadTaskRunner&) = delete;
7721
7722 ThreadTaskRunner(ThreadTaskRunner&&) noexcept;
7723 ThreadTaskRunner& operator=(ThreadTaskRunner&&);
7724 ~ThreadTaskRunner() override;
7725
7726 // Executes the given function on the task runner thread and blocks the caller
7727 // thread until the function has run.
7728 void PostTaskAndWaitForTesting(std::function<void()>);
7729
7730 // Can be called from another thread to get the CPU time of the thread the
7731 // task-runner is executing on.
7732 uint64_t GetThreadCPUTimeNsForTesting();
7733
7734 // Returns a pointer to the UnixTaskRunner, which is valid for the lifetime of
7735 // this ThreadTaskRunner object (unless this object is moved-from, in which
7736 // case the pointer remains valid for the lifetime of the new owning
7737 // ThreadTaskRunner).
7738 //
7739 // Warning: do not call Quit() on the returned runner pointer, the termination
7740 // should be handled exclusively by this class' destructor.
get() const7741 UnixTaskRunner* get() const { return task_runner_; }
7742
7743 // TaskRunner implementation.
7744 // These methods just proxy to the underlying task_runner_.
7745 void PostTask(std::function<void()>) override;
7746 void PostDelayedTask(std::function<void()>, uint32_t delay_ms) override;
7747 void AddFileDescriptorWatch(PlatformHandle, std::function<void()>) override;
7748 void RemoveFileDescriptorWatch(PlatformHandle) override;
7749 bool RunsTasksOnCurrentThread() const override;
7750
7751 private:
7752 explicit ThreadTaskRunner(const std::string& name);
7753 void RunTaskThread(std::function<void(UnixTaskRunner*)> initializer);
7754
7755 std::thread thread_;
7756 std::string name_;
7757 UnixTaskRunner* task_runner_ = nullptr;
7758 };
7759
7760 } // namespace base
7761 } // namespace perfetto
7762
7763 #endif // INCLUDE_PERFETTO_EXT_BASE_THREAD_TASK_RUNNER_H_
7764 // gen_amalgamated begin header: include/perfetto/ext/base/thread_utils.h
7765 /*
7766 * Copyright (C) 2020 The Android Open Source Project
7767 *
7768 * Licensed under the Apache License, Version 2.0 (the "License");
7769 * you may not use this file except in compliance with the License.
7770 * You may obtain a copy of the License at
7771 *
7772 * http://www.apache.org/licenses/LICENSE-2.0
7773 *
7774 * Unless required by applicable law or agreed to in writing, software
7775 * distributed under the License is distributed on an "AS IS" BASIS,
7776 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
7777 * See the License for the specific language governing permissions and
7778 * limitations under the License.
7779 */
7780
7781 #ifndef INCLUDE_PERFETTO_EXT_BASE_THREAD_UTILS_H_
7782 #define INCLUDE_PERFETTO_EXT_BASE_THREAD_UTILS_H_
7783
7784 #include <string>
7785
7786 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
7787 // gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
7788
7789 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
7790 PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
7791 PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
7792 #include <pthread.h>
7793 #include <string.h>
7794 #include <algorithm>
7795 #endif
7796
7797 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
7798 #include <sys/prctl.h>
7799 #endif
7800
7801 // Internal implementation utils that aren't as widely useful/supported as
7802 // base/thread_utils.h.
7803
7804 namespace perfetto {
7805 namespace base {
7806
7807 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
7808 PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
7809 PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
7810 // Sets the "comm" of the calling thread to the first 15 chars of the given
7811 // string.
MaybeSetThreadName(const std::string & name)7812 inline bool MaybeSetThreadName(const std::string& name) {
7813 char buf[16] = {};
7814 StringCopy(buf, name.c_str(), sizeof(buf));
7815
7816 #if PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
7817 return pthread_setname_np(buf) == 0;
7818 #else
7819 return pthread_setname_np(pthread_self(), buf) == 0;
7820 #endif
7821 }
7822
GetThreadName(std::string & out_result)7823 inline bool GetThreadName(std::string& out_result) {
7824 char buf[16] = {};
7825 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
7826 if (prctl(PR_GET_NAME, buf) != 0)
7827 return false;
7828 #else
7829 if (pthread_getname_np(pthread_self(), buf, sizeof(buf)) != 0)
7830 return false;
7831 #endif
7832 out_result = std::string(buf);
7833 return true;
7834 }
7835
7836 #else
7837 inline bool MaybeSetThreadName(const std::string&) {
7838 return false;
7839 }
7840 inline bool GetThreadName(std::string&) {
7841 return false;
7842 }
7843 #endif
7844
7845 } // namespace base
7846 } // namespace perfetto
7847
7848 #endif // INCLUDE_PERFETTO_EXT_BASE_THREAD_UTILS_H_
7849 /*
7850 * Copyright (C) 2019 The Android Open Source Project
7851 *
7852 * Licensed under the Apache License, Version 2.0 (the "License");
7853 * you may not use this file except in compliance with the License.
7854 * You may obtain a copy of the License at
7855 *
7856 * http://www.apache.org/licenses/LICENSE-2.0
7857 *
7858 * Unless required by applicable law or agreed to in writing, software
7859 * distributed under the License is distributed on an "AS IS" BASIS,
7860 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
7861 * See the License for the specific language governing permissions and
7862 * limitations under the License.
7863 */
7864
7865 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
7866
7867 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_task_runner.h"
7868
7869 #include <condition_variable>
7870 #include <functional>
7871 #include <mutex>
7872 #include <thread>
7873
7874 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
7875 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_utils.h"
7876 // gen_amalgamated expanded: #include "perfetto/ext/base/unix_task_runner.h"
7877
7878 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
7879 PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
7880 #include <sys/prctl.h>
7881 #endif
7882
7883 namespace perfetto {
7884 namespace base {
7885
ThreadTaskRunner(ThreadTaskRunner && other)7886 ThreadTaskRunner::ThreadTaskRunner(ThreadTaskRunner&& other) noexcept
7887 : thread_(std::move(other.thread_)), task_runner_(other.task_runner_) {
7888 other.task_runner_ = nullptr;
7889 }
7890
operator =(ThreadTaskRunner && other)7891 ThreadTaskRunner& ThreadTaskRunner::operator=(ThreadTaskRunner&& other) {
7892 this->~ThreadTaskRunner();
7893 new (this) ThreadTaskRunner(std::move(other));
7894 return *this;
7895 }
7896
~ThreadTaskRunner()7897 ThreadTaskRunner::~ThreadTaskRunner() {
7898 if (task_runner_) {
7899 PERFETTO_CHECK(!task_runner_->QuitCalled());
7900 task_runner_->Quit();
7901
7902 PERFETTO_DCHECK(thread_.joinable());
7903 }
7904 if (thread_.joinable())
7905 thread_.join();
7906 }
7907
ThreadTaskRunner(const std::string & name)7908 ThreadTaskRunner::ThreadTaskRunner(const std::string& name) : name_(name) {
7909 std::mutex init_lock;
7910 std::condition_variable init_cv;
7911
7912 std::function<void(UnixTaskRunner*)> initializer =
7913 [this, &init_lock, &init_cv](UnixTaskRunner* task_runner) {
7914 std::lock_guard<std::mutex> lock(init_lock);
7915 task_runner_ = task_runner;
7916 // Notify while still holding the lock, as init_cv ceases to exist as
7917 // soon as the main thread observes a non-null task_runner_, and it can
7918 // wake up spuriously (i.e. before the notify if we had unlocked before
7919 // notifying).
7920 init_cv.notify_one();
7921 };
7922
7923 thread_ = std::thread(&ThreadTaskRunner::RunTaskThread, this,
7924 std::move(initializer));
7925
7926 std::unique_lock<std::mutex> lock(init_lock);
7927 init_cv.wait(lock, [this] { return !!task_runner_; });
7928 }
7929
RunTaskThread(std::function<void (UnixTaskRunner *)> initializer)7930 void ThreadTaskRunner::RunTaskThread(
7931 std::function<void(UnixTaskRunner*)> initializer) {
7932 if (!name_.empty()) {
7933 base::MaybeSetThreadName(name_);
7934 }
7935
7936 UnixTaskRunner task_runner;
7937 task_runner.PostTask(std::bind(std::move(initializer), &task_runner));
7938 task_runner.Run();
7939 }
7940
PostTaskAndWaitForTesting(std::function<void ()> fn)7941 void ThreadTaskRunner::PostTaskAndWaitForTesting(std::function<void()> fn) {
7942 std::mutex mutex;
7943 std::condition_variable cv;
7944
7945 std::unique_lock<std::mutex> lock(mutex);
7946 bool done = false;
7947 task_runner_->PostTask([&mutex, &cv, &done, &fn] {
7948 fn();
7949
7950 std::lock_guard<std::mutex> inner_lock(mutex);
7951 done = true;
7952 cv.notify_one();
7953 });
7954 cv.wait(lock, [&done] { return done; });
7955 }
7956
GetThreadCPUTimeNsForTesting()7957 uint64_t ThreadTaskRunner::GetThreadCPUTimeNsForTesting() {
7958 uint64_t thread_time_ns = 0;
7959 PostTaskAndWaitForTesting([&thread_time_ns] {
7960 thread_time_ns = static_cast<uint64_t>(base::GetThreadCPUTimeNs().count());
7961 });
7962 return thread_time_ns;
7963 }
7964
PostTask(std::function<void ()> task)7965 void ThreadTaskRunner::PostTask(std::function<void()> task) {
7966 task_runner_->PostTask(std::move(task));
7967 }
7968
PostDelayedTask(std::function<void ()> task,uint32_t delay_ms)7969 void ThreadTaskRunner::PostDelayedTask(std::function<void()> task,
7970 uint32_t delay_ms) {
7971 task_runner_->PostDelayedTask(std::move(task), delay_ms);
7972 }
7973
AddFileDescriptorWatch(PlatformHandle handle,std::function<void ()> watch_task)7974 void ThreadTaskRunner::AddFileDescriptorWatch(
7975 PlatformHandle handle,
7976 std::function<void()> watch_task) {
7977 task_runner_->AddFileDescriptorWatch(handle, std::move(watch_task));
7978 }
7979
RemoveFileDescriptorWatch(PlatformHandle handle)7980 void ThreadTaskRunner::RemoveFileDescriptorWatch(PlatformHandle handle) {
7981 task_runner_->RemoveFileDescriptorWatch(handle);
7982 }
7983
RunsTasksOnCurrentThread() const7984 bool ThreadTaskRunner::RunsTasksOnCurrentThread() const {
7985 return task_runner_->RunsTasksOnCurrentThread();
7986 }
7987
7988 } // namespace base
7989 } // namespace perfetto
7990 // gen_amalgamated begin source: src/base/unix_task_runner.cc
7991 /*
7992 * Copyright (C) 2017 The Android Open Source Project
7993 *
7994 * Licensed under the Apache License, Version 2.0 (the "License");
7995 * you may not use this file except in compliance with the License.
7996 * You may obtain a copy of the License at
7997 *
7998 * http://www.apache.org/licenses/LICENSE-2.0
7999 *
8000 * Unless required by applicable law or agreed to in writing, software
8001 * distributed under the License is distributed on an "AS IS" BASIS,
8002 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8003 * See the License for the specific language governing permissions and
8004 * limitations under the License.
8005 */
8006
8007 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
8008
8009 // gen_amalgamated expanded: #include "perfetto/ext/base/unix_task_runner.h"
8010
8011 #include <errno.h>
8012 #include <stdlib.h>
8013
8014 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
8015 #include <Windows.h>
8016 #include <synchapi.h>
8017 #else
8018 #include <unistd.h>
8019 #endif
8020
8021 #include <algorithm>
8022 #include <limits>
8023
8024 // gen_amalgamated expanded: #include "perfetto/ext/base/watchdog.h"
8025
8026 namespace perfetto {
8027 namespace base {
8028
UnixTaskRunner()8029 UnixTaskRunner::UnixTaskRunner() {
8030 AddFileDescriptorWatch(event_.fd(), [] {
8031 // Not reached -- see PostFileDescriptorWatches().
8032 PERFETTO_DFATAL("Should be unreachable.");
8033 });
8034 }
8035
8036 UnixTaskRunner::~UnixTaskRunner() = default;
8037
WakeUp()8038 void UnixTaskRunner::WakeUp() {
8039 event_.Notify();
8040 }
8041
Run()8042 void UnixTaskRunner::Run() {
8043 PERFETTO_DCHECK_THREAD(thread_checker_);
8044 created_thread_id_ = GetThreadId();
8045 quit_ = false;
8046 for (;;) {
8047 int poll_timeout_ms;
8048 {
8049 std::lock_guard<std::mutex> lock(lock_);
8050 if (quit_)
8051 return;
8052 poll_timeout_ms = GetDelayMsToNextTaskLocked();
8053 UpdateWatchTasksLocked();
8054 }
8055
8056 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
8057 DWORD timeout =
8058 poll_timeout_ms >= 0 ? static_cast<DWORD>(poll_timeout_ms) : INFINITE;
8059 DWORD ret =
8060 WaitForMultipleObjects(static_cast<DWORD>(poll_fds_.size()),
8061 &poll_fds_[0], /*bWaitAll=*/false, timeout);
8062 // Unlike poll(2), WaitForMultipleObjects() returns only *one* handle in the
8063 // set, even when >1 is signalled. In order to avoid starvation,
8064 // PostFileDescriptorWatches() will WaitForSingleObject() each other handle
8065 // to ensure fairness. |ret| here is passed just to avoid an extra
8066 // WaitForSingleObject() for the one handle that WaitForMultipleObject()
8067 // returned.
8068 PostFileDescriptorWatches(ret);
8069 #else
8070 int ret = PERFETTO_EINTR(poll(
8071 &poll_fds_[0], static_cast<nfds_t>(poll_fds_.size()), poll_timeout_ms));
8072 PERFETTO_CHECK(ret >= 0);
8073 PostFileDescriptorWatches(0 /*ignored*/);
8074 #endif
8075
8076 // To avoid starvation we always interleave all types of tasks -- immediate,
8077 // delayed and file descriptor watches.
8078 RunImmediateAndDelayedTask();
8079 }
8080 }
8081
Quit()8082 void UnixTaskRunner::Quit() {
8083 std::lock_guard<std::mutex> lock(lock_);
8084 quit_ = true;
8085 WakeUp();
8086 }
8087
QuitCalled()8088 bool UnixTaskRunner::QuitCalled() {
8089 std::lock_guard<std::mutex> lock(lock_);
8090 return quit_;
8091 }
8092
IsIdleForTesting()8093 bool UnixTaskRunner::IsIdleForTesting() {
8094 std::lock_guard<std::mutex> lock(lock_);
8095 return immediate_tasks_.empty();
8096 }
8097
UpdateWatchTasksLocked()8098 void UnixTaskRunner::UpdateWatchTasksLocked() {
8099 PERFETTO_DCHECK_THREAD(thread_checker_);
8100 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
8101 if (!watch_tasks_changed_)
8102 return;
8103 watch_tasks_changed_ = false;
8104 #endif
8105 poll_fds_.clear();
8106 for (auto& it : watch_tasks_) {
8107 PlatformHandle handle = it.first;
8108 WatchTask& watch_task = it.second;
8109 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
8110 if (!watch_task.pending)
8111 poll_fds_.push_back(handle);
8112 #else
8113 watch_task.poll_fd_index = poll_fds_.size();
8114 poll_fds_.push_back({handle, POLLIN | POLLHUP, 0});
8115 #endif
8116 }
8117 }
8118
RunImmediateAndDelayedTask()8119 void UnixTaskRunner::RunImmediateAndDelayedTask() {
8120 // If locking overhead becomes an issue, add a separate work queue.
8121 std::function<void()> immediate_task;
8122 std::function<void()> delayed_task;
8123 TimeMillis now = GetWallTimeMs();
8124 {
8125 std::lock_guard<std::mutex> lock(lock_);
8126 if (!immediate_tasks_.empty()) {
8127 immediate_task = std::move(immediate_tasks_.front());
8128 immediate_tasks_.pop_front();
8129 }
8130 if (!delayed_tasks_.empty()) {
8131 auto it = delayed_tasks_.begin();
8132 if (now >= it->first) {
8133 delayed_task = std::move(it->second);
8134 delayed_tasks_.erase(it);
8135 }
8136 }
8137 }
8138
8139 errno = 0;
8140 if (immediate_task)
8141 RunTaskWithWatchdogGuard(immediate_task);
8142 errno = 0;
8143 if (delayed_task)
8144 RunTaskWithWatchdogGuard(delayed_task);
8145 }
8146
PostFileDescriptorWatches(uint64_t windows_wait_result)8147 void UnixTaskRunner::PostFileDescriptorWatches(uint64_t windows_wait_result) {
8148 PERFETTO_DCHECK_THREAD(thread_checker_);
8149 for (size_t i = 0; i < poll_fds_.size(); i++) {
8150 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
8151 const PlatformHandle handle = poll_fds_[i];
8152 // |windows_wait_result| is the result of WaitForMultipleObjects() call. If
8153 // one of the objects was signalled, it will have a value between
8154 // [0, poll_fds_.size()].
8155 if (i != windows_wait_result &&
8156 WaitForSingleObject(handle, 0) != WAIT_OBJECT_0) {
8157 continue;
8158 }
8159 #else
8160 base::ignore_result(windows_wait_result);
8161 const PlatformHandle handle = poll_fds_[i].fd;
8162 if (!(poll_fds_[i].revents & (POLLIN | POLLHUP)))
8163 continue;
8164 poll_fds_[i].revents = 0;
8165 #endif
8166
8167 // The wake-up event is handled inline to avoid an infinite recursion of
8168 // posted tasks.
8169 if (handle == event_.fd()) {
8170 event_.Clear();
8171 continue;
8172 }
8173
8174 // Binding to |this| is safe since we are the only object executing the
8175 // task.
8176 PostTask(std::bind(&UnixTaskRunner::RunFileDescriptorWatch, this, handle));
8177
8178 // Flag the task as pending.
8179 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
8180 // On Windows this is done by marking the WatchTask entry as pending. This
8181 // is more expensive than Linux as requires rebuilding the |poll_fds_|
8182 // vector on each call. There doesn't seem to be a good alternative though.
8183 auto it = watch_tasks_.find(handle);
8184 PERFETTO_CHECK(it != watch_tasks_.end());
8185 PERFETTO_DCHECK(!it->second.pending);
8186 it->second.pending = true;
8187 #else
8188 // On UNIX systems instead, we just make the fd negative while its task is
8189 // pending. This makes poll(2) ignore the fd.
8190 PERFETTO_DCHECK(poll_fds_[i].fd >= 0);
8191 poll_fds_[i].fd = -poll_fds_[i].fd;
8192 #endif
8193 }
8194 }
8195
RunFileDescriptorWatch(PlatformHandle fd)8196 void UnixTaskRunner::RunFileDescriptorWatch(PlatformHandle fd) {
8197 std::function<void()> task;
8198 {
8199 std::lock_guard<std::mutex> lock(lock_);
8200 auto it = watch_tasks_.find(fd);
8201 if (it == watch_tasks_.end())
8202 return;
8203 WatchTask& watch_task = it->second;
8204
8205 // Make poll(2) pay attention to the fd again. Since another thread may have
8206 // updated this watch we need to refresh the set first.
8207 UpdateWatchTasksLocked();
8208
8209 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
8210 // On Windows we manually track the presence of outstanding tasks for the
8211 // watch. The UpdateWatchTasksLocked() in the Run() loop will re-add the
8212 // task to the |poll_fds_| vector.
8213 PERFETTO_DCHECK(watch_task.pending);
8214 watch_task.pending = false;
8215 #else
8216 size_t fd_index = watch_task.poll_fd_index;
8217 PERFETTO_DCHECK(fd_index < poll_fds_.size());
8218 PERFETTO_DCHECK(::abs(poll_fds_[fd_index].fd) == fd);
8219 poll_fds_[fd_index].fd = fd;
8220 #endif
8221 task = watch_task.callback;
8222 }
8223 errno = 0;
8224 RunTaskWithWatchdogGuard(task);
8225 }
8226
GetDelayMsToNextTaskLocked() const8227 int UnixTaskRunner::GetDelayMsToNextTaskLocked() const {
8228 PERFETTO_DCHECK_THREAD(thread_checker_);
8229 if (!immediate_tasks_.empty())
8230 return 0;
8231 if (!delayed_tasks_.empty()) {
8232 TimeMillis diff = delayed_tasks_.begin()->first - GetWallTimeMs();
8233 return std::max(0, static_cast<int>(diff.count()));
8234 }
8235 return -1;
8236 }
8237
PostTask(std::function<void ()> task)8238 void UnixTaskRunner::PostTask(std::function<void()> task) {
8239 bool was_empty;
8240 {
8241 std::lock_guard<std::mutex> lock(lock_);
8242 was_empty = immediate_tasks_.empty();
8243 immediate_tasks_.push_back(std::move(task));
8244 }
8245 if (was_empty)
8246 WakeUp();
8247 }
8248
PostDelayedTask(std::function<void ()> task,uint32_t delay_ms)8249 void UnixTaskRunner::PostDelayedTask(std::function<void()> task,
8250 uint32_t delay_ms) {
8251 TimeMillis runtime = GetWallTimeMs() + TimeMillis(delay_ms);
8252 {
8253 std::lock_guard<std::mutex> lock(lock_);
8254 delayed_tasks_.insert(std::make_pair(runtime, std::move(task)));
8255 }
8256 WakeUp();
8257 }
8258
AddFileDescriptorWatch(PlatformHandle fd,std::function<void ()> task)8259 void UnixTaskRunner::AddFileDescriptorWatch(PlatformHandle fd,
8260 std::function<void()> task) {
8261 PERFETTO_DCHECK(PlatformHandleChecker::IsValid(fd));
8262 {
8263 std::lock_guard<std::mutex> lock(lock_);
8264 PERFETTO_DCHECK(!watch_tasks_.count(fd));
8265 WatchTask& watch_task = watch_tasks_[fd];
8266 watch_task.callback = std::move(task);
8267 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
8268 watch_task.pending = false;
8269 #else
8270 watch_task.poll_fd_index = SIZE_MAX;
8271 #endif
8272 watch_tasks_changed_ = true;
8273 }
8274 WakeUp();
8275 }
8276
RemoveFileDescriptorWatch(PlatformHandle fd)8277 void UnixTaskRunner::RemoveFileDescriptorWatch(PlatformHandle fd) {
8278 PERFETTO_DCHECK(PlatformHandleChecker::IsValid(fd));
8279 {
8280 std::lock_guard<std::mutex> lock(lock_);
8281 PERFETTO_DCHECK(watch_tasks_.count(fd));
8282 watch_tasks_.erase(fd);
8283 watch_tasks_changed_ = true;
8284 }
8285 // No need to schedule a wake-up for this.
8286 }
8287
RunsTasksOnCurrentThread() const8288 bool UnixTaskRunner::RunsTasksOnCurrentThread() const {
8289 return GetThreadId() == created_thread_id_;
8290 }
8291
8292 } // namespace base
8293 } // namespace perfetto
8294 // gen_amalgamated begin source: src/base/subprocess.cc
8295 // gen_amalgamated begin header: include/perfetto/ext/base/subprocess.h
8296 /*
8297 * Copyright (C) 2020 The Android Open Source Project
8298 *
8299 * Licensed under the Apache License, Version 2.0 (the "License");
8300 * you may not use this file except in compliance with the License.
8301 * You may obtain a copy of the License at
8302 *
8303 * http://www.apache.org/licenses/LICENSE-2.0
8304 *
8305 * Unless required by applicable law or agreed to in writing, software
8306 * distributed under the License is distributed on an "AS IS" BASIS,
8307 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8308 * See the License for the specific language governing permissions and
8309 * limitations under the License.
8310 */
8311
8312 #ifndef INCLUDE_PERFETTO_EXT_BASE_SUBPROCESS_H_
8313 #define INCLUDE_PERFETTO_EXT_BASE_SUBPROCESS_H_
8314
8315 #include <condition_variable>
8316 #include <functional>
8317 #include <initializer_list>
8318 #include <mutex>
8319 #include <string>
8320 #include <thread>
8321 #include <vector>
8322
8323 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
8324 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
8325 // gen_amalgamated expanded: #include "perfetto/base/platform_handle.h"
8326 // gen_amalgamated expanded: #include "perfetto/base/proc_utils.h"
8327 // gen_amalgamated expanded: #include "perfetto/ext/base/event_fd.h"
8328 // gen_amalgamated expanded: #include "perfetto/ext/base/optional.h"
8329 // gen_amalgamated expanded: #include "perfetto/ext/base/pipe.h"
8330 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
8331
8332 namespace perfetto {
8333 namespace base {
8334
8335 // Handles creation and lifecycle management of subprocesses, taking care of
8336 // all subtleties involved in handling processes on UNIX.
8337 // This class allows to deal with macro two use-cases:
8338 // 1) fork() + exec() equivalent: for spawning a brand new process image.
8339 // This happens when |args.exec_cmd| is not empty.
8340 // This is safe to use even in a multi-threaded environment.
8341 // 2) fork(): for spawning a process and running a function.
8342 // This happens when |args.posix_entrypoint_for_testing| is not empty.
8343 // This is intended only for tests as it is extremely subtle.
8344 // This mode must be used with extreme care. Before the entrypoint is
8345 // invoked all file descriptors other than stdin/out/err and the ones
8346 // specified in |args.preserve_fds| will be closed, to avoid each process
8347 // retaining a dupe of other subprocesses pipes. This however means that
8348 // any non trivial calls (including logging) must be avoided as they might
8349 // refer to FDs that are now closed. The entrypoint should really be used
8350 // just to signal a pipe or similar for synchronizing sequencing in tests.
8351
8352 //
8353 // This class allows to control stdin/out/err pipe redirection and takes care
8354 // of keeping all the pipes pumped (stdin) / drained (stdout/err), in a similar
8355 // fashion of python's subprocess.Communicate()
8356 // stdin: is always piped and closed once the |args.input| buffer is written.
8357 // stdout/err can be either:
8358 // - dup()ed onto the parent process stdout/err.
8359 // - redirected onto /dev/null.
8360 // - piped onto a buffer (see output() method). There is only one output
8361 // buffer in total. If both stdout and stderr are set to kBuffer mode, they
8362 // will be merged onto the same. There doesn't seem any use case where they
8363 // are needed distinctly.
8364 //
8365 // Some caveats worth mentioning:
8366 // - It always waitpid()s, to avoid leaving zombies around. If the process is
8367 // not terminated by the time the destructor is reached, the dtor will
8368 // send a SIGKILL and wait for the termination.
8369 // - After fork()-ing it will close all file descriptors, preserving only
8370 // stdin/out/err and the fds listed in |args.preserve_fds|.
8371 // - On Linux/Android, the child process will be SIGKILL-ed if the calling
8372 // thread exists, even if the Subprocess is std::move()-d onto another thread.
8373 // This happens by virtue PR_SET_PDEATHSIG, which is used to avoid that
8374 // child processes are leaked in the case of a crash of the parent (frequent
8375 // in tests). However, the child process might still be leaked if execing
8376 // a setuid/setgid binary (see man 2 prctl).
8377 //
8378 // Usage:
8379 // base::Subprocess p({"/bin/cat", "-"});
8380 // (or equivalently:
8381 // base::Subprocess p;
8382 // p.args.exec_cmd.push_back("/bin/cat");
8383 // p.args.exec_cmd.push_back("-");
8384 // )
8385 // p.args.stdout_mode = base::Subprocess::kBuffer;
8386 // p.args.stderr_mode = base::Subprocess::kInherit;
8387 // p.args.input = "stdin contents";
8388 // p.Call();
8389 // (or equivalently:
8390 // p.Start();
8391 // p.Wait();
8392 // )
8393 // EXPECT_EQ(p.status(), base::Subprocess::kTerminated);
8394 // EXPECT_EQ(p.returncode(), 0);
8395 class Subprocess {
8396 public:
8397 enum Status {
8398 kNotStarted = 0, // Before calling Start() or Call().
8399 kRunning, // After calling Start(), before Wait().
8400 kTerminated, // The subprocess terminated, either successfully or not.
8401 // This includes crashes or other signals on UNIX.
8402 };
8403
8404 enum OutputMode {
8405 kInherit = 0, // Inherit's the caller process stdout/stderr.
8406 kDevNull, // dup() onto /dev/null
8407 kBuffer, // dup() onto a pipe and move it into the output() buffer.
8408 kFd, // dup() onto the passed args.fd.
8409 };
8410
8411 // Input arguments for configuring the subprocess behavior.
8412 struct Args {
Argsperfetto::base::Subprocess::Args8413 Args(std::initializer_list<std::string> _cmd = {}) : exec_cmd(_cmd) {}
8414 Args(Args&&) noexcept;
8415 Args& operator=(Args&&);
8416 // If non-empty this will cause an exec() when Start()/Call() are called.
8417 std::vector<std::string> exec_cmd;
8418
8419 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
8420 // If non-empty, it changes the argv[0] argument passed to exec. If
8421 // unset, argv[0] == exec_cmd[0]. This is to handle cases like:
8422 // exec_cmd = {"/proc/self/exec"}, argv0: "my_custom_test_override".
8423 std::string posix_argv0_override_for_testing;
8424
8425 // If non-empty this will be invoked on the fork()-ed child process, after
8426 // stdin/out/err has been redirected and all other file descriptor are
8427 // closed. It is valid to specify both |exec_cmd| AND
8428 // |posix_entrypoint_for_testing|. In this case the latter will be invoked
8429 // just before the exec() call, but after having closed all fds % stdin/o/e.
8430 // This is for synchronization barriers in tests.
8431 std::function<void()> posix_entrypoint_for_testing;
8432
8433 // When set, will will move the process to the given process group. If set
8434 // and zero, it will create a new process group. Effectively this calls
8435 // setpgid(0 /*self_pid*/, posix_proc_group_id).
8436 // This can be used to avoid that subprocesses receive CTRL-C from the
8437 // terminal, while still living in the same session.
8438 base::Optional<pid_t> posix_proc_group_id{};
8439 #endif
8440
8441 // If non-empty, replaces the environment passed to exec().
8442 std::vector<std::string> env;
8443
8444 // The file descriptors in this list will not be closed.
8445 std::vector<int> preserve_fds;
8446
8447 // The data to push in the child process stdin.
8448 std::string input;
8449
8450 OutputMode stdout_mode = kInherit;
8451 OutputMode stderr_mode = kInherit;
8452
8453 base::ScopedPlatformHandle out_fd;
8454
8455 // Returns " ".join(exec_cmd), quoting arguments.
8456 std::string GetCmdString() const;
8457 };
8458
8459 struct ResourceUsage {
8460 uint32_t cpu_utime_ms = 0;
8461 uint32_t cpu_stime_ms = 0;
8462 uint32_t max_rss_kb = 0;
8463 uint32_t min_page_faults = 0;
8464 uint32_t maj_page_faults = 0;
8465 uint32_t vol_ctx_switch = 0;
8466 uint32_t invol_ctx_switch = 0;
8467
cpu_time_msperfetto::base::Subprocess::ResourceUsage8468 uint32_t cpu_time_ms() const { return cpu_utime_ms + cpu_stime_ms; }
8469 };
8470
8471 explicit Subprocess(std::initializer_list<std::string> exec_cmd = {});
8472 Subprocess(Subprocess&&) noexcept;
8473 Subprocess& operator=(Subprocess&&);
8474 ~Subprocess(); // It will KillAndWaitForTermination() if still alive.
8475
8476 // Starts the subprocess but doesn't wait for its termination. The caller
8477 // is expected to either call Wait() or Poll() after this call.
8478 void Start();
8479
8480 // Wait for process termination. Can be called more than once.
8481 // Args:
8482 // |timeout_ms| = 0: wait indefinitely.
8483 // |timeout_ms| > 0: wait for at most |timeout_ms|.
8484 // Returns:
8485 // True: The process terminated. See status() and returncode().
8486 // False: Timeout reached, the process is still running. In this case the
8487 // process will be left in the kRunning state.
8488 bool Wait(int timeout_ms = 0);
8489
8490 // Equivalent of Start() + Wait();
8491 // Returns true if the process exited cleanly with return code 0. False in
8492 // any othe case.
8493 bool Call(int timeout_ms = 0);
8494
8495 Status Poll();
8496
8497 // Sends a signal (SIGKILL if not specified) and wait for process termination.
8498 void KillAndWaitForTermination(int sig_num = 0);
8499
pid() const8500 PlatformProcessId pid() const { return s_->pid; }
8501
8502 // The accessors below are updated only after a call to Poll(), Wait() or
8503 // KillAndWaitForTermination().
8504 // In most cases you want to call Poll() rather than these accessors.
8505
status() const8506 Status status() const { return s_->status; }
returncode() const8507 int returncode() const { return s_->returncode; }
timed_out() const8508 bool timed_out() const { return s_->timed_out; }
8509
8510 // This contains both stdout and stderr (if the corresponding _mode ==
8511 // kBuffer). It's non-const so the caller can std::move() it.
output()8512 std::string& output() { return s_->output; }
output() const8513 const std::string& output() const { return s_->output; }
8514
posix_rusage() const8515 const ResourceUsage& posix_rusage() const { return *s_->rusage; }
8516
8517 Args args;
8518
8519 private:
8520 // The signal/exit code used when killing the process in case of a timeout.
8521 static const int kTimeoutSignal;
8522
8523 Subprocess(const Subprocess&) = delete;
8524 Subprocess& operator=(const Subprocess&) = delete;
8525
8526 // This is to deal robustly with the move operators, without having to
8527 // manually maintain member-wise move instructions.
8528 struct MovableState {
8529 base::Pipe stdin_pipe;
8530 base::Pipe stdouterr_pipe;
8531 PlatformProcessId pid;
8532 Status status = kNotStarted;
8533 int returncode = -1;
8534 std::string output; // Stdin+stderr. Only when kBuffer.
8535 std::unique_ptr<ResourceUsage> rusage{new ResourceUsage()};
8536 bool timed_out = false;
8537 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
8538 std::thread stdouterr_thread;
8539 std::thread stdin_thread;
8540 ScopedPlatformHandle win_proc_handle;
8541 ScopedPlatformHandle win_thread_handle;
8542
8543 base::EventFd stdouterr_done_event;
8544 std::mutex mutex; // Protects locked_outerr_buf and the two pipes.
8545 std::string locked_outerr_buf;
8546 #else
8547 base::Pipe exit_status_pipe;
8548 size_t input_written = 0;
8549 std::thread waitpid_thread;
8550 #endif
8551 };
8552
8553 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
8554 static void StdinThread(MovableState*, std::string input);
8555 static void StdoutErrThread(MovableState*);
8556 #else
8557 void TryPushStdin();
8558 void TryReadStdoutAndErr();
8559 void TryReadExitStatus();
8560 void KillAtMostOnce();
8561 bool PollInternal(int poll_timeout_ms);
8562 #endif
8563
8564 std::unique_ptr<MovableState> s_;
8565 };
8566
8567 } // namespace base
8568 } // namespace perfetto
8569
8570 #endif // INCLUDE_PERFETTO_EXT_BASE_SUBPROCESS_H_
8571 /*
8572 * Copyright (C) 2020 The Android Open Source Project
8573 *
8574 * Licensed under the Apache License, Version 2.0 (the "License");
8575 * you may not use this file except in compliance with the License.
8576 * You may obtain a copy of the License at
8577 *
8578 * http://www.apache.org/licenses/LICENSE-2.0
8579 *
8580 * Unless required by applicable law or agreed to in writing, software
8581 * distributed under the License is distributed on an "AS IS" BASIS,
8582 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8583 * See the License for the specific language governing permissions and
8584 * limitations under the License.
8585 */
8586
8587 // gen_amalgamated expanded: #include "perfetto/ext/base/subprocess.h"
8588
8589 #include <tuple>
8590
8591 // This file contains only the common bits (ctors / dtors / move operators).
8592 // The rest lives in subprocess_posix.cc and subprocess_windows.cc.
8593
8594 namespace perfetto {
8595 namespace base {
8596
8597 Subprocess::Args::Args(Args&&) noexcept = default;
8598 Subprocess::Args& Subprocess::Args::operator=(Args&&) = default;
8599
Subprocess(std::initializer_list<std::string> a)8600 Subprocess::Subprocess(std::initializer_list<std::string> a)
8601 : args(a), s_(new MovableState()) {}
8602
Subprocess(Subprocess && other)8603 Subprocess::Subprocess(Subprocess&& other) noexcept {
8604 static_assert(sizeof(Subprocess) ==
8605 sizeof(std::tuple<std::unique_ptr<MovableState>, Args>),
8606 "base::Subprocess' move ctor needs updating");
8607 s_ = std::move(other.s_);
8608 args = std::move(other.args);
8609
8610 // Reset the state of the moved-from object.
8611 other.s_.reset(new MovableState());
8612 other.~Subprocess();
8613 new (&other) Subprocess();
8614 }
8615
operator =(Subprocess && other)8616 Subprocess& Subprocess::operator=(Subprocess&& other) {
8617 this->~Subprocess();
8618 new (this) Subprocess(std::move(other));
8619 return *this;
8620 }
8621
~Subprocess()8622 Subprocess::~Subprocess() {
8623 if (s_->status == kRunning)
8624 KillAndWaitForTermination();
8625 }
8626
Call(int timeout_ms)8627 bool Subprocess::Call(int timeout_ms) {
8628 PERFETTO_CHECK(s_->status == kNotStarted);
8629 Start();
8630
8631 if (!Wait(timeout_ms)) {
8632 s_->timed_out = true;
8633 KillAndWaitForTermination(kTimeoutSignal);
8634 }
8635 PERFETTO_DCHECK(s_->status != kRunning);
8636 return s_->status == kTerminated && s_->returncode == 0;
8637 }
8638
GetCmdString() const8639 std::string Subprocess::Args::GetCmdString() const {
8640 std::string str;
8641 for (size_t i = 0; i < exec_cmd.size(); i++) {
8642 str += i > 0 ? " \"" : "";
8643 str += exec_cmd[i];
8644 str += i > 0 ? "\"" : "";
8645 }
8646 return str;
8647 }
8648
8649 } // namespace base
8650 } // namespace perfetto
8651 // gen_amalgamated begin source: src/base/subprocess_posix.cc
8652 /*
8653 * Copyright (C) 2020 The Android Open Source Project
8654 *
8655 * Licensed under the Apache License, Version 2.0 (the "License");
8656 * you may not use this file except in compliance with the License.
8657 * You may obtain a copy of the License at
8658 *
8659 * http://www.apache.org/licenses/LICENSE-2.0
8660 *
8661 * Unless required by applicable law or agreed to in writing, software
8662 * distributed under the License is distributed on an "AS IS" BASIS,
8663 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8664 * See the License for the specific language governing permissions and
8665 * limitations under the License.
8666 */
8667
8668 // gen_amalgamated expanded: #include "perfetto/ext/base/subprocess.h"
8669
8670 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
8671
8672 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
8673 PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
8674 PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
8675
8676 #include <fcntl.h>
8677 #include <poll.h>
8678 #include <signal.h>
8679 #include <stdio.h>
8680 #include <sys/resource.h>
8681 #include <sys/types.h>
8682 #include <sys/wait.h>
8683 #include <unistd.h>
8684
8685 #include <algorithm>
8686 #include <thread>
8687 #include <tuple>
8688
8689 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
8690 PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
8691 #include <sys/prctl.h>
8692 #endif
8693
8694 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
8695 // gen_amalgamated expanded: #include "perfetto/base/time.h"
8696 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
8697
8698 // In MacOS this is not defined in any header.
8699 extern "C" char** environ;
8700
8701 namespace perfetto {
8702 namespace base {
8703
8704 namespace {
8705
8706 struct ChildProcessArgs {
8707 Subprocess::Args* create_args;
8708 const char* exec_cmd = nullptr;
8709 std::vector<char*> argv;
8710 std::vector<char*> env;
8711 int stdin_pipe_rd = -1;
8712 int stdouterr_pipe_wr = -1;
8713 };
8714
8715 // Don't add any dynamic allocation in this function. This will be invoked
8716 // under a fork(), potentially in a state where the allocator lock is held.
ChildProcess(ChildProcessArgs * args)8717 void __attribute__((noreturn)) ChildProcess(ChildProcessArgs* args) {
8718 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
8719 PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
8720 // In no case we want a child process to outlive its parent process. This is
8721 // relevant for tests, so that a test failure/crash doesn't leave child
8722 // processes around that get reparented to init.
8723 prctl(PR_SET_PDEATHSIG, SIGKILL);
8724 #endif
8725
8726 auto die = [args](const char* err) __attribute__((noreturn)) {
8727 base::ignore_result(write(args->stdouterr_pipe_wr, err, strlen(err)));
8728 base::ignore_result(write(args->stdouterr_pipe_wr, "\n", 1));
8729 // From https://www.gnu.org/software/libc/manual/html_node/Exit-Status.html
8730 // "In particular, the value 128 is used to indicate failure to execute
8731 // another program in a subprocess. This convention is not universally
8732 // obeyed, but it is a good idea to follow it in your programs."
8733 _exit(128);
8734 };
8735
8736 if (args->create_args->posix_proc_group_id.has_value()) {
8737 if (setpgid(0 /*self*/, args->create_args->posix_proc_group_id.value())) {
8738 die("setpgid() failed");
8739 }
8740 }
8741
8742 auto set_fd_close_on_exec = [&die](int fd, bool close_on_exec) {
8743 int flags = fcntl(fd, F_GETFD, 0);
8744 if (flags < 0)
8745 die("fcntl(F_GETFD) failed");
8746 flags = close_on_exec ? (flags | FD_CLOEXEC) : (flags & ~FD_CLOEXEC);
8747 if (fcntl(fd, F_SETFD, flags) < 0)
8748 die("fcntl(F_SETFD) failed");
8749 };
8750
8751 if (getppid() == 1)
8752 die("terminating because parent process died");
8753
8754 if (dup2(args->stdin_pipe_rd, STDIN_FILENO) == -1)
8755 die("Failed to dup2(STDIN)");
8756 close(args->stdin_pipe_rd);
8757
8758 switch (args->create_args->stdout_mode) {
8759 case Subprocess::kInherit:
8760 break;
8761 case Subprocess::kDevNull: {
8762 if (dup2(open("/dev/null", O_RDWR), STDOUT_FILENO) == -1)
8763 die("Failed to dup2(STDOUT)");
8764 break;
8765 }
8766 case Subprocess::kBuffer:
8767 if (dup2(args->stdouterr_pipe_wr, STDOUT_FILENO) == -1)
8768 die("Failed to dup2(STDOUT)");
8769 break;
8770 case Subprocess::kFd:
8771 if (dup2(*args->create_args->out_fd, STDOUT_FILENO) == -1)
8772 die("Failed to dup2(STDOUT)");
8773 break;
8774 }
8775
8776 switch (args->create_args->stderr_mode) {
8777 case Subprocess::kInherit:
8778 break;
8779 case Subprocess::kDevNull: {
8780 if (dup2(open("/dev/null", O_RDWR), STDERR_FILENO) == -1)
8781 die("Failed to dup2(STDERR)");
8782 break;
8783 }
8784 case Subprocess::kBuffer:
8785 if (dup2(args->stdouterr_pipe_wr, STDERR_FILENO) == -1)
8786 die("Failed to dup2(STDERR)");
8787 break;
8788 case Subprocess::kFd:
8789 if (dup2(*args->create_args->out_fd, STDERR_FILENO) == -1)
8790 die("Failed to dup2(STDERR)");
8791 break;
8792 }
8793
8794 // Close all FDs % stdin/out/err and the ones that the client explicitly
8795 // asked to retain. The reason for this is twofold:
8796 // 1. For exec-only (i.e. entrypoint == empty) cases: it avoids leaking FDs
8797 // that didn't get marked as O_CLOEXEC by accident.
8798 // 2. In fork() mode (entrypoint not empty) avoids retaining a dup of eventfds
8799 // that would prevent the parent process to receive EOFs (tests usually use
8800 // pipes as a synchronization mechanism between subprocesses).
8801 const auto& preserve_fds = args->create_args->preserve_fds;
8802 for (int i = 0; i < 512; i++) {
8803 if (i != STDIN_FILENO && i != STDERR_FILENO && i != STDOUT_FILENO &&
8804 i != args->stdouterr_pipe_wr &&
8805 !std::count(preserve_fds.begin(), preserve_fds.end(), i)) {
8806 close(i);
8807 }
8808 }
8809
8810 // Clears O_CLOEXEC from stdin/out/err and the |preserve_fds| list. These are
8811 // the only FDs that we want to be preserved after the exec().
8812 set_fd_close_on_exec(STDIN_FILENO, false);
8813 set_fd_close_on_exec(STDOUT_FILENO, false);
8814 set_fd_close_on_exec(STDERR_FILENO, false);
8815
8816 for (auto fd : preserve_fds)
8817 set_fd_close_on_exec(fd, false);
8818
8819 // If the caller specified a std::function entrypoint, run that first.
8820 if (args->create_args->posix_entrypoint_for_testing)
8821 args->create_args->posix_entrypoint_for_testing();
8822
8823 // If the caller specified only an entrypoint, without any args, exit now.
8824 // Otherwise proceed with the exec() below.
8825 if (!args->exec_cmd)
8826 _exit(0);
8827
8828 // If |args[0]| is a path use execv() (which takes a path), othewise use
8829 // exevp(), which uses the shell and follows PATH.
8830 if (strchr(args->exec_cmd, '/')) {
8831 char** env = args->env.empty() ? environ : args->env.data();
8832 execve(args->exec_cmd, args->argv.data(), env);
8833 } else {
8834 // There is no execvpe() on Mac.
8835 if (!args->env.empty())
8836 die("A full path is required for |exec_cmd| when setting |env|");
8837 execvp(args->exec_cmd, args->argv.data());
8838 }
8839
8840 // Reached only if execv fails.
8841 die("execve() failed");
8842 }
8843
8844 } // namespace
8845
8846 // static
8847 const int Subprocess::kTimeoutSignal = SIGKILL;
8848
Start()8849 void Subprocess::Start() {
8850 ChildProcessArgs proc_args;
8851 proc_args.create_args = &args;
8852
8853 // Setup argv.
8854 if (!args.exec_cmd.empty()) {
8855 proc_args.exec_cmd = args.exec_cmd[0].c_str();
8856 for (const std::string& arg : args.exec_cmd)
8857 proc_args.argv.push_back(const_cast<char*>(arg.c_str()));
8858 proc_args.argv.push_back(nullptr);
8859
8860 if (!args.posix_argv0_override_for_testing.empty()) {
8861 proc_args.argv[0] =
8862 const_cast<char*>(args.posix_argv0_override_for_testing.c_str());
8863 }
8864 }
8865
8866 // Setup env.
8867 if (!args.env.empty()) {
8868 for (const std::string& str : args.env)
8869 proc_args.env.push_back(const_cast<char*>(str.c_str()));
8870 proc_args.env.push_back(nullptr);
8871 }
8872
8873 // Setup the pipes for stdin/err redirection.
8874 s_->stdin_pipe = base::Pipe::Create(base::Pipe::kWrNonBlock);
8875 proc_args.stdin_pipe_rd = *s_->stdin_pipe.rd;
8876 s_->stdouterr_pipe = base::Pipe::Create(base::Pipe::kRdNonBlock);
8877 proc_args.stdouterr_pipe_wr = *s_->stdouterr_pipe.wr;
8878
8879 // Spawn the child process that will exec().
8880 s_->pid = fork();
8881 PERFETTO_CHECK(s_->pid >= 0);
8882 if (s_->pid == 0) {
8883 // Close the parent-ends of the pipes.
8884 s_->stdin_pipe.wr.reset();
8885 s_->stdouterr_pipe.rd.reset();
8886 ChildProcess(&proc_args);
8887 // ChildProcess() doesn't return, not even in case of failures.
8888 PERFETTO_FATAL("not reached");
8889 }
8890
8891 s_->status = kRunning;
8892
8893 // Close the child-end of the pipes.
8894 // Deliberately NOT closing the s_->stdin_pipe.rd. This is to avoid crashing
8895 // with a SIGPIPE if the process exits without consuming its stdin, while
8896 // the parent tries to write() on the other end of the stdin pipe.
8897 s_->stdouterr_pipe.wr.reset();
8898 proc_args.create_args->out_fd.reset();
8899
8900 // Spawn a thread that is blocked on waitpid() and writes the termination
8901 // status onto a pipe. The problem here is that waipid() doesn't have a
8902 // timeout option and can't be passed to poll(). The alternative would be
8903 // using a SIGCHLD handler, but anecdotally signal handlers introduce more
8904 // problems than what they solve.
8905 s_->exit_status_pipe = base::Pipe::Create(base::Pipe::kRdNonBlock);
8906
8907 // Both ends of the pipe are closed after the thread.join().
8908 int pid = s_->pid;
8909 int exit_status_pipe_wr = s_->exit_status_pipe.wr.release();
8910 auto* rusage = s_->rusage.get();
8911 s_->waitpid_thread = std::thread([pid, exit_status_pipe_wr, rusage] {
8912 int pid_stat = -1;
8913 struct rusage usg {};
8914 int wait_res = PERFETTO_EINTR(wait4(pid, &pid_stat, 0, &usg));
8915 PERFETTO_CHECK(wait_res == pid);
8916
8917 auto tv_to_ms = [](const struct timeval& tv) {
8918 return static_cast<uint32_t>(tv.tv_sec * 1000 + tv.tv_usec / 1000);
8919 };
8920 rusage->cpu_utime_ms = tv_to_ms(usg.ru_utime);
8921 rusage->cpu_stime_ms = tv_to_ms(usg.ru_stime);
8922 rusage->max_rss_kb = static_cast<uint32_t>(usg.ru_maxrss) / 1000;
8923 rusage->min_page_faults = static_cast<uint32_t>(usg.ru_minflt);
8924 rusage->maj_page_faults = static_cast<uint32_t>(usg.ru_majflt);
8925 rusage->vol_ctx_switch = static_cast<uint32_t>(usg.ru_nvcsw);
8926 rusage->invol_ctx_switch = static_cast<uint32_t>(usg.ru_nivcsw);
8927
8928 base::ignore_result(PERFETTO_EINTR(
8929 write(exit_status_pipe_wr, &pid_stat, sizeof(pid_stat))));
8930 PERFETTO_CHECK(close(exit_status_pipe_wr) == 0 || errno == EINTR);
8931 });
8932 }
8933
Poll()8934 Subprocess::Status Subprocess::Poll() {
8935 if (s_->status != kRunning)
8936 return s_->status; // Nothing to poll.
8937 while (PollInternal(0 /* don't block*/)) {
8938 }
8939 return s_->status;
8940 }
8941
8942 // |timeout_ms| semantic:
8943 // -1: Block indefinitely.
8944 // 0: Don't block, return immediately.
8945 // >0: Block for at most X ms.
8946 // Returns:
8947 // True: Read at least one fd (so there might be more queued).
8948 // False: if all fds reached quiescent (no data to read/write).
PollInternal(int poll_timeout_ms)8949 bool Subprocess::PollInternal(int poll_timeout_ms) {
8950 struct pollfd fds[3]{};
8951 size_t num_fds = 0;
8952 if (s_->exit_status_pipe.rd) {
8953 fds[num_fds].fd = *s_->exit_status_pipe.rd;
8954 fds[num_fds].events = POLLIN;
8955 num_fds++;
8956 }
8957 if (s_->stdouterr_pipe.rd) {
8958 fds[num_fds].fd = *s_->stdouterr_pipe.rd;
8959 fds[num_fds].events = POLLIN;
8960 num_fds++;
8961 }
8962 if (s_->stdin_pipe.wr) {
8963 fds[num_fds].fd = *s_->stdin_pipe.wr;
8964 fds[num_fds].events = POLLOUT;
8965 num_fds++;
8966 }
8967
8968 if (num_fds == 0)
8969 return false;
8970
8971 auto nfds = static_cast<nfds_t>(num_fds);
8972 int poll_res = PERFETTO_EINTR(poll(fds, nfds, poll_timeout_ms));
8973 PERFETTO_CHECK(poll_res >= 0);
8974
8975 TryReadStdoutAndErr();
8976 TryPushStdin();
8977 TryReadExitStatus();
8978
8979 return poll_res > 0;
8980 }
8981
Wait(int timeout_ms)8982 bool Subprocess::Wait(int timeout_ms) {
8983 PERFETTO_CHECK(s_->status != kNotStarted);
8984
8985 // Break out of the loop only after both conditions are satisfied:
8986 // - All stdout/stderr data has been read (if kBuffer).
8987 // - The process exited.
8988 // Note that the two events can happen arbitrary order. After the process
8989 // exits, there might be still data in the pipe buffer, which we want to
8990 // read fully.
8991 //
8992 // Instead, don't wait on the stdin to be fully written. The child process
8993 // might exit prematurely (or crash). If that happens, we can end up in a
8994 // state where the write(stdin_pipe_.wr) will never unblock.
8995
8996 const int64_t t_start = base::GetWallTimeMs().count();
8997 while (s_->exit_status_pipe.rd || s_->stdouterr_pipe.rd) {
8998 int poll_timeout_ms = -1; // Block until a FD is ready.
8999 if (timeout_ms > 0) {
9000 const int64_t now = GetWallTimeMs().count();
9001 poll_timeout_ms = timeout_ms - static_cast<int>(now - t_start);
9002 if (poll_timeout_ms <= 0)
9003 return false;
9004 }
9005 PollInternal(poll_timeout_ms);
9006 } // while(...)
9007 return true;
9008 }
9009
TryReadExitStatus()9010 void Subprocess::TryReadExitStatus() {
9011 if (!s_->exit_status_pipe.rd)
9012 return;
9013
9014 int pid_stat = -1;
9015 int64_t rsize = PERFETTO_EINTR(
9016 read(*s_->exit_status_pipe.rd, &pid_stat, sizeof(pid_stat)));
9017 if (rsize < 0 && errno == EAGAIN)
9018 return;
9019
9020 if (rsize > 0) {
9021 PERFETTO_CHECK(rsize == sizeof(pid_stat));
9022 } else if (rsize < 0) {
9023 PERFETTO_PLOG("Subprocess read(s_->exit_status_pipe) failed");
9024 }
9025 s_->waitpid_thread.join();
9026 s_->exit_status_pipe.rd.reset();
9027
9028 s_->status = kTerminated;
9029 if (WIFEXITED(pid_stat)) {
9030 s_->returncode = WEXITSTATUS(pid_stat);
9031 } else if (WIFSIGNALED(pid_stat)) {
9032 s_->returncode = 128 + WTERMSIG(pid_stat); // Follow bash convention.
9033 } else {
9034 PERFETTO_FATAL("waitpid() returned an unexpected value (0x%x)", pid_stat);
9035 }
9036 }
9037
9038 // If the stidn pipe is still open, push input data and close it at the end.
TryPushStdin()9039 void Subprocess::TryPushStdin() {
9040 if (!s_->stdin_pipe.wr)
9041 return;
9042
9043 PERFETTO_DCHECK(args.input.empty() || s_->input_written < args.input.size());
9044 if (!args.input.empty()) {
9045 int64_t wsize =
9046 PERFETTO_EINTR(write(*s_->stdin_pipe.wr, &args.input[s_->input_written],
9047 args.input.size() - s_->input_written));
9048 if (wsize < 0 && errno == EAGAIN)
9049 return;
9050
9051 if (wsize >= 0) {
9052 // Whether write() can return 0 is one of the greatest mysteries of UNIX.
9053 // Just ignore it.
9054 s_->input_written += static_cast<size_t>(wsize);
9055 } else {
9056 PERFETTO_PLOG("Subprocess write(stdin) failed");
9057 s_->stdin_pipe.wr.reset();
9058 }
9059 }
9060 PERFETTO_DCHECK(s_->input_written <= args.input.size());
9061 if (s_->input_written == args.input.size())
9062 s_->stdin_pipe.wr.reset(); // Close stdin.
9063 }
9064
TryReadStdoutAndErr()9065 void Subprocess::TryReadStdoutAndErr() {
9066 if (!s_->stdouterr_pipe.rd)
9067 return;
9068 char buf[4096];
9069 int64_t rsize =
9070 PERFETTO_EINTR(read(*s_->stdouterr_pipe.rd, buf, sizeof(buf)));
9071 if (rsize < 0 && errno == EAGAIN)
9072 return;
9073
9074 if (rsize > 0) {
9075 s_->output.append(buf, static_cast<size_t>(rsize));
9076 } else if (rsize == 0 /* EOF */) {
9077 s_->stdouterr_pipe.rd.reset();
9078 } else {
9079 PERFETTO_PLOG("Subprocess read(stdout/err) failed");
9080 s_->stdouterr_pipe.rd.reset();
9081 }
9082 }
9083
KillAndWaitForTermination(int sig_num)9084 void Subprocess::KillAndWaitForTermination(int sig_num) {
9085 kill(s_->pid, sig_num ? sig_num : SIGKILL);
9086 Wait();
9087 // TryReadExitStatus must have joined the thread.
9088 PERFETTO_DCHECK(!s_->waitpid_thread.joinable());
9089 }
9090
9091 } // namespace base
9092 } // namespace perfetto
9093
9094 #endif // PERFETTO_OS_LINUX || PERFETTO_OS_ANDROID || PERFETTO_OS_APPLE
9095 // gen_amalgamated begin source: src/base/subprocess_windows.cc
9096 /*
9097 * Copyright (C) 2020 The Android Open Source Project
9098 *
9099 * Licensed under the Apache License, Version 2.0 (the "License");
9100 * you may not use this file except in compliance with the License.
9101 * You may obtain a copy of the License at
9102 *
9103 * http://www.apache.org/licenses/LICENSE-2.0
9104 *
9105 * Unless required by applicable law or agreed to in writing, software
9106 * distributed under the License is distributed on an "AS IS" BASIS,
9107 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9108 * See the License for the specific language governing permissions and
9109 * limitations under the License.
9110 */
9111
9112 // gen_amalgamated expanded: #include "perfetto/ext/base/subprocess.h"
9113
9114 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
9115
9116 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
9117
9118 #include <stdio.h>
9119
9120 #include <algorithm>
9121 #include <mutex>
9122 #include <tuple>
9123
9124 #include <Windows.h>
9125
9126 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
9127 // gen_amalgamated expanded: #include "perfetto/base/time.h"
9128 // gen_amalgamated expanded: #include "perfetto/ext/base/pipe.h"
9129 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
9130
9131 namespace perfetto {
9132 namespace base {
9133
9134 // static
9135 const int Subprocess::kTimeoutSignal = static_cast<int>(STATUS_TIMEOUT);
9136
Start()9137 void Subprocess::Start() {
9138 if (args.exec_cmd.empty()) {
9139 PERFETTO_ELOG("Subprocess.exec_cmd cannot be empty on Windows");
9140 return;
9141 }
9142
9143 // Quote arguments but only when ambiguous. When quoting, CreateProcess()
9144 // assumes that the command is an absolute path and does not search in the
9145 // %PATH%. If non quoted, instead, CreateProcess() tries both. This is to
9146 // allow Subprocess("cmd.exe", "/c", "shell command").
9147 std::string cmd;
9148 for (const auto& part : args.exec_cmd) {
9149 if (part.find(" ") != std::string::npos) {
9150 cmd += "\"" + part + "\" ";
9151 } else {
9152 cmd += part + " ";
9153 }
9154 }
9155 // Remove trailing space.
9156 if (!cmd.empty())
9157 cmd.resize(cmd.size() - 1);
9158
9159 s_->stdin_pipe = Pipe::Create();
9160 // Allow the child process to inherit the other end of the pipe.
9161 PERFETTO_CHECK(
9162 ::SetHandleInformation(*s_->stdin_pipe.rd, HANDLE_FLAG_INHERIT, 1));
9163
9164 if (args.stderr_mode == kBuffer || args.stdout_mode == kBuffer) {
9165 s_->stdouterr_pipe = Pipe::Create();
9166 PERFETTO_CHECK(
9167 ::SetHandleInformation(*s_->stdouterr_pipe.wr, HANDLE_FLAG_INHERIT, 1));
9168 }
9169
9170 ScopedPlatformHandle nul_handle;
9171 if (args.stderr_mode == kDevNull || args.stdout_mode == kDevNull) {
9172 nul_handle.reset(::CreateFileA("NUL", GENERIC_WRITE, FILE_SHARE_WRITE,
9173 nullptr, OPEN_EXISTING,
9174 FILE_ATTRIBUTE_NORMAL, nullptr));
9175 PERFETTO_CHECK(::SetHandleInformation(*nul_handle, HANDLE_FLAG_INHERIT, 1));
9176 }
9177
9178 PROCESS_INFORMATION proc_info{};
9179 STARTUPINFOA start_info{};
9180 start_info.cb = sizeof(STARTUPINFOA);
9181
9182 if (args.stderr_mode == kInherit) {
9183 start_info.hStdError = ::GetStdHandle(STD_ERROR_HANDLE);
9184 } else if (args.stderr_mode == kBuffer) {
9185 start_info.hStdError = *s_->stdouterr_pipe.wr;
9186 } else if (args.stderr_mode == kDevNull) {
9187 start_info.hStdError = *nul_handle;
9188 } else if (args.stderr_mode == kFd) {
9189 PERFETTO_CHECK(
9190 ::SetHandleInformation(*args.out_fd, HANDLE_FLAG_INHERIT, 1));
9191 start_info.hStdError = *args.out_fd;
9192 } else {
9193 PERFETTO_CHECK(false);
9194 }
9195
9196 if (args.stdout_mode == kInherit) {
9197 start_info.hStdOutput = ::GetStdHandle(STD_OUTPUT_HANDLE);
9198 } else if (args.stdout_mode == kBuffer) {
9199 start_info.hStdOutput = *s_->stdouterr_pipe.wr;
9200 } else if (args.stdout_mode == kDevNull) {
9201 start_info.hStdOutput = *nul_handle;
9202 } else if (args.stdout_mode == kFd) {
9203 PERFETTO_CHECK(
9204 ::SetHandleInformation(*args.out_fd, HANDLE_FLAG_INHERIT, 1));
9205 start_info.hStdOutput = *args.out_fd;
9206 } else {
9207 PERFETTO_CHECK(false);
9208 }
9209
9210 start_info.hStdInput = *s_->stdin_pipe.rd;
9211 start_info.dwFlags |= STARTF_USESTDHANDLES;
9212
9213 // Create the child process.
9214 bool success =
9215 ::CreateProcessA(nullptr, // App name. Needs to be null to use PATH.
9216 &cmd[0], // Command line.
9217 nullptr, // Process security attributes.
9218 nullptr, // Primary thread security attributes.
9219 true, // Handles are inherited.
9220 0, // Flags.
9221 nullptr, // Use parent's environment.
9222 nullptr, // Use parent's current directory.
9223 &start_info, // STARTUPINFO pointer.
9224 &proc_info); // Receives PROCESS_INFORMATION.
9225
9226 // Close on our side the pipe ends that we passed to the child process.
9227 s_->stdin_pipe.rd.reset();
9228 s_->stdouterr_pipe.wr.reset();
9229 args.out_fd.reset();
9230
9231 if (!success) {
9232 s_->returncode = ERROR_FILE_NOT_FOUND;
9233 s_->status = kTerminated;
9234 s_->stdin_pipe.wr.reset();
9235 s_->stdouterr_pipe.rd.reset();
9236 PERFETTO_ELOG("CreateProcess failed: %lx, cmd: %s", GetLastError(),
9237 &cmd[0]);
9238 return;
9239 }
9240
9241 s_->pid = proc_info.dwProcessId;
9242 s_->win_proc_handle = ScopedPlatformHandle(proc_info.hProcess);
9243 s_->win_thread_handle = ScopedPlatformHandle(proc_info.hThread);
9244 s_->status = kRunning;
9245
9246 MovableState* s = s_.get();
9247 s_->stdin_thread = std::thread(&Subprocess::StdinThread, s, args.input);
9248
9249 if (args.stderr_mode == kBuffer || args.stdout_mode == kBuffer) {
9250 PERFETTO_DCHECK(s_->stdouterr_pipe.rd);
9251 s_->stdouterr_thread = std::thread(&Subprocess::StdoutErrThread, s);
9252 }
9253 }
9254
9255 // static
StdinThread(MovableState * s,std::string input)9256 void Subprocess::StdinThread(MovableState* s, std::string input) {
9257 size_t input_written = 0;
9258 while (input_written < input.size()) {
9259 DWORD wsize = 0;
9260 if (::WriteFile(*s->stdin_pipe.wr, input.data() + input_written,
9261 static_cast<DWORD>(input.size() - input_written), &wsize,
9262 nullptr)) {
9263 input_written += wsize;
9264 } else {
9265 // ERROR_BROKEN_PIPE is WAI when the child just closes stdin and stops
9266 // accepting input.
9267 auto err = ::GetLastError();
9268 if (err != ERROR_BROKEN_PIPE)
9269 PERFETTO_PLOG("Subprocess WriteFile(stdin) failed %lx", err);
9270 break;
9271 }
9272 } // while(...)
9273 std::unique_lock<std::mutex> lock(s->mutex);
9274 s->stdin_pipe.wr.reset();
9275 }
9276
9277 // static
StdoutErrThread(MovableState * s)9278 void Subprocess::StdoutErrThread(MovableState* s) {
9279 char buf[4096];
9280 for (;;) {
9281 DWORD rsize = 0;
9282 bool res =
9283 ::ReadFile(*s->stdouterr_pipe.rd, buf, sizeof(buf), &rsize, nullptr);
9284 if (!res) {
9285 auto err = GetLastError();
9286 if (err != ERROR_BROKEN_PIPE)
9287 PERFETTO_PLOG("Subprocess ReadFile(stdouterr) failed %ld", err);
9288 }
9289
9290 if (rsize > 0) {
9291 std::unique_lock<std::mutex> lock(s->mutex);
9292 s->locked_outerr_buf.append(buf, static_cast<size_t>(rsize));
9293 } else { // EOF or some error.
9294 break;
9295 }
9296 } // For(..)
9297
9298 // Close the stdouterr_pipe. The main loop looks at the pipe closure to
9299 // determine whether the stdout/err thread has completed.
9300 {
9301 std::unique_lock<std::mutex> lock(s->mutex);
9302 s->stdouterr_pipe.rd.reset();
9303 }
9304 s->stdouterr_done_event.Notify();
9305 }
9306
Poll()9307 Subprocess::Status Subprocess::Poll() {
9308 if (s_->status != kRunning)
9309 return s_->status; // Nothing to poll.
9310 Wait(1 /*ms*/);
9311 return s_->status;
9312 }
9313
Wait(int timeout_ms)9314 bool Subprocess::Wait(int timeout_ms) {
9315 PERFETTO_CHECK(s_->status != kNotStarted);
9316 const bool wait_forever = timeout_ms == 0;
9317 const int64_t wait_start_ms = base::GetWallTimeMs().count();
9318
9319 // Break out of the loop only after both conditions are satisfied:
9320 // - All stdout/stderr data has been read (if kBuffer).
9321 // - The process exited.
9322 // Note that the two events can happen arbitrary order. After the process
9323 // exits, there might be still data in the pipe buffer, which we want to
9324 // read fully.
9325 // Note also that stdout/err might be "complete" before starting, if neither
9326 // is operating in kBuffer mode. In that case we just want to wait for the
9327 // process termination.
9328 //
9329 // Instead, don't wait on the stdin to be fully written. The child process
9330 // might exit prematurely (or crash). If that happens, we can end up in a
9331 // state where the write(stdin_pipe_.wr) will never unblock.
9332 bool stdouterr_complete = false;
9333 for (;;) {
9334 HANDLE wait_handles[2]{};
9335 DWORD num_handles = 0;
9336
9337 // Check if the process exited.
9338 bool process_exited = !s_->win_proc_handle;
9339 if (!process_exited) {
9340 DWORD exit_code = STILL_ACTIVE;
9341 PERFETTO_CHECK(::GetExitCodeProcess(*s_->win_proc_handle, &exit_code));
9342 if (exit_code != STILL_ACTIVE) {
9343 s_->returncode = static_cast<int>(exit_code);
9344 s_->status = kTerminated;
9345 s_->win_proc_handle.reset();
9346 s_->win_thread_handle.reset();
9347 process_exited = true;
9348 }
9349 } else {
9350 PERFETTO_DCHECK(s_->status != kRunning);
9351 }
9352 if (!process_exited) {
9353 wait_handles[num_handles++] = *s_->win_proc_handle;
9354 }
9355
9356 // Check if there is more output and if the stdout/err pipe has been closed.
9357 {
9358 std::unique_lock<std::mutex> lock(s_->mutex);
9359 // Move the output from the internal buffer shared with the
9360 // stdouterr_thread to the final buffer exposed to the client.
9361 if (!s_->locked_outerr_buf.empty()) {
9362 s_->output.append(std::move(s_->locked_outerr_buf));
9363 s_->locked_outerr_buf.clear();
9364 }
9365 stdouterr_complete = !s_->stdouterr_pipe.rd;
9366 if (!stdouterr_complete) {
9367 wait_handles[num_handles++] = s_->stdouterr_done_event.fd();
9368 }
9369 } // lock(s_->mutex)
9370
9371 if (num_handles == 0) {
9372 PERFETTO_DCHECK(process_exited && stdouterr_complete);
9373 break;
9374 }
9375
9376 DWORD wait_ms; // Note: DWORD is unsigned.
9377 if (wait_forever) {
9378 wait_ms = INFINITE;
9379 } else {
9380 const int64_t now = GetWallTimeMs().count();
9381 const int64_t wait_left_ms = timeout_ms - (now - wait_start_ms);
9382 if (wait_left_ms <= 0)
9383 return false; // Timed out
9384 wait_ms = static_cast<DWORD>(wait_left_ms);
9385 }
9386
9387 auto wait_res =
9388 ::WaitForMultipleObjects(num_handles, wait_handles, false, wait_ms);
9389 PERFETTO_CHECK(wait_res != WAIT_FAILED);
9390 }
9391
9392 PERFETTO_DCHECK(!s_->win_proc_handle);
9393 PERFETTO_DCHECK(!s_->win_thread_handle);
9394
9395 if (s_->stdin_thread.joinable()) // Might not exist if CreateProcess failed.
9396 s_->stdin_thread.join();
9397 if (s_->stdouterr_thread.joinable())
9398 s_->stdouterr_thread.join();
9399
9400 // The stdin pipe is closed by the dedicated stdin thread. However if that is
9401 // not started (e.g. because of no redirection) force close it now. Needs to
9402 // happen after the join() to be thread safe.
9403 s_->stdin_pipe.wr.reset();
9404 s_->stdouterr_pipe.rd.reset();
9405
9406 return true;
9407 }
9408
KillAndWaitForTermination(int exit_code)9409 void Subprocess::KillAndWaitForTermination(int exit_code) {
9410 auto code = exit_code ? static_cast<DWORD>(exit_code) : STATUS_CONTROL_C_EXIT;
9411 ::TerminateProcess(*s_->win_proc_handle, code);
9412 Wait();
9413 // TryReadExitStatus must have joined the threads.
9414 PERFETTO_DCHECK(!s_->stdin_thread.joinable());
9415 PERFETTO_DCHECK(!s_->stdouterr_thread.joinable());
9416 }
9417
9418 } // namespace base
9419 } // namespace perfetto
9420
9421 #endif // PERFETTO_OS_WIN
9422 // gen_amalgamated begin source: src/protozero/field.cc
9423 /*
9424 * Copyright (C) 2019 The Android Open Source Project
9425 *
9426 * Licensed under the Apache License, Version 2.0 (the "License");
9427 * you may not use this file except in compliance with the License.
9428 * You may obtain a copy of the License at
9429 *
9430 * http://www.apache.org/licenses/LICENSE-2.0
9431 *
9432 * Unless required by applicable law or agreed to in writing, software
9433 * distributed under the License is distributed on an "AS IS" BASIS,
9434 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9435 * See the License for the specific language governing permissions and
9436 * limitations under the License.
9437 */
9438
9439 // gen_amalgamated expanded: #include "perfetto/protozero/field.h"
9440
9441 // gen_amalgamated expanded: #include "perfetto/base/compiler.h"
9442 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
9443
9444 #if !PERFETTO_IS_LITTLE_ENDIAN()
9445 // The memcpy() for fixed32/64 below needs to be adjusted if we want to
9446 // support big endian CPUs. There doesn't seem to be a compelling need today.
9447 #error Unimplemented for big endian archs.
9448 #endif
9449
9450 namespace protozero {
9451
9452 template <typename Container>
SerializeAndAppendToInternal(Container * dst) const9453 void Field::SerializeAndAppendToInternal(Container* dst) const {
9454 namespace pu = proto_utils;
9455 size_t initial_size = dst->size();
9456 dst->resize(initial_size + pu::kMaxSimpleFieldEncodedSize + size_);
9457 uint8_t* start = reinterpret_cast<uint8_t*>(&(*dst)[initial_size]);
9458 uint8_t* wptr = start;
9459 switch (type_) {
9460 case static_cast<int>(pu::ProtoWireType::kVarInt): {
9461 wptr = pu::WriteVarInt(pu::MakeTagVarInt(id_), wptr);
9462 wptr = pu::WriteVarInt(int_value_, wptr);
9463 break;
9464 }
9465 case static_cast<int>(pu::ProtoWireType::kFixed32): {
9466 wptr = pu::WriteVarInt(pu::MakeTagFixed<uint32_t>(id_), wptr);
9467 uint32_t value32 = static_cast<uint32_t>(int_value_);
9468 memcpy(wptr, &value32, sizeof(value32));
9469 wptr += sizeof(uint32_t);
9470 break;
9471 }
9472 case static_cast<int>(pu::ProtoWireType::kFixed64): {
9473 wptr = pu::WriteVarInt(pu::MakeTagFixed<uint64_t>(id_), wptr);
9474 memcpy(wptr, &int_value_, sizeof(int_value_));
9475 wptr += sizeof(uint64_t);
9476 break;
9477 }
9478 case static_cast<int>(pu::ProtoWireType::kLengthDelimited): {
9479 ConstBytes payload = as_bytes();
9480 wptr = pu::WriteVarInt(pu::MakeTagLengthDelimited(id_), wptr);
9481 wptr = pu::WriteVarInt(payload.size, wptr);
9482 memcpy(wptr, payload.data, payload.size);
9483 wptr += payload.size;
9484 break;
9485 }
9486 default:
9487 PERFETTO_FATAL("Unknown field type %u", type_);
9488 }
9489 size_t written_size = static_cast<size_t>(wptr - start);
9490 PERFETTO_DCHECK(written_size > 0 && written_size < pu::kMaxMessageLength);
9491 PERFETTO_DCHECK(initial_size + written_size <= dst->size());
9492 dst->resize(initial_size + written_size);
9493 }
9494
SerializeAndAppendTo(std::string * dst) const9495 void Field::SerializeAndAppendTo(std::string* dst) const {
9496 SerializeAndAppendToInternal(dst);
9497 }
9498
SerializeAndAppendTo(std::vector<uint8_t> * dst) const9499 void Field::SerializeAndAppendTo(std::vector<uint8_t>* dst) const {
9500 SerializeAndAppendToInternal(dst);
9501 }
9502
9503 } // namespace protozero
9504 // gen_amalgamated begin source: src/protozero/message.cc
9505 /*
9506 * Copyright (C) 2017 The Android Open Source Project
9507 *
9508 * Licensed under the Apache License, Version 2.0 (the "License");
9509 * you may not use this file except in compliance with the License.
9510 * You may obtain a copy of the License at
9511 *
9512 * http://www.apache.org/licenses/LICENSE-2.0
9513 *
9514 * Unless required by applicable law or agreed to in writing, software
9515 * distributed under the License is distributed on an "AS IS" BASIS,
9516 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9517 * See the License for the specific language governing permissions and
9518 * limitations under the License.
9519 */
9520
9521 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
9522
9523 #include <atomic>
9524 #include <type_traits>
9525
9526 // gen_amalgamated expanded: #include "perfetto/base/compiler.h"
9527 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
9528 // gen_amalgamated expanded: #include "perfetto/protozero/message_arena.h"
9529 // gen_amalgamated expanded: #include "perfetto/protozero/message_handle.h"
9530
9531 #if !PERFETTO_IS_LITTLE_ENDIAN()
9532 // The memcpy() for float and double below needs to be adjusted if we want to
9533 // support big endian CPUs. There doesn't seem to be a compelling need today.
9534 #error Unimplemented for big endian archs.
9535 #endif
9536
9537 namespace protozero {
9538
9539 namespace {
9540
9541 #if PERFETTO_DCHECK_IS_ON()
9542 std::atomic<uint32_t> g_generation;
9543 #endif
9544
9545 } // namespace
9546
9547 // Do NOT put any code in the constructor or use default initialization.
9548 // Use the Reset() method below instead.
9549
9550 // This method is called to initialize both root and nested messages.
Reset(ScatteredStreamWriter * stream_writer,MessageArena * arena)9551 void Message::Reset(ScatteredStreamWriter* stream_writer, MessageArena* arena) {
9552 // Older versions of libstdcxx don't have is_trivially_constructible.
9553 #if !defined(__GLIBCXX__) || __GLIBCXX__ >= 20170516
9554 static_assert(std::is_trivially_constructible<Message>::value,
9555 "Message must be trivially constructible");
9556 #endif
9557
9558 static_assert(std::is_trivially_destructible<Message>::value,
9559 "Message must be trivially destructible");
9560 stream_writer_ = stream_writer;
9561 arena_ = arena;
9562 size_ = 0;
9563 size_field_ = nullptr;
9564 size_already_written_ = 0;
9565 nested_message_ = nullptr;
9566 finalized_ = false;
9567 #if PERFETTO_DCHECK_IS_ON()
9568 handle_ = nullptr;
9569 generation_ = g_generation.fetch_add(1, std::memory_order_relaxed);
9570 #endif
9571 }
9572
AppendString(uint32_t field_id,const char * str)9573 void Message::AppendString(uint32_t field_id, const char* str) {
9574 AppendBytes(field_id, str, strlen(str));
9575 }
9576
AppendBytes(uint32_t field_id,const void * src,size_t size)9577 void Message::AppendBytes(uint32_t field_id, const void* src, size_t size) {
9578 if (nested_message_)
9579 EndNestedMessage();
9580
9581 PERFETTO_DCHECK(size < proto_utils::kMaxMessageLength);
9582 // Write the proto preamble (field id, type and length of the field).
9583 uint8_t buffer[proto_utils::kMaxSimpleFieldEncodedSize];
9584 uint8_t* pos = buffer;
9585 pos = proto_utils::WriteVarInt(proto_utils::MakeTagLengthDelimited(field_id),
9586 pos);
9587 pos = proto_utils::WriteVarInt(static_cast<uint32_t>(size), pos);
9588 WriteToStream(buffer, pos);
9589
9590 const uint8_t* src_u8 = reinterpret_cast<const uint8_t*>(src);
9591 WriteToStream(src_u8, src_u8 + size);
9592 }
9593
AppendScatteredBytes(uint32_t field_id,ContiguousMemoryRange * ranges,size_t num_ranges)9594 size_t Message::AppendScatteredBytes(uint32_t field_id,
9595 ContiguousMemoryRange* ranges,
9596 size_t num_ranges) {
9597 size_t size = 0;
9598 for (size_t i = 0; i < num_ranges; ++i) {
9599 size += ranges[i].size();
9600 }
9601
9602 PERFETTO_DCHECK(size < proto_utils::kMaxMessageLength);
9603
9604 uint8_t buffer[proto_utils::kMaxSimpleFieldEncodedSize];
9605 uint8_t* pos = buffer;
9606 pos = proto_utils::WriteVarInt(proto_utils::MakeTagLengthDelimited(field_id),
9607 pos);
9608 pos = proto_utils::WriteVarInt(static_cast<uint32_t>(size), pos);
9609 WriteToStream(buffer, pos);
9610
9611 for (size_t i = 0; i < num_ranges; ++i) {
9612 auto& range = ranges[i];
9613 WriteToStream(range.begin, range.end);
9614 }
9615
9616 return size;
9617 }
9618
Finalize()9619 uint32_t Message::Finalize() {
9620 if (finalized_)
9621 return size_;
9622
9623 if (nested_message_)
9624 EndNestedMessage();
9625
9626 // Write the length of the nested message a posteriori, using a leading-zero
9627 // redundant varint encoding.
9628 if (size_field_) {
9629 PERFETTO_DCHECK(!finalized_);
9630 PERFETTO_DCHECK(size_ < proto_utils::kMaxMessageLength);
9631 PERFETTO_DCHECK(size_ >= size_already_written_);
9632 proto_utils::WriteRedundantVarInt(size_ - size_already_written_,
9633 size_field_);
9634 size_field_ = nullptr;
9635 }
9636
9637 finalized_ = true;
9638 #if PERFETTO_DCHECK_IS_ON()
9639 if (handle_)
9640 handle_->reset_message();
9641 #endif
9642
9643 return size_;
9644 }
9645
BeginNestedMessageInternal(uint32_t field_id)9646 Message* Message::BeginNestedMessageInternal(uint32_t field_id) {
9647 if (nested_message_)
9648 EndNestedMessage();
9649
9650 // Write the proto preamble for the nested message.
9651 uint8_t data[proto_utils::kMaxTagEncodedSize];
9652 uint8_t* data_end = proto_utils::WriteVarInt(
9653 proto_utils::MakeTagLengthDelimited(field_id), data);
9654 WriteToStream(data, data_end);
9655
9656 Message* message = arena_->NewMessage();
9657 message->Reset(stream_writer_, arena_);
9658
9659 // The length of the nested message cannot be known upfront. So right now
9660 // just reserve the bytes to encode the size after the nested message is done.
9661 message->set_size_field(
9662 stream_writer_->ReserveBytes(proto_utils::kMessageLengthFieldSize));
9663 size_ += proto_utils::kMessageLengthFieldSize;
9664
9665 nested_message_ = message;
9666 return message;
9667 }
9668
EndNestedMessage()9669 void Message::EndNestedMessage() {
9670 size_ += nested_message_->Finalize();
9671 arena_->DeleteLastMessage(nested_message_);
9672 nested_message_ = nullptr;
9673 }
9674
9675 } // namespace protozero
9676 // gen_amalgamated begin source: src/protozero/message_arena.cc
9677 /*
9678 * Copyright (C) 2020 The Android Open Source Project
9679 *
9680 * Licensed under the Apache License, Version 2.0 (the "License");
9681 * you may not use this file except in compliance with the License.
9682 * You may obtain a copy of the License at
9683 *
9684 * http://www.apache.org/licenses/LICENSE-2.0
9685 *
9686 * Unless required by applicable law or agreed to in writing, software
9687 * distributed under the License is distributed on an "AS IS" BASIS,
9688 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9689 * See the License for the specific language governing permissions and
9690 * limitations under the License.
9691 */
9692
9693 // gen_amalgamated expanded: #include "perfetto/protozero/message_arena.h"
9694
9695 #include <atomic>
9696 #include <type_traits>
9697
9698 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
9699 // gen_amalgamated expanded: #include "perfetto/protozero/message_handle.h"
9700
9701 namespace protozero {
9702
MessageArena()9703 MessageArena::MessageArena() {
9704 // The code below assumes that there is always at least one block.
9705 blocks_.emplace_front();
9706 static_assert(std::alignment_of<decltype(blocks_.back().storage[0])>::value >=
9707 alignof(Message),
9708 "MessageArea's storage is not properly aligned");
9709 }
9710
9711 MessageArena::~MessageArena() = default;
9712
NewMessage()9713 Message* MessageArena::NewMessage() {
9714 PERFETTO_DCHECK(!blocks_.empty()); // Should never become empty.
9715
9716 Block* block = &blocks_.back();
9717 if (PERFETTO_UNLIKELY(block->entries >= Block::kCapacity)) {
9718 blocks_.emplace_back();
9719 block = &blocks_.back();
9720 }
9721 const auto idx = block->entries++;
9722 void* storage = &block->storage[idx];
9723 PERFETTO_ASAN_UNPOISON(storage, sizeof(Message));
9724 return new (storage) Message();
9725 }
9726
DeleteLastMessageInternal()9727 void MessageArena::DeleteLastMessageInternal() {
9728 PERFETTO_DCHECK(!blocks_.empty()); // Should never be empty, see below.
9729 Block* block = &blocks_.back();
9730 PERFETTO_DCHECK(block->entries > 0);
9731
9732 // This is the reason why there is no ~Message() call here.
9733 // MessageArea::Reset() (see header) also relies on dtor being trivial.
9734 static_assert(std::is_trivially_destructible<Message>::value,
9735 "Message must be trivially destructible");
9736
9737 --block->entries;
9738 PERFETTO_ASAN_POISON(&block->storage[block->entries], sizeof(Message));
9739
9740 // Don't remove the first block to avoid malloc/free calls when the root
9741 // message is reset. Hitting the allocator all the times is a waste of time.
9742 if (block->entries == 0 && blocks_.size() > 1) {
9743 blocks_.pop_back();
9744 }
9745 }
9746
9747 } // namespace protozero
9748 // gen_amalgamated begin source: src/protozero/message_handle.cc
9749 /*
9750 * Copyright (C) 2017 The Android Open Source Project
9751 *
9752 * Licensed under the Apache License, Version 2.0 (the "License");
9753 * you may not use this file except in compliance with the License.
9754 * You may obtain a copy of the License at
9755 *
9756 * http://www.apache.org/licenses/LICENSE-2.0
9757 *
9758 * Unless required by applicable law or agreed to in writing, software
9759 * distributed under the License is distributed on an "AS IS" BASIS,
9760 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9761 * See the License for the specific language governing permissions and
9762 * limitations under the License.
9763 */
9764
9765 // gen_amalgamated expanded: #include "perfetto/protozero/message_handle.h"
9766
9767 #include <utility>
9768
9769 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
9770
9771 namespace protozero {
9772
MessageHandleBase(Message * message)9773 MessageHandleBase::MessageHandleBase(Message* message) : message_(message) {
9774 #if PERFETTO_DCHECK_IS_ON()
9775 generation_ = message_ ? message->generation_ : 0;
9776 if (message_)
9777 message_->set_handle(this);
9778 #endif
9779 }
9780
~MessageHandleBase()9781 MessageHandleBase::~MessageHandleBase() {
9782 if (message_) {
9783 #if PERFETTO_DCHECK_IS_ON()
9784 PERFETTO_DCHECK(generation_ == message_->generation_);
9785 #endif
9786 FinalizeMessage();
9787 }
9788 }
9789
MessageHandleBase(MessageHandleBase && other)9790 MessageHandleBase::MessageHandleBase(MessageHandleBase&& other) noexcept {
9791 Move(std::move(other));
9792 }
9793
operator =(MessageHandleBase && other)9794 MessageHandleBase& MessageHandleBase::operator=(MessageHandleBase&& other) {
9795 // If the current handle was pointing to a message and is being reset to a new
9796 // one, finalize the old message. However, if the other message is the same as
9797 // the one we point to, don't finalize.
9798 if (message_ && message_ != other.message_)
9799 FinalizeMessage();
9800 Move(std::move(other));
9801 return *this;
9802 }
9803
Move(MessageHandleBase && other)9804 void MessageHandleBase::Move(MessageHandleBase&& other) {
9805 message_ = other.message_;
9806 other.message_ = nullptr;
9807 #if PERFETTO_DCHECK_IS_ON()
9808 if (message_) {
9809 generation_ = message_->generation_;
9810 message_->set_handle(this);
9811 }
9812 #endif
9813 }
9814
9815 } // namespace protozero
9816 // gen_amalgamated begin source: src/protozero/packed_repeated_fields.cc
9817 /*
9818 * Copyright (C) 2017 The Android Open Source Project
9819 *
9820 * Licensed under the Apache License, Version 2.0 (the "License");
9821 * you may not use this file except in compliance with the License.
9822 * You may obtain a copy of the License at
9823 *
9824 * http://www.apache.org/licenses/LICENSE-2.0
9825 *
9826 * Unless required by applicable law or agreed to in writing, software
9827 * distributed under the License is distributed on an "AS IS" BASIS,
9828 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9829 * See the License for the specific language governing permissions and
9830 * limitations under the License.
9831 */
9832
9833 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
9834
9835 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
9836
9837 namespace protozero {
9838
9839 // static
9840 constexpr size_t PackedBufferBase::kOnStackStorageSize;
9841
GrowSlowpath()9842 void PackedBufferBase::GrowSlowpath() {
9843 size_t write_off = static_cast<size_t>(write_ptr_ - storage_begin_);
9844 size_t old_size = static_cast<size_t>(storage_end_ - storage_begin_);
9845 size_t new_size = old_size < 65536 ? (old_size * 2) : (old_size * 3 / 2);
9846 new_size = perfetto::base::AlignUp<4096>(new_size);
9847 std::unique_ptr<uint8_t[]> new_buf(new uint8_t[new_size]);
9848 memcpy(new_buf.get(), storage_begin_, old_size);
9849 heap_buf_ = std::move(new_buf);
9850 storage_begin_ = heap_buf_.get();
9851 storage_end_ = storage_begin_ + new_size;
9852 write_ptr_ = storage_begin_ + write_off;
9853 }
9854
Reset()9855 void PackedBufferBase::Reset() {
9856 heap_buf_.reset();
9857 storage_begin_ = reinterpret_cast<uint8_t*>(&stack_buf_[0]);
9858 storage_end_ = reinterpret_cast<uint8_t*>(&stack_buf_[kOnStackStorageSize]);
9859 write_ptr_ = storage_begin_;
9860 }
9861
9862 } // namespace protozero
9863 // gen_amalgamated begin source: src/protozero/proto_decoder.cc
9864 /*
9865 * Copyright (C) 2018 The Android Open Source Project
9866 *
9867 * Licensed under the Apache License, Version 2.0 (the "License");
9868 * you may not use this file except in compliance with the License.
9869 * You may obtain a copy of the License at
9870 *
9871 * http://www.apache.org/licenses/LICENSE-2.0
9872 *
9873 * Unless required by applicable law or agreed to in writing, software
9874 * distributed under the License is distributed on an "AS IS" BASIS,
9875 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9876 * See the License for the specific language governing permissions and
9877 * limitations under the License.
9878 */
9879
9880 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
9881
9882 #include <string.h>
9883
9884 #include <cinttypes>
9885 #include <limits>
9886 #include <memory>
9887
9888 // gen_amalgamated expanded: #include "perfetto/base/compiler.h"
9889 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
9890 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
9891 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
9892
9893 namespace protozero {
9894
9895 using namespace proto_utils;
9896
9897 #if !PERFETTO_IS_LITTLE_ENDIAN()
9898 #error Unimplemented for big endian archs.
9899 #endif
9900
9901 namespace {
9902
9903 struct ParseFieldResult {
9904 enum ParseResult { kAbort, kSkip, kOk };
9905 ParseResult parse_res;
9906 const uint8_t* next;
9907 Field field;
9908 };
9909
9910 // Parses one field and returns the field itself and a pointer to the next
9911 // field to parse. If parsing fails, the returned |next| == |buffer|.
9912 PERFETTO_ALWAYS_INLINE ParseFieldResult
ParseOneField(const uint8_t * const buffer,const uint8_t * const end)9913 ParseOneField(const uint8_t* const buffer, const uint8_t* const end) {
9914 ParseFieldResult res{ParseFieldResult::kAbort, buffer, Field{}};
9915
9916 // The first byte of a proto field is structured as follows:
9917 // The least 3 significant bits determine the field type.
9918 // The most 5 significant bits determine the field id. If MSB == 1, the
9919 // field id continues on the next bytes following the VarInt encoding.
9920 const uint8_t kFieldTypeNumBits = 3;
9921 const uint64_t kFieldTypeMask = (1 << kFieldTypeNumBits) - 1; // 0000 0111;
9922 const uint8_t* pos = buffer;
9923
9924 // If we've already hit the end, just return an invalid field.
9925 if (PERFETTO_UNLIKELY(pos >= end))
9926 return res;
9927
9928 uint64_t preamble = 0;
9929 if (PERFETTO_LIKELY(*pos < 0x80)) { // Fastpath for fields with ID < 16.
9930 preamble = *(pos++);
9931 } else {
9932 const uint8_t* next = ParseVarInt(pos, end, &preamble);
9933 if (PERFETTO_UNLIKELY(pos == next))
9934 return res;
9935 pos = next;
9936 }
9937
9938 uint32_t field_id = static_cast<uint32_t>(preamble >> kFieldTypeNumBits);
9939 if (field_id == 0 || pos >= end)
9940 return res;
9941
9942 auto field_type = static_cast<uint8_t>(preamble & kFieldTypeMask);
9943 const uint8_t* new_pos = pos;
9944 uint64_t int_value = 0;
9945 uint64_t size = 0;
9946
9947 switch (field_type) {
9948 case static_cast<uint8_t>(ProtoWireType::kVarInt): {
9949 new_pos = ParseVarInt(pos, end, &int_value);
9950
9951 // new_pos not being greater than pos means ParseVarInt could not fully
9952 // parse the number. This is because we are out of space in the buffer.
9953 // Set the id to zero and return but don't update the offset so a future
9954 // read can read this field.
9955 if (PERFETTO_UNLIKELY(new_pos == pos))
9956 return res;
9957
9958 break;
9959 }
9960
9961 case static_cast<uint8_t>(ProtoWireType::kLengthDelimited): {
9962 uint64_t payload_length;
9963 new_pos = ParseVarInt(pos, end, &payload_length);
9964 if (PERFETTO_UNLIKELY(new_pos == pos))
9965 return res;
9966
9967 // ParseVarInt guarantees that |new_pos| <= |end| when it succeeds;
9968 if (payload_length > static_cast<uint64_t>(end - new_pos))
9969 return res;
9970
9971 const uintptr_t payload_start = reinterpret_cast<uintptr_t>(new_pos);
9972 int_value = payload_start;
9973 size = payload_length;
9974 new_pos += payload_length;
9975 break;
9976 }
9977
9978 case static_cast<uint8_t>(ProtoWireType::kFixed64): {
9979 new_pos = pos + sizeof(uint64_t);
9980 if (PERFETTO_UNLIKELY(new_pos > end))
9981 return res;
9982 memcpy(&int_value, pos, sizeof(uint64_t));
9983 break;
9984 }
9985
9986 case static_cast<uint8_t>(ProtoWireType::kFixed32): {
9987 new_pos = pos + sizeof(uint32_t);
9988 if (PERFETTO_UNLIKELY(new_pos > end))
9989 return res;
9990 memcpy(&int_value, pos, sizeof(uint32_t));
9991 break;
9992 }
9993
9994 default:
9995 PERFETTO_DLOG("Invalid proto field type: %u", field_type);
9996 return res;
9997 }
9998
9999 res.next = new_pos;
10000
10001 if (PERFETTO_UNLIKELY(field_id > std::numeric_limits<uint16_t>::max())) {
10002 PERFETTO_DLOG("Skipping field %" PRIu32 " because its id > 0xFFFF",
10003 field_id);
10004 res.parse_res = ParseFieldResult::kSkip;
10005 return res;
10006 }
10007
10008 if (PERFETTO_UNLIKELY(size > proto_utils::kMaxMessageLength)) {
10009 PERFETTO_DLOG("Skipping field %" PRIu32 " because it's too big (%" PRIu64
10010 " KB)",
10011 field_id, size / 1024);
10012 res.parse_res = ParseFieldResult::kSkip;
10013 return res;
10014 }
10015
10016 res.parse_res = ParseFieldResult::kOk;
10017 res.field.initialize(static_cast<uint16_t>(field_id), field_type, int_value,
10018 static_cast<uint32_t>(size));
10019 return res;
10020 }
10021
10022 } // namespace
10023
FindField(uint32_t field_id)10024 Field ProtoDecoder::FindField(uint32_t field_id) {
10025 Field res{};
10026 auto old_position = read_ptr_;
10027 read_ptr_ = begin_;
10028 for (auto f = ReadField(); f.valid(); f = ReadField()) {
10029 if (f.id() == field_id) {
10030 res = f;
10031 break;
10032 }
10033 }
10034 read_ptr_ = old_position;
10035 return res;
10036 }
10037
10038 PERFETTO_ALWAYS_INLINE
ReadField()10039 Field ProtoDecoder::ReadField() {
10040 ParseFieldResult res;
10041 do {
10042 res = ParseOneField(read_ptr_, end_);
10043 read_ptr_ = res.next;
10044 } while (PERFETTO_UNLIKELY(res.parse_res == ParseFieldResult::kSkip));
10045 return res.field;
10046 }
10047
ParseAllFields()10048 void TypedProtoDecoderBase::ParseAllFields() {
10049 const uint8_t* cur = begin_;
10050 ParseFieldResult res;
10051 for (;;) {
10052 res = ParseOneField(cur, end_);
10053 PERFETTO_DCHECK(res.parse_res != ParseFieldResult::kOk || res.next != cur);
10054 cur = res.next;
10055 if (PERFETTO_UNLIKELY(res.parse_res == ParseFieldResult::kSkip))
10056 continue;
10057 if (PERFETTO_UNLIKELY(res.parse_res == ParseFieldResult::kAbort))
10058 break;
10059
10060 PERFETTO_DCHECK(res.parse_res == ParseFieldResult::kOk);
10061 PERFETTO_DCHECK(res.field.valid());
10062 auto field_id = res.field.id();
10063 if (PERFETTO_UNLIKELY(field_id >= num_fields_))
10064 continue;
10065
10066 // There are two reasons why we might want to expand the heap capacity:
10067 // 1. We are writing a non-repeated field, which has an id >
10068 // INITIAL_STACK_CAPACITY. In this case ExpandHeapStorage() ensures to
10069 // allocate at least (num_fields_ + 1) slots.
10070 // 2. We are writing a repeated field but ran out of capacity.
10071 if (PERFETTO_UNLIKELY(field_id >= size_ || size_ >= capacity_))
10072 ExpandHeapStorage();
10073
10074 PERFETTO_DCHECK(field_id < size_);
10075 Field* fld = &fields_[field_id];
10076 if (PERFETTO_LIKELY(!fld->valid())) {
10077 // This is the first time we see this field.
10078 *fld = std::move(res.field);
10079 } else {
10080 // Repeated field case.
10081 // In this case we need to:
10082 // 1. Append the last value of the field to end of the repeated field
10083 // storage.
10084 // 2. Replace the default instance at offset |field_id| with the current
10085 // value. This is because in case of repeated field a call to Get(X) is
10086 // supposed to return the last value of X, not the first one.
10087 // This is so that the RepeatedFieldIterator will iterate in the right
10088 // order, see comments on RepeatedFieldIterator.
10089 PERFETTO_DCHECK(size_ < capacity_);
10090 fields_[size_++] = *fld;
10091 *fld = std::move(res.field);
10092 }
10093 }
10094 read_ptr_ = res.next;
10095 }
10096
ExpandHeapStorage()10097 void TypedProtoDecoderBase::ExpandHeapStorage() {
10098 // When we expand the heap we must ensure that we have at very last capacity
10099 // to deal with all known fields plus at least one repeated field. We go +2048
10100 // here based on observations on a large 4GB android trace. This is to avoid
10101 // trivial re-allocations when dealing with repeated fields of a message that
10102 // has > INITIAL_STACK_CAPACITY fields.
10103 const uint32_t min_capacity = num_fields_ + 2048; // Any num >= +1 will do.
10104 const uint32_t new_capacity = std::max(capacity_ * 2, min_capacity);
10105 PERFETTO_CHECK(new_capacity > size_ && new_capacity > num_fields_);
10106 std::unique_ptr<Field[]> new_storage(new Field[new_capacity]);
10107
10108 static_assert(std::is_trivially_constructible<Field>::value,
10109 "Field must be trivially constructible");
10110 static_assert(std::is_trivially_copyable<Field>::value,
10111 "Field must be trivially copyable");
10112
10113 // Zero-initialize the slots for known field IDs slots, as they can be
10114 // randomly accessed. Instead, there is no need to initialize the repeated
10115 // slots, because they are written linearly with no gaps and are always
10116 // initialized before incrementing |size_|.
10117 const uint32_t new_size = std::max(size_, num_fields_);
10118 memset(&new_storage[size_], 0, sizeof(Field) * (new_size - size_));
10119
10120 memcpy(&new_storage[0], fields_, sizeof(Field) * size_);
10121
10122 heap_storage_ = std::move(new_storage);
10123 fields_ = &heap_storage_[0];
10124 capacity_ = new_capacity;
10125 size_ = new_size;
10126 }
10127
10128 } // namespace protozero
10129 // gen_amalgamated begin source: src/protozero/scattered_heap_buffer.cc
10130 /*
10131 * Copyright (C) 2017 The Android Open Source Project
10132 *
10133 * Licensed under the Apache License, Version 2.0 (the "License");
10134 * you may not use this file except in compliance with the License.
10135 * You may obtain a copy of the License at
10136 *
10137 * http://www.apache.org/licenses/LICENSE-2.0
10138 *
10139 * Unless required by applicable law or agreed to in writing, software
10140 * distributed under the License is distributed on an "AS IS" BASIS,
10141 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10142 * See the License for the specific language governing permissions and
10143 * limitations under the License.
10144 */
10145
10146 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
10147
10148 #include <algorithm>
10149
10150 namespace protozero {
10151
Slice()10152 ScatteredHeapBuffer::Slice::Slice()
10153 : buffer_(nullptr), size_(0u), unused_bytes_(0u) {}
10154
Slice(size_t size)10155 ScatteredHeapBuffer::Slice::Slice(size_t size)
10156 : buffer_(std::unique_ptr<uint8_t[]>(new uint8_t[size])),
10157 size_(size),
10158 unused_bytes_(size) {
10159 PERFETTO_DCHECK(size);
10160 Clear();
10161 }
10162
10163 ScatteredHeapBuffer::Slice::Slice(Slice&& slice) noexcept = default;
10164
10165 ScatteredHeapBuffer::Slice::~Slice() = default;
10166
10167 ScatteredHeapBuffer::Slice& ScatteredHeapBuffer::Slice::operator=(Slice&&) =
10168 default;
10169
Clear()10170 void ScatteredHeapBuffer::Slice::Clear() {
10171 unused_bytes_ = size_;
10172 #if PERFETTO_DCHECK_IS_ON()
10173 memset(start(), 0xff, size_);
10174 #endif // PERFETTO_DCHECK_IS_ON()
10175 }
10176
ScatteredHeapBuffer(size_t initial_slice_size_bytes,size_t maximum_slice_size_bytes)10177 ScatteredHeapBuffer::ScatteredHeapBuffer(size_t initial_slice_size_bytes,
10178 size_t maximum_slice_size_bytes)
10179 : next_slice_size_(initial_slice_size_bytes),
10180 maximum_slice_size_(maximum_slice_size_bytes) {
10181 PERFETTO_DCHECK(next_slice_size_ && maximum_slice_size_);
10182 PERFETTO_DCHECK(maximum_slice_size_ >= initial_slice_size_bytes);
10183 }
10184
10185 ScatteredHeapBuffer::~ScatteredHeapBuffer() = default;
10186
GetNewBuffer()10187 protozero::ContiguousMemoryRange ScatteredHeapBuffer::GetNewBuffer() {
10188 PERFETTO_CHECK(writer_);
10189 AdjustUsedSizeOfCurrentSlice();
10190
10191 if (cached_slice_.start()) {
10192 slices_.push_back(std::move(cached_slice_));
10193 PERFETTO_DCHECK(!cached_slice_.start());
10194 } else {
10195 slices_.emplace_back(next_slice_size_);
10196 }
10197 next_slice_size_ = std::min(maximum_slice_size_, next_slice_size_ * 2);
10198 return slices_.back().GetTotalRange();
10199 }
10200
10201 const std::vector<ScatteredHeapBuffer::Slice>&
GetSlices()10202 ScatteredHeapBuffer::GetSlices() {
10203 AdjustUsedSizeOfCurrentSlice();
10204 return slices_;
10205 }
10206
StitchSlices()10207 std::vector<uint8_t> ScatteredHeapBuffer::StitchSlices() {
10208 size_t stitched_size = 0u;
10209 const auto& slices = GetSlices();
10210 for (const auto& slice : slices)
10211 stitched_size += slice.size() - slice.unused_bytes();
10212
10213 std::vector<uint8_t> buffer;
10214 buffer.reserve(stitched_size);
10215 for (const auto& slice : slices) {
10216 auto used_range = slice.GetUsedRange();
10217 buffer.insert(buffer.end(), used_range.begin, used_range.end);
10218 }
10219 return buffer;
10220 }
10221
GetRanges()10222 std::vector<protozero::ContiguousMemoryRange> ScatteredHeapBuffer::GetRanges() {
10223 std::vector<protozero::ContiguousMemoryRange> ranges;
10224 for (const auto& slice : GetSlices())
10225 ranges.push_back(slice.GetUsedRange());
10226 return ranges;
10227 }
10228
AdjustUsedSizeOfCurrentSlice()10229 void ScatteredHeapBuffer::AdjustUsedSizeOfCurrentSlice() {
10230 if (!slices_.empty())
10231 slices_.back().set_unused_bytes(writer_->bytes_available());
10232 }
10233
GetTotalSize()10234 size_t ScatteredHeapBuffer::GetTotalSize() {
10235 size_t total_size = 0;
10236 for (auto& slice : slices_) {
10237 total_size += slice.size();
10238 }
10239 return total_size;
10240 }
10241
Reset()10242 void ScatteredHeapBuffer::Reset() {
10243 if (slices_.empty())
10244 return;
10245 cached_slice_ = std::move(slices_.front());
10246 cached_slice_.Clear();
10247 slices_.clear();
10248 }
10249
10250 } // namespace protozero
10251 // gen_amalgamated begin source: src/protozero/scattered_stream_null_delegate.cc
10252 // gen_amalgamated begin header: include/perfetto/protozero/scattered_stream_null_delegate.h
10253 /*
10254 * Copyright (C) 2018 The Android Open Source Project
10255 *
10256 * Licensed under the Apache License, Version 2.0 (the "License");
10257 * you may not use this file except in compliance with the License.
10258 * You may obtain a copy of the License at
10259 *
10260 * http://www.apache.org/licenses/LICENSE-2.0
10261 *
10262 * Unless required by applicable law or agreed to in writing, software
10263 * distributed under the License is distributed on an "AS IS" BASIS,
10264 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10265 * See the License for the specific language governing permissions and
10266 * limitations under the License.
10267 */
10268
10269 #ifndef INCLUDE_PERFETTO_PROTOZERO_SCATTERED_STREAM_NULL_DELEGATE_H_
10270 #define INCLUDE_PERFETTO_PROTOZERO_SCATTERED_STREAM_NULL_DELEGATE_H_
10271
10272 #include <memory>
10273 #include <vector>
10274
10275 // gen_amalgamated expanded: #include "perfetto/base/export.h"
10276 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
10277 // gen_amalgamated expanded: #include "perfetto/protozero/contiguous_memory_range.h"
10278 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_stream_writer.h"
10279
10280 namespace protozero {
10281
10282 class PERFETTO_EXPORT ScatteredStreamWriterNullDelegate
10283 : public ScatteredStreamWriter::Delegate {
10284 public:
10285 explicit ScatteredStreamWriterNullDelegate(size_t chunk_size);
10286 ~ScatteredStreamWriterNullDelegate() override;
10287
10288 // protozero::ScatteredStreamWriter::Delegate implementation.
10289 ContiguousMemoryRange GetNewBuffer() override;
10290
10291 private:
10292 const size_t chunk_size_;
10293 std::unique_ptr<uint8_t[]> chunk_;
10294 };
10295
10296 } // namespace protozero
10297
10298 #endif // INCLUDE_PERFETTO_PROTOZERO_SCATTERED_STREAM_NULL_DELEGATE_H_
10299 /*
10300 * Copyright (C) 2018 The Android Open Source Project
10301 *
10302 * Licensed under the Apache License, Version 2.0 (the "License");
10303 * you may not use this file except in compliance with the License.
10304 * You may obtain a copy of the License at
10305 *
10306 * http://www.apache.org/licenses/LICENSE-2.0
10307 *
10308 * Unless required by applicable law or agreed to in writing, software
10309 * distributed under the License is distributed on an "AS IS" BASIS,
10310 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10311 * See the License for the specific language governing permissions and
10312 * limitations under the License.
10313 */
10314
10315 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_stream_null_delegate.h"
10316
10317 namespace protozero {
10318
10319 // An implementation of ScatteredStreamWriter::Delegate which always returns
10320 // the same piece of memory.
10321 // This is used when we need to no-op the writers (e.g. during teardown or in
10322 // case of resource exhaustion), avoiding that the clients have to deal with
10323 // nullptr checks.
ScatteredStreamWriterNullDelegate(size_t chunk_size)10324 ScatteredStreamWriterNullDelegate::ScatteredStreamWriterNullDelegate(
10325 size_t chunk_size)
10326 : chunk_size_(chunk_size),
10327 chunk_(std::unique_ptr<uint8_t[]>(new uint8_t[chunk_size_])) {}
10328
~ScatteredStreamWriterNullDelegate()10329 ScatteredStreamWriterNullDelegate::~ScatteredStreamWriterNullDelegate() {}
10330
GetNewBuffer()10331 ContiguousMemoryRange ScatteredStreamWriterNullDelegate::GetNewBuffer() {
10332 return {chunk_.get(), chunk_.get() + chunk_size_};
10333 }
10334
10335 } // namespace protozero
10336 // gen_amalgamated begin source: src/protozero/scattered_stream_writer.cc
10337 /*
10338 * Copyright (C) 2017 The Android Open Source Project
10339 *
10340 * Licensed under the Apache License, Version 2.0 (the "License");
10341 * you may not use this file except in compliance with the License.
10342 * You may obtain a copy of the License at
10343 *
10344 * http://www.apache.org/licenses/LICENSE-2.0
10345 *
10346 * Unless required by applicable law or agreed to in writing, software
10347 * distributed under the License is distributed on an "AS IS" BASIS,
10348 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10349 * See the License for the specific language governing permissions and
10350 * limitations under the License.
10351 */
10352
10353 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_stream_writer.h"
10354
10355 #include <algorithm>
10356
10357 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
10358
10359 namespace protozero {
10360
~Delegate()10361 ScatteredStreamWriter::Delegate::~Delegate() {}
10362
ScatteredStreamWriter(Delegate * delegate)10363 ScatteredStreamWriter::ScatteredStreamWriter(Delegate* delegate)
10364 : delegate_(delegate),
10365 cur_range_({nullptr, nullptr}),
10366 write_ptr_(nullptr) {}
10367
~ScatteredStreamWriter()10368 ScatteredStreamWriter::~ScatteredStreamWriter() {}
10369
Reset(ContiguousMemoryRange range)10370 void ScatteredStreamWriter::Reset(ContiguousMemoryRange range) {
10371 written_previously_ += static_cast<uint64_t>(write_ptr_ - cur_range_.begin);
10372 cur_range_ = range;
10373 write_ptr_ = range.begin;
10374 PERFETTO_DCHECK(!write_ptr_ || write_ptr_ < cur_range_.end);
10375 }
10376
Extend()10377 void ScatteredStreamWriter::Extend() {
10378 Reset(delegate_->GetNewBuffer());
10379 }
10380
WriteBytesSlowPath(const uint8_t * src,size_t size)10381 void ScatteredStreamWriter::WriteBytesSlowPath(const uint8_t* src,
10382 size_t size) {
10383 size_t bytes_left = size;
10384 while (bytes_left > 0) {
10385 if (write_ptr_ >= cur_range_.end)
10386 Extend();
10387 const size_t burst_size = std::min(bytes_available(), bytes_left);
10388 WriteBytesUnsafe(src, burst_size);
10389 bytes_left -= burst_size;
10390 src += burst_size;
10391 }
10392 }
10393
10394 // TODO(primiano): perf optimization: I suspect that at the end this will always
10395 // be called with |size| == 4, in which case we might just hardcode it.
ReserveBytes(size_t size)10396 uint8_t* ScatteredStreamWriter::ReserveBytes(size_t size) {
10397 if (write_ptr_ + size > cur_range_.end) {
10398 // Assume the reservations are always < Delegate::GetNewBuffer().size(),
10399 // so that one single call to Extend() will definitely give enough headroom.
10400 Extend();
10401 PERFETTO_DCHECK(write_ptr_ + size <= cur_range_.end);
10402 }
10403 uint8_t* begin = write_ptr_;
10404 write_ptr_ += size;
10405 #if PERFETTO_DCHECK_IS_ON()
10406 // In the past, the service had a matching DCHECK in
10407 // TraceBuffer::TryPatchChunkContents, which was assuming that service and all
10408 // producers are built with matching DCHECK levels. This turned out to be a
10409 // source of problems and was removed in b/197340286. This memset is useless
10410 // these days and is here only to maintain ABI compatibility between producers
10411 // that use a v20+ SDK and older versions of the service that were built in
10412 // debug mode. At some point around 2023 it should be safe to remove it.
10413 // (running a debug version of traced in production seems a bad idea
10414 // regardless).
10415 memset(begin, 0, size);
10416 #endif
10417 return begin;
10418 }
10419
10420 } // namespace protozero
10421 // gen_amalgamated begin source: src/protozero/static_buffer.cc
10422 // gen_amalgamated begin header: include/perfetto/protozero/static_buffer.h
10423 /*
10424 * Copyright (C) 2019 The Android Open Source Project
10425 *
10426 * Licensed under the Apache License, Version 2.0 (the "License");
10427 * you may not use this file except in compliance with the License.
10428 * You may obtain a copy of the License at
10429 *
10430 * http://www.apache.org/licenses/LICENSE-2.0
10431 *
10432 * Unless required by applicable law or agreed to in writing, software
10433 * distributed under the License is distributed on an "AS IS" BASIS,
10434 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10435 * See the License for the specific language governing permissions and
10436 * limitations under the License.
10437 */
10438
10439 #ifndef INCLUDE_PERFETTO_PROTOZERO_STATIC_BUFFER_H_
10440 #define INCLUDE_PERFETTO_PROTOZERO_STATIC_BUFFER_H_
10441
10442 #include <memory>
10443 #include <string>
10444 #include <vector>
10445
10446 // gen_amalgamated expanded: #include "perfetto/base/export.h"
10447 // gen_amalgamated expanded: #include "perfetto/protozero/root_message.h"
10448 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_stream_writer.h"
10449
10450 namespace protozero {
10451
10452 class Message;
10453
10454 // A simple implementation of ScatteredStreamWriter::Delegate backed by a
10455 // fixed-size buffer. It doesn't support expansion. The caller needs to ensure
10456 // to never write more than the size of the buffer. Will CHECK() otherwise.
10457 class PERFETTO_EXPORT StaticBufferDelegate
10458 : public ScatteredStreamWriter::Delegate {
10459 public:
StaticBufferDelegate(uint8_t * buf,size_t len)10460 StaticBufferDelegate(uint8_t* buf, size_t len) : range_{buf, buf + len} {}
10461 ~StaticBufferDelegate() override;
10462
10463 // ScatteredStreamWriter::Delegate implementation.
10464 ContiguousMemoryRange GetNewBuffer() override;
10465
10466 ContiguousMemoryRange const range_;
10467 bool get_new_buffer_called_once_ = false;
10468 };
10469
10470 // Helper function to create protozero messages backed by a fixed-size buffer
10471 // in one line. You can write:
10472 // protozero::Static<protozero::MyMessage> msg(buf.data(), buf.size());
10473 // msg->set_stuff(...);
10474 // size_t bytes_encoded = msg.Finalize();
10475 template <typename T /* protozero::Message */>
10476 class StaticBuffered {
10477 public:
StaticBuffered(void * buf,size_t len)10478 StaticBuffered(void* buf, size_t len)
10479 : delegate_(reinterpret_cast<uint8_t*>(buf), len), writer_(&delegate_) {
10480 msg_.Reset(&writer_);
10481 }
10482
10483 // This can't be neither copied nor moved because Message hands out pointers
10484 // to itself when creating submessages.
10485 StaticBuffered(const StaticBuffered&) = delete;
10486 StaticBuffered& operator=(const StaticBuffered&) = delete;
10487 StaticBuffered(StaticBuffered&&) = delete;
10488 StaticBuffered& operator=(StaticBuffered&&) = delete;
10489
get()10490 T* get() { return &msg_; }
operator ->()10491 T* operator->() { return &msg_; }
10492
10493 // The lack of a size() method is deliberate. It's to prevent that one
10494 // accidentally calls size() before Finalize().
10495
10496 // Returns the number of encoded bytes (<= the size passed in the ctor).
Finalize()10497 size_t Finalize() {
10498 msg_.Finalize();
10499 return static_cast<size_t>(writer_.write_ptr() - delegate_.range_.begin);
10500 }
10501
10502 private:
10503 StaticBufferDelegate delegate_;
10504 ScatteredStreamWriter writer_;
10505 RootMessage<T> msg_;
10506 };
10507
10508 // Helper function to create stack-based protozero messages in one line.
10509 // You can write:
10510 // protozero::StackBuffered<protozero::MyMessage, 16> msg;
10511 // msg->set_stuff(...);
10512 // size_t bytes_encoded = msg.Finalize();
10513 template <typename T /* protozero::Message */, size_t N>
10514 class StackBuffered : public StaticBuffered<T> {
10515 public:
StackBuffered()10516 StackBuffered() : StaticBuffered<T>(&buf_[0], N) {}
10517
10518 private:
10519 uint8_t buf_[N]; // Deliberately not initialized.
10520 };
10521
10522 } // namespace protozero
10523
10524 #endif // INCLUDE_PERFETTO_PROTOZERO_STATIC_BUFFER_H_
10525 /*
10526 * Copyright (C) 2019 The Android Open Source Project
10527 *
10528 * Licensed under the Apache License, Version 2.0 (the "License");
10529 * you may not use this file except in compliance with the License.
10530 * You may obtain a copy of the License at
10531 *
10532 * http://www.apache.org/licenses/LICENSE-2.0
10533 *
10534 * Unless required by applicable law or agreed to in writing, software
10535 * distributed under the License is distributed on an "AS IS" BASIS,
10536 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10537 * See the License for the specific language governing permissions and
10538 * limitations under the License.
10539 */
10540
10541 // gen_amalgamated expanded: #include "perfetto/protozero/static_buffer.h"
10542
10543 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
10544
10545 namespace protozero {
10546
10547 StaticBufferDelegate::~StaticBufferDelegate() = default;
10548
GetNewBuffer()10549 ContiguousMemoryRange StaticBufferDelegate::GetNewBuffer() {
10550 if (get_new_buffer_called_once_) {
10551 // This is the 2nd time GetNewBuffer is called. The estimate is wrong. We
10552 // shouldn't try to grow the buffer after the initial call.
10553 PERFETTO_FATAL("Static buffer too small");
10554 }
10555 get_new_buffer_called_once_ = true;
10556 return range_;
10557 }
10558
10559 } // namespace protozero
10560 // gen_amalgamated begin source: src/protozero/virtual_destructors.cc
10561 /*
10562 * Copyright (C) 2019 The Android Open Source Project
10563 *
10564 * Licensed under the Apache License, Version 2.0 (the "License");
10565 * you may not use this file except in compliance with the License.
10566 * You may obtain a copy of the License at
10567 *
10568 * http://www.apache.org/licenses/LICENSE-2.0
10569 *
10570 * Unless required by applicable law or agreed to in writing, software
10571 * distributed under the License is distributed on an "AS IS" BASIS,
10572 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10573 * See the License for the specific language governing permissions and
10574 * limitations under the License.
10575 */
10576
10577 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
10578
10579 namespace protozero {
10580
10581 CppMessageObj::~CppMessageObj() = default;
10582
10583 } // namespace protozero
10584 // gen_amalgamated begin source: gen/protos/perfetto/common/android_energy_consumer_descriptor.gen.cc
10585 // gen_amalgamated begin header: gen/protos/perfetto/common/android_energy_consumer_descriptor.gen.h
10586 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
10587 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_ANDROID_ENERGY_CONSUMER_DESCRIPTOR_PROTO_CPP_H_
10588 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_ANDROID_ENERGY_CONSUMER_DESCRIPTOR_PROTO_CPP_H_
10589
10590 #include <stdint.h>
10591 #include <bitset>
10592 #include <vector>
10593 #include <string>
10594 #include <type_traits>
10595
10596 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
10597 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
10598 // gen_amalgamated expanded: #include "perfetto/base/export.h"
10599
10600 namespace perfetto {
10601 namespace protos {
10602 namespace gen {
10603 class AndroidEnergyConsumerDescriptor;
10604 class AndroidEnergyConsumer;
10605 } // namespace perfetto
10606 } // namespace protos
10607 } // namespace gen
10608
10609 namespace protozero {
10610 class Message;
10611 } // namespace protozero
10612
10613 namespace perfetto {
10614 namespace protos {
10615 namespace gen {
10616
10617 class PERFETTO_EXPORT AndroidEnergyConsumerDescriptor : public ::protozero::CppMessageObj {
10618 public:
10619 enum FieldNumbers {
10620 kEnergyConsumersFieldNumber = 1,
10621 };
10622
10623 AndroidEnergyConsumerDescriptor();
10624 ~AndroidEnergyConsumerDescriptor() override;
10625 AndroidEnergyConsumerDescriptor(AndroidEnergyConsumerDescriptor&&) noexcept;
10626 AndroidEnergyConsumerDescriptor& operator=(AndroidEnergyConsumerDescriptor&&);
10627 AndroidEnergyConsumerDescriptor(const AndroidEnergyConsumerDescriptor&);
10628 AndroidEnergyConsumerDescriptor& operator=(const AndroidEnergyConsumerDescriptor&);
10629 bool operator==(const AndroidEnergyConsumerDescriptor&) const;
operator !=(const AndroidEnergyConsumerDescriptor & other) const10630 bool operator!=(const AndroidEnergyConsumerDescriptor& other) const { return !(*this == other); }
10631
10632 bool ParseFromArray(const void*, size_t) override;
10633 std::string SerializeAsString() const override;
10634 std::vector<uint8_t> SerializeAsArray() const override;
10635 void Serialize(::protozero::Message*) const;
10636
energy_consumers() const10637 const std::vector<AndroidEnergyConsumer>& energy_consumers() const { return energy_consumers_; }
mutable_energy_consumers()10638 std::vector<AndroidEnergyConsumer>* mutable_energy_consumers() { return &energy_consumers_; }
10639 int energy_consumers_size() const;
10640 void clear_energy_consumers();
10641 AndroidEnergyConsumer* add_energy_consumers();
10642
10643 private:
10644 std::vector<AndroidEnergyConsumer> energy_consumers_;
10645
10646 // Allows to preserve unknown protobuf fields for compatibility
10647 // with future versions of .proto files.
10648 std::string unknown_fields_;
10649
10650 std::bitset<2> _has_field_{};
10651 };
10652
10653
10654 class PERFETTO_EXPORT AndroidEnergyConsumer : public ::protozero::CppMessageObj {
10655 public:
10656 enum FieldNumbers {
10657 kEnergyConsumerIdFieldNumber = 1,
10658 kOrdinalFieldNumber = 2,
10659 kTypeFieldNumber = 3,
10660 kNameFieldNumber = 4,
10661 };
10662
10663 AndroidEnergyConsumer();
10664 ~AndroidEnergyConsumer() override;
10665 AndroidEnergyConsumer(AndroidEnergyConsumer&&) noexcept;
10666 AndroidEnergyConsumer& operator=(AndroidEnergyConsumer&&);
10667 AndroidEnergyConsumer(const AndroidEnergyConsumer&);
10668 AndroidEnergyConsumer& operator=(const AndroidEnergyConsumer&);
10669 bool operator==(const AndroidEnergyConsumer&) const;
operator !=(const AndroidEnergyConsumer & other) const10670 bool operator!=(const AndroidEnergyConsumer& other) const { return !(*this == other); }
10671
10672 bool ParseFromArray(const void*, size_t) override;
10673 std::string SerializeAsString() const override;
10674 std::vector<uint8_t> SerializeAsArray() const override;
10675 void Serialize(::protozero::Message*) const;
10676
has_energy_consumer_id() const10677 bool has_energy_consumer_id() const { return _has_field_[1]; }
energy_consumer_id() const10678 int32_t energy_consumer_id() const { return energy_consumer_id_; }
set_energy_consumer_id(int32_t value)10679 void set_energy_consumer_id(int32_t value) { energy_consumer_id_ = value; _has_field_.set(1); }
10680
has_ordinal() const10681 bool has_ordinal() const { return _has_field_[2]; }
ordinal() const10682 int32_t ordinal() const { return ordinal_; }
set_ordinal(int32_t value)10683 void set_ordinal(int32_t value) { ordinal_ = value; _has_field_.set(2); }
10684
has_type() const10685 bool has_type() const { return _has_field_[3]; }
type() const10686 const std::string& type() const { return type_; }
set_type(const std::string & value)10687 void set_type(const std::string& value) { type_ = value; _has_field_.set(3); }
10688
has_name() const10689 bool has_name() const { return _has_field_[4]; }
name() const10690 const std::string& name() const { return name_; }
set_name(const std::string & value)10691 void set_name(const std::string& value) { name_ = value; _has_field_.set(4); }
10692
10693 private:
10694 int32_t energy_consumer_id_{};
10695 int32_t ordinal_{};
10696 std::string type_{};
10697 std::string name_{};
10698
10699 // Allows to preserve unknown protobuf fields for compatibility
10700 // with future versions of .proto files.
10701 std::string unknown_fields_;
10702
10703 std::bitset<5> _has_field_{};
10704 };
10705
10706 } // namespace perfetto
10707 } // namespace protos
10708 } // namespace gen
10709
10710 #endif // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_ANDROID_ENERGY_CONSUMER_DESCRIPTOR_PROTO_CPP_H_
10711 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
10712 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
10713 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
10714 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
10715 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
10716 #if defined(__GNUC__) || defined(__clang__)
10717 #pragma GCC diagnostic push
10718 #pragma GCC diagnostic ignored "-Wfloat-equal"
10719 #endif
10720 // gen_amalgamated expanded: #include "protos/perfetto/common/android_energy_consumer_descriptor.gen.h"
10721
10722 namespace perfetto {
10723 namespace protos {
10724 namespace gen {
10725
10726 AndroidEnergyConsumerDescriptor::AndroidEnergyConsumerDescriptor() = default;
10727 AndroidEnergyConsumerDescriptor::~AndroidEnergyConsumerDescriptor() = default;
10728 AndroidEnergyConsumerDescriptor::AndroidEnergyConsumerDescriptor(const AndroidEnergyConsumerDescriptor&) = default;
10729 AndroidEnergyConsumerDescriptor& AndroidEnergyConsumerDescriptor::operator=(const AndroidEnergyConsumerDescriptor&) = default;
10730 AndroidEnergyConsumerDescriptor::AndroidEnergyConsumerDescriptor(AndroidEnergyConsumerDescriptor&&) noexcept = default;
10731 AndroidEnergyConsumerDescriptor& AndroidEnergyConsumerDescriptor::operator=(AndroidEnergyConsumerDescriptor&&) = default;
10732
operator ==(const AndroidEnergyConsumerDescriptor & other) const10733 bool AndroidEnergyConsumerDescriptor::operator==(const AndroidEnergyConsumerDescriptor& other) const {
10734 return unknown_fields_ == other.unknown_fields_
10735 && energy_consumers_ == other.energy_consumers_;
10736 }
10737
energy_consumers_size() const10738 int AndroidEnergyConsumerDescriptor::energy_consumers_size() const { return static_cast<int>(energy_consumers_.size()); }
clear_energy_consumers()10739 void AndroidEnergyConsumerDescriptor::clear_energy_consumers() { energy_consumers_.clear(); }
add_energy_consumers()10740 AndroidEnergyConsumer* AndroidEnergyConsumerDescriptor::add_energy_consumers() { energy_consumers_.emplace_back(); return &energy_consumers_.back(); }
ParseFromArray(const void * raw,size_t size)10741 bool AndroidEnergyConsumerDescriptor::ParseFromArray(const void* raw, size_t size) {
10742 energy_consumers_.clear();
10743 unknown_fields_.clear();
10744 bool packed_error = false;
10745
10746 ::protozero::ProtoDecoder dec(raw, size);
10747 for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
10748 if (field.id() < _has_field_.size()) {
10749 _has_field_.set(field.id());
10750 }
10751 switch (field.id()) {
10752 case 1 /* energy_consumers */:
10753 energy_consumers_.emplace_back();
10754 energy_consumers_.back().ParseFromArray(field.data(), field.size());
10755 break;
10756 default:
10757 field.SerializeAndAppendTo(&unknown_fields_);
10758 break;
10759 }
10760 }
10761 return !packed_error && !dec.bytes_left();
10762 }
10763
SerializeAsString() const10764 std::string AndroidEnergyConsumerDescriptor::SerializeAsString() const {
10765 ::protozero::HeapBuffered<::protozero::Message> msg;
10766 Serialize(msg.get());
10767 return msg.SerializeAsString();
10768 }
10769
SerializeAsArray() const10770 std::vector<uint8_t> AndroidEnergyConsumerDescriptor::SerializeAsArray() const {
10771 ::protozero::HeapBuffered<::protozero::Message> msg;
10772 Serialize(msg.get());
10773 return msg.SerializeAsArray();
10774 }
10775
Serialize(::protozero::Message * msg) const10776 void AndroidEnergyConsumerDescriptor::Serialize(::protozero::Message* msg) const {
10777 // Field 1: energy_consumers
10778 for (auto& it : energy_consumers_) {
10779 it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
10780 }
10781
10782 msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
10783 }
10784
10785
10786 AndroidEnergyConsumer::AndroidEnergyConsumer() = default;
10787 AndroidEnergyConsumer::~AndroidEnergyConsumer() = default;
10788 AndroidEnergyConsumer::AndroidEnergyConsumer(const AndroidEnergyConsumer&) = default;
10789 AndroidEnergyConsumer& AndroidEnergyConsumer::operator=(const AndroidEnergyConsumer&) = default;
10790 AndroidEnergyConsumer::AndroidEnergyConsumer(AndroidEnergyConsumer&&) noexcept = default;
10791 AndroidEnergyConsumer& AndroidEnergyConsumer::operator=(AndroidEnergyConsumer&&) = default;
10792
operator ==(const AndroidEnergyConsumer & other) const10793 bool AndroidEnergyConsumer::operator==(const AndroidEnergyConsumer& other) const {
10794 return unknown_fields_ == other.unknown_fields_
10795 && energy_consumer_id_ == other.energy_consumer_id_
10796 && ordinal_ == other.ordinal_
10797 && type_ == other.type_
10798 && name_ == other.name_;
10799 }
10800
ParseFromArray(const void * raw,size_t size)10801 bool AndroidEnergyConsumer::ParseFromArray(const void* raw, size_t size) {
10802 unknown_fields_.clear();
10803 bool packed_error = false;
10804
10805 ::protozero::ProtoDecoder dec(raw, size);
10806 for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
10807 if (field.id() < _has_field_.size()) {
10808 _has_field_.set(field.id());
10809 }
10810 switch (field.id()) {
10811 case 1 /* energy_consumer_id */:
10812 field.get(&energy_consumer_id_);
10813 break;
10814 case 2 /* ordinal */:
10815 field.get(&ordinal_);
10816 break;
10817 case 3 /* type */:
10818 field.get(&type_);
10819 break;
10820 case 4 /* name */:
10821 field.get(&name_);
10822 break;
10823 default:
10824 field.SerializeAndAppendTo(&unknown_fields_);
10825 break;
10826 }
10827 }
10828 return !packed_error && !dec.bytes_left();
10829 }
10830
SerializeAsString() const10831 std::string AndroidEnergyConsumer::SerializeAsString() const {
10832 ::protozero::HeapBuffered<::protozero::Message> msg;
10833 Serialize(msg.get());
10834 return msg.SerializeAsString();
10835 }
10836
SerializeAsArray() const10837 std::vector<uint8_t> AndroidEnergyConsumer::SerializeAsArray() const {
10838 ::protozero::HeapBuffered<::protozero::Message> msg;
10839 Serialize(msg.get());
10840 return msg.SerializeAsArray();
10841 }
10842
Serialize(::protozero::Message * msg) const10843 void AndroidEnergyConsumer::Serialize(::protozero::Message* msg) const {
10844 // Field 1: energy_consumer_id
10845 if (_has_field_[1]) {
10846 msg->AppendVarInt(1, energy_consumer_id_);
10847 }
10848
10849 // Field 2: ordinal
10850 if (_has_field_[2]) {
10851 msg->AppendVarInt(2, ordinal_);
10852 }
10853
10854 // Field 3: type
10855 if (_has_field_[3]) {
10856 msg->AppendString(3, type_);
10857 }
10858
10859 // Field 4: name
10860 if (_has_field_[4]) {
10861 msg->AppendString(4, name_);
10862 }
10863
10864 msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
10865 }
10866
10867 } // namespace perfetto
10868 } // namespace protos
10869 } // namespace gen
10870 #if defined(__GNUC__) || defined(__clang__)
10871 #pragma GCC diagnostic pop
10872 #endif
10873 // gen_amalgamated begin source: gen/protos/perfetto/common/android_log_constants.gen.cc
10874 // gen_amalgamated begin header: gen/protos/perfetto/common/android_log_constants.gen.h
10875 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
10876 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_ANDROID_LOG_CONSTANTS_PROTO_CPP_H_
10877 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_ANDROID_LOG_CONSTANTS_PROTO_CPP_H_
10878
10879 #include <stdint.h>
10880 #include <bitset>
10881 #include <vector>
10882 #include <string>
10883 #include <type_traits>
10884
10885 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
10886 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
10887 // gen_amalgamated expanded: #include "perfetto/base/export.h"
10888
10889 namespace perfetto {
10890 namespace protos {
10891 namespace gen {
10892 enum AndroidLogId : int;
10893 enum AndroidLogPriority : int;
10894 } // namespace perfetto
10895 } // namespace protos
10896 } // namespace gen
10897
10898 namespace protozero {
10899 class Message;
10900 } // namespace protozero
10901
10902 namespace perfetto {
10903 namespace protos {
10904 namespace gen {
10905 enum AndroidLogId : int {
10906 LID_DEFAULT = 0,
10907 LID_RADIO = 1,
10908 LID_EVENTS = 2,
10909 LID_SYSTEM = 3,
10910 LID_CRASH = 4,
10911 LID_STATS = 5,
10912 LID_SECURITY = 6,
10913 LID_KERNEL = 7,
10914 };
10915 enum AndroidLogPriority : int {
10916 PRIO_UNSPECIFIED = 0,
10917 PRIO_UNUSED = 1,
10918 PRIO_VERBOSE = 2,
10919 PRIO_DEBUG = 3,
10920 PRIO_INFO = 4,
10921 PRIO_WARN = 5,
10922 PRIO_ERROR = 6,
10923 PRIO_FATAL = 7,
10924 };
10925 } // namespace perfetto
10926 } // namespace protos
10927 } // namespace gen
10928
10929 #endif // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_ANDROID_LOG_CONSTANTS_PROTO_CPP_H_
10930 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
10931 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
10932 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
10933 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
10934 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
10935 #if defined(__GNUC__) || defined(__clang__)
10936 #pragma GCC diagnostic push
10937 #pragma GCC diagnostic ignored "-Wfloat-equal"
10938 #endif
10939 // gen_amalgamated expanded: #include "protos/perfetto/common/android_log_constants.gen.h"
10940
10941 namespace perfetto {
10942 namespace protos {
10943 namespace gen {
10944 } // namespace perfetto
10945 } // namespace protos
10946 } // namespace gen
10947 #if defined(__GNUC__) || defined(__clang__)
10948 #pragma GCC diagnostic pop
10949 #endif
10950 // gen_amalgamated begin source: gen/protos/perfetto/common/builtin_clock.gen.cc
10951 // gen_amalgamated begin header: gen/protos/perfetto/common/builtin_clock.gen.h
10952 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
10953 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_BUILTIN_CLOCK_PROTO_CPP_H_
10954 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_BUILTIN_CLOCK_PROTO_CPP_H_
10955
10956 #include <stdint.h>
10957 #include <bitset>
10958 #include <vector>
10959 #include <string>
10960 #include <type_traits>
10961
10962 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
10963 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
10964 // gen_amalgamated expanded: #include "perfetto/base/export.h"
10965
10966 namespace perfetto {
10967 namespace protos {
10968 namespace gen {
10969 enum BuiltinClock : int;
10970 } // namespace perfetto
10971 } // namespace protos
10972 } // namespace gen
10973
10974 namespace protozero {
10975 class Message;
10976 } // namespace protozero
10977
10978 namespace perfetto {
10979 namespace protos {
10980 namespace gen {
10981 enum BuiltinClock : int {
10982 BUILTIN_CLOCK_UNKNOWN = 0,
10983 BUILTIN_CLOCK_REALTIME = 1,
10984 BUILTIN_CLOCK_REALTIME_COARSE = 2,
10985 BUILTIN_CLOCK_MONOTONIC = 3,
10986 BUILTIN_CLOCK_MONOTONIC_COARSE = 4,
10987 BUILTIN_CLOCK_MONOTONIC_RAW = 5,
10988 BUILTIN_CLOCK_BOOTTIME = 6,
10989 BUILTIN_CLOCK_MAX_ID = 63,
10990 };
10991 } // namespace perfetto
10992 } // namespace protos
10993 } // namespace gen
10994
10995 #endif // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_BUILTIN_CLOCK_PROTO_CPP_H_
10996 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
10997 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
10998 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
10999 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
11000 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
11001 #if defined(__GNUC__) || defined(__clang__)
11002 #pragma GCC diagnostic push
11003 #pragma GCC diagnostic ignored "-Wfloat-equal"
11004 #endif
11005 // gen_amalgamated expanded: #include "protos/perfetto/common/builtin_clock.gen.h"
11006
11007 namespace perfetto {
11008 namespace protos {
11009 namespace gen {
11010 } // namespace perfetto
11011 } // namespace protos
11012 } // namespace gen
11013 #if defined(__GNUC__) || defined(__clang__)
11014 #pragma GCC diagnostic pop
11015 #endif
11016 // gen_amalgamated begin source: gen/protos/perfetto/common/commit_data_request.gen.cc
11017 // gen_amalgamated begin header: gen/protos/perfetto/common/commit_data_request.gen.h
11018 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
11019 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_COMMIT_DATA_REQUEST_PROTO_CPP_H_
11020 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_COMMIT_DATA_REQUEST_PROTO_CPP_H_
11021
11022 #include <stdint.h>
11023 #include <bitset>
11024 #include <vector>
11025 #include <string>
11026 #include <type_traits>
11027
11028 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
11029 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
11030 // gen_amalgamated expanded: #include "perfetto/base/export.h"
11031
11032 namespace perfetto {
11033 namespace protos {
11034 namespace gen {
11035 class CommitDataRequest;
11036 class CommitDataRequest_ChunkToPatch;
11037 class CommitDataRequest_ChunkToPatch_Patch;
11038 class CommitDataRequest_ChunksToMove;
11039 } // namespace perfetto
11040 } // namespace protos
11041 } // namespace gen
11042
11043 namespace protozero {
11044 class Message;
11045 } // namespace protozero
11046
11047 namespace perfetto {
11048 namespace protos {
11049 namespace gen {
11050
11051 class PERFETTO_EXPORT CommitDataRequest : public ::protozero::CppMessageObj {
11052 public:
11053 using ChunksToMove = CommitDataRequest_ChunksToMove;
11054 using ChunkToPatch = CommitDataRequest_ChunkToPatch;
11055 enum FieldNumbers {
11056 kChunksToMoveFieldNumber = 1,
11057 kChunksToPatchFieldNumber = 2,
11058 kFlushRequestIdFieldNumber = 3,
11059 };
11060
11061 CommitDataRequest();
11062 ~CommitDataRequest() override;
11063 CommitDataRequest(CommitDataRequest&&) noexcept;
11064 CommitDataRequest& operator=(CommitDataRequest&&);
11065 CommitDataRequest(const CommitDataRequest&);
11066 CommitDataRequest& operator=(const CommitDataRequest&);
11067 bool operator==(const CommitDataRequest&) const;
operator !=(const CommitDataRequest & other) const11068 bool operator!=(const CommitDataRequest& other) const { return !(*this == other); }
11069
11070 bool ParseFromArray(const void*, size_t) override;
11071 std::string SerializeAsString() const override;
11072 std::vector<uint8_t> SerializeAsArray() const override;
11073 void Serialize(::protozero::Message*) const;
11074
chunks_to_move() const11075 const std::vector<CommitDataRequest_ChunksToMove>& chunks_to_move() const { return chunks_to_move_; }
mutable_chunks_to_move()11076 std::vector<CommitDataRequest_ChunksToMove>* mutable_chunks_to_move() { return &chunks_to_move_; }
11077 int chunks_to_move_size() const;
11078 void clear_chunks_to_move();
11079 CommitDataRequest_ChunksToMove* add_chunks_to_move();
11080
chunks_to_patch() const11081 const std::vector<CommitDataRequest_ChunkToPatch>& chunks_to_patch() const { return chunks_to_patch_; }
mutable_chunks_to_patch()11082 std::vector<CommitDataRequest_ChunkToPatch>* mutable_chunks_to_patch() { return &chunks_to_patch_; }
11083 int chunks_to_patch_size() const;
11084 void clear_chunks_to_patch();
11085 CommitDataRequest_ChunkToPatch* add_chunks_to_patch();
11086
has_flush_request_id() const11087 bool has_flush_request_id() const { return _has_field_[3]; }
flush_request_id() const11088 uint64_t flush_request_id() const { return flush_request_id_; }
set_flush_request_id(uint64_t value)11089 void set_flush_request_id(uint64_t value) { flush_request_id_ = value; _has_field_.set(3); }
11090
11091 private:
11092 std::vector<CommitDataRequest_ChunksToMove> chunks_to_move_;
11093 std::vector<CommitDataRequest_ChunkToPatch> chunks_to_patch_;
11094 uint64_t flush_request_id_{};
11095
11096 // Allows to preserve unknown protobuf fields for compatibility
11097 // with future versions of .proto files.
11098 std::string unknown_fields_;
11099
11100 std::bitset<4> _has_field_{};
11101 };
11102
11103
11104 class PERFETTO_EXPORT CommitDataRequest_ChunkToPatch : public ::protozero::CppMessageObj {
11105 public:
11106 using Patch = CommitDataRequest_ChunkToPatch_Patch;
11107 enum FieldNumbers {
11108 kTargetBufferFieldNumber = 1,
11109 kWriterIdFieldNumber = 2,
11110 kChunkIdFieldNumber = 3,
11111 kPatchesFieldNumber = 4,
11112 kHasMorePatchesFieldNumber = 5,
11113 };
11114
11115 CommitDataRequest_ChunkToPatch();
11116 ~CommitDataRequest_ChunkToPatch() override;
11117 CommitDataRequest_ChunkToPatch(CommitDataRequest_ChunkToPatch&&) noexcept;
11118 CommitDataRequest_ChunkToPatch& operator=(CommitDataRequest_ChunkToPatch&&);
11119 CommitDataRequest_ChunkToPatch(const CommitDataRequest_ChunkToPatch&);
11120 CommitDataRequest_ChunkToPatch& operator=(const CommitDataRequest_ChunkToPatch&);
11121 bool operator==(const CommitDataRequest_ChunkToPatch&) const;
operator !=(const CommitDataRequest_ChunkToPatch & other) const11122 bool operator!=(const CommitDataRequest_ChunkToPatch& other) const { return !(*this == other); }
11123
11124 bool ParseFromArray(const void*, size_t) override;
11125 std::string SerializeAsString() const override;
11126 std::vector<uint8_t> SerializeAsArray() const override;
11127 void Serialize(::protozero::Message*) const;
11128
has_target_buffer() const11129 bool has_target_buffer() const { return _has_field_[1]; }
target_buffer() const11130 uint32_t target_buffer() const { return target_buffer_; }
set_target_buffer(uint32_t value)11131 void set_target_buffer(uint32_t value) { target_buffer_ = value; _has_field_.set(1); }
11132
has_writer_id() const11133 bool has_writer_id() const { return _has_field_[2]; }
writer_id() const11134 uint32_t writer_id() const { return writer_id_; }
set_writer_id(uint32_t value)11135 void set_writer_id(uint32_t value) { writer_id_ = value; _has_field_.set(2); }
11136
has_chunk_id() const11137 bool has_chunk_id() const { return _has_field_[3]; }
chunk_id() const11138 uint32_t chunk_id() const { return chunk_id_; }
set_chunk_id(uint32_t value)11139 void set_chunk_id(uint32_t value) { chunk_id_ = value; _has_field_.set(3); }
11140
patches() const11141 const std::vector<CommitDataRequest_ChunkToPatch_Patch>& patches() const { return patches_; }
mutable_patches()11142 std::vector<CommitDataRequest_ChunkToPatch_Patch>* mutable_patches() { return &patches_; }
11143 int patches_size() const;
11144 void clear_patches();
11145 CommitDataRequest_ChunkToPatch_Patch* add_patches();
11146
has_has_more_patches() const11147 bool has_has_more_patches() const { return _has_field_[5]; }
has_more_patches() const11148 bool has_more_patches() const { return has_more_patches_; }
set_has_more_patches(bool value)11149 void set_has_more_patches(bool value) { has_more_patches_ = value; _has_field_.set(5); }
11150
11151 private:
11152 uint32_t target_buffer_{};
11153 uint32_t writer_id_{};
11154 uint32_t chunk_id_{};
11155 std::vector<CommitDataRequest_ChunkToPatch_Patch> patches_;
11156 bool has_more_patches_{};
11157
11158 // Allows to preserve unknown protobuf fields for compatibility
11159 // with future versions of .proto files.
11160 std::string unknown_fields_;
11161
11162 std::bitset<6> _has_field_{};
11163 };
11164
11165
11166 class PERFETTO_EXPORT CommitDataRequest_ChunkToPatch_Patch : public ::protozero::CppMessageObj {
11167 public:
11168 enum FieldNumbers {
11169 kOffsetFieldNumber = 1,
11170 kDataFieldNumber = 2,
11171 };
11172
11173 CommitDataRequest_ChunkToPatch_Patch();
11174 ~CommitDataRequest_ChunkToPatch_Patch() override;
11175 CommitDataRequest_ChunkToPatch_Patch(CommitDataRequest_ChunkToPatch_Patch&&) noexcept;
11176 CommitDataRequest_ChunkToPatch_Patch& operator=(CommitDataRequest_ChunkToPatch_Patch&&);
11177 CommitDataRequest_ChunkToPatch_Patch(const CommitDataRequest_ChunkToPatch_Patch&);
11178 CommitDataRequest_ChunkToPatch_Patch& operator=(const CommitDataRequest_ChunkToPatch_Patch&);
11179 bool operator==(const CommitDataRequest_ChunkToPatch_Patch&) const;
operator !=(const CommitDataRequest_ChunkToPatch_Patch & other) const11180 bool operator!=(const CommitDataRequest_ChunkToPatch_Patch& other) const { return !(*this == other); }
11181
11182 bool ParseFromArray(const void*, size_t) override;
11183 std::string SerializeAsString() const override;
11184 std::vector<uint8_t> SerializeAsArray() const override;
11185 void Serialize(::protozero::Message*) const;
11186
has_offset() const11187 bool has_offset() const { return _has_field_[1]; }
offset() const11188 uint32_t offset() const { return offset_; }
set_offset(uint32_t value)11189 void set_offset(uint32_t value) { offset_ = value; _has_field_.set(1); }
11190
has_data() const11191 bool has_data() const { return _has_field_[2]; }
data() const11192 const std::string& data() const { return data_; }
set_data(const std::string & value)11193 void set_data(const std::string& value) { data_ = value; _has_field_.set(2); }
set_data(const void * p,size_t s)11194 void set_data(const void* p, size_t s) { data_.assign(reinterpret_cast<const char*>(p), s); _has_field_.set(2); }
11195
11196 private:
11197 uint32_t offset_{};
11198 std::string data_{};
11199
11200 // Allows to preserve unknown protobuf fields for compatibility
11201 // with future versions of .proto files.
11202 std::string unknown_fields_;
11203
11204 std::bitset<3> _has_field_{};
11205 };
11206
11207
11208 class PERFETTO_EXPORT CommitDataRequest_ChunksToMove : public ::protozero::CppMessageObj {
11209 public:
11210 enum FieldNumbers {
11211 kPageFieldNumber = 1,
11212 kChunkFieldNumber = 2,
11213 kTargetBufferFieldNumber = 3,
11214 };
11215
11216 CommitDataRequest_ChunksToMove();
11217 ~CommitDataRequest_ChunksToMove() override;
11218 CommitDataRequest_ChunksToMove(CommitDataRequest_ChunksToMove&&) noexcept;
11219 CommitDataRequest_ChunksToMove& operator=(CommitDataRequest_ChunksToMove&&);
11220 CommitDataRequest_ChunksToMove(const CommitDataRequest_ChunksToMove&);
11221 CommitDataRequest_ChunksToMove& operator=(const CommitDataRequest_ChunksToMove&);
11222 bool operator==(const CommitDataRequest_ChunksToMove&) const;
operator !=(const CommitDataRequest_ChunksToMove & other) const11223 bool operator!=(const CommitDataRequest_ChunksToMove& other) const { return !(*this == other); }
11224
11225 bool ParseFromArray(const void*, size_t) override;
11226 std::string SerializeAsString() const override;
11227 std::vector<uint8_t> SerializeAsArray() const override;
11228 void Serialize(::protozero::Message*) const;
11229
has_page() const11230 bool has_page() const { return _has_field_[1]; }
page() const11231 uint32_t page() const { return page_; }
set_page(uint32_t value)11232 void set_page(uint32_t value) { page_ = value; _has_field_.set(1); }
11233
has_chunk() const11234 bool has_chunk() const { return _has_field_[2]; }
chunk() const11235 uint32_t chunk() const { return chunk_; }
set_chunk(uint32_t value)11236 void set_chunk(uint32_t value) { chunk_ = value; _has_field_.set(2); }
11237
has_target_buffer() const11238 bool has_target_buffer() const { return _has_field_[3]; }
target_buffer() const11239 uint32_t target_buffer() const { return target_buffer_; }
set_target_buffer(uint32_t value)11240 void set_target_buffer(uint32_t value) { target_buffer_ = value; _has_field_.set(3); }
11241
11242 private:
11243 uint32_t page_{};
11244 uint32_t chunk_{};
11245 uint32_t target_buffer_{};
11246
11247 // Allows to preserve unknown protobuf fields for compatibility
11248 // with future versions of .proto files.
11249 std::string unknown_fields_;
11250
11251 std::bitset<4> _has_field_{};
11252 };
11253
11254 } // namespace perfetto
11255 } // namespace protos
11256 } // namespace gen
11257
11258 #endif // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_COMMIT_DATA_REQUEST_PROTO_CPP_H_
11259 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
11260 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
11261 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
11262 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
11263 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
11264 #if defined(__GNUC__) || defined(__clang__)
11265 #pragma GCC diagnostic push
11266 #pragma GCC diagnostic ignored "-Wfloat-equal"
11267 #endif
11268 // gen_amalgamated expanded: #include "protos/perfetto/common/commit_data_request.gen.h"
11269
11270 namespace perfetto {
11271 namespace protos {
11272 namespace gen {
11273
11274 CommitDataRequest::CommitDataRequest() = default;
11275 CommitDataRequest::~CommitDataRequest() = default;
11276 CommitDataRequest::CommitDataRequest(const CommitDataRequest&) = default;
11277 CommitDataRequest& CommitDataRequest::operator=(const CommitDataRequest&) = default;
11278 CommitDataRequest::CommitDataRequest(CommitDataRequest&&) noexcept = default;
11279 CommitDataRequest& CommitDataRequest::operator=(CommitDataRequest&&) = default;
11280
operator ==(const CommitDataRequest & other) const11281 bool CommitDataRequest::operator==(const CommitDataRequest& other) const {
11282 return unknown_fields_ == other.unknown_fields_
11283 && chunks_to_move_ == other.chunks_to_move_
11284 && chunks_to_patch_ == other.chunks_to_patch_
11285 && flush_request_id_ == other.flush_request_id_;
11286 }
11287
chunks_to_move_size() const11288 int CommitDataRequest::chunks_to_move_size() const { return static_cast<int>(chunks_to_move_.size()); }
clear_chunks_to_move()11289 void CommitDataRequest::clear_chunks_to_move() { chunks_to_move_.clear(); }
add_chunks_to_move()11290 CommitDataRequest_ChunksToMove* CommitDataRequest::add_chunks_to_move() { chunks_to_move_.emplace_back(); return &chunks_to_move_.back(); }
chunks_to_patch_size() const11291 int CommitDataRequest::chunks_to_patch_size() const { return static_cast<int>(chunks_to_patch_.size()); }
clear_chunks_to_patch()11292 void CommitDataRequest::clear_chunks_to_patch() { chunks_to_patch_.clear(); }
add_chunks_to_patch()11293 CommitDataRequest_ChunkToPatch* CommitDataRequest::add_chunks_to_patch() { chunks_to_patch_.emplace_back(); return &chunks_to_patch_.back(); }
ParseFromArray(const void * raw,size_t size)11294 bool CommitDataRequest::ParseFromArray(const void* raw, size_t size) {
11295 chunks_to_move_.clear();
11296 chunks_to_patch_.clear();
11297 unknown_fields_.clear();
11298 bool packed_error = false;
11299
11300 ::protozero::ProtoDecoder dec(raw, size);
11301 for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
11302 if (field.id() < _has_field_.size()) {
11303 _has_field_.set(field.id());
11304 }
11305 switch (field.id()) {
11306 case 1 /* chunks_to_move */:
11307 chunks_to_move_.emplace_back();
11308 chunks_to_move_.back().ParseFromArray(field.data(), field.size());
11309 break;
11310 case 2 /* chunks_to_patch */:
11311 chunks_to_patch_.emplace_back();
11312 chunks_to_patch_.back().ParseFromArray(field.data(), field.size());
11313 break;
11314 case 3 /* flush_request_id */:
11315 field.get(&flush_request_id_);
11316 break;
11317 default:
11318 field.SerializeAndAppendTo(&unknown_fields_);
11319 break;
11320 }
11321 }
11322 return !packed_error && !dec.bytes_left();
11323 }
11324
SerializeAsString() const11325 std::string CommitDataRequest::SerializeAsString() const {
11326 ::protozero::HeapBuffered<::protozero::Message> msg;
11327 Serialize(msg.get());
11328 return msg.SerializeAsString();
11329 }
11330
SerializeAsArray() const11331 std::vector<uint8_t> CommitDataRequest::SerializeAsArray() const {
11332 ::protozero::HeapBuffered<::protozero::Message> msg;
11333 Serialize(msg.get());
11334 return msg.SerializeAsArray();
11335 }
11336
Serialize(::protozero::Message * msg) const11337 void CommitDataRequest::Serialize(::protozero::Message* msg) const {
11338 // Field 1: chunks_to_move
11339 for (auto& it : chunks_to_move_) {
11340 it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
11341 }
11342
11343 // Field 2: chunks_to_patch
11344 for (auto& it : chunks_to_patch_) {
11345 it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
11346 }
11347
11348 // Field 3: flush_request_id
11349 if (_has_field_[3]) {
11350 msg->AppendVarInt(3, flush_request_id_);
11351 }
11352
11353 msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
11354 }
11355
11356
11357 CommitDataRequest_ChunkToPatch::CommitDataRequest_ChunkToPatch() = default;
11358 CommitDataRequest_ChunkToPatch::~CommitDataRequest_ChunkToPatch() = default;
11359 CommitDataRequest_ChunkToPatch::CommitDataRequest_ChunkToPatch(const CommitDataRequest_ChunkToPatch&) = default;
11360 CommitDataRequest_ChunkToPatch& CommitDataRequest_ChunkToPatch::operator=(const CommitDataRequest_ChunkToPatch&) = default;
11361 CommitDataRequest_ChunkToPatch::CommitDataRequest_ChunkToPatch(CommitDataRequest_ChunkToPatch&&) noexcept = default;
11362 CommitDataRequest_ChunkToPatch& CommitDataRequest_ChunkToPatch::operator=(CommitDataRequest_ChunkToPatch&&) = default;
11363
operator ==(const CommitDataRequest_ChunkToPatch & other) const11364 bool CommitDataRequest_ChunkToPatch::operator==(const CommitDataRequest_ChunkToPatch& other) const {
11365 return unknown_fields_ == other.unknown_fields_
11366 && target_buffer_ == other.target_buffer_
11367 && writer_id_ == other.writer_id_
11368 && chunk_id_ == other.chunk_id_
11369 && patches_ == other.patches_
11370 && has_more_patches_ == other.has_more_patches_;
11371 }
11372
patches_size() const11373 int CommitDataRequest_ChunkToPatch::patches_size() const { return static_cast<int>(patches_.size()); }
clear_patches()11374 void CommitDataRequest_ChunkToPatch::clear_patches() { patches_.clear(); }
add_patches()11375 CommitDataRequest_ChunkToPatch_Patch* CommitDataRequest_ChunkToPatch::add_patches() { patches_.emplace_back(); return &patches_.back(); }
ParseFromArray(const void * raw,size_t size)11376 bool CommitDataRequest_ChunkToPatch::ParseFromArray(const void* raw, size_t size) {
11377 patches_.clear();
11378 unknown_fields_.clear();
11379 bool packed_error = false;
11380
11381 ::protozero::ProtoDecoder dec(raw, size);
11382 for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
11383 if (field.id() < _has_field_.size()) {
11384 _has_field_.set(field.id());
11385 }
11386 switch (field.id()) {
11387 case 1 /* target_buffer */:
11388 field.get(&target_buffer_);
11389 break;
11390 case 2 /* writer_id */:
11391 field.get(&writer_id_);
11392 break;
11393 case 3 /* chunk_id */:
11394 field.get(&chunk_id_);
11395 break;
11396 case 4 /* patches */:
11397 patches_.emplace_back();
11398 patches_.back().ParseFromArray(field.data(), field.size());
11399 break;
11400 case 5 /* has_more_patches */:
11401 field.get(&has_more_patches_);
11402 break;
11403 default:
11404 field.SerializeAndAppendTo(&unknown_fields_);
11405 break;
11406 }
11407 }
11408 return !packed_error && !dec.bytes_left();
11409 }
11410
SerializeAsString() const11411 std::string CommitDataRequest_ChunkToPatch::SerializeAsString() const {
11412 ::protozero::HeapBuffered<::protozero::Message> msg;
11413 Serialize(msg.get());
11414 return msg.SerializeAsString();
11415 }
11416
SerializeAsArray() const11417 std::vector<uint8_t> CommitDataRequest_ChunkToPatch::SerializeAsArray() const {
11418 ::protozero::HeapBuffered<::protozero::Message> msg;
11419 Serialize(msg.get());
11420 return msg.SerializeAsArray();
11421 }
11422
Serialize(::protozero::Message * msg) const11423 void CommitDataRequest_ChunkToPatch::Serialize(::protozero::Message* msg) const {
11424 // Field 1: target_buffer
11425 if (_has_field_[1]) {
11426 msg->AppendVarInt(1, target_buffer_);
11427 }
11428
11429 // Field 2: writer_id
11430 if (_has_field_[2]) {
11431 msg->AppendVarInt(2, writer_id_);
11432 }
11433
11434 // Field 3: chunk_id
11435 if (_has_field_[3]) {
11436 msg->AppendVarInt(3, chunk_id_);
11437 }
11438
11439 // Field 4: patches
11440 for (auto& it : patches_) {
11441 it.Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
11442 }
11443
11444 // Field 5: has_more_patches
11445 if (_has_field_[5]) {
11446 msg->AppendTinyVarInt(5, has_more_patches_);
11447 }
11448
11449 msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
11450 }
11451
11452
11453 CommitDataRequest_ChunkToPatch_Patch::CommitDataRequest_ChunkToPatch_Patch() = default;
11454 CommitDataRequest_ChunkToPatch_Patch::~CommitDataRequest_ChunkToPatch_Patch() = default;
11455 CommitDataRequest_ChunkToPatch_Patch::CommitDataRequest_ChunkToPatch_Patch(const CommitDataRequest_ChunkToPatch_Patch&) = default;
11456 CommitDataRequest_ChunkToPatch_Patch& CommitDataRequest_ChunkToPatch_Patch::operator=(const CommitDataRequest_ChunkToPatch_Patch&) = default;
11457 CommitDataRequest_ChunkToPatch_Patch::CommitDataRequest_ChunkToPatch_Patch(CommitDataRequest_ChunkToPatch_Patch&&) noexcept = default;
11458 CommitDataRequest_ChunkToPatch_Patch& CommitDataRequest_ChunkToPatch_Patch::operator=(CommitDataRequest_ChunkToPatch_Patch&&) = default;
11459
operator ==(const CommitDataRequest_ChunkToPatch_Patch & other) const11460 bool CommitDataRequest_ChunkToPatch_Patch::operator==(const CommitDataRequest_ChunkToPatch_Patch& other) const {
11461 return unknown_fields_ == other.unknown_fields_
11462 && offset_ == other.offset_
11463 && data_ == other.data_;
11464 }
11465
ParseFromArray(const void * raw,size_t size)11466 bool CommitDataRequest_ChunkToPatch_Patch::ParseFromArray(const void* raw, size_t size) {
11467 unknown_fields_.clear();
11468 bool packed_error = false;
11469
11470 ::protozero::ProtoDecoder dec(raw, size);
11471 for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
11472 if (field.id() < _has_field_.size()) {
11473 _has_field_.set(field.id());
11474 }
11475 switch (field.id()) {
11476 case 1 /* offset */:
11477 field.get(&offset_);
11478 break;
11479 case 2 /* data */:
11480 field.get(&data_);
11481 break;
11482 default:
11483 field.SerializeAndAppendTo(&unknown_fields_);
11484 break;
11485 }
11486 }
11487 return !packed_error && !dec.bytes_left();
11488 }
11489
SerializeAsString() const11490 std::string CommitDataRequest_ChunkToPatch_Patch::SerializeAsString() const {
11491 ::protozero::HeapBuffered<::protozero::Message> msg;
11492 Serialize(msg.get());
11493 return msg.SerializeAsString();
11494 }
11495
SerializeAsArray() const11496 std::vector<uint8_t> CommitDataRequest_ChunkToPatch_Patch::SerializeAsArray() const {
11497 ::protozero::HeapBuffered<::protozero::Message> msg;
11498 Serialize(msg.get());
11499 return msg.SerializeAsArray();
11500 }
11501
Serialize(::protozero::Message * msg) const11502 void CommitDataRequest_ChunkToPatch_Patch::Serialize(::protozero::Message* msg) const {
11503 // Field 1: offset
11504 if (_has_field_[1]) {
11505 msg->AppendVarInt(1, offset_);
11506 }
11507
11508 // Field 2: data
11509 if (_has_field_[2]) {
11510 msg->AppendString(2, data_);
11511 }
11512
11513 msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
11514 }
11515
11516
11517 CommitDataRequest_ChunksToMove::CommitDataRequest_ChunksToMove() = default;
11518 CommitDataRequest_ChunksToMove::~CommitDataRequest_ChunksToMove() = default;
11519 CommitDataRequest_ChunksToMove::CommitDataRequest_ChunksToMove(const CommitDataRequest_ChunksToMove&) = default;
11520 CommitDataRequest_ChunksToMove& CommitDataRequest_ChunksToMove::operator=(const CommitDataRequest_ChunksToMove&) = default;
11521 CommitDataRequest_ChunksToMove::CommitDataRequest_ChunksToMove(CommitDataRequest_ChunksToMove&&) noexcept = default;
11522 CommitDataRequest_ChunksToMove& CommitDataRequest_ChunksToMove::operator=(CommitDataRequest_ChunksToMove&&) = default;
11523
operator ==(const CommitDataRequest_ChunksToMove & other) const11524 bool CommitDataRequest_ChunksToMove::operator==(const CommitDataRequest_ChunksToMove& other) const {
11525 return unknown_fields_ == other.unknown_fields_
11526 && page_ == other.page_
11527 && chunk_ == other.chunk_
11528 && target_buffer_ == other.target_buffer_;
11529 }
11530
ParseFromArray(const void * raw,size_t size)11531 bool CommitDataRequest_ChunksToMove::ParseFromArray(const void* raw, size_t size) {
11532 unknown_fields_.clear();
11533 bool packed_error = false;
11534
11535 ::protozero::ProtoDecoder dec(raw, size);
11536 for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
11537 if (field.id() < _has_field_.size()) {
11538 _has_field_.set(field.id());
11539 }
11540 switch (field.id()) {
11541 case 1 /* page */:
11542 field.get(&page_);
11543 break;
11544 case 2 /* chunk */:
11545 field.get(&chunk_);
11546 break;
11547 case 3 /* target_buffer */:
11548 field.get(&target_buffer_);
11549 break;
11550 default:
11551 field.SerializeAndAppendTo(&unknown_fields_);
11552 break;
11553 }
11554 }
11555 return !packed_error && !dec.bytes_left();
11556 }
11557
SerializeAsString() const11558 std::string CommitDataRequest_ChunksToMove::SerializeAsString() const {
11559 ::protozero::HeapBuffered<::protozero::Message> msg;
11560 Serialize(msg.get());
11561 return msg.SerializeAsString();
11562 }
11563
SerializeAsArray() const11564 std::vector<uint8_t> CommitDataRequest_ChunksToMove::SerializeAsArray() const {
11565 ::protozero::HeapBuffered<::protozero::Message> msg;
11566 Serialize(msg.get());
11567 return msg.SerializeAsArray();
11568 }
11569
Serialize(::protozero::Message * msg) const11570 void CommitDataRequest_ChunksToMove::Serialize(::protozero::Message* msg) const {
11571 // Field 1: page
11572 if (_has_field_[1]) {
11573 msg->AppendVarInt(1, page_);
11574 }
11575
11576 // Field 2: chunk
11577 if (_has_field_[2]) {
11578 msg->AppendVarInt(2, chunk_);
11579 }
11580
11581 // Field 3: target_buffer
11582 if (_has_field_[3]) {
11583 msg->AppendVarInt(3, target_buffer_);
11584 }
11585
11586 msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
11587 }
11588
11589 } // namespace perfetto
11590 } // namespace protos
11591 } // namespace gen
11592 #if defined(__GNUC__) || defined(__clang__)
11593 #pragma GCC diagnostic pop
11594 #endif
11595 // gen_amalgamated begin source: gen/protos/perfetto/common/data_source_descriptor.gen.cc
11596 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
11597 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
11598 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
11599 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
11600 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
11601 #if defined(__GNUC__) || defined(__clang__)
11602 #pragma GCC diagnostic push
11603 #pragma GCC diagnostic ignored "-Wfloat-equal"
11604 #endif
11605 // gen_amalgamated expanded: #include "protos/perfetto/common/data_source_descriptor.gen.h"
11606
11607 namespace perfetto {
11608 namespace protos {
11609 namespace gen {
11610
11611 DataSourceDescriptor::DataSourceDescriptor() = default;
11612 DataSourceDescriptor::~DataSourceDescriptor() = default;
11613 DataSourceDescriptor::DataSourceDescriptor(const DataSourceDescriptor&) = default;
11614 DataSourceDescriptor& DataSourceDescriptor::operator=(const DataSourceDescriptor&) = default;
11615 DataSourceDescriptor::DataSourceDescriptor(DataSourceDescriptor&&) noexcept = default;
11616 DataSourceDescriptor& DataSourceDescriptor::operator=(DataSourceDescriptor&&) = default;
11617
operator ==(const DataSourceDescriptor & other) const11618 bool DataSourceDescriptor::operator==(const DataSourceDescriptor& other) const {
11619 return unknown_fields_ == other.unknown_fields_
11620 && name_ == other.name_
11621 && id_ == other.id_
11622 && will_notify_on_stop_ == other.will_notify_on_stop_
11623 && will_notify_on_start_ == other.will_notify_on_start_
11624 && handles_incremental_state_clear_ == other.handles_incremental_state_clear_
11625 && gpu_counter_descriptor_ == other.gpu_counter_descriptor_
11626 && track_event_descriptor_ == other.track_event_descriptor_;
11627 }
11628
ParseFromArray(const void * raw,size_t size)11629 bool DataSourceDescriptor::ParseFromArray(const void* raw, size_t size) {
11630 unknown_fields_.clear();
11631 bool packed_error = false;
11632
11633 ::protozero::ProtoDecoder dec(raw, size);
11634 for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
11635 if (field.id() < _has_field_.size()) {
11636 _has_field_.set(field.id());
11637 }
11638 switch (field.id()) {
11639 case 1 /* name */:
11640 field.get(&name_);
11641 break;
11642 case 7 /* id */:
11643 field.get(&id_);
11644 break;
11645 case 2 /* will_notify_on_stop */:
11646 field.get(&will_notify_on_stop_);
11647 break;
11648 case 3 /* will_notify_on_start */:
11649 field.get(&will_notify_on_start_);
11650 break;
11651 case 4 /* handles_incremental_state_clear */:
11652 field.get(&handles_incremental_state_clear_);
11653 break;
11654 case 5 /* gpu_counter_descriptor */:
11655 gpu_counter_descriptor_ = field.as_std_string();
11656 break;
11657 case 6 /* track_event_descriptor */:
11658 track_event_descriptor_ = field.as_std_string();
11659 break;
11660 default:
11661 field.SerializeAndAppendTo(&unknown_fields_);
11662 break;
11663 }
11664 }
11665 return !packed_error && !dec.bytes_left();
11666 }
11667
SerializeAsString() const11668 std::string DataSourceDescriptor::SerializeAsString() const {
11669 ::protozero::HeapBuffered<::protozero::Message> msg;
11670 Serialize(msg.get());
11671 return msg.SerializeAsString();
11672 }
11673
SerializeAsArray() const11674 std::vector<uint8_t> DataSourceDescriptor::SerializeAsArray() const {
11675 ::protozero::HeapBuffered<::protozero::Message> msg;
11676 Serialize(msg.get());
11677 return msg.SerializeAsArray();
11678 }
11679
Serialize(::protozero::Message * msg) const11680 void DataSourceDescriptor::Serialize(::protozero::Message* msg) const {
11681 // Field 1: name
11682 if (_has_field_[1]) {
11683 msg->AppendString(1, name_);
11684 }
11685
11686 // Field 7: id
11687 if (_has_field_[7]) {
11688 msg->AppendVarInt(7, id_);
11689 }
11690
11691 // Field 2: will_notify_on_stop
11692 if (_has_field_[2]) {
11693 msg->AppendTinyVarInt(2, will_notify_on_stop_);
11694 }
11695
11696 // Field 3: will_notify_on_start
11697 if (_has_field_[3]) {
11698 msg->AppendTinyVarInt(3, will_notify_on_start_);
11699 }
11700
11701 // Field 4: handles_incremental_state_clear
11702 if (_has_field_[4]) {
11703 msg->AppendTinyVarInt(4, handles_incremental_state_clear_);
11704 }
11705
11706 // Field 5: gpu_counter_descriptor
11707 if (_has_field_[5]) {
11708 msg->AppendString(5, gpu_counter_descriptor_);
11709 }
11710
11711 // Field 6: track_event_descriptor
11712 if (_has_field_[6]) {
11713 msg->AppendString(6, track_event_descriptor_);
11714 }
11715
11716 msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
11717 }
11718
11719 } // namespace perfetto
11720 } // namespace protos
11721 } // namespace gen
11722 #if defined(__GNUC__) || defined(__clang__)
11723 #pragma GCC diagnostic pop
11724 #endif
11725 // gen_amalgamated begin source: gen/protos/perfetto/common/descriptor.gen.cc
11726 // gen_amalgamated begin header: gen/protos/perfetto/common/descriptor.gen.h
11727 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
11728 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_DESCRIPTOR_PROTO_CPP_H_
11729 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_DESCRIPTOR_PROTO_CPP_H_
11730
11731 #include <stdint.h>
11732 #include <bitset>
11733 #include <vector>
11734 #include <string>
11735 #include <type_traits>
11736
11737 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
11738 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
11739 // gen_amalgamated expanded: #include "perfetto/base/export.h"
11740
11741 namespace perfetto {
11742 namespace protos {
11743 namespace gen {
11744 class OneofOptions;
11745 class EnumValueDescriptorProto;
11746 class EnumDescriptorProto;
11747 class OneofDescriptorProto;
11748 class FieldDescriptorProto;
11749 class DescriptorProto;
11750 class DescriptorProto_ReservedRange;
11751 class FileDescriptorProto;
11752 class FileDescriptorSet;
11753 enum FieldDescriptorProto_Type : int;
11754 enum FieldDescriptorProto_Label : int;
11755 } // namespace perfetto
11756 } // namespace protos
11757 } // namespace gen
11758
11759 namespace protozero {
11760 class Message;
11761 } // namespace protozero
11762
11763 namespace perfetto {
11764 namespace protos {
11765 namespace gen {
11766 enum FieldDescriptorProto_Type : int {
11767 FieldDescriptorProto_Type_TYPE_DOUBLE = 1,
11768 FieldDescriptorProto_Type_TYPE_FLOAT = 2,
11769 FieldDescriptorProto_Type_TYPE_INT64 = 3,
11770 FieldDescriptorProto_Type_TYPE_UINT64 = 4,
11771 FieldDescriptorProto_Type_TYPE_INT32 = 5,
11772 FieldDescriptorProto_Type_TYPE_FIXED64 = 6,
11773 FieldDescriptorProto_Type_TYPE_FIXED32 = 7,
11774 FieldDescriptorProto_Type_TYPE_BOOL = 8,
11775 FieldDescriptorProto_Type_TYPE_STRING = 9,
11776 FieldDescriptorProto_Type_TYPE_GROUP = 10,
11777 FieldDescriptorProto_Type_TYPE_MESSAGE = 11,
11778 FieldDescriptorProto_Type_TYPE_BYTES = 12,
11779 FieldDescriptorProto_Type_TYPE_UINT32 = 13,
11780 FieldDescriptorProto_Type_TYPE_ENUM = 14,
11781 FieldDescriptorProto_Type_TYPE_SFIXED32 = 15,
11782 FieldDescriptorProto_Type_TYPE_SFIXED64 = 16,
11783 FieldDescriptorProto_Type_TYPE_SINT32 = 17,
11784 FieldDescriptorProto_Type_TYPE_SINT64 = 18,
11785 };
11786 enum FieldDescriptorProto_Label : int {
11787 FieldDescriptorProto_Label_LABEL_OPTIONAL = 1,
11788 FieldDescriptorProto_Label_LABEL_REQUIRED = 2,
11789 FieldDescriptorProto_Label_LABEL_REPEATED = 3,
11790 };
11791
11792 class PERFETTO_EXPORT OneofOptions : public ::protozero::CppMessageObj {
11793 public:
11794 enum FieldNumbers {
11795 };
11796
11797 OneofOptions();
11798 ~OneofOptions() override;
11799 OneofOptions(OneofOptions&&) noexcept;
11800 OneofOptions& operator=(OneofOptions&&);
11801 OneofOptions(const OneofOptions&);
11802 OneofOptions& operator=(const OneofOptions&);
11803 bool operator==(const OneofOptions&) const;
operator !=(const OneofOptions & other) const11804 bool operator!=(const OneofOptions& other) const { return !(*this == other); }
11805
11806 bool ParseFromArray(const void*, size_t) override;
11807 std::string SerializeAsString() const override;
11808 std::vector<uint8_t> SerializeAsArray() const override;
11809 void Serialize(::protozero::Message*) const;
11810
11811 private:
11812
11813 // Allows to preserve unknown protobuf fields for compatibility
11814 // with future versions of .proto files.
11815 std::string unknown_fields_;
11816
11817 std::bitset<2> _has_field_{};
11818 };
11819
11820
11821 class PERFETTO_EXPORT EnumValueDescriptorProto : public ::protozero::CppMessageObj {
11822 public:
11823 enum FieldNumbers {
11824 kNameFieldNumber = 1,
11825 kNumberFieldNumber = 2,
11826 };
11827
11828 EnumValueDescriptorProto();
11829 ~EnumValueDescriptorProto() override;
11830 EnumValueDescriptorProto(EnumValueDescriptorProto&&) noexcept;
11831 EnumValueDescriptorProto& operator=(EnumValueDescriptorProto&&);
11832 EnumValueDescriptorProto(const EnumValueDescriptorProto&);
11833 EnumValueDescriptorProto& operator=(const EnumValueDescriptorProto&);
11834 bool operator==(const EnumValueDescriptorProto&) const;
operator !=(const EnumValueDescriptorProto & other) const11835 bool operator!=(const EnumValueDescriptorProto& other) const { return !(*this == other); }
11836
11837 bool ParseFromArray(const void*, size_t) override;
11838 std::string SerializeAsString() const override;
11839 std::vector<uint8_t> SerializeAsArray() const override;
11840 void Serialize(::protozero::Message*) const;
11841
has_name() const11842 bool has_name() const { return _has_field_[1]; }
name() const11843 const std::string& name() const { return name_; }
set_name(const std::string & value)11844 void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
11845
has_number() const11846 bool has_number() const { return _has_field_[2]; }
number() const11847 int32_t number() const { return number_; }
set_number(int32_t value)11848 void set_number(int32_t value) { number_ = value; _has_field_.set(2); }
11849
11850 private:
11851 std::string name_{};
11852 int32_t number_{};
11853
11854 // Allows to preserve unknown protobuf fields for compatibility
11855 // with future versions of .proto files.
11856 std::string unknown_fields_;
11857
11858 std::bitset<3> _has_field_{};
11859 };
11860
11861
11862 class PERFETTO_EXPORT EnumDescriptorProto : public ::protozero::CppMessageObj {
11863 public:
11864 enum FieldNumbers {
11865 kNameFieldNumber = 1,
11866 kValueFieldNumber = 2,
11867 kReservedNameFieldNumber = 5,
11868 };
11869
11870 EnumDescriptorProto();
11871 ~EnumDescriptorProto() override;
11872 EnumDescriptorProto(EnumDescriptorProto&&) noexcept;
11873 EnumDescriptorProto& operator=(EnumDescriptorProto&&);
11874 EnumDescriptorProto(const EnumDescriptorProto&);
11875 EnumDescriptorProto& operator=(const EnumDescriptorProto&);
11876 bool operator==(const EnumDescriptorProto&) const;
operator !=(const EnumDescriptorProto & other) const11877 bool operator!=(const EnumDescriptorProto& other) const { return !(*this == other); }
11878
11879 bool ParseFromArray(const void*, size_t) override;
11880 std::string SerializeAsString() const override;
11881 std::vector<uint8_t> SerializeAsArray() const override;
11882 void Serialize(::protozero::Message*) const;
11883
has_name() const11884 bool has_name() const { return _has_field_[1]; }
name() const11885 const std::string& name() const { return name_; }
set_name(const std::string & value)11886 void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
11887
value() const11888 const std::vector<EnumValueDescriptorProto>& value() const { return value_; }
mutable_value()11889 std::vector<EnumValueDescriptorProto>* mutable_value() { return &value_; }
11890 int value_size() const;
11891 void clear_value();
11892 EnumValueDescriptorProto* add_value();
11893
reserved_name() const11894 const std::vector<std::string>& reserved_name() const { return reserved_name_; }
mutable_reserved_name()11895 std::vector<std::string>* mutable_reserved_name() { return &reserved_name_; }
reserved_name_size() const11896 int reserved_name_size() const { return static_cast<int>(reserved_name_.size()); }
clear_reserved_name()11897 void clear_reserved_name() { reserved_name_.clear(); }
add_reserved_name(std::string value)11898 void add_reserved_name(std::string value) { reserved_name_.emplace_back(value); }
add_reserved_name()11899 std::string* add_reserved_name() { reserved_name_.emplace_back(); return &reserved_name_.back(); }
11900
11901 private:
11902 std::string name_{};
11903 std::vector<EnumValueDescriptorProto> value_;
11904 std::vector<std::string> reserved_name_;
11905
11906 // Allows to preserve unknown protobuf fields for compatibility
11907 // with future versions of .proto files.
11908 std::string unknown_fields_;
11909
11910 std::bitset<6> _has_field_{};
11911 };
11912
11913
11914 class PERFETTO_EXPORT OneofDescriptorProto : public ::protozero::CppMessageObj {
11915 public:
11916 enum FieldNumbers {
11917 kNameFieldNumber = 1,
11918 kOptionsFieldNumber = 2,
11919 };
11920
11921 OneofDescriptorProto();
11922 ~OneofDescriptorProto() override;
11923 OneofDescriptorProto(OneofDescriptorProto&&) noexcept;
11924 OneofDescriptorProto& operator=(OneofDescriptorProto&&);
11925 OneofDescriptorProto(const OneofDescriptorProto&);
11926 OneofDescriptorProto& operator=(const OneofDescriptorProto&);
11927 bool operator==(const OneofDescriptorProto&) const;
operator !=(const OneofDescriptorProto & other) const11928 bool operator!=(const OneofDescriptorProto& other) const { return !(*this == other); }
11929
11930 bool ParseFromArray(const void*, size_t) override;
11931 std::string SerializeAsString() const override;
11932 std::vector<uint8_t> SerializeAsArray() const override;
11933 void Serialize(::protozero::Message*) const;
11934
has_name() const11935 bool has_name() const { return _has_field_[1]; }
name() const11936 const std::string& name() const { return name_; }
set_name(const std::string & value)11937 void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
11938
has_options() const11939 bool has_options() const { return _has_field_[2]; }
options() const11940 const OneofOptions& options() const { return *options_; }
mutable_options()11941 OneofOptions* mutable_options() { _has_field_.set(2); return options_.get(); }
11942
11943 private:
11944 std::string name_{};
11945 ::protozero::CopyablePtr<OneofOptions> options_;
11946
11947 // Allows to preserve unknown protobuf fields for compatibility
11948 // with future versions of .proto files.
11949 std::string unknown_fields_;
11950
11951 std::bitset<3> _has_field_{};
11952 };
11953
11954
11955 class PERFETTO_EXPORT FieldDescriptorProto : public ::protozero::CppMessageObj {
11956 public:
11957 using Type = FieldDescriptorProto_Type;
11958 static constexpr auto TYPE_DOUBLE = FieldDescriptorProto_Type_TYPE_DOUBLE;
11959 static constexpr auto TYPE_FLOAT = FieldDescriptorProto_Type_TYPE_FLOAT;
11960 static constexpr auto TYPE_INT64 = FieldDescriptorProto_Type_TYPE_INT64;
11961 static constexpr auto TYPE_UINT64 = FieldDescriptorProto_Type_TYPE_UINT64;
11962 static constexpr auto TYPE_INT32 = FieldDescriptorProto_Type_TYPE_INT32;
11963 static constexpr auto TYPE_FIXED64 = FieldDescriptorProto_Type_TYPE_FIXED64;
11964 static constexpr auto TYPE_FIXED32 = FieldDescriptorProto_Type_TYPE_FIXED32;
11965 static constexpr auto TYPE_BOOL = FieldDescriptorProto_Type_TYPE_BOOL;
11966 static constexpr auto TYPE_STRING = FieldDescriptorProto_Type_TYPE_STRING;
11967 static constexpr auto TYPE_GROUP = FieldDescriptorProto_Type_TYPE_GROUP;
11968 static constexpr auto TYPE_MESSAGE = FieldDescriptorProto_Type_TYPE_MESSAGE;
11969 static constexpr auto TYPE_BYTES = FieldDescriptorProto_Type_TYPE_BYTES;
11970 static constexpr auto TYPE_UINT32 = FieldDescriptorProto_Type_TYPE_UINT32;
11971 static constexpr auto TYPE_ENUM = FieldDescriptorProto_Type_TYPE_ENUM;
11972 static constexpr auto TYPE_SFIXED32 = FieldDescriptorProto_Type_TYPE_SFIXED32;
11973 static constexpr auto TYPE_SFIXED64 = FieldDescriptorProto_Type_TYPE_SFIXED64;
11974 static constexpr auto TYPE_SINT32 = FieldDescriptorProto_Type_TYPE_SINT32;
11975 static constexpr auto TYPE_SINT64 = FieldDescriptorProto_Type_TYPE_SINT64;
11976 static constexpr auto Type_MIN = FieldDescriptorProto_Type_TYPE_DOUBLE;
11977 static constexpr auto Type_MAX = FieldDescriptorProto_Type_TYPE_SINT64;
11978 using Label = FieldDescriptorProto_Label;
11979 static constexpr auto LABEL_OPTIONAL = FieldDescriptorProto_Label_LABEL_OPTIONAL;
11980 static constexpr auto LABEL_REQUIRED = FieldDescriptorProto_Label_LABEL_REQUIRED;
11981 static constexpr auto LABEL_REPEATED = FieldDescriptorProto_Label_LABEL_REPEATED;
11982 static constexpr auto Label_MIN = FieldDescriptorProto_Label_LABEL_OPTIONAL;
11983 static constexpr auto Label_MAX = FieldDescriptorProto_Label_LABEL_REPEATED;
11984 enum FieldNumbers {
11985 kNameFieldNumber = 1,
11986 kNumberFieldNumber = 3,
11987 kLabelFieldNumber = 4,
11988 kTypeFieldNumber = 5,
11989 kTypeNameFieldNumber = 6,
11990 kExtendeeFieldNumber = 2,
11991 kDefaultValueFieldNumber = 7,
11992 kOneofIndexFieldNumber = 9,
11993 };
11994
11995 FieldDescriptorProto();
11996 ~FieldDescriptorProto() override;
11997 FieldDescriptorProto(FieldDescriptorProto&&) noexcept;
11998 FieldDescriptorProto& operator=(FieldDescriptorProto&&);
11999 FieldDescriptorProto(const FieldDescriptorProto&);
12000 FieldDescriptorProto& operator=(const FieldDescriptorProto&);
12001 bool operator==(const FieldDescriptorProto&) const;
operator !=(const FieldDescriptorProto & other) const12002 bool operator!=(const FieldDescriptorProto& other) const { return !(*this == other); }
12003
12004 bool ParseFromArray(const void*, size_t) override;
12005 std::string SerializeAsString() const override;
12006 std::vector<uint8_t> SerializeAsArray() const override;
12007 void Serialize(::protozero::Message*) const;
12008
has_name() const12009 bool has_name() const { return _has_field_[1]; }
name() const12010 const std::string& name() const { return name_; }
set_name(const std::string & value)12011 void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
12012
has_number() const12013 bool has_number() const { return _has_field_[3]; }
number() const12014 int32_t number() const { return number_; }
set_number(int32_t value)12015 void set_number(int32_t value) { number_ = value; _has_field_.set(3); }
12016
has_label() const12017 bool has_label() const { return _has_field_[4]; }
label() const12018 FieldDescriptorProto_Label label() const { return label_; }
set_label(FieldDescriptorProto_Label value)12019 void set_label(FieldDescriptorProto_Label value) { label_ = value; _has_field_.set(4); }
12020
has_type() const12021 bool has_type() const { return _has_field_[5]; }
type() const12022 FieldDescriptorProto_Type type() const { return type_; }
set_type(FieldDescriptorProto_Type value)12023 void set_type(FieldDescriptorProto_Type value) { type_ = value; _has_field_.set(5); }
12024
has_type_name() const12025 bool has_type_name() const { return _has_field_[6]; }
type_name() const12026 const std::string& type_name() const { return type_name_; }
set_type_name(const std::string & value)12027 void set_type_name(const std::string& value) { type_name_ = value; _has_field_.set(6); }
12028
has_extendee() const12029 bool has_extendee() const { return _has_field_[2]; }
extendee() const12030 const std::string& extendee() const { return extendee_; }
set_extendee(const std::string & value)12031 void set_extendee(const std::string& value) { extendee_ = value; _has_field_.set(2); }
12032
has_default_value() const12033 bool has_default_value() const { return _has_field_[7]; }
default_value() const12034 const std::string& default_value() const { return default_value_; }
set_default_value(const std::string & value)12035 void set_default_value(const std::string& value) { default_value_ = value; _has_field_.set(7); }
12036
has_oneof_index() const12037 bool has_oneof_index() const { return _has_field_[9]; }
oneof_index() const12038 int32_t oneof_index() const { return oneof_index_; }
set_oneof_index(int32_t value)12039 void set_oneof_index(int32_t value) { oneof_index_ = value; _has_field_.set(9); }
12040
12041 private:
12042 std::string name_{};
12043 int32_t number_{};
12044 FieldDescriptorProto_Label label_{};
12045 FieldDescriptorProto_Type type_{};
12046 std::string type_name_{};
12047 std::string extendee_{};
12048 std::string default_value_{};
12049 int32_t oneof_index_{};
12050
12051 // Allows to preserve unknown protobuf fields for compatibility
12052 // with future versions of .proto files.
12053 std::string unknown_fields_;
12054
12055 std::bitset<10> _has_field_{};
12056 };
12057
12058
12059 class PERFETTO_EXPORT DescriptorProto : public ::protozero::CppMessageObj {
12060 public:
12061 using ReservedRange = DescriptorProto_ReservedRange;
12062 enum FieldNumbers {
12063 kNameFieldNumber = 1,
12064 kFieldFieldNumber = 2,
12065 kExtensionFieldNumber = 6,
12066 kNestedTypeFieldNumber = 3,
12067 kEnumTypeFieldNumber = 4,
12068 kOneofDeclFieldNumber = 8,
12069 kReservedRangeFieldNumber = 9,
12070 kReservedNameFieldNumber = 10,
12071 };
12072
12073 DescriptorProto();
12074 ~DescriptorProto() override;
12075 DescriptorProto(DescriptorProto&&) noexcept;
12076 DescriptorProto& operator=(DescriptorProto&&);
12077 DescriptorProto(const DescriptorProto&);
12078 DescriptorProto& operator=(const DescriptorProto&);
12079 bool operator==(const DescriptorProto&) const;
operator !=(const DescriptorProto & other) const12080 bool operator!=(const DescriptorProto& other) const { return !(*this == other); }
12081
12082 bool ParseFromArray(const void*, size_t) override;
12083 std::string SerializeAsString() const override;
12084 std::vector<uint8_t> SerializeAsArray() const override;
12085 void Serialize(::protozero::Message*) const;
12086
has_name() const12087 bool has_name() const { return _has_field_[1]; }
name() const12088 const std::string& name() const { return name_; }
set_name(const std::string & value)12089 void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
12090
field() const12091 const std::vector<FieldDescriptorProto>& field() const { return field_; }
mutable_field()12092 std::vector<FieldDescriptorProto>* mutable_field() { return &field_; }
12093 int field_size() const;
12094 void clear_field();
12095 FieldDescriptorProto* add_field();
12096
extension() const12097 const std::vector<FieldDescriptorProto>& extension() const { return extension_; }
mutable_extension()12098 std::vector<FieldDescriptorProto>* mutable_extension() { return &extension_; }
12099 int extension_size() const;
12100 void clear_extension();
12101 FieldDescriptorProto* add_extension();
12102
nested_type() const12103 const std::vector<DescriptorProto>& nested_type() const { return nested_type_; }
mutable_nested_type()12104 std::vector<DescriptorProto>* mutable_nested_type() { return &nested_type_; }
12105 int nested_type_size() const;
12106 void clear_nested_type();
12107 DescriptorProto* add_nested_type();
12108
enum_type() const12109 const std::vector<EnumDescriptorProto>& enum_type() const { return enum_type_; }
mutable_enum_type()12110 std::vector<EnumDescriptorProto>* mutable_enum_type() { return &enum_type_; }
12111 int enum_type_size() const;
12112 void clear_enum_type();
12113 EnumDescriptorProto* add_enum_type();
12114
oneof_decl() const12115 const std::vector<OneofDescriptorProto>& oneof_decl() const { return oneof_decl_; }
mutable_oneof_decl()12116 std::vector<OneofDescriptorProto>* mutable_oneof_decl() { return &oneof_decl_; }
12117 int oneof_decl_size() const;
12118 void clear_oneof_decl();
12119 OneofDescriptorProto* add_oneof_decl();
12120
reserved_range() const12121 const std::vector<DescriptorProto_ReservedRange>& reserved_range() const { return reserved_range_; }
mutable_reserved_range()12122 std::vector<DescriptorProto_ReservedRange>* mutable_reserved_range() { return &reserved_range_; }
12123 int reserved_range_size() const;
12124 void clear_reserved_range();
12125 DescriptorProto_ReservedRange* add_reserved_range();
12126
reserved_name() const12127 const std::vector<std::string>& reserved_name() const { return reserved_name_; }
mutable_reserved_name()12128 std::vector<std::string>* mutable_reserved_name() { return &reserved_name_; }
reserved_name_size() const12129 int reserved_name_size() const { return static_cast<int>(reserved_name_.size()); }
clear_reserved_name()12130 void clear_reserved_name() { reserved_name_.clear(); }
add_reserved_name(std::string value)12131 void add_reserved_name(std::string value) { reserved_name_.emplace_back(value); }
add_reserved_name()12132 std::string* add_reserved_name() { reserved_name_.emplace_back(); return &reserved_name_.back(); }
12133
12134 private:
12135 std::string name_{};
12136 std::vector<FieldDescriptorProto> field_;
12137 std::vector<FieldDescriptorProto> extension_;
12138 std::vector<DescriptorProto> nested_type_;
12139 std::vector<EnumDescriptorProto> enum_type_;
12140 std::vector<OneofDescriptorProto> oneof_decl_;
12141 std::vector<DescriptorProto_ReservedRange> reserved_range_;
12142 std::vector<std::string> reserved_name_;
12143
12144 // Allows to preserve unknown protobuf fields for compatibility
12145 // with future versions of .proto files.
12146 std::string unknown_fields_;
12147
12148 std::bitset<11> _has_field_{};
12149 };
12150
12151
12152 class PERFETTO_EXPORT DescriptorProto_ReservedRange : public ::protozero::CppMessageObj {
12153 public:
12154 enum FieldNumbers {
12155 kStartFieldNumber = 1,
12156 kEndFieldNumber = 2,
12157 };
12158
12159 DescriptorProto_ReservedRange();
12160 ~DescriptorProto_ReservedRange() override;
12161 DescriptorProto_ReservedRange(DescriptorProto_ReservedRange&&) noexcept;
12162 DescriptorProto_ReservedRange& operator=(DescriptorProto_ReservedRange&&);
12163 DescriptorProto_ReservedRange(const DescriptorProto_ReservedRange&);
12164 DescriptorProto_ReservedRange& operator=(const DescriptorProto_ReservedRange&);
12165 bool operator==(const DescriptorProto_ReservedRange&) const;
operator !=(const DescriptorProto_ReservedRange & other) const12166 bool operator!=(const DescriptorProto_ReservedRange& other) const { return !(*this == other); }
12167
12168 bool ParseFromArray(const void*, size_t) override;
12169 std::string SerializeAsString() const override;
12170 std::vector<uint8_t> SerializeAsArray() const override;
12171 void Serialize(::protozero::Message*) const;
12172
has_start() const12173 bool has_start() const { return _has_field_[1]; }
start() const12174 int32_t start() const { return start_; }
set_start(int32_t value)12175 void set_start(int32_t value) { start_ = value; _has_field_.set(1); }
12176
has_end() const12177 bool has_end() const { return _has_field_[2]; }
end() const12178 int32_t end() const { return end_; }
set_end(int32_t value)12179 void set_end(int32_t value) { end_ = value; _has_field_.set(2); }
12180
12181 private:
12182 int32_t start_{};
12183 int32_t end_{};
12184
12185 // Allows to preserve unknown protobuf fields for compatibility
12186 // with future versions of .proto files.
12187 std::string unknown_fields_;
12188
12189 std::bitset<3> _has_field_{};
12190 };
12191
12192
12193 class PERFETTO_EXPORT FileDescriptorProto : public ::protozero::CppMessageObj {
12194 public:
12195 enum FieldNumbers {
12196 kNameFieldNumber = 1,
12197 kPackageFieldNumber = 2,
12198 kDependencyFieldNumber = 3,
12199 kPublicDependencyFieldNumber = 10,
12200 kWeakDependencyFieldNumber = 11,
12201 kMessageTypeFieldNumber = 4,
12202 kEnumTypeFieldNumber = 5,
12203 kExtensionFieldNumber = 7,
12204 };
12205
12206 FileDescriptorProto();
12207 ~FileDescriptorProto() override;
12208 FileDescriptorProto(FileDescriptorProto&&) noexcept;
12209 FileDescriptorProto& operator=(FileDescriptorProto&&);
12210 FileDescriptorProto(const FileDescriptorProto&);
12211 FileDescriptorProto& operator=(const FileDescriptorProto&);
12212 bool operator==(const FileDescriptorProto&) const;
operator !=(const FileDescriptorProto & other) const12213 bool operator!=(const FileDescriptorProto& other) const { return !(*this == other); }
12214
12215 bool ParseFromArray(const void*, size_t) override;
12216 std::string SerializeAsString() const override;
12217 std::vector<uint8_t> SerializeAsArray() const override;
12218 void Serialize(::protozero::Message*) const;
12219
has_name() const12220 bool has_name() const { return _has_field_[1]; }
name() const12221 const std::string& name() const { return name_; }
set_name(const std::string & value)12222 void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
12223
has_package() const12224 bool has_package() const { return _has_field_[2]; }
package() const12225 const std::string& package() const { return package_; }
set_package(const std::string & value)12226 void set_package(const std::string& value) { package_ = value; _has_field_.set(2); }
12227
dependency() const12228 const std::vector<std::string>& dependency() const { return dependency_; }
mutable_dependency()12229 std::vector<std::string>* mutable_dependency() { return &dependency_; }
dependency_size() const12230 int dependency_size() const { return static_cast<int>(dependency_.size()); }
clear_dependency()12231 void clear_dependency() { dependency_.clear(); }
add_dependency(std::string value)12232 void add_dependency(std::string value) { dependency_.emplace_back(value); }
add_dependency()12233 std::string* add_dependency() { dependency_.emplace_back(); return &dependency_.back(); }
12234
public_dependency() const12235 const std::vector<int32_t>& public_dependency() const { return public_dependency_; }
mutable_public_dependency()12236 std::vector<int32_t>* mutable_public_dependency() { return &public_dependency_; }
public_dependency_size() const12237 int public_dependency_size() const { return static_cast<int>(public_dependency_.size()); }
clear_public_dependency()12238 void clear_public_dependency() { public_dependency_.clear(); }
add_public_dependency(int32_t value)12239 void add_public_dependency(int32_t value) { public_dependency_.emplace_back(value); }
add_public_dependency()12240 int32_t* add_public_dependency() { public_dependency_.emplace_back(); return &public_dependency_.back(); }
12241
weak_dependency() const12242 const std::vector<int32_t>& weak_dependency() const { return weak_dependency_; }
mutable_weak_dependency()12243 std::vector<int32_t>* mutable_weak_dependency() { return &weak_dependency_; }
weak_dependency_size() const12244 int weak_dependency_size() const { return static_cast<int>(weak_dependency_.size()); }
clear_weak_dependency()12245 void clear_weak_dependency() { weak_dependency_.clear(); }
add_weak_dependency(int32_t value)12246 void add_weak_dependency(int32_t value) { weak_dependency_.emplace_back(value); }
add_weak_dependency()12247 int32_t* add_weak_dependency() { weak_dependency_.emplace_back(); return &weak_dependency_.back(); }
12248
message_type() const12249 const std::vector<DescriptorProto>& message_type() const { return message_type_; }
mutable_message_type()12250 std::vector<DescriptorProto>* mutable_message_type() { return &message_type_; }
12251 int message_type_size() const;
12252 void clear_message_type();
12253 DescriptorProto* add_message_type();
12254
enum_type() const12255 const std::vector<EnumDescriptorProto>& enum_type() const { return enum_type_; }
mutable_enum_type()12256 std::vector<EnumDescriptorProto>* mutable_enum_type() { return &enum_type_; }
12257 int enum_type_size() const;
12258 void clear_enum_type();
12259 EnumDescriptorProto* add_enum_type();
12260
extension() const12261 const std::vector<FieldDescriptorProto>& extension() const { return extension_; }
mutable_extension()12262 std::vector<FieldDescriptorProto>* mutable_extension() { return &extension_; }
12263 int extension_size() const;
12264 void clear_extension();
12265 FieldDescriptorProto* add_extension();
12266
12267 private:
12268 std::string name_{};
12269 std::string package_{};
12270 std::vector<std::string> dependency_;
12271 std::vector<int32_t> public_dependency_;
12272 std::vector<int32_t> weak_dependency_;
12273 std::vector<DescriptorProto> message_type_;
12274 std::vector<EnumDescriptorProto> enum_type_;
12275 std::vector<FieldDescriptorProto> extension_;
12276
12277 // Allows to preserve unknown protobuf fields for compatibility
12278 // with future versions of .proto files.
12279 std::string unknown_fields_;
12280
12281 std::bitset<12> _has_field_{};
12282 };
12283
12284
12285 class PERFETTO_EXPORT FileDescriptorSet : public ::protozero::CppMessageObj {
12286 public:
12287 enum FieldNumbers {
12288 kFileFieldNumber = 1,
12289 };
12290
12291 FileDescriptorSet();
12292 ~FileDescriptorSet() override;
12293 FileDescriptorSet(FileDescriptorSet&&) noexcept;
12294 FileDescriptorSet& operator=(FileDescriptorSet&&);
12295 FileDescriptorSet(const FileDescriptorSet&);
12296 FileDescriptorSet& operator=(const FileDescriptorSet&);
12297 bool operator==(const FileDescriptorSet&) const;
operator !=(const FileDescriptorSet & other) const12298 bool operator!=(const FileDescriptorSet& other) const { return !(*this == other); }
12299
12300 bool ParseFromArray(const void*, size_t) override;
12301 std::string SerializeAsString() const override;
12302 std::vector<uint8_t> SerializeAsArray() const override;
12303 void Serialize(::protozero::Message*) const;
12304
file() const12305 const std::vector<FileDescriptorProto>& file() const { return file_; }
mutable_file()12306 std::vector<FileDescriptorProto>* mutable_file() { return &file_; }
12307 int file_size() const;
12308 void clear_file();
12309 FileDescriptorProto* add_file();
12310
12311 private:
12312 std::vector<FileDescriptorProto> file_;
12313
12314 // Allows to preserve unknown protobuf fields for compatibility
12315 // with future versions of .proto files.
12316 std::string unknown_fields_;
12317
12318 std::bitset<2> _has_field_{};
12319 };
12320
12321 } // namespace perfetto
12322 } // namespace protos
12323 } // namespace gen
12324
12325 #endif // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_DESCRIPTOR_PROTO_CPP_H_
12326 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
12327 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
12328 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
12329 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
12330 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
12331 #if defined(__GNUC__) || defined(__clang__)
12332 #pragma GCC diagnostic push
12333 #pragma GCC diagnostic ignored "-Wfloat-equal"
12334 #endif
12335 // gen_amalgamated expanded: #include "protos/perfetto/common/descriptor.gen.h"
12336
12337 namespace perfetto {
12338 namespace protos {
12339 namespace gen {
12340
12341 OneofOptions::OneofOptions() = default;
12342 OneofOptions::~OneofOptions() = default;
12343 OneofOptions::OneofOptions(const OneofOptions&) = default;
12344 OneofOptions& OneofOptions::operator=(const OneofOptions&) = default;
12345 OneofOptions::OneofOptions(OneofOptions&&) noexcept = default;
12346 OneofOptions& OneofOptions::operator=(OneofOptions&&) = default;
12347
operator ==(const OneofOptions & other) const12348 bool OneofOptions::operator==(const OneofOptions& other) const {
12349 return unknown_fields_ == other.unknown_fields_;
12350 }
12351
ParseFromArray(const void * raw,size_t size)12352 bool OneofOptions::ParseFromArray(const void* raw, size_t size) {
12353 unknown_fields_.clear();
12354 bool packed_error = false;
12355
12356 ::protozero::ProtoDecoder dec(raw, size);
12357 for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
12358 if (field.id() < _has_field_.size()) {
12359 _has_field_.set(field.id());
12360 }
12361 switch (field.id()) {
12362 default:
12363 field.SerializeAndAppendTo(&unknown_fields_);
12364 break;
12365 }
12366 }
12367 return !packed_error && !dec.bytes_left();
12368 }
12369
SerializeAsString() const12370 std::string OneofOptions::SerializeAsString() const {
12371 ::protozero::HeapBuffered<::protozero::Message> msg;
12372 Serialize(msg.get());
12373 return msg.SerializeAsString();
12374 }
12375
SerializeAsArray() const12376 std::vector<uint8_t> OneofOptions::SerializeAsArray() const {
12377 ::protozero::HeapBuffered<::protozero::Message> msg;
12378 Serialize(msg.get());
12379 return msg.SerializeAsArray();
12380 }
12381
Serialize(::protozero::Message * msg) const12382 void OneofOptions::Serialize(::protozero::Message* msg) const {
12383 msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
12384 }
12385
12386
12387 EnumValueDescriptorProto::EnumValueDescriptorProto() = default;
12388 EnumValueDescriptorProto::~EnumValueDescriptorProto() = default;
12389 EnumValueDescriptorProto::EnumValueDescriptorProto(const EnumValueDescriptorProto&) = default;
12390 EnumValueDescriptorProto& EnumValueDescriptorProto::operator=(const EnumValueDescriptorProto&) = default;
12391 EnumValueDescriptorProto::EnumValueDescriptorProto(EnumValueDescriptorProto&&) noexcept = default;
12392 EnumValueDescriptorProto& EnumValueDescriptorProto::operator=(EnumValueDescriptorProto&&) = default;
12393
operator ==(const EnumValueDescriptorProto & other) const12394 bool EnumValueDescriptorProto::operator==(const EnumValueDescriptorProto& other) const {
12395 return unknown_fields_ == other.unknown_fields_
12396 && name_ == other.name_
12397 && number_ == other.number_;
12398 }
12399
ParseFromArray(const void * raw,size_t size)12400 bool EnumValueDescriptorProto::ParseFromArray(const void* raw, size_t size) {
12401 unknown_fields_.clear();
12402 bool packed_error = false;
12403
12404 ::protozero::ProtoDecoder dec(raw, size);
12405 for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
12406 if (field.id() < _has_field_.size()) {
12407 _has_field_.set(field.id());
12408 }
12409 switch (field.id()) {
12410 case 1 /* name */:
12411 field.get(&name_);
12412 break;
12413 case 2 /* number */:
12414 field.get(&number_);
12415 break;
12416 default:
12417 field.SerializeAndAppendTo(&unknown_fields_);
12418 break;
12419 }
12420 }
12421 return !packed_error && !dec.bytes_left();
12422 }
12423
SerializeAsString() const12424 std::string EnumValueDescriptorProto::SerializeAsString() const {
12425 ::protozero::HeapBuffered<::protozero::Message> msg;
12426 Serialize(msg.get());
12427 return msg.SerializeAsString();
12428 }
12429
SerializeAsArray() const12430 std::vector<uint8_t> EnumValueDescriptorProto::SerializeAsArray() const {
12431 ::protozero::HeapBuffered<::protozero::Message> msg;
12432 Serialize(msg.get());
12433 return msg.SerializeAsArray();
12434 }
12435
Serialize(::protozero::Message * msg) const12436 void EnumValueDescriptorProto::Serialize(::protozero::Message* msg) const {
12437 // Field 1: name
12438 if (_has_field_[1]) {
12439 msg->AppendString(1, name_);
12440 }
12441
12442 // Field 2: number
12443 if (_has_field_[2]) {
12444 msg->AppendVarInt(2, number_);
12445 }
12446
12447 msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
12448 }
12449
12450
12451 EnumDescriptorProto::EnumDescriptorProto() = default;
12452 EnumDescriptorProto::~EnumDescriptorProto() = default;
12453 EnumDescriptorProto::EnumDescriptorProto(const EnumDescriptorProto&) = default;
12454 EnumDescriptorProto& EnumDescriptorProto::operator=(const EnumDescriptorProto&) = default;
12455 EnumDescriptorProto::EnumDescriptorProto(EnumDescriptorProto&&) noexcept = default;
12456 EnumDescriptorProto& EnumDescriptorProto::operator=(EnumDescriptorProto&&) = default;
12457
operator ==(const EnumDescriptorProto & other) const12458 bool EnumDescriptorProto::operator==(const EnumDescriptorProto& other) const {
12459 return unknown_fields_ == other.unknown_fields_
12460 && name_ == other.name_
12461 && value_ == other.value_
12462 && reserved_name_ == other.reserved_name_;
12463 }
12464
value_size() const12465 int EnumDescriptorProto::value_size() const { return static_cast<int>(value_.size()); }
clear_value()12466 void EnumDescriptorProto::clear_value() { value_.clear(); }
add_value()12467 EnumValueDescriptorProto* EnumDescriptorProto::add_value() { value_.emplace_back(); return &value_.back(); }
ParseFromArray(const void * raw,size_t size)12468 bool EnumDescriptorProto::ParseFromArray(const void* raw, size_t size) {
12469 value_.clear();
12470 reserved_name_.clear();
12471 unknown_fields_.clear();
12472 bool packed_error = false;
12473
12474 ::protozero::ProtoDecoder dec(raw, size);
12475 for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
12476 if (field.id() < _has_field_.size()) {
12477 _has_field_.set(field.id());
12478 }
12479 switch (field.id()) {
12480 case 1 /* name */:
12481 field.get(&name_);
12482 break;
12483 case 2 /* value */:
12484 value_.emplace_back();
12485 value_.back().ParseFromArray(field.data(), field.size());
12486 break;
12487 case 5 /* reserved_name */:
12488 reserved_name_.emplace_back();
12489 field.get(&reserved_name_.back());
12490 break;
12491 default:
12492 field.SerializeAndAppendTo(&unknown_fields_);
12493 break;
12494 }
12495 }
12496 return !packed_error && !dec.bytes_left();
12497 }
12498
SerializeAsString() const12499 std::string EnumDescriptorProto::SerializeAsString() const {
12500 ::protozero::HeapBuffered<::protozero::Message> msg;
12501 Serialize(msg.get());
12502 return msg.SerializeAsString();
12503 }
12504
SerializeAsArray() const12505 std::vector<uint8_t> EnumDescriptorProto::SerializeAsArray() const {
12506 ::protozero::HeapBuffered<::protozero::Message> msg;
12507 Serialize(msg.get());
12508 return msg.SerializeAsArray();
12509 }
12510
Serialize(::protozero::Message * msg) const12511 void EnumDescriptorProto::Serialize(::protozero::Message* msg) const {
12512 // Field 1: name
12513 if (_has_field_[1]) {
12514 msg->AppendString(1, name_);
12515 }
12516
12517 // Field 2: value
12518 for (auto& it : value_) {
12519 it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
12520 }
12521
12522 // Field 5: reserved_name
12523 for (auto& it : reserved_name_) {
12524 msg->AppendString(5, it);
12525 }
12526
12527 msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
12528 }
12529
12530
12531 OneofDescriptorProto::OneofDescriptorProto() = default;
12532 OneofDescriptorProto::~OneofDescriptorProto() = default;
12533 OneofDescriptorProto::OneofDescriptorProto(const OneofDescriptorProto&) = default;
12534 OneofDescriptorProto& OneofDescriptorProto::operator=(const OneofDescriptorProto&) = default;
12535 OneofDescriptorProto::OneofDescriptorProto(OneofDescriptorProto&&) noexcept = default;
12536 OneofDescriptorProto& OneofDescriptorProto::operator=(OneofDescriptorProto&&) = default;
12537
operator ==(const OneofDescriptorProto & other) const12538 bool OneofDescriptorProto::operator==(const OneofDescriptorProto& other) const {
12539 return unknown_fields_ == other.unknown_fields_
12540 && name_ == other.name_
12541 && options_ == other.options_;
12542 }
12543
ParseFromArray(const void * raw,size_t size)12544 bool OneofDescriptorProto::ParseFromArray(const void* raw, size_t size) {
12545 unknown_fields_.clear();
12546 bool packed_error = false;
12547
12548 ::protozero::ProtoDecoder dec(raw, size);
12549 for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
12550 if (field.id() < _has_field_.size()) {
12551 _has_field_.set(field.id());
12552 }
12553 switch (field.id()) {
12554 case 1 /* name */:
12555 field.get(&name_);
12556 break;
12557 case 2 /* options */:
12558 (*options_).ParseFromArray(field.data(), field.size());
12559 break;
12560 default:
12561 field.SerializeAndAppendTo(&unknown_fields_);
12562 break;
12563 }
12564 }
12565 return !packed_error && !dec.bytes_left();
12566 }
12567
SerializeAsString() const12568 std::string OneofDescriptorProto::SerializeAsString() const {
12569 ::protozero::HeapBuffered<::protozero::Message> msg;
12570 Serialize(msg.get());
12571 return msg.SerializeAsString();
12572 }
12573
SerializeAsArray() const12574 std::vector<uint8_t> OneofDescriptorProto::SerializeAsArray() const {
12575 ::protozero::HeapBuffered<::protozero::Message> msg;
12576 Serialize(msg.get());
12577 return msg.SerializeAsArray();
12578 }
12579
Serialize(::protozero::Message * msg) const12580 void OneofDescriptorProto::Serialize(::protozero::Message* msg) const {
12581 // Field 1: name
12582 if (_has_field_[1]) {
12583 msg->AppendString(1, name_);
12584 }
12585
12586 // Field 2: options
12587 if (_has_field_[2]) {
12588 (*options_).Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
12589 }
12590
12591 msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
12592 }
12593
12594
12595 FieldDescriptorProto::FieldDescriptorProto() = default;
12596 FieldDescriptorProto::~FieldDescriptorProto() = default;
12597 FieldDescriptorProto::FieldDescriptorProto(const FieldDescriptorProto&) = default;
12598 FieldDescriptorProto& FieldDescriptorProto::operator=(const FieldDescriptorProto&) = default;
12599 FieldDescriptorProto::FieldDescriptorProto(FieldDescriptorProto&&) noexcept = default;
12600 FieldDescriptorProto& FieldDescriptorProto::operator=(FieldDescriptorProto&&) = default;
12601
operator ==(const FieldDescriptorProto & other) const12602 bool FieldDescriptorProto::operator==(const FieldDescriptorProto& other) const {
12603 return unknown_fields_ == other.unknown_fields_
12604 && name_ == other.name_
12605 && number_ == other.number_
12606 && label_ == other.label_
12607 && type_ == other.type_
12608 && type_name_ == other.type_name_
12609 && extendee_ == other.extendee_
12610 && default_value_ == other.default_value_
12611 && oneof_index_ == other.oneof_index_;
12612 }
12613
ParseFromArray(const void * raw,size_t size)12614 bool FieldDescriptorProto::ParseFromArray(const void* raw, size_t size) {
12615 unknown_fields_.clear();
12616 bool packed_error = false;
12617
12618 ::protozero::ProtoDecoder dec(raw, size);
12619 for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
12620 if (field.id() < _has_field_.size()) {
12621 _has_field_.set(field.id());
12622 }
12623 switch (field.id()) {
12624 case 1 /* name */:
12625 field.get(&name_);
12626 break;
12627 case 3 /* number */:
12628 field.get(&number_);
12629 break;
12630 case 4 /* label */:
12631 field.get(&label_);
12632 break;
12633 case 5 /* type */:
12634 field.get(&type_);
12635 break;
12636 case 6 /* type_name */:
12637 field.get(&type_name_);
12638 break;
12639 case 2 /* extendee */:
12640 field.get(&extendee_);
12641 break;
12642 case 7 /* default_value */:
12643 field.get(&default_value_);
12644 break;
12645 case 9 /* oneof_index */:
12646 field.get(&oneof_index_);
12647 break;
12648 default:
12649 field.SerializeAndAppendTo(&unknown_fields_);
12650 break;
12651 }
12652 }
12653 return !packed_error && !dec.bytes_left();
12654 }
12655
SerializeAsString() const12656 std::string FieldDescriptorProto::SerializeAsString() const {
12657 ::protozero::HeapBuffered<::protozero::Message> msg;
12658 Serialize(msg.get());
12659 return msg.SerializeAsString();
12660 }
12661
SerializeAsArray() const12662 std::vector<uint8_t> FieldDescriptorProto::SerializeAsArray() const {
12663 ::protozero::HeapBuffered<::protozero::Message> msg;
12664 Serialize(msg.get());
12665 return msg.SerializeAsArray();
12666 }
12667
Serialize(::protozero::Message * msg) const12668 void FieldDescriptorProto::Serialize(::protozero::Message* msg) const {
12669 // Field 1: name
12670 if (_has_field_[1]) {
12671 msg->AppendString(1, name_);
12672 }
12673
12674 // Field 3: number
12675 if (_has_field_[3]) {
12676 msg->AppendVarInt(3, number_);
12677 }
12678
12679 // Field 4: label
12680 if (_has_field_[4]) {
12681 msg->AppendVarInt(4, label_);
12682 }
12683
12684 // Field 5: type
12685 if (_has_field_[5]) {
12686 msg->AppendVarInt(5, type_);
12687 }
12688
12689 // Field 6: type_name
12690 if (_has_field_[6]) {
12691 msg->AppendString(6, type_name_);
12692 }
12693
12694 // Field 2: extendee
12695 if (_has_field_[2]) {
12696 msg->AppendString(2, extendee_);
12697 }
12698
12699 // Field 7: default_value
12700 if (_has_field_[7]) {
12701 msg->AppendString(7, default_value_);
12702 }
12703
12704 // Field 9: oneof_index
12705 if (_has_field_[9]) {
12706 msg->AppendVarInt(9, oneof_index_);
12707 }
12708
12709 msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
12710 }
12711
12712
12713 DescriptorProto::DescriptorProto() = default;
12714 DescriptorProto::~DescriptorProto() = default;
12715 DescriptorProto::DescriptorProto(const DescriptorProto&) = default;
12716 DescriptorProto& DescriptorProto::operator=(const DescriptorProto&) = default;
12717 DescriptorProto::DescriptorProto(DescriptorProto&&) noexcept = default;
12718 DescriptorProto& DescriptorProto::operator=(DescriptorProto&&) = default;
12719
operator ==(const DescriptorProto & other) const12720 bool DescriptorProto::operator==(const DescriptorProto& other) const {
12721 return unknown_fields_ == other.unknown_fields_
12722 && name_ == other.name_
12723 && field_ == other.field_
12724 && extension_ == other.extension_
12725 && nested_type_ == other.nested_type_
12726 && enum_type_ == other.enum_type_
12727 && oneof_decl_ == other.oneof_decl_
12728 && reserved_range_ == other.reserved_range_
12729 && reserved_name_ == other.reserved_name_;
12730 }
12731
field_size() const12732 int DescriptorProto::field_size() const { return static_cast<int>(field_.size()); }
clear_field()12733 void DescriptorProto::clear_field() { field_.clear(); }
add_field()12734 FieldDescriptorProto* DescriptorProto::add_field() { field_.emplace_back(); return &field_.back(); }
extension_size() const12735 int DescriptorProto::extension_size() const { return static_cast<int>(extension_.size()); }
clear_extension()12736 void DescriptorProto::clear_extension() { extension_.clear(); }
add_extension()12737 FieldDescriptorProto* DescriptorProto::add_extension() { extension_.emplace_back(); return &extension_.back(); }
nested_type_size() const12738 int DescriptorProto::nested_type_size() const { return static_cast<int>(nested_type_.size()); }
clear_nested_type()12739 void DescriptorProto::clear_nested_type() { nested_type_.clear(); }
add_nested_type()12740 DescriptorProto* DescriptorProto::add_nested_type() { nested_type_.emplace_back(); return &nested_type_.back(); }
enum_type_size() const12741 int DescriptorProto::enum_type_size() const { return static_cast<int>(enum_type_.size()); }
clear_enum_type()12742 void DescriptorProto::clear_enum_type() { enum_type_.clear(); }
add_enum_type()12743 EnumDescriptorProto* DescriptorProto::add_enum_type() { enum_type_.emplace_back(); return &enum_type_.back(); }
oneof_decl_size() const12744 int DescriptorProto::oneof_decl_size() const { return static_cast<int>(oneof_decl_.size()); }
clear_oneof_decl()12745 void DescriptorProto::clear_oneof_decl() { oneof_decl_.clear(); }
add_oneof_decl()12746 OneofDescriptorProto* DescriptorProto::add_oneof_decl() { oneof_decl_.emplace_back(); return &oneof_decl_.back(); }
reserved_range_size() const12747 int DescriptorProto::reserved_range_size() const { return static_cast<int>(reserved_range_.size()); }
clear_reserved_range()12748 void DescriptorProto::clear_reserved_range() { reserved_range_.clear(); }
add_reserved_range()12749 DescriptorProto_ReservedRange* DescriptorProto::add_reserved_range() { reserved_range_.emplace_back(); return &reserved_range_.back(); }
ParseFromArray(const void * raw,size_t size)12750 bool DescriptorProto::ParseFromArray(const void* raw, size_t size) {
12751 field_.clear();
12752 extension_.clear();
12753 nested_type_.clear();
12754 enum_type_.clear();
12755 oneof_decl_.clear();
12756 reserved_range_.clear();
12757 reserved_name_.clear();
12758 unknown_fields_.clear();
12759 bool packed_error = false;
12760
12761 ::protozero::ProtoDecoder dec(raw, size);
12762 for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
12763 if (field.id() < _has_field_.size()) {
12764 _has_field_.set(field.id());
12765 }
12766 switch (field.id()) {
12767 case 1 /* name */:
12768 field.get(&name_);
12769 break;
12770 case 2 /* field */:
12771 field_.emplace_back();
12772 field_.back().ParseFromArray(field.data(), field.size());
12773 break;
12774 case 6 /* extension */:
12775 extension_.emplace_back();
12776 extension_.back().ParseFromArray(field.data(), field.size());
12777 break;
12778 case 3 /* nested_type */:
12779 nested_type_.emplace_back();
12780 nested_type_.back().ParseFromArray(field.data(), field.size());
12781 break;
12782 case 4 /* enum_type */:
12783 enum_type_.emplace_back();
12784 enum_type_.back().ParseFromArray(field.data(), field.size());
12785 break;
12786 case 8 /* oneof_decl */:
12787 oneof_decl_.emplace_back();
12788 oneof_decl_.back().ParseFromArray(field.data(), field.size());
12789 break;
12790 case 9 /* reserved_range */:
12791 reserved_range_.emplace_back();
12792 reserved_range_.back().ParseFromArray(field.data(), field.size());
12793 break;
12794 case 10 /* reserved_name */:
12795 reserved_name_.emplace_back();
12796 field.get(&reserved_name_.back());
12797 break;
12798 default:
12799 field.SerializeAndAppendTo(&unknown_fields_);
12800 break;
12801 }
12802 }
12803 return !packed_error && !dec.bytes_left();
12804 }
12805
SerializeAsString() const12806 std::string DescriptorProto::SerializeAsString() const {
12807 ::protozero::HeapBuffered<::protozero::Message> msg;
12808 Serialize(msg.get());
12809 return msg.SerializeAsString();
12810 }
12811
SerializeAsArray() const12812 std::vector<uint8_t> DescriptorProto::SerializeAsArray() const {
12813 ::protozero::HeapBuffered<::protozero::Message> msg;
12814 Serialize(msg.get());
12815 return msg.SerializeAsArray();
12816 }
12817
Serialize(::protozero::Message * msg) const12818 void DescriptorProto::Serialize(::protozero::Message* msg) const {
12819 // Field 1: name
12820 if (_has_field_[1]) {
12821 msg->AppendString(1, name_);
12822 }
12823
12824 // Field 2: field
12825 for (auto& it : field_) {
12826 it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
12827 }
12828
12829 // Field 6: extension
12830 for (auto& it : extension_) {
12831 it.Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
12832 }
12833
12834 // Field 3: nested_type
12835 for (auto& it : nested_type_) {
12836 it.Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
12837 }
12838
12839 // Field 4: enum_type
12840 for (auto& it : enum_type_) {
12841 it.Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
12842 }
12843
12844 // Field 8: oneof_decl
12845 for (auto& it : oneof_decl_) {
12846 it.Serialize(msg->BeginNestedMessage<::protozero::Message>(8));
12847 }
12848
12849 // Field 9: reserved_range
12850 for (auto& it : reserved_range_) {
12851 it.Serialize(msg->BeginNestedMessage<::protozero::Message>(9));
12852 }
12853
12854 // Field 10: reserved_name
12855 for (auto& it : reserved_name_) {
12856 msg->AppendString(10, it);
12857 }
12858
12859 msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
12860 }
12861
12862
12863 DescriptorProto_ReservedRange::DescriptorProto_ReservedRange() = default;
12864 DescriptorProto_ReservedRange::~DescriptorProto_ReservedRange() = default;
12865 DescriptorProto_ReservedRange::DescriptorProto_ReservedRange(const DescriptorProto_ReservedRange&) = default;
12866 DescriptorProto_ReservedRange& DescriptorProto_ReservedRange::operator=(const DescriptorProto_ReservedRange&) = default;
12867 DescriptorProto_ReservedRange::DescriptorProto_ReservedRange(DescriptorProto_ReservedRange&&) noexcept = default;
12868 DescriptorProto_ReservedRange& DescriptorProto_ReservedRange::operator=(DescriptorProto_ReservedRange&&) = default;
12869
operator ==(const DescriptorProto_ReservedRange & other) const12870 bool DescriptorProto_ReservedRange::operator==(const DescriptorProto_ReservedRange& other) const {
12871 return unknown_fields_ == other.unknown_fields_
12872 && start_ == other.start_
12873 && end_ == other.end_;
12874 }
12875
ParseFromArray(const void * raw,size_t size)12876 bool DescriptorProto_ReservedRange::ParseFromArray(const void* raw, size_t size) {
12877 unknown_fields_.clear();
12878 bool packed_error = false;
12879
12880 ::protozero::ProtoDecoder dec(raw, size);
12881 for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
12882 if (field.id() < _has_field_.size()) {
12883 _has_field_.set(field.id());
12884 }
12885 switch (field.id()) {
12886 case 1 /* start */:
12887 field.get(&start_);
12888 break;
12889 case 2 /* end */:
12890 field.get(&end_);
12891 break;
12892 default:
12893 field.SerializeAndAppendTo(&unknown_fields_);
12894 break;
12895 }
12896 }
12897 return !packed_error && !dec.bytes_left();
12898 }
12899
SerializeAsString() const12900 std::string DescriptorProto_ReservedRange::SerializeAsString() const {
12901 ::protozero::HeapBuffered<::protozero::Message> msg;
12902 Serialize(msg.get());
12903 return msg.SerializeAsString();
12904 }
12905
SerializeAsArray() const12906 std::vector<uint8_t> DescriptorProto_ReservedRange::SerializeAsArray() const {
12907 ::protozero::HeapBuffered<::protozero::Message> msg;
12908 Serialize(msg.get());
12909 return msg.SerializeAsArray();
12910 }
12911
Serialize(::protozero::Message * msg) const12912 void DescriptorProto_ReservedRange::Serialize(::protozero::Message* msg) const {
12913 // Field 1: start
12914 if (_has_field_[1]) {
12915 msg->AppendVarInt(1, start_);
12916 }
12917
12918 // Field 2: end
12919 if (_has_field_[2]) {
12920 msg->AppendVarInt(2, end_);
12921 }
12922
12923 msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
12924 }
12925
12926
12927 FileDescriptorProto::FileDescriptorProto() = default;
12928 FileDescriptorProto::~FileDescriptorProto() = default;
12929 FileDescriptorProto::FileDescriptorProto(const FileDescriptorProto&) = default;
12930 FileDescriptorProto& FileDescriptorProto::operator=(const FileDescriptorProto&) = default;
12931 FileDescriptorProto::FileDescriptorProto(FileDescriptorProto&&) noexcept = default;
12932 FileDescriptorProto& FileDescriptorProto::operator=(FileDescriptorProto&&) = default;
12933
operator ==(const FileDescriptorProto & other) const12934 bool FileDescriptorProto::operator==(const FileDescriptorProto& other) const {
12935 return unknown_fields_ == other.unknown_fields_
12936 && name_ == other.name_
12937 && package_ == other.package_
12938 && dependency_ == other.dependency_
12939 && public_dependency_ == other.public_dependency_
12940 && weak_dependency_ == other.weak_dependency_
12941 && message_type_ == other.message_type_
12942 && enum_type_ == other.enum_type_
12943 && extension_ == other.extension_;
12944 }
12945
message_type_size() const12946 int FileDescriptorProto::message_type_size() const { return static_cast<int>(message_type_.size()); }
clear_message_type()12947 void FileDescriptorProto::clear_message_type() { message_type_.clear(); }
add_message_type()12948 DescriptorProto* FileDescriptorProto::add_message_type() { message_type_.emplace_back(); return &message_type_.back(); }
enum_type_size() const12949 int FileDescriptorProto::enum_type_size() const { return static_cast<int>(enum_type_.size()); }
clear_enum_type()12950 void FileDescriptorProto::clear_enum_type() { enum_type_.clear(); }
add_enum_type()12951 EnumDescriptorProto* FileDescriptorProto::add_enum_type() { enum_type_.emplace_back(); return &enum_type_.back(); }
extension_size() const12952 int FileDescriptorProto::extension_size() const { return static_cast<int>(extension_.size()); }
clear_extension()12953 void FileDescriptorProto::clear_extension() { extension_.clear(); }
add_extension()12954 FieldDescriptorProto* FileDescriptorProto::add_extension() { extension_.emplace_back(); return &extension_.back(); }
ParseFromArray(const void * raw,size_t size)12955 bool FileDescriptorProto::ParseFromArray(const void* raw, size_t size) {
12956 dependency_.clear();
12957 public_dependency_.clear();
12958 weak_dependency_.clear();
12959 message_type_.clear();
12960 enum_type_.clear();
12961 extension_.clear();
12962 unknown_fields_.clear();
12963 bool packed_error = false;
12964
12965 ::protozero::ProtoDecoder dec(raw, size);
12966 for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
12967 if (field.id() < _has_field_.size()) {
12968 _has_field_.set(field.id());
12969 }
12970 switch (field.id()) {
12971 case 1 /* name */:
12972 field.get(&name_);
12973 break;
12974 case 2 /* package */:
12975 field.get(&package_);
12976 break;
12977 case 3 /* dependency */:
12978 dependency_.emplace_back();
12979 field.get(&dependency_.back());
12980 break;
12981 case 10 /* public_dependency */:
12982 public_dependency_.emplace_back();
12983 field.get(&public_dependency_.back());
12984 break;
12985 case 11 /* weak_dependency */:
12986 weak_dependency_.emplace_back();
12987 field.get(&weak_dependency_.back());
12988 break;
12989 case 4 /* message_type */:
12990 message_type_.emplace_back();
12991 message_type_.back().ParseFromArray(field.data(), field.size());
12992 break;
12993 case 5 /* enum_type */:
12994 enum_type_.emplace_back();
12995 enum_type_.back().ParseFromArray(field.data(), field.size());
12996 break;
12997 case 7 /* extension */:
12998 extension_.emplace_back();
12999 extension_.back().ParseFromArray(field.data(), field.size());
13000 break;
13001 default:
13002 field.SerializeAndAppendTo(&unknown_fields_);
13003 break;
13004 }
13005 }
13006 return !packed_error && !dec.bytes_left();
13007 }
13008
SerializeAsString() const13009 std::string FileDescriptorProto::SerializeAsString() const {
13010 ::protozero::HeapBuffered<::protozero::Message> msg;
13011 Serialize(msg.get());
13012 return msg.SerializeAsString();
13013 }
13014
SerializeAsArray() const13015 std::vector<uint8_t> FileDescriptorProto::SerializeAsArray() const {
13016 ::protozero::HeapBuffered<::protozero::Message> msg;
13017 Serialize(msg.get());
13018 return msg.SerializeAsArray();
13019 }
13020
Serialize(::protozero::Message * msg) const13021 void FileDescriptorProto::Serialize(::protozero::Message* msg) const {
13022 // Field 1: name
13023 if (_has_field_[1]) {
13024 msg->AppendString(1, name_);
13025 }
13026
13027 // Field 2: package
13028 if (_has_field_[2]) {
13029 msg->AppendString(2, package_);
13030 }
13031
13032 // Field 3: dependency
13033 for (auto& it : dependency_) {
13034 msg->AppendString(3, it);
13035 }
13036
13037 // Field 10: public_dependency
13038 for (auto& it : public_dependency_) {
13039 msg->AppendVarInt(10, it);
13040 }
13041
13042 // Field 11: weak_dependency
13043 for (auto& it : weak_dependency_) {
13044 msg->AppendVarInt(11, it);
13045 }
13046
13047 // Field 4: message_type
13048 for (auto& it : message_type_) {
13049 it.Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
13050 }
13051
13052 // Field 5: enum_type
13053 for (auto& it : enum_type_) {
13054 it.Serialize(msg->BeginNestedMessage<::protozero::Message>(5));
13055 }
13056
13057 // Field 7: extension
13058 for (auto& it : extension_) {
13059 it.Serialize(msg->BeginNestedMessage<::protozero::Message>(7));
13060 }
13061
13062 msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
13063 }
13064
13065
13066 FileDescriptorSet::FileDescriptorSet() = default;
13067 FileDescriptorSet::~FileDescriptorSet() = default;
13068 FileDescriptorSet::FileDescriptorSet(const FileDescriptorSet&) = default;
13069 FileDescriptorSet& FileDescriptorSet::operator=(const FileDescriptorSet&) = default;
13070 FileDescriptorSet::FileDescriptorSet(FileDescriptorSet&&) noexcept = default;
13071 FileDescriptorSet& FileDescriptorSet::operator=(FileDescriptorSet&&) = default;
13072
operator ==(const FileDescriptorSet & other) const13073 bool FileDescriptorSet::operator==(const FileDescriptorSet& other) const {
13074 return unknown_fields_ == other.unknown_fields_
13075 && file_ == other.file_;
13076 }
13077
file_size() const13078 int FileDescriptorSet::file_size() const { return static_cast<int>(file_.size()); }
clear_file()13079 void FileDescriptorSet::clear_file() { file_.clear(); }
add_file()13080 FileDescriptorProto* FileDescriptorSet::add_file() { file_.emplace_back(); return &file_.back(); }
ParseFromArray(const void * raw,size_t size)13081 bool FileDescriptorSet::ParseFromArray(const void* raw, size_t size) {
13082 file_.clear();
13083 unknown_fields_.clear();
13084 bool packed_error = false;
13085
13086 ::protozero::ProtoDecoder dec(raw, size);
13087 for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
13088 if (field.id() < _has_field_.size()) {
13089 _has_field_.set(field.id());
13090 }
13091 switch (field.id()) {
13092 case 1 /* file */:
13093 file_.emplace_back();
13094 file_.back().ParseFromArray(field.data(), field.size());
13095 break;
13096 default:
13097 field.SerializeAndAppendTo(&unknown_fields_);
13098 break;
13099 }
13100 }
13101 return !packed_error && !dec.bytes_left();
13102 }
13103
SerializeAsString() const13104 std::string FileDescriptorSet::SerializeAsString() const {
13105 ::protozero::HeapBuffered<::protozero::Message> msg;
13106 Serialize(msg.get());
13107 return msg.SerializeAsString();
13108 }
13109
SerializeAsArray() const13110 std::vector<uint8_t> FileDescriptorSet::SerializeAsArray() const {
13111 ::protozero::HeapBuffered<::protozero::Message> msg;
13112 Serialize(msg.get());
13113 return msg.SerializeAsArray();
13114 }
13115
Serialize(::protozero::Message * msg) const13116 void FileDescriptorSet::Serialize(::protozero::Message* msg) const {
13117 // Field 1: file
13118 for (auto& it : file_) {
13119 it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
13120 }
13121
13122 msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
13123 }
13124
13125 } // namespace perfetto
13126 } // namespace protos
13127 } // namespace gen
13128 #if defined(__GNUC__) || defined(__clang__)
13129 #pragma GCC diagnostic pop
13130 #endif
13131 // gen_amalgamated begin source: gen/protos/perfetto/common/gpu_counter_descriptor.gen.cc
13132 // gen_amalgamated begin header: gen/protos/perfetto/common/gpu_counter_descriptor.gen.h
13133 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
13134 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_GPU_COUNTER_DESCRIPTOR_PROTO_CPP_H_
13135 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_GPU_COUNTER_DESCRIPTOR_PROTO_CPP_H_
13136
13137 #include <stdint.h>
13138 #include <bitset>
13139 #include <vector>
13140 #include <string>
13141 #include <type_traits>
13142
13143 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
13144 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
13145 // gen_amalgamated expanded: #include "perfetto/base/export.h"
13146
13147 namespace perfetto {
13148 namespace protos {
13149 namespace gen {
13150 class GpuCounterDescriptor;
13151 class GpuCounterDescriptor_GpuCounterBlock;
13152 class GpuCounterDescriptor_GpuCounterSpec;
13153 enum GpuCounterDescriptor_GpuCounterGroup : int;
13154 enum GpuCounterDescriptor_MeasureUnit : int;
13155 } // namespace perfetto
13156 } // namespace protos
13157 } // namespace gen
13158
13159 namespace protozero {
13160 class Message;
13161 } // namespace protozero
13162
13163 namespace perfetto {
13164 namespace protos {
13165 namespace gen {
13166 enum GpuCounterDescriptor_GpuCounterGroup : int {
13167 GpuCounterDescriptor_GpuCounterGroup_UNCLASSIFIED = 0,
13168 GpuCounterDescriptor_GpuCounterGroup_SYSTEM = 1,
13169 GpuCounterDescriptor_GpuCounterGroup_VERTICES = 2,
13170 GpuCounterDescriptor_GpuCounterGroup_FRAGMENTS = 3,
13171 GpuCounterDescriptor_GpuCounterGroup_PRIMITIVES = 4,
13172 GpuCounterDescriptor_GpuCounterGroup_MEMORY = 5,
13173 GpuCounterDescriptor_GpuCounterGroup_COMPUTE = 6,
13174 };
13175 enum GpuCounterDescriptor_MeasureUnit : int {
13176 GpuCounterDescriptor_MeasureUnit_NONE = 0,
13177 GpuCounterDescriptor_MeasureUnit_BIT = 1,
13178 GpuCounterDescriptor_MeasureUnit_KILOBIT = 2,
13179 GpuCounterDescriptor_MeasureUnit_MEGABIT = 3,
13180 GpuCounterDescriptor_MeasureUnit_GIGABIT = 4,
13181 GpuCounterDescriptor_MeasureUnit_TERABIT = 5,
13182 GpuCounterDescriptor_MeasureUnit_PETABIT = 6,
13183 GpuCounterDescriptor_MeasureUnit_BYTE = 7,
13184 GpuCounterDescriptor_MeasureUnit_KILOBYTE = 8,
13185 GpuCounterDescriptor_MeasureUnit_MEGABYTE = 9,
13186 GpuCounterDescriptor_MeasureUnit_GIGABYTE = 10,
13187 GpuCounterDescriptor_MeasureUnit_TERABYTE = 11,
13188 GpuCounterDescriptor_MeasureUnit_PETABYTE = 12,
13189 GpuCounterDescriptor_MeasureUnit_HERTZ = 13,
13190 GpuCounterDescriptor_MeasureUnit_KILOHERTZ = 14,
13191 GpuCounterDescriptor_MeasureUnit_MEGAHERTZ = 15,
13192 GpuCounterDescriptor_MeasureUnit_GIGAHERTZ = 16,
13193 GpuCounterDescriptor_MeasureUnit_TERAHERTZ = 17,
13194 GpuCounterDescriptor_MeasureUnit_PETAHERTZ = 18,
13195 GpuCounterDescriptor_MeasureUnit_NANOSECOND = 19,
13196 GpuCounterDescriptor_MeasureUnit_MICROSECOND = 20,
13197 GpuCounterDescriptor_MeasureUnit_MILLISECOND = 21,
13198 GpuCounterDescriptor_MeasureUnit_SECOND = 22,
13199 GpuCounterDescriptor_MeasureUnit_MINUTE = 23,
13200 GpuCounterDescriptor_MeasureUnit_HOUR = 24,
13201 GpuCounterDescriptor_MeasureUnit_VERTEX = 25,
13202 GpuCounterDescriptor_MeasureUnit_PIXEL = 26,
13203 GpuCounterDescriptor_MeasureUnit_TRIANGLE = 27,
13204 GpuCounterDescriptor_MeasureUnit_PRIMITIVE = 38,
13205 GpuCounterDescriptor_MeasureUnit_FRAGMENT = 39,
13206 GpuCounterDescriptor_MeasureUnit_MILLIWATT = 28,
13207 GpuCounterDescriptor_MeasureUnit_WATT = 29,
13208 GpuCounterDescriptor_MeasureUnit_KILOWATT = 30,
13209 GpuCounterDescriptor_MeasureUnit_JOULE = 31,
13210 GpuCounterDescriptor_MeasureUnit_VOLT = 32,
13211 GpuCounterDescriptor_MeasureUnit_AMPERE = 33,
13212 GpuCounterDescriptor_MeasureUnit_CELSIUS = 34,
13213 GpuCounterDescriptor_MeasureUnit_FAHRENHEIT = 35,
13214 GpuCounterDescriptor_MeasureUnit_KELVIN = 36,
13215 GpuCounterDescriptor_MeasureUnit_PERCENT = 37,
13216 GpuCounterDescriptor_MeasureUnit_INSTRUCTION = 40,
13217 };
13218
13219 class PERFETTO_EXPORT GpuCounterDescriptor : public ::protozero::CppMessageObj {
13220 public:
13221 using GpuCounterSpec = GpuCounterDescriptor_GpuCounterSpec;
13222 using GpuCounterBlock = GpuCounterDescriptor_GpuCounterBlock;
13223 using GpuCounterGroup = GpuCounterDescriptor_GpuCounterGroup;
13224 static constexpr auto UNCLASSIFIED = GpuCounterDescriptor_GpuCounterGroup_UNCLASSIFIED;
13225 static constexpr auto SYSTEM = GpuCounterDescriptor_GpuCounterGroup_SYSTEM;
13226 static constexpr auto VERTICES = GpuCounterDescriptor_GpuCounterGroup_VERTICES;
13227 static constexpr auto FRAGMENTS = GpuCounterDescriptor_GpuCounterGroup_FRAGMENTS;
13228 static constexpr auto PRIMITIVES = GpuCounterDescriptor_GpuCounterGroup_PRIMITIVES;
13229 static constexpr auto MEMORY = GpuCounterDescriptor_GpuCounterGroup_MEMORY;
13230 static constexpr auto COMPUTE = GpuCounterDescriptor_GpuCounterGroup_COMPUTE;
13231 static constexpr auto GpuCounterGroup_MIN = GpuCounterDescriptor_GpuCounterGroup_UNCLASSIFIED;
13232 static constexpr auto GpuCounterGroup_MAX = GpuCounterDescriptor_GpuCounterGroup_COMPUTE;
13233 using MeasureUnit = GpuCounterDescriptor_MeasureUnit;
13234 static constexpr auto NONE = GpuCounterDescriptor_MeasureUnit_NONE;
13235 static constexpr auto BIT = GpuCounterDescriptor_MeasureUnit_BIT;
13236 static constexpr auto KILOBIT = GpuCounterDescriptor_MeasureUnit_KILOBIT;
13237 static constexpr auto MEGABIT = GpuCounterDescriptor_MeasureUnit_MEGABIT;
13238 static constexpr auto GIGABIT = GpuCounterDescriptor_MeasureUnit_GIGABIT;
13239 static constexpr auto TERABIT = GpuCounterDescriptor_MeasureUnit_TERABIT;
13240 static constexpr auto PETABIT = GpuCounterDescriptor_MeasureUnit_PETABIT;
13241 static constexpr auto BYTE = GpuCounterDescriptor_MeasureUnit_BYTE;
13242 static constexpr auto KILOBYTE = GpuCounterDescriptor_MeasureUnit_KILOBYTE;
13243 static constexpr auto MEGABYTE = GpuCounterDescriptor_MeasureUnit_MEGABYTE;
13244 static constexpr auto GIGABYTE = GpuCounterDescriptor_MeasureUnit_GIGABYTE;
13245 static constexpr auto TERABYTE = GpuCounterDescriptor_MeasureUnit_TERABYTE;
13246 static constexpr auto PETABYTE = GpuCounterDescriptor_MeasureUnit_PETABYTE;
13247 static constexpr auto HERTZ = GpuCounterDescriptor_MeasureUnit_HERTZ;
13248 static constexpr auto KILOHERTZ = GpuCounterDescriptor_MeasureUnit_KILOHERTZ;
13249 static constexpr auto MEGAHERTZ = GpuCounterDescriptor_MeasureUnit_MEGAHERTZ;
13250 static constexpr auto GIGAHERTZ = GpuCounterDescriptor_MeasureUnit_GIGAHERTZ;
13251 static constexpr auto TERAHERTZ = GpuCounterDescriptor_MeasureUnit_TERAHERTZ;
13252 static constexpr auto PETAHERTZ = GpuCounterDescriptor_MeasureUnit_PETAHERTZ;
13253 static constexpr auto NANOSECOND = GpuCounterDescriptor_MeasureUnit_NANOSECOND;
13254 static constexpr auto MICROSECOND = GpuCounterDescriptor_MeasureUnit_MICROSECOND;
13255 static constexpr auto MILLISECOND = GpuCounterDescriptor_MeasureUnit_MILLISECOND;
13256 static constexpr auto SECOND = GpuCounterDescriptor_MeasureUnit_SECOND;
13257 static constexpr auto MINUTE = GpuCounterDescriptor_MeasureUnit_MINUTE;
13258 static constexpr auto HOUR = GpuCounterDescriptor_MeasureUnit_HOUR;
13259 static constexpr auto VERTEX = GpuCounterDescriptor_MeasureUnit_VERTEX;
13260 static constexpr auto PIXEL = GpuCounterDescriptor_MeasureUnit_PIXEL;
13261 static constexpr auto TRIANGLE = GpuCounterDescriptor_MeasureUnit_TRIANGLE;
13262 static constexpr auto PRIMITIVE = GpuCounterDescriptor_MeasureUnit_PRIMITIVE;
13263 static constexpr auto FRAGMENT = GpuCounterDescriptor_MeasureUnit_FRAGMENT;
13264 static constexpr auto MILLIWATT = GpuCounterDescriptor_MeasureUnit_MILLIWATT;
13265 static constexpr auto WATT = GpuCounterDescriptor_MeasureUnit_WATT;
13266 static constexpr auto KILOWATT = GpuCounterDescriptor_MeasureUnit_KILOWATT;
13267 static constexpr auto JOULE = GpuCounterDescriptor_MeasureUnit_JOULE;
13268 static constexpr auto VOLT = GpuCounterDescriptor_MeasureUnit_VOLT;
13269 static constexpr auto AMPERE = GpuCounterDescriptor_MeasureUnit_AMPERE;
13270 static constexpr auto CELSIUS = GpuCounterDescriptor_MeasureUnit_CELSIUS;
13271 static constexpr auto FAHRENHEIT = GpuCounterDescriptor_MeasureUnit_FAHRENHEIT;
13272 static constexpr auto KELVIN = GpuCounterDescriptor_MeasureUnit_KELVIN;
13273 static constexpr auto PERCENT = GpuCounterDescriptor_MeasureUnit_PERCENT;
13274 static constexpr auto INSTRUCTION = GpuCounterDescriptor_MeasureUnit_INSTRUCTION;
13275 static constexpr auto MeasureUnit_MIN = GpuCounterDescriptor_MeasureUnit_NONE;
13276 static constexpr auto MeasureUnit_MAX = GpuCounterDescriptor_MeasureUnit_INSTRUCTION;
13277 enum FieldNumbers {
13278 kSpecsFieldNumber = 1,
13279 kBlocksFieldNumber = 2,
13280 kMinSamplingPeriodNsFieldNumber = 3,
13281 kMaxSamplingPeriodNsFieldNumber = 4,
13282 kSupportsInstrumentedSamplingFieldNumber = 5,
13283 };
13284
13285 GpuCounterDescriptor();
13286 ~GpuCounterDescriptor() override;
13287 GpuCounterDescriptor(GpuCounterDescriptor&&) noexcept;
13288 GpuCounterDescriptor& operator=(GpuCounterDescriptor&&);
13289 GpuCounterDescriptor(const GpuCounterDescriptor&);
13290 GpuCounterDescriptor& operator=(const GpuCounterDescriptor&);
13291 bool operator==(const GpuCounterDescriptor&) const;
operator !=(const GpuCounterDescriptor & other) const13292 bool operator!=(const GpuCounterDescriptor& other) const { return !(*this == other); }
13293
13294 bool ParseFromArray(const void*, size_t) override;
13295 std::string SerializeAsString() const override;
13296 std::vector<uint8_t> SerializeAsArray() const override;
13297 void Serialize(::protozero::Message*) const;
13298
specs() const13299 const std::vector<GpuCounterDescriptor_GpuCounterSpec>& specs() const { return specs_; }
mutable_specs()13300 std::vector<GpuCounterDescriptor_GpuCounterSpec>* mutable_specs() { return &specs_; }
13301 int specs_size() const;
13302 void clear_specs();
13303 GpuCounterDescriptor_GpuCounterSpec* add_specs();
13304
blocks() const13305 const std::vector<GpuCounterDescriptor_GpuCounterBlock>& blocks() const { return blocks_; }
mutable_blocks()13306 std::vector<GpuCounterDescriptor_GpuCounterBlock>* mutable_blocks() { return &blocks_; }
13307 int blocks_size() const;
13308 void clear_blocks();
13309 GpuCounterDescriptor_GpuCounterBlock* add_blocks();
13310
has_min_sampling_period_ns() const13311 bool has_min_sampling_period_ns() const { return _has_field_[3]; }
min_sampling_period_ns() const13312 uint64_t min_sampling_period_ns() const { return min_sampling_period_ns_; }
set_min_sampling_period_ns(uint64_t value)13313 void set_min_sampling_period_ns(uint64_t value) { min_sampling_period_ns_ = value; _has_field_.set(3); }
13314
has_max_sampling_period_ns() const13315 bool has_max_sampling_period_ns() const { return _has_field_[4]; }
max_sampling_period_ns() const13316 uint64_t max_sampling_period_ns() const { return max_sampling_period_ns_; }
set_max_sampling_period_ns(uint64_t value)13317 void set_max_sampling_period_ns(uint64_t value) { max_sampling_period_ns_ = value; _has_field_.set(4); }
13318
has_supports_instrumented_sampling() const13319 bool has_supports_instrumented_sampling() const { return _has_field_[5]; }
supports_instrumented_sampling() const13320 bool supports_instrumented_sampling() const { return supports_instrumented_sampling_; }
set_supports_instrumented_sampling(bool value)13321 void set_supports_instrumented_sampling(bool value) { supports_instrumented_sampling_ = value; _has_field_.set(5); }
13322
13323 private:
13324 std::vector<GpuCounterDescriptor_GpuCounterSpec> specs_;
13325 std::vector<GpuCounterDescriptor_GpuCounterBlock> blocks_;
13326 uint64_t min_sampling_period_ns_{};
13327 uint64_t max_sampling_period_ns_{};
13328 bool supports_instrumented_sampling_{};
13329
13330 // Allows to preserve unknown protobuf fields for compatibility
13331 // with future versions of .proto files.
13332 std::string unknown_fields_;
13333
13334 std::bitset<6> _has_field_{};
13335 };
13336
13337
13338 class PERFETTO_EXPORT GpuCounterDescriptor_GpuCounterBlock : public ::protozero::CppMessageObj {
13339 public:
13340 enum FieldNumbers {
13341 kBlockIdFieldNumber = 1,
13342 kBlockCapacityFieldNumber = 2,
13343 kNameFieldNumber = 3,
13344 kDescriptionFieldNumber = 4,
13345 kCounterIdsFieldNumber = 5,
13346 };
13347
13348 GpuCounterDescriptor_GpuCounterBlock();
13349 ~GpuCounterDescriptor_GpuCounterBlock() override;
13350 GpuCounterDescriptor_GpuCounterBlock(GpuCounterDescriptor_GpuCounterBlock&&) noexcept;
13351 GpuCounterDescriptor_GpuCounterBlock& operator=(GpuCounterDescriptor_GpuCounterBlock&&);
13352 GpuCounterDescriptor_GpuCounterBlock(const GpuCounterDescriptor_GpuCounterBlock&);
13353 GpuCounterDescriptor_GpuCounterBlock& operator=(const GpuCounterDescriptor_GpuCounterBlock&);
13354 bool operator==(const GpuCounterDescriptor_GpuCounterBlock&) const;
operator !=(const GpuCounterDescriptor_GpuCounterBlock & other) const13355 bool operator!=(const GpuCounterDescriptor_GpuCounterBlock& other) const { return !(*this == other); }
13356
13357 bool ParseFromArray(const void*, size_t) override;
13358 std::string SerializeAsString() const override;
13359 std::vector<uint8_t> SerializeAsArray() const override;
13360 void Serialize(::protozero::Message*) const;
13361
has_block_id() const13362 bool has_block_id() const { return _has_field_[1]; }
block_id() const13363 uint32_t block_id() const { return block_id_; }
set_block_id(uint32_t value)13364 void set_block_id(uint32_t value) { block_id_ = value; _has_field_.set(1); }
13365
has_block_capacity() const13366 bool has_block_capacity() const { return _has_field_[2]; }
block_capacity() const13367 uint32_t block_capacity() const { return block_capacity_; }
set_block_capacity(uint32_t value)13368 void set_block_capacity(uint32_t value) { block_capacity_ = value; _has_field_.set(2); }
13369
has_name() const13370 bool has_name() const { return _has_field_[3]; }
name() const13371 const std::string& name() const { return name_; }
set_name(const std::string & value)13372 void set_name(const std::string& value) { name_ = value; _has_field_.set(3); }
13373
has_description() const13374 bool has_description() const { return _has_field_[4]; }
description() const13375 const std::string& description() const { return description_; }
set_description(const std::string & value)13376 void set_description(const std::string& value) { description_ = value; _has_field_.set(4); }
13377
counter_ids() const13378 const std::vector<uint32_t>& counter_ids() const { return counter_ids_; }
mutable_counter_ids()13379 std::vector<uint32_t>* mutable_counter_ids() { return &counter_ids_; }
counter_ids_size() const13380 int counter_ids_size() const { return static_cast<int>(counter_ids_.size()); }
clear_counter_ids()13381 void clear_counter_ids() { counter_ids_.clear(); }
add_counter_ids(uint32_t value)13382 void add_counter_ids(uint32_t value) { counter_ids_.emplace_back(value); }
add_counter_ids()13383 uint32_t* add_counter_ids() { counter_ids_.emplace_back(); return &counter_ids_.back(); }
13384
13385 private:
13386 uint32_t block_id_{};
13387 uint32_t block_capacity_{};
13388 std::string name_{};
13389 std::string description_{};
13390 std::vector<uint32_t> counter_ids_;
13391
13392 // Allows to preserve unknown protobuf fields for compatibility
13393 // with future versions of .proto files.
13394 std::string unknown_fields_;
13395
13396 std::bitset<6> _has_field_{};
13397 };
13398
13399
13400 class PERFETTO_EXPORT GpuCounterDescriptor_GpuCounterSpec : public ::protozero::CppMessageObj {
13401 public:
13402 enum FieldNumbers {
13403 kCounterIdFieldNumber = 1,
13404 kNameFieldNumber = 2,
13405 kDescriptionFieldNumber = 3,
13406 kIntPeakValueFieldNumber = 5,
13407 kDoublePeakValueFieldNumber = 6,
13408 kNumeratorUnitsFieldNumber = 7,
13409 kDenominatorUnitsFieldNumber = 8,
13410 kSelectByDefaultFieldNumber = 9,
13411 kGroupsFieldNumber = 10,
13412 };
13413
13414 GpuCounterDescriptor_GpuCounterSpec();
13415 ~GpuCounterDescriptor_GpuCounterSpec() override;
13416 GpuCounterDescriptor_GpuCounterSpec(GpuCounterDescriptor_GpuCounterSpec&&) noexcept;
13417 GpuCounterDescriptor_GpuCounterSpec& operator=(GpuCounterDescriptor_GpuCounterSpec&&);
13418 GpuCounterDescriptor_GpuCounterSpec(const GpuCounterDescriptor_GpuCounterSpec&);
13419 GpuCounterDescriptor_GpuCounterSpec& operator=(const GpuCounterDescriptor_GpuCounterSpec&);
13420 bool operator==(const GpuCounterDescriptor_GpuCounterSpec&) const;
operator !=(const GpuCounterDescriptor_GpuCounterSpec & other) const13421 bool operator!=(const GpuCounterDescriptor_GpuCounterSpec& other) const { return !(*this == other); }
13422
13423 bool ParseFromArray(const void*, size_t) override;
13424 std::string SerializeAsString() const override;
13425 std::vector<uint8_t> SerializeAsArray() const override;
13426 void Serialize(::protozero::Message*) const;
13427
has_counter_id() const13428 bool has_counter_id() const { return _has_field_[1]; }
counter_id() const13429 uint32_t counter_id() const { return counter_id_; }
set_counter_id(uint32_t value)13430 void set_counter_id(uint32_t value) { counter_id_ = value; _has_field_.set(1); }
13431
has_name() const13432 bool has_name() const { return _has_field_[2]; }
name() const13433 const std::string& name() const { return name_; }
set_name(const std::string & value)13434 void set_name(const std::string& value) { name_ = value; _has_field_.set(2); }
13435
has_description() const13436 bool has_description() const { return _has_field_[3]; }
description() const13437 const std::string& description() const { return description_; }
set_description(const std::string & value)13438 void set_description(const std::string& value) { description_ = value; _has_field_.set(3); }
13439
has_int_peak_value() const13440 bool has_int_peak_value() const { return _has_field_[5]; }
int_peak_value() const13441 int64_t int_peak_value() const { return int_peak_value_; }
set_int_peak_value(int64_t value)13442 void set_int_peak_value(int64_t value) { int_peak_value_ = value; _has_field_.set(5); }
13443
has_double_peak_value() const13444 bool has_double_peak_value() const { return _has_field_[6]; }
double_peak_value() const13445 double double_peak_value() const { return double_peak_value_; }
set_double_peak_value(double value)13446 void set_double_peak_value(double value) { double_peak_value_ = value; _has_field_.set(6); }
13447
numerator_units() const13448 const std::vector<GpuCounterDescriptor_MeasureUnit>& numerator_units() const { return numerator_units_; }
mutable_numerator_units()13449 std::vector<GpuCounterDescriptor_MeasureUnit>* mutable_numerator_units() { return &numerator_units_; }
numerator_units_size() const13450 int numerator_units_size() const { return static_cast<int>(numerator_units_.size()); }
clear_numerator_units()13451 void clear_numerator_units() { numerator_units_.clear(); }
add_numerator_units(GpuCounterDescriptor_MeasureUnit value)13452 void add_numerator_units(GpuCounterDescriptor_MeasureUnit value) { numerator_units_.emplace_back(value); }
add_numerator_units()13453 GpuCounterDescriptor_MeasureUnit* add_numerator_units() { numerator_units_.emplace_back(); return &numerator_units_.back(); }
13454
denominator_units() const13455 const std::vector<GpuCounterDescriptor_MeasureUnit>& denominator_units() const { return denominator_units_; }
mutable_denominator_units()13456 std::vector<GpuCounterDescriptor_MeasureUnit>* mutable_denominator_units() { return &denominator_units_; }
denominator_units_size() const13457 int denominator_units_size() const { return static_cast<int>(denominator_units_.size()); }
clear_denominator_units()13458 void clear_denominator_units() { denominator_units_.clear(); }
add_denominator_units(GpuCounterDescriptor_MeasureUnit value)13459 void add_denominator_units(GpuCounterDescriptor_MeasureUnit value) { denominator_units_.emplace_back(value); }
add_denominator_units()13460 GpuCounterDescriptor_MeasureUnit* add_denominator_units() { denominator_units_.emplace_back(); return &denominator_units_.back(); }
13461
has_select_by_default() const13462 bool has_select_by_default() const { return _has_field_[9]; }
select_by_default() const13463 bool select_by_default() const { return select_by_default_; }
set_select_by_default(bool value)13464 void set_select_by_default(bool value) { select_by_default_ = value; _has_field_.set(9); }
13465
groups() const13466 const std::vector<GpuCounterDescriptor_GpuCounterGroup>& groups() const { return groups_; }
mutable_groups()13467 std::vector<GpuCounterDescriptor_GpuCounterGroup>* mutable_groups() { return &groups_; }
groups_size() const13468 int groups_size() const { return static_cast<int>(groups_.size()); }
clear_groups()13469 void clear_groups() { groups_.clear(); }
add_groups(GpuCounterDescriptor_GpuCounterGroup value)13470 void add_groups(GpuCounterDescriptor_GpuCounterGroup value) { groups_.emplace_back(value); }
add_groups()13471 GpuCounterDescriptor_GpuCounterGroup* add_groups() { groups_.emplace_back(); return &groups_.back(); }
13472
13473 private:
13474 uint32_t counter_id_{};
13475 std::string name_{};
13476 std::string description_{};
13477 int64_t int_peak_value_{};
13478 double double_peak_value_{};
13479 std::vector<GpuCounterDescriptor_MeasureUnit> numerator_units_;
13480 std::vector<GpuCounterDescriptor_MeasureUnit> denominator_units_;
13481 bool select_by_default_{};
13482 std::vector<GpuCounterDescriptor_GpuCounterGroup> groups_;
13483
13484 // Allows to preserve unknown protobuf fields for compatibility
13485 // with future versions of .proto files.
13486 std::string unknown_fields_;
13487
13488 std::bitset<11> _has_field_{};
13489 };
13490
13491 } // namespace perfetto
13492 } // namespace protos
13493 } // namespace gen
13494
13495 #endif // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_GPU_COUNTER_DESCRIPTOR_PROTO_CPP_H_
13496 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
13497 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
13498 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
13499 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
13500 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
13501 #if defined(__GNUC__) || defined(__clang__)
13502 #pragma GCC diagnostic push
13503 #pragma GCC diagnostic ignored "-Wfloat-equal"
13504 #endif
13505 // gen_amalgamated expanded: #include "protos/perfetto/common/gpu_counter_descriptor.gen.h"
13506
13507 namespace perfetto {
13508 namespace protos {
13509 namespace gen {
13510
13511 GpuCounterDescriptor::GpuCounterDescriptor() = default;
13512 GpuCounterDescriptor::~GpuCounterDescriptor() = default;
13513 GpuCounterDescriptor::GpuCounterDescriptor(const GpuCounterDescriptor&) = default;
13514 GpuCounterDescriptor& GpuCounterDescriptor::operator=(const GpuCounterDescriptor&) = default;
13515 GpuCounterDescriptor::GpuCounterDescriptor(GpuCounterDescriptor&&) noexcept = default;
13516 GpuCounterDescriptor& GpuCounterDescriptor::operator=(GpuCounterDescriptor&&) = default;
13517
operator ==(const GpuCounterDescriptor & other) const13518 bool GpuCounterDescriptor::operator==(const GpuCounterDescriptor& other) const {
13519 return unknown_fields_ == other.unknown_fields_
13520 && specs_ == other.specs_
13521 && blocks_ == other.blocks_
13522 && min_sampling_period_ns_ == other.min_sampling_period_ns_
13523 && max_sampling_period_ns_ == other.max_sampling_period_ns_
13524 && supports_instrumented_sampling_ == other.supports_instrumented_sampling_;
13525 }
13526
specs_size() const13527 int GpuCounterDescriptor::specs_size() const { return static_cast<int>(specs_.size()); }
clear_specs()13528 void GpuCounterDescriptor::clear_specs() { specs_.clear(); }
add_specs()13529 GpuCounterDescriptor_GpuCounterSpec* GpuCounterDescriptor::add_specs() { specs_.emplace_back(); return &specs_.back(); }
blocks_size() const13530 int GpuCounterDescriptor::blocks_size() const { return static_cast<int>(blocks_.size()); }
clear_blocks()13531 void GpuCounterDescriptor::clear_blocks() { blocks_.clear(); }
add_blocks()13532 GpuCounterDescriptor_GpuCounterBlock* GpuCounterDescriptor::add_blocks() { blocks_.emplace_back(); return &blocks_.back(); }
ParseFromArray(const void * raw,size_t size)13533 bool GpuCounterDescriptor::ParseFromArray(const void* raw, size_t size) {
13534 specs_.clear();
13535 blocks_.clear();
13536 unknown_fields_.clear();
13537 bool packed_error = false;
13538
13539 ::protozero::ProtoDecoder dec(raw, size);
13540 for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
13541 if (field.id() < _has_field_.size()) {
13542 _has_field_.set(field.id());
13543 }
13544 switch (field.id()) {
13545 case 1 /* specs */:
13546 specs_.emplace_back();
13547 specs_.back().ParseFromArray(field.data(), field.size());
13548 break;
13549 case 2 /* blocks */:
13550 blocks_.emplace_back();
13551 blocks_.back().ParseFromArray(field.data(), field.size());
13552 break;
13553 case 3 /* min_sampling_period_ns */:
13554 field.get(&min_sampling_period_ns_);
13555 break;
13556 case 4 /* max_sampling_period_ns */:
13557 field.get(&max_sampling_period_ns_);
13558 break;
13559 case 5 /* supports_instrumented_sampling */:
13560 field.get(&supports_instrumented_sampling_);
13561 break;
13562 default:
13563 field.SerializeAndAppendTo(&unknown_fields_);
13564 break;
13565 }
13566 }
13567 return !packed_error && !dec.bytes_left();
13568 }
13569
SerializeAsString() const13570 std::string GpuCounterDescriptor::SerializeAsString() const {
13571 ::protozero::HeapBuffered<::protozero::Message> msg;
13572 Serialize(msg.get());
13573 return msg.SerializeAsString();
13574 }
13575
SerializeAsArray() const13576 std::vector<uint8_t> GpuCounterDescriptor::SerializeAsArray() const {
13577 ::protozero::HeapBuffered<::protozero::Message> msg;
13578 Serialize(msg.get());
13579 return msg.SerializeAsArray();
13580 }
13581
Serialize(::protozero::Message * msg) const13582 void GpuCounterDescriptor::Serialize(::protozero::Message* msg) const {
13583 // Field 1: specs
13584 for (auto& it : specs_) {
13585 it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
13586 }
13587
13588 // Field 2: blocks
13589 for (auto& it : blocks_) {
13590 it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
13591 }
13592
13593 // Field 3: min_sampling_period_ns
13594 if (_has_field_[3]) {
13595 msg->AppendVarInt(3, min_sampling_period_ns_);
13596 }
13597
13598 // Field 4: max_sampling_period_ns
13599 if (_has_field_[4]) {
13600 msg->AppendVarInt(4, max_sampling_period_ns_);
13601 }
13602
13603 // Field 5: supports_instrumented_sampling
13604 if (_has_field_[5]) {
13605 msg->AppendTinyVarInt(5, supports_instrumented_sampling_);
13606 }
13607
13608 msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
13609 }
13610
13611
13612 GpuCounterDescriptor_GpuCounterBlock::GpuCounterDescriptor_GpuCounterBlock() = default;
13613 GpuCounterDescriptor_GpuCounterBlock::~GpuCounterDescriptor_GpuCounterBlock() = default;
13614 GpuCounterDescriptor_GpuCounterBlock::GpuCounterDescriptor_GpuCounterBlock(const GpuCounterDescriptor_GpuCounterBlock&) = default;
13615 GpuCounterDescriptor_GpuCounterBlock& GpuCounterDescriptor_GpuCounterBlock::operator=(const GpuCounterDescriptor_GpuCounterBlock&) = default;
13616 GpuCounterDescriptor_GpuCounterBlock::GpuCounterDescriptor_GpuCounterBlock(GpuCounterDescriptor_GpuCounterBlock&&) noexcept = default;
13617 GpuCounterDescriptor_GpuCounterBlock& GpuCounterDescriptor_GpuCounterBlock::operator=(GpuCounterDescriptor_GpuCounterBlock&&) = default;
13618
operator ==(const GpuCounterDescriptor_GpuCounterBlock & other) const13619 bool GpuCounterDescriptor_GpuCounterBlock::operator==(const GpuCounterDescriptor_GpuCounterBlock& other) const {
13620 return unknown_fields_ == other.unknown_fields_
13621 && block_id_ == other.block_id_
13622 && block_capacity_ == other.block_capacity_
13623 && name_ == other.name_
13624 && description_ == other.description_
13625 && counter_ids_ == other.counter_ids_;
13626 }
13627
ParseFromArray(const void * raw,size_t size)13628 bool GpuCounterDescriptor_GpuCounterBlock::ParseFromArray(const void* raw, size_t size) {
13629 counter_ids_.clear();
13630 unknown_fields_.clear();
13631 bool packed_error = false;
13632
13633 ::protozero::ProtoDecoder dec(raw, size);
13634 for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
13635 if (field.id() < _has_field_.size()) {
13636 _has_field_.set(field.id());
13637 }
13638 switch (field.id()) {
13639 case 1 /* block_id */:
13640 field.get(&block_id_);
13641 break;
13642 case 2 /* block_capacity */:
13643 field.get(&block_capacity_);
13644 break;
13645 case 3 /* name */:
13646 field.get(&name_);
13647 break;
13648 case 4 /* description */:
13649 field.get(&description_);
13650 break;
13651 case 5 /* counter_ids */:
13652 counter_ids_.emplace_back();
13653 field.get(&counter_ids_.back());
13654 break;
13655 default:
13656 field.SerializeAndAppendTo(&unknown_fields_);
13657 break;
13658 }
13659 }
13660 return !packed_error && !dec.bytes_left();
13661 }
13662
SerializeAsString() const13663 std::string GpuCounterDescriptor_GpuCounterBlock::SerializeAsString() const {
13664 ::protozero::HeapBuffered<::protozero::Message> msg;
13665 Serialize(msg.get());
13666 return msg.SerializeAsString();
13667 }
13668
SerializeAsArray() const13669 std::vector<uint8_t> GpuCounterDescriptor_GpuCounterBlock::SerializeAsArray() const {
13670 ::protozero::HeapBuffered<::protozero::Message> msg;
13671 Serialize(msg.get());
13672 return msg.SerializeAsArray();
13673 }
13674
Serialize(::protozero::Message * msg) const13675 void GpuCounterDescriptor_GpuCounterBlock::Serialize(::protozero::Message* msg) const {
13676 // Field 1: block_id
13677 if (_has_field_[1]) {
13678 msg->AppendVarInt(1, block_id_);
13679 }
13680
13681 // Field 2: block_capacity
13682 if (_has_field_[2]) {
13683 msg->AppendVarInt(2, block_capacity_);
13684 }
13685
13686 // Field 3: name
13687 if (_has_field_[3]) {
13688 msg->AppendString(3, name_);
13689 }
13690
13691 // Field 4: description
13692 if (_has_field_[4]) {
13693 msg->AppendString(4, description_);
13694 }
13695
13696 // Field 5: counter_ids
13697 for (auto& it : counter_ids_) {
13698 msg->AppendVarInt(5, it);
13699 }
13700
13701 msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
13702 }
13703
13704
13705 GpuCounterDescriptor_GpuCounterSpec::GpuCounterDescriptor_GpuCounterSpec() = default;
13706 GpuCounterDescriptor_GpuCounterSpec::~GpuCounterDescriptor_GpuCounterSpec() = default;
13707 GpuCounterDescriptor_GpuCounterSpec::GpuCounterDescriptor_GpuCounterSpec(const GpuCounterDescriptor_GpuCounterSpec&) = default;
13708 GpuCounterDescriptor_GpuCounterSpec& GpuCounterDescriptor_GpuCounterSpec::operator=(const GpuCounterDescriptor_GpuCounterSpec&) = default;
13709 GpuCounterDescriptor_GpuCounterSpec::GpuCounterDescriptor_GpuCounterSpec(GpuCounterDescriptor_GpuCounterSpec&&) noexcept = default;
13710 GpuCounterDescriptor_GpuCounterSpec& GpuCounterDescriptor_GpuCounterSpec::operator=(GpuCounterDescriptor_GpuCounterSpec&&) = default;
13711
operator ==(const GpuCounterDescriptor_GpuCounterSpec & other) const13712 bool GpuCounterDescriptor_GpuCounterSpec::operator==(const GpuCounterDescriptor_GpuCounterSpec& other) const {
13713 return unknown_fields_ == other.unknown_fields_
13714 && counter_id_ == other.counter_id_
13715 && name_ == other.name_
13716 && description_ == other.description_
13717 && int_peak_value_ == other.int_peak_value_
13718 && double_peak_value_ == other.double_peak_value_
13719 && numerator_units_ == other.numerator_units_
13720 && denominator_units_ == other.denominator_units_
13721 && select_by_default_ == other.select_by_default_
13722 && groups_ == other.groups_;
13723 }
13724
ParseFromArray(const void * raw,size_t size)13725 bool GpuCounterDescriptor_GpuCounterSpec::ParseFromArray(const void* raw, size_t size) {
13726 numerator_units_.clear();
13727 denominator_units_.clear();
13728 groups_.clear();
13729 unknown_fields_.clear();
13730 bool packed_error = false;
13731
13732 ::protozero::ProtoDecoder dec(raw, size);
13733 for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
13734 if (field.id() < _has_field_.size()) {
13735 _has_field_.set(field.id());
13736 }
13737 switch (field.id()) {
13738 case 1 /* counter_id */:
13739 field.get(&counter_id_);
13740 break;
13741 case 2 /* name */:
13742 field.get(&name_);
13743 break;
13744 case 3 /* description */:
13745 field.get(&description_);
13746 break;
13747 case 5 /* int_peak_value */:
13748 field.get(&int_peak_value_);
13749 break;
13750 case 6 /* double_peak_value */:
13751 field.get(&double_peak_value_);
13752 break;
13753 case 7 /* numerator_units */:
13754 numerator_units_.emplace_back();
13755 field.get(&numerator_units_.back());
13756 break;
13757 case 8 /* denominator_units */:
13758 denominator_units_.emplace_back();
13759 field.get(&denominator_units_.back());
13760 break;
13761 case 9 /* select_by_default */:
13762 field.get(&select_by_default_);
13763 break;
13764 case 10 /* groups */:
13765 groups_.emplace_back();
13766 field.get(&groups_.back());
13767 break;
13768 default:
13769 field.SerializeAndAppendTo(&unknown_fields_);
13770 break;
13771 }
13772 }
13773 return !packed_error && !dec.bytes_left();
13774 }
13775
SerializeAsString() const13776 std::string GpuCounterDescriptor_GpuCounterSpec::SerializeAsString() const {
13777 ::protozero::HeapBuffered<::protozero::Message> msg;
13778 Serialize(msg.get());
13779 return msg.SerializeAsString();
13780 }
13781
SerializeAsArray() const13782 std::vector<uint8_t> GpuCounterDescriptor_GpuCounterSpec::SerializeAsArray() const {
13783 ::protozero::HeapBuffered<::protozero::Message> msg;
13784 Serialize(msg.get());
13785 return msg.SerializeAsArray();
13786 }
13787
Serialize(::protozero::Message * msg) const13788 void GpuCounterDescriptor_GpuCounterSpec::Serialize(::protozero::Message* msg) const {
13789 // Field 1: counter_id
13790 if (_has_field_[1]) {
13791 msg->AppendVarInt(1, counter_id_);
13792 }
13793
13794 // Field 2: name
13795 if (_has_field_[2]) {
13796 msg->AppendString(2, name_);
13797 }
13798
13799 // Field 3: description
13800 if (_has_field_[3]) {
13801 msg->AppendString(3, description_);
13802 }
13803
13804 // Field 5: int_peak_value
13805 if (_has_field_[5]) {
13806 msg->AppendVarInt(5, int_peak_value_);
13807 }
13808
13809 // Field 6: double_peak_value
13810 if (_has_field_[6]) {
13811 msg->AppendFixed(6, double_peak_value_);
13812 }
13813
13814 // Field 7: numerator_units
13815 for (auto& it : numerator_units_) {
13816 msg->AppendVarInt(7, it);
13817 }
13818
13819 // Field 8: denominator_units
13820 for (auto& it : denominator_units_) {
13821 msg->AppendVarInt(8, it);
13822 }
13823
13824 // Field 9: select_by_default
13825 if (_has_field_[9]) {
13826 msg->AppendTinyVarInt(9, select_by_default_);
13827 }
13828
13829 // Field 10: groups
13830 for (auto& it : groups_) {
13831 msg->AppendVarInt(10, it);
13832 }
13833
13834 msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
13835 }
13836
13837 } // namespace perfetto
13838 } // namespace protos
13839 } // namespace gen
13840 #if defined(__GNUC__) || defined(__clang__)
13841 #pragma GCC diagnostic pop
13842 #endif
13843 // gen_amalgamated begin source: gen/protos/perfetto/common/interceptor_descriptor.gen.cc
13844 // gen_amalgamated begin header: gen/protos/perfetto/common/interceptor_descriptor.gen.h
13845 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
13846 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_INTERCEPTOR_DESCRIPTOR_PROTO_CPP_H_
13847 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_INTERCEPTOR_DESCRIPTOR_PROTO_CPP_H_
13848
13849 #include <stdint.h>
13850 #include <bitset>
13851 #include <vector>
13852 #include <string>
13853 #include <type_traits>
13854
13855 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
13856 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
13857 // gen_amalgamated expanded: #include "perfetto/base/export.h"
13858
13859 namespace perfetto {
13860 namespace protos {
13861 namespace gen {
13862 class InterceptorDescriptor;
13863 } // namespace perfetto
13864 } // namespace protos
13865 } // namespace gen
13866
13867 namespace protozero {
13868 class Message;
13869 } // namespace protozero
13870
13871 namespace perfetto {
13872 namespace protos {
13873 namespace gen {
13874
13875 class PERFETTO_EXPORT InterceptorDescriptor : public ::protozero::CppMessageObj {
13876 public:
13877 enum FieldNumbers {
13878 kNameFieldNumber = 1,
13879 };
13880
13881 InterceptorDescriptor();
13882 ~InterceptorDescriptor() override;
13883 InterceptorDescriptor(InterceptorDescriptor&&) noexcept;
13884 InterceptorDescriptor& operator=(InterceptorDescriptor&&);
13885 InterceptorDescriptor(const InterceptorDescriptor&);
13886 InterceptorDescriptor& operator=(const InterceptorDescriptor&);
13887 bool operator==(const InterceptorDescriptor&) const;
operator !=(const InterceptorDescriptor & other) const13888 bool operator!=(const InterceptorDescriptor& other) const { return !(*this == other); }
13889
13890 bool ParseFromArray(const void*, size_t) override;
13891 std::string SerializeAsString() const override;
13892 std::vector<uint8_t> SerializeAsArray() const override;
13893 void Serialize(::protozero::Message*) const;
13894
has_name() const13895 bool has_name() const { return _has_field_[1]; }
name() const13896 const std::string& name() const { return name_; }
set_name(const std::string & value)13897 void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
13898
13899 private:
13900 std::string name_{};
13901
13902 // Allows to preserve unknown protobuf fields for compatibility
13903 // with future versions of .proto files.
13904 std::string unknown_fields_;
13905
13906 std::bitset<2> _has_field_{};
13907 };
13908
13909 } // namespace perfetto
13910 } // namespace protos
13911 } // namespace gen
13912
13913 #endif // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_INTERCEPTOR_DESCRIPTOR_PROTO_CPP_H_
13914 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
13915 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
13916 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
13917 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
13918 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
13919 #if defined(__GNUC__) || defined(__clang__)
13920 #pragma GCC diagnostic push
13921 #pragma GCC diagnostic ignored "-Wfloat-equal"
13922 #endif
13923 // gen_amalgamated expanded: #include "protos/perfetto/common/interceptor_descriptor.gen.h"
13924
13925 namespace perfetto {
13926 namespace protos {
13927 namespace gen {
13928
13929 InterceptorDescriptor::InterceptorDescriptor() = default;
13930 InterceptorDescriptor::~InterceptorDescriptor() = default;
13931 InterceptorDescriptor::InterceptorDescriptor(const InterceptorDescriptor&) = default;
13932 InterceptorDescriptor& InterceptorDescriptor::operator=(const InterceptorDescriptor&) = default;
13933 InterceptorDescriptor::InterceptorDescriptor(InterceptorDescriptor&&) noexcept = default;
13934 InterceptorDescriptor& InterceptorDescriptor::operator=(InterceptorDescriptor&&) = default;
13935
operator ==(const InterceptorDescriptor & other) const13936 bool InterceptorDescriptor::operator==(const InterceptorDescriptor& other) const {
13937 return unknown_fields_ == other.unknown_fields_
13938 && name_ == other.name_;
13939 }
13940
ParseFromArray(const void * raw,size_t size)13941 bool InterceptorDescriptor::ParseFromArray(const void* raw, size_t size) {
13942 unknown_fields_.clear();
13943 bool packed_error = false;
13944
13945 ::protozero::ProtoDecoder dec(raw, size);
13946 for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
13947 if (field.id() < _has_field_.size()) {
13948 _has_field_.set(field.id());
13949 }
13950 switch (field.id()) {
13951 case 1 /* name */:
13952 field.get(&name_);
13953 break;
13954 default:
13955 field.SerializeAndAppendTo(&unknown_fields_);
13956 break;
13957 }
13958 }
13959 return !packed_error && !dec.bytes_left();
13960 }
13961
SerializeAsString() const13962 std::string InterceptorDescriptor::SerializeAsString() const {
13963 ::protozero::HeapBuffered<::protozero::Message> msg;
13964 Serialize(msg.get());
13965 return msg.SerializeAsString();
13966 }
13967
SerializeAsArray() const13968 std::vector<uint8_t> InterceptorDescriptor::SerializeAsArray() const {
13969 ::protozero::HeapBuffered<::protozero::Message> msg;
13970 Serialize(msg.get());
13971 return msg.SerializeAsArray();
13972 }
13973
Serialize(::protozero::Message * msg) const13974 void InterceptorDescriptor::Serialize(::protozero::Message* msg) const {
13975 // Field 1: name
13976 if (_has_field_[1]) {
13977 msg->AppendString(1, name_);
13978 }
13979
13980 msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
13981 }
13982
13983 } // namespace perfetto
13984 } // namespace protos
13985 } // namespace gen
13986 #if defined(__GNUC__) || defined(__clang__)
13987 #pragma GCC diagnostic pop
13988 #endif
13989 // gen_amalgamated begin source: gen/protos/perfetto/common/observable_events.gen.cc
13990 // gen_amalgamated begin header: gen/protos/perfetto/common/observable_events.gen.h
13991 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
13992 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_OBSERVABLE_EVENTS_PROTO_CPP_H_
13993 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_OBSERVABLE_EVENTS_PROTO_CPP_H_
13994
13995 #include <stdint.h>
13996 #include <bitset>
13997 #include <vector>
13998 #include <string>
13999 #include <type_traits>
14000
14001 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
14002 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
14003 // gen_amalgamated expanded: #include "perfetto/base/export.h"
14004
14005 namespace perfetto {
14006 namespace protos {
14007 namespace gen {
14008 class ObservableEvents;
14009 class ObservableEvents_DataSourceInstanceStateChange;
14010 enum ObservableEvents_Type : int;
14011 enum ObservableEvents_DataSourceInstanceState : int;
14012 } // namespace perfetto
14013 } // namespace protos
14014 } // namespace gen
14015
14016 namespace protozero {
14017 class Message;
14018 } // namespace protozero
14019
14020 namespace perfetto {
14021 namespace protos {
14022 namespace gen {
14023 enum ObservableEvents_Type : int {
14024 ObservableEvents_Type_TYPE_UNSPECIFIED = 0,
14025 ObservableEvents_Type_TYPE_DATA_SOURCES_INSTANCES = 1,
14026 ObservableEvents_Type_TYPE_ALL_DATA_SOURCES_STARTED = 2,
14027 };
14028 enum ObservableEvents_DataSourceInstanceState : int {
14029 ObservableEvents_DataSourceInstanceState_DATA_SOURCE_INSTANCE_STATE_STOPPED = 1,
14030 ObservableEvents_DataSourceInstanceState_DATA_SOURCE_INSTANCE_STATE_STARTED = 2,
14031 };
14032
14033 class PERFETTO_EXPORT ObservableEvents : public ::protozero::CppMessageObj {
14034 public:
14035 using DataSourceInstanceStateChange = ObservableEvents_DataSourceInstanceStateChange;
14036 using Type = ObservableEvents_Type;
14037 static constexpr auto TYPE_UNSPECIFIED = ObservableEvents_Type_TYPE_UNSPECIFIED;
14038 static constexpr auto TYPE_DATA_SOURCES_INSTANCES = ObservableEvents_Type_TYPE_DATA_SOURCES_INSTANCES;
14039 static constexpr auto TYPE_ALL_DATA_SOURCES_STARTED = ObservableEvents_Type_TYPE_ALL_DATA_SOURCES_STARTED;
14040 static constexpr auto Type_MIN = ObservableEvents_Type_TYPE_UNSPECIFIED;
14041 static constexpr auto Type_MAX = ObservableEvents_Type_TYPE_ALL_DATA_SOURCES_STARTED;
14042 using DataSourceInstanceState = ObservableEvents_DataSourceInstanceState;
14043 static constexpr auto DATA_SOURCE_INSTANCE_STATE_STOPPED = ObservableEvents_DataSourceInstanceState_DATA_SOURCE_INSTANCE_STATE_STOPPED;
14044 static constexpr auto DATA_SOURCE_INSTANCE_STATE_STARTED = ObservableEvents_DataSourceInstanceState_DATA_SOURCE_INSTANCE_STATE_STARTED;
14045 static constexpr auto DataSourceInstanceState_MIN = ObservableEvents_DataSourceInstanceState_DATA_SOURCE_INSTANCE_STATE_STOPPED;
14046 static constexpr auto DataSourceInstanceState_MAX = ObservableEvents_DataSourceInstanceState_DATA_SOURCE_INSTANCE_STATE_STARTED;
14047 enum FieldNumbers {
14048 kInstanceStateChangesFieldNumber = 1,
14049 kAllDataSourcesStartedFieldNumber = 2,
14050 };
14051
14052 ObservableEvents();
14053 ~ObservableEvents() override;
14054 ObservableEvents(ObservableEvents&&) noexcept;
14055 ObservableEvents& operator=(ObservableEvents&&);
14056 ObservableEvents(const ObservableEvents&);
14057 ObservableEvents& operator=(const ObservableEvents&);
14058 bool operator==(const ObservableEvents&) const;
operator !=(const ObservableEvents & other) const14059 bool operator!=(const ObservableEvents& other) const { return !(*this == other); }
14060
14061 bool ParseFromArray(const void*, size_t) override;
14062 std::string SerializeAsString() const override;
14063 std::vector<uint8_t> SerializeAsArray() const override;
14064 void Serialize(::protozero::Message*) const;
14065
instance_state_changes() const14066 const std::vector<ObservableEvents_DataSourceInstanceStateChange>& instance_state_changes() const { return instance_state_changes_; }
mutable_instance_state_changes()14067 std::vector<ObservableEvents_DataSourceInstanceStateChange>* mutable_instance_state_changes() { return &instance_state_changes_; }
14068 int instance_state_changes_size() const;
14069 void clear_instance_state_changes();
14070 ObservableEvents_DataSourceInstanceStateChange* add_instance_state_changes();
14071
has_all_data_sources_started() const14072 bool has_all_data_sources_started() const { return _has_field_[2]; }
all_data_sources_started() const14073