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(PERFETTO_IMPLEMENTATION)
19 #define PERFETTO_IMPLEMENTATION
20 #endif
21 #if !defined(GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER)
22 #define GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
23 #endif
24 #if !defined(GOOGLE_PROTOBUF_NO_RTTI)
25 #define GOOGLE_PROTOBUF_NO_RTTI
26 #endif
27 #include "perfetto.h"
28 // gen_amalgamated begin source: src/base/ctrl_c_handler.cc
29 // gen_amalgamated begin header: include/perfetto/ext/base/ctrl_c_handler.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_CTRL_C_HANDLER_H_
47 #define INCLUDE_PERFETTO_EXT_BASE_CTRL_C_HANDLER_H_
48 
49 namespace perfetto {
50 namespace base {
51 
52 // On Linux/Android/Mac: installs SIGINT + SIGTERM signal handlers.
53 // On Windows: installs a SetConsoleCtrlHandler() handler.
54 // The passed handler must be async safe.
55 using CtrlCHandlerFunction = void (*)();
56 void InstallCtrCHandler(CtrlCHandlerFunction);
57 
58 }  // namespace base
59 }  // namespace perfetto
60 
61 #endif  // INCLUDE_PERFETTO_EXT_BASE_CTRL_C_HANDLER_H_
62 /*
63  * Copyright (C) 2021 The Android Open Source Project
64  *
65  * Licensed under the Apache License, Version 2.0 (the "License");
66  * you may not use this file except in compliance with the License.
67  * You may obtain a copy of the License at
68  *
69  *      http://www.apache.org/licenses/LICENSE-2.0
70  *
71  * Unless required by applicable law or agreed to in writing, software
72  * distributed under the License is distributed on an "AS IS" BASIS,
73  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
74  * See the License for the specific language governing permissions and
75  * limitations under the License.
76  */
77 
78 // gen_amalgamated expanded: #include "perfetto/ext/base/ctrl_c_handler.h"
79 
80 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
81 // gen_amalgamated expanded: #include "perfetto/base/compiler.h"
82 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
83 
84 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
85 #include <Windows.h>
86 #include <io.h>
87 #else
88 #include <signal.h>
89 #include <unistd.h>
90 #endif
91 
92 namespace perfetto {
93 namespace base {
94 
95 namespace {
96 CtrlCHandlerFunction g_handler = nullptr;
97 }
98 
InstallCtrCHandler(CtrlCHandlerFunction handler)99 void InstallCtrCHandler(CtrlCHandlerFunction handler) {
100   PERFETTO_CHECK(g_handler == nullptr);
101   g_handler = handler;
102 
103 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
104   auto trampoline = [](DWORD type) -> int {
105     if (type == CTRL_C_EVENT) {
106       g_handler();
107       return true;
108     }
109     return false;
110   };
111   ::SetConsoleCtrlHandler(trampoline, true);
112 #elif PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
113     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
114     PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
115   // Setup signal handler.
116   struct sigaction sa {};
117 
118 // Glibc headers for sa_sigaction trigger this.
119 #pragma GCC diagnostic push
120 #if defined(__clang__)
121 #pragma GCC diagnostic ignored "-Wdisabled-macro-expansion"
122 #endif
123   sa.sa_handler = [](int) { g_handler(); };
124   sa.sa_flags = static_cast<decltype(sa.sa_flags)>(SA_RESETHAND | SA_RESTART);
125 #pragma GCC diagnostic pop
126   sigaction(SIGINT, &sa, nullptr);
127   sigaction(SIGTERM, &sa, nullptr);
128 #else
129   // Do nothing on NaCL and Fuchsia.
130   ignore_result(handler);
131 #endif
132 }
133 
134 }  // namespace base
135 }  // namespace perfetto
136 // gen_amalgamated begin source: src/base/event_fd.cc
137 // gen_amalgamated begin header: include/perfetto/ext/base/event_fd.h
138 // gen_amalgamated begin header: include/perfetto/base/platform_handle.h
139 /*
140  * Copyright (C) 2020 The Android Open Source Project
141  *
142  * Licensed under the Apache License, Version 2.0 (the "License");
143  * you may not use this file except in compliance with the License.
144  * You may obtain a copy of the License at
145  *
146  *      http://www.apache.org/licenses/LICENSE-2.0
147  *
148  * Unless required by applicable law or agreed to in writing, software
149  * distributed under the License is distributed on an "AS IS" BASIS,
150  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
151  * See the License for the specific language governing permissions and
152  * limitations under the License.
153  */
154 
155 #ifndef INCLUDE_PERFETTO_BASE_PLATFORM_HANDLE_H_
156 #define INCLUDE_PERFETTO_BASE_PLATFORM_HANDLE_H_
157 
158 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
159 
160 namespace perfetto {
161 namespace base {
162 
163 // PlatformHandle should be used only for types that are HANDLE(s) in Windows.
164 // It should NOT be used to blanket-replace "int fd" in the codebase.
165 // Windows has two types of "handles", which, in UNIX-land, both map to int:
166 // 1. File handles returned by the posix-compatibility API like _open().
167 //    These are just int(s) and should stay such, because all the posix-like API
168 //    in Windows.h take an int, not a HANDLE.
169 // 2. Handles returned by old-school WINAPI like CreateFile, CreateEvent etc.
170 //    These are proper HANDLE(s). PlatformHandle should be used here.
171 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
172 // Windows.h typedefs HANDLE to void*. We use void* here to avoid leaking
173 // Windows.h through our headers.
174 using PlatformHandle = void*;
175 
176 // On Windows both nullptr and 0xffff... (INVALID_HANDLE_VALUE) are invalid.
177 struct PlatformHandleChecker {
IsValidperfetto::base::PlatformHandleChecker178   static inline bool IsValid(PlatformHandle h) {
179     return h && h != reinterpret_cast<PlatformHandle>(-1);
180   }
181 };
182 #else
183 using PlatformHandle = int;
184 struct PlatformHandleChecker {
185   static inline bool IsValid(PlatformHandle h) { return h >= 0; }
186 };
187 #endif
188 
189 // The definition of this lives in base/file_utils.cc (to avoid creating an
190 // extra build edge for a one liner). This is really an alias for close() (UNIX)
191 // CloseHandle() (Windows). THe indirection layer is just to avoid leaking
192 // system headers like Windows.h through perfetto headers.
193 // Thre return value is always UNIX-style: 0 on success, -1 on failure.
194 int ClosePlatformHandle(PlatformHandle);
195 
196 }  // namespace base
197 }  // namespace perfetto
198 
199 #endif  // INCLUDE_PERFETTO_BASE_PLATFORM_HANDLE_H_
200 // gen_amalgamated begin header: include/perfetto/ext/base/scoped_file.h
201 /*
202  * Copyright (C) 2017 The Android Open Source Project
203  *
204  * Licensed under the Apache License, Version 2.0 (the "License");
205  * you may not use this file except in compliance with the License.
206  * You may obtain a copy of the License at
207  *
208  *      http://www.apache.org/licenses/LICENSE-2.0
209  *
210  * Unless required by applicable law or agreed to in writing, software
211  * distributed under the License is distributed on an "AS IS" BASIS,
212  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
213  * See the License for the specific language governing permissions and
214  * limitations under the License.
215  */
216 
217 #ifndef INCLUDE_PERFETTO_EXT_BASE_SCOPED_FILE_H_
218 #define INCLUDE_PERFETTO_EXT_BASE_SCOPED_FILE_H_
219 
220 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
221 
222 #include <stdio.h>
223 
224 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
225 #include <dirent.h>  // For DIR* / opendir().
226 #endif
227 
228 #include <string>
229 
230 // gen_amalgamated expanded: #include "perfetto/base/export.h"
231 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
232 // gen_amalgamated expanded: #include "perfetto/base/platform_handle.h"
233 
234 namespace perfetto {
235 namespace base {
236 
237 namespace internal {
238 // Used for the most common cases of ScopedResource where there is only one
239 // invalid value.
240 template <typename T, T InvalidValue>
241 struct DefaultValidityChecker {
IsValidperfetto::base::internal::DefaultValidityChecker242   static bool IsValid(T t) { return t != InvalidValue; }
243 };
244 }  // namespace internal
245 
246 // RAII classes for auto-releasing fds and dirs.
247 // if T is a pointer type, InvalidValue must be nullptr. Doing otherwise
248 // causes weird unexpected behaviors (See https://godbolt.org/z/5nGMW4).
249 template <typename T,
250           int (*CloseFunction)(T),
251           T InvalidValue,
252           bool CheckClose = true,
253           class Checker = internal::DefaultValidityChecker<T, InvalidValue>>
254 class PERFETTO_EXPORT ScopedResource {
255  public:
256   using ValidityChecker = Checker;
257   static constexpr T kInvalid = InvalidValue;
258 
ScopedResource(T t=InvalidValue)259   explicit ScopedResource(T t = InvalidValue) : t_(t) {}
ScopedResource(ScopedResource && other)260   ScopedResource(ScopedResource&& other) noexcept {
261     t_ = other.t_;
262     other.t_ = InvalidValue;
263   }
operator =(ScopedResource && other)264   ScopedResource& operator=(ScopedResource&& other) {
265     reset(other.t_);
266     other.t_ = InvalidValue;
267     return *this;
268   }
get() const269   T get() const { return t_; }
operator *() const270   T operator*() const { return t_; }
operator bool() const271   explicit operator bool() const { return Checker::IsValid(t_); }
reset(T r=InvalidValue)272   void reset(T r = InvalidValue) {
273     if (Checker::IsValid(t_)) {
274       int res = CloseFunction(t_);
275       if (CheckClose)
276         PERFETTO_CHECK(res == 0);
277     }
278     t_ = r;
279   }
release()280   T release() {
281     T t = t_;
282     t_ = InvalidValue;
283     return t;
284   }
~ScopedResource()285   ~ScopedResource() { reset(InvalidValue); }
286 
287  private:
288   ScopedResource(const ScopedResource&) = delete;
289   ScopedResource& operator=(const ScopedResource&) = delete;
290   T t_;
291 };
292 
293 // Declared in file_utils.h. Forward declared to avoid #include cycles.
294 int PERFETTO_EXPORT CloseFile(int fd);
295 
296 // Use this for file resources obtained via open() and similar APIs.
297 using ScopedFile = ScopedResource<int, CloseFile, -1>;
298 using ScopedFstream = ScopedResource<FILE*, fclose, nullptr>;
299 
300 // Use this for resources that are HANDLE on Windows. See comments in
301 // platform_handle.h
302 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
303 using ScopedPlatformHandle = ScopedResource<PlatformHandle,
304                                             ClosePlatformHandle,
305                                             /*InvalidValue=*/nullptr,
306                                             /*CheckClose=*/true,
307                                             PlatformHandleChecker>;
308 #else
309 // On non-windows systems we alias ScopedPlatformHandle to ScopedFile because
310 // they are really the same. This is to allow assignments between the two in
311 // Linux-specific code paths that predate ScopedPlatformHandle.
312 static_assert(std::is_same<int, PlatformHandle>::value, "");
313 using ScopedPlatformHandle = ScopedFile;
314 
315 // DIR* does not exist on Windows.
316 using ScopedDir = ScopedResource<DIR*, closedir, nullptr>;
317 #endif
318 
319 }  // namespace base
320 }  // namespace perfetto
321 
322 #endif  // INCLUDE_PERFETTO_EXT_BASE_SCOPED_FILE_H_
323 /*
324  * Copyright (C) 2018 The Android Open Source Project
325  *
326  * Licensed under the Apache License, Version 2.0 (the "License");
327  * you may not use this file except in compliance with the License.
328  * You may obtain a copy of the License at
329  *
330  *      http://www.apache.org/licenses/LICENSE-2.0
331  *
332  * Unless required by applicable law or agreed to in writing, software
333  * distributed under the License is distributed on an "AS IS" BASIS,
334  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
335  * See the License for the specific language governing permissions and
336  * limitations under the License.
337  */
338 
339 #ifndef INCLUDE_PERFETTO_EXT_BASE_EVENT_FD_H_
340 #define INCLUDE_PERFETTO_EXT_BASE_EVENT_FD_H_
341 
342 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
343 // gen_amalgamated expanded: #include "perfetto/base/platform_handle.h"
344 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
345 
346 namespace perfetto {
347 namespace base {
348 
349 // A waitable event that can be used with poll/select.
350 // This is really a wrapper around eventfd_create with a pipe-based fallback
351 // for other platforms where eventfd is not supported.
352 class EventFd {
353  public:
354   EventFd();
355   ~EventFd();
356   EventFd(EventFd&&) noexcept = default;
357   EventFd& operator=(EventFd&&) = default;
358 
359   // The non-blocking file descriptor that can be polled to wait for the event.
fd() const360   PlatformHandle fd() const { return event_handle_.get(); }
361 
362   // Can be called from any thread.
363   void Notify();
364 
365   // Can be called from any thread. If more Notify() are queued a Clear() call
366   // can clear all of them (up to 16 per call).
367   void Clear();
368 
369  private:
370   // The eventfd, when eventfd is supported, otherwise this is the read end of
371   // the pipe for fallback mode.
372   ScopedPlatformHandle event_handle_;
373 
374 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) &&   \
375     !PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && \
376     !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
377   // On Mac and other non-Linux UNIX platforms a pipe-based fallback is used.
378   // The write end of the wakeup pipe.
379   ScopedFile write_fd_;
380 #endif
381 };
382 
383 }  // namespace base
384 }  // namespace perfetto
385 
386 #endif  // INCLUDE_PERFETTO_EXT_BASE_EVENT_FD_H_
387 // gen_amalgamated begin header: include/perfetto/ext/base/pipe.h
388 /*
389  * Copyright (C) 2018 The Android Open Source Project
390  *
391  * Licensed under the Apache License, Version 2.0 (the "License");
392  * you may not use this file except in compliance with the License.
393  * You may obtain a copy of the License at
394  *
395  *      http://www.apache.org/licenses/LICENSE-2.0
396  *
397  * Unless required by applicable law or agreed to in writing, software
398  * distributed under the License is distributed on an "AS IS" BASIS,
399  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
400  * See the License for the specific language governing permissions and
401  * limitations under the License.
402  */
403 
404 #ifndef INCLUDE_PERFETTO_EXT_BASE_PIPE_H_
405 #define INCLUDE_PERFETTO_EXT_BASE_PIPE_H_
406 
407 // gen_amalgamated expanded: #include "perfetto/base/platform_handle.h"
408 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
409 
410 namespace perfetto {
411 namespace base {
412 
413 class Pipe {
414  public:
415   enum Flags {
416     kBothBlock = 0,
417 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
418     kBothNonBlock,
419     kRdNonBlock,
420     kWrNonBlock,
421 #endif
422   };
423 
424   static Pipe Create(Flags = kBothBlock);
425 
426   Pipe();
427   Pipe(Pipe&&) noexcept;
428   Pipe& operator=(Pipe&&);
429 
430   ScopedPlatformHandle rd;
431   ScopedPlatformHandle wr;
432 };
433 
434 }  // namespace base
435 }  // namespace perfetto
436 
437 #endif  // INCLUDE_PERFETTO_EXT_BASE_PIPE_H_
438 // gen_amalgamated begin header: include/perfetto/ext/base/utils.h
439 /*
440  * Copyright (C) 2017 The Android Open Source Project
441  *
442  * Licensed under the Apache License, Version 2.0 (the "License");
443  * you may not use this file except in compliance with the License.
444  * You may obtain a copy of the License at
445  *
446  *      http://www.apache.org/licenses/LICENSE-2.0
447  *
448  * Unless required by applicable law or agreed to in writing, software
449  * distributed under the License is distributed on an "AS IS" BASIS,
450  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
451  * See the License for the specific language governing permissions and
452  * limitations under the License.
453  */
454 
455 #ifndef INCLUDE_PERFETTO_EXT_BASE_UTILS_H_
456 #define INCLUDE_PERFETTO_EXT_BASE_UTILS_H_
457 
458 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
459 // gen_amalgamated expanded: #include "perfetto/base/compiler.h"
460 
461 #include <errno.h>
462 #include <stddef.h>
463 #include <stdint.h>
464 #include <stdlib.h>
465 #include <sys/types.h>
466 
467 #include <atomic>
468 #include <string>
469 
470 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
471 // Even if Windows has errno.h, the all syscall-restart behavior does not apply.
472 // Trying to handle EINTR can cause more harm than good if errno is left stale.
473 // Chromium does the same.
474 #define PERFETTO_EINTR(x) (x)
475 #else
476 #define PERFETTO_EINTR(x)                                   \
477   ([&] {                                                    \
478     decltype(x) eintr_wrapper_result;                       \
479     do {                                                    \
480       eintr_wrapper_result = (x);                           \
481     } while (eintr_wrapper_result == -1 && errno == EINTR); \
482     return eintr_wrapper_result;                            \
483   }())
484 #endif
485 
486 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
487 using uid_t = unsigned int;
488 #if !PERFETTO_BUILDFLAG(PERFETTO_COMPILER_GCC)
489 using pid_t = unsigned int;
490 #endif
491 #if defined(_WIN64)
492 using ssize_t = int64_t;
493 #else
494 using ssize_t = long;
495 #endif
496 #endif
497 
498 namespace perfetto {
499 namespace base {
500 
501 constexpr uid_t kInvalidUid = static_cast<uid_t>(-1);
502 constexpr pid_t kInvalidPid = static_cast<pid_t>(-1);
503 
504 // Do not add new usages of kPageSize, consider using GetSysPageSize() below.
505 // TODO(primiano): over time the semantic of kPageSize became too ambiguous.
506 // Strictly speaking, this constant is incorrect on some new devices where the
507 // page size can be 16K (e.g., crbug.com/1116576). Unfortunately too much code
508 // ended up depending on kPageSize for purposes that are not strictly related
509 // with the kernel's mm subsystem.
510 constexpr size_t kPageSize = 4096;
511 
512 // Returns the system's page size. Use this when dealing with mmap, madvise and
513 // similar mm-related syscalls.
514 uint32_t GetSysPageSize();
515 
516 template <typename T>
ArraySize(const T & array)517 constexpr size_t ArraySize(const T& array) {
518   return sizeof(array) / sizeof(array[0]);
519 }
520 
521 // Function object which invokes 'free' on its parameter, which must be
522 // a pointer. Can be used to store malloc-allocated pointers in std::unique_ptr:
523 //
524 // std::unique_ptr<int, base::FreeDeleter> foo_ptr(
525 //     static_cast<int*>(malloc(sizeof(int))));
526 struct FreeDeleter {
operator ()perfetto::base::FreeDeleter527   inline void operator()(void* ptr) const { free(ptr); }
528 };
529 
530 template <typename T>
AssumeLittleEndian(T value)531 constexpr T AssumeLittleEndian(T value) {
532 #if !PERFETTO_IS_LITTLE_ENDIAN()
533   static_assert(false, "Unimplemented on big-endian archs");
534 #endif
535   return value;
536 }
537 
538 // Round up |size| to a multiple of |alignment| (must be a power of two).
539 template <size_t alignment>
AlignUp(size_t size)540 constexpr size_t AlignUp(size_t size) {
541   static_assert((alignment & (alignment - 1)) == 0, "alignment must be a pow2");
542   return (size + alignment - 1) & ~(alignment - 1);
543 }
544 
IsAgain(int err)545 inline bool IsAgain(int err) {
546   return err == EAGAIN || err == EWOULDBLOCK;
547 }
548 
549 // setenv(2)-equivalent. Deals with Windows vs Posix discrepancies.
550 void SetEnv(const std::string& key, const std::string& value);
551 
552 // Calls mallopt(M_PURGE, 0) on Android. Does nothing on other platforms.
553 // This forces the allocator to release freed memory. This is used to work
554 // around various Scudo inefficiencies. See b/170217718.
555 void MaybeReleaseAllocatorMemToOS();
556 
557 // geteuid() on POSIX OSes, returns 0 on Windows (See comment in utils.cc).
558 uid_t GetCurrentUserId();
559 
560 // Forks the process.
561 // Parent: prints the PID of the child and exit(0).
562 // Child: redirects stdio onto /dev/null and chdirs into .
563 void Daemonize();
564 
565 }  // namespace base
566 }  // namespace perfetto
567 
568 #endif  // INCLUDE_PERFETTO_EXT_BASE_UTILS_H_
569 /*
570  * Copyright (C) 2018 The Android Open Source Project
571  *
572  * Licensed under the Apache License, Version 2.0 (the "License");
573  * you may not use this file except in compliance with the License.
574  * You may obtain a copy of the License at
575  *
576  *      http://www.apache.org/licenses/LICENSE-2.0
577  *
578  * Unless required by applicable law or agreed to in writing, software
579  * distributed under the License is distributed on an "AS IS" BASIS,
580  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
581  * See the License for the specific language governing permissions and
582  * limitations under the License.
583  */
584 
585 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
586 
587 #include <errno.h>
588 #include <stdint.h>
589 
590 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
591 #include <Windows.h>
592 #include <synchapi.h>
593 #elif PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
594     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
595 #include <sys/eventfd.h>
596 #include <unistd.h>
597 #else  // Mac, Fuchsia and other non-Linux UNIXes
598 #include <unistd.h>
599 #endif
600 
601 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
602 // gen_amalgamated expanded: #include "perfetto/ext/base/event_fd.h"
603 // gen_amalgamated expanded: #include "perfetto/ext/base/pipe.h"
604 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
605 
606 namespace perfetto {
607 namespace base {
608 
609 EventFd::~EventFd() = default;
610 
611 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
EventFd()612 EventFd::EventFd() {
613   event_handle_.reset(
614       CreateEventA(/*lpEventAttributes=*/nullptr, /*bManualReset=*/true,
615                    /*bInitialState=*/false, /*bInitialState=*/nullptr));
616 }
617 
Notify()618 void EventFd::Notify() {
619   if (!SetEvent(event_handle_.get()))  // 0: fail, !0: success, unlike UNIX.
620     PERFETTO_DFATAL("EventFd::Notify()");
621 }
622 
Clear()623 void EventFd::Clear() {
624   if (!ResetEvent(event_handle_.get()))  // 0: fail, !0: success, unlike UNIX.
625     PERFETTO_DFATAL("EventFd::Clear()");
626 }
627 
628 #elif PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
629     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
630 
EventFd()631 EventFd::EventFd() {
632   event_handle_.reset(eventfd(/*initval=*/0, EFD_CLOEXEC | EFD_NONBLOCK));
633   PERFETTO_CHECK(event_handle_);
634 }
635 
Notify()636 void EventFd::Notify() {
637   const uint64_t value = 1;
638   ssize_t ret = write(event_handle_.get(), &value, sizeof(value));
639   if (ret <= 0 && errno != EAGAIN)
640     PERFETTO_DFATAL("EventFd::Notify()");
641 }
642 
Clear()643 void EventFd::Clear() {
644   uint64_t value;
645   ssize_t ret = read(event_handle_.get(), &value, sizeof(value));
646   if (ret <= 0 && errno != EAGAIN)
647     PERFETTO_DFATAL("EventFd::Clear()");
648 }
649 
650 #else
651 
EventFd()652 EventFd::EventFd() {
653   // Make the pipe non-blocking so that we never block the waking thread (either
654   // the main thread or another one) when scheduling a wake-up.
655   Pipe pipe = Pipe::Create(Pipe::kBothNonBlock);
656   event_handle_ = ScopedPlatformHandle(std::move(pipe.rd).release());
657   write_fd_ = std::move(pipe.wr);
658 }
659 
Notify()660 void EventFd::Notify() {
661   const uint64_t value = 1;
662   ssize_t ret = write(write_fd_.get(), &value, sizeof(uint8_t));
663   if (ret <= 0 && errno != EAGAIN)
664     PERFETTO_DFATAL("EventFd::Notify()");
665 }
666 
Clear()667 void EventFd::Clear() {
668   // Drain the byte(s) written to the wake-up pipe. We can potentially read
669   // more than one byte if several wake-ups have been scheduled.
670   char buffer[16];
671   ssize_t ret = read(event_handle_.get(), &buffer[0], sizeof(buffer));
672   if (ret <= 0 && errno != EAGAIN)
673     PERFETTO_DFATAL("EventFd::Clear()");
674 }
675 #endif
676 
677 }  // namespace base
678 }  // namespace perfetto
679 // gen_amalgamated begin source: src/base/file_utils.cc
680 // gen_amalgamated begin header: include/perfetto/ext/base/file_utils.h
681 /*
682  * Copyright (C) 2018 The Android Open Source Project
683  *
684  * Licensed under the Apache License, Version 2.0 (the "License");
685  * you may not use this file except in compliance with the License.
686  * You may obtain a copy of the License at
687  *
688  *      http://www.apache.org/licenses/LICENSE-2.0
689  *
690  * Unless required by applicable law or agreed to in writing, software
691  * distributed under the License is distributed on an "AS IS" BASIS,
692  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
693  * See the License for the specific language governing permissions and
694  * limitations under the License.
695  */
696 
697 #ifndef INCLUDE_PERFETTO_EXT_BASE_FILE_UTILS_H_
698 #define INCLUDE_PERFETTO_EXT_BASE_FILE_UTILS_H_
699 
700 #include <fcntl.h>  // For mode_t & O_RDONLY/RDWR. Exists also on Windows.
701 #include <stddef.h>
702 
703 #include <string>
704 
705 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
706 // gen_amalgamated expanded: #include "perfetto/base/export.h"
707 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
708 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
709 
710 namespace perfetto {
711 namespace base {
712 
713 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
714 using FileOpenMode = int;
715 #else
716 using FileOpenMode = mode_t;
717 #endif
718 
719 constexpr FileOpenMode kFileModeInvalid = static_cast<FileOpenMode>(-1);
720 
721 bool ReadPlatformHandle(PlatformHandle, std::string* out);
722 bool ReadFileDescriptor(int fd, std::string* out);
723 bool ReadFileStream(FILE* f, std::string* out);
724 bool ReadFile(const std::string& path, std::string* out);
725 
726 // A wrapper around read(2). It deals with Linux vs Windows includes. It also
727 // deals with handling EINTR. Has the same semantics of UNIX's read(2).
728 ssize_t Read(int fd, void* dst, size_t dst_size);
729 
730 // Call write until all data is written or an error is detected.
731 //
732 // man 2 write:
733 //   If a write() is interrupted by a signal handler before any bytes are
734 //   written, then the call fails with the error EINTR; if it is
735 //   interrupted after at least one byte has been written, the call
736 //   succeeds, and returns the number of bytes written.
737 ssize_t WriteAll(int fd, const void* buf, size_t count);
738 
739 ssize_t WriteAllHandle(PlatformHandle, const void* buf, size_t count);
740 
741 ScopedFile OpenFile(const std::string& path,
742                     int flags,
743                     FileOpenMode = kFileModeInvalid);
744 
745 // This is an alias for close(). It's to avoid leaking Windows.h in headers.
746 // Exported because ScopedFile is used in the /include/ext API by Chromium
747 // component builds.
748 int PERFETTO_EXPORT CloseFile(int fd);
749 
750 bool FlushFile(int fd);
751 
752 // Returns true if mkdir succeeds, false if it fails (see errno in that case).
753 bool Mkdir(const std::string& path);
754 
755 // Calls rmdir() on UNIX, _rmdir() on Windows.
756 bool Rmdir(const std::string& path);
757 
758 // Wrapper around access(path, F_OK).
759 bool FileExists(const std::string& path);
760 
761 }  // namespace base
762 }  // namespace perfetto
763 
764 #endif  // INCLUDE_PERFETTO_EXT_BASE_FILE_UTILS_H_
765 /*
766  * Copyright (C) 2018 The Android Open Source Project
767  *
768  * Licensed under the Apache License, Version 2.0 (the "License");
769  * you may not use this file except in compliance with the License.
770  * You may obtain a copy of the License at
771  *
772  *      http://www.apache.org/licenses/LICENSE-2.0
773  *
774  * Unless required by applicable law or agreed to in writing, software
775  * distributed under the License is distributed on an "AS IS" BASIS,
776  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
777  * See the License for the specific language governing permissions and
778  * limitations under the License.
779  */
780 
781 // gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
782 
783 #include <sys/stat.h>
784 #include <sys/types.h>
785 
786 #include <algorithm>
787 
788 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
789 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
790 // gen_amalgamated expanded: #include "perfetto/base/platform_handle.h"
791 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
792 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
793 
794 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
795 #include <Windows.h>
796 #include <direct.h>
797 #include <io.h>
798 #else
799 #include <dirent.h>
800 #include <unistd.h>
801 #endif
802 
803 namespace perfetto {
804 namespace base {
805 namespace {
806 constexpr size_t kBufSize = 2048;
807 }
808 
Read(int fd,void * dst,size_t dst_size)809 ssize_t Read(int fd, void* dst, size_t dst_size) {
810 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
811   return _read(fd, dst, static_cast<unsigned>(dst_size));
812 #else
813   return PERFETTO_EINTR(read(fd, dst, dst_size));
814 #endif
815 }
816 
ReadFileDescriptor(int fd,std::string * out)817 bool ReadFileDescriptor(int fd, std::string* out) {
818   // Do not override existing data in string.
819   size_t i = out->size();
820 
821   struct stat buf {};
822   if (fstat(fd, &buf) != -1) {
823     if (buf.st_size > 0)
824       out->resize(i + static_cast<size_t>(buf.st_size));
825   }
826 
827   ssize_t bytes_read;
828   for (;;) {
829     if (out->size() < i + kBufSize)
830       out->resize(out->size() + kBufSize);
831 
832     bytes_read = Read(fd, &((*out)[i]), kBufSize);
833     if (bytes_read > 0) {
834       i += static_cast<size_t>(bytes_read);
835     } else {
836       out->resize(i);
837       return bytes_read == 0;
838     }
839   }
840 }
841 
ReadPlatformHandle(PlatformHandle h,std::string * out)842 bool ReadPlatformHandle(PlatformHandle h, std::string* out) {
843 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
844   // Do not override existing data in string.
845   size_t i = out->size();
846 
847   for (;;) {
848     if (out->size() < i + kBufSize)
849       out->resize(out->size() + kBufSize);
850     DWORD bytes_read = 0;
851     auto res = ::ReadFile(h, &((*out)[i]), kBufSize, &bytes_read, nullptr);
852     if (res && bytes_read > 0) {
853       i += static_cast<size_t>(bytes_read);
854     } else {
855       out->resize(i);
856       const bool is_eof = res && bytes_read == 0;
857       auto err = res ? 0 : GetLastError();
858       // The "Broken pipe" error on Windows is slighly different than Unix:
859       // On Unix: a "broken pipe" error can happen only on the writer side. On
860       // the reader there is no broken pipe, just a EOF.
861       // On windows: the reader also sees a broken pipe error.
862       // Here we normalize on the Unix behavior, treating broken pipe as EOF.
863       return is_eof || err == ERROR_BROKEN_PIPE;
864     }
865   }
866 #else
867   return ReadFileDescriptor(h, out);
868 #endif
869 }
870 
ReadFileStream(FILE * f,std::string * out)871 bool ReadFileStream(FILE* f, std::string* out) {
872   return ReadFileDescriptor(fileno(f), out);
873 }
874 
ReadFile(const std::string & path,std::string * out)875 bool ReadFile(const std::string& path, std::string* out) {
876   base::ScopedFile fd = base::OpenFile(path, O_RDONLY);
877   if (!fd)
878     return false;
879 
880   return ReadFileDescriptor(*fd, out);
881 }
882 
WriteAll(int fd,const void * buf,size_t count)883 ssize_t WriteAll(int fd, const void* buf, size_t count) {
884   size_t written = 0;
885   while (written < count) {
886     // write() on windows takes an unsigned int size.
887     uint32_t bytes_left = static_cast<uint32_t>(
888         std::min(count - written, static_cast<size_t>(UINT32_MAX)));
889     ssize_t wr = PERFETTO_EINTR(
890         write(fd, static_cast<const char*>(buf) + written, bytes_left));
891     if (wr == 0)
892       break;
893     if (wr < 0)
894       return wr;
895     written += static_cast<size_t>(wr);
896   }
897   return static_cast<ssize_t>(written);
898 }
899 
WriteAllHandle(PlatformHandle h,const void * buf,size_t count)900 ssize_t WriteAllHandle(PlatformHandle h, const void* buf, size_t count) {
901 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
902   DWORD wsize = 0;
903   if (::WriteFile(h, buf, static_cast<DWORD>(count), &wsize, nullptr)) {
904     return wsize;
905   } else {
906     return -1;
907   }
908 #else
909   return WriteAll(h, buf, count);
910 #endif
911 }
912 
FlushFile(int fd)913 bool FlushFile(int fd) {
914   PERFETTO_DCHECK(fd != 0);
915 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
916     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
917   return !PERFETTO_EINTR(fdatasync(fd));
918 #elif PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
919   return !PERFETTO_EINTR(_commit(fd));
920 #else
921   return !PERFETTO_EINTR(fsync(fd));
922 #endif
923 }
924 
Mkdir(const std::string & path)925 bool Mkdir(const std::string& path) {
926 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
927   return _mkdir(path.c_str()) == 0;
928 #else
929   return mkdir(path.c_str(), 0755) == 0;
930 #endif
931 }
932 
Rmdir(const std::string & path)933 bool Rmdir(const std::string& path) {
934 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
935   return _rmdir(path.c_str()) == 0;
936 #else
937   return rmdir(path.c_str()) == 0;
938 #endif
939 }
940 
CloseFile(int fd)941 int CloseFile(int fd) {
942   return close(fd);
943 }
944 
OpenFile(const std::string & path,int flags,FileOpenMode mode)945 ScopedFile OpenFile(const std::string& path, int flags, FileOpenMode mode) {
946   PERFETTO_DCHECK((flags & O_CREAT) == 0 || mode != kFileModeInvalid);
947 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
948   // Always use O_BINARY on Windows, to avoid silly EOL translations.
949   ScopedFile fd(_open(path.c_str(), flags | O_BINARY, mode));
950 #else
951   // Always open a ScopedFile with O_CLOEXEC so we can safely fork and exec.
952   ScopedFile fd(open(path.c_str(), flags | O_CLOEXEC, mode));
953 #endif
954   return fd;
955 }
956 
FileExists(const std::string & path)957 bool FileExists(const std::string& path) {
958 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
959   return _access(path.c_str(), 0) == 0;
960 #else
961   return access(path.c_str(), F_OK) == 0;
962 #endif
963 }
964 
965 // Declared in base/platform_handle.h.
ClosePlatformHandle(PlatformHandle handle)966 int ClosePlatformHandle(PlatformHandle handle) {
967 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
968   // Make the return value UNIX-style.
969   return CloseHandle(handle) ? 0 : -1;
970 #else
971   return close(handle);
972 #endif
973 }
974 
975 }  // namespace base
976 }  // namespace perfetto
977 // gen_amalgamated begin source: src/base/getopt_compat.cc
978 // gen_amalgamated begin header: include/perfetto/ext/base/getopt_compat.h
979 /*
980  * Copyright (C) 2021 The Android Open Source Project
981  *
982  * Licensed under the Apache License, Version 2.0 (the "License");
983  * you may not use this file except in compliance with the License.
984  * You may obtain a copy of the License at
985  *
986  *      http://www.apache.org/licenses/LICENSE-2.0
987  *
988  * Unless required by applicable law or agreed to in writing, software
989  * distributed under the License is distributed on an "AS IS" BASIS,
990  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
991  * See the License for the specific language governing permissions and
992  * limitations under the License.
993  */
994 
995 #ifndef INCLUDE_PERFETTO_EXT_BASE_GETOPT_COMPAT_H_
996 #define INCLUDE_PERFETTO_EXT_BASE_GETOPT_COMPAT_H_
997 
998 #include <cstddef>  // For std::nullptr_t
999 
1000 // No translation units other than base/getopt.h and getopt_compat_unittest.cc
1001 // should directly include this file. Use base/getopt.h instead.
1002 
1003 namespace perfetto {
1004 namespace base {
1005 namespace getopt_compat {
1006 
1007 // A tiny getopt() replacement for Windows, which doesn't have <getopt.h>.
1008 // This implementation is based on the subset of features that we use in the
1009 // Perfetto codebase. It doesn't even try to deal with the full surface of GNU's
1010 // getopt().
1011 // Limitations:
1012 // - getopt_long_only() is not supported.
1013 // - optional_argument is not supported. That is extremely subtle and caused us
1014 //   problems in the past with GNU's getopt.
1015 // - It does not reorder non-option arguments. It behaves like MacOS getopt, or
1016 //   GNU's when POSIXLY_CORRECT=1.
1017 // - Doesn't expose optopt or opterr.
1018 // - option.flag and longindex are not supported and must be nullptr.
1019 
1020 enum {
1021   no_argument = 0,
1022   required_argument = 1,
1023 };
1024 
1025 struct option {
1026   const char* name;
1027   int has_arg;
1028   std::nullptr_t flag;  // Only nullptr is supported.
1029   int val;
1030 };
1031 
1032 extern char* optarg;
1033 extern int optind;
1034 
1035 int getopt_long(int argc,
1036                 char** argv,
1037                 const char* shortopts,
1038                 const option* longopts,
1039                 std::nullptr_t /*longindex is not supported*/);
1040 
1041 int getopt(int argc, char** argv, const char* shortopts);
1042 
1043 }  // namespace getopt_compat
1044 }  // namespace base
1045 }  // namespace perfetto
1046 
1047 #endif  // INCLUDE_PERFETTO_EXT_BASE_GETOPT_COMPAT_H_
1048 /*
1049  * Copyright (C) 2021 The Android Open Source Project
1050  *
1051  * Licensed under the Apache License, Version 2.0 (the "License");
1052  * you may not use this file except in compliance with the License.
1053  * You may obtain a copy of the License at
1054  *
1055  *      http://www.apache.org/licenses/LICENSE-2.0
1056  *
1057  * Unless required by applicable law or agreed to in writing, software
1058  * distributed under the License is distributed on an "AS IS" BASIS,
1059  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1060  * See the License for the specific language governing permissions and
1061  * limitations under the License.
1062  */
1063 
1064 // gen_amalgamated expanded: #include "perfetto/ext/base/getopt_compat.h"
1065 
1066 #include <stdio.h>
1067 #include <stdlib.h>
1068 #include <string.h>
1069 
1070 #include <vector>
1071 
1072 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
1073 
1074 namespace perfetto {
1075 namespace base {
1076 namespace getopt_compat {
1077 
1078 char* optarg = nullptr;
1079 int optind = 0;
1080 
1081 namespace {
1082 
1083 char* nextchar = nullptr;
1084 
LookupLongOpt(const std::vector<option> & opts,const char * name,size_t len)1085 const option* LookupLongOpt(const std::vector<option>& opts,
1086                             const char* name,
1087                             size_t len) {
1088   for (const option& opt : opts) {
1089     if (strncmp(opt.name, name, len) == 0 && strlen(opt.name) == len)
1090       return &opt;
1091   }
1092   return nullptr;
1093 }
1094 
LookupShortOpt(const std::vector<option> & opts,char c)1095 const option* LookupShortOpt(const std::vector<option>& opts, char c) {
1096   for (const option& opt : opts) {
1097     if (opt.name == nullptr && opt.val == c)
1098       return &opt;
1099   }
1100   return nullptr;
1101 }
1102 
ParseOpts(const char * shortopts,const option * longopts,std::vector<option> * res)1103 bool ParseOpts(const char* shortopts,
1104                const option* longopts,
1105                std::vector<option>* res) {
1106   // Parse long options first.
1107   for (const option* lopt = longopts; lopt && lopt->name; lopt++) {
1108     PERFETTO_CHECK(lopt->flag == nullptr);
1109     PERFETTO_CHECK(lopt->has_arg == no_argument ||
1110                    lopt->has_arg == required_argument);
1111     res->emplace_back(*lopt);
1112   }
1113 
1114   // Merge short options.
1115   for (const char* sopt = shortopts; sopt && *sopt;) {
1116     const size_t idx = static_cast<size_t>(sopt - shortopts);
1117     char c = *sopt++;
1118     bool valid = (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
1119                  (c >= '0' && c <= '9');
1120     if (!valid) {
1121       fprintf(stderr,
1122               "Error parsing shortopts. Unexpected char '%c' at offset %zu\n",
1123               c, idx);
1124       return false;
1125     }
1126     res->emplace_back();
1127     option& opt = res->back();
1128     opt.val = c;
1129     opt.has_arg = no_argument;
1130     if (*sopt == ':') {
1131       opt.has_arg = required_argument;
1132       ++sopt;
1133     }
1134   }
1135   return true;
1136 }
1137 
1138 }  // namespace
1139 
getopt_long(int argc,char ** argv,const char * shortopts,const option * longopts,std::nullptr_t)1140 int getopt_long(int argc,
1141                 char** argv,
1142                 const char* shortopts,
1143                 const option* longopts,
1144                 std::nullptr_t /*longind*/) {
1145   std::vector<option> opts;
1146   optarg = nullptr;
1147 
1148   if (optind == 0)
1149     optind = 1;
1150 
1151   if (optind >= argc)
1152     return -1;
1153 
1154   if (!ParseOpts(shortopts, longopts, &opts))
1155     return '?';
1156 
1157   char* arg = argv[optind];
1158 
1159   if (!nextchar) {
1160     // If |nextchar| is null we are NOT in the middle of a short option and we
1161     // should parse the next argv.
1162     if (strncmp(arg, "--", 2) == 0 && strlen(arg) > 2) {
1163       // A --long option.
1164       arg += 2;
1165       char* sep = strchr(arg, '=');
1166       optind++;
1167 
1168       size_t len = sep ? static_cast<size_t>(sep - arg) : strlen(arg);
1169       const option* opt = LookupLongOpt(opts, arg, len);
1170       if (!opt) {
1171         fprintf(stderr, "unrecognized option '--%s'\n", arg);
1172         return '?';
1173       }
1174 
1175       if (opt->has_arg == no_argument) {
1176         if (sep) {
1177           fprintf(stderr, "option '--%s' doesn't allow an argument\n", arg);
1178           return '?';
1179         } else {
1180           return opt->val;
1181         }
1182       } else if (opt->has_arg == required_argument) {
1183         if (sep) {
1184           optarg = sep + 1;
1185           return opt->val;
1186         } else if (optind >= argc) {
1187           fprintf(stderr, "option '--%s' requires an argument\n", arg);
1188           return '?';
1189         } else {
1190           optarg = argv[optind++];
1191           return opt->val;
1192         }
1193       }
1194       // has_arg must be either |no_argument| or |required_argument|. We
1195       // shoulnd't get here unless the check in ParseOpts() has a bug.
1196       PERFETTO_CHECK(false);
1197     }  // if (arg ~= "--*").
1198 
1199     if (strlen(arg) > 1 && arg[0] == '-' && arg[1] != '-') {
1200       // A sequence of short options. Parsing logic continues below.
1201       nextchar = &arg[1];
1202     }
1203   }  // if(!nextchar)
1204 
1205   if (nextchar) {
1206     // At this point either:
1207     // 1. This is the first char of a sequence of short options, and we fell
1208     //    through here from the lines above.
1209     // 2. This is the N (>1) char of a sequence of short options, and we got
1210     //    here from a new getopt() call to getopt().
1211     const char cur_char = *nextchar;
1212     PERFETTO_CHECK(cur_char != '\0');
1213 
1214     // Advance the option char in any case, before we start reasoning on them.
1215     // if we got to the end of the "-abc" sequence, increment optind so the next
1216     // getopt() call resumes from the next argv argument.
1217     if (*(++nextchar) == '\0') {
1218       nextchar = nullptr;
1219       ++optind;
1220     }
1221 
1222     const option* opt = LookupShortOpt(opts, cur_char);
1223     if (!opt) {
1224       fprintf(stderr, "invalid option -- '%c'\n", cur_char);
1225       return '?';
1226     }
1227     if (opt->has_arg == no_argument) {
1228       return cur_char;
1229     } else if (opt->has_arg == required_argument) {
1230       // This is a subtle getopt behavior. Say you call `tar -fx`, there are
1231       // two cases:
1232       // 1. If 'f' is no_argument then 'x' (and anything else after) is
1233       //    interpreted as an independent argument (like `tar -f -x`).
1234       // 2. If 'f' is required_argument, than everything else after the 'f'
1235       //    is interpreted as the option argument (like `tar -f x`)
1236       if (!nextchar) {
1237         // Case 1.
1238         if (optind >= argc) {
1239           fprintf(stderr, "option requires an argument -- '%c'\n", cur_char);
1240           return '?';
1241         } else {
1242           optarg = argv[optind++];
1243           return cur_char;
1244         }
1245       } else {
1246         // Case 2.
1247         optarg = nextchar;
1248         nextchar = nullptr;
1249         optind++;
1250         return cur_char;
1251       }
1252     }
1253     PERFETTO_CHECK(false);
1254   }  // if (nextchar)
1255 
1256   // If we get here, we found the first non-option argument. Stop here.
1257 
1258   if (strcmp(arg, "--") == 0)
1259     optind++;
1260 
1261   return -1;
1262 }
1263 
getopt(int argc,char ** argv,const char * shortopts)1264 int getopt(int argc, char** argv, const char* shortopts) {
1265   return getopt_long(argc, argv, shortopts, nullptr, nullptr);
1266 }
1267 
1268 }  // namespace getopt_compat
1269 }  // namespace base
1270 }  // namespace perfetto
1271 // gen_amalgamated begin source: src/base/logging.cc
1272 /*
1273  * Copyright (C) 2019 The Android Open Source Project
1274  *
1275  * Licensed under the Apache License, Version 2.0 (the "License");
1276  * you may not use this file except in compliance with the License.
1277  * You may obtain a copy of the License at
1278  *
1279  *      http://www.apache.org/licenses/LICENSE-2.0
1280  *
1281  * Unless required by applicable law or agreed to in writing, software
1282  * distributed under the License is distributed on an "AS IS" BASIS,
1283  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1284  * See the License for the specific language governing permissions and
1285  * limitations under the License.
1286  */
1287 
1288 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
1289 
1290 #include <stdarg.h>
1291 #include <stdio.h>
1292 
1293 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
1294 #include <unistd.h>  // For isatty()
1295 #endif
1296 
1297 #include <atomic>
1298 #include <memory>
1299 
1300 // gen_amalgamated expanded: #include "perfetto/base/time.h"
1301 
1302 namespace perfetto {
1303 namespace base {
1304 
1305 namespace {
1306 const char kReset[] = "\x1b[0m";
1307 const char kDefault[] = "\x1b[39m";
1308 const char kDim[] = "\x1b[2m";
1309 const char kRed[] = "\x1b[31m";
1310 const char kBoldGreen[] = "\x1b[1m\x1b[32m";
1311 const char kLightGray[] = "\x1b[90m";
1312 
1313 std::atomic<LogMessageCallback> g_log_callback{};
1314 
1315 }  // namespace
1316 
SetLogMessageCallback(LogMessageCallback callback)1317 void SetLogMessageCallback(LogMessageCallback callback) {
1318   g_log_callback.store(callback, std::memory_order_relaxed);
1319 }
1320 
LogMessage(LogLev level,const char * fname,int line,const char * fmt,...)1321 void LogMessage(LogLev level,
1322                 const char* fname,
1323                 int line,
1324                 const char* fmt,
1325                 ...) {
1326   char stack_buf[512];
1327   std::unique_ptr<char[]> large_buf;
1328   char* log_msg = &stack_buf[0];
1329 
1330   // By default use a stack allocated buffer because most log messages are quite
1331   // short. In rare cases they can be larger (e.g. --help). In those cases we
1332   // pay the cost of allocating the buffer on the heap.
1333   for (size_t max_len = sizeof(stack_buf);;) {
1334     va_list args;
1335     va_start(args, fmt);
1336     int res = vsnprintf(log_msg, max_len, fmt, args);
1337     va_end(args);
1338 
1339     // If for any reason the print fails, overwrite the message but still print
1340     // it. The code below will attach the filename and line, which is still
1341     // useful.
1342     if (res < 0) {
1343       strncpy(log_msg, "[printf format error]", max_len);
1344       break;
1345     }
1346 
1347     // if res == max_len, vsnprintf saturated the input buffer. Retry with a
1348     // larger buffer in that case (within reasonable limits).
1349     if (res < static_cast<int>(max_len) || max_len >= 128 * 1024)
1350       break;
1351     max_len *= 4;
1352     large_buf.reset(new char[max_len]);
1353     log_msg = &large_buf[0];
1354   }
1355 
1356   LogMessageCallback cb = g_log_callback.load(std::memory_order_relaxed);
1357   if (cb) {
1358     cb({level, line, fname, log_msg});
1359     return;
1360   }
1361 
1362   const char* color = kDefault;
1363   switch (level) {
1364     case kLogDebug:
1365       color = kDim;
1366       break;
1367     case kLogInfo:
1368       color = kDefault;
1369       break;
1370     case kLogImportant:
1371       color = kBoldGreen;
1372       break;
1373     case kLogError:
1374       color = kRed;
1375       break;
1376   }
1377 
1378 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) && \
1379     !PERFETTO_BUILDFLAG(PERFETTO_OS_WASM)
1380   static const bool use_colors = isatty(STDERR_FILENO);
1381 #else
1382   static const bool use_colors = false;
1383 #endif
1384 
1385   // Formats file.cc:line as a space-padded fixed width string. If the file name
1386   // |fname| is too long, truncate it on the left-hand side.
1387   char line_str[10];
1388   size_t line_len =
1389       static_cast<size_t>(snprintf(line_str, sizeof(line_str), "%d", line));
1390 
1391   // 24 will be the width of the file.cc:line column in the log event.
1392   char file_and_line[24];
1393   size_t fname_len = strlen(fname);
1394   size_t fname_max = sizeof(file_and_line) - line_len - 2;  // 2 = ':' + '\0'.
1395   size_t fname_offset = fname_len <= fname_max ? 0 : fname_len - fname_max;
1396   int len = snprintf(file_and_line, sizeof(file_and_line), "%s:%s",
1397                      fname + fname_offset, line_str);
1398   memset(&file_and_line[len], ' ', sizeof(file_and_line) - size_t(len));
1399   file_and_line[sizeof(file_and_line) - 1] = '\0';
1400 
1401 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
1402   // Logcat has already timestamping, don't re-emit it.
1403   __android_log_print(ANDROID_LOG_DEBUG + level, "perfetto", "%s %s",
1404                       file_and_line, log_msg);
1405 #endif
1406 
1407   // When printing on stderr, print also the timestamp. We don't really care
1408   // about the actual time. We just need some reference clock that can be used
1409   // to correlated events across differrent processses (e.g. traced and
1410   // traced_probes). The wall time % 1000 is good enough.
1411   char timestamp[32];
1412   uint32_t t_ms = static_cast<uint32_t>(GetWallTimeMs().count());
1413   uint32_t t_sec = t_ms / 1000;
1414   t_ms -= t_sec * 1000;
1415   t_sec = t_sec % 1000;
1416   snprintf(timestamp, sizeof(timestamp), "[%03u.%03u] ", t_sec, t_ms);
1417 
1418   if (use_colors) {
1419     fprintf(stderr, "%s%s%s%s %s%s%s\n", kLightGray, timestamp, file_and_line,
1420             kReset, color, log_msg, kReset);
1421   } else {
1422     fprintf(stderr, "%s%s %s\n", timestamp, file_and_line, log_msg);
1423   }
1424 }
1425 
1426 }  // namespace base
1427 }  // namespace perfetto
1428 // gen_amalgamated begin source: src/base/metatrace.cc
1429 // gen_amalgamated begin header: include/perfetto/ext/base/metatrace.h
1430 // gen_amalgamated begin header: include/perfetto/ext/base/metatrace_events.h
1431 /*
1432  * Copyright (C) 2019 The Android Open Source Project
1433  *
1434  * Licensed under the Apache License, Version 2.0 (the "License");
1435  * you may not use this file except in compliance with the License.
1436  * You may obtain a copy of the License at
1437  *
1438  *      http://www.apache.org/licenses/LICENSE-2.0
1439  *
1440  * Unless required by applicable law or agreed to in writing, software
1441  * distributed under the License is distributed on an "AS IS" BASIS,
1442  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1443  * See the License for the specific language governing permissions and
1444  * limitations under the License.
1445  */
1446 
1447 #ifndef INCLUDE_PERFETTO_EXT_BASE_METATRACE_EVENTS_H_
1448 #define INCLUDE_PERFETTO_EXT_BASE_METATRACE_EVENTS_H_
1449 
1450 #include <stdint.h>
1451 
1452 namespace perfetto {
1453 namespace metatrace {
1454 
1455 enum Tags : uint32_t {
1456   TAG_NONE = 0,
1457   TAG_ANY = uint32_t(-1),
1458   TAG_FTRACE = 1 << 0,
1459   TAG_PROC_POLLERS = 1 << 1,
1460   TAG_TRACE_WRITER = 1 << 2,
1461   TAG_TRACE_SERVICE = 1 << 3,
1462   TAG_PRODUCER = 1 << 4,
1463 };
1464 
1465 // The macros below generate matching enums and arrays of string literals.
1466 // This is to avoid maintaining string maps manually.
1467 
1468 // clang-format off
1469 
1470 // DO NOT remove or reshuffle items in this list, only append. The ID of these
1471 // events are an ABI, the trace processor relies on these to open old traces.
1472 #define PERFETTO_METATRACE_EVENTS(F) \
1473   F(EVENT_ZERO_UNUSED), \
1474   F(FTRACE_CPU_READER_READ), /*unused*/ \
1475   F(FTRACE_DRAIN_CPUS), /*unused*/ \
1476   F(FTRACE_UNBLOCK_READERS), /*unused*/ \
1477   F(FTRACE_CPU_READ_NONBLOCK), /*unused*/ \
1478   F(FTRACE_CPU_READ_BLOCK), /*unused*/ \
1479   F(FTRACE_CPU_SPLICE_NONBLOCK), /*unused*/ \
1480   F(FTRACE_CPU_SPLICE_BLOCK), /*unused*/ \
1481   F(FTRACE_CPU_WAIT_CMD), /*unused*/ \
1482   F(FTRACE_CPU_RUN_CYCLE), /*unused*/ \
1483   F(FTRACE_CPU_FLUSH), \
1484   F(FTRACE_CPU_DRAIN), /*unused*/ \
1485   F(READ_SYS_STATS), \
1486   F(PS_WRITE_ALL_PROCESSES), \
1487   F(PS_ON_PIDS), \
1488   F(PS_ON_RENAME_PIDS), \
1489   F(PS_WRITE_ALL_PROCESS_STATS), \
1490   F(TRACE_WRITER_COMMIT_STARTUP_WRITER_BATCH), \
1491   F(FTRACE_READ_TICK), \
1492   F(FTRACE_CPU_READ_CYCLE), \
1493   F(FTRACE_CPU_READ_BATCH), \
1494   F(KALLSYMS_PARSE), \
1495   F(PROFILER_READ_TICK), \
1496   F(PROFILER_READ_CPU), \
1497   F(PROFILER_UNWIND_TICK), \
1498   F(PROFILER_UNWIND_SAMPLE), \
1499   F(PROFILER_UNWIND_INITIAL_ATTEMPT), \
1500   F(PROFILER_UNWIND_ATTEMPT), \
1501   F(PROFILER_MAPS_PARSE), \
1502   F(PROFILER_MAPS_REPARSE), \
1503   F(PROFILER_UNWIND_CACHE_CLEAR)
1504 
1505 // Append only, see above.
1506 //
1507 // Values that aren't used as counters:
1508 // * FTRACE_SERVICE_COMMIT_DATA is a bit-packed representation of an event, see
1509 //   tracing_service_impl.cc for the format.
1510 // * PROFILER_UNWIND_CURRENT_PID represents the PID that is being unwound.
1511 //
1512 #define PERFETTO_METATRACE_COUNTERS(F) \
1513   F(COUNTER_ZERO_UNUSED),\
1514   F(FTRACE_PAGES_DRAINED), \
1515   F(PS_PIDS_SCANNED), \
1516   F(TRACE_SERVICE_COMMIT_DATA), \
1517   F(PROFILER_UNWIND_QUEUE_SZ), \
1518   F(PROFILER_UNWIND_CURRENT_PID)
1519 
1520 // clang-format on
1521 
1522 #define PERFETTO_METATRACE_IDENTITY(name) name
1523 #define PERFETTO_METATRACE_TOSTRING(name) #name
1524 
1525 enum Events : uint16_t {
1526   PERFETTO_METATRACE_EVENTS(PERFETTO_METATRACE_IDENTITY),
1527   EVENTS_MAX
1528 };
1529 constexpr char const* kEventNames[] = {
1530     PERFETTO_METATRACE_EVENTS(PERFETTO_METATRACE_TOSTRING)};
1531 
1532 enum Counters : uint16_t {
1533   PERFETTO_METATRACE_COUNTERS(PERFETTO_METATRACE_IDENTITY),
1534   COUNTERS_MAX
1535 };
1536 constexpr char const* kCounterNames[] = {
1537     PERFETTO_METATRACE_COUNTERS(PERFETTO_METATRACE_TOSTRING)};
1538 
SuppressUnusedVarsInAmalgamatedBuild()1539 inline void SuppressUnusedVarsInAmalgamatedBuild() {
1540   (void)kCounterNames;
1541   (void)kEventNames;
1542 }
1543 
1544 }  // namespace metatrace
1545 }  // namespace perfetto
1546 
1547 #endif  // INCLUDE_PERFETTO_EXT_BASE_METATRACE_EVENTS_H_
1548 /*
1549  * Copyright (C) 2019 The Android Open Source Project
1550  *
1551  * Licensed under the Apache License, Version 2.0 (the "License");
1552  * you may not use this file except in compliance with the License.
1553  * You may obtain a copy of the License at
1554  *
1555  *      http://www.apache.org/licenses/LICENSE-2.0
1556  *
1557  * Unless required by applicable law or agreed to in writing, software
1558  * distributed under the License is distributed on an "AS IS" BASIS,
1559  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1560  * See the License for the specific language governing permissions and
1561  * limitations under the License.
1562  */
1563 
1564 #ifndef INCLUDE_PERFETTO_EXT_BASE_METATRACE_H_
1565 #define INCLUDE_PERFETTO_EXT_BASE_METATRACE_H_
1566 
1567 #include <array>
1568 #include <atomic>
1569 #include <functional>
1570 #include <string>
1571 
1572 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
1573 // gen_amalgamated expanded: #include "perfetto/base/thread_utils.h"
1574 // gen_amalgamated expanded: #include "perfetto/base/time.h"
1575 // gen_amalgamated expanded: #include "perfetto/ext/base/metatrace_events.h"
1576 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
1577 
1578 // A facility to trace execution of the perfetto codebase itself.
1579 // The meta-tracing framework is organized into three layers:
1580 //
1581 // 1. A static ring-buffer in base/ (this file) that supports concurrent writes
1582 //    and a single reader.
1583 //    The responsibility of this layer is to store events and counters as
1584 //    efficiently as possible without re-entering any tracing code.
1585 //    This is really a static-storage-based ring-buffer based on a POD array.
1586 //    This layer does NOT deal with serializing the meta-trace buffer.
1587 //    It posts a task when it's half full and expects something outside of
1588 //    base/ to drain the ring-buffer and serialize it, eventually writing it
1589 //    into the trace itself, before it gets 100% full.
1590 //
1591 // 2. A class in tracing/core which takes care of serializing the meta-trace
1592 //    buffer into the trace using a TraceWriter. See metatrace_writer.h .
1593 //
1594 // 3. A data source in traced_probes that, when be enabled via the trace config,
1595 //    injects metatrace events into the trace. See metatrace_data_source.h .
1596 //
1597 // The available events and tags are defined in metatrace_events.h .
1598 
1599 namespace perfetto {
1600 
1601 namespace base {
1602 class TaskRunner;
1603 }  // namespace base
1604 
1605 namespace metatrace {
1606 
1607 // Meta-tracing is organized in "tags" that can be selectively enabled. This is
1608 // to enable meta-tracing only of one sub-system. This word has one "enabled"
1609 // bit for each tag. 0 -> meta-tracing off.
1610 extern std::atomic<uint32_t> g_enabled_tags;
1611 
1612 // Time of the Enable() call. Used as a reference for keeping delta timestmaps
1613 // in Record.
1614 extern std::atomic<uint64_t> g_enabled_timestamp;
1615 
1616 // Enables meta-tracing for one or more tags. Once enabled it will discard any
1617 // further Enable() calls and return false until disabled,
1618 // |read_task| is a closure that will be called enqueued |task_runner| when the
1619 // meta-tracing ring buffer is half full. The task is expected to read the ring
1620 // buffer using RingBuffer::GetReadIterator() and serialize the contents onto a
1621 // file or into the trace itself.
1622 // Must be called on the |task_runner| passed.
1623 // |task_runner| must have static lifetime.
1624 bool Enable(std::function<void()> read_task, base::TaskRunner*, uint32_t tags);
1625 
1626 // Disables meta-tracing.
1627 // Must be called on the same |task_runner| as Enable().
1628 void Disable();
1629 
TraceTimeNowNs()1630 inline uint64_t TraceTimeNowNs() {
1631   return static_cast<uint64_t>(base::GetBootTimeNs().count());
1632 }
1633 
1634 // Returns a relaxed view of whether metatracing is enabled for the given tag.
1635 // Useful for skipping unnecessary argument computation if metatracing is off.
IsEnabled(uint32_t tag)1636 inline bool IsEnabled(uint32_t tag) {
1637   auto enabled_tags = g_enabled_tags.load(std::memory_order_relaxed);
1638   return PERFETTO_UNLIKELY((enabled_tags & tag) != 0);
1639 }
1640 
1641 // Holds the data for a metatrace event or counter.
1642 struct Record {
1643   static constexpr uint16_t kTypeMask = 0x8000;
1644   static constexpr uint16_t kTypeCounter = 0x8000;
1645   static constexpr uint16_t kTypeEvent = 0;
1646 
timestamp_nsperfetto::metatrace::Record1647   uint64_t timestamp_ns() const {
1648     auto base_ns = g_enabled_timestamp.load(std::memory_order_relaxed);
1649     PERFETTO_DCHECK(base_ns);
1650     return base_ns + ((static_cast<uint64_t>(timestamp_ns_high) << 32) |
1651                       timestamp_ns_low);
1652   }
1653 
set_timestampperfetto::metatrace::Record1654   void set_timestamp(uint64_t ts) {
1655     auto t_start = g_enabled_timestamp.load(std::memory_order_relaxed);
1656     uint64_t diff = ts - t_start;
1657     PERFETTO_DCHECK(diff < (1ull << 48));
1658     timestamp_ns_low = static_cast<uint32_t>(diff);
1659     timestamp_ns_high = static_cast<uint16_t>(diff >> 32);
1660   }
1661 
1662   // We can't just memset() this class because on MSVC std::atomic<> is not
1663   // trivially constructible anymore. Also std::atomic<> has a deleted copy
1664   // constructor so we cant just do "*this = Record()" either.
1665   // See http://bit.ly/339Jlzd .
clearperfetto::metatrace::Record1666   void clear() {
1667     this->~Record();
1668     new (this) Record();
1669   }
1670 
1671   // This field holds the type (counter vs event) in the MSB and event ID (as
1672   // defined in metatrace_events.h) in the lowest 15 bits. It is also used also
1673   // as a linearization point: this is always written after all the other
1674   // fields with a release-store. This is so the reader can determine whether it
1675   // can safely process the other event fields after a load-acquire.
1676   std::atomic<uint16_t> type_and_id{};
1677 
1678   // Timestamp is stored as a 48-bits value diffed against g_enabled_timestamp.
1679   // This gives us 78 hours from Enabled().
1680   uint16_t timestamp_ns_high = 0;
1681   uint32_t timestamp_ns_low = 0;
1682 
1683   uint32_t thread_id = 0;
1684 
1685   union {
1686     // Only one of the two elements can be zero initialized, clang complains
1687     // about "initializing multiple members of union" otherwise.
1688     uint32_t duration_ns = 0;  // If type == event.
1689     int32_t counter_value;     // If type == counter.
1690   };
1691 };
1692 
1693 // Hold the meta-tracing data into a statically allocated array.
1694 // This class uses static storage (as opposite to being a singleton) to:
1695 // - Have the guarantee of always valid storage, so that meta-tracing can be
1696 //   safely used in any part of the codebase, including base/ itself.
1697 // - Avoid barriers that thread-safe static locals would require.
1698 class RingBuffer {
1699  public:
1700   static constexpr size_t kCapacity = 4096;  // 4096 * 16 bytes = 64K.
1701 
1702   // This iterator is not idempotent and will bump the read index in the buffer
1703   // at the end of the reads. There can be only one reader at any time.
1704   // Usage: for (auto it = RingBuffer::GetReadIterator(); it; ++it) { it->... }
1705   class ReadIterator {
1706    public:
ReadIterator(ReadIterator && other)1707     ReadIterator(ReadIterator&& other) {
1708       PERFETTO_DCHECK(other.valid_);
1709       cur_ = other.cur_;
1710       end_ = other.end_;
1711       valid_ = other.valid_;
1712       other.valid_ = false;
1713     }
1714 
~ReadIterator()1715     ~ReadIterator() {
1716       if (!valid_)
1717         return;
1718       PERFETTO_DCHECK(cur_ >= RingBuffer::rd_index_);
1719       PERFETTO_DCHECK(cur_ <= RingBuffer::wr_index_);
1720       RingBuffer::rd_index_.store(cur_, std::memory_order_release);
1721     }
1722 
operator bool() const1723     explicit operator bool() const { return cur_ < end_; }
operator ->() const1724     const Record* operator->() const { return RingBuffer::At(cur_); }
operator *() const1725     const Record& operator*() const { return *operator->(); }
1726 
1727     // This is for ++it. it++ is deliberately not supported.
operator ++()1728     ReadIterator& operator++() {
1729       PERFETTO_DCHECK(cur_ < end_);
1730       // Once a record has been read, mark it as free clearing its type_and_id,
1731       // so if we encounter it in another read iteration while being written
1732       // we know it's not fully written yet.
1733       // The memory_order_relaxed below is enough because:
1734       // - The reader is single-threaded and doesn't re-read the same records.
1735       // - Before starting a read batch, the reader has an acquire barrier on
1736       //   |rd_index_|.
1737       // - After terminating a read batch, the ~ReadIterator dtor updates the
1738       //   |rd_index_| with a release-store.
1739       // - Reader and writer are typically kCapacity/2 apart. So unless an
1740       //   overrun happens a writer won't reuse a newly released record any time
1741       //   soon. If an overrun happens, everything is busted regardless.
1742       At(cur_)->type_and_id.store(0, std::memory_order_relaxed);
1743       ++cur_;
1744       return *this;
1745     }
1746 
1747    private:
1748     friend class RingBuffer;
ReadIterator(uint64_t begin,uint64_t end)1749     ReadIterator(uint64_t begin, uint64_t end)
1750         : cur_(begin), end_(end), valid_(true) {}
1751     ReadIterator& operator=(const ReadIterator&) = delete;
1752     ReadIterator(const ReadIterator&) = delete;
1753 
1754     uint64_t cur_;
1755     uint64_t end_;
1756     bool valid_;
1757   };
1758 
At(uint64_t index)1759   static Record* At(uint64_t index) {
1760     // Doesn't really have to be pow2, but if not the compiler will emit
1761     // arithmetic operations to compute the modulo instead of a bitwise AND.
1762     static_assert(!(kCapacity & (kCapacity - 1)), "kCapacity must be pow2");
1763     PERFETTO_DCHECK(index >= rd_index_);
1764     PERFETTO_DCHECK(index <= wr_index_);
1765     return &records_[index % kCapacity];
1766   }
1767 
1768   // Must be called on the same task runner passed to Enable()
GetReadIterator()1769   static ReadIterator GetReadIterator() {
1770     PERFETTO_DCHECK(RingBuffer::IsOnValidTaskRunner());
1771     return ReadIterator(rd_index_.load(std::memory_order_acquire),
1772                         wr_index_.load(std::memory_order_acquire));
1773   }
1774 
1775   static Record* AppendNewRecord();
1776   static void Reset();
1777 
has_overruns()1778   static bool has_overruns() {
1779     return has_overruns_.load(std::memory_order_acquire);
1780   }
1781 
1782   // Can temporarily return a value >= kCapacity but is eventually consistent.
1783   // This would happen in case of overruns until threads hit the --wr_index_
1784   // in AppendNewRecord().
GetSizeForTesting()1785   static uint64_t GetSizeForTesting() {
1786     auto wr_index = wr_index_.load(std::memory_order_relaxed);
1787     auto rd_index = rd_index_.load(std::memory_order_relaxed);
1788     PERFETTO_DCHECK(wr_index >= rd_index);
1789     return wr_index - rd_index;
1790   }
1791 
1792  private:
1793   friend class ReadIterator;
1794 
1795   // Returns true if the caller is on the task runner passed to Enable().
1796   // Used only for DCHECKs.
1797   static bool IsOnValidTaskRunner();
1798 
1799   static std::array<Record, kCapacity> records_;
1800   static std::atomic<bool> read_task_queued_;
1801   static std::atomic<uint64_t> wr_index_;
1802   static std::atomic<uint64_t> rd_index_;
1803   static std::atomic<bool> has_overruns_;
1804   static Record bankruptcy_record_;  // Used in case of overruns.
1805 };
1806 
TraceCounter(uint32_t tag,uint16_t id,int32_t value)1807 inline void TraceCounter(uint32_t tag, uint16_t id, int32_t value) {
1808   // memory_order_relaxed is okay because the storage has static lifetime.
1809   // It is safe to accidentally log an event soon after disabling.
1810   auto enabled_tags = g_enabled_tags.load(std::memory_order_relaxed);
1811   if (PERFETTO_LIKELY((enabled_tags & tag) == 0))
1812     return;
1813   Record* record = RingBuffer::AppendNewRecord();
1814   record->thread_id = static_cast<uint32_t>(base::GetThreadId());
1815   record->set_timestamp(TraceTimeNowNs());
1816   record->counter_value = value;
1817   record->type_and_id.store(Record::kTypeCounter | id,
1818                             std::memory_order_release);
1819 }
1820 
1821 class ScopedEvent {
1822  public:
ScopedEvent(uint32_t tag,uint16_t event_id)1823   ScopedEvent(uint32_t tag, uint16_t event_id) {
1824     auto enabled_tags = g_enabled_tags.load(std::memory_order_relaxed);
1825     if (PERFETTO_LIKELY((enabled_tags & tag) == 0))
1826       return;
1827     event_id_ = event_id;
1828     record_ = RingBuffer::AppendNewRecord();
1829     record_->thread_id = static_cast<uint32_t>(base::GetThreadId());
1830     record_->set_timestamp(TraceTimeNowNs());
1831   }
1832 
~ScopedEvent()1833   ~ScopedEvent() {
1834     if (PERFETTO_LIKELY(!record_))
1835       return;
1836     auto now = TraceTimeNowNs();
1837     record_->duration_ns = static_cast<uint32_t>(now - record_->timestamp_ns());
1838     record_->type_and_id.store(Record::kTypeEvent | event_id_,
1839                                std::memory_order_release);
1840   }
1841 
1842  private:
1843   Record* record_ = nullptr;
1844   uint16_t event_id_ = 0;
1845   ScopedEvent(const ScopedEvent&) = delete;
1846   ScopedEvent& operator=(const ScopedEvent&) = delete;
1847 };
1848 
1849 // Boilerplate to derive a unique variable name for the event.
1850 #define PERFETTO_METATRACE_UID2(a, b) a##b
1851 #define PERFETTO_METATRACE_UID(x) PERFETTO_METATRACE_UID2(metatrace_, x)
1852 
1853 #define PERFETTO_METATRACE_SCOPED(TAG, ID)                                \
1854   ::perfetto::metatrace::ScopedEvent PERFETTO_METATRACE_UID(__COUNTER__)( \
1855       ::perfetto::metatrace::TAG, ::perfetto::metatrace::ID)
1856 
1857 #define PERFETTO_METATRACE_COUNTER(TAG, ID, VALUE)                \
1858   ::perfetto::metatrace::TraceCounter(::perfetto::metatrace::TAG, \
1859                                       ::perfetto::metatrace::ID,  \
1860                                       static_cast<int32_t>(VALUE))
1861 
1862 }  // namespace metatrace
1863 }  // namespace perfetto
1864 
1865 #endif  // INCLUDE_PERFETTO_EXT_BASE_METATRACE_H_
1866 // gen_amalgamated begin header: include/perfetto/base/task_runner.h
1867 /*
1868  * Copyright (C) 2017 The Android Open Source Project
1869  *
1870  * Licensed under the Apache License, Version 2.0 (the "License");
1871  * you may not use this file except in compliance with the License.
1872  * You may obtain a copy of the License at
1873  *
1874  *      http://www.apache.org/licenses/LICENSE-2.0
1875  *
1876  * Unless required by applicable law or agreed to in writing, software
1877  * distributed under the License is distributed on an "AS IS" BASIS,
1878  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1879  * See the License for the specific language governing permissions and
1880  * limitations under the License.
1881  */
1882 
1883 #ifndef INCLUDE_PERFETTO_BASE_TASK_RUNNER_H_
1884 #define INCLUDE_PERFETTO_BASE_TASK_RUNNER_H_
1885 
1886 #include <stdint.h>
1887 
1888 #include <functional>
1889 
1890 // gen_amalgamated expanded: #include "perfetto/base/export.h"
1891 // gen_amalgamated expanded: #include "perfetto/base/platform_handle.h"
1892 
1893 namespace perfetto {
1894 namespace base {
1895 
1896 // A generic interface to allow the library clients to interleave the execution
1897 // of the tracing internals in their runtime environment.
1898 // The expectation is that all tasks, which are queued either via PostTask() or
1899 // AddFileDescriptorWatch(), are executed on the same sequence (either on the
1900 // same thread, or on a thread pool that gives sequencing guarantees).
1901 //
1902 // Tasks are never executed synchronously inside PostTask and there is a full
1903 // memory barrier between tasks.
1904 //
1905 // All methods of this interface can be called from any thread.
1906 class PERFETTO_EXPORT TaskRunner {
1907  public:
1908   virtual ~TaskRunner();
1909 
1910   // Schedule a task for immediate execution. Immediate tasks are always
1911   // executed in the order they are posted. Can be called from any thread.
1912   virtual void PostTask(std::function<void()>) = 0;
1913 
1914   // Schedule a task for execution after |delay_ms|. Note that there is no
1915   // strict ordering guarantee between immediate and delayed tasks. Can be
1916   // called from any thread.
1917   virtual void PostDelayedTask(std::function<void()>, uint32_t delay_ms) = 0;
1918 
1919   // Schedule a task to run when the handle becomes readable. The same handle
1920   // can only be monitored by one function. Note that this function only needs
1921   // to be implemented on platforms where the built-in ipc framework is used.
1922   // Can be called from any thread.
1923   // TODO(skyostil): Refactor this out of the shared interface.
1924   virtual void AddFileDescriptorWatch(PlatformHandle,
1925                                       std::function<void()>) = 0;
1926 
1927   // Remove a previously scheduled watch for the handle. If this is run on the
1928   // target thread of this TaskRunner, guarantees that the task registered to
1929   // this handle will not be executed after this function call.
1930   // Can be called from any thread.
1931   virtual void RemoveFileDescriptorWatch(PlatformHandle) = 0;
1932 
1933   // Checks if the current thread is the same thread where the TaskRunner's task
1934   // run. This allows single threaded task runners (like the ones used in
1935   // perfetto) to inform the caller that anything posted will run on the same
1936   // thread/sequence. This can allow some callers to skip PostTask and instead
1937   // directly execute the code. Can be called from any thread.
1938   virtual bool RunsTasksOnCurrentThread() const = 0;
1939 };
1940 
1941 }  // namespace base
1942 }  // namespace perfetto
1943 
1944 #endif  // INCLUDE_PERFETTO_BASE_TASK_RUNNER_H_
1945 // gen_amalgamated begin header: include/perfetto/ext/base/thread_annotations.h
1946 /*
1947  * Copyright (C) 2019 The Android Open Source Project
1948  *
1949  * Licensed under the Apache License, Version 2.0 (the "License");
1950  * you may not use this file except in compliance with the License.
1951  * You may obtain a copy of the License at
1952  *
1953  *      http://www.apache.org/licenses/LICENSE-2.0
1954  *
1955  * Unless required by applicable law or agreed to in writing, software
1956  * distributed under the License is distributed on an "AS IS" BASIS,
1957  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1958  * See the License for the specific language governing permissions and
1959  * limitations under the License.
1960  */
1961 
1962 #ifndef INCLUDE_PERFETTO_EXT_BASE_THREAD_ANNOTATIONS_H_
1963 #define INCLUDE_PERFETTO_EXT_BASE_THREAD_ANNOTATIONS_H_
1964 
1965 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
1966 
1967 // Windows TSAN doesn't currently support these annotations.
1968 #if defined(THREAD_SANITIZER) && !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
1969 extern "C" {
1970 void AnnotateBenignRaceSized(const char* file,
1971                              int line,
1972                              unsigned long address,
1973                              unsigned long size,
1974                              const char* description);
1975 }
1976 
1977 #define PERFETTO_ANNOTATE_BENIGN_RACE_SIZED(pointer, size, description)   \
1978   AnnotateBenignRaceSized(__FILE__, __LINE__,                             \
1979                           reinterpret_cast<unsigned long>(pointer), size, \
1980                           description);
1981 #else  // defined(ADDRESS_SANITIZER)
1982 #define PERFETTO_ANNOTATE_BENIGN_RACE_SIZED(pointer, size, description)
1983 #endif  // defined(ADDRESS_SANITIZER)
1984 
1985 #endif  // INCLUDE_PERFETTO_EXT_BASE_THREAD_ANNOTATIONS_H_
1986 /*
1987  * Copyright (C) 2018 The Android Open Source Project
1988  *
1989  * Licensed under the Apache License, Version 2.0 (the "License");
1990  * you may not use this file except in compliance with the License.
1991  * You may obtain a copy of the License at
1992  *
1993  *      http://www.apache.org/licenses/LICENSE-2.0
1994  *
1995  * Unless required by applicable law or agreed to in writing, software
1996  * distributed under the License is distributed on an "AS IS" BASIS,
1997  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1998  * See the License for the specific language governing permissions and
1999  * limitations under the License.
2000  */
2001 
2002 // gen_amalgamated expanded: #include "perfetto/ext/base/metatrace.h"
2003 
2004 // gen_amalgamated expanded: #include "perfetto/base/compiler.h"
2005 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
2006 // gen_amalgamated expanded: #include "perfetto/base/time.h"
2007 // gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
2008 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_annotations.h"
2009 
2010 namespace perfetto {
2011 namespace metatrace {
2012 
2013 std::atomic<uint32_t> g_enabled_tags{0};
2014 std::atomic<uint64_t> g_enabled_timestamp{0};
2015 
2016 // static members
2017 constexpr size_t RingBuffer::kCapacity;
2018 std::array<Record, RingBuffer::kCapacity> RingBuffer::records_;
2019 std::atomic<bool> RingBuffer::read_task_queued_;
2020 std::atomic<uint64_t> RingBuffer::wr_index_;
2021 std::atomic<uint64_t> RingBuffer::rd_index_;
2022 std::atomic<bool> RingBuffer::has_overruns_;
2023 Record RingBuffer::bankruptcy_record_;
2024 
2025 constexpr uint16_t Record::kTypeMask;
2026 constexpr uint16_t Record::kTypeCounter;
2027 constexpr uint16_t Record::kTypeEvent;
2028 
2029 namespace {
2030 
2031 // std::function<> is not trivially de/constructible. This struct wraps it in a
2032 // heap-allocated struct to avoid static initializers.
2033 struct Delegate {
GetInstanceperfetto::metatrace::__anon2fbee8800911::Delegate2034   static Delegate* GetInstance() {
2035     static Delegate* instance = new Delegate();
2036     return instance;
2037   }
2038 
2039   base::TaskRunner* task_runner = nullptr;
2040   std::function<void()> read_task;
2041 };
2042 
2043 }  // namespace
2044 
Enable(std::function<void ()> read_task,base::TaskRunner * task_runner,uint32_t tags)2045 bool Enable(std::function<void()> read_task,
2046             base::TaskRunner* task_runner,
2047             uint32_t tags) {
2048   PERFETTO_DCHECK(read_task);
2049   PERFETTO_DCHECK(task_runner->RunsTasksOnCurrentThread());
2050   if (g_enabled_tags.load(std::memory_order_acquire))
2051     return false;
2052 
2053   Delegate* dg = Delegate::GetInstance();
2054   dg->task_runner = task_runner;
2055   dg->read_task = std::move(read_task);
2056   RingBuffer::Reset();
2057   g_enabled_timestamp.store(TraceTimeNowNs(), std::memory_order_relaxed);
2058   g_enabled_tags.store(tags, std::memory_order_release);
2059   return true;
2060 }
2061 
Disable()2062 void Disable() {
2063   g_enabled_tags.store(0, std::memory_order_release);
2064   Delegate* dg = Delegate::GetInstance();
2065   PERFETTO_DCHECK(!dg->task_runner ||
2066                   dg->task_runner->RunsTasksOnCurrentThread());
2067   dg->task_runner = nullptr;
2068   dg->read_task = nullptr;
2069 }
2070 
2071 // static
Reset()2072 void RingBuffer::Reset() {
2073   bankruptcy_record_.clear();
2074   for (Record& record : records_)
2075     record.clear();
2076   wr_index_ = 0;
2077   rd_index_ = 0;
2078   has_overruns_ = false;
2079   read_task_queued_ = false;
2080 }
2081 
2082 // static
AppendNewRecord()2083 Record* RingBuffer::AppendNewRecord() {
2084   auto wr_index = wr_index_.fetch_add(1, std::memory_order_acq_rel);
2085 
2086   // rd_index can only monotonically increase, we don't care if we read an
2087   // older value, we'll just hit the slow-path a bit earlier if it happens.
2088   auto rd_index = rd_index_.load(std::memory_order_relaxed);
2089 
2090   PERFETTO_DCHECK(wr_index >= rd_index);
2091   auto size = wr_index - rd_index;
2092   if (PERFETTO_LIKELY(size < kCapacity / 2))
2093     return At(wr_index);
2094 
2095   // Slow-path: Enqueue the read task and handle overruns.
2096   bool expected = false;
2097   if (RingBuffer::read_task_queued_.compare_exchange_strong(expected, true)) {
2098     Delegate* dg = Delegate::GetInstance();
2099     if (dg->task_runner) {
2100       dg->task_runner->PostTask([] {
2101         // Meta-tracing might have been disabled in the meantime.
2102         auto read_task = Delegate::GetInstance()->read_task;
2103         if (read_task)
2104           read_task();
2105         RingBuffer::read_task_queued_ = false;
2106       });
2107     }
2108   }
2109 
2110   if (PERFETTO_LIKELY(size < kCapacity))
2111     return At(wr_index);
2112 
2113   has_overruns_.store(true, std::memory_order_release);
2114   wr_index_.fetch_sub(1, std::memory_order_acq_rel);
2115 
2116   // In the case of overflows, threads will race writing on the same memory
2117   // location and TSan will rightly complain. This is fine though because nobody
2118   // will read the bankruptcy record and it's designed to contain garbage.
2119   PERFETTO_ANNOTATE_BENIGN_RACE_SIZED(&bankruptcy_record_, sizeof(Record),
2120                                       "nothing reads bankruptcy_record_")
2121   return &bankruptcy_record_;
2122 }
2123 
2124 // static
IsOnValidTaskRunner()2125 bool RingBuffer::IsOnValidTaskRunner() {
2126   auto* task_runner = Delegate::GetInstance()->task_runner;
2127   return task_runner && task_runner->RunsTasksOnCurrentThread();
2128 }
2129 
2130 }  // namespace metatrace
2131 }  // namespace perfetto
2132 // gen_amalgamated begin source: src/base/paged_memory.cc
2133 // gen_amalgamated begin header: include/perfetto/ext/base/paged_memory.h
2134 // gen_amalgamated begin header: include/perfetto/ext/base/container_annotations.h
2135 /*
2136  * Copyright (C) 2018 The Android Open Source Project
2137  *
2138  * Licensed under the Apache License, Version 2.0 (the "License");
2139  * you may not use this file except in compliance with the License.
2140  * You may obtain a copy of the License at
2141  *
2142  *      http://www.apache.org/licenses/LICENSE-2.0
2143  *
2144  * Unless required by applicable law or agreed to in writing, software
2145  * distributed under the License is distributed on an "AS IS" BASIS,
2146  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2147  * See the License for the specific language governing permissions and
2148  * limitations under the License.
2149  */
2150 
2151 #ifndef INCLUDE_PERFETTO_EXT_BASE_CONTAINER_ANNOTATIONS_H_
2152 #define INCLUDE_PERFETTO_EXT_BASE_CONTAINER_ANNOTATIONS_H_
2153 
2154 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
2155 
2156 // Windows ASAN doesn't currently support these annotations.
2157 #if defined(ADDRESS_SANITIZER) && !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) && \
2158     !defined(ADDRESS_SANITIZER_WITHOUT_INSTRUMENTATION)
2159 
2160 #define ANNOTATE_NEW_BUFFER(buffer, capacity, new_size)                      \
2161   if (buffer) {                                                              \
2162     __sanitizer_annotate_contiguous_container(buffer, (buffer) + (capacity), \
2163                                               (buffer) + (capacity),         \
2164                                               (buffer) + (new_size));        \
2165   }
2166 #define ANNOTATE_DELETE_BUFFER(buffer, capacity, old_size)                   \
2167   if (buffer) {                                                              \
2168     __sanitizer_annotate_contiguous_container(buffer, (buffer) + (capacity), \
2169                                               (buffer) + (old_size),         \
2170                                               (buffer) + (capacity));        \
2171   }
2172 #define ANNOTATE_CHANGE_SIZE(buffer, capacity, old_size, new_size)           \
2173   if (buffer) {                                                              \
2174     __sanitizer_annotate_contiguous_container(buffer, (buffer) + (capacity), \
2175                                               (buffer) + (old_size),         \
2176                                               (buffer) + (new_size));        \
2177   }
2178 #define ANNOTATE_CHANGE_CAPACITY(buffer, old_capacity, buffer_size, \
2179                                  new_capacity)                      \
2180   ANNOTATE_DELETE_BUFFER(buffer, old_capacity, buffer_size);        \
2181   ANNOTATE_NEW_BUFFER(buffer, new_capacity, buffer_size);
2182 // Annotations require buffers to begin on an 8-byte boundary.
2183 #else  // defined(ADDRESS_SANITIZER)
2184 #define ANNOTATE_NEW_BUFFER(buffer, capacity, new_size)
2185 #define ANNOTATE_DELETE_BUFFER(buffer, capacity, old_size)
2186 #define ANNOTATE_CHANGE_SIZE(buffer, capacity, old_size, new_size)
2187 #define ANNOTATE_CHANGE_CAPACITY(buffer, old_capacity, buffer_size, \
2188                                  new_capacity)
2189 #endif  // defined(ADDRESS_SANITIZER)
2190 
2191 #endif  // INCLUDE_PERFETTO_EXT_BASE_CONTAINER_ANNOTATIONS_H_
2192 /*
2193  * Copyright (C) 2017 The Android Open Source Project
2194  *
2195  * Licensed under the Apache License, Version 2.0 (the "License");
2196  * you may not use this file except in compliance with the License.
2197  * You may obtain a copy of the License at
2198  *
2199  *      http://www.apache.org/licenses/LICENSE-2.0
2200  *
2201  * Unless required by applicable law or agreed to in writing, software
2202  * distributed under the License is distributed on an "AS IS" BASIS,
2203  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2204  * See the License for the specific language governing permissions and
2205  * limitations under the License.
2206  */
2207 
2208 #ifndef INCLUDE_PERFETTO_EXT_BASE_PAGED_MEMORY_H_
2209 #define INCLUDE_PERFETTO_EXT_BASE_PAGED_MEMORY_H_
2210 
2211 #include <memory>
2212 
2213 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
2214 // gen_amalgamated expanded: #include "perfetto/ext/base/container_annotations.h"
2215 
2216 // We need to track the committed size on windows and when ASAN is enabled.
2217 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) || defined(ADDRESS_SANITIZER)
2218 #define TRACK_COMMITTED_SIZE() 1
2219 #else
2220 #define TRACK_COMMITTED_SIZE() 0
2221 #endif
2222 
2223 namespace perfetto {
2224 namespace base {
2225 
2226 class PagedMemory {
2227  public:
2228   // Initializes an invalid PagedMemory pointing to nullptr.
2229   PagedMemory();
2230 
2231   ~PagedMemory();
2232 
2233   PagedMemory(PagedMemory&& other) noexcept;
2234   PagedMemory& operator=(PagedMemory&& other);
2235 
2236   enum AllocationFlags {
2237     // By default, Allocate() crashes if the underlying mmap fails (e.g., if out
2238     // of virtual address space). When this flag is provided, an invalid
2239     // PagedMemory pointing to nullptr is returned in this case instead.
2240     kMayFail = 1 << 0,
2241 
2242     // By default, Allocate() commits the allocated memory immediately. When
2243     // this flag is provided, the memory virtual address space may only be
2244     // reserved and the user should call EnsureCommitted() before writing to
2245     // memory addresses.
2246     kDontCommit = 1 << 1,
2247   };
2248 
2249   // Allocates |size| bytes using mmap(MAP_ANONYMOUS). The returned memory is
2250   // guaranteed to be page-aligned and guaranteed to be zeroed.
2251   // For |flags|, see the AllocationFlags enum above.
2252   static PagedMemory Allocate(size_t size, int flags = 0);
2253 
2254   // Hint to the OS that the memory range is not needed and can be discarded.
2255   // The memory remains accessible and its contents may be retained, or they
2256   // may be zeroed. This function may be a NOP on some platforms. Returns true
2257   // if implemented.
2258   bool AdviseDontNeed(void* p, size_t size);
2259 
2260   // Ensures that at least the first |committed_size| bytes of the allocated
2261   // memory region are committed. The implementation may commit memory in larger
2262   // chunks above |committed_size|. Crashes if the memory couldn't be committed.
2263 #if TRACK_COMMITTED_SIZE()
2264   void EnsureCommitted(size_t committed_size);
2265 #else   // TRACK_COMMITTED_SIZE()
EnsureCommitted(size_t)2266   void EnsureCommitted(size_t /*committed_size*/) {}
2267 #endif  // TRACK_COMMITTED_SIZE()
2268 
Get() const2269   inline void* Get() const noexcept { return p_; }
IsValid() const2270   inline bool IsValid() const noexcept { return !!p_; }
size() const2271   inline size_t size() const noexcept { return size_; }
2272 
2273  private:
2274   PagedMemory(char* p, size_t size);
2275 
2276   PagedMemory(const PagedMemory&) = delete;
2277   // Defaulted for implementation of move constructor + assignment.
2278   PagedMemory& operator=(const PagedMemory&) = default;
2279 
2280   char* p_ = nullptr;
2281 
2282   // The size originally passed to Allocate(). The actual virtual memory
2283   // reservation will be larger due to: (i) guard pages; (ii) rounding up to
2284   // the system page size.
2285   size_t size_ = 0;
2286 
2287 #if TRACK_COMMITTED_SIZE()
2288   size_t committed_size_ = 0u;
2289 #endif  // TRACK_COMMITTED_SIZE()
2290 };
2291 
2292 }  // namespace base
2293 }  // namespace perfetto
2294 
2295 #endif  // INCLUDE_PERFETTO_EXT_BASE_PAGED_MEMORY_H_
2296 /*
2297  * Copyright (C) 2017 The Android Open Source Project
2298  *
2299  * Licensed under the Apache License, Version 2.0 (the "License");
2300  * you may not use this file except in compliance with the License.
2301  * You may obtain a copy of the License at
2302  *
2303  *      http://www.apache.org/licenses/LICENSE-2.0
2304  *
2305  * Unless required by applicable law or agreed to in writing, software
2306  * distributed under the License is distributed on an "AS IS" BASIS,
2307  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2308  * See the License for the specific language governing permissions and
2309  * limitations under the License.
2310  */
2311 
2312 // gen_amalgamated expanded: #include "perfetto/ext/base/paged_memory.h"
2313 
2314 #include <algorithm>
2315 #include <cmath>
2316 
2317 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
2318 #include <Windows.h>
2319 #else  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
2320 #include <sys/mman.h>
2321 #endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
2322 
2323 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
2324 // gen_amalgamated expanded: #include "perfetto/ext/base/container_annotations.h"
2325 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
2326 
2327 namespace perfetto {
2328 namespace base {
2329 
2330 namespace {
2331 
2332 #if TRACK_COMMITTED_SIZE()
2333 constexpr size_t kCommitChunkSize = 4 * 1024 * 1024;  // 4MB
2334 #endif
2335 
RoundUpToSysPageSize(size_t req_size)2336 size_t RoundUpToSysPageSize(size_t req_size) {
2337   const size_t page_size = GetSysPageSize();
2338   return (req_size + page_size - 1) & ~(page_size - 1);
2339 }
2340 
GuardSize()2341 size_t GuardSize() {
2342   return GetSysPageSize();
2343 }
2344 
2345 }  // namespace
2346 
2347 // static
Allocate(size_t req_size,int flags)2348 PagedMemory PagedMemory::Allocate(size_t req_size, int flags) {
2349   size_t rounded_up_size = RoundUpToSysPageSize(req_size);
2350   PERFETTO_CHECK(rounded_up_size >= req_size);
2351   size_t outer_size = rounded_up_size + GuardSize() * 2;
2352 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
2353   void* ptr = VirtualAlloc(nullptr, outer_size, MEM_RESERVE, PAGE_NOACCESS);
2354   if (!ptr && (flags & kMayFail))
2355     return PagedMemory();
2356   PERFETTO_CHECK(ptr);
2357   char* usable_region = reinterpret_cast<char*>(ptr) + GuardSize();
2358 #else   // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
2359   void* ptr = mmap(nullptr, outer_size, PROT_READ | PROT_WRITE,
2360                    MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
2361   if (ptr == MAP_FAILED && (flags & kMayFail))
2362     return PagedMemory();
2363   PERFETTO_CHECK(ptr && ptr != MAP_FAILED);
2364   char* usable_region = reinterpret_cast<char*>(ptr) + GuardSize();
2365   int res = mprotect(ptr, GuardSize(), PROT_NONE);
2366   res |= mprotect(usable_region + rounded_up_size, GuardSize(), PROT_NONE);
2367   PERFETTO_CHECK(res == 0);
2368 #endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
2369 
2370   auto memory = PagedMemory(usable_region, req_size);
2371 #if TRACK_COMMITTED_SIZE()
2372   size_t initial_commit = req_size;
2373   if (flags & kDontCommit)
2374     initial_commit = std::min(initial_commit, kCommitChunkSize);
2375   memory.EnsureCommitted(initial_commit);
2376 #endif  // TRACK_COMMITTED_SIZE()
2377   return memory;
2378 }
2379 
PagedMemory()2380 PagedMemory::PagedMemory() {}
2381 
2382 // clang-format off
PagedMemory(char * p,size_t size)2383 PagedMemory::PagedMemory(char* p, size_t size) : p_(p), size_(size) {
2384   ANNOTATE_NEW_BUFFER(p_, size_, committed_size_)
2385 }
2386 
PagedMemory(PagedMemory && other)2387 PagedMemory::PagedMemory(PagedMemory&& other) noexcept {
2388   *this = other;
2389   other.p_ = nullptr;
2390 }
2391 // clang-format on
2392 
operator =(PagedMemory && other)2393 PagedMemory& PagedMemory::operator=(PagedMemory&& other) {
2394   this->~PagedMemory();
2395   new (this) PagedMemory(std::move(other));
2396   return *this;
2397 }
2398 
~PagedMemory()2399 PagedMemory::~PagedMemory() {
2400   if (!p_)
2401     return;
2402   PERFETTO_CHECK(size_);
2403   char* start = p_ - GuardSize();
2404 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
2405   BOOL res = VirtualFree(start, 0, MEM_RELEASE);
2406   PERFETTO_CHECK(res != 0);
2407 #else   // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
2408   const size_t outer_size = RoundUpToSysPageSize(size_) + GuardSize() * 2;
2409   int res = munmap(start, outer_size);
2410   PERFETTO_CHECK(res == 0);
2411 #endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
2412   ANNOTATE_DELETE_BUFFER(p_, size_, committed_size_)
2413 }
2414 
AdviseDontNeed(void * p,size_t size)2415 bool PagedMemory::AdviseDontNeed(void* p, size_t size) {
2416   PERFETTO_DCHECK(p_);
2417   PERFETTO_DCHECK(p >= p_);
2418   PERFETTO_DCHECK(static_cast<char*>(p) + size <= p_ + size_);
2419 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) || PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
2420   // Discarding pages on Windows has more CPU cost than is justified for the
2421   // possible memory savings.
2422   return false;
2423 #else   // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) ||
2424         // PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
2425   // http://man7.org/linux/man-pages/man2/madvise.2.html
2426   int res = madvise(p, size, MADV_DONTNEED);
2427   PERFETTO_DCHECK(res == 0);
2428   return true;
2429 #endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) ||
2430         // PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
2431 }
2432 
2433 #if TRACK_COMMITTED_SIZE()
EnsureCommitted(size_t committed_size)2434 void PagedMemory::EnsureCommitted(size_t committed_size) {
2435   PERFETTO_DCHECK(committed_size > 0u);
2436   PERFETTO_DCHECK(committed_size <= size_);
2437 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
2438   if (committed_size_ >= committed_size)
2439     return;
2440   // Rounding up.
2441   size_t delta = committed_size - committed_size_;
2442   size_t num_additional_chunks =
2443       (delta + kCommitChunkSize - 1) / kCommitChunkSize;
2444   PERFETTO_DCHECK(num_additional_chunks * kCommitChunkSize >= delta);
2445   // Don't commit more than the total size.
2446   size_t commit_size = std::min(num_additional_chunks * kCommitChunkSize,
2447                                 size_ - committed_size_);
2448   void* res = VirtualAlloc(p_ + committed_size_, commit_size, MEM_COMMIT,
2449                            PAGE_READWRITE);
2450   PERFETTO_CHECK(res);
2451   ANNOTATE_CHANGE_SIZE(p_, size_, committed_size_,
2452                        committed_size_ + commit_size)
2453   committed_size_ += commit_size;
2454 #else   // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
2455   // mmap commits automatically as needed, so we only track here for ASAN.
2456   committed_size = std::max(committed_size_, committed_size);
2457   ANNOTATE_CHANGE_SIZE(p_, size_, committed_size_, committed_size)
2458   committed_size_ = committed_size;
2459 #endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
2460 }
2461 #endif  // TRACK_COMMITTED_SIZE()
2462 
2463 }  // namespace base
2464 }  // namespace perfetto
2465 // gen_amalgamated begin source: src/base/periodic_task.cc
2466 // gen_amalgamated begin header: include/perfetto/ext/base/periodic_task.h
2467 // gen_amalgamated begin header: include/perfetto/ext/base/thread_checker.h
2468 /*
2469  * Copyright (C) 2017 The Android Open Source Project
2470  *
2471  * Licensed under the Apache License, Version 2.0 (the "License");
2472  * you may not use this file except in compliance with the License.
2473  * You may obtain a copy of the License at
2474  *
2475  *      http://www.apache.org/licenses/LICENSE-2.0
2476  *
2477  * Unless required by applicable law or agreed to in writing, software
2478  * distributed under the License is distributed on an "AS IS" BASIS,
2479  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2480  * See the License for the specific language governing permissions and
2481  * limitations under the License.
2482  */
2483 
2484 #ifndef INCLUDE_PERFETTO_EXT_BASE_THREAD_CHECKER_H_
2485 #define INCLUDE_PERFETTO_EXT_BASE_THREAD_CHECKER_H_
2486 
2487 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
2488 
2489 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
2490 #include <pthread.h>
2491 #endif
2492 #include <atomic>
2493 
2494 // gen_amalgamated expanded: #include "perfetto/base/export.h"
2495 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
2496 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
2497 
2498 namespace perfetto {
2499 namespace base {
2500 
2501 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
2502 using ThreadID = unsigned long;
2503 #else
2504 using ThreadID = pthread_t;
2505 #endif
2506 
2507 class PERFETTO_EXPORT ThreadChecker {
2508  public:
2509   ThreadChecker();
2510   ~ThreadChecker();
2511   ThreadChecker(const ThreadChecker&);
2512   ThreadChecker& operator=(const ThreadChecker&);
2513   bool CalledOnValidThread() const PERFETTO_WARN_UNUSED_RESULT;
2514   void DetachFromThread();
2515 
2516  private:
2517   mutable std::atomic<ThreadID> thread_id_;
2518 };
2519 
2520 #if PERFETTO_DCHECK_IS_ON() && !PERFETTO_BUILDFLAG(PERFETTO_CHROMIUM_BUILD)
2521 // TODO(primiano) Use Chromium's thread checker in Chromium.
2522 #define PERFETTO_THREAD_CHECKER(name) base::ThreadChecker name;
2523 #define PERFETTO_DCHECK_THREAD(name) \
2524   PERFETTO_DCHECK((name).CalledOnValidThread())
2525 #define PERFETTO_DETACH_FROM_THREAD(name) (name).DetachFromThread()
2526 #else
2527 #define PERFETTO_THREAD_CHECKER(name)
2528 #define PERFETTO_DCHECK_THREAD(name)
2529 #define PERFETTO_DETACH_FROM_THREAD(name)
2530 #endif  // PERFETTO_DCHECK_IS_ON()
2531 
2532 }  // namespace base
2533 }  // namespace perfetto
2534 
2535 #endif  // INCLUDE_PERFETTO_EXT_BASE_THREAD_CHECKER_H_
2536 // gen_amalgamated begin header: include/perfetto/ext/base/weak_ptr.h
2537 /*
2538  * Copyright (C) 2017 The Android Open Source Project
2539  *
2540  * Licensed under the Apache License, Version 2.0 (the "License");
2541  * you may not use this file except in compliance with the License.
2542  * You may obtain a copy of the License at
2543  *
2544  *      http://www.apache.org/licenses/LICENSE-2.0
2545  *
2546  * Unless required by applicable law or agreed to in writing, software
2547  * distributed under the License is distributed on an "AS IS" BASIS,
2548  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2549  * See the License for the specific language governing permissions and
2550  * limitations under the License.
2551  */
2552 
2553 #ifndef INCLUDE_PERFETTO_EXT_BASE_WEAK_PTR_H_
2554 #define INCLUDE_PERFETTO_EXT_BASE_WEAK_PTR_H_
2555 
2556 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_checker.h"
2557 
2558 #include <memory>
2559 
2560 namespace perfetto {
2561 namespace base {
2562 
2563 // A simple WeakPtr for single-threaded cases.
2564 // Generally keep the WeakPtrFactory as last fields in classes: it makes the
2565 // WeakPtr(s) invalidate as first thing in the class dtor.
2566 // Usage:
2567 // class MyClass {
2568 //  MyClass() : weak_factory_(this) {}
2569 //  WeakPtr<MyClass> GetWeakPtr() { return weak_factory_.GetWeakPtr(); }
2570 //
2571 // private:
2572 //  WeakPtrFactory<MyClass> weak_factory_;
2573 // }
2574 //
2575 // int main() {
2576 //  std::unique_ptr<MyClass> foo(new MyClass);
2577 //  auto wptr = foo.GetWeakPtr();
2578 //  ASSERT_TRUE(wptr);
2579 //  ASSERT_EQ(foo.get(), wptr->get());
2580 //  foo.reset();
2581 //  ASSERT_FALSE(wptr);
2582 //  ASSERT_EQ(nullptr, wptr->get());
2583 // }
2584 
2585 template <typename T>
2586 class WeakPtrFactory;  // Forward declaration, defined below.
2587 
2588 template <typename T>
2589 class WeakPtr {
2590  public:
WeakPtr()2591   WeakPtr() {}
2592   WeakPtr(const WeakPtr&) = default;
2593   WeakPtr& operator=(const WeakPtr&) = default;
2594   WeakPtr(WeakPtr&&) = default;
2595   WeakPtr& operator=(WeakPtr&&) = default;
2596 
get() const2597   T* get() const {
2598     PERFETTO_DCHECK_THREAD(thread_checker);
2599     return handle_ ? *handle_.get() : nullptr;
2600   }
operator ->() const2601   T* operator->() const { return get(); }
operator *() const2602   T& operator*() const { return *get(); }
2603 
operator bool() const2604   explicit operator bool() const { return !!get(); }
2605 
2606  private:
2607   friend class WeakPtrFactory<T>;
WeakPtr(const std::shared_ptr<T * > & handle)2608   explicit WeakPtr(const std::shared_ptr<T*>& handle) : handle_(handle) {}
2609 
2610   std::shared_ptr<T*> handle_;
2611   PERFETTO_THREAD_CHECKER(thread_checker)
2612 };
2613 
2614 template <typename T>
2615 class WeakPtrFactory {
2616  public:
WeakPtrFactory(T * owner)2617   explicit WeakPtrFactory(T* owner)
2618       : weak_ptr_(std::shared_ptr<T*>(new T* {owner})) {
2619     PERFETTO_DCHECK_THREAD(thread_checker);
2620   }
2621 
~WeakPtrFactory()2622   ~WeakPtrFactory() {
2623     PERFETTO_DCHECK_THREAD(thread_checker);
2624     *(weak_ptr_.handle_.get()) = nullptr;
2625   }
2626 
2627   // Can be safely called on any thread, since it simply copies |weak_ptr_|.
2628   // Note that any accesses to the returned pointer need to be made on the
2629   // thread that created/reset the factory.
GetWeakPtr() const2630   WeakPtr<T> GetWeakPtr() const { return weak_ptr_; }
2631 
2632   // Reset the factory to a new owner & thread. May only be called before any
2633   // weak pointers were passed out. Future weak pointers will be valid on the
2634   // calling thread.
Reset(T * owner)2635   void Reset(T* owner) {
2636     // Reset thread checker to current thread.
2637     PERFETTO_DETACH_FROM_THREAD(thread_checker);
2638     PERFETTO_DCHECK_THREAD(thread_checker);
2639 
2640     // We should not have passed out any weak pointers yet at this point.
2641     PERFETTO_DCHECK(weak_ptr_.handle_.use_count() == 1);
2642 
2643     weak_ptr_ = WeakPtr<T>(std::shared_ptr<T*>(new T* {owner}));
2644   }
2645 
2646  private:
2647   WeakPtrFactory(const WeakPtrFactory&) = delete;
2648   WeakPtrFactory& operator=(const WeakPtrFactory&) = delete;
2649 
2650   WeakPtr<T> weak_ptr_;
2651   PERFETTO_THREAD_CHECKER(thread_checker)
2652 };
2653 
2654 }  // namespace base
2655 }  // namespace perfetto
2656 
2657 #endif  // INCLUDE_PERFETTO_EXT_BASE_WEAK_PTR_H_
2658 /*
2659  * Copyright (C) 2021 The Android Open Source Project
2660  *
2661  * Licensed under the Apache License, Version 2.0 (the "License");
2662  * you may not use this file except in compliance with the License.
2663  * You may obtain a copy of the License at
2664  *
2665  *      http://www.apache.org/licenses/LICENSE-2.0
2666  *
2667  * Unless required by applicable law or agreed to in writing, software
2668  * distributed under the License is distributed on an "AS IS" BASIS,
2669  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2670  * See the License for the specific language governing permissions and
2671  * limitations under the License.
2672  */
2673 
2674 #ifndef INCLUDE_PERFETTO_EXT_BASE_PERIODIC_TASK_H_
2675 #define INCLUDE_PERFETTO_EXT_BASE_PERIODIC_TASK_H_
2676 
2677 #include <functional>
2678 
2679 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
2680 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_checker.h"
2681 // gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
2682 
2683 namespace perfetto {
2684 namespace base {
2685 
2686 class TaskRunner;
2687 
2688 // A periodic task utility class. It wraps the logic necessary to do periodic
2689 // tasks using a TaskRunner, taking care of subtleties like ensuring that
2690 // outstanding tasks are cancelled after reset/dtor.
2691 // Tasks are aligned on wall time, this is to ensure that when using multiple
2692 // periodic tasks, they happen at the same time, minimizing wakeups.
2693 // On Linux/Android it also supports suspend-aware mode (via timerfd). On other
2694 // operating systems it falls back to PostDelayedTask, which is not
2695 // suspend-aware.
2696 // TODO(primiano): this should probably become a periodic timer scheduler, so we
2697 // can use one FD for everything rather than one FD per task. For now we take
2698 // the hit of a FD-per-task to keep this low-risk.
2699 class PeriodicTask {
2700  public:
2701   explicit PeriodicTask(base::TaskRunner*);
2702   ~PeriodicTask();  // Calls Reset().
2703 
2704   struct Args {
2705     uint32_t period_ms = 0;
2706     std::function<void()> task = nullptr;
2707     bool start_first_task_immediately = false;
2708     bool use_suspend_aware_timer = false;
2709   };
2710 
2711   void Start(Args);
2712 
2713   // Safe to be called multiple times, even without calling Start():
2714   void Reset();
2715 
2716   // No copy or move. WeakPtr-wrapped pointers to |this| are posted on the
2717   // task runner, this class is not easily movable.
2718   PeriodicTask(const PeriodicTask&) = delete;
2719   PeriodicTask& operator=(const PeriodicTask&) = delete;
2720   PeriodicTask(PeriodicTask&&) = delete;
2721   PeriodicTask& operator=(PeriodicTask&&) = delete;
2722 
timer_fd_for_testing()2723   base::PlatformHandle timer_fd_for_testing() { return *timer_fd_; }
2724 
2725  private:
2726   static void RunTaskAndPostNext(base::WeakPtr<PeriodicTask>,
2727                                  uint32_t generation);
2728   void PostNextTask();
2729   void ResetTimerFd();
2730 
2731   base::TaskRunner* const task_runner_;
2732   Args args_;
2733   uint32_t generation_ = 0;
2734   base::ScopedPlatformHandle timer_fd_;
2735 
2736   PERFETTO_THREAD_CHECKER(thread_checker_)
2737   base::WeakPtrFactory<PeriodicTask> weak_ptr_factory_;  // Keep last.
2738 };
2739 
2740 }  // namespace base
2741 }  // namespace perfetto
2742 
2743 #endif  // INCLUDE_PERFETTO_EXT_BASE_PERIODIC_TASK_H_
2744 /*
2745  * Copyright (C) 2021 The Android Open Source Project
2746  *
2747  * Licensed under the Apache License, Version 2.0 (the "License");
2748  * you may not use this file except in compliance with the License.
2749  * You may obtain a copy of the License at
2750  *
2751  *      http://www.apache.org/licenses/LICENSE-2.0
2752  *
2753  * Unless required by applicable law or agreed to in writing, software
2754  * distributed under the License is distributed on an "AS IS" BASIS,
2755  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2756  * See the License for the specific language governing permissions and
2757  * limitations under the License.
2758  */
2759 
2760 // gen_amalgamated expanded: #include "perfetto/ext/base/periodic_task.h"
2761 
2762 #include <limits>
2763 
2764 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
2765 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
2766 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
2767 // gen_amalgamated expanded: #include "perfetto/base/time.h"
2768 // gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
2769 
2770 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
2771     (PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && __ANDROID_API__ >= 19)
2772 #include <sys/timerfd.h>
2773 #endif
2774 
2775 namespace perfetto {
2776 namespace base {
2777 
2778 namespace {
CreateTimerFd(uint32_t period_ms)2779 base::ScopedPlatformHandle CreateTimerFd(uint32_t period_ms) {
2780 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
2781     (PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && __ANDROID_API__ >= 19)
2782   base::ScopedPlatformHandle tfd(
2783       timerfd_create(CLOCK_BOOTTIME, TFD_CLOEXEC | TFD_NONBLOCK));
2784   // The initial phase, aligned on wall clock.
2785   uint32_t phase_ms =
2786       period_ms -
2787       static_cast<uint32_t>(base::GetBootTimeNs().count() % period_ms);
2788   struct itimerspec its {};
2789   // The "1 +" is to make sure that we never pass a zero it_value in the
2790   // unlikely case of phase_ms being 0. That would cause the timer to be
2791   // considered disarmed by timerfd_settime.
2792   its.it_value.tv_sec = static_cast<time_t>(phase_ms / 1000u);
2793   its.it_value.tv_nsec = 1 + static_cast<long>((phase_ms % 1000u) * 1000000u);
2794   its.it_interval.tv_sec = static_cast<time_t>(period_ms / 1000u);
2795   its.it_interval.tv_nsec = static_cast<long>((period_ms % 1000u) * 1000000u);
2796   if (timerfd_settime(*tfd, 0, &its, nullptr) < 0)
2797     return base::ScopedPlatformHandle();
2798   return tfd;
2799 #else
2800   base::ignore_result(period_ms);
2801   return base::ScopedPlatformHandle();
2802 #endif
2803 }
2804 }  // namespace
2805 
PeriodicTask(base::TaskRunner * task_runner)2806 PeriodicTask::PeriodicTask(base::TaskRunner* task_runner)
2807     : task_runner_(task_runner), weak_ptr_factory_(this) {}
2808 
~PeriodicTask()2809 PeriodicTask::~PeriodicTask() {
2810   Reset();
2811 }
2812 
Start(Args args)2813 void PeriodicTask::Start(Args args) {
2814   PERFETTO_DCHECK_THREAD(thread_checker_);
2815   Reset();
2816   if (args.period_ms == 0 || !args.task) {
2817     PERFETTO_DCHECK(args.period_ms > 0);
2818     PERFETTO_DCHECK(args.task);
2819     return;
2820   }
2821   args_ = std::move(args);
2822   if (args_.use_suspend_aware_timer) {
2823     timer_fd_ = CreateTimerFd(args_.period_ms);
2824     if (timer_fd_) {
2825       auto weak_this = weak_ptr_factory_.GetWeakPtr();
2826       task_runner_->AddFileDescriptorWatch(
2827           *timer_fd_,
2828           std::bind(PeriodicTask::RunTaskAndPostNext, weak_this, generation_));
2829     } else {
2830       PERFETTO_DPLOG("timerfd not supported, falling back on PostDelayedTask");
2831     }
2832   }  // if (use_suspend_aware_timer).
2833 
2834   if (!timer_fd_)
2835     PostNextTask();
2836 
2837   if (args_.start_first_task_immediately)
2838     args_.task();
2839 }
2840 
PostNextTask()2841 void PeriodicTask::PostNextTask() {
2842   PERFETTO_DCHECK_THREAD(thread_checker_);
2843   PERFETTO_DCHECK(args_.period_ms > 0);
2844   PERFETTO_DCHECK(!timer_fd_);
2845   uint32_t delay_ms =
2846       args_.period_ms -
2847       static_cast<uint32_t>(base::GetWallTimeMs().count() % args_.period_ms);
2848   auto weak_this = weak_ptr_factory_.GetWeakPtr();
2849   task_runner_->PostDelayedTask(
2850       std::bind(PeriodicTask::RunTaskAndPostNext, weak_this, generation_),
2851       delay_ms);
2852 }
2853 
2854 // static
2855 // This function can be called in two ways (both from the TaskRunner):
2856 // 1. When using a timerfd, this task is registered as a FD watch.
2857 // 2. When using PostDelayedTask, this is the task posted on the TaskRunner.
RunTaskAndPostNext(base::WeakPtr<PeriodicTask> thiz,uint32_t generation)2858 void PeriodicTask::RunTaskAndPostNext(base::WeakPtr<PeriodicTask> thiz,
2859                                       uint32_t generation) {
2860   if (!thiz || !thiz->args_.task || generation != thiz->generation_)
2861     return;  // Destroyed or Reset() in the meanwhile.
2862   PERFETTO_DCHECK_THREAD(thiz->thread_checker_);
2863   if (thiz->timer_fd_) {
2864 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
2865     PERFETTO_FATAL("timerfd for periodic tasks unsupported on Windows");
2866 #else
2867     // If we are using a timerfd there is no need to repeatedly call
2868     // PostDelayedTask(). The kernel will wakeup the timer fd periodically. We
2869     // just need to read() it.
2870     uint64_t ignored = 0;
2871     errno = 0;
2872     auto rsize = base::Read(*thiz->timer_fd_, &ignored, sizeof(&ignored));
2873     if (rsize != sizeof(uint64_t)) {
2874       if (errno == EAGAIN)
2875         return;  // A spurious wakeup. Rare, but can happen, just ignore.
2876       PERFETTO_PLOG("read(timerfd) failed, falling back on PostDelayedTask");
2877       thiz->ResetTimerFd();
2878     }
2879 #endif
2880   }
2881   // The repetition of the if() is to deal with the ResetTimerFd() case above.
2882   if (!thiz->timer_fd_) {
2883     thiz->PostNextTask();
2884   }
2885   // Create a copy of the task in the unlikely event that the task ends up
2886   // up destroying the PeriodicTask object or calling Reset() on it. That would
2887   // cause a reset of the args_.task itself, which would invalidate the task
2888   // bind state while we are invoking it.
2889   auto task = thiz->args_.task;
2890   task();
2891 }
2892 
Reset()2893 void PeriodicTask::Reset() {
2894   PERFETTO_DCHECK_THREAD(thread_checker_);
2895   ++generation_;
2896   args_ = Args();
2897   PERFETTO_DCHECK(!args_.task);
2898   ResetTimerFd();
2899 }
2900 
ResetTimerFd()2901 void PeriodicTask::ResetTimerFd() {
2902   if (!timer_fd_)
2903     return;
2904   task_runner_->RemoveFileDescriptorWatch(*timer_fd_);
2905   timer_fd_.reset();
2906 }
2907 
2908 }  // namespace base
2909 }  // namespace perfetto
2910 // gen_amalgamated begin source: src/base/pipe.cc
2911 /*
2912  * Copyright (C) 2018 The Android Open Source Project
2913  *
2914  * Licensed under the Apache License, Version 2.0 (the "License");
2915  * you may not use this file except in compliance with the License.
2916  * You may obtain a copy of the License at
2917  *
2918  *      http://www.apache.org/licenses/LICENSE-2.0
2919  *
2920  * Unless required by applicable law or agreed to in writing, software
2921  * distributed under the License is distributed on an "AS IS" BASIS,
2922  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2923  * See the License for the specific language governing permissions and
2924  * limitations under the License.
2925  */
2926 
2927 // gen_amalgamated expanded: #include "perfetto/ext/base/pipe.h"
2928 
2929 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
2930 
2931 #include <fcntl.h>  // For O_BINARY (Windows) and F_SETxx (UNIX)
2932 
2933 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
2934 #include <Windows.h>
2935 #include <namedpipeapi.h>
2936 #else
2937 #include <sys/types.h>
2938 #include <unistd.h>
2939 #endif
2940 
2941 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
2942 
2943 namespace perfetto {
2944 namespace base {
2945 
2946 Pipe::Pipe() = default;
2947 Pipe::Pipe(Pipe&&) noexcept = default;
2948 Pipe& Pipe::operator=(Pipe&&) = default;
2949 
Create(Flags flags)2950 Pipe Pipe::Create(Flags flags) {
2951   PlatformHandle fds[2];
2952 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
2953   PERFETTO_CHECK(::CreatePipe(&fds[0], &fds[1], /*lpPipeAttributes=*/nullptr,
2954                               0 /*default size*/));
2955 #else
2956   PERFETTO_CHECK(pipe(fds) == 0);
2957   PERFETTO_CHECK(fcntl(fds[0], F_SETFD, FD_CLOEXEC) == 0);
2958   PERFETTO_CHECK(fcntl(fds[1], F_SETFD, FD_CLOEXEC) == 0);
2959 #endif
2960   Pipe p;
2961   p.rd.reset(fds[0]);
2962   p.wr.reset(fds[1]);
2963 
2964 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
2965   if (flags == kBothNonBlock || flags == kRdNonBlock) {
2966     int cur_flags = fcntl(*p.rd, F_GETFL, 0);
2967     PERFETTO_CHECK(cur_flags >= 0);
2968     PERFETTO_CHECK(fcntl(*p.rd, F_SETFL, cur_flags | O_NONBLOCK) == 0);
2969   }
2970 
2971   if (flags == kBothNonBlock || flags == kWrNonBlock) {
2972     int cur_flags = fcntl(*p.wr, F_GETFL, 0);
2973     PERFETTO_CHECK(cur_flags >= 0);
2974     PERFETTO_CHECK(fcntl(*p.wr, F_SETFL, cur_flags | O_NONBLOCK) == 0);
2975   }
2976 #else
2977   PERFETTO_CHECK(flags == kBothBlock);
2978 #endif
2979   return p;
2980 }
2981 
2982 }  // namespace base
2983 }  // namespace perfetto
2984 // gen_amalgamated begin source: src/base/status.cc
2985 // gen_amalgamated begin header: include/perfetto/base/status.h
2986 /*
2987  * Copyright (C) 2019 The Android Open Source Project
2988  *
2989  * Licensed under the Apache License, Version 2.0 (the "License");
2990  * you may not use this file except in compliance with the License.
2991  * You may obtain a copy of the License at
2992  *
2993  *      http://www.apache.org/licenses/LICENSE-2.0
2994  *
2995  * Unless required by applicable law or agreed to in writing, software
2996  * distributed under the License is distributed on an "AS IS" BASIS,
2997  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2998  * See the License for the specific language governing permissions and
2999  * limitations under the License.
3000  */
3001 
3002 #ifndef INCLUDE_PERFETTO_BASE_STATUS_H_
3003 #define INCLUDE_PERFETTO_BASE_STATUS_H_
3004 
3005 #include <string>
3006 
3007 // gen_amalgamated expanded: #include "perfetto/base/compiler.h"
3008 // gen_amalgamated expanded: #include "perfetto/base/export.h"
3009 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
3010 
3011 namespace perfetto {
3012 namespace base {
3013 
3014 // Represents either the success or the failure message of a function.
3015 // This can used as the return type of functions which would usually return an
3016 // bool for success or int for errno but also wants to add some string context
3017 // (ususally for logging).
3018 class PERFETTO_EXPORT Status {
3019  public:
Status()3020   Status() : ok_(true) {}
Status(std::string msg)3021   explicit Status(std::string msg) : ok_(false), message_(std::move(msg)) {
3022     PERFETTO_CHECK(!message_.empty());
3023   }
3024 
3025   // Copy operations.
3026   Status(const Status&) = default;
3027   Status& operator=(const Status&) = default;
3028 
3029   // Move operations. The moved-from state is valid but unspecified.
3030   Status(Status&&) noexcept = default;
3031   Status& operator=(Status&&) = default;
3032 
ok() const3033   bool ok() const { return ok_; }
3034 
3035   // When ok() is false this returns the error message. Returns the empty string
3036   // otherwise.
message() const3037   const std::string& message() const { return message_; }
c_message() const3038   const char* c_message() const { return message_.c_str(); }
3039 
3040  private:
3041   bool ok_ = false;
3042   std::string message_;
3043 };
3044 
3045 // Returns a status object which represents the Ok status.
OkStatus()3046 inline Status OkStatus() {
3047   return Status();
3048 }
3049 
3050 PERFETTO_PRINTF_FORMAT(1, 2) Status ErrStatus(const char* format, ...);
3051 
3052 }  // namespace base
3053 }  // namespace perfetto
3054 
3055 #endif  // INCLUDE_PERFETTO_BASE_STATUS_H_
3056 /*
3057  * Copyright (C) 2020 The Android Open Source Project
3058  *
3059  * Licensed under the Apache License, Version 2.0 (the "License");
3060  * you may not use this file except in compliance with the License.
3061  * You may obtain a copy of the License at
3062  *
3063  *      http://www.apache.org/licenses/LICENSE-2.0
3064  *
3065  * Unless required by applicable law or agreed to in writing, software
3066  * distributed under the License is distributed on an "AS IS" BASIS,
3067  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3068  * See the License for the specific language governing permissions and
3069  * limitations under the License.
3070  */
3071 
3072 // gen_amalgamated expanded: #include "perfetto/base/status.h"
3073 
3074 #include <stdarg.h>
3075 
3076 namespace perfetto {
3077 namespace base {
3078 
ErrStatus(const char * format,...)3079 Status ErrStatus(const char* format, ...) {
3080   char buffer[1024];
3081   va_list ap;
3082   va_start(ap, format);
3083   vsnprintf(buffer, sizeof(buffer), format, ap);
3084   va_end(ap);
3085   Status status(buffer);
3086   return status;
3087 }
3088 
3089 }  // namespace base
3090 }  // namespace perfetto
3091 // gen_amalgamated begin source: src/base/string_splitter.cc
3092 // gen_amalgamated begin header: include/perfetto/ext/base/string_splitter.h
3093 /*
3094  * Copyright (C) 2018 The Android Open Source Project
3095  *
3096  * Licensed under the Apache License, Version 2.0 (the "License");
3097  * you may not use this file except in compliance with the License.
3098  * You may obtain a copy of the License at
3099  *
3100  *      http://www.apache.org/licenses/LICENSE-2.0
3101  *
3102  * Unless required by applicable law or agreed to in writing, software
3103  * distributed under the License is distributed on an "AS IS" BASIS,
3104  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3105  * See the License for the specific language governing permissions and
3106  * limitations under the License.
3107  */
3108 
3109 #ifndef INCLUDE_PERFETTO_EXT_BASE_STRING_SPLITTER_H_
3110 #define INCLUDE_PERFETTO_EXT_BASE_STRING_SPLITTER_H_
3111 
3112 #include <string>
3113 
3114 namespace perfetto {
3115 namespace base {
3116 
3117 // C++ version of strtok(). Splits a string without making copies or any heap
3118 // allocations. Destructs the original string passed in input.
3119 // Supports the special case of using \0 as a delimiter.
3120 // The token returned in output are valid as long as the input string is valid.
3121 class StringSplitter {
3122  public:
3123   // Can take ownership of the string if passed via std::move(), e.g.:
3124   // StringSplitter(std::move(str), '\n');
3125   StringSplitter(std::string, char delimiter);
3126 
3127   // Splits a C-string. The input string will be forcefully null-terminated (so
3128   // str[size - 1] should be == '\0' or the last char will be truncated).
3129   StringSplitter(char* str, size_t size, char delimiter);
3130 
3131   // Splits the current token from an outer StringSplitter instance. This is to
3132   // chain splitters as follows:
3133   // for (base::StringSplitter lines(x, '\n'); ss.Next();)
3134   //   for (base::StringSplitter words(&lines, ' '); words.Next();)
3135   StringSplitter(StringSplitter*, char delimiter);
3136 
3137   // Returns true if a token is found (in which case it will be stored in
3138   // cur_token()), false if no more tokens are found.
3139   bool Next();
3140 
3141   // Returns the current token iff last call to Next() returned true. In this
3142   // case it guarantees that the returned string is always null terminated.
3143   // In all other cases (before the 1st call to Next() and after Next() returns
3144   // false) returns nullptr.
cur_token()3145   char* cur_token() { return cur_; }
3146 
3147   // Returns the length of the current token (excluding the null terminator).
cur_token_size() const3148   size_t cur_token_size() const { return cur_size_; }
3149 
3150  private:
3151   StringSplitter(const StringSplitter&) = delete;
3152   StringSplitter& operator=(const StringSplitter&) = delete;
3153   void Initialize(char* str, size_t size);
3154 
3155   std::string str_;
3156   char* cur_;
3157   size_t cur_size_;
3158   char* next_;
3159   char* end_;  // STL-style, points one past the last char.
3160   const char delimiter_;
3161 };
3162 
3163 }  // namespace base
3164 }  // namespace perfetto
3165 
3166 #endif  // INCLUDE_PERFETTO_EXT_BASE_STRING_SPLITTER_H_
3167 /*
3168  * Copyright (C) 2018 The Android Open Source Project
3169  *
3170  * Licensed under the Apache License, Version 2.0 (the "License");
3171  * you may not use this file except in compliance with the License.
3172  * You may obtain a copy of the License at
3173  *
3174  *      http://www.apache.org/licenses/LICENSE-2.0
3175  *
3176  * Unless required by applicable law or agreed to in writing, software
3177  * distributed under the License is distributed on an "AS IS" BASIS,
3178  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3179  * See the License for the specific language governing permissions and
3180  * limitations under the License.
3181  */
3182 
3183 // gen_amalgamated expanded: #include "perfetto/ext/base/string_splitter.h"
3184 
3185 #include <utility>
3186 
3187 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
3188 
3189 namespace perfetto {
3190 namespace base {
3191 
StringSplitter(std::string str,char delimiter)3192 StringSplitter::StringSplitter(std::string str, char delimiter)
3193     : str_(std::move(str)), delimiter_(delimiter) {
3194   // It's legal to access str[str.size()] in C++11 (it always returns \0),
3195   // hence the +1 (which becomes just size() after the -1 in Initialize()).
3196   Initialize(&str_[0], str_.size() + 1);
3197 }
3198 
StringSplitter(char * str,size_t size,char delimiter)3199 StringSplitter::StringSplitter(char* str, size_t size, char delimiter)
3200     : delimiter_(delimiter) {
3201   Initialize(str, size);
3202 }
3203 
StringSplitter(StringSplitter * outer,char delimiter)3204 StringSplitter::StringSplitter(StringSplitter* outer, char delimiter)
3205     : delimiter_(delimiter) {
3206   Initialize(outer->cur_token(), outer->cur_token_size() + 1);
3207 }
3208 
Initialize(char * str,size_t size)3209 void StringSplitter::Initialize(char* str, size_t size) {
3210   PERFETTO_DCHECK(!size || str);
3211   next_ = str;
3212   end_ = str + size;
3213   cur_ = nullptr;
3214   cur_size_ = 0;
3215   if (size)
3216     next_[size - 1] = '\0';
3217 }
3218 
Next()3219 bool StringSplitter::Next() {
3220   for (; next_ < end_; next_++) {
3221     if (*next_ == delimiter_)
3222       continue;
3223     cur_ = next_;
3224     for (;; next_++) {
3225       if (*next_ == delimiter_) {
3226         cur_size_ = static_cast<size_t>(next_ - cur_);
3227         *(next_++) = '\0';
3228         break;
3229       }
3230       if (*next_ == '\0') {
3231         cur_size_ = static_cast<size_t>(next_ - cur_);
3232         next_ = end_;
3233         break;
3234       }
3235     }
3236     if (*cur_)
3237       return true;
3238     break;
3239   }
3240   cur_ = nullptr;
3241   cur_size_ = 0;
3242   return false;
3243 }
3244 
3245 }  // namespace base
3246 }  // namespace perfetto
3247 // gen_amalgamated begin source: src/base/string_utils.cc
3248 // gen_amalgamated begin header: include/perfetto/ext/base/string_utils.h
3249 // gen_amalgamated begin header: include/perfetto/ext/base/optional.h
3250 /*
3251  * Copyright (C) 2018 The Android Open Source Project
3252  *
3253  * Licensed under the Apache License, Version 2.0 (the "License");
3254  * you may not use this file except in compliance with the License.
3255  * You may obtain a copy of the License at
3256  *
3257  *      http://www.apache.org/licenses/LICENSE-2.0
3258  *
3259  * Unless required by applicable law or agreed to in writing, software
3260  * distributed under the License is distributed on an "AS IS" BASIS,
3261  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3262  * See the License for the specific language governing permissions and
3263  * limitations under the License.
3264  */
3265 
3266 #ifndef INCLUDE_PERFETTO_EXT_BASE_OPTIONAL_H_
3267 #define INCLUDE_PERFETTO_EXT_BASE_OPTIONAL_H_
3268 
3269 #include <functional>
3270 #include <type_traits>
3271 #include <utility>
3272 
3273 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
3274 
3275 namespace perfetto {
3276 namespace base {
3277 
3278 // Specification:
3279 // http://en.cppreference.com/w/cpp/utility/optional/in_place_t
3280 struct in_place_t {};
3281 
3282 // Specification:
3283 // http://en.cppreference.com/w/cpp/utility/optional/nullopt_t
3284 struct nullopt_t {
nullopt_tperfetto::base::nullopt_t3285   constexpr explicit nullopt_t(int) {}
3286 };
3287 
3288 // Specification:
3289 // http://en.cppreference.com/w/cpp/utility/optional/in_place
3290 constexpr in_place_t in_place = {};
3291 
3292 // Specification:
3293 // http://en.cppreference.com/w/cpp/utility/optional/nullopt
3294 constexpr nullopt_t nullopt(0);
3295 
3296 // Forward declaration, which is referred by following helpers.
3297 template <typename T>
3298 class Optional;
3299 
3300 namespace internal {
3301 
3302 template <typename T, bool = std::is_trivially_destructible<T>::value>
3303 struct OptionalStorageBase {
3304   // Initializing |empty_| here instead of using default member initializing
3305   // to avoid errors in g++ 4.8.
OptionalStorageBaseperfetto::base::internal::OptionalStorageBase3306   constexpr OptionalStorageBase() : empty_('\0') {}
3307 
3308   template <class... Args>
OptionalStorageBaseperfetto::base::internal::OptionalStorageBase3309   constexpr explicit OptionalStorageBase(in_place_t, Args&&... args)
3310       : is_populated_(true), value_(std::forward<Args>(args)...) {}
3311 
3312   // When T is not trivially destructible we must call its
3313   // destructor before deallocating its memory.
3314   // Note that this hides the (implicitly declared) move constructor, which
3315   // would be used for constexpr move constructor in OptionalStorage<T>.
3316   // It is needed iff T is trivially move constructible. However, the current
3317   // is_trivially_{copy,move}_constructible implementation requires
3318   // is_trivially_destructible (which looks a bug, cf:
3319   // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51452 and
3320   // http://cplusplus.github.io/LWG/lwg-active.html#2116), so it is not
3321   // necessary for this case at the moment. Please see also the destructor
3322   // comment in "is_trivially_destructible = true" specialization below.
~OptionalStorageBaseperfetto::base::internal::OptionalStorageBase3323   ~OptionalStorageBase() {
3324     if (is_populated_)
3325       value_.~T();
3326   }
3327 
3328   template <class... Args>
Initperfetto::base::internal::OptionalStorageBase3329   void Init(Args&&... args) {
3330     PERFETTO_DCHECK(!is_populated_);
3331     ::new (&value_) T(std::forward<Args>(args)...);
3332     is_populated_ = true;
3333   }
3334 
3335   bool is_populated_ = false;
3336   union {
3337     // |empty_| exists so that the union will always be initialized, even when
3338     // it doesn't contain a value. Union members must be initialized for the
3339     // constructor to be 'constexpr'.
3340     char empty_;
3341     T value_;
3342   };
3343 };
3344 
3345 template <typename T>
3346 struct OptionalStorageBase<T, true /* trivially destructible */> {
3347   // Initializing |empty_| here instead of using default member initializing
3348   // to avoid errors in g++ 4.8.
OptionalStorageBaseperfetto::base::internal::OptionalStorageBase3349   constexpr OptionalStorageBase() : empty_('\0') {}
3350 
3351   template <class... Args>
OptionalStorageBaseperfetto::base::internal::OptionalStorageBase3352   constexpr explicit OptionalStorageBase(in_place_t, Args&&... args)
3353       : is_populated_(true), value_(std::forward<Args>(args)...) {}
3354 
3355   // When T is trivially destructible (i.e. its destructor does nothing) there
3356   // is no need to call it. Implicitly defined destructor is trivial, because
3357   // both members (bool and union containing only variants which are trivially
3358   // destructible) are trivially destructible.
3359   // Explicitly-defaulted destructor is also trivial, but do not use it here,
3360   // because it hides the implicit move constructor. It is needed to implement
3361   // constexpr move constructor in OptionalStorage iff T is trivially move
3362   // constructible. Note that, if T is trivially move constructible, the move
3363   // constructor of OptionalStorageBase<T> is also implicitly defined and it is
3364   // trivially move constructor. If T is not trivially move constructible,
3365   // "not declaring move constructor without destructor declaration" here means
3366   // "delete move constructor", which works because any move constructor of
3367   // OptionalStorage will not refer to it in that case.
3368 
3369   template <class... Args>
Initperfetto::base::internal::OptionalStorageBase3370   void Init(Args&&... args) {
3371     PERFETTO_DCHECK(!is_populated_);
3372     ::new (&value_) T(std::forward<Args>(args)...);
3373     is_populated_ = true;
3374   }
3375 
3376   bool is_populated_ = false;
3377   union {
3378     // |empty_| exists so that the union will always be initialized, even when
3379     // it doesn't contain a value. Union members must be initialized for the
3380     // constructor to be 'constexpr'.
3381     char empty_;
3382     T value_;
3383   };
3384 };
3385 
3386 // Implement conditional constexpr copy and move constructors. These are
3387 // constexpr if is_trivially_{copy,move}_constructible<T>::value is true
3388 // respectively. If each is true, the corresponding constructor is defined as
3389 // "= default;", which generates a constexpr constructor (In this case,
3390 // the condition of constexpr-ness is satisfied because the base class also has
3391 // compiler generated constexpr {copy,move} constructors). Note that
3392 // placement-new is prohibited in constexpr.
3393 template <typename T, bool = std::is_trivially_copy_constructible<T>::value>
3394 struct OptionalStorage : OptionalStorageBase<T> {
3395   // This is no trivially {copy,move} constructible case. Other cases are
3396   // defined below as specializations.
3397 
3398   // Accessing the members of template base class requires explicit
3399   // declaration.
3400   using OptionalStorageBase<T>::is_populated_;
3401   using OptionalStorageBase<T>::value_;
3402   using OptionalStorageBase<T>::Init;
3403 
3404   // Inherit constructors (specifically, the in_place constructor).
3405   using OptionalStorageBase<T>::OptionalStorageBase;
3406 
3407   // User defined constructor deletes the default constructor.
3408   // Define it explicitly.
3409   OptionalStorage() = default;
3410 
OptionalStorageperfetto::base::internal::OptionalStorage3411   OptionalStorage(const OptionalStorage& other) : OptionalStorageBase<T>() {
3412     if (other.is_populated_)
3413       Init(other.value_);
3414   }
3415 
OptionalStorageperfetto::base::internal::OptionalStorage3416   OptionalStorage(OptionalStorage&& other) noexcept(
3417       std::is_nothrow_move_constructible<T>::value) {
3418     if (other.is_populated_)
3419       Init(std::move(other.value_));
3420   }
3421 };
3422 
3423 template <typename T>
3424 struct OptionalStorage<T, true /* trivially copy constructible */>
3425     : OptionalStorageBase<T> {
3426   using OptionalStorageBase<T>::is_populated_;
3427   using OptionalStorageBase<T>::value_;
3428   using OptionalStorageBase<T>::Init;
3429   using OptionalStorageBase<T>::OptionalStorageBase;
3430 
3431   OptionalStorage() = default;
3432   OptionalStorage(const OptionalStorage& other) = default;
3433 
OptionalStorageperfetto::base::internal::OptionalStorage3434   OptionalStorage(OptionalStorage&& other) noexcept(
3435       std::is_nothrow_move_constructible<T>::value) {
3436     if (other.is_populated_)
3437       Init(std::move(other.value_));
3438   }
3439 };
3440 
3441 // Base class to support conditionally usable copy-/move- constructors
3442 // and assign operators.
3443 template <typename T>
3444 class OptionalBase {
3445   // This class provides implementation rather than public API, so everything
3446   // should be hidden. Often we use composition, but we cannot in this case
3447   // because of C++ language restriction.
3448  protected:
3449   constexpr OptionalBase() = default;
3450   constexpr OptionalBase(const OptionalBase& other) = default;
3451   constexpr OptionalBase(OptionalBase&& other) = default;
3452 
3453   template <class... Args>
OptionalBase(in_place_t,Args &&...args)3454   constexpr explicit OptionalBase(in_place_t, Args&&... args)
3455       : storage_(in_place, std::forward<Args>(args)...) {}
3456 
3457   // Implementation of converting constructors.
3458   template <typename U>
OptionalBase(const OptionalBase<U> & other)3459   explicit OptionalBase(const OptionalBase<U>& other) {
3460     if (other.storage_.is_populated_)
3461       storage_.Init(other.storage_.value_);
3462   }
3463 
3464   template <typename U>
OptionalBase(OptionalBase<U> && other)3465   explicit OptionalBase(OptionalBase<U>&& other) {
3466     if (other.storage_.is_populated_)
3467       storage_.Init(std::move(other.storage_.value_));
3468   }
3469 
3470   ~OptionalBase() = default;
3471 
operator =(const OptionalBase & other)3472   OptionalBase& operator=(const OptionalBase& other) {
3473     CopyAssign(other);
3474     return *this;
3475   }
3476 
operator =(OptionalBase && other)3477   OptionalBase& operator=(OptionalBase&& other) noexcept(
3478       std::is_nothrow_move_assignable<T>::value&&
3479           std::is_nothrow_move_constructible<T>::value) {
3480     MoveAssign(std::move(other));
3481     return *this;
3482   }
3483 
3484   template <typename U>
CopyAssign(const OptionalBase<U> & other)3485   void CopyAssign(const OptionalBase<U>& other) {
3486     if (other.storage_.is_populated_)
3487       InitOrAssign(other.storage_.value_);
3488     else
3489       FreeIfNeeded();
3490   }
3491 
3492   template <typename U>
MoveAssign(OptionalBase<U> && other)3493   void MoveAssign(OptionalBase<U>&& other) {
3494     if (other.storage_.is_populated_)
3495       InitOrAssign(std::move(other.storage_.value_));
3496     else
3497       FreeIfNeeded();
3498   }
3499 
3500   template <typename U>
InitOrAssign(U && value)3501   void InitOrAssign(U&& value) {
3502     if (storage_.is_populated_)
3503       storage_.value_ = std::forward<U>(value);
3504     else
3505       storage_.Init(std::forward<U>(value));
3506   }
3507 
FreeIfNeeded()3508   void FreeIfNeeded() {
3509     if (!storage_.is_populated_)
3510       return;
3511     storage_.value_.~T();
3512     storage_.is_populated_ = false;
3513   }
3514 
3515   // For implementing conversion, allow access to other typed OptionalBase
3516   // class.
3517   template <typename U>
3518   friend class OptionalBase;
3519 
3520   OptionalStorage<T> storage_;
3521 };
3522 
3523 // The following {Copy,Move}{Constructible,Assignable} structs are helpers to
3524 // implement constructor/assign-operator overloading. Specifically, if T is
3525 // is not movable but copyable, Optional<T>'s move constructor should not
3526 // participate in overload resolution. This inheritance trick implements that.
3527 template <bool is_copy_constructible>
3528 struct CopyConstructible {};
3529 
3530 template <>
3531 struct CopyConstructible<false> {
3532   constexpr CopyConstructible() = default;
3533   constexpr CopyConstructible(const CopyConstructible&) = delete;
3534   constexpr CopyConstructible(CopyConstructible&&) = default;
3535   CopyConstructible& operator=(const CopyConstructible&) = default;
3536   CopyConstructible& operator=(CopyConstructible&&) = default;
3537 };
3538 
3539 template <bool is_move_constructible>
3540 struct MoveConstructible {};
3541 
3542 template <>
3543 struct MoveConstructible<false> {
3544   constexpr MoveConstructible() = default;
3545   constexpr MoveConstructible(const MoveConstructible&) = default;
3546   constexpr MoveConstructible(MoveConstructible&&) = delete;
3547   MoveConstructible& operator=(const MoveConstructible&) = default;
3548   MoveConstructible& operator=(MoveConstructible&&) = default;
3549 };
3550 
3551 template <bool is_copy_assignable>
3552 struct CopyAssignable {};
3553 
3554 template <>
3555 struct CopyAssignable<false> {
3556   constexpr CopyAssignable() = default;
3557   constexpr CopyAssignable(const CopyAssignable&) = default;
3558   constexpr CopyAssignable(CopyAssignable&&) = default;
3559   CopyAssignable& operator=(const CopyAssignable&) = delete;
3560   CopyAssignable& operator=(CopyAssignable&&) = default;
3561 };
3562 
3563 template <bool is_move_assignable>
3564 struct MoveAssignable {};
3565 
3566 template <>
3567 struct MoveAssignable<false> {
3568   constexpr MoveAssignable() = default;
3569   constexpr MoveAssignable(const MoveAssignable&) = default;
3570   constexpr MoveAssignable(MoveAssignable&&) = default;
3571   MoveAssignable& operator=(const MoveAssignable&) = default;
3572   MoveAssignable& operator=(MoveAssignable&&) = delete;
3573 };
3574 
3575 // Helper to conditionally enable converting constructors and assign operators.
3576 template <typename T, typename U>
3577 struct IsConvertibleFromOptional
3578     : std::integral_constant<
3579           bool,
3580           std::is_constructible<T, Optional<U>&>::value ||
3581               std::is_constructible<T, const Optional<U>&>::value ||
3582               std::is_constructible<T, Optional<U>&&>::value ||
3583               std::is_constructible<T, const Optional<U>&&>::value ||
3584               std::is_convertible<Optional<U>&, T>::value ||
3585               std::is_convertible<const Optional<U>&, T>::value ||
3586               std::is_convertible<Optional<U>&&, T>::value ||
3587               std::is_convertible<const Optional<U>&&, T>::value> {};
3588 
3589 template <typename T, typename U>
3590 struct IsAssignableFromOptional
3591     : std::integral_constant<
3592           bool,
3593           IsConvertibleFromOptional<T, U>::value ||
3594               std::is_assignable<T&, Optional<U>&>::value ||
3595               std::is_assignable<T&, const Optional<U>&>::value ||
3596               std::is_assignable<T&, Optional<U>&&>::value ||
3597               std::is_assignable<T&, const Optional<U>&&>::value> {};
3598 
3599 // Forward compatibility for C++17.
3600 // Introduce one more deeper nested namespace to avoid leaking using std::swap.
3601 namespace swappable_impl {
3602 using std::swap;
3603 
3604 struct IsSwappableImpl {
3605   // Tests if swap can be called. Check<T&>(0) returns true_type iff swap is
3606   // available for T. Otherwise, Check's overload resolution falls back to
3607   // Check(...) declared below thanks to SFINAE, so returns false_type.
3608   template <typename T>
3609   static auto Check(int)
3610       -> decltype(swap(std::declval<T>(), std::declval<T>()), std::true_type());
3611 
3612   template <typename T>
3613   static std::false_type Check(...);
3614 };
3615 }  // namespace swappable_impl
3616 
3617 template <typename T>
3618 struct IsSwappable : decltype(swappable_impl::IsSwappableImpl::Check<T&>(0)) {};
3619 
3620 // Forward compatibility for C++20.
3621 template <typename T>
3622 using RemoveCvRefT =
3623     typename std::remove_cv<typename std::remove_reference<T>::type>::type;
3624 
3625 }  // namespace internal
3626 
3627 // On Windows, by default, empty-base class optimization does not work,
3628 // which means even if the base class is empty struct, it still consumes one
3629 // byte for its body. __declspec(empty_bases) enables the optimization.
3630 // cf)
3631 // https://blogs.msdn.microsoft.com/vcblog/2016/03/30/optimizing-the-layout-of-empty-base-classes-in-vs2015-update-2-3/
3632 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) && \
3633     !PERFETTO_BUILDFLAG(PERFETTO_COMPILER_GCC)
3634 #define OPTIONAL_DECLSPEC_EMPTY_BASES __declspec(empty_bases)
3635 #else
3636 #define OPTIONAL_DECLSPEC_EMPTY_BASES
3637 #endif
3638 
3639 // base::Optional is a Chromium version of the C++17 optional class:
3640 // std::optional documentation:
3641 // http://en.cppreference.com/w/cpp/utility/optional
3642 // Chromium documentation:
3643 // https://chromium.googlesource.com/chromium/src/+/master/docs/optional.md
3644 //
3645 // These are the differences between the specification and the implementation:
3646 // - Constructors do not use 'constexpr' as it is a C++14 extension.
3647 // - 'constexpr' might be missing in some places for reasons specified locally.
3648 // - No exceptions are thrown, because they are banned from Chromium.
3649 //   Marked noexcept for only move constructor and move assign operators.
3650 // - All the non-members are in the 'base' namespace instead of 'std'.
3651 //
3652 // Note that T cannot have a constructor T(Optional<T>) etc. Optional<T>
3653 // PERFETTO_CHECKs T's constructor (specifically via IsConvertibleFromOptional),
3654 // and in the PERFETTO_CHECK whether T can be constructible from Optional<T>,
3655 // which is recursive so it does not work. As of Feb 2018, std::optional C++17
3656 // implementation in both clang and gcc has same limitation. MSVC SFINAE looks
3657 // to have different behavior, but anyway it reports an error, too.
3658 //
3659 // This file is a modified version of optional.h from Chromium at revision
3660 // 5e71bd454e60511c1293c0c686544aaa76094424. The changes remove C++14/C++17
3661 // specific code and replace with C++11 counterparts.
3662 template <typename T>
3663 class OPTIONAL_DECLSPEC_EMPTY_BASES Optional
3664     : public internal::OptionalBase<T>,
3665       public internal::CopyConstructible<std::is_copy_constructible<T>::value>,
3666       public internal::MoveConstructible<std::is_move_constructible<T>::value>,
3667       public internal::CopyAssignable<std::is_copy_constructible<T>::value &&
3668                                       std::is_copy_assignable<T>::value>,
3669       public internal::MoveAssignable<std::is_move_constructible<T>::value &&
3670                                       std::is_move_assignable<T>::value> {
3671  public:
3672 #undef OPTIONAL_DECLSPEC_EMPTY_BASES
3673   using value_type = T;
3674 
3675   // Defer default/copy/move constructor implementation to OptionalBase.
3676   constexpr Optional() = default;
3677   constexpr Optional(const Optional& other) = default;
3678   constexpr Optional(Optional&& other) noexcept(
3679       std::is_nothrow_move_constructible<T>::value) = default;
3680 
Optional(nullopt_t)3681   constexpr Optional(nullopt_t) {}  // NOLINT(runtime/explicit)
3682 
3683   // Converting copy constructor. "explicit" only if
3684   // std::is_convertible<const U&, T>::value is false. It is implemented by
3685   // declaring two almost same constructors, but that condition in enable_if_t
3686   // is different, so that either one is chosen, thanks to SFINAE.
3687   template <typename U,
3688             typename std::enable_if<
3689                 std::is_constructible<T, const U&>::value &&
3690                     !internal::IsConvertibleFromOptional<T, U>::value &&
3691                     std::is_convertible<const U&, T>::value,
3692                 bool>::type = false>
Optional(const Optional<U> & other)3693   Optional(const Optional<U>& other) : internal::OptionalBase<T>(other) {}
3694 
3695   template <typename U,
3696             typename std::enable_if<
3697                 std::is_constructible<T, const U&>::value &&
3698                     !internal::IsConvertibleFromOptional<T, U>::value &&
3699                     !std::is_convertible<const U&, T>::value,
3700                 bool>::type = false>
Optional(const Optional<U> & other)3701   explicit Optional(const Optional<U>& other)
3702       : internal::OptionalBase<T>(other) {}
3703 
3704   // Converting move constructor. Similar to converting copy constructor,
3705   // declaring two (explicit and non-explicit) constructors.
3706   template <typename U,
3707             typename std::enable_if<
3708                 std::is_constructible<T, U&&>::value &&
3709                     !internal::IsConvertibleFromOptional<T, U>::value &&
3710                     std::is_convertible<U&&, T>::value,
3711                 bool>::type = false>
Optional(Optional<U> && other)3712   Optional(Optional<U>&& other) : internal::OptionalBase<T>(std::move(other)) {}
3713 
3714   template <typename U,
3715             typename std::enable_if<
3716                 std::is_constructible<T, U&&>::value &&
3717                     !internal::IsConvertibleFromOptional<T, U>::value &&
3718                     !std::is_convertible<U&&, T>::value,
3719                 bool>::type = false>
Optional(Optional<U> && other)3720   explicit Optional(Optional<U>&& other)
3721       : internal::OptionalBase<T>(std::move(other)) {}
3722 
3723   template <class... Args>
Optional(in_place_t,Args &&...args)3724   constexpr explicit Optional(in_place_t, Args&&... args)
3725       : internal::OptionalBase<T>(in_place, std::forward<Args>(args)...) {}
3726 
3727   template <class U,
3728             class... Args,
3729             class = typename std::enable_if<
3730                 std::is_constructible<value_type,
3731                                       std::initializer_list<U>&,
3732                                       Args...>::value>::type>
Optional(in_place_t,std::initializer_list<U> il,Args &&...args)3733   constexpr explicit Optional(in_place_t,
3734                               std::initializer_list<U> il,
3735                               Args&&... args)
3736       : internal::OptionalBase<T>(in_place, il, std::forward<Args>(args)...) {}
3737 
3738   // Forward value constructor. Similar to converting constructors,
3739   // conditionally explicit.
3740   template <
3741       typename U = value_type,
3742       typename std::enable_if<
3743           std::is_constructible<T, U&&>::value &&
3744               !std::is_same<internal::RemoveCvRefT<U>, in_place_t>::value &&
3745               !std::is_same<internal::RemoveCvRefT<U>, Optional<T>>::value &&
3746               std::is_convertible<U&&, T>::value,
3747           bool>::type = false>
Optional(U && value)3748   constexpr Optional(U&& value)
3749       : internal::OptionalBase<T>(in_place, std::forward<U>(value)) {}
3750 
3751   template <
3752       typename U = value_type,
3753       typename std::enable_if<
3754           std::is_constructible<T, U&&>::value &&
3755               !std::is_same<internal::RemoveCvRefT<U>, in_place_t>::value &&
3756               !std::is_same<internal::RemoveCvRefT<U>, Optional<T>>::value &&
3757               !std::is_convertible<U&&, T>::value,
3758           bool>::type = false>
Optional(U && value)3759   constexpr explicit Optional(U&& value)
3760       : internal::OptionalBase<T>(in_place, std::forward<U>(value)) {}
3761 
3762   ~Optional() = default;
3763 
3764   // Defer copy-/move- assign operator implementation to OptionalBase.
3765   Optional& operator=(const Optional& other) = default;
3766   Optional& operator=(Optional&& other) noexcept(
3767       std::is_nothrow_move_assignable<T>::value&&
3768           std::is_nothrow_move_constructible<T>::value) = default;
3769 
operator =(nullopt_t)3770   Optional& operator=(nullopt_t) {
3771     FreeIfNeeded();
3772     return *this;
3773   }
3774 
3775   // Perfect-forwarded assignment.
3776   template <typename U>
3777   typename std::enable_if<
3778       !std::is_same<internal::RemoveCvRefT<U>, Optional<T>>::value &&
3779           std::is_constructible<T, U>::value &&
3780           std::is_assignable<T&, U>::value &&
3781           (!std::is_scalar<T>::value ||
3782            !std::is_same<typename std::decay<U>::type, T>::value),
3783       Optional&>::type
operator =(U && value)3784   operator=(U&& value) {
3785     InitOrAssign(std::forward<U>(value));
3786     return *this;
3787   }
3788 
3789   // Copy assign the state of other.
3790   template <typename U>
3791   typename std::enable_if<!internal::IsAssignableFromOptional<T, U>::value &&
3792                               std::is_constructible<T, const U&>::value &&
3793                               std::is_assignable<T&, const U&>::value,
3794                           Optional&>::type
operator =(const Optional<U> & other)3795   operator=(const Optional<U>& other) {
3796     CopyAssign(other);
3797     return *this;
3798   }
3799 
3800   // Move assign the state of other.
3801   template <typename U>
3802   typename std::enable_if<!internal::IsAssignableFromOptional<T, U>::value &&
3803                               std::is_constructible<T, U>::value &&
3804                               std::is_assignable<T&, U>::value,
3805                           Optional&>::type
operator =(Optional<U> && other)3806   operator=(Optional<U>&& other) {
3807     MoveAssign(std::move(other));
3808     return *this;
3809   }
3810 
operator ->() const3811   const T* operator->() const {
3812     PERFETTO_DCHECK(storage_.is_populated_);
3813     return &storage_.value_;
3814   }
3815 
operator ->()3816   T* operator->() {
3817     PERFETTO_DCHECK(storage_.is_populated_);
3818     return &storage_.value_;
3819   }
3820 
operator *() const3821   const T& operator*() const& {
3822     PERFETTO_DCHECK(storage_.is_populated_);
3823     return storage_.value_;
3824   }
3825 
operator *()3826   T& operator*() & {
3827     PERFETTO_DCHECK(storage_.is_populated_);
3828     return storage_.value_;
3829   }
3830 
operator *() const3831   const T&& operator*() const&& {
3832     PERFETTO_DCHECK(storage_.is_populated_);
3833     return std::move(storage_.value_);
3834   }
3835 
operator *()3836   T&& operator*() && {
3837     PERFETTO_DCHECK(storage_.is_populated_);
3838     return std::move(storage_.value_);
3839   }
3840 
operator bool() const3841   constexpr explicit operator bool() const { return storage_.is_populated_; }
3842 
has_value() const3843   constexpr bool has_value() const { return storage_.is_populated_; }
3844 
value()3845   T& value() & {
3846     PERFETTO_CHECK(storage_.is_populated_);
3847     return storage_.value_;
3848   }
3849 
value() const3850   const T& value() const& {
3851     PERFETTO_CHECK(storage_.is_populated_);
3852     return storage_.value_;
3853   }
3854 
value()3855   T&& value() && {
3856     PERFETTO_CHECK(storage_.is_populated_);
3857     return std::move(storage_.value_);
3858   }
3859 
value() const3860   const T&& value() const&& {
3861     PERFETTO_CHECK(storage_.is_populated_);
3862     return std::move(storage_.value_);
3863   }
3864 
3865   template <class U>
value_or(U && default_value) const3866   constexpr T value_or(U&& default_value) const& {
3867     static_assert(std::is_convertible<U, T>::value,
3868                   "U must be convertible to T");
3869     return storage_.is_populated_
3870                ? storage_.value_
3871                : static_cast<T>(std::forward<U>(default_value));
3872   }
3873 
3874   template <class U>
value_or(U && default_value)3875   T value_or(U&& default_value) && {
3876     static_assert(std::is_convertible<U, T>::value,
3877                   "U must be convertible to T");
3878     return storage_.is_populated_
3879                ? std::move(storage_.value_)
3880                : static_cast<T>(std::forward<U>(default_value));
3881   }
3882 
swap(Optional & other)3883   void swap(Optional& other) {
3884     if (!storage_.is_populated_ && !other.storage_.is_populated_)
3885       return;
3886 
3887     if (storage_.is_populated_ != other.storage_.is_populated_) {
3888       if (storage_.is_populated_) {
3889         other.storage_.Init(std::move(storage_.value_));
3890         FreeIfNeeded();
3891       } else {
3892         storage_.Init(std::move(other.storage_.value_));
3893         other.FreeIfNeeded();
3894       }
3895       return;
3896     }
3897 
3898     PERFETTO_DCHECK(storage_.is_populated_ && other.storage_.is_populated_);
3899     using std::swap;
3900     swap(**this, *other);
3901   }
3902 
reset()3903   void reset() { FreeIfNeeded(); }
3904 
3905   template <class... Args>
emplace(Args &&...args)3906   T& emplace(Args&&... args) {
3907     FreeIfNeeded();
3908     storage_.Init(std::forward<Args>(args)...);
3909     return storage_.value_;
3910   }
3911 
3912   template <class U, class... Args>
3913   typename std::enable_if<
3914       std::is_constructible<T, std::initializer_list<U>&, Args&&...>::value,
3915       T&>::type
emplace(std::initializer_list<U> il,Args &&...args)3916   emplace(std::initializer_list<U> il, Args&&... args) {
3917     FreeIfNeeded();
3918     storage_.Init(il, std::forward<Args>(args)...);
3919     return storage_.value_;
3920   }
3921 
3922  private:
3923   // Accessing template base class's protected member needs explicit
3924   // declaration to do so.
3925   using internal::OptionalBase<T>::CopyAssign;
3926   using internal::OptionalBase<T>::FreeIfNeeded;
3927   using internal::OptionalBase<T>::InitOrAssign;
3928   using internal::OptionalBase<T>::MoveAssign;
3929   using internal::OptionalBase<T>::storage_;
3930 };
3931 
3932 // Here after defines comparation operators. The definition follows
3933 // http://en.cppreference.com/w/cpp/utility/optional/operator_cmp
3934 // while bool() casting is replaced by has_value() to meet the chromium
3935 // style guide.
3936 template <class T, class U>
operator ==(const Optional<T> & lhs,const Optional<U> & rhs)3937 bool operator==(const Optional<T>& lhs, const Optional<U>& rhs) {
3938   if (lhs.has_value() != rhs.has_value())
3939     return false;
3940   if (!lhs.has_value())
3941     return true;
3942   return *lhs == *rhs;
3943 }
3944 
3945 template <class T, class U>
operator !=(const Optional<T> & lhs,const Optional<U> & rhs)3946 bool operator!=(const Optional<T>& lhs, const Optional<U>& rhs) {
3947   if (lhs.has_value() != rhs.has_value())
3948     return true;
3949   if (!lhs.has_value())
3950     return false;
3951   return *lhs != *rhs;
3952 }
3953 
3954 template <class T, class U>
operator <(const Optional<T> & lhs,const Optional<U> & rhs)3955 bool operator<(const Optional<T>& lhs, const Optional<U>& rhs) {
3956   if (!rhs.has_value())
3957     return false;
3958   if (!lhs.has_value())
3959     return true;
3960   return *lhs < *rhs;
3961 }
3962 
3963 template <class T, class U>
operator <=(const Optional<T> & lhs,const Optional<U> & rhs)3964 bool operator<=(const Optional<T>& lhs, const Optional<U>& rhs) {
3965   if (!lhs.has_value())
3966     return true;
3967   if (!rhs.has_value())
3968     return false;
3969   return *lhs <= *rhs;
3970 }
3971 
3972 template <class T, class U>
operator >(const Optional<T> & lhs,const Optional<U> & rhs)3973 bool operator>(const Optional<T>& lhs, const Optional<U>& rhs) {
3974   if (!lhs.has_value())
3975     return false;
3976   if (!rhs.has_value())
3977     return true;
3978   return *lhs > *rhs;
3979 }
3980 
3981 template <class T, class U>
operator >=(const Optional<T> & lhs,const Optional<U> & rhs)3982 bool operator>=(const Optional<T>& lhs, const Optional<U>& rhs) {
3983   if (!rhs.has_value())
3984     return true;
3985   if (!lhs.has_value())
3986     return false;
3987   return *lhs >= *rhs;
3988 }
3989 
3990 template <class T>
operator ==(const Optional<T> & opt,nullopt_t)3991 constexpr bool operator==(const Optional<T>& opt, nullopt_t) {
3992   return !opt;
3993 }
3994 
3995 template <class T>
operator ==(nullopt_t,const Optional<T> & opt)3996 constexpr bool operator==(nullopt_t, const Optional<T>& opt) {
3997   return !opt;
3998 }
3999 
4000 template <class T>
operator !=(const Optional<T> & opt,nullopt_t)4001 constexpr bool operator!=(const Optional<T>& opt, nullopt_t) {
4002   return opt.has_value();
4003 }
4004 
4005 template <class T>
operator !=(nullopt_t,const Optional<T> & opt)4006 constexpr bool operator!=(nullopt_t, const Optional<T>& opt) {
4007   return opt.has_value();
4008 }
4009 
4010 template <class T>
operator <(const Optional<T> &,nullopt_t)4011 constexpr bool operator<(const Optional<T>&, nullopt_t) {
4012   return false;
4013 }
4014 
4015 template <class T>
operator <(nullopt_t,const Optional<T> & opt)4016 constexpr bool operator<(nullopt_t, const Optional<T>& opt) {
4017   return opt.has_value();
4018 }
4019 
4020 template <class T>
operator <=(const Optional<T> & opt,nullopt_t)4021 constexpr bool operator<=(const Optional<T>& opt, nullopt_t) {
4022   return !opt;
4023 }
4024 
4025 template <class T>
operator <=(nullopt_t,const Optional<T> &)4026 constexpr bool operator<=(nullopt_t, const Optional<T>&) {
4027   return true;
4028 }
4029 
4030 template <class T>
operator >(const Optional<T> & opt,nullopt_t)4031 constexpr bool operator>(const Optional<T>& opt, nullopt_t) {
4032   return opt.has_value();
4033 }
4034 
4035 template <class T>
operator >(nullopt_t,const Optional<T> &)4036 constexpr bool operator>(nullopt_t, const Optional<T>&) {
4037   return false;
4038 }
4039 
4040 template <class T>
operator >=(const Optional<T> &,nullopt_t)4041 constexpr bool operator>=(const Optional<T>&, nullopt_t) {
4042   return true;
4043 }
4044 
4045 template <class T>
operator >=(nullopt_t,const Optional<T> & opt)4046 constexpr bool operator>=(nullopt_t, const Optional<T>& opt) {
4047   return !opt;
4048 }
4049 
4050 template <class T, class U>
operator ==(const Optional<T> & opt,const U & value)4051 constexpr bool operator==(const Optional<T>& opt, const U& value) {
4052   return opt.has_value() ? *opt == value : false;
4053 }
4054 
4055 template <class T, class U>
operator ==(const U & value,const Optional<T> & opt)4056 constexpr bool operator==(const U& value, const Optional<T>& opt) {
4057   return opt.has_value() ? value == *opt : false;
4058 }
4059 
4060 template <class T, class U>
operator !=(const Optional<T> & opt,const U & value)4061 constexpr bool operator!=(const Optional<T>& opt, const U& value) {
4062   return opt.has_value() ? *opt != value : true;
4063 }
4064 
4065 template <class T, class U>
operator !=(const U & value,const Optional<T> & opt)4066 constexpr bool operator!=(const U& value, const Optional<T>& opt) {
4067   return opt.has_value() ? value != *opt : true;
4068 }
4069 
4070 template <class T, class U>
operator <(const Optional<T> & opt,const U & value)4071 constexpr bool operator<(const Optional<T>& opt, const U& value) {
4072   return opt.has_value() ? *opt < value : true;
4073 }
4074 
4075 template <class T, class U>
operator <(const U & value,const Optional<T> & opt)4076 constexpr bool operator<(const U& value, const Optional<T>& opt) {
4077   return opt.has_value() ? value < *opt : false;
4078 }
4079 
4080 template <class T, class U>
operator <=(const Optional<T> & opt,const U & value)4081 constexpr bool operator<=(const Optional<T>& opt, const U& value) {
4082   return opt.has_value() ? *opt <= value : true;
4083 }
4084 
4085 template <class T, class U>
operator <=(const U & value,const Optional<T> & opt)4086 constexpr bool operator<=(const U& value, const Optional<T>& opt) {
4087   return opt.has_value() ? value <= *opt : false;
4088 }
4089 
4090 template <class T, class U>
operator >(const Optional<T> & opt,const U & value)4091 constexpr bool operator>(const Optional<T>& opt, const U& value) {
4092   return opt.has_value() ? *opt > value : false;
4093 }
4094 
4095 template <class T, class U>
operator >(const U & value,const Optional<T> & opt)4096 constexpr bool operator>(const U& value, const Optional<T>& opt) {
4097   return opt.has_value() ? value > *opt : true;
4098 }
4099 
4100 template <class T, class U>
operator >=(const Optional<T> & opt,const U & value)4101 constexpr bool operator>=(const Optional<T>& opt, const U& value) {
4102   return opt.has_value() ? *opt >= value : false;
4103 }
4104 
4105 template <class T, class U>
operator >=(const U & value,const Optional<T> & opt)4106 constexpr bool operator>=(const U& value, const Optional<T>& opt) {
4107   return opt.has_value() ? value >= *opt : true;
4108 }
4109 
4110 template <class T>
make_optional(T && value)4111 constexpr Optional<typename std::decay<T>::type> make_optional(T&& value) {
4112   return Optional<typename std::decay<T>::type>(std::forward<T>(value));
4113 }
4114 
4115 template <class T, class... Args>
make_optional(Args &&...args)4116 constexpr Optional<T> make_optional(Args&&... args) {
4117   return Optional<T>(in_place, std::forward<Args>(args)...);
4118 }
4119 
4120 template <class T, class U, class... Args>
make_optional(std::initializer_list<U> il,Args &&...args)4121 constexpr Optional<T> make_optional(std::initializer_list<U> il,
4122                                     Args&&... args) {
4123   return Optional<T>(in_place, il, std::forward<Args>(args)...);
4124 }
4125 
4126 // Partial specialization for a function template is not allowed. Also, it is
4127 // not allowed to add overload function to std namespace, while it is allowed
4128 // to specialize the template in std. Thus, swap() (kind of) overloading is
4129 // defined in base namespace, instead.
4130 template <class T>
4131 typename std::enable_if<std::is_move_constructible<T>::value &&
4132                         internal::IsSwappable<T>::value>::type
swap(Optional<T> & lhs,Optional<T> & rhs)4133 swap(Optional<T>& lhs, Optional<T>& rhs) {
4134   lhs.swap(rhs);
4135 }
4136 
4137 }  // namespace base
4138 }  // namespace perfetto
4139 
4140 template <class T>
4141 struct std::hash<perfetto::base::Optional<T>> {
operator ()std::hash4142   size_t operator()(const perfetto::base::Optional<T>& opt) const {
4143     return opt == perfetto::base::nullopt ? 0 : std::hash<T>()(*opt);
4144   }
4145 };
4146 
4147 #endif  // INCLUDE_PERFETTO_EXT_BASE_OPTIONAL_H_
4148 // gen_amalgamated begin header: include/perfetto/ext/base/string_view.h
4149 // gen_amalgamated begin header: include/perfetto/ext/base/hash.h
4150 /*
4151  * Copyright (C) 2019 The Android Open Source Project
4152  *
4153  * Licensed under the Apache License, Version 2.0 (the "License");
4154  * you may not use this file except in compliance with the License.
4155  * You may obtain a copy of the License at
4156  *
4157  *      http://www.apache.org/licenses/LICENSE-2.0
4158  *
4159  * Unless required by applicable law or agreed to in writing, software
4160  * distributed under the License is distributed on an "AS IS" BASIS,
4161  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4162  * See the License for the specific language governing permissions and
4163  * limitations under the License.
4164  */
4165 
4166 #ifndef INCLUDE_PERFETTO_EXT_BASE_HASH_H_
4167 #define INCLUDE_PERFETTO_EXT_BASE_HASH_H_
4168 
4169 #include <stddef.h>
4170 #include <stdint.h>
4171 #include <type_traits>
4172 
4173 namespace perfetto {
4174 namespace base {
4175 
4176 // A helper class which computes a 64-bit hash of the input data.
4177 // The algorithm used is FNV-1a as it is fast and easy to implement and has
4178 // relatively few collisions.
4179 // WARNING: This hash function should not be used for any cryptographic purpose.
4180 class Hash {
4181  public:
4182   // Creates an empty hash object
Hash()4183   Hash() {}
4184 
4185   // Hashes a numeric value.
4186   template <
4187       typename T,
4188       typename std::enable_if<std::is_arithmetic<T>::value, bool>::type = true>
Update(T data)4189   void Update(T data) {
4190     Update(reinterpret_cast<const char*>(&data), sizeof(data));
4191   }
4192 
4193   // Hashes a byte array.
Update(const char * data,size_t size)4194   void Update(const char* data, size_t size) {
4195     for (size_t i = 0; i < size; i++) {
4196       result_ ^= static_cast<uint8_t>(data[i]);
4197       result_ *= kFnv1a64Prime;
4198     }
4199   }
4200 
digest()4201   uint64_t digest() { return result_; }
4202 
4203  private:
4204   static constexpr uint64_t kFnv1a64OffsetBasis = 0xcbf29ce484222325;
4205   static constexpr uint64_t kFnv1a64Prime = 0x100000001b3;
4206 
4207   uint64_t result_ = kFnv1a64OffsetBasis;
4208 };
4209 
4210 }  // namespace base
4211 }  // namespace perfetto
4212 
4213 #endif  // INCLUDE_PERFETTO_EXT_BASE_HASH_H_
4214 /*
4215  * Copyright (C) 2018 The Android Open Source Project
4216  *
4217  * Licensed under the Apache License, Version 2.0 (the "License");
4218  * you may not use this file except in compliance with the License.
4219  * You may obtain a copy of the License at
4220  *
4221  *      http://www.apache.org/licenses/LICENSE-2.0
4222  *
4223  * Unless required by applicable law or agreed to in writing, software
4224  * distributed under the License is distributed on an "AS IS" BASIS,
4225  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4226  * See the License for the specific language governing permissions and
4227  * limitations under the License.
4228  */
4229 
4230 #ifndef INCLUDE_PERFETTO_EXT_BASE_STRING_VIEW_H_
4231 #define INCLUDE_PERFETTO_EXT_BASE_STRING_VIEW_H_
4232 
4233 #include <string.h>
4234 
4235 #include <algorithm>
4236 #include <string>
4237 
4238 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
4239 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
4240 // gen_amalgamated expanded: #include "perfetto/ext/base/hash.h"
4241 
4242 namespace perfetto {
4243 namespace base {
4244 
4245 // A string-like object that refers to a non-owned piece of memory.
4246 // Strings are internally NOT null terminated.
4247 class StringView {
4248  public:
4249   static constexpr size_t npos = static_cast<size_t>(-1);
4250 
StringView()4251   StringView() : data_(nullptr), size_(0) {}
4252   StringView(const StringView&) = default;
4253   StringView& operator=(const StringView&) = default;
StringView(const char * data,size_t size)4254   StringView(const char* data, size_t size) : data_(data), size_(size) {
4255     PERFETTO_DCHECK(size == 0 || data != nullptr);
4256   }
4257 
4258   // Allow implicit conversion from any class that has a |data| and |size| field
4259   // and has the kConvertibleToStringView trait (e.g., protozero::ConstChars).
4260   template <typename T, typename = std::enable_if<T::kConvertibleToStringView>>
StringView(const T & x)4261   StringView(const T& x) : StringView(x.data, x.size) {
4262     PERFETTO_DCHECK(x.size == 0 || x.data != nullptr);
4263   }
4264 
4265   // Creates a StringView from a null-terminated C string.
4266   // Deliberately not "explicit".
StringView(const char * cstr)4267   StringView(const char* cstr) : data_(cstr), size_(strlen(cstr)) {
4268     PERFETTO_DCHECK(cstr != nullptr);
4269   }
4270 
4271   // This instead has to be explicit, as creating a StringView out of a
4272   // std::string can be subtle.
StringView(const std::string & str)4273   explicit StringView(const std::string& str)
4274       : data_(str.data()), size_(str.size()) {}
4275 
empty() const4276   bool empty() const { return size_ == 0; }
size() const4277   size_t size() const { return size_; }
data() const4278   const char* data() const { return data_; }
begin() const4279   const char* begin() const { return data_; }
end() const4280   const char* end() const { return data_ + size_; }
4281 
at(size_t pos) const4282   char at(size_t pos) const {
4283     PERFETTO_DCHECK(pos < size_);
4284     return data_[pos];
4285   }
4286 
find(char c,size_t start_pos=0) const4287   size_t find(char c, size_t start_pos = 0) const {
4288     for (size_t i = start_pos; i < size_; ++i) {
4289       if (data_[i] == c)
4290         return i;
4291     }
4292     return npos;
4293   }
4294 
find(const StringView & str,size_t start_pos=0) const4295   size_t find(const StringView& str, size_t start_pos = 0) const {
4296     if (start_pos > size())
4297       return npos;
4298     auto it = std::search(begin() + start_pos, end(), str.begin(), str.end());
4299     size_t pos = static_cast<size_t>(it - begin());
4300     return pos + str.size() <= size() ? pos : npos;
4301   }
4302 
find(const char * str,size_t start_pos=0) const4303   size_t find(const char* str, size_t start_pos = 0) const {
4304     return find(StringView(str), start_pos);
4305   }
4306 
rfind(char c) const4307   size_t rfind(char c) const {
4308     for (size_t i = size_; i > 0; --i) {
4309       if (data_[i - 1] == c)
4310         return i - 1;
4311     }
4312     return npos;
4313   }
4314 
substr(size_t pos,size_t count=npos) const4315   StringView substr(size_t pos, size_t count = npos) const {
4316     if (pos >= size_)
4317       return StringView("", 0);
4318     size_t rcount = std::min(count, size_ - pos);
4319     return StringView(data_ + pos, rcount);
4320   }
4321 
CaseInsensitiveEq(const StringView & other)4322   bool CaseInsensitiveEq(const StringView& other) {
4323     if (size() != other.size())
4324       return false;
4325     if (size() == 0)
4326       return true;
4327 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
4328     return _strnicmp(data(), other.data(), size()) == 0;
4329 #else
4330     return strncasecmp(data(), other.data(), size()) == 0;
4331 #endif
4332   }
4333 
ToStdString() const4334   std::string ToStdString() const {
4335     return data_ == nullptr ? "" : std::string(data_, size_);
4336   }
4337 
Hash() const4338   uint64_t Hash() const {
4339     base::Hash hasher;
4340     hasher.Update(data_, size_);
4341     return hasher.digest();
4342   }
4343 
4344  private:
4345   const char* data_ = nullptr;
4346   size_t size_ = 0;
4347 };
4348 
operator ==(const StringView & x,const StringView & y)4349 inline bool operator==(const StringView& x, const StringView& y) {
4350   if (x.size() != y.size())
4351     return false;
4352   if (x.size() == 0)
4353     return true;
4354   return memcmp(x.data(), y.data(), x.size()) == 0;
4355 }
4356 
operator !=(const StringView & x,const StringView & y)4357 inline bool operator!=(const StringView& x, const StringView& y) {
4358   return !(x == y);
4359 }
4360 
operator <(const StringView & x,const StringView & y)4361 inline bool operator<(const StringView& x, const StringView& y) {
4362   auto size = std::min(x.size(), y.size());
4363   if (size == 0)
4364     return x.size() < y.size();
4365   int result = memcmp(x.data(), y.data(), size);
4366   return result < 0 || (result == 0 && x.size() < y.size());
4367 }
4368 
operator >=(const StringView & x,const StringView & y)4369 inline bool operator>=(const StringView& x, const StringView& y) {
4370   return !(x < y);
4371 }
4372 
operator >(const StringView & x,const StringView & y)4373 inline bool operator>(const StringView& x, const StringView& y) {
4374   return y < x;
4375 }
4376 
operator <=(const StringView & x,const StringView & y)4377 inline bool operator<=(const StringView& x, const StringView& y) {
4378   return !(y < x);
4379 }
4380 
4381 }  // namespace base
4382 }  // namespace perfetto
4383 
4384 template <>
4385 struct std::hash<::perfetto::base::StringView> {
operator ()std::hash4386   size_t operator()(const ::perfetto::base::StringView& sv) const {
4387     return static_cast<size_t>(sv.Hash());
4388   }
4389 };
4390 
4391 #endif  // INCLUDE_PERFETTO_EXT_BASE_STRING_VIEW_H_
4392 /*
4393  * Copyright (C) 2018 The Android Open Source Project
4394  *
4395  * Licensed under the Apache License, Version 2.0 (the "License");
4396  * you may not use this file except in compliance with the License.
4397  * You may obtain a copy of the License at
4398  *
4399  *      http://www.apache.org/licenses/LICENSE-2.0
4400  *
4401  * Unless required by applicable law or agreed to in writing, software
4402  * distributed under the License is distributed on an "AS IS" BASIS,
4403  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4404  * See the License for the specific language governing permissions and
4405  * limitations under the License.
4406  */
4407 
4408 #ifndef INCLUDE_PERFETTO_EXT_BASE_STRING_UTILS_H_
4409 #define INCLUDE_PERFETTO_EXT_BASE_STRING_UTILS_H_
4410 
4411 #include <string>
4412 #include <vector>
4413 
4414 #include <inttypes.h>
4415 #include <stdlib.h>
4416 
4417 // gen_amalgamated expanded: #include "perfetto/ext/base/optional.h"
4418 // gen_amalgamated expanded: #include "perfetto/ext/base/string_view.h"
4419 
4420 namespace perfetto {
4421 namespace base {
4422 
4423 std::string QuoteAndEscapeControlCodes(const std::string& raw);
4424 
Lowercase(char c)4425 inline char Lowercase(char c) {
4426   return ('A' <= c && c <= 'Z') ? static_cast<char>(c - ('A' - 'a')) : c;
4427 }
4428 
Uppercase(char c)4429 inline char Uppercase(char c) {
4430   return ('a' <= c && c <= 'z') ? static_cast<char>(c + ('A' - 'a')) : c;
4431 }
4432 
CStringToUInt32(const char * s,int base=10)4433 inline Optional<uint32_t> CStringToUInt32(const char* s, int base = 10) {
4434   char* endptr = nullptr;
4435   auto value = static_cast<uint32_t>(strtoul(s, &endptr, base));
4436   return (*s && !*endptr) ? base::make_optional(value) : base::nullopt;
4437 }
4438 
CStringToInt32(const char * s,int base=10)4439 inline Optional<int32_t> CStringToInt32(const char* s, int base = 10) {
4440   char* endptr = nullptr;
4441   auto value = static_cast<int32_t>(strtol(s, &endptr, base));
4442   return (*s && !*endptr) ? base::make_optional(value) : base::nullopt;
4443 }
4444 
4445 // Note: it saturates to 7fffffffffffffff if parsing a hex number >= 0x8000...
CStringToInt64(const char * s,int base=10)4446 inline Optional<int64_t> CStringToInt64(const char* s, int base = 10) {
4447   char* endptr = nullptr;
4448   auto value = static_cast<int64_t>(strtoll(s, &endptr, base));
4449   return (*s && !*endptr) ? base::make_optional(value) : base::nullopt;
4450 }
4451 
CStringToUInt64(const char * s,int base=10)4452 inline Optional<uint64_t> CStringToUInt64(const char* s, int base = 10) {
4453   char* endptr = nullptr;
4454   auto value = static_cast<uint64_t>(strtoull(s, &endptr, base));
4455   return (*s && !*endptr) ? base::make_optional(value) : base::nullopt;
4456 }
4457 
4458 double StrToD(const char* nptr, char** endptr);
4459 
CStringToDouble(const char * s)4460 inline Optional<double> CStringToDouble(const char* s) {
4461   char* endptr = nullptr;
4462   double value = StrToD(s, &endptr);
4463   Optional<double> result(base::nullopt);
4464   if (*s != '\0' && *endptr == '\0')
4465     result = value;
4466   return result;
4467 }
4468 
StringToUInt32(const std::string & s,int base=10)4469 inline Optional<uint32_t> StringToUInt32(const std::string& s, int base = 10) {
4470   return CStringToUInt32(s.c_str(), base);
4471 }
4472 
StringToInt32(const std::string & s,int base=10)4473 inline Optional<int32_t> StringToInt32(const std::string& s, int base = 10) {
4474   return CStringToInt32(s.c_str(), base);
4475 }
4476 
StringToUInt64(const std::string & s,int base=10)4477 inline Optional<uint64_t> StringToUInt64(const std::string& s, int base = 10) {
4478   return CStringToUInt64(s.c_str(), base);
4479 }
4480 
StringToInt64(const std::string & s,int base=10)4481 inline Optional<int64_t> StringToInt64(const std::string& s, int base = 10) {
4482   return CStringToInt64(s.c_str(), base);
4483 }
4484 
StringToDouble(const std::string & s)4485 inline Optional<double> StringToDouble(const std::string& s) {
4486   return CStringToDouble(s.c_str());
4487 }
4488 
4489 bool StartsWith(const std::string& str, const std::string& prefix);
4490 bool EndsWith(const std::string& str, const std::string& suffix);
4491 bool Contains(const std::string& haystack, const std::string& needle);
4492 bool Contains(const std::string& haystack, char needle);
4493 size_t Find(const StringView& needle, const StringView& haystack);
4494 bool CaseInsensitiveEqual(const std::string& first, const std::string& second);
4495 std::string Join(const std::vector<std::string>& parts,
4496                  const std::string& delim);
4497 std::vector<std::string> SplitString(const std::string& text,
4498                                      const std::string& delimiter);
4499 std::string StripPrefix(const std::string& str, const std::string& prefix);
4500 std::string StripSuffix(const std::string& str, const std::string& suffix);
4501 std::string ToLower(const std::string& str);
4502 std::string ToUpper(const std::string& str);
4503 std::string StripChars(const std::string& str,
4504                        const std::string& chars,
4505                        char replacement);
4506 std::string ToHex(const char* data, size_t size);
ToHex(const std::string & s)4507 inline std::string ToHex(const std::string& s) {
4508   return ToHex(s.c_str(), s.size());
4509 }
4510 std::string IntToHexString(uint32_t number);
4511 std::string Uint64ToHexString(uint64_t number);
4512 std::string Uint64ToHexStringNoPrefix(uint64_t number);
4513 std::string ReplaceAll(std::string str,
4514                        const std::string& to_replace,
4515                        const std::string& replacement);
4516 std::string TrimLeading(const std::string& str);
4517 std::string Base64Encode(const void* raw, size_t size);
4518 
4519 }  // namespace base
4520 }  // namespace perfetto
4521 
4522 #endif  // INCLUDE_PERFETTO_EXT_BASE_STRING_UTILS_H_
4523 /*
4524  * Copyright (C) 2018 The Android Open Source Project
4525  *
4526  * Licensed under the Apache License, Version 2.0 (the "License");
4527  * you may not use this file except in compliance with the License.
4528  * You may obtain a copy of the License at
4529  *
4530  *      http://www.apache.org/licenses/LICENSE-2.0
4531  *
4532  * Unless required by applicable law or agreed to in writing, software
4533  * distributed under the License is distributed on an "AS IS" BASIS,
4534  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4535  * See the License for the specific language governing permissions and
4536  * limitations under the License.
4537  */
4538 
4539 // gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
4540 
4541 #include <inttypes.h>
4542 #include <locale.h>
4543 #include <string.h>
4544 
4545 #if PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
4546 #include <xlocale.h>
4547 #endif
4548 
4549 #include <algorithm>
4550 
4551 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
4552 
4553 namespace perfetto {
4554 namespace base {
4555 namespace {
4556 constexpr char kBase64Table[] =
4557     "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
4558     "abcdefghijklmnopqrstuvwxyz0123456789+/";
4559 }
4560 
4561 // Locale-independant as possible version of strtod.
StrToD(const char * nptr,char ** endptr)4562 double StrToD(const char* nptr, char** endptr) {
4563 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
4564     PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
4565     PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
4566   static auto c_locale = newlocale(LC_ALL, "C", nullptr);
4567   return strtod_l(nptr, endptr, c_locale);
4568 #else
4569   return strtod(nptr, endptr);
4570 #endif
4571 }
4572 
QuoteAndEscapeControlCodes(const std::string & raw)4573 std::string QuoteAndEscapeControlCodes(const std::string& raw) {
4574   std::string ret;
4575   for (auto it = raw.cbegin(); it != raw.cend(); it++) {
4576     switch (*it) {
4577       case '\\':
4578         ret += "\\\\";
4579         break;
4580       case '"':
4581         ret += "\\\"";
4582         break;
4583       case '/':
4584         ret += "\\/";
4585         break;
4586       case '\b':
4587         ret += "\\b";
4588         break;
4589       case '\f':
4590         ret += "\\f";
4591         break;
4592       case '\n':
4593         ret += "\\n";
4594         break;
4595       case '\r':
4596         ret += "\\r";
4597         break;
4598       case '\t':
4599         ret += "\\t";
4600         break;
4601       default:
4602         ret += *it;
4603         break;
4604     }
4605   }
4606   return '"' + ret + '"';
4607 }
4608 
StartsWith(const std::string & str,const std::string & prefix)4609 bool StartsWith(const std::string& str, const std::string& prefix) {
4610   return str.compare(0, prefix.length(), prefix) == 0;
4611 }
4612 
EndsWith(const std::string & str,const std::string & suffix)4613 bool EndsWith(const std::string& str, const std::string& suffix) {
4614   if (suffix.size() > str.size())
4615     return false;
4616   return str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
4617 }
4618 
Contains(const std::string & haystack,const std::string & needle)4619 bool Contains(const std::string& haystack, const std::string& needle) {
4620   return haystack.find(needle) != std::string::npos;
4621 }
4622 
Contains(const std::string & haystack,const char needle)4623 bool Contains(const std::string& haystack, const char needle) {
4624   return haystack.find(needle) != std::string::npos;
4625 }
4626 
Find(const StringView & needle,const StringView & haystack)4627 size_t Find(const StringView& needle, const StringView& haystack) {
4628   if (needle.empty())
4629     return 0;
4630   if (needle.size() > haystack.size())
4631     return std::string::npos;
4632   for (size_t i = 0; i < haystack.size() - (needle.size() - 1); ++i) {
4633     if (strncmp(haystack.data() + i, needle.data(), needle.size()) == 0)
4634       return i;
4635   }
4636   return std::string::npos;
4637 }
4638 
CaseInsensitiveEqual(const std::string & first,const std::string & second)4639 bool CaseInsensitiveEqual(const std::string& first, const std::string& second) {
4640   return first.size() == second.size() &&
4641          std::equal(
4642              first.begin(), first.end(), second.begin(),
4643              [](char a, char b) { return Lowercase(a) == Lowercase(b); });
4644 }
4645 
Join(const std::vector<std::string> & parts,const std::string & delim)4646 std::string Join(const std::vector<std::string>& parts,
4647                  const std::string& delim) {
4648   std::string acc;
4649   for (size_t i = 0; i < parts.size(); ++i) {
4650     acc += parts[i];
4651     if (i + 1 != parts.size()) {
4652       acc += delim;
4653     }
4654   }
4655   return acc;
4656 }
4657 
SplitString(const std::string & text,const std::string & delimiter)4658 std::vector<std::string> SplitString(const std::string& text,
4659                                      const std::string& delimiter) {
4660   PERFETTO_CHECK(!delimiter.empty());
4661 
4662   std::vector<std::string> output;
4663   size_t start = 0;
4664   size_t next;
4665   for (;;) {
4666     next = std::min(text.find(delimiter, start), text.size());
4667     if (next > start)
4668       output.emplace_back(&text[start], next - start);
4669     start = next + delimiter.size();
4670     if (start >= text.size())
4671       break;
4672   }
4673   return output;
4674 }
4675 
StripPrefix(const std::string & str,const std::string & prefix)4676 std::string StripPrefix(const std::string& str, const std::string& prefix) {
4677   return StartsWith(str, prefix) ? str.substr(prefix.size()) : str;
4678 }
4679 
StripSuffix(const std::string & str,const std::string & suffix)4680 std::string StripSuffix(const std::string& str, const std::string& suffix) {
4681   return EndsWith(str, suffix) ? str.substr(0, str.size() - suffix.size())
4682                                : str;
4683 }
4684 
ToUpper(const std::string & str)4685 std::string ToUpper(const std::string& str) {
4686   // Don't use toupper(), it depends on the locale.
4687   std::string res(str);
4688   auto end = res.end();
4689   for (auto c = res.begin(); c != end; ++c)
4690     *c = Uppercase(*c);
4691   return res;
4692 }
4693 
ToLower(const std::string & str)4694 std::string ToLower(const std::string& str) {
4695   // Don't use tolower(), it depends on the locale.
4696   std::string res(str);
4697   auto end = res.end();
4698   for (auto c = res.begin(); c != end; ++c)
4699     *c = Lowercase(*c);
4700   return res;
4701 }
4702 
ToHex(const char * data,size_t size)4703 std::string ToHex(const char* data, size_t size) {
4704   std::string hex(2 * size + 1, 'x');
4705   for (size_t i = 0; i < size; ++i) {
4706     // snprintf prints 3 characters, the two hex digits and a null byte. As we
4707     // write left to right, we keep overwriting the nullbytes, except for the
4708     // last call to snprintf.
4709     snprintf(&(hex[2 * i]), 3, "%02hhx", data[i]);
4710   }
4711   // Remove the trailing nullbyte produced by the last snprintf.
4712   hex.resize(2 * size);
4713   return hex;
4714 }
4715 
IntToHexString(uint32_t number)4716 std::string IntToHexString(uint32_t number) {
4717   size_t max_size = 11;  // Max uint32 is 0xFFFFFFFF + 1 for null byte.
4718   std::string buf;
4719   buf.resize(max_size);
4720   auto final_size = snprintf(&buf[0], max_size, "0x%02x", number);
4721   PERFETTO_DCHECK(final_size >= 0);
4722   buf.resize(static_cast<size_t>(final_size));  // Cuts off the final null byte.
4723   return buf;
4724 }
4725 
Uint64ToHexString(uint64_t number)4726 std::string Uint64ToHexString(uint64_t number) {
4727   return "0x" + Uint64ToHexStringNoPrefix(number);
4728 }
4729 
Uint64ToHexStringNoPrefix(uint64_t number)4730 std::string Uint64ToHexStringNoPrefix(uint64_t number) {
4731   size_t max_size = 17;  // Max uint64 is FFFFFFFFFFFFFFFF + 1 for null byte.
4732   std::string buf;
4733   buf.resize(max_size);
4734   auto final_size = snprintf(&buf[0], max_size, "%" PRIx64 "", number);
4735   PERFETTO_DCHECK(final_size >= 0);
4736   buf.resize(static_cast<size_t>(final_size));  // Cuts off the final null byte.
4737   return buf;
4738 }
4739 
StripChars(const std::string & str,const std::string & chars,char replacement)4740 std::string StripChars(const std::string& str,
4741                        const std::string& chars,
4742                        char replacement) {
4743   std::string res(str);
4744   const char* start = res.c_str();
4745   const char* remove = chars.c_str();
4746   for (const char* c = strpbrk(start, remove); c; c = strpbrk(c + 1, remove))
4747     res[static_cast<uintptr_t>(c - start)] = replacement;
4748   return res;
4749 }
4750 
ReplaceAll(std::string str,const std::string & to_replace,const std::string & replacement)4751 std::string ReplaceAll(std::string str,
4752                        const std::string& to_replace,
4753                        const std::string& replacement) {
4754   PERFETTO_CHECK(!to_replace.empty());
4755   size_t pos = 0;
4756   while ((pos = str.find(to_replace, pos)) != std::string::npos) {
4757     str.replace(pos, to_replace.length(), replacement);
4758     pos += replacement.length();
4759   }
4760   return str;
4761 }
4762 
TrimLeading(const std::string & str)4763 std::string TrimLeading(const std::string& str) {
4764   size_t idx = str.find_first_not_of(' ');
4765   return idx == std::string::npos ? str : str.substr(idx);
4766 }
4767 
Base64Encode(const void * raw,size_t size)4768 std::string Base64Encode(const void* raw, size_t size) {
4769   // The following three cases are based on the tables in the example
4770   // section in https://en.wikipedia.org/wiki/Base64. We process three
4771   // input bytes at a time, emitting 4 output bytes at a time.
4772   const uint8_t* ptr = static_cast<const uint8_t*>(raw);
4773   size_t ii = 0;
4774 
4775   std::string out;
4776   out.reserve((size + 2) * 4 / 3);
4777 
4778   // While possible, process three input bytes.
4779   for (; ii + 3 <= size; ii += 3) {
4780     uint32_t twentyfour_bits =
4781         (uint32_t(ptr[ii]) << 16) | (uint32_t(ptr[ii + 1]) << 8) | ptr[ii + 2];
4782     out.push_back(kBase64Table[(twentyfour_bits >> 18)]);
4783     out.push_back(kBase64Table[(twentyfour_bits >> 12) & 0x3f]);
4784     out.push_back(kBase64Table[(twentyfour_bits >> 6) & 0x3f]);
4785     out.push_back(kBase64Table[twentyfour_bits & 0x3f]);
4786   }
4787   if (ii + 2 <= size) {  // Process two input bytes.
4788     uint32_t twentyfour_bits =
4789         (uint32_t(ptr[ii]) << 16) | (uint32_t(ptr[ii + 1]) << 8);
4790     out.push_back(kBase64Table[(twentyfour_bits >> 18)]);
4791     out.push_back(kBase64Table[(twentyfour_bits >> 12) & 0x3f]);
4792     out.push_back(kBase64Table[(twentyfour_bits >> 6) & 0x3f]);
4793     out.push_back('=');  // Emit padding.
4794     return out;
4795   }
4796   if (ii + 1 <= size) {  // Process a single input byte.
4797     uint32_t twentyfour_bits = (uint32_t(ptr[ii]) << 16);
4798     out.push_back(kBase64Table[(twentyfour_bits >> 18)]);
4799     out.push_back(kBase64Table[(twentyfour_bits >> 12) & 0x3f]);
4800     out.push_back('=');  // Emit padding.
4801     out.push_back('=');  // Emit padding.
4802   }
4803   return out;
4804 }
4805 
4806 }  // namespace base
4807 }  // namespace perfetto
4808 // gen_amalgamated begin source: src/base/string_view.cc
4809 /*
4810  * Copyright (C) 2019 The Android Open Source Project
4811  *
4812  * Licensed under the Apache License, Version 2.0 (the "License");
4813  * you may not use this file except in compliance with the License.
4814  * You may obtain a copy of the License at
4815  *
4816  *      http://www.apache.org/licenses/LICENSE-2.0
4817  *
4818  * Unless required by applicable law or agreed to in writing, software
4819  * distributed under the License is distributed on an "AS IS" BASIS,
4820  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4821  * See the License for the specific language governing permissions and
4822  * limitations under the License.
4823  */
4824 
4825 // gen_amalgamated expanded: #include "perfetto/ext/base/string_view.h"
4826 
4827 namespace perfetto {
4828 namespace base {
4829 
4830 // static
4831 constexpr size_t StringView::npos;
4832 
4833 }  // namespace base
4834 }  // namespace perfetto
4835 // gen_amalgamated begin source: src/base/temp_file.cc
4836 // gen_amalgamated begin header: include/perfetto/ext/base/temp_file.h
4837 /*
4838  * Copyright (C) 2018 The Android Open Source Project
4839  *
4840  * Licensed under the Apache License, Version 2.0 (the "License");
4841  * you may not use this file except in compliance with the License.
4842  * You may obtain a copy of the License at
4843  *
4844  *      http://www.apache.org/licenses/LICENSE-2.0
4845  *
4846  * Unless required by applicable law or agreed to in writing, software
4847  * distributed under the License is distributed on an "AS IS" BASIS,
4848  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4849  * See the License for the specific language governing permissions and
4850  * limitations under the License.
4851  */
4852 
4853 #ifndef INCLUDE_PERFETTO_EXT_BASE_TEMP_FILE_H_
4854 #define INCLUDE_PERFETTO_EXT_BASE_TEMP_FILE_H_
4855 
4856 #include <string>
4857 
4858 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
4859 
4860 namespace perfetto {
4861 namespace base {
4862 
4863 std::string GetSysTempDir();
4864 
4865 class TempFile {
4866  public:
4867   static TempFile CreateUnlinked();
4868   static TempFile Create();
4869 
4870   TempFile(TempFile&&) noexcept;
4871   TempFile& operator=(TempFile&&);
4872   ~TempFile();
4873 
path() const4874   const std::string& path() const { return path_; }
fd() const4875   int fd() const { return *fd_; }
operator *() const4876   int operator*() const { return *fd_; }
4877 
4878   // Unlinks the file from the filesystem but keeps the fd() open.
4879   // It is safe to call this multiple times.
4880   void Unlink();
4881 
4882   // Releases the underlying file descriptor. Will unlink the file from the
4883   // filesystem if it was created via CreateUnlinked().
4884   ScopedFile ReleaseFD();
4885 
4886  private:
4887   TempFile();
4888   TempFile(const TempFile&) = delete;
4889   TempFile& operator=(const TempFile&) = delete;
4890 
4891   ScopedFile fd_;
4892   std::string path_;
4893 };
4894 
4895 class TempDir {
4896  public:
4897   static TempDir Create();
4898 
4899   TempDir(TempDir&&) noexcept;
4900   TempDir& operator=(TempDir&&);
4901   ~TempDir();
4902 
path() const4903   const std::string& path() const { return path_; }
4904 
4905  private:
4906   TempDir();
4907   TempDir(const TempDir&) = delete;
4908   TempDir& operator=(const TempDir&) = delete;
4909 
4910   std::string path_;
4911 };
4912 
4913 }  // namespace base
4914 }  // namespace perfetto
4915 
4916 #endif  // INCLUDE_PERFETTO_EXT_BASE_TEMP_FILE_H_
4917 /*
4918  * Copyright (C) 2018 The Android Open Source Project
4919  *
4920  * Licensed under the Apache License, Version 2.0 (the "License");
4921  * you may not use this file except in compliance with the License.
4922  * You may obtain a copy of the License at
4923  *
4924  *      http://www.apache.org/licenses/LICENSE-2.0
4925  *
4926  * Unless required by applicable law or agreed to in writing, software
4927  * distributed under the License is distributed on an "AS IS" BASIS,
4928  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4929  * See the License for the specific language governing permissions and
4930  * limitations under the License.
4931  */
4932 
4933 // gen_amalgamated expanded: #include "perfetto/ext/base/temp_file.h"
4934 
4935 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
4936 
4937 #include <stdio.h>
4938 #include <stdlib.h>
4939 #include <string.h>
4940 
4941 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
4942 #include <Windows.h>
4943 #include <direct.h>
4944 #include <fileapi.h>
4945 #include <io.h>
4946 #else
4947 #include <unistd.h>
4948 #endif
4949 
4950 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
4951 // gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
4952 // gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
4953 
4954 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
4955 namespace {
GetTempName()4956 std::string GetTempName() {
4957   char name[] = "perfetto-XXXXXX";
4958   PERFETTO_CHECK(_mktemp_s(name, sizeof(name)) == 0);
4959   return name;
4960 }
4961 }  // namespace
4962 #endif
4963 
4964 namespace perfetto {
4965 namespace base {
4966 
GetSysTempDir()4967 std::string GetSysTempDir() {
4968   const char* tmpdir = nullptr;
4969 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
4970   if ((tmpdir = getenv("TMP")))
4971     return tmpdir;
4972   if ((tmpdir = getenv("TEMP")))
4973     return tmpdir;
4974   return "C:\\TEMP";
4975 #else
4976   if ((tmpdir = getenv("TMPDIR")))
4977     return base::StripSuffix(tmpdir, "/");
4978 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
4979   return "/data/local/tmp";
4980 #else
4981   return "/tmp";
4982 #endif  // !OS_ANDROID
4983 #endif  // !OS_WIN
4984 }
4985 
4986 // static
Create()4987 TempFile TempFile::Create() {
4988   TempFile temp_file;
4989 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
4990   temp_file.path_ = GetSysTempDir() + "\\" + GetTempName();
4991   // Several tests want to read-back the temp file while still open. On Windows,
4992   // that requires FILE_SHARE_READ. FILE_SHARE_READ is NOT settable when using
4993   // the POSIX-compat equivalent function _open(). Hence the CreateFileA +
4994   // _open_osfhandle dance here.
4995   HANDLE h =
4996       ::CreateFileA(temp_file.path_.c_str(), GENERIC_READ | GENERIC_WRITE,
4997                     FILE_SHARE_DELETE | FILE_SHARE_READ, nullptr, CREATE_ALWAYS,
4998                     FILE_ATTRIBUTE_TEMPORARY, nullptr);
4999   PERFETTO_CHECK(PlatformHandleChecker::IsValid(h));
5000   // According to MSDN, when using _open_osfhandle the caller must not call
5001   // CloseHandle(). Ownership is moved to the file descriptor, which then needs
5002   // to be closed with just with _close().
5003   temp_file.fd_.reset(_open_osfhandle(reinterpret_cast<intptr_t>(h), 0));
5004 #else
5005   temp_file.path_ = GetSysTempDir() + "/perfetto-XXXXXXXX";
5006   temp_file.fd_.reset(mkstemp(&temp_file.path_[0]));
5007 #endif
5008   if (PERFETTO_UNLIKELY(!temp_file.fd_)) {
5009     PERFETTO_FATAL("Could not create temp file %s", temp_file.path_.c_str());
5010   }
5011   return temp_file;
5012 }
5013 
5014 // static
CreateUnlinked()5015 TempFile TempFile::CreateUnlinked() {
5016   TempFile temp_file = TempFile::Create();
5017   temp_file.Unlink();
5018   return temp_file;
5019 }
5020 
5021 TempFile::TempFile() = default;
5022 
~TempFile()5023 TempFile::~TempFile() {
5024   Unlink();
5025 }
5026 
ReleaseFD()5027 ScopedFile TempFile::ReleaseFD() {
5028   Unlink();
5029   return std::move(fd_);
5030 }
5031 
Unlink()5032 void TempFile::Unlink() {
5033   if (path_.empty())
5034     return;
5035 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
5036   // If the FD is still open DeleteFile will mark the file as pending deletion
5037   // and delete it only when the process exists.
5038   PERFETTO_CHECK(DeleteFileA(path_.c_str()));
5039 #else
5040   PERFETTO_CHECK(unlink(path_.c_str()) == 0);
5041 #endif
5042   path_.clear();
5043 }
5044 
5045 TempFile::TempFile(TempFile&&) noexcept = default;
5046 TempFile& TempFile::operator=(TempFile&&) = default;
5047 
5048 // static
Create()5049 TempDir TempDir::Create() {
5050   TempDir temp_dir;
5051 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
5052   temp_dir.path_ = GetSysTempDir() + "\\" + GetTempName();
5053   PERFETTO_CHECK(_mkdir(temp_dir.path_.c_str()) == 0);
5054 #else
5055   temp_dir.path_ = GetSysTempDir() + "/perfetto-XXXXXXXX";
5056   PERFETTO_CHECK(mkdtemp(&temp_dir.path_[0]));
5057 #endif
5058   return temp_dir;
5059 }
5060 
5061 TempDir::TempDir() = default;
5062 TempDir::TempDir(TempDir&&) noexcept = default;
5063 TempDir& TempDir::operator=(TempDir&&) = default;
5064 
~TempDir()5065 TempDir::~TempDir() {
5066   if (path_.empty())
5067     return;  // For objects that get std::move()d.
5068   PERFETTO_CHECK(Rmdir(path_));
5069 }
5070 
5071 }  // namespace base
5072 }  // namespace perfetto
5073 // gen_amalgamated begin source: src/base/thread_checker.cc
5074 /*
5075  * Copyright (C) 2017 The Android Open Source Project
5076  *
5077  * Licensed under the Apache License, Version 2.0 (the "License");
5078  * you may not use this file except in compliance with the License.
5079  * You may obtain a copy of the License at
5080  *
5081  *      http://www.apache.org/licenses/LICENSE-2.0
5082  *
5083  * Unless required by applicable law or agreed to in writing, software
5084  * distributed under the License is distributed on an "AS IS" BASIS,
5085  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5086  * See the License for the specific language governing permissions and
5087  * limitations under the License.
5088  */
5089 
5090 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_checker.h"
5091 
5092 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
5093 #include <Windows.h>
5094 #endif
5095 
5096 namespace perfetto {
5097 namespace base {
5098 
5099 namespace {
5100 constexpr ThreadID kDetached{};
5101 
CurrentThreadId()5102 ThreadID CurrentThreadId() {
5103 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
5104   return ::GetCurrentThreadId();
5105 #else
5106   return pthread_self();
5107 #endif
5108 }
5109 }  // namespace
5110 
ThreadChecker()5111 ThreadChecker::ThreadChecker() {
5112   thread_id_.store(CurrentThreadId());
5113 }
5114 
5115 ThreadChecker::~ThreadChecker() = default;
5116 
ThreadChecker(const ThreadChecker & other)5117 ThreadChecker::ThreadChecker(const ThreadChecker& other) {
5118   thread_id_ = other.thread_id_.load();
5119 }
5120 
operator =(const ThreadChecker & other)5121 ThreadChecker& ThreadChecker::operator=(const ThreadChecker& other) {
5122   thread_id_ = other.thread_id_.load();
5123   return *this;
5124 }
5125 
CalledOnValidThread() const5126 bool ThreadChecker::CalledOnValidThread() const {
5127   auto self = CurrentThreadId();
5128 
5129   // Will re-attach if previously detached using DetachFromThread().
5130   auto prev_value = kDetached;
5131   if (thread_id_.compare_exchange_strong(prev_value, self))
5132     return true;
5133   return prev_value == self;
5134 }
5135 
DetachFromThread()5136 void ThreadChecker::DetachFromThread() {
5137   thread_id_.store(kDetached);
5138 }
5139 
5140 }  // namespace base
5141 }  // namespace perfetto
5142 // gen_amalgamated begin source: src/base/time.cc
5143 /*
5144  * Copyright (C) 2018 The Android Open Source Project
5145  *
5146  * Licensed under the Apache License, Version 2.0 (the "License");
5147  * you may not use this file except in compliance with the License.
5148  * You may obtain a copy of the License at
5149  *
5150  *      http://www.apache.org/licenses/LICENSE-2.0
5151  *
5152  * Unless required by applicable law or agreed to in writing, software
5153  * distributed under the License is distributed on an "AS IS" BASIS,
5154  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5155  * See the License for the specific language governing permissions and
5156  * limitations under the License.
5157  */
5158 
5159 // gen_amalgamated expanded: #include "perfetto/base/time.h"
5160 
5161 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
5162 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
5163 
5164 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
5165 #include <Windows.h>
5166 #else
5167 #include <unistd.h>
5168 #endif
5169 
5170 namespace perfetto {
5171 namespace base {
5172 
5173 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
5174 
GetWallTimeNs()5175 TimeNanos GetWallTimeNs() {
5176   LARGE_INTEGER freq;
5177   ::QueryPerformanceFrequency(&freq);
5178   LARGE_INTEGER counter;
5179   ::QueryPerformanceCounter(&counter);
5180   double elapsed_nanoseconds = (1e9 * static_cast<double>(counter.QuadPart)) /
5181                                static_cast<double>(freq.QuadPart);
5182   return TimeNanos(static_cast<uint64_t>(elapsed_nanoseconds));
5183 }
5184 
GetThreadCPUTimeNs()5185 TimeNanos GetThreadCPUTimeNs() {
5186   FILETIME dummy, kernel_ftime, user_ftime;
5187   ::GetThreadTimes(GetCurrentThread(), &dummy, &dummy, &kernel_ftime,
5188                    &user_ftime);
5189   uint64_t kernel_time = kernel_ftime.dwHighDateTime * 0x100000000 +
5190                          kernel_ftime.dwLowDateTime;
5191   uint64_t user_time = user_ftime.dwHighDateTime * 0x100000000 +
5192                        user_ftime.dwLowDateTime;
5193 
5194   return TimeNanos((kernel_time + user_time) * 100);
5195 }
5196 
SleepMicroseconds(unsigned interval_us)5197 void SleepMicroseconds(unsigned interval_us) {
5198   // The Windows Sleep function takes a millisecond count. Round up so that
5199   // short sleeps don't turn into a busy wait. Note that the sleep granularity
5200   // on Windows can dynamically vary from 1 ms to ~16 ms, so don't count on this
5201   // being a short sleep.
5202   ::Sleep(static_cast<DWORD>((interval_us + 999) / 1000));
5203 }
5204 
5205 #else  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
5206 
5207 void SleepMicroseconds(unsigned interval_us) {
5208   ::usleep(static_cast<useconds_t>(interval_us));
5209 }
5210 
5211 #endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
5212 
GetTimeFmt(const std::string & fmt)5213 std::string GetTimeFmt(const std::string& fmt) {
5214   time_t raw_time;
5215   time(&raw_time);
5216   struct tm* local_tm;
5217   local_tm = localtime(&raw_time);
5218   char buf[128];
5219   PERFETTO_CHECK(strftime(buf, 80, fmt.c_str(), local_tm) > 0);
5220   return buf;
5221 }
5222 
5223 }  // namespace base
5224 }  // namespace perfetto
5225 // gen_amalgamated begin source: src/base/utils.cc
5226 /*
5227  * Copyright (C) 2020 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/file_utils.h"
5243 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
5244 
5245 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
5246 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
5247 
5248 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
5249     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
5250     PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
5251 #include <unistd.h>  // For getpagesize() and geteuid() & fork()
5252 #endif
5253 
5254 #if PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
5255 #include <mach/vm_page_size.h>
5256 #endif
5257 
5258 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
5259 #include <dlfcn.h>
5260 #include <malloc.h>
5261 
5262 #ifdef M_PURGE
5263 #define PERFETTO_M_PURGE M_PURGE
5264 #else
5265 // Only available in in-tree builds and on newer SDKs.
5266 #define PERFETTO_M_PURGE -101
5267 #endif
5268 
5269 namespace {
5270 extern "C" {
5271 using MalloptType = void (*)(int, int);
5272 }
5273 }  // namespace
5274 #endif  // OS_ANDROID
5275 
5276 namespace perfetto {
5277 namespace base {
5278 
MaybeReleaseAllocatorMemToOS()5279 void MaybeReleaseAllocatorMemToOS() {
5280 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
5281   // mallopt() on Android requires SDK level 26. Many targets and embedders
5282   // still depend on a lower SDK level. Given mallopt() is a quite simple API,
5283   // use reflection to do this rather than bumping the SDK level for all
5284   // embedders. This keeps the behavior of standalone builds aligned with
5285   // in-tree builds.
5286   static MalloptType mallopt_fn =
5287       reinterpret_cast<MalloptType>(dlsym(RTLD_DEFAULT, "mallopt"));
5288   if (!mallopt_fn)
5289     return;
5290   mallopt_fn(PERFETTO_M_PURGE, 0);
5291 #endif
5292 }
5293 
GetSysPageSize()5294 uint32_t GetSysPageSize() {
5295   ignore_result(kPageSize);  // Just to keep the amalgamated build happy.
5296 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
5297     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
5298   static std::atomic<uint32_t> page_size{0};
5299   // This function might be called in hot paths. Avoid calling getpagesize() all
5300   // the times, in many implementations getpagesize() calls sysconf() which is
5301   // not cheap.
5302   uint32_t cached_value = page_size.load(std::memory_order_relaxed);
5303   if (PERFETTO_UNLIKELY(cached_value == 0)) {
5304     cached_value = static_cast<uint32_t>(getpagesize());
5305     page_size.store(cached_value, std::memory_order_relaxed);
5306   }
5307   return cached_value;
5308 #elif PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
5309   return static_cast<uint32_t>(vm_page_size);
5310 #else
5311   return 4096;
5312 #endif
5313 }
5314 
GetCurrentUserId()5315 uid_t GetCurrentUserId() {
5316 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
5317     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
5318     PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
5319   return geteuid();
5320 #else
5321   // TODO(primiano): On Windows we could hash the current user SID and derive a
5322   // numeric user id [1]. It is not clear whether we need that. Right now that
5323   // would not bring any benefit. Returning 0 unil we can prove we need it.
5324   // [1]:https://android-review.googlesource.com/c/platform/external/perfetto/+/1513879/25/src/base/utils.cc
5325   return 0;
5326 #endif
5327 }
5328 
SetEnv(const std::string & key,const std::string & value)5329 void SetEnv(const std::string& key, const std::string& value) {
5330 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
5331   PERFETTO_CHECK(::_putenv_s(key.c_str(), value.c_str()) == 0);
5332 #else
5333   PERFETTO_CHECK(::setenv(key.c_str(), value.c_str(), /*overwrite=*/true) == 0);
5334 #endif
5335 }
5336 
Daemonize()5337 void Daemonize() {
5338    #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
5339        PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
5340        PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
5341       pid_t pid;
5342       switch (pid = fork()) {
5343         case -1:
5344           PERFETTO_FATAL("fork");
5345         case 0: {
5346           PERFETTO_CHECK(setsid() != -1);
5347           base::ignore_result(chdir("/"));
5348           base::ScopedFile null = base::OpenFile("/dev/null", O_RDONLY);
5349           PERFETTO_CHECK(null);
5350           PERFETTO_CHECK(dup2(*null, STDIN_FILENO) != -1);
5351           PERFETTO_CHECK(dup2(*null, STDOUT_FILENO) != -1);
5352           PERFETTO_CHECK(dup2(*null, STDERR_FILENO) != -1);
5353           // Do not accidentally close stdin/stdout/stderr.
5354           if (*null <= 2)
5355             null.release();
5356           break;
5357         }
5358         default:
5359           printf("%d\n", pid);
5360           exit(0);
5361       }
5362   #else
5363     // Avoid -Wunreachable warnings.
5364     if (reinterpret_cast<intptr_t>(&Daemonize) != 16)
5365       PERFETTO_FATAL("--background is only supported on Linux/Android/Mac");
5366   #endif  // OS_WIN
5367 }
5368 
5369 }  // namespace base
5370 }  // namespace perfetto
5371 // gen_amalgamated begin source: src/base/uuid.cc
5372 // gen_amalgamated begin header: include/perfetto/ext/base/uuid.h
5373 /*
5374  * Copyright (C) 2019 The Android Open Source Project
5375  *
5376  * Licensed under the Apache License, Version 2.0 (the "License");
5377  * you may not use this file except in compliance with the License.
5378  * You may obtain a copy of the License at
5379  *
5380  *      http://www.apache.org/licenses/LICENSE-2.0
5381  *
5382  * Unless required by applicable law or agreed to in writing, software
5383  * distributed under the License is distributed on an "AS IS" BASIS,
5384  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5385  * See the License for the specific language governing permissions and
5386  * limitations under the License.
5387  */
5388 
5389 #ifndef INCLUDE_PERFETTO_EXT_BASE_UUID_H_
5390 #define INCLUDE_PERFETTO_EXT_BASE_UUID_H_
5391 
5392 #include <array>
5393 #include <string>
5394 
5395 // gen_amalgamated expanded: #include "perfetto/ext/base/optional.h"
5396 
5397 namespace perfetto {
5398 namespace base {
5399 
5400 class Uuid {
5401  public:
5402   explicit Uuid(const std::string& s);
5403   explicit Uuid(int64_t lsb, int64_t msb);
5404   Uuid();
5405 
data()5406   std::array<uint8_t, 16>* data() { return &data_; }
data() const5407   const std::array<uint8_t, 16>* data() const { return &data_; }
5408 
operator ==(const Uuid & other) const5409   bool operator==(const Uuid& other) const { return data_ == other.data_; }
5410 
operator !=(const Uuid & other) const5411   bool operator!=(const Uuid& other) const { return !(*this == other); }
5412 
msb() const5413   int64_t msb() const {
5414     int64_t result;
5415     memcpy(&result, data_.data() + 8, 8);
5416     return result;
5417   }
5418 
lsb() const5419   int64_t lsb() const {
5420     int64_t result;
5421     memcpy(&result, data_.data(), 8);
5422     return result;
5423   }
5424 
set_lsb_msb(int64_t lsb,int64_t msb)5425   void set_lsb_msb(int64_t lsb, int64_t msb) {
5426     set_lsb(lsb);
5427     set_msb(msb);
5428   }
set_msb(int64_t msb)5429   void set_msb(int64_t msb) { memcpy(data_.data() + 8, &msb, 8); }
set_lsb(int64_t lsb)5430   void set_lsb(int64_t lsb) { memcpy(data_.data(), &lsb, 8); }
5431 
5432   std::string ToString() const;
5433   std::string ToPrettyString() const;
5434 
5435  private:
5436   std::array<uint8_t, 16> data_{};
5437 };
5438 
5439 Uuid Uuidv4();
5440 
5441 }  // namespace base
5442 }  // namespace perfetto
5443 
5444 #endif  // INCLUDE_PERFETTO_EXT_BASE_UUID_H_
5445 /*
5446  * Copyright (C) 2019 The Android Open Source Project
5447  *
5448  * Licensed under the Apache License, Version 2.0 (the "License");
5449  * you may not use this file except in compliance with the License.
5450  * You may obtain a copy of the License at
5451  *
5452  *      http://www.apache.org/licenses/LICENSE-2.0
5453  *
5454  * Unless required by applicable law or agreed to in writing, software
5455  * distributed under the License is distributed on an "AS IS" BASIS,
5456  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5457  * See the License for the specific language governing permissions and
5458  * limitations under the License.
5459  */
5460 
5461 // gen_amalgamated expanded: #include "perfetto/ext/base/uuid.h"
5462 
5463 #include <random>
5464 
5465 // gen_amalgamated expanded: #include "perfetto/base/time.h"
5466 
5467 namespace perfetto {
5468 namespace base {
5469 namespace {
5470 
5471 constexpr char kHexmap[] = {'0', '1', '2', '3', '4', '5', '6', '7',
5472                             '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
5473 }  // namespace
5474 
5475 // See https://www.ietf.org/rfc/rfc4122.txt
Uuidv4()5476 Uuid Uuidv4() {
5477   static std::minstd_rand rng(static_cast<uint32_t>(GetBootTimeNs().count()));
5478   Uuid uuid;
5479   auto& data = *uuid.data();
5480 
5481   for (size_t i = 0; i < 16; ++i)
5482     data[i] = static_cast<uint8_t>(rng());
5483 
5484   // version:
5485   data[6] = (data[6] & 0x0f) | 0x40;
5486   // clock_seq_hi_and_reserved:
5487   data[8] = (data[8] & 0x3f) | 0x80;
5488 
5489   return uuid;
5490 }
5491 
Uuid()5492 Uuid::Uuid() {}
5493 
Uuid(const std::string & s)5494 Uuid::Uuid(const std::string& s) {
5495   PERFETTO_CHECK(s.size() == data_.size());
5496   memcpy(data_.data(), s.data(), s.size());
5497 }
5498 
Uuid(int64_t lsb,int64_t msb)5499 Uuid::Uuid(int64_t lsb, int64_t msb) {
5500   set_lsb_msb(lsb, msb);
5501 }
5502 
ToString() const5503 std::string Uuid::ToString() const {
5504   return std::string(reinterpret_cast<const char*>(data_.data()), data_.size());
5505 }
5506 
ToPrettyString() const5507 std::string Uuid::ToPrettyString() const {
5508   std::string s(data_.size() * 2 + 4, '-');
5509   // Format is 123e4567-e89b-12d3-a456-426655443322.
5510   size_t j = 0;
5511   for (size_t i = 0; i < data_.size(); ++i) {
5512     if (i == 4 || i == 6 || i == 8 || i == 10)
5513       j++;
5514     s[2 * i + j] = kHexmap[(data_[data_.size() - i - 1] & 0xf0) >> 4];
5515     s[2 * i + 1 + j] = kHexmap[(data_[data_.size() - i - 1] & 0x0f)];
5516   }
5517   return s;
5518 }
5519 
5520 }  // namespace base
5521 }  // namespace perfetto
5522 // gen_amalgamated begin source: src/base/version.cc
5523 // gen_amalgamated begin header: include/perfetto/ext/base/version.h
5524 /*
5525  * Copyright (C) 2020 The Android Open Source Project
5526  *
5527  * Licensed under the Apache License, Version 2.0 (the "License");
5528  * you may not use this file except in compliance with the License.
5529  * You may obtain a copy of the License at
5530  *
5531  *      http://www.apache.org/licenses/LICENSE-2.0
5532  *
5533  * Unless required by applicable law or agreed to in writing, software
5534  * distributed under the License is distributed on an "AS IS" BASIS,
5535  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5536  * See the License for the specific language governing permissions and
5537  * limitations under the License.
5538  */
5539 
5540 #ifndef INCLUDE_PERFETTO_EXT_BASE_VERSION_H_
5541 #define INCLUDE_PERFETTO_EXT_BASE_VERSION_H_
5542 
5543 namespace perfetto {
5544 namespace base {
5545 
5546 // The returned pointer is a static string is safe to pass around.
5547 const char* GetVersionString();
5548 
5549 }  // namespace base
5550 }  // namespace perfetto
5551 
5552 #endif  // INCLUDE_PERFETTO_EXT_BASE_VERSION_H_
5553 // gen_amalgamated begin header: gen/perfetto_version.gen.h
5554 // Generated by write_version_header.py
5555 
5556 #ifndef GEN_PERFETTO_VERSION_GEN_H_
5557 #define GEN_PERFETTO_VERSION_GEN_H_
5558 
5559 #define PERFETTO_VERSION_STRING() "v15.0"
5560 #define PERFETTO_VERSION_SCM_REVISION() "f69a7701253a1c934595a31c581465a1acb0af80"
5561 
5562 #endif  // GEN_PERFETTO_VERSION_GEN_H_
5563 /*
5564  * Copyright (C) 2020 The Android Open Source Project
5565  *
5566  * Licensed under the Apache License, Version 2.0 (the "License");
5567  * you may not use this file except in compliance with the License.
5568  * You may obtain a copy of the License at
5569  *
5570  *      http://www.apache.org/licenses/LICENSE-2.0
5571  *
5572  * Unless required by applicable law or agreed to in writing, software
5573  * distributed under the License is distributed on an "AS IS" BASIS,
5574  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5575  * See the License for the specific language governing permissions and
5576  * limitations under the License.
5577  */
5578 
5579 // gen_amalgamated expanded: #include "perfetto/ext/base/version.h"
5580 
5581 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
5582 
5583 #include <stdio.h>
5584 
5585 #if PERFETTO_BUILDFLAG(PERFETTO_VERSION_GEN)
5586 // gen_amalgamated expanded: #include "perfetto_version.gen.h"
5587 #else
5588 #define PERFETTO_VERSION_STRING() "v0.0"
5589 #define PERFETTO_VERSION_SCM_REVISION() "unknown"
5590 #endif
5591 
5592 namespace perfetto {
5593 namespace base {
5594 
GetVersionString()5595 const char* GetVersionString() {
5596   static const char* version_str = [] {
5597     static constexpr size_t kMaxLen = 256;
5598     char* version = new char[kMaxLen + 1];
5599     snprintf(version, kMaxLen, "Perfetto %s (%s)", PERFETTO_VERSION_STRING(),
5600              PERFETTO_VERSION_SCM_REVISION());
5601     return version;
5602   }();
5603   return version_str;
5604 }
5605 
5606 }  // namespace base
5607 }  // namespace perfetto
5608 // gen_amalgamated begin source: src/base/virtual_destructors.cc
5609 /*
5610  * Copyright (C) 2017 The Android Open Source Project
5611  *
5612  * Licensed under the Apache License, Version 2.0 (the "License");
5613  * you may not use this file except in compliance with the License.
5614  * You may obtain a copy of the License at
5615  *
5616  *      http://www.apache.org/licenses/LICENSE-2.0
5617  *
5618  * Unless required by applicable law or agreed to in writing, software
5619  * distributed under the License is distributed on an "AS IS" BASIS,
5620  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5621  * See the License for the specific language governing permissions and
5622  * limitations under the License.
5623  */
5624 
5625 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
5626 
5627 // This translation unit contains the definitions for the destructor of pure
5628 // virtual interfaces for the current build target. The alternative would be
5629 // introducing a one-liner .cc file for each pure virtual interface, which is
5630 // overkill. This is for compliance with -Wweak-vtables.
5631 
5632 namespace perfetto {
5633 namespace base {
5634 
5635 TaskRunner::~TaskRunner() = default;
5636 
5637 }  // namespace base
5638 }  // namespace perfetto
5639 // gen_amalgamated begin source: src/base/waitable_event.cc
5640 // gen_amalgamated begin header: include/perfetto/ext/base/waitable_event.h
5641 /*
5642  * Copyright (C) 2019 The Android Open Source Project
5643  *
5644  * Licensed under the Apache License, Version 2.0 (the "License");
5645  * you may not use this file except in compliance with the License.
5646  * You may obtain a copy of the License at
5647  *
5648  *      http://www.apache.org/licenses/LICENSE-2.0
5649  *
5650  * Unless required by applicable law or agreed to in writing, software
5651  * distributed under the License is distributed on an "AS IS" BASIS,
5652  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5653  * See the License for the specific language governing permissions and
5654  * limitations under the License.
5655  */
5656 
5657 #ifndef INCLUDE_PERFETTO_EXT_BASE_WAITABLE_EVENT_H_
5658 #define INCLUDE_PERFETTO_EXT_BASE_WAITABLE_EVENT_H_
5659 
5660 #include <condition_variable>
5661 #include <mutex>
5662 
5663 namespace perfetto {
5664 namespace base {
5665 
5666 // A waitable event for cross-thread synchronization.
5667 // All methods on this class can be called from any thread.
5668 class WaitableEvent {
5669  public:
5670   WaitableEvent();
5671   ~WaitableEvent();
5672   WaitableEvent(const WaitableEvent&) = delete;
5673   WaitableEvent operator=(const WaitableEvent&) = delete;
5674 
5675   // Synchronously block until the event is notified.
5676   void Wait();
5677 
5678   // Signal the event, waking up blocked waiters.
5679   void Notify();
5680 
5681  private:
5682   std::mutex mutex_;
5683   std::condition_variable event_;
5684   bool notified_ = false;
5685 };
5686 
5687 }  // namespace base
5688 }  // namespace perfetto
5689 
5690 #endif  // INCLUDE_PERFETTO_EXT_BASE_WAITABLE_EVENT_H_
5691 /*
5692  * Copyright (C) 2019 The Android Open Source Project
5693  *
5694  * Licensed under the Apache License, Version 2.0 (the "License");
5695  * you may not use this file except in compliance with the License.
5696  * You may obtain a copy of the License at
5697  *
5698  *      http://www.apache.org/licenses/LICENSE-2.0
5699  *
5700  * Unless required by applicable law or agreed to in writing, software
5701  * distributed under the License is distributed on an "AS IS" BASIS,
5702  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5703  * See the License for the specific language governing permissions and
5704  * limitations under the License.
5705  */
5706 
5707 // gen_amalgamated expanded: #include "perfetto/ext/base/waitable_event.h"
5708 
5709 namespace perfetto {
5710 namespace base {
5711 
5712 WaitableEvent::WaitableEvent() = default;
5713 WaitableEvent::~WaitableEvent() = default;
5714 
Wait()5715 void WaitableEvent::Wait() {
5716   std::unique_lock<std::mutex> lock(mutex_);
5717   return event_.wait(lock, [this] { return notified_; });
5718 }
5719 
Notify()5720 void WaitableEvent::Notify() {
5721   std::unique_lock<std::mutex> lock(mutex_);
5722   notified_ = true;
5723   event_.notify_all();
5724 }
5725 
5726 }  // namespace base
5727 }  // namespace perfetto
5728 // gen_amalgamated begin source: src/base/watchdog_posix.cc
5729 // gen_amalgamated begin header: include/perfetto/ext/base/watchdog.h
5730 // gen_amalgamated begin header: include/perfetto/ext/base/watchdog_noop.h
5731 /*
5732  * Copyright (C) 2018 The Android Open Source Project
5733  *
5734  * Licensed under the Apache License, Version 2.0 (the "License");
5735  * you may not use this file except in compliance with the License.
5736  * You may obtain a copy of the License at
5737  *
5738  *      http://www.apache.org/licenses/LICENSE-2.0
5739  *
5740  * Unless required by applicable law or agreed to in writing, software
5741  * distributed under the License is distributed on an "AS IS" BASIS,
5742  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5743  * See the License for the specific language governing permissions and
5744  * limitations under the License.
5745  */
5746 
5747 #ifndef INCLUDE_PERFETTO_EXT_BASE_WATCHDOG_NOOP_H_
5748 #define INCLUDE_PERFETTO_EXT_BASE_WATCHDOG_NOOP_H_
5749 
5750 #include <stdint.h>
5751 
5752 namespace perfetto {
5753 namespace base {
5754 
5755 class Watchdog {
5756  public:
5757   class Timer {
5758    public:
5759     // Define an empty dtor to avoid "unused variable" errors on the call site.
Timer()5760     Timer() {}
Timer(const Timer &)5761     Timer(const Timer&) {}
~Timer()5762     ~Timer() {}
5763   };
GetInstance()5764   static Watchdog* GetInstance() {
5765     static Watchdog* watchdog = new Watchdog();
5766     return watchdog;
5767   }
CreateFatalTimer(uint32_t)5768   Timer CreateFatalTimer(uint32_t /*ms*/) { return Timer(); }
Start()5769   void Start() {}
SetMemoryLimit(uint64_t,uint32_t)5770   void SetMemoryLimit(uint64_t /*bytes*/, uint32_t /*window_ms*/) {}
SetCpuLimit(uint32_t,uint32_t)5771   void SetCpuLimit(uint32_t /*percentage*/, uint32_t /*window_ms*/) {}
5772 };
5773 
5774 }  // namespace base
5775 }  // namespace perfetto
5776 
5777 #endif  // INCLUDE_PERFETTO_EXT_BASE_WATCHDOG_NOOP_H_
5778 /*
5779  * Copyright (C) 2018 The Android Open Source Project
5780  *
5781  * Licensed under the Apache License, Version 2.0 (the "License");
5782  * you may not use this file except in compliance with the License.
5783  * You may obtain a copy of the License at
5784  *
5785  *      http://www.apache.org/licenses/LICENSE-2.0
5786  *
5787  * Unless required by applicable law or agreed to in writing, software
5788  * distributed under the License is distributed on an "AS IS" BASIS,
5789  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5790  * See the License for the specific language governing permissions and
5791  * limitations under the License.
5792  */
5793 
5794 #ifndef INCLUDE_PERFETTO_EXT_BASE_WATCHDOG_H_
5795 #define INCLUDE_PERFETTO_EXT_BASE_WATCHDOG_H_
5796 
5797 #include <functional>
5798 
5799 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
5800 
5801 // The POSIX watchdog is only supported on Linux and Android in non-embedder
5802 // builds.
5803 #if PERFETTO_BUILDFLAG(PERFETTO_WATCHDOG)
5804 // gen_amalgamated expanded: #include "perfetto/ext/base/watchdog_posix.h"
5805 #else
5806 // gen_amalgamated expanded: #include "perfetto/ext/base/watchdog_noop.h"
5807 #endif
5808 
5809 namespace perfetto {
5810 namespace base {
5811 
5812 // Make the limits more relaxed on desktop, where multi-GB traces are likely.
5813 // Multi-GB traces can take bursts of cpu time to write into disk at the end of
5814 // the trace.
5815 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
5816 constexpr uint32_t kWatchdogDefaultCpuLimit = 75;
5817 constexpr uint32_t kWatchdogDefaultCpuWindow = 5 * 60 * 1000;  // 5 minutes.
5818 #else
5819 constexpr uint32_t kWatchdogDefaultCpuLimit = 90;
5820 constexpr uint32_t kWatchdogDefaultCpuWindow = 10 * 60 * 1000;  // 10 minutes.
5821 #endif
5822 
5823 // The default memory margin we give to our processes. This is used as as a
5824 // constant to put on top of the trace buffers.
5825 constexpr uint64_t kWatchdogDefaultMemorySlack = 32 * 1024 * 1024;  // 32 MiB.
5826 constexpr uint32_t kWatchdogDefaultMemoryWindow = 30 * 1000;  // 30 seconds.
5827 
RunTaskWithWatchdogGuard(const std::function<void ()> & task)5828 inline void RunTaskWithWatchdogGuard(const std::function<void()>& task) {
5829   // Maximum time a single task can take in a TaskRunner before the
5830   // program suicides.
5831   constexpr int64_t kWatchdogMillis = 30000;  // 30s
5832 
5833   Watchdog::Timer handle =
5834       base::Watchdog::GetInstance()->CreateFatalTimer(kWatchdogMillis);
5835   task();
5836 
5837   // Suppress unused variable warnings in the client library amalgamated build.
5838   (void)kWatchdogDefaultCpuLimit;
5839   (void)kWatchdogDefaultCpuWindow;
5840   (void)kWatchdogDefaultMemorySlack;
5841   (void)kWatchdogDefaultMemoryWindow;
5842 }
5843 
5844 }  // namespace base
5845 }  // namespace perfetto
5846 
5847 #endif  // INCLUDE_PERFETTO_EXT_BASE_WATCHDOG_H_
5848 /*
5849  * Copyright (C) 2018 The Android Open Source Project
5850  *
5851  * Licensed under the Apache License, Version 2.0 (the "License");
5852  * you may not use this file except in compliance with the License.
5853  * You may obtain a copy of the License at
5854  *
5855  *      http://www.apache.org/licenses/LICENSE-2.0
5856  *
5857  * Unless required by applicable law or agreed to in writing, software
5858  * distributed under the License is distributed on an "AS IS" BASIS,
5859  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5860  * See the License for the specific language governing permissions and
5861  * limitations under the License.
5862  */
5863 
5864 // gen_amalgamated expanded: #include "perfetto/ext/base/watchdog.h"
5865 
5866 #if PERFETTO_BUILDFLAG(PERFETTO_WATCHDOG)
5867 
5868 #include <fcntl.h>
5869 #include <inttypes.h>
5870 #include <signal.h>
5871 #include <stdint.h>
5872 
5873 #include <fstream>
5874 #include <thread>
5875 
5876 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
5877 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
5878 // gen_amalgamated expanded: #include "perfetto/base/thread_utils.h"
5879 // gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
5880 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
5881 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
5882 
5883 namespace perfetto {
5884 namespace base {
5885 
5886 namespace {
5887 
5888 constexpr uint32_t kDefaultPollingInterval = 30 * 1000;
5889 
IsMultipleOf(uint32_t number,uint32_t divisor)5890 bool IsMultipleOf(uint32_t number, uint32_t divisor) {
5891   return number >= divisor && number % divisor == 0;
5892 }
5893 
MeanForArray(const uint64_t array[],size_t size)5894 double MeanForArray(const uint64_t array[], size_t size) {
5895   uint64_t total = 0;
5896   for (size_t i = 0; i < size; i++) {
5897     total += array[i];
5898   }
5899   return static_cast<double>(total / size);
5900 
5901 }
5902 
5903 }  //  namespace
5904 
ReadProcStat(int fd,ProcStat * out)5905 bool ReadProcStat(int fd, ProcStat* out) {
5906   char c[512];
5907   size_t c_pos = 0;
5908   while (c_pos < sizeof(c) - 1) {
5909     ssize_t rd = PERFETTO_EINTR(read(fd, c + c_pos, sizeof(c) - c_pos));
5910     if (rd < 0) {
5911       PERFETTO_ELOG("Failed to read stat file to enforce resource limits.");
5912       return false;
5913     }
5914     if (rd == 0)
5915       break;
5916     c_pos += static_cast<size_t>(rd);
5917   }
5918   PERFETTO_CHECK(c_pos < sizeof(c));
5919   c[c_pos] = '\0';
5920 
5921   if (sscanf(c,
5922              "%*d %*s %*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u %lu "
5923              "%lu %*d %*d %*d %*d %*d %*d %*u %*u %ld",
5924              &out->utime, &out->stime, &out->rss_pages) != 3) {
5925     PERFETTO_ELOG("Invalid stat format: %s", c);
5926     return false;
5927   }
5928   return true;
5929 }
5930 
Watchdog(uint32_t polling_interval_ms)5931 Watchdog::Watchdog(uint32_t polling_interval_ms)
5932     : polling_interval_ms_(polling_interval_ms) {}
5933 
~Watchdog()5934 Watchdog::~Watchdog() {
5935   if (!thread_.joinable()) {
5936     PERFETTO_DCHECK(!enabled_);
5937     return;
5938   }
5939   PERFETTO_DCHECK(enabled_);
5940   enabled_ = false;
5941   exit_signal_.notify_one();
5942   thread_.join();
5943 }
5944 
GetInstance()5945 Watchdog* Watchdog::GetInstance() {
5946   static Watchdog* watchdog = new Watchdog(kDefaultPollingInterval);
5947   return watchdog;
5948 }
5949 
CreateFatalTimer(uint32_t ms)5950 Watchdog::Timer Watchdog::CreateFatalTimer(uint32_t ms) {
5951   if (!enabled_.load(std::memory_order_relaxed))
5952     return Watchdog::Timer(0);
5953 
5954   return Watchdog::Timer(ms);
5955 }
5956 
Start()5957 void Watchdog::Start() {
5958   std::lock_guard<std::mutex> guard(mutex_);
5959   if (thread_.joinable()) {
5960     PERFETTO_DCHECK(enabled_);
5961   } else {
5962     PERFETTO_DCHECK(!enabled_);
5963 
5964 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
5965     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
5966     // Kick the thread to start running but only on Android or Linux.
5967     enabled_ = true;
5968     thread_ = std::thread(&Watchdog::ThreadMain, this);
5969 #endif
5970   }
5971 }
5972 
SetMemoryLimit(uint64_t bytes,uint32_t window_ms)5973 void Watchdog::SetMemoryLimit(uint64_t bytes, uint32_t window_ms) {
5974   // Update the fields under the lock.
5975   std::lock_guard<std::mutex> guard(mutex_);
5976 
5977   PERFETTO_CHECK(IsMultipleOf(window_ms, polling_interval_ms_) || bytes == 0);
5978 
5979   size_t size = bytes == 0 ? 0 : window_ms / polling_interval_ms_ + 1;
5980   memory_window_bytes_.Reset(size);
5981   memory_limit_bytes_ = bytes;
5982 }
5983 
SetCpuLimit(uint32_t percentage,uint32_t window_ms)5984 void Watchdog::SetCpuLimit(uint32_t percentage, uint32_t window_ms) {
5985   std::lock_guard<std::mutex> guard(mutex_);
5986 
5987   PERFETTO_CHECK(percentage <= 100);
5988   PERFETTO_CHECK(IsMultipleOf(window_ms, polling_interval_ms_) ||
5989                  percentage == 0);
5990 
5991   size_t size = percentage == 0 ? 0 : window_ms / polling_interval_ms_ + 1;
5992   cpu_window_time_ticks_.Reset(size);
5993   cpu_limit_percentage_ = percentage;
5994 }
5995 
ThreadMain()5996 void Watchdog::ThreadMain() {
5997   base::ScopedFile stat_fd(base::OpenFile("/proc/self/stat", O_RDONLY));
5998   if (!stat_fd) {
5999     PERFETTO_ELOG("Failed to open stat file to enforce resource limits.");
6000     return;
6001   }
6002 
6003   std::unique_lock<std::mutex> guard(mutex_);
6004   for (;;) {
6005     exit_signal_.wait_for(guard,
6006                           std::chrono::milliseconds(polling_interval_ms_));
6007     if (!enabled_)
6008       return;
6009 
6010     lseek(stat_fd.get(), 0, SEEK_SET);
6011 
6012     ProcStat stat;
6013     if (!ReadProcStat(stat_fd.get(), &stat)) {
6014       return;
6015     }
6016 
6017     uint64_t cpu_time = stat.utime + stat.stime;
6018     uint64_t rss_bytes =
6019         static_cast<uint64_t>(stat.rss_pages) * base::GetSysPageSize();
6020 
6021     CheckMemory(rss_bytes);
6022     CheckCpu(cpu_time);
6023   }
6024 }
6025 
CheckMemory(uint64_t rss_bytes)6026 void Watchdog::CheckMemory(uint64_t rss_bytes) {
6027   if (memory_limit_bytes_ == 0)
6028     return;
6029 
6030   // Add the current stat value to the ring buffer and check that the mean
6031   // remains under our threshold.
6032   if (memory_window_bytes_.Push(rss_bytes)) {
6033     if (memory_window_bytes_.Mean() > static_cast<double>(memory_limit_bytes_)) {
6034       PERFETTO_ELOG(
6035           "Memory watchdog trigger. Memory window of %f bytes is above the "
6036           "%" PRIu64 " bytes limit.",
6037           memory_window_bytes_.Mean(), memory_limit_bytes_);
6038       kill(getpid(), SIGABRT);
6039     }
6040   }
6041 }
6042 
CheckCpu(uint64_t cpu_time)6043 void Watchdog::CheckCpu(uint64_t cpu_time) {
6044   if (cpu_limit_percentage_ == 0)
6045     return;
6046 
6047   // Add the cpu time to the ring buffer.
6048   if (cpu_window_time_ticks_.Push(cpu_time)) {
6049     // Compute the percentage over the whole window and check that it remains
6050     // under the threshold.
6051     uint64_t difference_ticks = cpu_window_time_ticks_.NewestWhenFull() -
6052                                 cpu_window_time_ticks_.OldestWhenFull();
6053     double window_interval_ticks =
6054         (static_cast<double>(WindowTimeForRingBuffer(cpu_window_time_ticks_)) /
6055          1000.0) *
6056         static_cast<double>(sysconf(_SC_CLK_TCK));
6057     double percentage = static_cast<double>(difference_ticks) /
6058                         static_cast<double>(window_interval_ticks) * 100;
6059     if (percentage > cpu_limit_percentage_) {
6060       PERFETTO_ELOG("CPU watchdog trigger. %f%% CPU use is above the %" PRIu32
6061                     "%% CPU limit.",
6062                     percentage, cpu_limit_percentage_);
6063       kill(getpid(), SIGABRT);
6064     }
6065   }
6066 }
6067 
WindowTimeForRingBuffer(const WindowedInterval & window)6068 uint32_t Watchdog::WindowTimeForRingBuffer(const WindowedInterval& window) {
6069   return static_cast<uint32_t>(window.size() - 1) * polling_interval_ms_;
6070 }
6071 
Push(uint64_t sample)6072 bool Watchdog::WindowedInterval::Push(uint64_t sample) {
6073   // Add the sample to the current position in the ring buffer.
6074   buffer_[position_] = sample;
6075 
6076   // Update the position with next one circularily.
6077   position_ = (position_ + 1) % size_;
6078 
6079   // Set the filled flag the first time we wrap.
6080   filled_ = filled_ || position_ == 0;
6081   return filled_;
6082 }
6083 
Mean() const6084 double Watchdog::WindowedInterval::Mean() const {
6085   return MeanForArray(buffer_.get(), size_);
6086 }
6087 
Clear()6088 void Watchdog::WindowedInterval::Clear() {
6089   position_ = 0;
6090   buffer_.reset(new uint64_t[size_]());
6091 }
6092 
Reset(size_t new_size)6093 void Watchdog::WindowedInterval::Reset(size_t new_size) {
6094   position_ = 0;
6095   size_ = new_size;
6096   buffer_.reset(new_size == 0 ? nullptr : new uint64_t[new_size]());
6097 }
6098 
Timer(uint32_t ms)6099 Watchdog::Timer::Timer(uint32_t ms) {
6100   if (!ms)
6101     return;  // No-op timer created when the watchdog is disabled.
6102 
6103   struct sigevent sev = {};
6104   timer_t timerid;
6105   sev.sigev_notify = SIGEV_THREAD_ID;
6106   sev._sigev_un._tid = base::GetThreadId();
6107   sev.sigev_signo = SIGABRT;
6108   PERFETTO_CHECK(timer_create(CLOCK_MONOTONIC, &sev, &timerid) != -1);
6109   timerid_ = base::make_optional(timerid);
6110   struct itimerspec its = {};
6111   its.it_value.tv_sec = ms / 1000;
6112   its.it_value.tv_nsec = 1000000L * (ms % 1000);
6113   PERFETTO_CHECK(timer_settime(timerid_.value(), 0, &its, nullptr) != -1);
6114 }
6115 
~Timer()6116 Watchdog::Timer::~Timer() {
6117   if (timerid_) {
6118     timer_delete(timerid_.value());
6119   }
6120 }
6121 
Timer(Timer && other)6122 Watchdog::Timer::Timer(Timer&& other) noexcept {
6123   timerid_ = std::move(other.timerid_);
6124   other.timerid_ = base::nullopt;
6125 }
6126 
6127 }  // namespace base
6128 }  // namespace perfetto
6129 
6130 #endif  // PERFETTO_BUILDFLAG(PERFETTO_WATCHDOG)
6131 // gen_amalgamated begin source: src/base/thread_task_runner.cc
6132 // gen_amalgamated begin header: include/perfetto/ext/base/thread_task_runner.h
6133 // gen_amalgamated begin header: include/perfetto/ext/base/unix_task_runner.h
6134 /*
6135  * Copyright (C) 2017 The Android Open Source Project
6136  *
6137  * Licensed under the Apache License, Version 2.0 (the "License");
6138  * you may not use this file except in compliance with the License.
6139  * You may obtain a copy of the License at
6140  *
6141  *      http://www.apache.org/licenses/LICENSE-2.0
6142  *
6143  * Unless required by applicable law or agreed to in writing, software
6144  * distributed under the License is distributed on an "AS IS" BASIS,
6145  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6146  * See the License for the specific language governing permissions and
6147  * limitations under the License.
6148  */
6149 
6150 #ifndef INCLUDE_PERFETTO_EXT_BASE_UNIX_TASK_RUNNER_H_
6151 #define INCLUDE_PERFETTO_EXT_BASE_UNIX_TASK_RUNNER_H_
6152 
6153 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
6154 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
6155 // gen_amalgamated expanded: #include "perfetto/base/thread_utils.h"
6156 // gen_amalgamated expanded: #include "perfetto/base/time.h"
6157 // gen_amalgamated expanded: #include "perfetto/ext/base/event_fd.h"
6158 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
6159 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_checker.h"
6160 
6161 #include <chrono>
6162 #include <deque>
6163 #include <map>
6164 #include <mutex>
6165 #include <vector>
6166 
6167 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
6168 #include <poll.h>
6169 #endif
6170 
6171 namespace perfetto {
6172 namespace base {
6173 
6174 // Runs a task runner on the current thread.
6175 //
6176 // Implementation note: we currently assume (and enforce in debug builds) that
6177 // Run() is called from the thread that constructed the UnixTaskRunner. This is
6178 // not strictly necessary, and we could instead track the thread that invokes
6179 // Run(). However, a related property that *might* be important to enforce is
6180 // that the destructor runs on the task-running thread. Otherwise, if there are
6181 // still-pending tasks at the time of destruction, we would destroy those
6182 // outside of the task thread (which might be unexpected to the caller). On the
6183 // other hand, the std::function task interface discourages use of any
6184 // resource-owning tasks (as the callable needs to be copyable), so this might
6185 // not be important in practice.
6186 //
6187 // TODO(rsavitski): consider adding a thread-check in the destructor, after
6188 // auditing existing usages.
6189 // TODO(primiano): rename this to TaskRunnerImpl. The "Unix" part is misleading
6190 // now as it supports also Windows.
6191 class UnixTaskRunner : public TaskRunner {
6192  public:
6193   UnixTaskRunner();
6194   ~UnixTaskRunner() override;
6195 
6196   // Start executing tasks. Doesn't return until Quit() is called. Run() may be
6197   // called multiple times on the same task runner.
6198   void Run();
6199   void Quit();
6200 
6201   // Checks whether there are any pending immediate tasks to run. Note that
6202   // delayed tasks don't count even if they are due to run.
6203   bool IsIdleForTesting();
6204 
6205   // TaskRunner implementation:
6206   void PostTask(std::function<void()>) override;
6207   void PostDelayedTask(std::function<void()>, uint32_t delay_ms) override;
6208   void AddFileDescriptorWatch(PlatformHandle, std::function<void()>) override;
6209   void RemoveFileDescriptorWatch(PlatformHandle) override;
6210   bool RunsTasksOnCurrentThread() const override;
6211 
6212   // Returns true if the task runner is quitting, or has quit and hasn't been
6213   // restarted since. Exposed primarily for ThreadTaskRunner, not necessary for
6214   // normal use of this class.
6215   bool QuitCalled();
6216 
6217  private:
6218   void WakeUp();
6219   void UpdateWatchTasksLocked();
6220   int GetDelayMsToNextTaskLocked() const;
6221   void RunImmediateAndDelayedTask();
6222   void PostFileDescriptorWatches(uint64_t windows_wait_result);
6223   void RunFileDescriptorWatch(PlatformHandle);
6224 
6225   ThreadChecker thread_checker_;
6226   PlatformThreadId created_thread_id_ = GetThreadId();
6227 
6228   EventFd event_;
6229 
6230 // The array of fds/handles passed to poll(2) / WaitForMultipleObjects().
6231 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
6232   std::vector<PlatformHandle> poll_fds_;
6233 #else
6234   std::vector<struct pollfd> poll_fds_;
6235 #endif
6236 
6237   // --- Begin lock-protected members ---
6238 
6239   std::mutex lock_;
6240 
6241   std::deque<std::function<void()>> immediate_tasks_;
6242   std::multimap<TimeMillis, std::function<void()>> delayed_tasks_;
6243   bool quit_ = false;
6244 
6245   struct WatchTask {
6246     std::function<void()> callback;
6247 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
6248     // On UNIX systems we make the FD number negative in |poll_fds_| to avoid
6249     // polling it again until the queued task runs. On Windows we can't do that.
6250     // Instead we keep track of its state here.
6251     bool pending = false;
6252 #else
6253     size_t poll_fd_index;  // Index into |poll_fds_|.
6254 #endif
6255   };
6256 
6257   std::map<PlatformHandle, WatchTask> watch_tasks_;
6258   bool watch_tasks_changed_ = false;
6259 
6260   // --- End lock-protected members ---
6261 };
6262 
6263 }  // namespace base
6264 }  // namespace perfetto
6265 
6266 #endif  // INCLUDE_PERFETTO_EXT_BASE_UNIX_TASK_RUNNER_H_
6267 /*
6268  * Copyright (C) 2019 The Android Open Source Project
6269  *
6270  * Licensed under the Apache License, Version 2.0 (the "License");
6271  * you may not use this file except in compliance with the License.
6272  * You may obtain a copy of the License at
6273  *
6274  *      http://www.apache.org/licenses/LICENSE-2.0
6275  *
6276  * Unless required by applicable law or agreed to in writing, software
6277  * distributed under the License is distributed on an "AS IS" BASIS,
6278  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6279  * See the License for the specific language governing permissions and
6280  * limitations under the License.
6281  */
6282 
6283 #ifndef INCLUDE_PERFETTO_EXT_BASE_THREAD_TASK_RUNNER_H_
6284 #define INCLUDE_PERFETTO_EXT_BASE_THREAD_TASK_RUNNER_H_
6285 
6286 #include <functional>
6287 #include <thread>
6288 
6289 // gen_amalgamated expanded: #include "perfetto/ext/base/unix_task_runner.h"
6290 
6291 namespace perfetto {
6292 namespace base {
6293 
6294 // A UnixTaskRunner backed by a dedicated task thread. Shuts down the runner and
6295 // joins the thread upon destruction. Can be moved to transfer ownership.
6296 //
6297 // Guarantees that:
6298 // * the UnixTaskRunner will be constructed and destructed on the task thread.
6299 // * the task thread will live for the lifetime of the UnixTaskRunner.
6300 //
6301 class PERFETTO_EXPORT ThreadTaskRunner : public TaskRunner {
6302  public:
CreateAndStart(const std::string & name="")6303   static ThreadTaskRunner CreateAndStart(const std::string& name = "") {
6304     return ThreadTaskRunner(name);
6305   }
6306 
6307   ThreadTaskRunner(const ThreadTaskRunner&) = delete;
6308   ThreadTaskRunner& operator=(const ThreadTaskRunner&) = delete;
6309 
6310   ThreadTaskRunner(ThreadTaskRunner&&) noexcept;
6311   ThreadTaskRunner& operator=(ThreadTaskRunner&&);
6312   ~ThreadTaskRunner() override;
6313 
6314   // Executes the given function on the task runner thread and blocks the caller
6315   // thread until the function has run.
6316   void PostTaskAndWaitForTesting(std::function<void()>);
6317 
6318   // Can be called from another thread to get the CPU time of the thread the
6319   // task-runner is executing on.
6320   uint64_t GetThreadCPUTimeNsForTesting();
6321 
6322   // Returns a pointer to the UnixTaskRunner, which is valid for the lifetime of
6323   // this ThreadTaskRunner object (unless this object is moved-from, in which
6324   // case the pointer remains valid for the lifetime of the new owning
6325   // ThreadTaskRunner).
6326   //
6327   // Warning: do not call Quit() on the returned runner pointer, the termination
6328   // should be handled exclusively by this class' destructor.
get() const6329   UnixTaskRunner* get() const { return task_runner_; }
6330 
6331   // TaskRunner implementation.
6332   // These methods just proxy to the underlying task_runner_.
6333   void PostTask(std::function<void()>) override;
6334   void PostDelayedTask(std::function<void()>, uint32_t delay_ms) override;
6335   void AddFileDescriptorWatch(PlatformHandle, std::function<void()>) override;
6336   void RemoveFileDescriptorWatch(PlatformHandle) override;
6337   bool RunsTasksOnCurrentThread() const override;
6338 
6339  private:
6340   explicit ThreadTaskRunner(const std::string& name);
6341   void RunTaskThread(std::function<void(UnixTaskRunner*)> initializer);
6342 
6343   std::thread thread_;
6344   std::string name_;
6345   UnixTaskRunner* task_runner_ = nullptr;
6346 };
6347 
6348 }  // namespace base
6349 }  // namespace perfetto
6350 
6351 #endif  // INCLUDE_PERFETTO_EXT_BASE_THREAD_TASK_RUNNER_H_
6352 // gen_amalgamated begin header: include/perfetto/ext/base/thread_utils.h
6353 /*
6354  * Copyright (C) 2020 The Android Open Source Project
6355  *
6356  * Licensed under the Apache License, Version 2.0 (the "License");
6357  * you may not use this file except in compliance with the License.
6358  * You may obtain a copy of the License at
6359  *
6360  *      http://www.apache.org/licenses/LICENSE-2.0
6361  *
6362  * Unless required by applicable law or agreed to in writing, software
6363  * distributed under the License is distributed on an "AS IS" BASIS,
6364  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6365  * See the License for the specific language governing permissions and
6366  * limitations under the License.
6367  */
6368 
6369 #ifndef INCLUDE_PERFETTO_EXT_BASE_THREAD_UTILS_H_
6370 #define INCLUDE_PERFETTO_EXT_BASE_THREAD_UTILS_H_
6371 
6372 #include <string>
6373 
6374 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
6375 
6376 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
6377     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
6378     PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
6379 #include <pthread.h>
6380 #include <string.h>
6381 #include <algorithm>
6382 #endif
6383 
6384 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
6385 #include <sys/prctl.h>
6386 #endif
6387 
6388 // Internal implementation utils that aren't as widely useful/supported as
6389 // base/thread_utils.h.
6390 
6391 namespace perfetto {
6392 namespace base {
6393 
6394 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
6395     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
6396     PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
6397 // Sets the "comm" of the calling thread to the first 15 chars of the given
6398 // string.
MaybeSetThreadName(const std::string & name)6399 inline bool MaybeSetThreadName(const std::string& name) {
6400   char buf[16] = {};
6401   size_t sz = std::min(name.size(), static_cast<size_t>(15));
6402   strncpy(buf, name.c_str(), sz);
6403 
6404 #if PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
6405   return pthread_setname_np(buf) == 0;
6406 #else
6407   return pthread_setname_np(pthread_self(), buf) == 0;
6408 #endif
6409 }
6410 
GetThreadName(std::string & out_result)6411 inline bool GetThreadName(std::string& out_result) {
6412   char buf[16] = {};
6413 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
6414   if (prctl(PR_GET_NAME, buf) != 0)
6415     return false;
6416 #else
6417   if (pthread_getname_np(pthread_self(), buf, sizeof(buf)) != 0)
6418     return false;
6419 #endif
6420   out_result = std::string(buf);
6421   return true;
6422 }
6423 
6424 #else
6425 inline bool MaybeSetThreadName(const std::string&) {
6426   return false;
6427 }
6428 inline bool GetThreadName(std::string&) {
6429   return false;
6430 }
6431 #endif
6432 
6433 }  // namespace base
6434 }  // namespace perfetto
6435 
6436 #endif  // INCLUDE_PERFETTO_EXT_BASE_THREAD_UTILS_H_
6437 /*
6438  * Copyright (C) 2019 The Android Open Source Project
6439  *
6440  * Licensed under the Apache License, Version 2.0 (the "License");
6441  * you may not use this file except in compliance with the License.
6442  * You may obtain a copy of the License at
6443  *
6444  *      http://www.apache.org/licenses/LICENSE-2.0
6445  *
6446  * Unless required by applicable law or agreed to in writing, software
6447  * distributed under the License is distributed on an "AS IS" BASIS,
6448  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6449  * See the License for the specific language governing permissions and
6450  * limitations under the License.
6451  */
6452 
6453 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
6454 
6455 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_task_runner.h"
6456 
6457 #include <condition_variable>
6458 #include <functional>
6459 #include <mutex>
6460 #include <thread>
6461 
6462 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
6463 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_utils.h"
6464 // gen_amalgamated expanded: #include "perfetto/ext/base/unix_task_runner.h"
6465 
6466 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
6467     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
6468 #include <sys/prctl.h>
6469 #endif
6470 
6471 namespace perfetto {
6472 namespace base {
6473 
ThreadTaskRunner(ThreadTaskRunner && other)6474 ThreadTaskRunner::ThreadTaskRunner(ThreadTaskRunner&& other) noexcept
6475     : thread_(std::move(other.thread_)), task_runner_(other.task_runner_) {
6476   other.task_runner_ = nullptr;
6477 }
6478 
operator =(ThreadTaskRunner && other)6479 ThreadTaskRunner& ThreadTaskRunner::operator=(ThreadTaskRunner&& other) {
6480   this->~ThreadTaskRunner();
6481   new (this) ThreadTaskRunner(std::move(other));
6482   return *this;
6483 }
6484 
~ThreadTaskRunner()6485 ThreadTaskRunner::~ThreadTaskRunner() {
6486   if (task_runner_) {
6487     PERFETTO_CHECK(!task_runner_->QuitCalled());
6488     task_runner_->Quit();
6489 
6490     PERFETTO_DCHECK(thread_.joinable());
6491   }
6492   if (thread_.joinable())
6493     thread_.join();
6494 }
6495 
ThreadTaskRunner(const std::string & name)6496 ThreadTaskRunner::ThreadTaskRunner(const std::string& name) : name_(name) {
6497   std::mutex init_lock;
6498   std::condition_variable init_cv;
6499 
6500   std::function<void(UnixTaskRunner*)> initializer =
6501       [this, &init_lock, &init_cv](UnixTaskRunner* task_runner) {
6502         std::lock_guard<std::mutex> lock(init_lock);
6503         task_runner_ = task_runner;
6504         // Notify while still holding the lock, as init_cv ceases to exist as
6505         // soon as the main thread observes a non-null task_runner_, and it can
6506         // wake up spuriously (i.e. before the notify if we had unlocked before
6507         // notifying).
6508         init_cv.notify_one();
6509       };
6510 
6511   thread_ = std::thread(&ThreadTaskRunner::RunTaskThread, this,
6512                         std::move(initializer));
6513 
6514   std::unique_lock<std::mutex> lock(init_lock);
6515   init_cv.wait(lock, [this] { return !!task_runner_; });
6516 }
6517 
RunTaskThread(std::function<void (UnixTaskRunner *)> initializer)6518 void ThreadTaskRunner::RunTaskThread(
6519     std::function<void(UnixTaskRunner*)> initializer) {
6520   if (!name_.empty()) {
6521     base::MaybeSetThreadName(name_);
6522   }
6523 
6524   UnixTaskRunner task_runner;
6525   task_runner.PostTask(std::bind(std::move(initializer), &task_runner));
6526   task_runner.Run();
6527 }
6528 
PostTaskAndWaitForTesting(std::function<void ()> fn)6529 void ThreadTaskRunner::PostTaskAndWaitForTesting(std::function<void()> fn) {
6530   std::mutex mutex;
6531   std::condition_variable cv;
6532 
6533   std::unique_lock<std::mutex> lock(mutex);
6534   bool done = false;
6535   task_runner_->PostTask([&mutex, &cv, &done, &fn] {
6536     fn();
6537 
6538     std::lock_guard<std::mutex> inner_lock(mutex);
6539     done = true;
6540     cv.notify_one();
6541   });
6542   cv.wait(lock, [&done] { return done; });
6543 }
6544 
GetThreadCPUTimeNsForTesting()6545 uint64_t ThreadTaskRunner::GetThreadCPUTimeNsForTesting() {
6546   uint64_t thread_time_ns = 0;
6547   PostTaskAndWaitForTesting([&thread_time_ns] {
6548     thread_time_ns = static_cast<uint64_t>(base::GetThreadCPUTimeNs().count());
6549   });
6550   return thread_time_ns;
6551 }
6552 
PostTask(std::function<void ()> task)6553 void ThreadTaskRunner::PostTask(std::function<void()> task) {
6554   task_runner_->PostTask(std::move(task));
6555 }
6556 
PostDelayedTask(std::function<void ()> task,uint32_t delay_ms)6557 void ThreadTaskRunner::PostDelayedTask(std::function<void()> task,
6558                                        uint32_t delay_ms) {
6559   task_runner_->PostDelayedTask(std::move(task), delay_ms);
6560 }
6561 
AddFileDescriptorWatch(PlatformHandle handle,std::function<void ()> watch_task)6562 void ThreadTaskRunner::AddFileDescriptorWatch(
6563     PlatformHandle handle,
6564     std::function<void()> watch_task) {
6565   task_runner_->AddFileDescriptorWatch(handle, std::move(watch_task));
6566 }
6567 
RemoveFileDescriptorWatch(PlatformHandle handle)6568 void ThreadTaskRunner::RemoveFileDescriptorWatch(PlatformHandle handle) {
6569   task_runner_->RemoveFileDescriptorWatch(handle);
6570 }
6571 
RunsTasksOnCurrentThread() const6572 bool ThreadTaskRunner::RunsTasksOnCurrentThread() const {
6573   return task_runner_->RunsTasksOnCurrentThread();
6574 }
6575 
6576 }  // namespace base
6577 }  // namespace perfetto
6578 // gen_amalgamated begin source: src/base/unix_task_runner.cc
6579 /*
6580  * Copyright (C) 2017 The Android Open Source Project
6581  *
6582  * Licensed under the Apache License, Version 2.0 (the "License");
6583  * you may not use this file except in compliance with the License.
6584  * You may obtain a copy of the License at
6585  *
6586  *      http://www.apache.org/licenses/LICENSE-2.0
6587  *
6588  * Unless required by applicable law or agreed to in writing, software
6589  * distributed under the License is distributed on an "AS IS" BASIS,
6590  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6591  * See the License for the specific language governing permissions and
6592  * limitations under the License.
6593  */
6594 
6595 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
6596 
6597 // gen_amalgamated expanded: #include "perfetto/ext/base/unix_task_runner.h"
6598 
6599 #include <errno.h>
6600 #include <stdlib.h>
6601 
6602 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
6603 #include <Windows.h>
6604 #include <synchapi.h>
6605 #else
6606 #include <unistd.h>
6607 #endif
6608 
6609 #include <algorithm>
6610 #include <limits>
6611 
6612 // gen_amalgamated expanded: #include "perfetto/ext/base/watchdog.h"
6613 
6614 namespace perfetto {
6615 namespace base {
6616 
UnixTaskRunner()6617 UnixTaskRunner::UnixTaskRunner() {
6618   AddFileDescriptorWatch(event_.fd(), [] {
6619     // Not reached -- see PostFileDescriptorWatches().
6620     PERFETTO_DFATAL("Should be unreachable.");
6621   });
6622 }
6623 
6624 UnixTaskRunner::~UnixTaskRunner() = default;
6625 
WakeUp()6626 void UnixTaskRunner::WakeUp() {
6627   event_.Notify();
6628 }
6629 
Run()6630 void UnixTaskRunner::Run() {
6631   PERFETTO_DCHECK_THREAD(thread_checker_);
6632   created_thread_id_ = GetThreadId();
6633   quit_ = false;
6634   for (;;) {
6635     int poll_timeout_ms;
6636     {
6637       std::lock_guard<std::mutex> lock(lock_);
6638       if (quit_)
6639         return;
6640       poll_timeout_ms = GetDelayMsToNextTaskLocked();
6641       UpdateWatchTasksLocked();
6642     }
6643 
6644 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
6645     DWORD timeout =
6646         poll_timeout_ms >= 0 ? static_cast<DWORD>(poll_timeout_ms) : INFINITE;
6647     DWORD ret =
6648         WaitForMultipleObjects(static_cast<DWORD>(poll_fds_.size()),
6649                                &poll_fds_[0], /*bWaitAll=*/false, timeout);
6650     // Unlike poll(2), WaitForMultipleObjects() returns only *one* handle in the
6651     // set, even when >1 is signalled. In order to avoid starvation,
6652     // PostFileDescriptorWatches() will WaitForSingleObject() each other handle
6653     // to ensure fairness. |ret| here is passed just to avoid an extra
6654     // WaitForSingleObject() for the one handle that WaitForMultipleObject()
6655     // returned.
6656     PostFileDescriptorWatches(ret);
6657 #else
6658     int ret = PERFETTO_EINTR(poll(
6659         &poll_fds_[0], static_cast<nfds_t>(poll_fds_.size()), poll_timeout_ms));
6660     PERFETTO_CHECK(ret >= 0);
6661     PostFileDescriptorWatches(0 /*ignored*/);
6662 #endif
6663 
6664     // To avoid starvation we always interleave all types of tasks -- immediate,
6665     // delayed and file descriptor watches.
6666     RunImmediateAndDelayedTask();
6667   }
6668 }
6669 
Quit()6670 void UnixTaskRunner::Quit() {
6671   std::lock_guard<std::mutex> lock(lock_);
6672   quit_ = true;
6673   WakeUp();
6674 }
6675 
QuitCalled()6676 bool UnixTaskRunner::QuitCalled() {
6677   std::lock_guard<std::mutex> lock(lock_);
6678   return quit_;
6679 }
6680 
IsIdleForTesting()6681 bool UnixTaskRunner::IsIdleForTesting() {
6682   std::lock_guard<std::mutex> lock(lock_);
6683   return immediate_tasks_.empty();
6684 }
6685 
UpdateWatchTasksLocked()6686 void UnixTaskRunner::UpdateWatchTasksLocked() {
6687   PERFETTO_DCHECK_THREAD(thread_checker_);
6688 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
6689   if (!watch_tasks_changed_)
6690     return;
6691   watch_tasks_changed_ = false;
6692 #endif
6693   poll_fds_.clear();
6694   for (auto& it : watch_tasks_) {
6695     PlatformHandle handle = it.first;
6696     WatchTask& watch_task = it.second;
6697 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
6698     if (!watch_task.pending)
6699       poll_fds_.push_back(handle);
6700 #else
6701     watch_task.poll_fd_index = poll_fds_.size();
6702     poll_fds_.push_back({handle, POLLIN | POLLHUP, 0});
6703 #endif
6704   }
6705 }
6706 
RunImmediateAndDelayedTask()6707 void UnixTaskRunner::RunImmediateAndDelayedTask() {
6708   // If locking overhead becomes an issue, add a separate work queue.
6709   std::function<void()> immediate_task;
6710   std::function<void()> delayed_task;
6711   TimeMillis now = GetWallTimeMs();
6712   {
6713     std::lock_guard<std::mutex> lock(lock_);
6714     if (!immediate_tasks_.empty()) {
6715       immediate_task = std::move(immediate_tasks_.front());
6716       immediate_tasks_.pop_front();
6717     }
6718     if (!delayed_tasks_.empty()) {
6719       auto it = delayed_tasks_.begin();
6720       if (now >= it->first) {
6721         delayed_task = std::move(it->second);
6722         delayed_tasks_.erase(it);
6723       }
6724     }
6725   }
6726 
6727   errno = 0;
6728   if (immediate_task)
6729     RunTaskWithWatchdogGuard(immediate_task);
6730   errno = 0;
6731   if (delayed_task)
6732     RunTaskWithWatchdogGuard(delayed_task);
6733 }
6734 
PostFileDescriptorWatches(uint64_t windows_wait_result)6735 void UnixTaskRunner::PostFileDescriptorWatches(uint64_t windows_wait_result) {
6736   PERFETTO_DCHECK_THREAD(thread_checker_);
6737   for (size_t i = 0; i < poll_fds_.size(); i++) {
6738 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
6739     const PlatformHandle handle = poll_fds_[i];
6740     // |windows_wait_result| is the result of WaitForMultipleObjects() call. If
6741     // one of the objects was signalled, it will have a value between
6742     // [0, poll_fds_.size()].
6743     if (i != windows_wait_result &&
6744         WaitForSingleObject(handle, 0) != WAIT_OBJECT_0) {
6745       continue;
6746     }
6747 #else
6748     base::ignore_result(windows_wait_result);
6749     const PlatformHandle handle = poll_fds_[i].fd;
6750     if (!(poll_fds_[i].revents & (POLLIN | POLLHUP)))
6751       continue;
6752     poll_fds_[i].revents = 0;
6753 #endif
6754 
6755     // The wake-up event is handled inline to avoid an infinite recursion of
6756     // posted tasks.
6757     if (handle == event_.fd()) {
6758       event_.Clear();
6759       continue;
6760     }
6761 
6762     // Binding to |this| is safe since we are the only object executing the
6763     // task.
6764     PostTask(std::bind(&UnixTaskRunner::RunFileDescriptorWatch, this, handle));
6765 
6766     // Flag the task as pending.
6767 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
6768     // On Windows this is done by marking the WatchTask entry as pending. This
6769     // is more expensive than Linux as requires rebuilding the |poll_fds_|
6770     // vector on each call. There doesn't seem to be a good alternative though.
6771     auto it = watch_tasks_.find(handle);
6772     PERFETTO_CHECK(it != watch_tasks_.end());
6773     PERFETTO_DCHECK(!it->second.pending);
6774     it->second.pending = true;
6775 #else
6776     // On UNIX systems instead, we just make the fd negative while its task is
6777     // pending. This makes poll(2) ignore the fd.
6778     PERFETTO_DCHECK(poll_fds_[i].fd >= 0);
6779     poll_fds_[i].fd = -poll_fds_[i].fd;
6780 #endif
6781   }
6782 }
6783 
RunFileDescriptorWatch(PlatformHandle fd)6784 void UnixTaskRunner::RunFileDescriptorWatch(PlatformHandle fd) {
6785   std::function<void()> task;
6786   {
6787     std::lock_guard<std::mutex> lock(lock_);
6788     auto it = watch_tasks_.find(fd);
6789     if (it == watch_tasks_.end())
6790       return;
6791     WatchTask& watch_task = it->second;
6792 
6793     // Make poll(2) pay attention to the fd again. Since another thread may have
6794     // updated this watch we need to refresh the set first.
6795     UpdateWatchTasksLocked();
6796 
6797 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
6798     // On Windows we manually track the presence of outstanding tasks for the
6799     // watch. The UpdateWatchTasksLocked() in the Run() loop will re-add the
6800     // task to the |poll_fds_| vector.
6801     PERFETTO_DCHECK(watch_task.pending);
6802     watch_task.pending = false;
6803 #else
6804     size_t fd_index = watch_task.poll_fd_index;
6805     PERFETTO_DCHECK(fd_index < poll_fds_.size());
6806     PERFETTO_DCHECK(::abs(poll_fds_[fd_index].fd) == fd);
6807     poll_fds_[fd_index].fd = fd;
6808 #endif
6809     task = watch_task.callback;
6810   }
6811   errno = 0;
6812   RunTaskWithWatchdogGuard(task);
6813 }
6814 
GetDelayMsToNextTaskLocked() const6815 int UnixTaskRunner::GetDelayMsToNextTaskLocked() const {
6816   PERFETTO_DCHECK_THREAD(thread_checker_);
6817   if (!immediate_tasks_.empty())
6818     return 0;
6819   if (!delayed_tasks_.empty()) {
6820     TimeMillis diff = delayed_tasks_.begin()->first - GetWallTimeMs();
6821     return std::max(0, static_cast<int>(diff.count()));
6822   }
6823   return -1;
6824 }
6825 
PostTask(std::function<void ()> task)6826 void UnixTaskRunner::PostTask(std::function<void()> task) {
6827   bool was_empty;
6828   {
6829     std::lock_guard<std::mutex> lock(lock_);
6830     was_empty = immediate_tasks_.empty();
6831     immediate_tasks_.push_back(std::move(task));
6832   }
6833   if (was_empty)
6834     WakeUp();
6835 }
6836 
PostDelayedTask(std::function<void ()> task,uint32_t delay_ms)6837 void UnixTaskRunner::PostDelayedTask(std::function<void()> task,
6838                                      uint32_t delay_ms) {
6839   TimeMillis runtime = GetWallTimeMs() + TimeMillis(delay_ms);
6840   {
6841     std::lock_guard<std::mutex> lock(lock_);
6842     delayed_tasks_.insert(std::make_pair(runtime, std::move(task)));
6843   }
6844   WakeUp();
6845 }
6846 
AddFileDescriptorWatch(PlatformHandle fd,std::function<void ()> task)6847 void UnixTaskRunner::AddFileDescriptorWatch(PlatformHandle fd,
6848                                             std::function<void()> task) {
6849   PERFETTO_DCHECK(PlatformHandleChecker::IsValid(fd));
6850   {
6851     std::lock_guard<std::mutex> lock(lock_);
6852     PERFETTO_DCHECK(!watch_tasks_.count(fd));
6853     WatchTask& watch_task = watch_tasks_[fd];
6854     watch_task.callback = std::move(task);
6855 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
6856     watch_task.pending = false;
6857 #else
6858     watch_task.poll_fd_index = SIZE_MAX;
6859 #endif
6860     watch_tasks_changed_ = true;
6861   }
6862   WakeUp();
6863 }
6864 
RemoveFileDescriptorWatch(PlatformHandle fd)6865 void UnixTaskRunner::RemoveFileDescriptorWatch(PlatformHandle fd) {
6866   PERFETTO_DCHECK(PlatformHandleChecker::IsValid(fd));
6867   {
6868     std::lock_guard<std::mutex> lock(lock_);
6869     PERFETTO_DCHECK(watch_tasks_.count(fd));
6870     watch_tasks_.erase(fd);
6871     watch_tasks_changed_ = true;
6872   }
6873   // No need to schedule a wake-up for this.
6874 }
6875 
RunsTasksOnCurrentThread() const6876 bool UnixTaskRunner::RunsTasksOnCurrentThread() const {
6877   return GetThreadId() == created_thread_id_;
6878 }
6879 
6880 }  // namespace base
6881 }  // namespace perfetto
6882 // gen_amalgamated begin source: src/base/subprocess.cc
6883 // gen_amalgamated begin header: include/perfetto/ext/base/subprocess.h
6884 /*
6885  * Copyright (C) 2020 The Android Open Source Project
6886  *
6887  * Licensed under the Apache License, Version 2.0 (the "License");
6888  * you may not use this file except in compliance with the License.
6889  * You may obtain a copy of the License at
6890  *
6891  *      http://www.apache.org/licenses/LICENSE-2.0
6892  *
6893  * Unless required by applicable law or agreed to in writing, software
6894  * distributed under the License is distributed on an "AS IS" BASIS,
6895  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6896  * See the License for the specific language governing permissions and
6897  * limitations under the License.
6898  */
6899 
6900 #ifndef INCLUDE_PERFETTO_EXT_BASE_SUBPROCESS_H_
6901 #define INCLUDE_PERFETTO_EXT_BASE_SUBPROCESS_H_
6902 
6903 #include <condition_variable>
6904 #include <functional>
6905 #include <initializer_list>
6906 #include <mutex>
6907 #include <string>
6908 #include <thread>
6909 #include <vector>
6910 
6911 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
6912 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
6913 // gen_amalgamated expanded: #include "perfetto/base/platform_handle.h"
6914 // gen_amalgamated expanded: #include "perfetto/base/proc_utils.h"
6915 // gen_amalgamated expanded: #include "perfetto/ext/base/event_fd.h"
6916 // gen_amalgamated expanded: #include "perfetto/ext/base/pipe.h"
6917 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
6918 
6919 namespace perfetto {
6920 namespace base {
6921 
6922 // Handles creation and lifecycle management of subprocesses, taking care of
6923 // all subtleties involved in handling processes on UNIX.
6924 // This class allows to deal with macro two use-cases:
6925 // 1) fork() + exec() equivalent: for spawning a brand new process image.
6926 //    This happens when |args.exec_cmd| is not empty.
6927 //    This is safe to use even in a multi-threaded environment.
6928 // 2) fork(): for spawning a process and running a function.
6929 //    This happens when |args.posix_entrypoint_for_testing| is not empty.
6930 //    This is intended only for tests as it is extremely subtle.
6931 //    This mode must be used with extreme care. Before the entrypoint is
6932 //    invoked all file descriptors other than stdin/out/err and the ones
6933 //    specified in |args.preserve_fds| will be closed, to avoid each process
6934 //    retaining a dupe of other subprocesses pipes. This however means that
6935 //    any non trivial calls (including logging) must be avoided as they might
6936 //    refer to FDs that are now closed. The entrypoint should really be used
6937 //    just to signal a pipe or similar for synchronizing sequencing in tests.
6938 
6939 //
6940 // This class allows to control stdin/out/err pipe redirection and takes care
6941 // of keeping all the pipes pumped (stdin) / drained (stdout/err), in a similar
6942 // fashion of python's subprocess.Communicate()
6943 // stdin: is always piped and closed once the |args.input| buffer is written.
6944 // stdout/err can be either:
6945 //   - dup()ed onto the parent process stdout/err.
6946 //   - redirected onto /dev/null.
6947 //   - piped onto a buffer (see output() method). There is only one output
6948 //     buffer in total. If both stdout and stderr are set to kBuffer mode, they
6949 //     will be merged onto the same. There doesn't seem any use case where they
6950 //     are needed distinctly.
6951 //
6952 // Some caveats worth mentioning:
6953 // - It always waitpid()s, to avoid leaving zombies around. If the process is
6954 //   not terminated by the time the destructor is reached, the dtor will
6955 //   send a SIGKILL and wait for the termination.
6956 // - After fork()-ing it will close all file descriptors, preserving only
6957 //   stdin/out/err and the fds listed in |args.preserve_fds|.
6958 // - On Linux/Android, the child process will be SIGKILL-ed if the calling
6959 //   thread exists, even if the Subprocess is std::move()-d onto another thread.
6960 //   This happens by virtue PR_SET_PDEATHSIG, which is used to avoid that
6961 //   child processes are leaked in the case of a crash of the parent (frequent
6962 //   in tests). However, the child process might still be leaked if execing
6963 //   a setuid/setgid binary (see man 2 prctl).
6964 //
6965 // Usage:
6966 // base::Subprocess p({"/bin/cat", "-"});
6967 // (or equivalently:
6968 //     base::Subprocess p;
6969 //     p.args.exec_cmd.push_back("/bin/cat");
6970 //     p.args.exec_cmd.push_back("-");
6971 //  )
6972 // p.args.stdout_mode = base::Subprocess::kBuffer;
6973 // p.args.stderr_mode = base::Subprocess::kInherit;
6974 // p.args.input = "stdin contents";
6975 // p.Call();
6976 // (or equivalently:
6977 //     p.Start();
6978 //     p.Wait();
6979 // )
6980 // EXPECT_EQ(p.status(), base::Subprocess::kTerminated);
6981 // EXPECT_EQ(p.returncode(), 0);
6982 class Subprocess {
6983  public:
6984   enum Status {
6985     kNotStarted = 0,  // Before calling Start() or Call().
6986     kRunning,         // After calling Start(), before Wait().
6987     kTerminated,      // The subprocess terminated, either successfully or not.
6988                       // This includes crashes or other signals on UNIX.
6989   };
6990 
6991   enum OutputMode {
6992     kInherit = 0,  // Inherit's the caller process stdout/stderr.
6993     kDevNull,      // dup() onto /dev/null
6994     kBuffer,       // dup() onto a pipe and move it into the output() buffer.
6995     kFd,           // dup() onto the passed args.fd.
6996   };
6997 
6998   // Input arguments for configuring the subprocess behavior.
6999   struct Args {
Argsperfetto::base::Subprocess::Args7000     Args(std::initializer_list<std::string> _cmd = {}) : exec_cmd(_cmd) {}
7001     Args(Args&&) noexcept;
7002     Args& operator=(Args&&);
7003     // If non-empty this will cause an exec() when Start()/Call() are called.
7004     std::vector<std::string> exec_cmd;
7005 
7006 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
7007     // If non-empty, it changes the argv[0] argument passed to exec. If
7008     // unset, argv[0] == exec_cmd[0]. This is to handle cases like:
7009     // exec_cmd = {"/proc/self/exec"}, argv0: "my_custom_test_override".
7010     std::string posix_argv0_override_for_testing;
7011 
7012     // If non-empty this will be invoked on the fork()-ed child process, after
7013     // stdin/out/err has been redirected and all other file descriptor are
7014     // closed. It is valid to specify both |exec_cmd| AND
7015     // |posix_entrypoint_for_testing|. In this case the latter will be invoked
7016     // just before the exec() call, but after having closed all fds % stdin/o/e.
7017     // This is for synchronization barriers in tests.
7018     std::function<void()> posix_entrypoint_for_testing;
7019 #endif
7020 
7021     // If non-empty, replaces the environment passed to exec().
7022     std::vector<std::string> env;
7023 
7024     // The file descriptors in this list will not be closed.
7025     std::vector<int> preserve_fds;
7026 
7027     // The data to push in the child process stdin.
7028     std::string input;
7029 
7030     OutputMode stdout_mode = kInherit;
7031     OutputMode stderr_mode = kInherit;
7032 
7033     base::ScopedPlatformHandle out_fd;
7034 
7035     // Returns " ".join(exec_cmd), quoting arguments.
7036     std::string GetCmdString() const;
7037   };
7038 
7039   struct ResourceUsage {
7040     uint32_t cpu_utime_ms = 0;
7041     uint32_t cpu_stime_ms = 0;
7042     uint32_t max_rss_kb = 0;
7043     uint32_t min_page_faults = 0;
7044     uint32_t maj_page_faults = 0;
7045     uint32_t vol_ctx_switch = 0;
7046     uint32_t invol_ctx_switch = 0;
7047 
cpu_time_msperfetto::base::Subprocess::ResourceUsage7048     uint32_t cpu_time_ms() const { return cpu_utime_ms + cpu_stime_ms; }
7049   };
7050 
7051   explicit Subprocess(std::initializer_list<std::string> exec_cmd = {});
7052   Subprocess(Subprocess&&) noexcept;
7053   Subprocess& operator=(Subprocess&&);
7054   ~Subprocess();  // It will KillAndWaitForTermination() if still alive.
7055 
7056   // Starts the subprocess but doesn't wait for its termination. The caller
7057   // is expected to either call Wait() or Poll() after this call.
7058   void Start();
7059 
7060   // Wait for process termination. Can be called more than once.
7061   // Args:
7062   //   |timeout_ms| = 0: wait indefinitely.
7063   //   |timeout_ms| > 0: wait for at most |timeout_ms|.
7064   // Returns:
7065   //  True: The process terminated. See status() and returncode().
7066   //  False: Timeout reached, the process is still running. In this case the
7067   //         process will be left in the kRunning state.
7068   bool Wait(int timeout_ms = 0);
7069 
7070   // Equivalent of Start() + Wait();
7071   // Returns true if the process exited cleanly with return code 0. False in
7072   // any othe case.
7073   bool Call(int timeout_ms = 0);
7074 
7075   Status Poll();
7076 
7077   // Sends a signal (SIGKILL if not specified) and wait for process termination.
7078   void KillAndWaitForTermination(int sig_num = 0);
7079 
pid() const7080   PlatformProcessId pid() const { return s_->pid; }
7081 
7082   // The accessors below are updated only after a call to Poll(), Wait() or
7083   // KillAndWaitForTermination().
7084   // In most cases you want to call Poll() rather than these accessors.
7085 
status() const7086   Status status() const { return s_->status; }
returncode() const7087   int returncode() const { return s_->returncode; }
timed_out() const7088   bool timed_out() const { return s_->timed_out; }
7089 
7090   // This contains both stdout and stderr (if the corresponding _mode ==
7091   // kBuffer). It's non-const so the caller can std::move() it.
output()7092   std::string& output() { return s_->output; }
output() const7093   const std::string& output() const { return s_->output; }
7094 
posix_rusage() const7095   const ResourceUsage& posix_rusage() const { return *s_->rusage; }
7096 
7097   Args args;
7098 
7099  private:
7100   // The signal/exit code used when killing the process in case of a timeout.
7101   static const int kTimeoutSignal;
7102 
7103   Subprocess(const Subprocess&) = delete;
7104   Subprocess& operator=(const Subprocess&) = delete;
7105 
7106   // This is to deal robustly with the move operators, without having to
7107   // manually maintain member-wise move instructions.
7108   struct MovableState {
7109     base::Pipe stdin_pipe;
7110     base::Pipe stdouterr_pipe;
7111     PlatformProcessId pid;
7112     Status status = kNotStarted;
7113     int returncode = -1;
7114     std::string output;  // Stdin+stderr. Only when kBuffer.
7115     std::unique_ptr<ResourceUsage> rusage{new ResourceUsage()};
7116     bool timed_out = false;
7117 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
7118     std::thread stdouterr_thread;
7119     std::thread stdin_thread;
7120     ScopedPlatformHandle win_proc_handle;
7121     ScopedPlatformHandle win_thread_handle;
7122 
7123     base::EventFd stdouterr_done_event;
7124     std::mutex mutex;  // Protects locked_outerr_buf and the two pipes.
7125     std::string locked_outerr_buf;
7126 #else
7127     base::Pipe exit_status_pipe;
7128     size_t input_written = 0;
7129     std::thread waitpid_thread;
7130 #endif
7131   };
7132 
7133 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
7134   static void StdinThread(MovableState*, std::string input);
7135   static void StdoutErrThread(MovableState*);
7136 #else
7137   void TryPushStdin();
7138   void TryReadStdoutAndErr();
7139   void TryReadExitStatus();
7140   void KillAtMostOnce();
7141   bool PollInternal(int poll_timeout_ms);
7142 #endif
7143 
7144   std::unique_ptr<MovableState> s_;
7145 };
7146 
7147 }  // namespace base
7148 }  // namespace perfetto
7149 
7150 #endif  // INCLUDE_PERFETTO_EXT_BASE_SUBPROCESS_H_
7151 /*
7152  * Copyright (C) 2020 The Android Open Source Project
7153  *
7154  * Licensed under the Apache License, Version 2.0 (the "License");
7155  * you may not use this file except in compliance with the License.
7156  * You may obtain a copy of the License at
7157  *
7158  *      http://www.apache.org/licenses/LICENSE-2.0
7159  *
7160  * Unless required by applicable law or agreed to in writing, software
7161  * distributed under the License is distributed on an "AS IS" BASIS,
7162  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
7163  * See the License for the specific language governing permissions and
7164  * limitations under the License.
7165  */
7166 
7167 // gen_amalgamated expanded: #include "perfetto/ext/base/subprocess.h"
7168 
7169 #include <tuple>
7170 
7171 // This file contains only the common bits (ctors / dtors / move operators).
7172 // The rest lives in subprocess_posix.cc and subprocess_windows.cc.
7173 
7174 namespace perfetto {
7175 namespace base {
7176 
7177 Subprocess::Args::Args(Args&&) noexcept = default;
7178 Subprocess::Args& Subprocess::Args::operator=(Args&&) = default;
7179 
Subprocess(std::initializer_list<std::string> a)7180 Subprocess::Subprocess(std::initializer_list<std::string> a)
7181     : args(a), s_(new MovableState()) {}
7182 
Subprocess(Subprocess && other)7183 Subprocess::Subprocess(Subprocess&& other) noexcept {
7184   static_assert(sizeof(Subprocess) ==
7185                     sizeof(std::tuple<std::unique_ptr<MovableState>, Args>),
7186                 "base::Subprocess' move ctor needs updating");
7187   s_ = std::move(other.s_);
7188   args = std::move(other.args);
7189 
7190   // Reset the state of the moved-from object.
7191   other.s_.reset(new MovableState());
7192   other.~Subprocess();
7193   new (&other) Subprocess();
7194 }
7195 
operator =(Subprocess && other)7196 Subprocess& Subprocess::operator=(Subprocess&& other) {
7197   this->~Subprocess();
7198   new (this) Subprocess(std::move(other));
7199   return *this;
7200 }
7201 
~Subprocess()7202 Subprocess::~Subprocess() {
7203   if (s_->status == kRunning)
7204     KillAndWaitForTermination();
7205 }
7206 
Call(int timeout_ms)7207 bool Subprocess::Call(int timeout_ms) {
7208   PERFETTO_CHECK(s_->status == kNotStarted);
7209   Start();
7210 
7211   if (!Wait(timeout_ms)) {
7212     s_->timed_out = true;
7213     KillAndWaitForTermination(kTimeoutSignal);
7214   }
7215   PERFETTO_DCHECK(s_->status != kRunning);
7216   return s_->status == kTerminated && s_->returncode == 0;
7217 }
7218 
GetCmdString() const7219 std::string Subprocess::Args::GetCmdString() const {
7220   std::string str;
7221   for (size_t i = 0; i < exec_cmd.size(); i++) {
7222     str += i > 0 ? " \"" : "";
7223     str += exec_cmd[i];
7224     str += i > 0 ? "\"" : "";
7225   }
7226   return str;
7227 }
7228 
7229 }  // namespace base
7230 }  // namespace perfetto
7231 // gen_amalgamated begin source: src/base/subprocess_posix.cc
7232 /*
7233  * Copyright (C) 2020 The Android Open Source Project
7234  *
7235  * Licensed under the Apache License, Version 2.0 (the "License");
7236  * you may not use this file except in compliance with the License.
7237  * You may obtain a copy of the License at
7238  *
7239  *      http://www.apache.org/licenses/LICENSE-2.0
7240  *
7241  * Unless required by applicable law or agreed to in writing, software
7242  * distributed under the License is distributed on an "AS IS" BASIS,
7243  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
7244  * See the License for the specific language governing permissions and
7245  * limitations under the License.
7246  */
7247 
7248 // gen_amalgamated expanded: #include "perfetto/ext/base/subprocess.h"
7249 
7250 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
7251 
7252 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
7253     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
7254     PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
7255 
7256 #include <fcntl.h>
7257 #include <poll.h>
7258 #include <signal.h>
7259 #include <stdio.h>
7260 #include <sys/resource.h>
7261 #include <sys/types.h>
7262 #include <sys/wait.h>
7263 #include <unistd.h>
7264 
7265 #include <algorithm>
7266 #include <thread>
7267 #include <tuple>
7268 
7269 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
7270     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
7271 #include <sys/prctl.h>
7272 #endif
7273 
7274 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
7275 // gen_amalgamated expanded: #include "perfetto/base/time.h"
7276 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
7277 
7278 // In MacOS this is not defined in any header.
7279 extern "C" char** environ;
7280 
7281 namespace perfetto {
7282 namespace base {
7283 
7284 namespace {
7285 
7286 struct ChildProcessArgs {
7287   Subprocess::Args* create_args;
7288   const char* exec_cmd = nullptr;
7289   std::vector<char*> argv;
7290   std::vector<char*> env;
7291   int stdin_pipe_rd = -1;
7292   int stdouterr_pipe_wr = -1;
7293 };
7294 
7295 // Don't add any dynamic allocation in this function. This will be invoked
7296 // under a fork(), potentially in a state where the allocator lock is held.
ChildProcess(ChildProcessArgs * args)7297 void __attribute__((noreturn)) ChildProcess(ChildProcessArgs* args) {
7298 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
7299     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
7300   // In no case we want a child process to outlive its parent process. This is
7301   // relevant for tests, so that a test failure/crash doesn't leave child
7302   // processes around that get reparented to init.
7303   prctl(PR_SET_PDEATHSIG, SIGKILL);
7304 #endif
7305 
7306   auto die = [args](const char* err) __attribute__((noreturn)) {
7307     base::ignore_result(write(args->stdouterr_pipe_wr, err, strlen(err)));
7308     base::ignore_result(write(args->stdouterr_pipe_wr, "\n", 1));
7309     // From https://www.gnu.org/software/libc/manual/html_node/Exit-Status.html
7310     // "In particular, the value 128 is used to indicate failure to execute
7311     // another program in a subprocess. This convention is not universally
7312     // obeyed, but it is a good idea to follow it in your programs."
7313     _exit(128);
7314   };
7315 
7316   auto set_fd_close_on_exec = [&die](int fd, bool close_on_exec) {
7317     int flags = fcntl(fd, F_GETFD, 0);
7318     if (flags < 0)
7319       die("fcntl(F_GETFD) failed");
7320     flags = close_on_exec ? (flags | FD_CLOEXEC) : (flags & ~FD_CLOEXEC);
7321     if (fcntl(fd, F_SETFD, flags) < 0)
7322       die("fcntl(F_SETFD) failed");
7323   };
7324 
7325   if (getppid() == 1)
7326     die("terminating because parent process died");
7327 
7328   if (dup2(args->stdin_pipe_rd, STDIN_FILENO) == -1)
7329     die("Failed to dup2(STDIN)");
7330   close(args->stdin_pipe_rd);
7331 
7332   switch (args->create_args->stdout_mode) {
7333     case Subprocess::kInherit:
7334       break;
7335     case Subprocess::kDevNull: {
7336       if (dup2(open("/dev/null", O_RDWR), STDOUT_FILENO) == -1)
7337         die("Failed to dup2(STDOUT)");
7338       break;
7339     }
7340     case Subprocess::kBuffer:
7341       if (dup2(args->stdouterr_pipe_wr, STDOUT_FILENO) == -1)
7342         die("Failed to dup2(STDOUT)");
7343       break;
7344     case Subprocess::kFd:
7345       if (dup2(*args->create_args->out_fd, STDOUT_FILENO) == -1)
7346         die("Failed to dup2(STDOUT)");
7347       break;
7348   }
7349 
7350   switch (args->create_args->stderr_mode) {
7351     case Subprocess::kInherit:
7352       break;
7353     case Subprocess::kDevNull: {
7354       if (dup2(open("/dev/null", O_RDWR), STDERR_FILENO) == -1)
7355         die("Failed to dup2(STDERR)");
7356       break;
7357     }
7358     case Subprocess::kBuffer:
7359       if (dup2(args->stdouterr_pipe_wr, STDERR_FILENO) == -1)
7360         die("Failed to dup2(STDERR)");
7361       break;
7362     case Subprocess::kFd:
7363       if (dup2(*args->create_args->out_fd, STDERR_FILENO) == -1)
7364         die("Failed to dup2(STDERR)");
7365       break;
7366   }
7367 
7368   // Close all FDs % stdin/out/err and the ones that the client explicitly
7369   // asked to retain. The reason for this is twofold:
7370   // 1. For exec-only (i.e. entrypoint == empty) cases: it avoids leaking FDs
7371   //    that didn't get marked as O_CLOEXEC by accident.
7372   // 2. In fork() mode (entrypoint not empty) avoids retaining a dup of eventfds
7373   //    that would prevent the parent process to receive EOFs (tests usually use
7374   //    pipes as a synchronization mechanism between subprocesses).
7375   const auto& preserve_fds = args->create_args->preserve_fds;
7376   for (int i = 0; i < 512; i++) {
7377     if (i != STDIN_FILENO && i != STDERR_FILENO && i != STDOUT_FILENO &&
7378         i != args->stdouterr_pipe_wr &&
7379         !std::count(preserve_fds.begin(), preserve_fds.end(), i)) {
7380       close(i);
7381     }
7382   }
7383 
7384   // Clears O_CLOEXEC from stdin/out/err. These are the only FDs that we want
7385   // to be preserved after the exec().
7386   set_fd_close_on_exec(STDIN_FILENO, false);
7387   set_fd_close_on_exec(STDOUT_FILENO, false);
7388   set_fd_close_on_exec(STDERR_FILENO, false);
7389 
7390   // If the caller specified a std::function entrypoint, run that first.
7391   if (args->create_args->posix_entrypoint_for_testing)
7392     args->create_args->posix_entrypoint_for_testing();
7393 
7394   // If the caller specified only an entrypoint, without any args, exit now.
7395   // Otherwise proceed with the exec() below.
7396   if (!args->exec_cmd)
7397     _exit(0);
7398 
7399   // If |args[0]| is a path use execv() (which takes a path), othewise use
7400   // exevp(), which uses the shell and follows PATH.
7401   if (strchr(args->exec_cmd, '/')) {
7402     char** env = args->env.empty() ? environ : args->env.data();
7403     execve(args->exec_cmd, args->argv.data(), env);
7404   } else {
7405     // There is no execvpe() on Mac.
7406     if (!args->env.empty())
7407       die("A full path is required for |exec_cmd| when setting |env|");
7408     execvp(args->exec_cmd, args->argv.data());
7409   }
7410 
7411   // Reached only if execv fails.
7412   die("execve() failed");
7413 }
7414 
7415 }  // namespace
7416 
7417 // static
7418 const int Subprocess::kTimeoutSignal = SIGKILL;
7419 
Start()7420 void Subprocess::Start() {
7421   ChildProcessArgs proc_args;
7422   proc_args.create_args = &args;
7423 
7424   // Setup argv.
7425   if (!args.exec_cmd.empty()) {
7426     proc_args.exec_cmd = args.exec_cmd[0].c_str();
7427     for (const std::string& arg : args.exec_cmd)
7428       proc_args.argv.push_back(const_cast<char*>(arg.c_str()));
7429     proc_args.argv.push_back(nullptr);
7430 
7431     if (!args.posix_argv0_override_for_testing.empty()) {
7432       proc_args.argv[0] =
7433           const_cast<char*>(args.posix_argv0_override_for_testing.c_str());
7434     }
7435   }
7436 
7437   // Setup env.
7438   if (!args.env.empty()) {
7439     for (const std::string& str : args.env)
7440       proc_args.env.push_back(const_cast<char*>(str.c_str()));
7441     proc_args.env.push_back(nullptr);
7442   }
7443 
7444   // Setup the pipes for stdin/err redirection.
7445   s_->stdin_pipe = base::Pipe::Create(base::Pipe::kWrNonBlock);
7446   proc_args.stdin_pipe_rd = *s_->stdin_pipe.rd;
7447   s_->stdouterr_pipe = base::Pipe::Create(base::Pipe::kRdNonBlock);
7448   proc_args.stdouterr_pipe_wr = *s_->stdouterr_pipe.wr;
7449 
7450   // Spawn the child process that will exec().
7451   s_->pid = fork();
7452   PERFETTO_CHECK(s_->pid >= 0);
7453   if (s_->pid == 0) {
7454     // Close the parent-ends of the pipes.
7455     s_->stdin_pipe.wr.reset();
7456     s_->stdouterr_pipe.rd.reset();
7457     ChildProcess(&proc_args);
7458     // ChildProcess() doesn't return, not even in case of failures.
7459     PERFETTO_FATAL("not reached");
7460   }
7461 
7462   s_->status = kRunning;
7463 
7464   // Close the child-end of the pipes.
7465   // Deliberately NOT closing the s_->stdin_pipe.rd. This is to avoid crashing
7466   // with a SIGPIPE if the process exits without consuming its stdin, while
7467   // the parent tries to write() on the other end of the stdin pipe.
7468   s_->stdouterr_pipe.wr.reset();
7469   proc_args.create_args->out_fd.reset();
7470 
7471   // Spawn a thread that is blocked on waitpid() and writes the termination
7472   // status onto a pipe. The problem here is that waipid() doesn't have a
7473   // timeout option and can't be passed to poll(). The alternative would be
7474   // using a SIGCHLD handler, but anecdotally signal handlers introduce more
7475   // problems than what they solve.
7476   s_->exit_status_pipe = base::Pipe::Create(base::Pipe::kRdNonBlock);
7477 
7478   // Both ends of the pipe are closed after the thread.join().
7479   int pid = s_->pid;
7480   int exit_status_pipe_wr = s_->exit_status_pipe.wr.release();
7481   auto* rusage = s_->rusage.get();
7482   s_->waitpid_thread = std::thread([pid, exit_status_pipe_wr, rusage] {
7483     int pid_stat = -1;
7484     struct rusage usg {};
7485     int wait_res = PERFETTO_EINTR(wait4(pid, &pid_stat, 0, &usg));
7486     PERFETTO_CHECK(wait_res == pid);
7487 
7488     auto tv_to_ms = [](const struct timeval& tv) {
7489       return static_cast<uint32_t>(tv.tv_sec * 1000 + tv.tv_usec / 1000);
7490     };
7491     rusage->cpu_utime_ms = tv_to_ms(usg.ru_utime);
7492     rusage->cpu_stime_ms = tv_to_ms(usg.ru_stime);
7493     rusage->max_rss_kb = static_cast<uint32_t>(usg.ru_maxrss) / 1000;
7494     rusage->min_page_faults = static_cast<uint32_t>(usg.ru_minflt);
7495     rusage->maj_page_faults = static_cast<uint32_t>(usg.ru_majflt);
7496     rusage->vol_ctx_switch = static_cast<uint32_t>(usg.ru_nvcsw);
7497     rusage->invol_ctx_switch = static_cast<uint32_t>(usg.ru_nivcsw);
7498 
7499     base::ignore_result(PERFETTO_EINTR(
7500         write(exit_status_pipe_wr, &pid_stat, sizeof(pid_stat))));
7501     PERFETTO_CHECK(close(exit_status_pipe_wr) == 0 || errno == EINTR);
7502   });
7503 }
7504 
Poll()7505 Subprocess::Status Subprocess::Poll() {
7506   if (s_->status != kRunning)
7507     return s_->status;  // Nothing to poll.
7508   while (PollInternal(0 /* don't block*/)) {
7509   }
7510   return s_->status;
7511 }
7512 
7513 // |timeout_ms| semantic:
7514 //   -1: Block indefinitely.
7515 //    0: Don't block, return immediately.
7516 //   >0: Block for at most X ms.
7517 // Returns:
7518 //  True: Read at least one fd (so there might be more queued).
7519 //  False: if all fds reached quiescent (no data to read/write).
PollInternal(int poll_timeout_ms)7520 bool Subprocess::PollInternal(int poll_timeout_ms) {
7521   struct pollfd fds[3]{};
7522   size_t num_fds = 0;
7523   if (s_->exit_status_pipe.rd) {
7524     fds[num_fds].fd = *s_->exit_status_pipe.rd;
7525     fds[num_fds].events = POLLIN;
7526     num_fds++;
7527   }
7528   if (s_->stdouterr_pipe.rd) {
7529     fds[num_fds].fd = *s_->stdouterr_pipe.rd;
7530     fds[num_fds].events = POLLIN;
7531     num_fds++;
7532   }
7533   if (s_->stdin_pipe.wr) {
7534     fds[num_fds].fd = *s_->stdin_pipe.wr;
7535     fds[num_fds].events = POLLOUT;
7536     num_fds++;
7537   }
7538 
7539   if (num_fds == 0)
7540     return false;
7541 
7542   auto nfds = static_cast<nfds_t>(num_fds);
7543   int poll_res = PERFETTO_EINTR(poll(fds, nfds, poll_timeout_ms));
7544   PERFETTO_CHECK(poll_res >= 0);
7545 
7546   TryReadStdoutAndErr();
7547   TryPushStdin();
7548   TryReadExitStatus();
7549 
7550   return poll_res > 0;
7551 }
7552 
Wait(int timeout_ms)7553 bool Subprocess::Wait(int timeout_ms) {
7554   PERFETTO_CHECK(s_->status != kNotStarted);
7555 
7556   // Break out of the loop only after both conditions are satisfied:
7557   // - All stdout/stderr data has been read (if kBuffer).
7558   // - The process exited.
7559   // Note that the two events can happen arbitrary order. After the process
7560   // exits, there might be still data in the pipe buffer, which we want to
7561   // read fully.
7562   //
7563   // Instead, don't wait on the stdin to be fully written. The child process
7564   // might exit prematurely (or crash). If that happens, we can end up in a
7565   // state where the write(stdin_pipe_.wr) will never unblock.
7566 
7567   const int64_t t_start = base::GetWallTimeMs().count();
7568   while (s_->exit_status_pipe.rd || s_->stdouterr_pipe.rd) {
7569     int poll_timeout_ms = -1;  // Block until a FD is ready.
7570     if (timeout_ms > 0) {
7571       const int64_t now = GetWallTimeMs().count();
7572       poll_timeout_ms = timeout_ms - static_cast<int>(now - t_start);
7573       if (poll_timeout_ms <= 0)
7574         return false;
7575     }
7576     PollInternal(poll_timeout_ms);
7577   }  // while(...)
7578   return true;
7579 }
7580 
TryReadExitStatus()7581 void Subprocess::TryReadExitStatus() {
7582   if (!s_->exit_status_pipe.rd)
7583     return;
7584 
7585   int pid_stat = -1;
7586   int64_t rsize = PERFETTO_EINTR(
7587       read(*s_->exit_status_pipe.rd, &pid_stat, sizeof(pid_stat)));
7588   if (rsize < 0 && errno == EAGAIN)
7589     return;
7590 
7591   if (rsize > 0) {
7592     PERFETTO_CHECK(rsize == sizeof(pid_stat));
7593   } else if (rsize < 0) {
7594     PERFETTO_PLOG("Subprocess read(s_->exit_status_pipe) failed");
7595   }
7596   s_->waitpid_thread.join();
7597   s_->exit_status_pipe.rd.reset();
7598 
7599   s_->status = kTerminated;
7600   if (WIFEXITED(pid_stat)) {
7601     s_->returncode = WEXITSTATUS(pid_stat);
7602   } else if (WIFSIGNALED(pid_stat)) {
7603     s_->returncode = 128 + WTERMSIG(pid_stat);  // Follow bash convention.
7604   } else {
7605     PERFETTO_FATAL("waitpid() returned an unexpected value (0x%x)", pid_stat);
7606   }
7607 }
7608 
7609 // If the stidn pipe is still open, push input data and close it at the end.
TryPushStdin()7610 void Subprocess::TryPushStdin() {
7611   if (!s_->stdin_pipe.wr)
7612     return;
7613 
7614   PERFETTO_DCHECK(args.input.empty() || s_->input_written < args.input.size());
7615   if (!args.input.empty()) {
7616     int64_t wsize =
7617         PERFETTO_EINTR(write(*s_->stdin_pipe.wr, &args.input[s_->input_written],
7618                              args.input.size() - s_->input_written));
7619     if (wsize < 0 && errno == EAGAIN)
7620       return;
7621 
7622     if (wsize >= 0) {
7623       // Whether write() can return 0 is one of the greatest mysteries of UNIX.
7624       // Just ignore it.
7625       s_->input_written += static_cast<size_t>(wsize);
7626     } else {
7627       PERFETTO_PLOG("Subprocess write(stdin) failed");
7628       s_->stdin_pipe.wr.reset();
7629     }
7630   }
7631   PERFETTO_DCHECK(s_->input_written <= args.input.size());
7632   if (s_->input_written == args.input.size())
7633     s_->stdin_pipe.wr.reset();  // Close stdin.
7634 }
7635 
TryReadStdoutAndErr()7636 void Subprocess::TryReadStdoutAndErr() {
7637   if (!s_->stdouterr_pipe.rd)
7638     return;
7639   char buf[4096];
7640   int64_t rsize =
7641       PERFETTO_EINTR(read(*s_->stdouterr_pipe.rd, buf, sizeof(buf)));
7642   if (rsize < 0 && errno == EAGAIN)
7643     return;
7644 
7645   if (rsize > 0) {
7646     s_->output.append(buf, static_cast<size_t>(rsize));
7647   } else if (rsize == 0 /* EOF */) {
7648     s_->stdouterr_pipe.rd.reset();
7649   } else {
7650     PERFETTO_PLOG("Subprocess read(stdout/err) failed");
7651     s_->stdouterr_pipe.rd.reset();
7652   }
7653 }
7654 
KillAndWaitForTermination(int sig_num)7655 void Subprocess::KillAndWaitForTermination(int sig_num) {
7656   kill(s_->pid, sig_num ? sig_num : SIGKILL);
7657   Wait();
7658   // TryReadExitStatus must have joined the thread.
7659   PERFETTO_DCHECK(!s_->waitpid_thread.joinable());
7660 }
7661 
7662 }  // namespace base
7663 }  // namespace perfetto
7664 
7665 #endif  // PERFETTO_OS_LINUX || PERFETTO_OS_ANDROID || PERFETTO_OS_APPLE
7666 // gen_amalgamated begin source: src/base/subprocess_windows.cc
7667 /*
7668  * Copyright (C) 2020 The Android Open Source Project
7669  *
7670  * Licensed under the Apache License, Version 2.0 (the "License");
7671  * you may not use this file except in compliance with the License.
7672  * You may obtain a copy of the License at
7673  *
7674  *      http://www.apache.org/licenses/LICENSE-2.0
7675  *
7676  * Unless required by applicable law or agreed to in writing, software
7677  * distributed under the License is distributed on an "AS IS" BASIS,
7678  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
7679  * See the License for the specific language governing permissions and
7680  * limitations under the License.
7681  */
7682 
7683 // gen_amalgamated expanded: #include "perfetto/ext/base/subprocess.h"
7684 
7685 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
7686 
7687 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
7688 
7689 #include <stdio.h>
7690 
7691 #include <algorithm>
7692 #include <mutex>
7693 #include <tuple>
7694 
7695 #include <Windows.h>
7696 
7697 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
7698 // gen_amalgamated expanded: #include "perfetto/base/time.h"
7699 // gen_amalgamated expanded: #include "perfetto/ext/base/pipe.h"
7700 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
7701 
7702 namespace perfetto {
7703 namespace base {
7704 
7705 // static
7706 const int Subprocess::kTimeoutSignal = static_cast<int>(STATUS_TIMEOUT);
7707 
Start()7708 void Subprocess::Start() {
7709   if (args.exec_cmd.empty()) {
7710     PERFETTO_ELOG("Subprocess.exec_cmd cannot be empty on Windows");
7711     return;
7712   }
7713 
7714   // Quote arguments but only when ambiguous. When quoting, CreateProcess()
7715   // assumes that the command is an absolute path and does not search in the
7716   // %PATH%. If non quoted, instead, CreateProcess() tries both. This is to
7717   // allow Subprocess("cmd.exe", "/c", "shell command").
7718   std::string cmd;
7719   for (const auto& part : args.exec_cmd) {
7720     if (part.find(" ") != std::string::npos) {
7721       cmd += "\"" + part + "\" ";
7722     } else {
7723       cmd += part + " ";
7724     }
7725   }
7726   // Remove trailing space.
7727   if (!cmd.empty())
7728     cmd.resize(cmd.size() - 1);
7729 
7730   s_->stdin_pipe = Pipe::Create();
7731   // Allow the child process to inherit the other end of the pipe.
7732   PERFETTO_CHECK(
7733       ::SetHandleInformation(*s_->stdin_pipe.rd, HANDLE_FLAG_INHERIT, 1));
7734 
7735   if (args.stderr_mode == kBuffer || args.stdout_mode == kBuffer) {
7736     s_->stdouterr_pipe = Pipe::Create();
7737     PERFETTO_CHECK(
7738         ::SetHandleInformation(*s_->stdouterr_pipe.wr, HANDLE_FLAG_INHERIT, 1));
7739   }
7740 
7741   ScopedPlatformHandle nul_handle;
7742   if (args.stderr_mode == kDevNull || args.stdout_mode == kDevNull) {
7743     nul_handle.reset(::CreateFileA("NUL", GENERIC_WRITE, FILE_SHARE_WRITE,
7744                                    nullptr, OPEN_EXISTING,
7745                                    FILE_ATTRIBUTE_NORMAL, nullptr));
7746     PERFETTO_CHECK(::SetHandleInformation(*nul_handle, HANDLE_FLAG_INHERIT, 1));
7747   }
7748 
7749   PROCESS_INFORMATION proc_info{};
7750   STARTUPINFOA start_info{};
7751   start_info.cb = sizeof(STARTUPINFOA);
7752 
7753   if (args.stderr_mode == kInherit) {
7754     start_info.hStdError = ::GetStdHandle(STD_ERROR_HANDLE);
7755   } else if (args.stderr_mode == kBuffer) {
7756     start_info.hStdError = *s_->stdouterr_pipe.wr;
7757   } else if (args.stderr_mode == kDevNull) {
7758     start_info.hStdError = *nul_handle;
7759   } else if (args.stderr_mode == kFd) {
7760     PERFETTO_CHECK(
7761         ::SetHandleInformation(*args.out_fd, HANDLE_FLAG_INHERIT, 1));
7762     start_info.hStdError = *args.out_fd;
7763   } else {
7764     PERFETTO_CHECK(false);
7765   }
7766 
7767   if (args.stdout_mode == kInherit) {
7768     start_info.hStdOutput = ::GetStdHandle(STD_OUTPUT_HANDLE);
7769   } else if (args.stdout_mode == kBuffer) {
7770     start_info.hStdOutput = *s_->stdouterr_pipe.wr;
7771   } else if (args.stdout_mode == kDevNull) {
7772     start_info.hStdOutput = *nul_handle;
7773   } else if (args.stdout_mode == kFd) {
7774     PERFETTO_CHECK(
7775         ::SetHandleInformation(*args.out_fd, HANDLE_FLAG_INHERIT, 1));
7776     start_info.hStdOutput = *args.out_fd;
7777   } else {
7778     PERFETTO_CHECK(false);
7779   }
7780 
7781   start_info.hStdInput = *s_->stdin_pipe.rd;
7782   start_info.dwFlags |= STARTF_USESTDHANDLES;
7783 
7784   // Create the child process.
7785   bool success =
7786       ::CreateProcessA(nullptr,      // App name. Needs to be null to use PATH.
7787                        &cmd[0],      // Command line.
7788                        nullptr,      // Process security attributes.
7789                        nullptr,      // Primary thread security attributes.
7790                        true,         // Handles are inherited.
7791                        0,            // Flags.
7792                        nullptr,      // Use parent's environment.
7793                        nullptr,      // Use parent's current directory.
7794                        &start_info,  // STARTUPINFO pointer.
7795                        &proc_info);  // Receives PROCESS_INFORMATION.
7796 
7797   // Close on our side the pipe ends that we passed to the child process.
7798   s_->stdin_pipe.rd.reset();
7799   s_->stdouterr_pipe.wr.reset();
7800   args.out_fd.reset();
7801 
7802   if (!success) {
7803     s_->returncode = ERROR_FILE_NOT_FOUND;
7804     s_->status = kTerminated;
7805     s_->stdin_pipe.wr.reset();
7806     s_->stdouterr_pipe.rd.reset();
7807     PERFETTO_ELOG("CreateProcess failed: %lx, cmd: %s", GetLastError(),
7808                   &cmd[0]);
7809     return;
7810   }
7811 
7812   s_->pid = proc_info.dwProcessId;
7813   s_->win_proc_handle = ScopedPlatformHandle(proc_info.hProcess);
7814   s_->win_thread_handle = ScopedPlatformHandle(proc_info.hThread);
7815   s_->status = kRunning;
7816 
7817   MovableState* s = s_.get();
7818   s_->stdin_thread = std::thread(&Subprocess::StdinThread, s, args.input);
7819 
7820   if (args.stderr_mode == kBuffer || args.stdout_mode == kBuffer) {
7821     PERFETTO_DCHECK(s_->stdouterr_pipe.rd);
7822     s_->stdouterr_thread = std::thread(&Subprocess::StdoutErrThread, s);
7823   }
7824 }
7825 
7826 // static
StdinThread(MovableState * s,std::string input)7827 void Subprocess::StdinThread(MovableState* s, std::string input) {
7828   size_t input_written = 0;
7829   while (input_written < input.size()) {
7830     DWORD wsize = 0;
7831     if (::WriteFile(*s->stdin_pipe.wr, input.data() + input_written,
7832                     static_cast<DWORD>(input.size() - input_written), &wsize,
7833                     nullptr)) {
7834       input_written += wsize;
7835     } else {
7836       // ERROR_BROKEN_PIPE is WAI when the child just closes stdin and stops
7837       // accepting input.
7838       auto err = ::GetLastError();
7839       if (err != ERROR_BROKEN_PIPE)
7840         PERFETTO_PLOG("Subprocess WriteFile(stdin) failed %lx", err);
7841       break;
7842     }
7843   }  // while(...)
7844   std::unique_lock<std::mutex> lock(s->mutex);
7845   s->stdin_pipe.wr.reset();
7846 }
7847 
7848 // static
StdoutErrThread(MovableState * s)7849 void Subprocess::StdoutErrThread(MovableState* s) {
7850   char buf[4096];
7851   for (;;) {
7852     DWORD rsize = 0;
7853     bool res =
7854         ::ReadFile(*s->stdouterr_pipe.rd, buf, sizeof(buf), &rsize, nullptr);
7855     if (!res) {
7856       auto err = GetLastError();
7857       if (err != ERROR_BROKEN_PIPE)
7858         PERFETTO_PLOG("Subprocess ReadFile(stdouterr) failed %ld", err);
7859     }
7860 
7861     if (rsize > 0) {
7862       std::unique_lock<std::mutex> lock(s->mutex);
7863       s->locked_outerr_buf.append(buf, static_cast<size_t>(rsize));
7864     } else {  // EOF or some error.
7865       break;
7866     }
7867   }  // For(..)
7868 
7869   // Close the stdouterr_pipe. The main loop looks at the pipe closure to
7870   // determine whether the stdout/err thread has completed.
7871   {
7872     std::unique_lock<std::mutex> lock(s->mutex);
7873     s->stdouterr_pipe.rd.reset();
7874   }
7875   s->stdouterr_done_event.Notify();
7876 }
7877 
Poll()7878 Subprocess::Status Subprocess::Poll() {
7879   if (s_->status != kRunning)
7880     return s_->status;  // Nothing to poll.
7881   Wait(1 /*ms*/);
7882   return s_->status;
7883 }
7884 
Wait(int timeout_ms)7885 bool Subprocess::Wait(int timeout_ms) {
7886   PERFETTO_CHECK(s_->status != kNotStarted);
7887   const bool wait_forever = timeout_ms == 0;
7888   const int64_t wait_start_ms = base::GetWallTimeMs().count();
7889 
7890   // Break out of the loop only after both conditions are satisfied:
7891   // - All stdout/stderr data has been read (if kBuffer).
7892   // - The process exited.
7893   // Note that the two events can happen arbitrary order. After the process
7894   // exits, there might be still data in the pipe buffer, which we want to
7895   // read fully.
7896   // Note also that stdout/err might be "complete" before starting, if neither
7897   // is operating in kBuffer mode. In that case we just want to wait for the
7898   // process termination.
7899   //
7900   // Instead, don't wait on the stdin to be fully written. The child process
7901   // might exit prematurely (or crash). If that happens, we can end up in a
7902   // state where the write(stdin_pipe_.wr) will never unblock.
7903   bool stdouterr_complete = false;
7904   for (;;) {
7905     HANDLE wait_handles[2]{};
7906     DWORD num_handles = 0;
7907 
7908     // Check if the process exited.
7909     bool process_exited = !s_->win_proc_handle;
7910     if (!process_exited) {
7911       DWORD exit_code = STILL_ACTIVE;
7912       PERFETTO_CHECK(::GetExitCodeProcess(*s_->win_proc_handle, &exit_code));
7913       if (exit_code != STILL_ACTIVE) {
7914         s_->returncode = static_cast<int>(exit_code);
7915         s_->status = kTerminated;
7916         s_->win_proc_handle.reset();
7917         s_->win_thread_handle.reset();
7918         process_exited = true;
7919       }
7920     } else {
7921       PERFETTO_DCHECK(s_->status != kRunning);
7922     }
7923     if (!process_exited) {
7924       wait_handles[num_handles++] = *s_->win_proc_handle;
7925     }
7926 
7927     // Check if there is more output and if the stdout/err pipe has been closed.
7928     {
7929       std::unique_lock<std::mutex> lock(s_->mutex);
7930       // Move the output from the internal buffer shared with the
7931       // stdouterr_thread to the final buffer exposed to the client.
7932       if (!s_->locked_outerr_buf.empty()) {
7933         s_->output.append(std::move(s_->locked_outerr_buf));
7934         s_->locked_outerr_buf.clear();
7935       }
7936       stdouterr_complete = !s_->stdouterr_pipe.rd;
7937       if (!stdouterr_complete) {
7938         wait_handles[num_handles++] = s_->stdouterr_done_event.fd();
7939       }
7940     }  // lock(s_->mutex)
7941 
7942     if (num_handles == 0) {
7943       PERFETTO_DCHECK(process_exited && stdouterr_complete);
7944       break;
7945     }
7946 
7947     DWORD wait_ms;  // Note: DWORD is unsigned.
7948     if (wait_forever) {
7949       wait_ms = INFINITE;
7950     } else {
7951       const int64_t now = GetWallTimeMs().count();
7952       const int64_t wait_left_ms = timeout_ms - (now - wait_start_ms);
7953       if (wait_left_ms <= 0)
7954         return false;  // Timed out
7955       wait_ms = static_cast<DWORD>(wait_left_ms);
7956     }
7957 
7958     auto wait_res =
7959         ::WaitForMultipleObjects(num_handles, wait_handles, false, wait_ms);
7960     PERFETTO_CHECK(wait_res != WAIT_FAILED);
7961   }
7962 
7963   PERFETTO_DCHECK(!s_->win_proc_handle);
7964   PERFETTO_DCHECK(!s_->win_thread_handle);
7965 
7966   if (s_->stdin_thread.joinable())  // Might not exist if CreateProcess failed.
7967     s_->stdin_thread.join();
7968   if (s_->stdouterr_thread.joinable())
7969     s_->stdouterr_thread.join();
7970 
7971   // The stdin pipe is closed by the dedicated stdin thread. However if that is
7972   // not started (e.g. because of no redirection) force close it now. Needs to
7973   // happen after the join() to be thread safe.
7974   s_->stdin_pipe.wr.reset();
7975   s_->stdouterr_pipe.rd.reset();
7976 
7977   return true;
7978 }
7979 
KillAndWaitForTermination(int exit_code)7980 void Subprocess::KillAndWaitForTermination(int exit_code) {
7981   auto code = exit_code ? static_cast<DWORD>(exit_code) : STATUS_CONTROL_C_EXIT;
7982   ::TerminateProcess(*s_->win_proc_handle, code);
7983   Wait();
7984   // TryReadExitStatus must have joined the threads.
7985   PERFETTO_DCHECK(!s_->stdin_thread.joinable());
7986   PERFETTO_DCHECK(!s_->stdouterr_thread.joinable());
7987 }
7988 
7989 }  // namespace base
7990 }  // namespace perfetto
7991 
7992 #endif  // PERFETTO_OS_WIN
7993 // gen_amalgamated begin source: src/protozero/field.cc
7994 /*
7995  * Copyright (C) 2019 The Android Open Source Project
7996  *
7997  * Licensed under the Apache License, Version 2.0 (the "License");
7998  * you may not use this file except in compliance with the License.
7999  * You may obtain a copy of the License at
8000  *
8001  *      http://www.apache.org/licenses/LICENSE-2.0
8002  *
8003  * Unless required by applicable law or agreed to in writing, software
8004  * distributed under the License is distributed on an "AS IS" BASIS,
8005  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8006  * See the License for the specific language governing permissions and
8007  * limitations under the License.
8008  */
8009 
8010 // gen_amalgamated expanded: #include "perfetto/protozero/field.h"
8011 
8012 // gen_amalgamated expanded: #include "perfetto/base/compiler.h"
8013 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
8014 
8015 #if !PERFETTO_IS_LITTLE_ENDIAN()
8016 // The memcpy() for fixed32/64 below needs to be adjusted if we want to
8017 // support big endian CPUs. There doesn't seem to be a compelling need today.
8018 #error Unimplemented for big endian archs.
8019 #endif
8020 
8021 namespace protozero {
8022 
8023 template <typename Container>
SerializeAndAppendToInternal(Container * dst) const8024 void Field::SerializeAndAppendToInternal(Container* dst) const {
8025   namespace pu = proto_utils;
8026   size_t initial_size = dst->size();
8027   dst->resize(initial_size + pu::kMaxSimpleFieldEncodedSize + size_);
8028   uint8_t* start = reinterpret_cast<uint8_t*>(&(*dst)[initial_size]);
8029   uint8_t* wptr = start;
8030   switch (type_) {
8031     case static_cast<int>(pu::ProtoWireType::kVarInt): {
8032       wptr = pu::WriteVarInt(pu::MakeTagVarInt(id_), wptr);
8033       wptr = pu::WriteVarInt(int_value_, wptr);
8034       break;
8035     }
8036     case static_cast<int>(pu::ProtoWireType::kFixed32): {
8037       wptr = pu::WriteVarInt(pu::MakeTagFixed<uint32_t>(id_), wptr);
8038       uint32_t value32 = static_cast<uint32_t>(int_value_);
8039       memcpy(wptr, &value32, sizeof(value32));
8040       wptr += sizeof(uint32_t);
8041       break;
8042     }
8043     case static_cast<int>(pu::ProtoWireType::kFixed64): {
8044       wptr = pu::WriteVarInt(pu::MakeTagFixed<uint64_t>(id_), wptr);
8045       memcpy(wptr, &int_value_, sizeof(int_value_));
8046       wptr += sizeof(uint64_t);
8047       break;
8048     }
8049     case static_cast<int>(pu::ProtoWireType::kLengthDelimited): {
8050       ConstBytes payload = as_bytes();
8051       wptr = pu::WriteVarInt(pu::MakeTagLengthDelimited(id_), wptr);
8052       wptr = pu::WriteVarInt(payload.size, wptr);
8053       memcpy(wptr, payload.data, payload.size);
8054       wptr += payload.size;
8055       break;
8056     }
8057     default:
8058       PERFETTO_FATAL("Unknown field type %u", type_);
8059   }
8060   size_t written_size = static_cast<size_t>(wptr - start);
8061   PERFETTO_DCHECK(written_size > 0 && written_size < pu::kMaxMessageLength);
8062   PERFETTO_DCHECK(initial_size + written_size <= dst->size());
8063   dst->resize(initial_size + written_size);
8064 }
8065 
SerializeAndAppendTo(std::string * dst) const8066 void Field::SerializeAndAppendTo(std::string* dst) const {
8067   SerializeAndAppendToInternal(dst);
8068 }
8069 
SerializeAndAppendTo(std::vector<uint8_t> * dst) const8070 void Field::SerializeAndAppendTo(std::vector<uint8_t>* dst) const {
8071   SerializeAndAppendToInternal(dst);
8072 }
8073 
8074 }  // namespace protozero
8075 // gen_amalgamated begin source: src/protozero/message.cc
8076 /*
8077  * Copyright (C) 2017 The Android Open Source Project
8078  *
8079  * Licensed under the Apache License, Version 2.0 (the "License");
8080  * you may not use this file except in compliance with the License.
8081  * You may obtain a copy of the License at
8082  *
8083  *      http://www.apache.org/licenses/LICENSE-2.0
8084  *
8085  * Unless required by applicable law or agreed to in writing, software
8086  * distributed under the License is distributed on an "AS IS" BASIS,
8087  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8088  * See the License for the specific language governing permissions and
8089  * limitations under the License.
8090  */
8091 
8092 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
8093 
8094 #include <atomic>
8095 #include <type_traits>
8096 
8097 // gen_amalgamated expanded: #include "perfetto/base/compiler.h"
8098 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
8099 // gen_amalgamated expanded: #include "perfetto/protozero/message_arena.h"
8100 // gen_amalgamated expanded: #include "perfetto/protozero/message_handle.h"
8101 
8102 #if !PERFETTO_IS_LITTLE_ENDIAN()
8103 // The memcpy() for float and double below needs to be adjusted if we want to
8104 // support big endian CPUs. There doesn't seem to be a compelling need today.
8105 #error Unimplemented for big endian archs.
8106 #endif
8107 
8108 namespace protozero {
8109 
8110 namespace {
8111 
8112 #if PERFETTO_DCHECK_IS_ON()
8113 std::atomic<uint32_t> g_generation;
8114 #endif
8115 
8116 }  // namespace
8117 
8118 // Do NOT put any code in the constructor or use default initialization.
8119 // Use the Reset() method below instead.
8120 
8121 // This method is called to initialize both root and nested messages.
Reset(ScatteredStreamWriter * stream_writer,MessageArena * arena)8122 void Message::Reset(ScatteredStreamWriter* stream_writer, MessageArena* arena) {
8123 // Older versions of libstdcxx don't have is_trivially_constructible.
8124 #if !defined(__GLIBCXX__) || __GLIBCXX__ >= 20170516
8125   static_assert(std::is_trivially_constructible<Message>::value,
8126                 "Message must be trivially constructible");
8127 #endif
8128 
8129   static_assert(std::is_trivially_destructible<Message>::value,
8130                 "Message must be trivially destructible");
8131   stream_writer_ = stream_writer;
8132   arena_ = arena;
8133   size_ = 0;
8134   size_field_ = nullptr;
8135   size_already_written_ = 0;
8136   nested_message_ = nullptr;
8137   finalized_ = false;
8138 #if PERFETTO_DCHECK_IS_ON()
8139   handle_ = nullptr;
8140   generation_ = g_generation.fetch_add(1, std::memory_order_relaxed);
8141 #endif
8142 }
8143 
AppendString(uint32_t field_id,const char * str)8144 void Message::AppendString(uint32_t field_id, const char* str) {
8145   AppendBytes(field_id, str, strlen(str));
8146 }
8147 
AppendBytes(uint32_t field_id,const void * src,size_t size)8148 void Message::AppendBytes(uint32_t field_id, const void* src, size_t size) {
8149   if (nested_message_)
8150     EndNestedMessage();
8151 
8152   PERFETTO_DCHECK(size < proto_utils::kMaxMessageLength);
8153   // Write the proto preamble (field id, type and length of the field).
8154   uint8_t buffer[proto_utils::kMaxSimpleFieldEncodedSize];
8155   uint8_t* pos = buffer;
8156   pos = proto_utils::WriteVarInt(proto_utils::MakeTagLengthDelimited(field_id),
8157                                  pos);
8158   pos = proto_utils::WriteVarInt(static_cast<uint32_t>(size), pos);
8159   WriteToStream(buffer, pos);
8160 
8161   const uint8_t* src_u8 = reinterpret_cast<const uint8_t*>(src);
8162   WriteToStream(src_u8, src_u8 + size);
8163 }
8164 
AppendScatteredBytes(uint32_t field_id,ContiguousMemoryRange * ranges,size_t num_ranges)8165 size_t Message::AppendScatteredBytes(uint32_t field_id,
8166                                      ContiguousMemoryRange* ranges,
8167                                      size_t num_ranges) {
8168   size_t size = 0;
8169   for (size_t i = 0; i < num_ranges; ++i) {
8170     size += ranges[i].size();
8171   }
8172 
8173   PERFETTO_DCHECK(size < proto_utils::kMaxMessageLength);
8174 
8175   uint8_t buffer[proto_utils::kMaxSimpleFieldEncodedSize];
8176   uint8_t* pos = buffer;
8177   pos = proto_utils::WriteVarInt(proto_utils::MakeTagLengthDelimited(field_id),
8178                                  pos);
8179   pos = proto_utils::WriteVarInt(static_cast<uint32_t>(size), pos);
8180   WriteToStream(buffer, pos);
8181 
8182   for (size_t i = 0; i < num_ranges; ++i) {
8183     auto& range = ranges[i];
8184     WriteToStream(range.begin, range.end);
8185   }
8186 
8187   return size;
8188 }
8189 
Finalize()8190 uint32_t Message::Finalize() {
8191   if (finalized_)
8192     return size_;
8193 
8194   if (nested_message_)
8195     EndNestedMessage();
8196 
8197   // Write the length of the nested message a posteriori, using a leading-zero
8198   // redundant varint encoding.
8199   if (size_field_) {
8200     PERFETTO_DCHECK(!finalized_);
8201     PERFETTO_DCHECK(size_ < proto_utils::kMaxMessageLength);
8202     PERFETTO_DCHECK(size_ >= size_already_written_);
8203     proto_utils::WriteRedundantVarInt(size_ - size_already_written_,
8204                                       size_field_);
8205     size_field_ = nullptr;
8206   }
8207 
8208   finalized_ = true;
8209 #if PERFETTO_DCHECK_IS_ON()
8210   if (handle_)
8211     handle_->reset_message();
8212 #endif
8213 
8214   return size_;
8215 }
8216 
BeginNestedMessageInternal(uint32_t field_id)8217 Message* Message::BeginNestedMessageInternal(uint32_t field_id) {
8218   if (nested_message_)
8219     EndNestedMessage();
8220 
8221   // Write the proto preamble for the nested message.
8222   uint8_t data[proto_utils::kMaxTagEncodedSize];
8223   uint8_t* data_end = proto_utils::WriteVarInt(
8224       proto_utils::MakeTagLengthDelimited(field_id), data);
8225   WriteToStream(data, data_end);
8226 
8227   Message* message = arena_->NewMessage();
8228   message->Reset(stream_writer_, arena_);
8229 
8230   // The length of the nested message cannot be known upfront. So right now
8231   // just reserve the bytes to encode the size after the nested message is done.
8232   message->set_size_field(
8233       stream_writer_->ReserveBytes(proto_utils::kMessageLengthFieldSize));
8234   size_ += proto_utils::kMessageLengthFieldSize;
8235 
8236   nested_message_ = message;
8237   return message;
8238 }
8239 
EndNestedMessage()8240 void Message::EndNestedMessage() {
8241   size_ += nested_message_->Finalize();
8242   arena_->DeleteLastMessage(nested_message_);
8243   nested_message_ = nullptr;
8244 }
8245 
8246 }  // namespace protozero
8247 // gen_amalgamated begin source: src/protozero/message_arena.cc
8248 /*
8249  * Copyright (C) 2020 The Android Open Source Project
8250  *
8251  * Licensed under the Apache License, Version 2.0 (the "License");
8252  * you may not use this file except in compliance with the License.
8253  * You may obtain a copy of the License at
8254  *
8255  *      http://www.apache.org/licenses/LICENSE-2.0
8256  *
8257  * Unless required by applicable law or agreed to in writing, software
8258  * distributed under the License is distributed on an "AS IS" BASIS,
8259  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8260  * See the License for the specific language governing permissions and
8261  * limitations under the License.
8262  */
8263 
8264 // gen_amalgamated expanded: #include "perfetto/protozero/message_arena.h"
8265 
8266 #include <atomic>
8267 #include <type_traits>
8268 
8269 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
8270 // gen_amalgamated expanded: #include "perfetto/protozero/message_handle.h"
8271 
8272 namespace protozero {
8273 
MessageArena()8274 MessageArena::MessageArena() {
8275   // The code below assumes that there is always at least one block.
8276   blocks_.emplace_front();
8277   static_assert(std::alignment_of<decltype(blocks_.back().storage[0])>::value >=
8278                     alignof(Message),
8279                 "MessageArea's storage is not properly aligned");
8280 }
8281 
8282 MessageArena::~MessageArena() = default;
8283 
NewMessage()8284 Message* MessageArena::NewMessage() {
8285   PERFETTO_DCHECK(!blocks_.empty());  // Should never become empty.
8286 
8287   Block* block = &blocks_.back();
8288   if (PERFETTO_UNLIKELY(block->entries >= Block::kCapacity)) {
8289     blocks_.emplace_back();
8290     block = &blocks_.back();
8291   }
8292   const auto idx = block->entries++;
8293   void* storage = &block->storage[idx];
8294   PERFETTO_ASAN_UNPOISON(storage, sizeof(Message));
8295   return new (storage) Message();
8296 }
8297 
DeleteLastMessageInternal()8298 void MessageArena::DeleteLastMessageInternal() {
8299   PERFETTO_DCHECK(!blocks_.empty());  // Should never be empty, see below.
8300   Block* block = &blocks_.back();
8301   PERFETTO_DCHECK(block->entries > 0);
8302 
8303   // This is the reason why there is no ~Message() call here.
8304   // MessageArea::Reset() (see header) also relies on dtor being trivial.
8305   static_assert(std::is_trivially_destructible<Message>::value,
8306                 "Message must be trivially destructible");
8307 
8308   --block->entries;
8309   PERFETTO_ASAN_POISON(&block->storage[block->entries], sizeof(Message));
8310 
8311   // Don't remove the first block to avoid malloc/free calls when the root
8312   // message is reset. Hitting the allocator all the times is a waste of time.
8313   if (block->entries == 0 && blocks_.size() > 1) {
8314     blocks_.pop_back();
8315   }
8316 }
8317 
8318 }  // namespace protozero
8319 // gen_amalgamated begin source: src/protozero/message_handle.cc
8320 /*
8321  * Copyright (C) 2017 The Android Open Source Project
8322  *
8323  * Licensed under the Apache License, Version 2.0 (the "License");
8324  * you may not use this file except in compliance with the License.
8325  * You may obtain a copy of the License at
8326  *
8327  *      http://www.apache.org/licenses/LICENSE-2.0
8328  *
8329  * Unless required by applicable law or agreed to in writing, software
8330  * distributed under the License is distributed on an "AS IS" BASIS,
8331  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8332  * See the License for the specific language governing permissions and
8333  * limitations under the License.
8334  */
8335 
8336 // gen_amalgamated expanded: #include "perfetto/protozero/message_handle.h"
8337 
8338 #include <utility>
8339 
8340 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
8341 
8342 namespace protozero {
8343 
MessageHandleBase(Message * message)8344 MessageHandleBase::MessageHandleBase(Message* message) : message_(message) {
8345 #if PERFETTO_DCHECK_IS_ON()
8346   generation_ = message_ ? message->generation_ : 0;
8347   if (message_)
8348     message_->set_handle(this);
8349 #endif
8350 }
8351 
~MessageHandleBase()8352 MessageHandleBase::~MessageHandleBase() {
8353   if (message_) {
8354 #if PERFETTO_DCHECK_IS_ON()
8355     PERFETTO_DCHECK(generation_ == message_->generation_);
8356 #endif
8357     FinalizeMessage();
8358   }
8359 }
8360 
MessageHandleBase(MessageHandleBase && other)8361 MessageHandleBase::MessageHandleBase(MessageHandleBase&& other) noexcept {
8362   Move(std::move(other));
8363 }
8364 
operator =(MessageHandleBase && other)8365 MessageHandleBase& MessageHandleBase::operator=(MessageHandleBase&& other) {
8366   // If the current handle was pointing to a message and is being reset to a new
8367   // one, finalize the old message. However, if the other message is the same as
8368   // the one we point to, don't finalize.
8369   if (message_ && message_ != other.message_)
8370     FinalizeMessage();
8371   Move(std::move(other));
8372   return *this;
8373 }
8374 
Move(MessageHandleBase && other)8375 void MessageHandleBase::Move(MessageHandleBase&& other) {
8376   message_ = other.message_;
8377   other.message_ = nullptr;
8378 #if PERFETTO_DCHECK_IS_ON()
8379   if (message_) {
8380     generation_ = message_->generation_;
8381     message_->set_handle(this);
8382   }
8383 #endif
8384 }
8385 
8386 }  // namespace protozero
8387 // gen_amalgamated begin source: src/protozero/packed_repeated_fields.cc
8388 /*
8389  * Copyright (C) 2017 The Android Open Source Project
8390  *
8391  * Licensed under the Apache License, Version 2.0 (the "License");
8392  * you may not use this file except in compliance with the License.
8393  * You may obtain a copy of the License at
8394  *
8395  *      http://www.apache.org/licenses/LICENSE-2.0
8396  *
8397  * Unless required by applicable law or agreed to in writing, software
8398  * distributed under the License is distributed on an "AS IS" BASIS,
8399  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8400  * See the License for the specific language governing permissions and
8401  * limitations under the License.
8402  */
8403 
8404 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
8405 
8406 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
8407 
8408 namespace protozero {
8409 
8410 // static
8411 constexpr size_t PackedBufferBase::kOnStackStorageSize;
8412 
GrowSlowpath()8413 void PackedBufferBase::GrowSlowpath() {
8414   size_t write_off = static_cast<size_t>(write_ptr_ - storage_begin_);
8415   size_t old_size = static_cast<size_t>(storage_end_ - storage_begin_);
8416   size_t new_size = old_size < 65536 ? (old_size * 2) : (old_size * 3 / 2);
8417   new_size = perfetto::base::AlignUp<4096>(new_size);
8418   std::unique_ptr<uint8_t[]> new_buf(new uint8_t[new_size]);
8419   memcpy(new_buf.get(), storage_begin_, old_size);
8420   heap_buf_ = std::move(new_buf);
8421   storage_begin_ = heap_buf_.get();
8422   storage_end_ = storage_begin_ + new_size;
8423   write_ptr_ = storage_begin_ + write_off;
8424 }
8425 
Reset()8426 void PackedBufferBase::Reset() {
8427   heap_buf_.reset();
8428   storage_begin_ = reinterpret_cast<uint8_t*>(&stack_buf_[0]);
8429   storage_end_ = reinterpret_cast<uint8_t*>(&stack_buf_[kOnStackStorageSize]);
8430   write_ptr_ = storage_begin_;
8431 }
8432 
8433 }  // namespace protozero
8434 // gen_amalgamated begin source: src/protozero/proto_decoder.cc
8435 /*
8436  * Copyright (C) 2018 The Android Open Source Project
8437  *
8438  * Licensed under the Apache License, Version 2.0 (the "License");
8439  * you may not use this file except in compliance with the License.
8440  * You may obtain a copy of the License at
8441  *
8442  *      http://www.apache.org/licenses/LICENSE-2.0
8443  *
8444  * Unless required by applicable law or agreed to in writing, software
8445  * distributed under the License is distributed on an "AS IS" BASIS,
8446  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8447  * See the License for the specific language governing permissions and
8448  * limitations under the License.
8449  */
8450 
8451 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
8452 
8453 #include <string.h>
8454 #include <limits>
8455 
8456 // gen_amalgamated expanded: #include "perfetto/base/compiler.h"
8457 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
8458 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
8459 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
8460 
8461 namespace protozero {
8462 
8463 using namespace proto_utils;
8464 
8465 #if !PERFETTO_IS_LITTLE_ENDIAN()
8466 #error Unimplemented for big endian archs.
8467 #endif
8468 
8469 namespace {
8470 
8471 struct ParseFieldResult {
8472   enum ParseResult { kAbort, kSkip, kOk };
8473   ParseResult parse_res;
8474   const uint8_t* next;
8475   Field field;
8476 };
8477 
8478 // Parses one field and returns the field itself and a pointer to the next
8479 // field to parse. If parsing fails, the returned |next| == |buffer|.
8480 PERFETTO_ALWAYS_INLINE ParseFieldResult
ParseOneField(const uint8_t * const buffer,const uint8_t * const end)8481 ParseOneField(const uint8_t* const buffer, const uint8_t* const end) {
8482   ParseFieldResult res{ParseFieldResult::kAbort, buffer, Field{}};
8483 
8484   // The first byte of a proto field is structured as follows:
8485   // The least 3 significant bits determine the field type.
8486   // The most 5 significant bits determine the field id. If MSB == 1, the
8487   // field id continues on the next bytes following the VarInt encoding.
8488   const uint8_t kFieldTypeNumBits = 3;
8489   const uint64_t kFieldTypeMask = (1 << kFieldTypeNumBits) - 1;  // 0000 0111;
8490   const uint8_t* pos = buffer;
8491 
8492   // If we've already hit the end, just return an invalid field.
8493   if (PERFETTO_UNLIKELY(pos >= end))
8494     return res;
8495 
8496   uint64_t preamble = 0;
8497   if (PERFETTO_LIKELY(*pos < 0x80)) {  // Fastpath for fields with ID < 16.
8498     preamble = *(pos++);
8499   } else {
8500     const uint8_t* next = ParseVarInt(pos, end, &preamble);
8501     if (PERFETTO_UNLIKELY(pos == next))
8502       return res;
8503     pos = next;
8504   }
8505 
8506   uint32_t field_id = static_cast<uint32_t>(preamble >> kFieldTypeNumBits);
8507   if (field_id == 0 || pos >= end)
8508     return res;
8509 
8510   auto field_type = static_cast<uint8_t>(preamble & kFieldTypeMask);
8511   const uint8_t* new_pos = pos;
8512   uint64_t int_value = 0;
8513   uint64_t size = 0;
8514 
8515   switch (field_type) {
8516     case static_cast<uint8_t>(ProtoWireType::kVarInt): {
8517       new_pos = ParseVarInt(pos, end, &int_value);
8518 
8519       // new_pos not being greater than pos means ParseVarInt could not fully
8520       // parse the number. This is because we are out of space in the buffer.
8521       // Set the id to zero and return but don't update the offset so a future
8522       // read can read this field.
8523       if (PERFETTO_UNLIKELY(new_pos == pos))
8524         return res;
8525 
8526       break;
8527     }
8528 
8529     case static_cast<uint8_t>(ProtoWireType::kLengthDelimited): {
8530       uint64_t payload_length;
8531       new_pos = ParseVarInt(pos, end, &payload_length);
8532       if (PERFETTO_UNLIKELY(new_pos == pos))
8533         return res;
8534 
8535       // ParseVarInt guarantees that |new_pos| <= |end| when it succeeds;
8536       if (payload_length > static_cast<uint64_t>(end - new_pos))
8537         return res;
8538 
8539       const uintptr_t payload_start = reinterpret_cast<uintptr_t>(new_pos);
8540       int_value = payload_start;
8541       size = payload_length;
8542       new_pos += payload_length;
8543       break;
8544     }
8545 
8546     case static_cast<uint8_t>(ProtoWireType::kFixed64): {
8547       new_pos = pos + sizeof(uint64_t);
8548       if (PERFETTO_UNLIKELY(new_pos > end))
8549         return res;
8550       memcpy(&int_value, pos, sizeof(uint64_t));
8551       break;
8552     }
8553 
8554     case static_cast<uint8_t>(ProtoWireType::kFixed32): {
8555       new_pos = pos + sizeof(uint32_t);
8556       if (PERFETTO_UNLIKELY(new_pos > end))
8557         return res;
8558       memcpy(&int_value, pos, sizeof(uint32_t));
8559       break;
8560     }
8561 
8562     default:
8563       PERFETTO_DLOG("Invalid proto field type: %u", field_type);
8564       return res;
8565   }
8566 
8567   res.next = new_pos;
8568 
8569   if (PERFETTO_UNLIKELY(field_id > std::numeric_limits<uint16_t>::max())) {
8570     PERFETTO_DLOG("Skipping field %" PRIu32 " because its id > 0xFFFF",
8571                   field_id);
8572     res.parse_res = ParseFieldResult::kSkip;
8573     return res;
8574   }
8575 
8576   if (PERFETTO_UNLIKELY(size > proto_utils::kMaxMessageLength)) {
8577     PERFETTO_DLOG("Skipping field %" PRIu32 " because it's too big (%" PRIu64
8578                   " KB)",
8579                   field_id, size / 1024);
8580     res.parse_res = ParseFieldResult::kSkip;
8581     return res;
8582   }
8583 
8584   res.parse_res = ParseFieldResult::kOk;
8585   res.field.initialize(static_cast<uint16_t>(field_id), field_type, int_value,
8586                        static_cast<uint32_t>(size));
8587   return res;
8588 }
8589 
8590 }  // namespace
8591 
FindField(uint32_t field_id)8592 Field ProtoDecoder::FindField(uint32_t field_id) {
8593   Field res{};
8594   auto old_position = read_ptr_;
8595   read_ptr_ = begin_;
8596   for (auto f = ReadField(); f.valid(); f = ReadField()) {
8597     if (f.id() == field_id) {
8598       res = f;
8599       break;
8600     }
8601   }
8602   read_ptr_ = old_position;
8603   return res;
8604 }
8605 
8606 PERFETTO_ALWAYS_INLINE
ReadField()8607 Field ProtoDecoder::ReadField() {
8608   ParseFieldResult res;
8609   do {
8610     res = ParseOneField(read_ptr_, end_);
8611     read_ptr_ = res.next;
8612   } while (PERFETTO_UNLIKELY(res.parse_res == ParseFieldResult::kSkip));
8613   return res.field;
8614 }
8615 
ParseAllFields()8616 void TypedProtoDecoderBase::ParseAllFields() {
8617   const uint8_t* cur = begin_;
8618   ParseFieldResult res;
8619   for (;;) {
8620     res = ParseOneField(cur, end_);
8621     PERFETTO_DCHECK(res.parse_res != ParseFieldResult::kOk || res.next != cur);
8622     cur = res.next;
8623     if (PERFETTO_UNLIKELY(res.parse_res == ParseFieldResult::kSkip)) {
8624       continue;
8625     } else if (PERFETTO_UNLIKELY(res.parse_res == ParseFieldResult::kAbort)) {
8626       break;
8627     }
8628     PERFETTO_DCHECK(res.parse_res == ParseFieldResult::kOk);
8629     PERFETTO_DCHECK(res.field.valid());
8630     auto field_id = res.field.id();
8631     if (PERFETTO_UNLIKELY(field_id >= num_fields_))
8632       continue;
8633 
8634     Field* fld = &fields_[field_id];
8635     if (PERFETTO_LIKELY(!fld->valid())) {
8636       // This is the first time we see this field.
8637       *fld = std::move(res.field);
8638     } else {
8639       // Repeated field case.
8640       // In this case we need to:
8641       // 1. Append the last value of the field to end of the repeated field
8642       //    storage.
8643       // 2. Replace the default instance at offset |field_id| with the current
8644       //    value. This is because in case of repeated field a call to Get(X) is
8645       //    supposed to return the last value of X, not the first one.
8646       // This is so that the RepeatedFieldIterator will iterate in the right
8647       // order, see comments on RepeatedFieldIterator.
8648       if (PERFETTO_UNLIKELY(size_ >= capacity_)) {
8649         ExpandHeapStorage();
8650         // ExpandHeapStorage moves fields_ so we need to update the ptr to fld:
8651         fld = &fields_[field_id];
8652         PERFETTO_DCHECK(size_ < capacity_);
8653       }
8654       fields_[size_++] = *fld;
8655       *fld = std::move(res.field);
8656     }
8657   }
8658   read_ptr_ = res.next;
8659 }
8660 
ExpandHeapStorage()8661 void TypedProtoDecoderBase::ExpandHeapStorage() {
8662   uint32_t new_capacity = capacity_ * 2;
8663   PERFETTO_CHECK(new_capacity > size_);
8664   std::unique_ptr<Field[]> new_storage(new Field[new_capacity]);
8665 
8666   static_assert(std::is_trivially_copyable<Field>::value,
8667                 "Field must be trivially copyable");
8668   memcpy(&new_storage[0], fields_, sizeof(Field) * size_);
8669 
8670   heap_storage_ = std::move(new_storage);
8671   fields_ = &heap_storage_[0];
8672   capacity_ = new_capacity;
8673 }
8674 
8675 }  // namespace protozero
8676 // gen_amalgamated begin source: src/protozero/scattered_heap_buffer.cc
8677 /*
8678  * Copyright (C) 2017 The Android Open Source Project
8679  *
8680  * Licensed under the Apache License, Version 2.0 (the "License");
8681  * you may not use this file except in compliance with the License.
8682  * You may obtain a copy of the License at
8683  *
8684  *      http://www.apache.org/licenses/LICENSE-2.0
8685  *
8686  * Unless required by applicable law or agreed to in writing, software
8687  * distributed under the License is distributed on an "AS IS" BASIS,
8688  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8689  * See the License for the specific language governing permissions and
8690  * limitations under the License.
8691  */
8692 
8693 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
8694 
8695 #include <algorithm>
8696 
8697 namespace protozero {
8698 
Slice()8699 ScatteredHeapBuffer::Slice::Slice()
8700     : buffer_(nullptr), size_(0u), unused_bytes_(0u) {}
8701 
Slice(size_t size)8702 ScatteredHeapBuffer::Slice::Slice(size_t size)
8703     : buffer_(std::unique_ptr<uint8_t[]>(new uint8_t[size])),
8704       size_(size),
8705       unused_bytes_(size) {
8706   PERFETTO_DCHECK(size);
8707   Clear();
8708 }
8709 
8710 ScatteredHeapBuffer::Slice::Slice(Slice&& slice) noexcept = default;
8711 
8712 ScatteredHeapBuffer::Slice::~Slice() = default;
8713 
8714 ScatteredHeapBuffer::Slice& ScatteredHeapBuffer::Slice::operator=(Slice&&) =
8715     default;
8716 
Clear()8717 void ScatteredHeapBuffer::Slice::Clear() {
8718   unused_bytes_ = size_;
8719 #if PERFETTO_DCHECK_IS_ON()
8720   memset(start(), 0xff, size_);
8721 #endif  // PERFETTO_DCHECK_IS_ON()
8722 }
8723 
ScatteredHeapBuffer(size_t initial_slice_size_bytes,size_t maximum_slice_size_bytes)8724 ScatteredHeapBuffer::ScatteredHeapBuffer(size_t initial_slice_size_bytes,
8725                                          size_t maximum_slice_size_bytes)
8726     : next_slice_size_(initial_slice_size_bytes),
8727       maximum_slice_size_(maximum_slice_size_bytes) {
8728   PERFETTO_DCHECK(next_slice_size_ && maximum_slice_size_);
8729   PERFETTO_DCHECK(maximum_slice_size_ >= initial_slice_size_bytes);
8730 }
8731 
8732 ScatteredHeapBuffer::~ScatteredHeapBuffer() = default;
8733 
GetNewBuffer()8734 protozero::ContiguousMemoryRange ScatteredHeapBuffer::GetNewBuffer() {
8735   PERFETTO_CHECK(writer_);
8736   AdjustUsedSizeOfCurrentSlice();
8737 
8738   if (cached_slice_.start()) {
8739     slices_.push_back(std::move(cached_slice_));
8740     PERFETTO_DCHECK(!cached_slice_.start());
8741   } else {
8742     slices_.emplace_back(next_slice_size_);
8743   }
8744   next_slice_size_ = std::min(maximum_slice_size_, next_slice_size_ * 2);
8745   return slices_.back().GetTotalRange();
8746 }
8747 
8748 const std::vector<ScatteredHeapBuffer::Slice>&
GetSlices()8749 ScatteredHeapBuffer::GetSlices() {
8750   AdjustUsedSizeOfCurrentSlice();
8751   return slices_;
8752 }
8753 
StitchSlices()8754 std::vector<uint8_t> ScatteredHeapBuffer::StitchSlices() {
8755   size_t stitched_size = 0u;
8756   const auto& slices = GetSlices();
8757   for (const auto& slice : slices)
8758     stitched_size += slice.size() - slice.unused_bytes();
8759 
8760   std::vector<uint8_t> buffer;
8761   buffer.reserve(stitched_size);
8762   for (const auto& slice : slices) {
8763     auto used_range = slice.GetUsedRange();
8764     buffer.insert(buffer.end(), used_range.begin, used_range.end);
8765   }
8766   return buffer;
8767 }
8768 
GetRanges()8769 std::vector<protozero::ContiguousMemoryRange> ScatteredHeapBuffer::GetRanges() {
8770   std::vector<protozero::ContiguousMemoryRange> ranges;
8771   for (const auto& slice : GetSlices())
8772     ranges.push_back(slice.GetUsedRange());
8773   return ranges;
8774 }
8775 
AdjustUsedSizeOfCurrentSlice()8776 void ScatteredHeapBuffer::AdjustUsedSizeOfCurrentSlice() {
8777   if (!slices_.empty())
8778     slices_.back().set_unused_bytes(writer_->bytes_available());
8779 }
8780 
GetTotalSize()8781 size_t ScatteredHeapBuffer::GetTotalSize() {
8782   size_t total_size = 0;
8783   for (auto& slice : slices_) {
8784     total_size += slice.size();
8785   }
8786   return total_size;
8787 }
8788 
Reset()8789 void ScatteredHeapBuffer::Reset() {
8790   if (slices_.empty())
8791     return;
8792   cached_slice_ = std::move(slices_.front());
8793   cached_slice_.Clear();
8794   slices_.clear();
8795 }
8796 
8797 }  // namespace protozero
8798 // gen_amalgamated begin source: src/protozero/scattered_stream_null_delegate.cc
8799 // gen_amalgamated begin header: include/perfetto/protozero/scattered_stream_null_delegate.h
8800 /*
8801  * Copyright (C) 2018 The Android Open Source Project
8802  *
8803  * Licensed under the Apache License, Version 2.0 (the "License");
8804  * you may not use this file except in compliance with the License.
8805  * You may obtain a copy of the License at
8806  *
8807  *      http://www.apache.org/licenses/LICENSE-2.0
8808  *
8809  * Unless required by applicable law or agreed to in writing, software
8810  * distributed under the License is distributed on an "AS IS" BASIS,
8811  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8812  * See the License for the specific language governing permissions and
8813  * limitations under the License.
8814  */
8815 
8816 #ifndef INCLUDE_PERFETTO_PROTOZERO_SCATTERED_STREAM_NULL_DELEGATE_H_
8817 #define INCLUDE_PERFETTO_PROTOZERO_SCATTERED_STREAM_NULL_DELEGATE_H_
8818 
8819 #include <memory>
8820 #include <vector>
8821 
8822 // gen_amalgamated expanded: #include "perfetto/base/export.h"
8823 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
8824 // gen_amalgamated expanded: #include "perfetto/protozero/contiguous_memory_range.h"
8825 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_stream_writer.h"
8826 
8827 namespace protozero {
8828 
8829 class PERFETTO_EXPORT ScatteredStreamWriterNullDelegate
8830     : public ScatteredStreamWriter::Delegate {
8831  public:
8832   explicit ScatteredStreamWriterNullDelegate(size_t chunk_size);
8833   ~ScatteredStreamWriterNullDelegate() override;
8834 
8835   // protozero::ScatteredStreamWriter::Delegate implementation.
8836   ContiguousMemoryRange GetNewBuffer() override;
8837 
8838  private:
8839   const size_t chunk_size_;
8840   std::unique_ptr<uint8_t[]> chunk_;
8841 };
8842 
8843 }  // namespace protozero
8844 
8845 #endif  // INCLUDE_PERFETTO_PROTOZERO_SCATTERED_STREAM_NULL_DELEGATE_H_
8846 /*
8847  * Copyright (C) 2018 The Android Open Source Project
8848  *
8849  * Licensed under the Apache License, Version 2.0 (the "License");
8850  * you may not use this file except in compliance with the License.
8851  * You may obtain a copy of the License at
8852  *
8853  *      http://www.apache.org/licenses/LICENSE-2.0
8854  *
8855  * Unless required by applicable law or agreed to in writing, software
8856  * distributed under the License is distributed on an "AS IS" BASIS,
8857  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8858  * See the License for the specific language governing permissions and
8859  * limitations under the License.
8860  */
8861 
8862 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_stream_null_delegate.h"
8863 
8864 namespace protozero {
8865 
8866 // An implementation of ScatteredStreamWriter::Delegate which always returns
8867 // the same piece of memory.
8868 // This is used when we need to no-op the writers (e.g. during teardown or in
8869 // case of resource exhaustion), avoiding that the clients have to deal with
8870 // nullptr checks.
ScatteredStreamWriterNullDelegate(size_t chunk_size)8871 ScatteredStreamWriterNullDelegate::ScatteredStreamWriterNullDelegate(
8872     size_t chunk_size)
8873     : chunk_size_(chunk_size),
8874       chunk_(std::unique_ptr<uint8_t[]>(new uint8_t[chunk_size_])) {}
8875 
~ScatteredStreamWriterNullDelegate()8876 ScatteredStreamWriterNullDelegate::~ScatteredStreamWriterNullDelegate() {}
8877 
GetNewBuffer()8878 ContiguousMemoryRange ScatteredStreamWriterNullDelegate::GetNewBuffer() {
8879   return {chunk_.get(), chunk_.get() + chunk_size_};
8880 }
8881 
8882 }  // namespace protozero
8883 // gen_amalgamated begin source: src/protozero/scattered_stream_writer.cc
8884 /*
8885  * Copyright (C) 2017 The Android Open Source Project
8886  *
8887  * Licensed under the Apache License, Version 2.0 (the "License");
8888  * you may not use this file except in compliance with the License.
8889  * You may obtain a copy of the License at
8890  *
8891  *      http://www.apache.org/licenses/LICENSE-2.0
8892  *
8893  * Unless required by applicable law or agreed to in writing, software
8894  * distributed under the License is distributed on an "AS IS" BASIS,
8895  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8896  * See the License for the specific language governing permissions and
8897  * limitations under the License.
8898  */
8899 
8900 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_stream_writer.h"
8901 
8902 #include <algorithm>
8903 
8904 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
8905 
8906 namespace protozero {
8907 
~Delegate()8908 ScatteredStreamWriter::Delegate::~Delegate() {}
8909 
ScatteredStreamWriter(Delegate * delegate)8910 ScatteredStreamWriter::ScatteredStreamWriter(Delegate* delegate)
8911     : delegate_(delegate),
8912       cur_range_({nullptr, nullptr}),
8913       write_ptr_(nullptr) {}
8914 
~ScatteredStreamWriter()8915 ScatteredStreamWriter::~ScatteredStreamWriter() {}
8916 
Reset(ContiguousMemoryRange range)8917 void ScatteredStreamWriter::Reset(ContiguousMemoryRange range) {
8918   written_previously_ += static_cast<uint64_t>(write_ptr_ - cur_range_.begin);
8919   cur_range_ = range;
8920   write_ptr_ = range.begin;
8921   PERFETTO_DCHECK(!write_ptr_ || write_ptr_ < cur_range_.end);
8922 }
8923 
Extend()8924 void ScatteredStreamWriter::Extend() {
8925   Reset(delegate_->GetNewBuffer());
8926 }
8927 
WriteBytesSlowPath(const uint8_t * src,size_t size)8928 void ScatteredStreamWriter::WriteBytesSlowPath(const uint8_t* src,
8929                                                size_t size) {
8930   size_t bytes_left = size;
8931   while (bytes_left > 0) {
8932     if (write_ptr_ >= cur_range_.end)
8933       Extend();
8934     const size_t burst_size = std::min(bytes_available(), bytes_left);
8935     WriteBytesUnsafe(src, burst_size);
8936     bytes_left -= burst_size;
8937     src += burst_size;
8938   }
8939 }
8940 
8941 // TODO(primiano): perf optimization: I suspect that at the end this will always
8942 // be called with |size| == 4, in which case we might just hardcode it.
ReserveBytes(size_t size)8943 uint8_t* ScatteredStreamWriter::ReserveBytes(size_t size) {
8944   if (write_ptr_ + size > cur_range_.end) {
8945     // Assume the reservations are always < Delegate::GetNewBuffer().size(),
8946     // so that one single call to Extend() will definitely give enough headroom.
8947     Extend();
8948     PERFETTO_DCHECK(write_ptr_ + size <= cur_range_.end);
8949   }
8950   uint8_t* begin = write_ptr_;
8951   write_ptr_ += size;
8952 #if PERFETTO_DCHECK_IS_ON()
8953   memset(begin, 0, size);
8954 #endif
8955   return begin;
8956 }
8957 
8958 }  // namespace protozero
8959 // gen_amalgamated begin source: src/protozero/static_buffer.cc
8960 // gen_amalgamated begin header: include/perfetto/protozero/static_buffer.h
8961 /*
8962  * Copyright (C) 2019 The Android Open Source Project
8963  *
8964  * Licensed under the Apache License, Version 2.0 (the "License");
8965  * you may not use this file except in compliance with the License.
8966  * You may obtain a copy of the License at
8967  *
8968  *      http://www.apache.org/licenses/LICENSE-2.0
8969  *
8970  * Unless required by applicable law or agreed to in writing, software
8971  * distributed under the License is distributed on an "AS IS" BASIS,
8972  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8973  * See the License for the specific language governing permissions and
8974  * limitations under the License.
8975  */
8976 
8977 #ifndef INCLUDE_PERFETTO_PROTOZERO_STATIC_BUFFER_H_
8978 #define INCLUDE_PERFETTO_PROTOZERO_STATIC_BUFFER_H_
8979 
8980 #include <memory>
8981 #include <string>
8982 #include <vector>
8983 
8984 // gen_amalgamated expanded: #include "perfetto/base/export.h"
8985 // gen_amalgamated expanded: #include "perfetto/protozero/root_message.h"
8986 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_stream_writer.h"
8987 
8988 namespace protozero {
8989 
8990 class Message;
8991 
8992 // A simple implementation of ScatteredStreamWriter::Delegate backed by a
8993 // fixed-size buffer. It doesn't support expansion. The caller needs to ensure
8994 // to never write more than the size of the buffer. Will CHECK() otherwise.
8995 class PERFETTO_EXPORT StaticBufferDelegate
8996     : public ScatteredStreamWriter::Delegate {
8997  public:
StaticBufferDelegate(uint8_t * buf,size_t len)8998   StaticBufferDelegate(uint8_t* buf, size_t len) : range_{buf, buf + len} {}
8999   ~StaticBufferDelegate() override;
9000 
9001   // ScatteredStreamWriter::Delegate implementation.
9002   ContiguousMemoryRange GetNewBuffer() override;
9003 
9004   ContiguousMemoryRange const range_;
9005   bool get_new_buffer_called_once_ = false;
9006 };
9007 
9008 // Helper function to create protozero messages backed by a fixed-size buffer
9009 // in one line. You can write:
9010 //   protozero::Static<protozero::MyMessage> msg(buf.data(), buf.size());
9011 //   msg->set_stuff(...);
9012 //   size_t bytes_encoded = msg.Finalize();
9013 template <typename T /* protozero::Message */>
9014 class StaticBuffered {
9015  public:
StaticBuffered(void * buf,size_t len)9016   StaticBuffered(void* buf, size_t len)
9017       : delegate_(reinterpret_cast<uint8_t*>(buf), len), writer_(&delegate_) {
9018     msg_.Reset(&writer_);
9019   }
9020 
9021   // This can't be neither copied nor moved because Message hands out pointers
9022   // to itself when creating submessages.
9023   StaticBuffered(const StaticBuffered&) = delete;
9024   StaticBuffered& operator=(const StaticBuffered&) = delete;
9025   StaticBuffered(StaticBuffered&&) = delete;
9026   StaticBuffered& operator=(StaticBuffered&&) = delete;
9027 
get()9028   T* get() { return &msg_; }
operator ->()9029   T* operator->() { return &msg_; }
9030 
9031   // The lack of a size() method is deliberate. It's to prevent that one
9032   // accidentally calls size() before Finalize().
9033 
9034   // Returns the number of encoded bytes (<= the size passed in the ctor).
Finalize()9035   size_t Finalize() {
9036     msg_.Finalize();
9037     return static_cast<size_t>(writer_.write_ptr() - delegate_.range_.begin);
9038   }
9039 
9040  private:
9041   StaticBufferDelegate delegate_;
9042   ScatteredStreamWriter writer_;
9043   RootMessage<T> msg_;
9044 };
9045 
9046 // Helper function to create stack-based protozero messages in one line.
9047 // You can write:
9048 //   protozero::StackBuffered<protozero::MyMessage, 16> msg;
9049 //   msg->set_stuff(...);
9050 //   size_t bytes_encoded = msg.Finalize();
9051 template <typename T /* protozero::Message */, size_t N>
9052 class StackBuffered : public StaticBuffered<T> {
9053  public:
StackBuffered()9054   StackBuffered() : StaticBuffered<T>(&buf_[0], N) {}
9055 
9056  private:
9057   uint8_t buf_[N];  // Deliberately not initialized.
9058 };
9059 
9060 }  // namespace protozero
9061 
9062 #endif  // INCLUDE_PERFETTO_PROTOZERO_STATIC_BUFFER_H_
9063 /*
9064  * Copyright (C) 2019 The Android Open Source Project
9065  *
9066  * Licensed under the Apache License, Version 2.0 (the "License");
9067  * you may not use this file except in compliance with the License.
9068  * You may obtain a copy of the License at
9069  *
9070  *      http://www.apache.org/licenses/LICENSE-2.0
9071  *
9072  * Unless required by applicable law or agreed to in writing, software
9073  * distributed under the License is distributed on an "AS IS" BASIS,
9074  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9075  * See the License for the specific language governing permissions and
9076  * limitations under the License.
9077  */
9078 
9079 // gen_amalgamated expanded: #include "perfetto/protozero/static_buffer.h"
9080 
9081 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
9082 
9083 namespace protozero {
9084 
9085 StaticBufferDelegate::~StaticBufferDelegate() = default;
9086 
GetNewBuffer()9087 ContiguousMemoryRange StaticBufferDelegate::GetNewBuffer() {
9088   if (get_new_buffer_called_once_) {
9089     // This is the 2nd time GetNewBuffer is called. The estimate is wrong. We
9090     // shouldn't try to grow the buffer after the initial call.
9091     PERFETTO_FATAL("Static buffer too small");
9092   }
9093   get_new_buffer_called_once_ = true;
9094   return range_;
9095 }
9096 
9097 }  // namespace protozero
9098 // gen_amalgamated begin source: src/protozero/virtual_destructors.cc
9099 /*
9100  * Copyright (C) 2019 The Android Open Source Project
9101  *
9102  * Licensed under the Apache License, Version 2.0 (the "License");
9103  * you may not use this file except in compliance with the License.
9104  * You may obtain a copy of the License at
9105  *
9106  *      http://www.apache.org/licenses/LICENSE-2.0
9107  *
9108  * Unless required by applicable law or agreed to in writing, software
9109  * distributed under the License is distributed on an "AS IS" BASIS,
9110  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9111  * See the License for the specific language governing permissions and
9112  * limitations under the License.
9113  */
9114 
9115 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
9116 
9117 namespace protozero {
9118 
9119 CppMessageObj::~CppMessageObj() = default;
9120 
9121 }  // namespace protozero
9122 // gen_amalgamated begin source: gen/protos/perfetto/common/android_energy_consumer_descriptor.gen.cc
9123 // gen_amalgamated begin header: gen/protos/perfetto/common/android_energy_consumer_descriptor.gen.h
9124 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
9125 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_ANDROID_ENERGY_CONSUMER_DESCRIPTOR_PROTO_CPP_H_
9126 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_ANDROID_ENERGY_CONSUMER_DESCRIPTOR_PROTO_CPP_H_
9127 
9128 #include <stdint.h>
9129 #include <bitset>
9130 #include <vector>
9131 #include <string>
9132 #include <type_traits>
9133 
9134 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
9135 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
9136 // gen_amalgamated expanded: #include "perfetto/base/export.h"
9137 
9138 namespace perfetto {
9139 namespace protos {
9140 namespace gen {
9141 class AndroidEnergyConsumerDescriptor;
9142 class AndroidEnergyConsumer;
9143 }  // namespace perfetto
9144 }  // namespace protos
9145 }  // namespace gen
9146 
9147 namespace protozero {
9148 class Message;
9149 }  // namespace protozero
9150 
9151 namespace perfetto {
9152 namespace protos {
9153 namespace gen {
9154 
9155 class PERFETTO_EXPORT AndroidEnergyConsumerDescriptor : public ::protozero::CppMessageObj {
9156  public:
9157   enum FieldNumbers {
9158     kEnergyConsumersFieldNumber = 1,
9159   };
9160 
9161   AndroidEnergyConsumerDescriptor();
9162   ~AndroidEnergyConsumerDescriptor() override;
9163   AndroidEnergyConsumerDescriptor(AndroidEnergyConsumerDescriptor&&) noexcept;
9164   AndroidEnergyConsumerDescriptor& operator=(AndroidEnergyConsumerDescriptor&&);
9165   AndroidEnergyConsumerDescriptor(const AndroidEnergyConsumerDescriptor&);
9166   AndroidEnergyConsumerDescriptor& operator=(const AndroidEnergyConsumerDescriptor&);
9167   bool operator==(const AndroidEnergyConsumerDescriptor&) const;
operator !=(const AndroidEnergyConsumerDescriptor & other) const9168   bool operator!=(const AndroidEnergyConsumerDescriptor& other) const { return !(*this == other); }
9169 
9170   bool ParseFromArray(const void*, size_t) override;
9171   std::string SerializeAsString() const override;
9172   std::vector<uint8_t> SerializeAsArray() const override;
9173   void Serialize(::protozero::Message*) const;
9174 
energy_consumers() const9175   const std::vector<AndroidEnergyConsumer>& energy_consumers() const { return energy_consumers_; }
mutable_energy_consumers()9176   std::vector<AndroidEnergyConsumer>* mutable_energy_consumers() { return &energy_consumers_; }
9177   int energy_consumers_size() const;
9178   void clear_energy_consumers();
9179   AndroidEnergyConsumer* add_energy_consumers();
9180 
9181  private:
9182   std::vector<AndroidEnergyConsumer> energy_consumers_;
9183 
9184   // Allows to preserve unknown protobuf fields for compatibility
9185   // with future versions of .proto files.
9186   std::string unknown_fields_;
9187 
9188   std::bitset<2> _has_field_{};
9189 };
9190 
9191 
9192 class PERFETTO_EXPORT AndroidEnergyConsumer : public ::protozero::CppMessageObj {
9193  public:
9194   enum FieldNumbers {
9195     kEnergyConsumerIdFieldNumber = 1,
9196     kOrdinalFieldNumber = 2,
9197     kTypeFieldNumber = 3,
9198     kNameFieldNumber = 4,
9199   };
9200 
9201   AndroidEnergyConsumer();
9202   ~AndroidEnergyConsumer() override;
9203   AndroidEnergyConsumer(AndroidEnergyConsumer&&) noexcept;
9204   AndroidEnergyConsumer& operator=(AndroidEnergyConsumer&&);
9205   AndroidEnergyConsumer(const AndroidEnergyConsumer&);
9206   AndroidEnergyConsumer& operator=(const AndroidEnergyConsumer&);
9207   bool operator==(const AndroidEnergyConsumer&) const;
operator !=(const AndroidEnergyConsumer & other) const9208   bool operator!=(const AndroidEnergyConsumer& other) const { return !(*this == other); }
9209 
9210   bool ParseFromArray(const void*, size_t) override;
9211   std::string SerializeAsString() const override;
9212   std::vector<uint8_t> SerializeAsArray() const override;
9213   void Serialize(::protozero::Message*) const;
9214 
has_energy_consumer_id() const9215   bool has_energy_consumer_id() const { return _has_field_[1]; }
energy_consumer_id() const9216   int32_t energy_consumer_id() const { return energy_consumer_id_; }
set_energy_consumer_id(int32_t value)9217   void set_energy_consumer_id(int32_t value) { energy_consumer_id_ = value; _has_field_.set(1); }
9218 
has_ordinal() const9219   bool has_ordinal() const { return _has_field_[2]; }
ordinal() const9220   int32_t ordinal() const { return ordinal_; }
set_ordinal(int32_t value)9221   void set_ordinal(int32_t value) { ordinal_ = value; _has_field_.set(2); }
9222 
has_type() const9223   bool has_type() const { return _has_field_[3]; }
type() const9224   const std::string& type() const { return type_; }
set_type(const std::string & value)9225   void set_type(const std::string& value) { type_ = value; _has_field_.set(3); }
9226 
has_name() const9227   bool has_name() const { return _has_field_[4]; }
name() const9228   const std::string& name() const { return name_; }
set_name(const std::string & value)9229   void set_name(const std::string& value) { name_ = value; _has_field_.set(4); }
9230 
9231  private:
9232   int32_t energy_consumer_id_{};
9233   int32_t ordinal_{};
9234   std::string type_{};
9235   std::string name_{};
9236 
9237   // Allows to preserve unknown protobuf fields for compatibility
9238   // with future versions of .proto files.
9239   std::string unknown_fields_;
9240 
9241   std::bitset<5> _has_field_{};
9242 };
9243 
9244 }  // namespace perfetto
9245 }  // namespace protos
9246 }  // namespace gen
9247 
9248 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_ANDROID_ENERGY_CONSUMER_DESCRIPTOR_PROTO_CPP_H_
9249 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
9250 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
9251 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
9252 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
9253 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
9254 #if defined(__GNUC__) || defined(__clang__)
9255 #pragma GCC diagnostic push
9256 #pragma GCC diagnostic ignored "-Wfloat-equal"
9257 #endif
9258 // gen_amalgamated expanded: #include "protos/perfetto/common/android_energy_consumer_descriptor.gen.h"
9259 
9260 namespace perfetto {
9261 namespace protos {
9262 namespace gen {
9263 
9264 AndroidEnergyConsumerDescriptor::AndroidEnergyConsumerDescriptor() = default;
9265 AndroidEnergyConsumerDescriptor::~AndroidEnergyConsumerDescriptor() = default;
9266 AndroidEnergyConsumerDescriptor::AndroidEnergyConsumerDescriptor(const AndroidEnergyConsumerDescriptor&) = default;
9267 AndroidEnergyConsumerDescriptor& AndroidEnergyConsumerDescriptor::operator=(const AndroidEnergyConsumerDescriptor&) = default;
9268 AndroidEnergyConsumerDescriptor::AndroidEnergyConsumerDescriptor(AndroidEnergyConsumerDescriptor&&) noexcept = default;
9269 AndroidEnergyConsumerDescriptor& AndroidEnergyConsumerDescriptor::operator=(AndroidEnergyConsumerDescriptor&&) = default;
9270 
operator ==(const AndroidEnergyConsumerDescriptor & other) const9271 bool AndroidEnergyConsumerDescriptor::operator==(const AndroidEnergyConsumerDescriptor& other) const {
9272   return unknown_fields_ == other.unknown_fields_
9273    && energy_consumers_ == other.energy_consumers_;
9274 }
9275 
energy_consumers_size() const9276 int AndroidEnergyConsumerDescriptor::energy_consumers_size() const { return static_cast<int>(energy_consumers_.size()); }
clear_energy_consumers()9277 void AndroidEnergyConsumerDescriptor::clear_energy_consumers() { energy_consumers_.clear(); }
add_energy_consumers()9278 AndroidEnergyConsumer* AndroidEnergyConsumerDescriptor::add_energy_consumers() { energy_consumers_.emplace_back(); return &energy_consumers_.back(); }
ParseFromArray(const void * raw,size_t size)9279 bool AndroidEnergyConsumerDescriptor::ParseFromArray(const void* raw, size_t size) {
9280   energy_consumers_.clear();
9281   unknown_fields_.clear();
9282   bool packed_error = false;
9283 
9284   ::protozero::ProtoDecoder dec(raw, size);
9285   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
9286     if (field.id() < _has_field_.size()) {
9287       _has_field_.set(field.id());
9288     }
9289     switch (field.id()) {
9290       case 1 /* energy_consumers */:
9291         energy_consumers_.emplace_back();
9292         energy_consumers_.back().ParseFromArray(field.data(), field.size());
9293         break;
9294       default:
9295         field.SerializeAndAppendTo(&unknown_fields_);
9296         break;
9297     }
9298   }
9299   return !packed_error && !dec.bytes_left();
9300 }
9301 
SerializeAsString() const9302 std::string AndroidEnergyConsumerDescriptor::SerializeAsString() const {
9303   ::protozero::HeapBuffered<::protozero::Message> msg;
9304   Serialize(msg.get());
9305   return msg.SerializeAsString();
9306 }
9307 
SerializeAsArray() const9308 std::vector<uint8_t> AndroidEnergyConsumerDescriptor::SerializeAsArray() const {
9309   ::protozero::HeapBuffered<::protozero::Message> msg;
9310   Serialize(msg.get());
9311   return msg.SerializeAsArray();
9312 }
9313 
Serialize(::protozero::Message * msg) const9314 void AndroidEnergyConsumerDescriptor::Serialize(::protozero::Message* msg) const {
9315   // Field 1: energy_consumers
9316   for (auto& it : energy_consumers_) {
9317     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
9318   }
9319 
9320   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
9321 }
9322 
9323 
9324 AndroidEnergyConsumer::AndroidEnergyConsumer() = default;
9325 AndroidEnergyConsumer::~AndroidEnergyConsumer() = default;
9326 AndroidEnergyConsumer::AndroidEnergyConsumer(const AndroidEnergyConsumer&) = default;
9327 AndroidEnergyConsumer& AndroidEnergyConsumer::operator=(const AndroidEnergyConsumer&) = default;
9328 AndroidEnergyConsumer::AndroidEnergyConsumer(AndroidEnergyConsumer&&) noexcept = default;
9329 AndroidEnergyConsumer& AndroidEnergyConsumer::operator=(AndroidEnergyConsumer&&) = default;
9330 
operator ==(const AndroidEnergyConsumer & other) const9331 bool AndroidEnergyConsumer::operator==(const AndroidEnergyConsumer& other) const {
9332   return unknown_fields_ == other.unknown_fields_
9333    && energy_consumer_id_ == other.energy_consumer_id_
9334    && ordinal_ == other.ordinal_
9335    && type_ == other.type_
9336    && name_ == other.name_;
9337 }
9338 
ParseFromArray(const void * raw,size_t size)9339 bool AndroidEnergyConsumer::ParseFromArray(const void* raw, size_t size) {
9340   unknown_fields_.clear();
9341   bool packed_error = false;
9342 
9343   ::protozero::ProtoDecoder dec(raw, size);
9344   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
9345     if (field.id() < _has_field_.size()) {
9346       _has_field_.set(field.id());
9347     }
9348     switch (field.id()) {
9349       case 1 /* energy_consumer_id */:
9350         field.get(&energy_consumer_id_);
9351         break;
9352       case 2 /* ordinal */:
9353         field.get(&ordinal_);
9354         break;
9355       case 3 /* type */:
9356         field.get(&type_);
9357         break;
9358       case 4 /* name */:
9359         field.get(&name_);
9360         break;
9361       default:
9362         field.SerializeAndAppendTo(&unknown_fields_);
9363         break;
9364     }
9365   }
9366   return !packed_error && !dec.bytes_left();
9367 }
9368 
SerializeAsString() const9369 std::string AndroidEnergyConsumer::SerializeAsString() const {
9370   ::protozero::HeapBuffered<::protozero::Message> msg;
9371   Serialize(msg.get());
9372   return msg.SerializeAsString();
9373 }
9374 
SerializeAsArray() const9375 std::vector<uint8_t> AndroidEnergyConsumer::SerializeAsArray() const {
9376   ::protozero::HeapBuffered<::protozero::Message> msg;
9377   Serialize(msg.get());
9378   return msg.SerializeAsArray();
9379 }
9380 
Serialize(::protozero::Message * msg) const9381 void AndroidEnergyConsumer::Serialize(::protozero::Message* msg) const {
9382   // Field 1: energy_consumer_id
9383   if (_has_field_[1]) {
9384     msg->AppendVarInt(1, energy_consumer_id_);
9385   }
9386 
9387   // Field 2: ordinal
9388   if (_has_field_[2]) {
9389     msg->AppendVarInt(2, ordinal_);
9390   }
9391 
9392   // Field 3: type
9393   if (_has_field_[3]) {
9394     msg->AppendString(3, type_);
9395   }
9396 
9397   // Field 4: name
9398   if (_has_field_[4]) {
9399     msg->AppendString(4, name_);
9400   }
9401 
9402   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
9403 }
9404 
9405 }  // namespace perfetto
9406 }  // namespace protos
9407 }  // namespace gen
9408 #if defined(__GNUC__) || defined(__clang__)
9409 #pragma GCC diagnostic pop
9410 #endif
9411 // gen_amalgamated begin source: gen/protos/perfetto/common/android_log_constants.gen.cc
9412 // gen_amalgamated begin header: gen/protos/perfetto/common/android_log_constants.gen.h
9413 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
9414 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_ANDROID_LOG_CONSTANTS_PROTO_CPP_H_
9415 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_ANDROID_LOG_CONSTANTS_PROTO_CPP_H_
9416 
9417 #include <stdint.h>
9418 #include <bitset>
9419 #include <vector>
9420 #include <string>
9421 #include <type_traits>
9422 
9423 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
9424 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
9425 // gen_amalgamated expanded: #include "perfetto/base/export.h"
9426 
9427 namespace perfetto {
9428 namespace protos {
9429 namespace gen {
9430 enum AndroidLogId : int;
9431 enum AndroidLogPriority : int;
9432 }  // namespace perfetto
9433 }  // namespace protos
9434 }  // namespace gen
9435 
9436 namespace protozero {
9437 class Message;
9438 }  // namespace protozero
9439 
9440 namespace perfetto {
9441 namespace protos {
9442 namespace gen {
9443 enum AndroidLogId : int {
9444   LID_DEFAULT = 0,
9445   LID_RADIO = 1,
9446   LID_EVENTS = 2,
9447   LID_SYSTEM = 3,
9448   LID_CRASH = 4,
9449   LID_STATS = 5,
9450   LID_SECURITY = 6,
9451   LID_KERNEL = 7,
9452 };
9453 enum AndroidLogPriority : int {
9454   PRIO_UNSPECIFIED = 0,
9455   PRIO_UNUSED = 1,
9456   PRIO_VERBOSE = 2,
9457   PRIO_DEBUG = 3,
9458   PRIO_INFO = 4,
9459   PRIO_WARN = 5,
9460   PRIO_ERROR = 6,
9461   PRIO_FATAL = 7,
9462 };
9463 }  // namespace perfetto
9464 }  // namespace protos
9465 }  // namespace gen
9466 
9467 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_ANDROID_LOG_CONSTANTS_PROTO_CPP_H_
9468 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
9469 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
9470 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
9471 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
9472 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
9473 #if defined(__GNUC__) || defined(__clang__)
9474 #pragma GCC diagnostic push
9475 #pragma GCC diagnostic ignored "-Wfloat-equal"
9476 #endif
9477 // gen_amalgamated expanded: #include "protos/perfetto/common/android_log_constants.gen.h"
9478 
9479 namespace perfetto {
9480 namespace protos {
9481 namespace gen {
9482 }  // namespace perfetto
9483 }  // namespace protos
9484 }  // namespace gen
9485 #if defined(__GNUC__) || defined(__clang__)
9486 #pragma GCC diagnostic pop
9487 #endif
9488 // gen_amalgamated begin source: gen/protos/perfetto/common/builtin_clock.gen.cc
9489 // gen_amalgamated begin header: gen/protos/perfetto/common/builtin_clock.gen.h
9490 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
9491 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_BUILTIN_CLOCK_PROTO_CPP_H_
9492 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_BUILTIN_CLOCK_PROTO_CPP_H_
9493 
9494 #include <stdint.h>
9495 #include <bitset>
9496 #include <vector>
9497 #include <string>
9498 #include <type_traits>
9499 
9500 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
9501 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
9502 // gen_amalgamated expanded: #include "perfetto/base/export.h"
9503 
9504 namespace perfetto {
9505 namespace protos {
9506 namespace gen {
9507 enum BuiltinClock : int;
9508 }  // namespace perfetto
9509 }  // namespace protos
9510 }  // namespace gen
9511 
9512 namespace protozero {
9513 class Message;
9514 }  // namespace protozero
9515 
9516 namespace perfetto {
9517 namespace protos {
9518 namespace gen {
9519 enum BuiltinClock : int {
9520   BUILTIN_CLOCK_UNKNOWN = 0,
9521   BUILTIN_CLOCK_REALTIME = 1,
9522   BUILTIN_CLOCK_REALTIME_COARSE = 2,
9523   BUILTIN_CLOCK_MONOTONIC = 3,
9524   BUILTIN_CLOCK_MONOTONIC_COARSE = 4,
9525   BUILTIN_CLOCK_MONOTONIC_RAW = 5,
9526   BUILTIN_CLOCK_BOOTTIME = 6,
9527   BUILTIN_CLOCK_MAX_ID = 63,
9528 };
9529 }  // namespace perfetto
9530 }  // namespace protos
9531 }  // namespace gen
9532 
9533 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_BUILTIN_CLOCK_PROTO_CPP_H_
9534 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
9535 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
9536 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
9537 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
9538 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
9539 #if defined(__GNUC__) || defined(__clang__)
9540 #pragma GCC diagnostic push
9541 #pragma GCC diagnostic ignored "-Wfloat-equal"
9542 #endif
9543 // gen_amalgamated expanded: #include "protos/perfetto/common/builtin_clock.gen.h"
9544 
9545 namespace perfetto {
9546 namespace protos {
9547 namespace gen {
9548 }  // namespace perfetto
9549 }  // namespace protos
9550 }  // namespace gen
9551 #if defined(__GNUC__) || defined(__clang__)
9552 #pragma GCC diagnostic pop
9553 #endif
9554 // gen_amalgamated begin source: gen/protos/perfetto/common/commit_data_request.gen.cc
9555 // gen_amalgamated begin header: gen/protos/perfetto/common/commit_data_request.gen.h
9556 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
9557 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_COMMIT_DATA_REQUEST_PROTO_CPP_H_
9558 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_COMMIT_DATA_REQUEST_PROTO_CPP_H_
9559 
9560 #include <stdint.h>
9561 #include <bitset>
9562 #include <vector>
9563 #include <string>
9564 #include <type_traits>
9565 
9566 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
9567 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
9568 // gen_amalgamated expanded: #include "perfetto/base/export.h"
9569 
9570 namespace perfetto {
9571 namespace protos {
9572 namespace gen {
9573 class CommitDataRequest;
9574 class CommitDataRequest_ChunkToPatch;
9575 class CommitDataRequest_ChunkToPatch_Patch;
9576 class CommitDataRequest_ChunksToMove;
9577 }  // namespace perfetto
9578 }  // namespace protos
9579 }  // namespace gen
9580 
9581 namespace protozero {
9582 class Message;
9583 }  // namespace protozero
9584 
9585 namespace perfetto {
9586 namespace protos {
9587 namespace gen {
9588 
9589 class PERFETTO_EXPORT CommitDataRequest : public ::protozero::CppMessageObj {
9590  public:
9591   using ChunksToMove = CommitDataRequest_ChunksToMove;
9592   using ChunkToPatch = CommitDataRequest_ChunkToPatch;
9593   enum FieldNumbers {
9594     kChunksToMoveFieldNumber = 1,
9595     kChunksToPatchFieldNumber = 2,
9596     kFlushRequestIdFieldNumber = 3,
9597   };
9598 
9599   CommitDataRequest();
9600   ~CommitDataRequest() override;
9601   CommitDataRequest(CommitDataRequest&&) noexcept;
9602   CommitDataRequest& operator=(CommitDataRequest&&);
9603   CommitDataRequest(const CommitDataRequest&);
9604   CommitDataRequest& operator=(const CommitDataRequest&);
9605   bool operator==(const CommitDataRequest&) const;
operator !=(const CommitDataRequest & other) const9606   bool operator!=(const CommitDataRequest& other) const { return !(*this == other); }
9607 
9608   bool ParseFromArray(const void*, size_t) override;
9609   std::string SerializeAsString() const override;
9610   std::vector<uint8_t> SerializeAsArray() const override;
9611   void Serialize(::protozero::Message*) const;
9612 
chunks_to_move() const9613   const std::vector<CommitDataRequest_ChunksToMove>& chunks_to_move() const { return chunks_to_move_; }
mutable_chunks_to_move()9614   std::vector<CommitDataRequest_ChunksToMove>* mutable_chunks_to_move() { return &chunks_to_move_; }
9615   int chunks_to_move_size() const;
9616   void clear_chunks_to_move();
9617   CommitDataRequest_ChunksToMove* add_chunks_to_move();
9618 
chunks_to_patch() const9619   const std::vector<CommitDataRequest_ChunkToPatch>& chunks_to_patch() const { return chunks_to_patch_; }
mutable_chunks_to_patch()9620   std::vector<CommitDataRequest_ChunkToPatch>* mutable_chunks_to_patch() { return &chunks_to_patch_; }
9621   int chunks_to_patch_size() const;
9622   void clear_chunks_to_patch();
9623   CommitDataRequest_ChunkToPatch* add_chunks_to_patch();
9624 
has_flush_request_id() const9625   bool has_flush_request_id() const { return _has_field_[3]; }
flush_request_id() const9626   uint64_t flush_request_id() const { return flush_request_id_; }
set_flush_request_id(uint64_t value)9627   void set_flush_request_id(uint64_t value) { flush_request_id_ = value; _has_field_.set(3); }
9628 
9629  private:
9630   std::vector<CommitDataRequest_ChunksToMove> chunks_to_move_;
9631   std::vector<CommitDataRequest_ChunkToPatch> chunks_to_patch_;
9632   uint64_t flush_request_id_{};
9633 
9634   // Allows to preserve unknown protobuf fields for compatibility
9635   // with future versions of .proto files.
9636   std::string unknown_fields_;
9637 
9638   std::bitset<4> _has_field_{};
9639 };
9640 
9641 
9642 class PERFETTO_EXPORT CommitDataRequest_ChunkToPatch : public ::protozero::CppMessageObj {
9643  public:
9644   using Patch = CommitDataRequest_ChunkToPatch_Patch;
9645   enum FieldNumbers {
9646     kTargetBufferFieldNumber = 1,
9647     kWriterIdFieldNumber = 2,
9648     kChunkIdFieldNumber = 3,
9649     kPatchesFieldNumber = 4,
9650     kHasMorePatchesFieldNumber = 5,
9651   };
9652 
9653   CommitDataRequest_ChunkToPatch();
9654   ~CommitDataRequest_ChunkToPatch() override;
9655   CommitDataRequest_ChunkToPatch(CommitDataRequest_ChunkToPatch&&) noexcept;
9656   CommitDataRequest_ChunkToPatch& operator=(CommitDataRequest_ChunkToPatch&&);
9657   CommitDataRequest_ChunkToPatch(const CommitDataRequest_ChunkToPatch&);
9658   CommitDataRequest_ChunkToPatch& operator=(const CommitDataRequest_ChunkToPatch&);
9659   bool operator==(const CommitDataRequest_ChunkToPatch&) const;
operator !=(const CommitDataRequest_ChunkToPatch & other) const9660   bool operator!=(const CommitDataRequest_ChunkToPatch& other) const { return !(*this == other); }
9661 
9662   bool ParseFromArray(const void*, size_t) override;
9663   std::string SerializeAsString() const override;
9664   std::vector<uint8_t> SerializeAsArray() const override;
9665   void Serialize(::protozero::Message*) const;
9666 
has_target_buffer() const9667   bool has_target_buffer() const { return _has_field_[1]; }
target_buffer() const9668   uint32_t target_buffer() const { return target_buffer_; }
set_target_buffer(uint32_t value)9669   void set_target_buffer(uint32_t value) { target_buffer_ = value; _has_field_.set(1); }
9670 
has_writer_id() const9671   bool has_writer_id() const { return _has_field_[2]; }
writer_id() const9672   uint32_t writer_id() const { return writer_id_; }
set_writer_id(uint32_t value)9673   void set_writer_id(uint32_t value) { writer_id_ = value; _has_field_.set(2); }
9674 
has_chunk_id() const9675   bool has_chunk_id() const { return _has_field_[3]; }
chunk_id() const9676   uint32_t chunk_id() const { return chunk_id_; }
set_chunk_id(uint32_t value)9677   void set_chunk_id(uint32_t value) { chunk_id_ = value; _has_field_.set(3); }
9678 
patches() const9679   const std::vector<CommitDataRequest_ChunkToPatch_Patch>& patches() const { return patches_; }
mutable_patches()9680   std::vector<CommitDataRequest_ChunkToPatch_Patch>* mutable_patches() { return &patches_; }
9681   int patches_size() const;
9682   void clear_patches();
9683   CommitDataRequest_ChunkToPatch_Patch* add_patches();
9684 
has_has_more_patches() const9685   bool has_has_more_patches() const { return _has_field_[5]; }
has_more_patches() const9686   bool has_more_patches() const { return has_more_patches_; }
set_has_more_patches(bool value)9687   void set_has_more_patches(bool value) { has_more_patches_ = value; _has_field_.set(5); }
9688 
9689  private:
9690   uint32_t target_buffer_{};
9691   uint32_t writer_id_{};
9692   uint32_t chunk_id_{};
9693   std::vector<CommitDataRequest_ChunkToPatch_Patch> patches_;
9694   bool has_more_patches_{};
9695 
9696   // Allows to preserve unknown protobuf fields for compatibility
9697   // with future versions of .proto files.
9698   std::string unknown_fields_;
9699 
9700   std::bitset<6> _has_field_{};
9701 };
9702 
9703 
9704 class PERFETTO_EXPORT CommitDataRequest_ChunkToPatch_Patch : public ::protozero::CppMessageObj {
9705  public:
9706   enum FieldNumbers {
9707     kOffsetFieldNumber = 1,
9708     kDataFieldNumber = 2,
9709   };
9710 
9711   CommitDataRequest_ChunkToPatch_Patch();
9712   ~CommitDataRequest_ChunkToPatch_Patch() override;
9713   CommitDataRequest_ChunkToPatch_Patch(CommitDataRequest_ChunkToPatch_Patch&&) noexcept;
9714   CommitDataRequest_ChunkToPatch_Patch& operator=(CommitDataRequest_ChunkToPatch_Patch&&);
9715   CommitDataRequest_ChunkToPatch_Patch(const CommitDataRequest_ChunkToPatch_Patch&);
9716   CommitDataRequest_ChunkToPatch_Patch& operator=(const CommitDataRequest_ChunkToPatch_Patch&);
9717   bool operator==(const CommitDataRequest_ChunkToPatch_Patch&) const;
operator !=(const CommitDataRequest_ChunkToPatch_Patch & other) const9718   bool operator!=(const CommitDataRequest_ChunkToPatch_Patch& other) const { return !(*this == other); }
9719 
9720   bool ParseFromArray(const void*, size_t) override;
9721   std::string SerializeAsString() const override;
9722   std::vector<uint8_t> SerializeAsArray() const override;
9723   void Serialize(::protozero::Message*) const;
9724 
has_offset() const9725   bool has_offset() const { return _has_field_[1]; }
offset() const9726   uint32_t offset() const { return offset_; }
set_offset(uint32_t value)9727   void set_offset(uint32_t value) { offset_ = value; _has_field_.set(1); }
9728 
has_data() const9729   bool has_data() const { return _has_field_[2]; }
data() const9730   const std::string& data() const { return data_; }
set_data(const std::string & value)9731   void set_data(const std::string& value) { data_ = value; _has_field_.set(2); }
set_data(const void * p,size_t s)9732   void set_data(const void* p, size_t s) { data_.assign(reinterpret_cast<const char*>(p), s); _has_field_.set(2); }
9733 
9734  private:
9735   uint32_t offset_{};
9736   std::string data_{};
9737 
9738   // Allows to preserve unknown protobuf fields for compatibility
9739   // with future versions of .proto files.
9740   std::string unknown_fields_;
9741 
9742   std::bitset<3> _has_field_{};
9743 };
9744 
9745 
9746 class PERFETTO_EXPORT CommitDataRequest_ChunksToMove : public ::protozero::CppMessageObj {
9747  public:
9748   enum FieldNumbers {
9749     kPageFieldNumber = 1,
9750     kChunkFieldNumber = 2,
9751     kTargetBufferFieldNumber = 3,
9752   };
9753 
9754   CommitDataRequest_ChunksToMove();
9755   ~CommitDataRequest_ChunksToMove() override;
9756   CommitDataRequest_ChunksToMove(CommitDataRequest_ChunksToMove&&) noexcept;
9757   CommitDataRequest_ChunksToMove& operator=(CommitDataRequest_ChunksToMove&&);
9758   CommitDataRequest_ChunksToMove(const CommitDataRequest_ChunksToMove&);
9759   CommitDataRequest_ChunksToMove& operator=(const CommitDataRequest_ChunksToMove&);
9760   bool operator==(const CommitDataRequest_ChunksToMove&) const;
operator !=(const CommitDataRequest_ChunksToMove & other) const9761   bool operator!=(const CommitDataRequest_ChunksToMove& other) const { return !(*this == other); }
9762 
9763   bool ParseFromArray(const void*, size_t) override;
9764   std::string SerializeAsString() const override;
9765   std::vector<uint8_t> SerializeAsArray() const override;
9766   void Serialize(::protozero::Message*) const;
9767 
has_page() const9768   bool has_page() const { return _has_field_[1]; }
page() const9769   uint32_t page() const { return page_; }
set_page(uint32_t value)9770   void set_page(uint32_t value) { page_ = value; _has_field_.set(1); }
9771 
has_chunk() const9772   bool has_chunk() const { return _has_field_[2]; }
chunk() const9773   uint32_t chunk() const { return chunk_; }
set_chunk(uint32_t value)9774   void set_chunk(uint32_t value) { chunk_ = value; _has_field_.set(2); }
9775 
has_target_buffer() const9776   bool has_target_buffer() const { return _has_field_[3]; }
target_buffer() const9777   uint32_t target_buffer() const { return target_buffer_; }
set_target_buffer(uint32_t value)9778   void set_target_buffer(uint32_t value) { target_buffer_ = value; _has_field_.set(3); }
9779 
9780  private:
9781   uint32_t page_{};
9782   uint32_t chunk_{};
9783   uint32_t target_buffer_{};
9784 
9785   // Allows to preserve unknown protobuf fields for compatibility
9786   // with future versions of .proto files.
9787   std::string unknown_fields_;
9788 
9789   std::bitset<4> _has_field_{};
9790 };
9791 
9792 }  // namespace perfetto
9793 }  // namespace protos
9794 }  // namespace gen
9795 
9796 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_COMMIT_DATA_REQUEST_PROTO_CPP_H_
9797 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
9798 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
9799 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
9800 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
9801 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
9802 #if defined(__GNUC__) || defined(__clang__)
9803 #pragma GCC diagnostic push
9804 #pragma GCC diagnostic ignored "-Wfloat-equal"
9805 #endif
9806 // gen_amalgamated expanded: #include "protos/perfetto/common/commit_data_request.gen.h"
9807 
9808 namespace perfetto {
9809 namespace protos {
9810 namespace gen {
9811 
9812 CommitDataRequest::CommitDataRequest() = default;
9813 CommitDataRequest::~CommitDataRequest() = default;
9814 CommitDataRequest::CommitDataRequest(const CommitDataRequest&) = default;
9815 CommitDataRequest& CommitDataRequest::operator=(const CommitDataRequest&) = default;
9816 CommitDataRequest::CommitDataRequest(CommitDataRequest&&) noexcept = default;
9817 CommitDataRequest& CommitDataRequest::operator=(CommitDataRequest&&) = default;
9818 
operator ==(const CommitDataRequest & other) const9819 bool CommitDataRequest::operator==(const CommitDataRequest& other) const {
9820   return unknown_fields_ == other.unknown_fields_
9821    && chunks_to_move_ == other.chunks_to_move_
9822    && chunks_to_patch_ == other.chunks_to_patch_
9823    && flush_request_id_ == other.flush_request_id_;
9824 }
9825 
chunks_to_move_size() const9826 int CommitDataRequest::chunks_to_move_size() const { return static_cast<int>(chunks_to_move_.size()); }
clear_chunks_to_move()9827 void CommitDataRequest::clear_chunks_to_move() { chunks_to_move_.clear(); }
add_chunks_to_move()9828 CommitDataRequest_ChunksToMove* CommitDataRequest::add_chunks_to_move() { chunks_to_move_.emplace_back(); return &chunks_to_move_.back(); }
chunks_to_patch_size() const9829 int CommitDataRequest::chunks_to_patch_size() const { return static_cast<int>(chunks_to_patch_.size()); }
clear_chunks_to_patch()9830 void CommitDataRequest::clear_chunks_to_patch() { chunks_to_patch_.clear(); }
add_chunks_to_patch()9831 CommitDataRequest_ChunkToPatch* CommitDataRequest::add_chunks_to_patch() { chunks_to_patch_.emplace_back(); return &chunks_to_patch_.back(); }
ParseFromArray(const void * raw,size_t size)9832 bool CommitDataRequest::ParseFromArray(const void* raw, size_t size) {
9833   chunks_to_move_.clear();
9834   chunks_to_patch_.clear();
9835   unknown_fields_.clear();
9836   bool packed_error = false;
9837 
9838   ::protozero::ProtoDecoder dec(raw, size);
9839   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
9840     if (field.id() < _has_field_.size()) {
9841       _has_field_.set(field.id());
9842     }
9843     switch (field.id()) {
9844       case 1 /* chunks_to_move */:
9845         chunks_to_move_.emplace_back();
9846         chunks_to_move_.back().ParseFromArray(field.data(), field.size());
9847         break;
9848       case 2 /* chunks_to_patch */:
9849         chunks_to_patch_.emplace_back();
9850         chunks_to_patch_.back().ParseFromArray(field.data(), field.size());
9851         break;
9852       case 3 /* flush_request_id */:
9853         field.get(&flush_request_id_);
9854         break;
9855       default:
9856         field.SerializeAndAppendTo(&unknown_fields_);
9857         break;
9858     }
9859   }
9860   return !packed_error && !dec.bytes_left();
9861 }
9862 
SerializeAsString() const9863 std::string CommitDataRequest::SerializeAsString() const {
9864   ::protozero::HeapBuffered<::protozero::Message> msg;
9865   Serialize(msg.get());
9866   return msg.SerializeAsString();
9867 }
9868 
SerializeAsArray() const9869 std::vector<uint8_t> CommitDataRequest::SerializeAsArray() const {
9870   ::protozero::HeapBuffered<::protozero::Message> msg;
9871   Serialize(msg.get());
9872   return msg.SerializeAsArray();
9873 }
9874 
Serialize(::protozero::Message * msg) const9875 void CommitDataRequest::Serialize(::protozero::Message* msg) const {
9876   // Field 1: chunks_to_move
9877   for (auto& it : chunks_to_move_) {
9878     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
9879   }
9880 
9881   // Field 2: chunks_to_patch
9882   for (auto& it : chunks_to_patch_) {
9883     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
9884   }
9885 
9886   // Field 3: flush_request_id
9887   if (_has_field_[3]) {
9888     msg->AppendVarInt(3, flush_request_id_);
9889   }
9890 
9891   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
9892 }
9893 
9894 
9895 CommitDataRequest_ChunkToPatch::CommitDataRequest_ChunkToPatch() = default;
9896 CommitDataRequest_ChunkToPatch::~CommitDataRequest_ChunkToPatch() = default;
9897 CommitDataRequest_ChunkToPatch::CommitDataRequest_ChunkToPatch(const CommitDataRequest_ChunkToPatch&) = default;
9898 CommitDataRequest_ChunkToPatch& CommitDataRequest_ChunkToPatch::operator=(const CommitDataRequest_ChunkToPatch&) = default;
9899 CommitDataRequest_ChunkToPatch::CommitDataRequest_ChunkToPatch(CommitDataRequest_ChunkToPatch&&) noexcept = default;
9900 CommitDataRequest_ChunkToPatch& CommitDataRequest_ChunkToPatch::operator=(CommitDataRequest_ChunkToPatch&&) = default;
9901 
operator ==(const CommitDataRequest_ChunkToPatch & other) const9902 bool CommitDataRequest_ChunkToPatch::operator==(const CommitDataRequest_ChunkToPatch& other) const {
9903   return unknown_fields_ == other.unknown_fields_
9904    && target_buffer_ == other.target_buffer_
9905    && writer_id_ == other.writer_id_
9906    && chunk_id_ == other.chunk_id_
9907    && patches_ == other.patches_
9908    && has_more_patches_ == other.has_more_patches_;
9909 }
9910 
patches_size() const9911 int CommitDataRequest_ChunkToPatch::patches_size() const { return static_cast<int>(patches_.size()); }
clear_patches()9912 void CommitDataRequest_ChunkToPatch::clear_patches() { patches_.clear(); }
add_patches()9913 CommitDataRequest_ChunkToPatch_Patch* CommitDataRequest_ChunkToPatch::add_patches() { patches_.emplace_back(); return &patches_.back(); }
ParseFromArray(const void * raw,size_t size)9914 bool CommitDataRequest_ChunkToPatch::ParseFromArray(const void* raw, size_t size) {
9915   patches_.clear();
9916   unknown_fields_.clear();
9917   bool packed_error = false;
9918 
9919   ::protozero::ProtoDecoder dec(raw, size);
9920   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
9921     if (field.id() < _has_field_.size()) {
9922       _has_field_.set(field.id());
9923     }
9924     switch (field.id()) {
9925       case 1 /* target_buffer */:
9926         field.get(&target_buffer_);
9927         break;
9928       case 2 /* writer_id */:
9929         field.get(&writer_id_);
9930         break;
9931       case 3 /* chunk_id */:
9932         field.get(&chunk_id_);
9933         break;
9934       case 4 /* patches */:
9935         patches_.emplace_back();
9936         patches_.back().ParseFromArray(field.data(), field.size());
9937         break;
9938       case 5 /* has_more_patches */:
9939         field.get(&has_more_patches_);
9940         break;
9941       default:
9942         field.SerializeAndAppendTo(&unknown_fields_);
9943         break;
9944     }
9945   }
9946   return !packed_error && !dec.bytes_left();
9947 }
9948 
SerializeAsString() const9949 std::string CommitDataRequest_ChunkToPatch::SerializeAsString() const {
9950   ::protozero::HeapBuffered<::protozero::Message> msg;
9951   Serialize(msg.get());
9952   return msg.SerializeAsString();
9953 }
9954 
SerializeAsArray() const9955 std::vector<uint8_t> CommitDataRequest_ChunkToPatch::SerializeAsArray() const {
9956   ::protozero::HeapBuffered<::protozero::Message> msg;
9957   Serialize(msg.get());
9958   return msg.SerializeAsArray();
9959 }
9960 
Serialize(::protozero::Message * msg) const9961 void CommitDataRequest_ChunkToPatch::Serialize(::protozero::Message* msg) const {
9962   // Field 1: target_buffer
9963   if (_has_field_[1]) {
9964     msg->AppendVarInt(1, target_buffer_);
9965   }
9966 
9967   // Field 2: writer_id
9968   if (_has_field_[2]) {
9969     msg->AppendVarInt(2, writer_id_);
9970   }
9971 
9972   // Field 3: chunk_id
9973   if (_has_field_[3]) {
9974     msg->AppendVarInt(3, chunk_id_);
9975   }
9976 
9977   // Field 4: patches
9978   for (auto& it : patches_) {
9979     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
9980   }
9981 
9982   // Field 5: has_more_patches
9983   if (_has_field_[5]) {
9984     msg->AppendTinyVarInt(5, has_more_patches_);
9985   }
9986 
9987   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
9988 }
9989 
9990 
9991 CommitDataRequest_ChunkToPatch_Patch::CommitDataRequest_ChunkToPatch_Patch() = default;
9992 CommitDataRequest_ChunkToPatch_Patch::~CommitDataRequest_ChunkToPatch_Patch() = default;
9993 CommitDataRequest_ChunkToPatch_Patch::CommitDataRequest_ChunkToPatch_Patch(const CommitDataRequest_ChunkToPatch_Patch&) = default;
9994 CommitDataRequest_ChunkToPatch_Patch& CommitDataRequest_ChunkToPatch_Patch::operator=(const CommitDataRequest_ChunkToPatch_Patch&) = default;
9995 CommitDataRequest_ChunkToPatch_Patch::CommitDataRequest_ChunkToPatch_Patch(CommitDataRequest_ChunkToPatch_Patch&&) noexcept = default;
9996 CommitDataRequest_ChunkToPatch_Patch& CommitDataRequest_ChunkToPatch_Patch::operator=(CommitDataRequest_ChunkToPatch_Patch&&) = default;
9997 
operator ==(const CommitDataRequest_ChunkToPatch_Patch & other) const9998 bool CommitDataRequest_ChunkToPatch_Patch::operator==(const CommitDataRequest_ChunkToPatch_Patch& other) const {
9999   return unknown_fields_ == other.unknown_fields_
10000    && offset_ == other.offset_
10001    && data_ == other.data_;
10002 }
10003 
ParseFromArray(const void * raw,size_t size)10004 bool CommitDataRequest_ChunkToPatch_Patch::ParseFromArray(const void* raw, size_t size) {
10005   unknown_fields_.clear();
10006   bool packed_error = false;
10007 
10008   ::protozero::ProtoDecoder dec(raw, size);
10009   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
10010     if (field.id() < _has_field_.size()) {
10011       _has_field_.set(field.id());
10012     }
10013     switch (field.id()) {
10014       case 1 /* offset */:
10015         field.get(&offset_);
10016         break;
10017       case 2 /* data */:
10018         field.get(&data_);
10019         break;
10020       default:
10021         field.SerializeAndAppendTo(&unknown_fields_);
10022         break;
10023     }
10024   }
10025   return !packed_error && !dec.bytes_left();
10026 }
10027 
SerializeAsString() const10028 std::string CommitDataRequest_ChunkToPatch_Patch::SerializeAsString() const {
10029   ::protozero::HeapBuffered<::protozero::Message> msg;
10030   Serialize(msg.get());
10031   return msg.SerializeAsString();
10032 }
10033 
SerializeAsArray() const10034 std::vector<uint8_t> CommitDataRequest_ChunkToPatch_Patch::SerializeAsArray() const {
10035   ::protozero::HeapBuffered<::protozero::Message> msg;
10036   Serialize(msg.get());
10037   return msg.SerializeAsArray();
10038 }
10039 
Serialize(::protozero::Message * msg) const10040 void CommitDataRequest_ChunkToPatch_Patch::Serialize(::protozero::Message* msg) const {
10041   // Field 1: offset
10042   if (_has_field_[1]) {
10043     msg->AppendVarInt(1, offset_);
10044   }
10045 
10046   // Field 2: data
10047   if (_has_field_[2]) {
10048     msg->AppendString(2, data_);
10049   }
10050 
10051   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
10052 }
10053 
10054 
10055 CommitDataRequest_ChunksToMove::CommitDataRequest_ChunksToMove() = default;
10056 CommitDataRequest_ChunksToMove::~CommitDataRequest_ChunksToMove() = default;
10057 CommitDataRequest_ChunksToMove::CommitDataRequest_ChunksToMove(const CommitDataRequest_ChunksToMove&) = default;
10058 CommitDataRequest_ChunksToMove& CommitDataRequest_ChunksToMove::operator=(const CommitDataRequest_ChunksToMove&) = default;
10059 CommitDataRequest_ChunksToMove::CommitDataRequest_ChunksToMove(CommitDataRequest_ChunksToMove&&) noexcept = default;
10060 CommitDataRequest_ChunksToMove& CommitDataRequest_ChunksToMove::operator=(CommitDataRequest_ChunksToMove&&) = default;
10061 
operator ==(const CommitDataRequest_ChunksToMove & other) const10062 bool CommitDataRequest_ChunksToMove::operator==(const CommitDataRequest_ChunksToMove& other) const {
10063   return unknown_fields_ == other.unknown_fields_
10064    && page_ == other.page_
10065    && chunk_ == other.chunk_
10066    && target_buffer_ == other.target_buffer_;
10067 }
10068 
ParseFromArray(const void * raw,size_t size)10069 bool CommitDataRequest_ChunksToMove::ParseFromArray(const void* raw, size_t size) {
10070   unknown_fields_.clear();
10071   bool packed_error = false;
10072 
10073   ::protozero::ProtoDecoder dec(raw, size);
10074   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
10075     if (field.id() < _has_field_.size()) {
10076       _has_field_.set(field.id());
10077     }
10078     switch (field.id()) {
10079       case 1 /* page */:
10080         field.get(&page_);
10081         break;
10082       case 2 /* chunk */:
10083         field.get(&chunk_);
10084         break;
10085       case 3 /* target_buffer */:
10086         field.get(&target_buffer_);
10087         break;
10088       default:
10089         field.SerializeAndAppendTo(&unknown_fields_);
10090         break;
10091     }
10092   }
10093   return !packed_error && !dec.bytes_left();
10094 }
10095 
SerializeAsString() const10096 std::string CommitDataRequest_ChunksToMove::SerializeAsString() const {
10097   ::protozero::HeapBuffered<::protozero::Message> msg;
10098   Serialize(msg.get());
10099   return msg.SerializeAsString();
10100 }
10101 
SerializeAsArray() const10102 std::vector<uint8_t> CommitDataRequest_ChunksToMove::SerializeAsArray() const {
10103   ::protozero::HeapBuffered<::protozero::Message> msg;
10104   Serialize(msg.get());
10105   return msg.SerializeAsArray();
10106 }
10107 
Serialize(::protozero::Message * msg) const10108 void CommitDataRequest_ChunksToMove::Serialize(::protozero::Message* msg) const {
10109   // Field 1: page
10110   if (_has_field_[1]) {
10111     msg->AppendVarInt(1, page_);
10112   }
10113 
10114   // Field 2: chunk
10115   if (_has_field_[2]) {
10116     msg->AppendVarInt(2, chunk_);
10117   }
10118 
10119   // Field 3: target_buffer
10120   if (_has_field_[3]) {
10121     msg->AppendVarInt(3, target_buffer_);
10122   }
10123 
10124   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
10125 }
10126 
10127 }  // namespace perfetto
10128 }  // namespace protos
10129 }  // namespace gen
10130 #if defined(__GNUC__) || defined(__clang__)
10131 #pragma GCC diagnostic pop
10132 #endif
10133 // gen_amalgamated begin source: gen/protos/perfetto/common/data_source_descriptor.gen.cc
10134 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
10135 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
10136 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
10137 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
10138 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
10139 #if defined(__GNUC__) || defined(__clang__)
10140 #pragma GCC diagnostic push
10141 #pragma GCC diagnostic ignored "-Wfloat-equal"
10142 #endif
10143 // gen_amalgamated expanded: #include "protos/perfetto/common/data_source_descriptor.gen.h"
10144 
10145 namespace perfetto {
10146 namespace protos {
10147 namespace gen {
10148 
10149 DataSourceDescriptor::DataSourceDescriptor() = default;
10150 DataSourceDescriptor::~DataSourceDescriptor() = default;
10151 DataSourceDescriptor::DataSourceDescriptor(const DataSourceDescriptor&) = default;
10152 DataSourceDescriptor& DataSourceDescriptor::operator=(const DataSourceDescriptor&) = default;
10153 DataSourceDescriptor::DataSourceDescriptor(DataSourceDescriptor&&) noexcept = default;
10154 DataSourceDescriptor& DataSourceDescriptor::operator=(DataSourceDescriptor&&) = default;
10155 
operator ==(const DataSourceDescriptor & other) const10156 bool DataSourceDescriptor::operator==(const DataSourceDescriptor& other) const {
10157   return unknown_fields_ == other.unknown_fields_
10158    && name_ == other.name_
10159    && will_notify_on_stop_ == other.will_notify_on_stop_
10160    && will_notify_on_start_ == other.will_notify_on_start_
10161    && handles_incremental_state_clear_ == other.handles_incremental_state_clear_
10162    && gpu_counter_descriptor_ == other.gpu_counter_descriptor_
10163    && track_event_descriptor_ == other.track_event_descriptor_;
10164 }
10165 
ParseFromArray(const void * raw,size_t size)10166 bool DataSourceDescriptor::ParseFromArray(const void* raw, size_t size) {
10167   unknown_fields_.clear();
10168   bool packed_error = false;
10169 
10170   ::protozero::ProtoDecoder dec(raw, size);
10171   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
10172     if (field.id() < _has_field_.size()) {
10173       _has_field_.set(field.id());
10174     }
10175     switch (field.id()) {
10176       case 1 /* name */:
10177         field.get(&name_);
10178         break;
10179       case 2 /* will_notify_on_stop */:
10180         field.get(&will_notify_on_stop_);
10181         break;
10182       case 3 /* will_notify_on_start */:
10183         field.get(&will_notify_on_start_);
10184         break;
10185       case 4 /* handles_incremental_state_clear */:
10186         field.get(&handles_incremental_state_clear_);
10187         break;
10188       case 5 /* gpu_counter_descriptor */:
10189         gpu_counter_descriptor_ = field.as_std_string();
10190         break;
10191       case 6 /* track_event_descriptor */:
10192         track_event_descriptor_ = field.as_std_string();
10193         break;
10194       default:
10195         field.SerializeAndAppendTo(&unknown_fields_);
10196         break;
10197     }
10198   }
10199   return !packed_error && !dec.bytes_left();
10200 }
10201 
SerializeAsString() const10202 std::string DataSourceDescriptor::SerializeAsString() const {
10203   ::protozero::HeapBuffered<::protozero::Message> msg;
10204   Serialize(msg.get());
10205   return msg.SerializeAsString();
10206 }
10207 
SerializeAsArray() const10208 std::vector<uint8_t> DataSourceDescriptor::SerializeAsArray() const {
10209   ::protozero::HeapBuffered<::protozero::Message> msg;
10210   Serialize(msg.get());
10211   return msg.SerializeAsArray();
10212 }
10213 
Serialize(::protozero::Message * msg) const10214 void DataSourceDescriptor::Serialize(::protozero::Message* msg) const {
10215   // Field 1: name
10216   if (_has_field_[1]) {
10217     msg->AppendString(1, name_);
10218   }
10219 
10220   // Field 2: will_notify_on_stop
10221   if (_has_field_[2]) {
10222     msg->AppendTinyVarInt(2, will_notify_on_stop_);
10223   }
10224 
10225   // Field 3: will_notify_on_start
10226   if (_has_field_[3]) {
10227     msg->AppendTinyVarInt(3, will_notify_on_start_);
10228   }
10229 
10230   // Field 4: handles_incremental_state_clear
10231   if (_has_field_[4]) {
10232     msg->AppendTinyVarInt(4, handles_incremental_state_clear_);
10233   }
10234 
10235   // Field 5: gpu_counter_descriptor
10236   if (_has_field_[5]) {
10237     msg->AppendString(5, gpu_counter_descriptor_);
10238   }
10239 
10240   // Field 6: track_event_descriptor
10241   if (_has_field_[6]) {
10242     msg->AppendString(6, track_event_descriptor_);
10243   }
10244 
10245   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
10246 }
10247 
10248 }  // namespace perfetto
10249 }  // namespace protos
10250 }  // namespace gen
10251 #if defined(__GNUC__) || defined(__clang__)
10252 #pragma GCC diagnostic pop
10253 #endif
10254 // gen_amalgamated begin source: gen/protos/perfetto/common/descriptor.gen.cc
10255 // gen_amalgamated begin header: gen/protos/perfetto/common/descriptor.gen.h
10256 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
10257 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_DESCRIPTOR_PROTO_CPP_H_
10258 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_DESCRIPTOR_PROTO_CPP_H_
10259 
10260 #include <stdint.h>
10261 #include <bitset>
10262 #include <vector>
10263 #include <string>
10264 #include <type_traits>
10265 
10266 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
10267 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
10268 // gen_amalgamated expanded: #include "perfetto/base/export.h"
10269 
10270 namespace perfetto {
10271 namespace protos {
10272 namespace gen {
10273 class OneofOptions;
10274 class EnumValueDescriptorProto;
10275 class EnumDescriptorProto;
10276 class OneofDescriptorProto;
10277 class FieldDescriptorProto;
10278 class DescriptorProto;
10279 class DescriptorProto_ReservedRange;
10280 class FileDescriptorProto;
10281 class FileDescriptorSet;
10282 enum FieldDescriptorProto_Type : int;
10283 enum FieldDescriptorProto_Label : int;
10284 }  // namespace perfetto
10285 }  // namespace protos
10286 }  // namespace gen
10287 
10288 namespace protozero {
10289 class Message;
10290 }  // namespace protozero
10291 
10292 namespace perfetto {
10293 namespace protos {
10294 namespace gen {
10295 enum FieldDescriptorProto_Type : int {
10296   FieldDescriptorProto_Type_TYPE_DOUBLE = 1,
10297   FieldDescriptorProto_Type_TYPE_FLOAT = 2,
10298   FieldDescriptorProto_Type_TYPE_INT64 = 3,
10299   FieldDescriptorProto_Type_TYPE_UINT64 = 4,
10300   FieldDescriptorProto_Type_TYPE_INT32 = 5,
10301   FieldDescriptorProto_Type_TYPE_FIXED64 = 6,
10302   FieldDescriptorProto_Type_TYPE_FIXED32 = 7,
10303   FieldDescriptorProto_Type_TYPE_BOOL = 8,
10304   FieldDescriptorProto_Type_TYPE_STRING = 9,
10305   FieldDescriptorProto_Type_TYPE_GROUP = 10,
10306   FieldDescriptorProto_Type_TYPE_MESSAGE = 11,
10307   FieldDescriptorProto_Type_TYPE_BYTES = 12,
10308   FieldDescriptorProto_Type_TYPE_UINT32 = 13,
10309   FieldDescriptorProto_Type_TYPE_ENUM = 14,
10310   FieldDescriptorProto_Type_TYPE_SFIXED32 = 15,
10311   FieldDescriptorProto_Type_TYPE_SFIXED64 = 16,
10312   FieldDescriptorProto_Type_TYPE_SINT32 = 17,
10313   FieldDescriptorProto_Type_TYPE_SINT64 = 18,
10314 };
10315 enum FieldDescriptorProto_Label : int {
10316   FieldDescriptorProto_Label_LABEL_OPTIONAL = 1,
10317   FieldDescriptorProto_Label_LABEL_REQUIRED = 2,
10318   FieldDescriptorProto_Label_LABEL_REPEATED = 3,
10319 };
10320 
10321 class PERFETTO_EXPORT OneofOptions : public ::protozero::CppMessageObj {
10322  public:
10323   enum FieldNumbers {
10324   };
10325 
10326   OneofOptions();
10327   ~OneofOptions() override;
10328   OneofOptions(OneofOptions&&) noexcept;
10329   OneofOptions& operator=(OneofOptions&&);
10330   OneofOptions(const OneofOptions&);
10331   OneofOptions& operator=(const OneofOptions&);
10332   bool operator==(const OneofOptions&) const;
operator !=(const OneofOptions & other) const10333   bool operator!=(const OneofOptions& other) const { return !(*this == other); }
10334 
10335   bool ParseFromArray(const void*, size_t) override;
10336   std::string SerializeAsString() const override;
10337   std::vector<uint8_t> SerializeAsArray() const override;
10338   void Serialize(::protozero::Message*) const;
10339 
10340  private:
10341 
10342   // Allows to preserve unknown protobuf fields for compatibility
10343   // with future versions of .proto files.
10344   std::string unknown_fields_;
10345 
10346   std::bitset<2> _has_field_{};
10347 };
10348 
10349 
10350 class PERFETTO_EXPORT EnumValueDescriptorProto : public ::protozero::CppMessageObj {
10351  public:
10352   enum FieldNumbers {
10353     kNameFieldNumber = 1,
10354     kNumberFieldNumber = 2,
10355   };
10356 
10357   EnumValueDescriptorProto();
10358   ~EnumValueDescriptorProto() override;
10359   EnumValueDescriptorProto(EnumValueDescriptorProto&&) noexcept;
10360   EnumValueDescriptorProto& operator=(EnumValueDescriptorProto&&);
10361   EnumValueDescriptorProto(const EnumValueDescriptorProto&);
10362   EnumValueDescriptorProto& operator=(const EnumValueDescriptorProto&);
10363   bool operator==(const EnumValueDescriptorProto&) const;
operator !=(const EnumValueDescriptorProto & other) const10364   bool operator!=(const EnumValueDescriptorProto& other) const { return !(*this == other); }
10365 
10366   bool ParseFromArray(const void*, size_t) override;
10367   std::string SerializeAsString() const override;
10368   std::vector<uint8_t> SerializeAsArray() const override;
10369   void Serialize(::protozero::Message*) const;
10370 
has_name() const10371   bool has_name() const { return _has_field_[1]; }
name() const10372   const std::string& name() const { return name_; }
set_name(const std::string & value)10373   void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
10374 
has_number() const10375   bool has_number() const { return _has_field_[2]; }
number() const10376   int32_t number() const { return number_; }
set_number(int32_t value)10377   void set_number(int32_t value) { number_ = value; _has_field_.set(2); }
10378 
10379  private:
10380   std::string name_{};
10381   int32_t number_{};
10382 
10383   // Allows to preserve unknown protobuf fields for compatibility
10384   // with future versions of .proto files.
10385   std::string unknown_fields_;
10386 
10387   std::bitset<3> _has_field_{};
10388 };
10389 
10390 
10391 class PERFETTO_EXPORT EnumDescriptorProto : public ::protozero::CppMessageObj {
10392  public:
10393   enum FieldNumbers {
10394     kNameFieldNumber = 1,
10395     kValueFieldNumber = 2,
10396     kReservedNameFieldNumber = 5,
10397   };
10398 
10399   EnumDescriptorProto();
10400   ~EnumDescriptorProto() override;
10401   EnumDescriptorProto(EnumDescriptorProto&&) noexcept;
10402   EnumDescriptorProto& operator=(EnumDescriptorProto&&);
10403   EnumDescriptorProto(const EnumDescriptorProto&);
10404   EnumDescriptorProto& operator=(const EnumDescriptorProto&);
10405   bool operator==(const EnumDescriptorProto&) const;
operator !=(const EnumDescriptorProto & other) const10406   bool operator!=(const EnumDescriptorProto& other) const { return !(*this == other); }
10407 
10408   bool ParseFromArray(const void*, size_t) override;
10409   std::string SerializeAsString() const override;
10410   std::vector<uint8_t> SerializeAsArray() const override;
10411   void Serialize(::protozero::Message*) const;
10412 
has_name() const10413   bool has_name() const { return _has_field_[1]; }
name() const10414   const std::string& name() const { return name_; }
set_name(const std::string & value)10415   void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
10416 
value() const10417   const std::vector<EnumValueDescriptorProto>& value() const { return value_; }
mutable_value()10418   std::vector<EnumValueDescriptorProto>* mutable_value() { return &value_; }
10419   int value_size() const;
10420   void clear_value();
10421   EnumValueDescriptorProto* add_value();
10422 
reserved_name() const10423   const std::vector<std::string>& reserved_name() const { return reserved_name_; }
mutable_reserved_name()10424   std::vector<std::string>* mutable_reserved_name() { return &reserved_name_; }
reserved_name_size() const10425   int reserved_name_size() const { return static_cast<int>(reserved_name_.size()); }
clear_reserved_name()10426   void clear_reserved_name() { reserved_name_.clear(); }
add_reserved_name(std::string value)10427   void add_reserved_name(std::string value) { reserved_name_.emplace_back(value); }
add_reserved_name()10428   std::string* add_reserved_name() { reserved_name_.emplace_back(); return &reserved_name_.back(); }
10429 
10430  private:
10431   std::string name_{};
10432   std::vector<EnumValueDescriptorProto> value_;
10433   std::vector<std::string> reserved_name_;
10434 
10435   // Allows to preserve unknown protobuf fields for compatibility
10436   // with future versions of .proto files.
10437   std::string unknown_fields_;
10438 
10439   std::bitset<6> _has_field_{};
10440 };
10441 
10442 
10443 class PERFETTO_EXPORT OneofDescriptorProto : public ::protozero::CppMessageObj {
10444  public:
10445   enum FieldNumbers {
10446     kNameFieldNumber = 1,
10447     kOptionsFieldNumber = 2,
10448   };
10449 
10450   OneofDescriptorProto();
10451   ~OneofDescriptorProto() override;
10452   OneofDescriptorProto(OneofDescriptorProto&&) noexcept;
10453   OneofDescriptorProto& operator=(OneofDescriptorProto&&);
10454   OneofDescriptorProto(const OneofDescriptorProto&);
10455   OneofDescriptorProto& operator=(const OneofDescriptorProto&);
10456   bool operator==(const OneofDescriptorProto&) const;
operator !=(const OneofDescriptorProto & other) const10457   bool operator!=(const OneofDescriptorProto& other) const { return !(*this == other); }
10458 
10459   bool ParseFromArray(const void*, size_t) override;
10460   std::string SerializeAsString() const override;
10461   std::vector<uint8_t> SerializeAsArray() const override;
10462   void Serialize(::protozero::Message*) const;
10463 
has_name() const10464   bool has_name() const { return _has_field_[1]; }
name() const10465   const std::string& name() const { return name_; }
set_name(const std::string & value)10466   void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
10467 
has_options() const10468   bool has_options() const { return _has_field_[2]; }
options() const10469   const OneofOptions& options() const { return *options_; }
mutable_options()10470   OneofOptions* mutable_options() { _has_field_.set(2); return options_.get(); }
10471 
10472  private:
10473   std::string name_{};
10474   ::protozero::CopyablePtr<OneofOptions> options_;
10475 
10476   // Allows to preserve unknown protobuf fields for compatibility
10477   // with future versions of .proto files.
10478   std::string unknown_fields_;
10479 
10480   std::bitset<3> _has_field_{};
10481 };
10482 
10483 
10484 class PERFETTO_EXPORT FieldDescriptorProto : public ::protozero::CppMessageObj {
10485  public:
10486   using Type = FieldDescriptorProto_Type;
10487   static constexpr auto TYPE_DOUBLE = FieldDescriptorProto_Type_TYPE_DOUBLE;
10488   static constexpr auto TYPE_FLOAT = FieldDescriptorProto_Type_TYPE_FLOAT;
10489   static constexpr auto TYPE_INT64 = FieldDescriptorProto_Type_TYPE_INT64;
10490   static constexpr auto TYPE_UINT64 = FieldDescriptorProto_Type_TYPE_UINT64;
10491   static constexpr auto TYPE_INT32 = FieldDescriptorProto_Type_TYPE_INT32;
10492   static constexpr auto TYPE_FIXED64 = FieldDescriptorProto_Type_TYPE_FIXED64;
10493   static constexpr auto TYPE_FIXED32 = FieldDescriptorProto_Type_TYPE_FIXED32;
10494   static constexpr auto TYPE_BOOL = FieldDescriptorProto_Type_TYPE_BOOL;
10495   static constexpr auto TYPE_STRING = FieldDescriptorProto_Type_TYPE_STRING;
10496   static constexpr auto TYPE_GROUP = FieldDescriptorProto_Type_TYPE_GROUP;
10497   static constexpr auto TYPE_MESSAGE = FieldDescriptorProto_Type_TYPE_MESSAGE;
10498   static constexpr auto TYPE_BYTES = FieldDescriptorProto_Type_TYPE_BYTES;
10499   static constexpr auto TYPE_UINT32 = FieldDescriptorProto_Type_TYPE_UINT32;
10500   static constexpr auto TYPE_ENUM = FieldDescriptorProto_Type_TYPE_ENUM;
10501   static constexpr auto TYPE_SFIXED32 = FieldDescriptorProto_Type_TYPE_SFIXED32;
10502   static constexpr auto TYPE_SFIXED64 = FieldDescriptorProto_Type_TYPE_SFIXED64;
10503   static constexpr auto TYPE_SINT32 = FieldDescriptorProto_Type_TYPE_SINT32;
10504   static constexpr auto TYPE_SINT64 = FieldDescriptorProto_Type_TYPE_SINT64;
10505   static constexpr auto Type_MIN = FieldDescriptorProto_Type_TYPE_DOUBLE;
10506   static constexpr auto Type_MAX = FieldDescriptorProto_Type_TYPE_SINT64;
10507   using Label = FieldDescriptorProto_Label;
10508   static constexpr auto LABEL_OPTIONAL = FieldDescriptorProto_Label_LABEL_OPTIONAL;
10509   static constexpr auto LABEL_REQUIRED = FieldDescriptorProto_Label_LABEL_REQUIRED;
10510   static constexpr auto LABEL_REPEATED = FieldDescriptorProto_Label_LABEL_REPEATED;
10511   static constexpr auto Label_MIN = FieldDescriptorProto_Label_LABEL_OPTIONAL;
10512   static constexpr auto Label_MAX = FieldDescriptorProto_Label_LABEL_REPEATED;
10513   enum FieldNumbers {
10514     kNameFieldNumber = 1,
10515     kNumberFieldNumber = 3,
10516     kLabelFieldNumber = 4,
10517     kTypeFieldNumber = 5,
10518     kTypeNameFieldNumber = 6,
10519     kExtendeeFieldNumber = 2,
10520     kDefaultValueFieldNumber = 7,
10521     kOneofIndexFieldNumber = 9,
10522   };
10523 
10524   FieldDescriptorProto();
10525   ~FieldDescriptorProto() override;
10526   FieldDescriptorProto(FieldDescriptorProto&&) noexcept;
10527   FieldDescriptorProto& operator=(FieldDescriptorProto&&);
10528   FieldDescriptorProto(const FieldDescriptorProto&);
10529   FieldDescriptorProto& operator=(const FieldDescriptorProto&);
10530   bool operator==(const FieldDescriptorProto&) const;
operator !=(const FieldDescriptorProto & other) const10531   bool operator!=(const FieldDescriptorProto& other) const { return !(*this == other); }
10532 
10533   bool ParseFromArray(const void*, size_t) override;
10534   std::string SerializeAsString() const override;
10535   std::vector<uint8_t> SerializeAsArray() const override;
10536   void Serialize(::protozero::Message*) const;
10537 
has_name() const10538   bool has_name() const { return _has_field_[1]; }
name() const10539   const std::string& name() const { return name_; }
set_name(const std::string & value)10540   void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
10541 
has_number() const10542   bool has_number() const { return _has_field_[3]; }
number() const10543   int32_t number() const { return number_; }
set_number(int32_t value)10544   void set_number(int32_t value) { number_ = value; _has_field_.set(3); }
10545 
has_label() const10546   bool has_label() const { return _has_field_[4]; }
label() const10547   FieldDescriptorProto_Label label() const { return label_; }
set_label(FieldDescriptorProto_Label value)10548   void set_label(FieldDescriptorProto_Label value) { label_ = value; _has_field_.set(4); }
10549 
has_type() const10550   bool has_type() const { return _has_field_[5]; }
type() const10551   FieldDescriptorProto_Type type() const { return type_; }
set_type(FieldDescriptorProto_Type value)10552   void set_type(FieldDescriptorProto_Type value) { type_ = value; _has_field_.set(5); }
10553 
has_type_name() const10554   bool has_type_name() const { return _has_field_[6]; }
type_name() const10555   const std::string& type_name() const { return type_name_; }
set_type_name(const std::string & value)10556   void set_type_name(const std::string& value) { type_name_ = value; _has_field_.set(6); }
10557 
has_extendee() const10558   bool has_extendee() const { return _has_field_[2]; }
extendee() const10559   const std::string& extendee() const { return extendee_; }
set_extendee(const std::string & value)10560   void set_extendee(const std::string& value) { extendee_ = value; _has_field_.set(2); }
10561 
has_default_value() const10562   bool has_default_value() const { return _has_field_[7]; }
default_value() const10563   const std::string& default_value() const { return default_value_; }
set_default_value(const std::string & value)10564   void set_default_value(const std::string& value) { default_value_ = value; _has_field_.set(7); }
10565 
has_oneof_index() const10566   bool has_oneof_index() const { return _has_field_[9]; }
oneof_index() const10567   int32_t oneof_index() const { return oneof_index_; }
set_oneof_index(int32_t value)10568   void set_oneof_index(int32_t value) { oneof_index_ = value; _has_field_.set(9); }
10569 
10570  private:
10571   std::string name_{};
10572   int32_t number_{};
10573   FieldDescriptorProto_Label label_{};
10574   FieldDescriptorProto_Type type_{};
10575   std::string type_name_{};
10576   std::string extendee_{};
10577   std::string default_value_{};
10578   int32_t oneof_index_{};
10579 
10580   // Allows to preserve unknown protobuf fields for compatibility
10581   // with future versions of .proto files.
10582   std::string unknown_fields_;
10583 
10584   std::bitset<10> _has_field_{};
10585 };
10586 
10587 
10588 class PERFETTO_EXPORT DescriptorProto : public ::protozero::CppMessageObj {
10589  public:
10590   using ReservedRange = DescriptorProto_ReservedRange;
10591   enum FieldNumbers {
10592     kNameFieldNumber = 1,
10593     kFieldFieldNumber = 2,
10594     kExtensionFieldNumber = 6,
10595     kNestedTypeFieldNumber = 3,
10596     kEnumTypeFieldNumber = 4,
10597     kOneofDeclFieldNumber = 8,
10598     kReservedRangeFieldNumber = 9,
10599     kReservedNameFieldNumber = 10,
10600   };
10601 
10602   DescriptorProto();
10603   ~DescriptorProto() override;
10604   DescriptorProto(DescriptorProto&&) noexcept;
10605   DescriptorProto& operator=(DescriptorProto&&);
10606   DescriptorProto(const DescriptorProto&);
10607   DescriptorProto& operator=(const DescriptorProto&);
10608   bool operator==(const DescriptorProto&) const;
operator !=(const DescriptorProto & other) const10609   bool operator!=(const DescriptorProto& other) const { return !(*this == other); }
10610 
10611   bool ParseFromArray(const void*, size_t) override;
10612   std::string SerializeAsString() const override;
10613   std::vector<uint8_t> SerializeAsArray() const override;
10614   void Serialize(::protozero::Message*) const;
10615 
has_name() const10616   bool has_name() const { return _has_field_[1]; }
name() const10617   const std::string& name() const { return name_; }
set_name(const std::string & value)10618   void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
10619 
field() const10620   const std::vector<FieldDescriptorProto>& field() const { return field_; }
mutable_field()10621   std::vector<FieldDescriptorProto>* mutable_field() { return &field_; }
10622   int field_size() const;
10623   void clear_field();
10624   FieldDescriptorProto* add_field();
10625 
extension() const10626   const std::vector<FieldDescriptorProto>& extension() const { return extension_; }
mutable_extension()10627   std::vector<FieldDescriptorProto>* mutable_extension() { return &extension_; }
10628   int extension_size() const;
10629   void clear_extension();
10630   FieldDescriptorProto* add_extension();
10631 
nested_type() const10632   const std::vector<DescriptorProto>& nested_type() const { return nested_type_; }
mutable_nested_type()10633   std::vector<DescriptorProto>* mutable_nested_type() { return &nested_type_; }
10634   int nested_type_size() const;
10635   void clear_nested_type();
10636   DescriptorProto* add_nested_type();
10637 
enum_type() const10638   const std::vector<EnumDescriptorProto>& enum_type() const { return enum_type_; }
mutable_enum_type()10639   std::vector<EnumDescriptorProto>* mutable_enum_type() { return &enum_type_; }
10640   int enum_type_size() const;
10641   void clear_enum_type();
10642   EnumDescriptorProto* add_enum_type();
10643 
oneof_decl() const10644   const std::vector<OneofDescriptorProto>& oneof_decl() const { return oneof_decl_; }
mutable_oneof_decl()10645   std::vector<OneofDescriptorProto>* mutable_oneof_decl() { return &oneof_decl_; }
10646   int oneof_decl_size() const;
10647   void clear_oneof_decl();
10648   OneofDescriptorProto* add_oneof_decl();
10649 
reserved_range() const10650   const std::vector<DescriptorProto_ReservedRange>& reserved_range() const { return reserved_range_; }
mutable_reserved_range()10651   std::vector<DescriptorProto_ReservedRange>* mutable_reserved_range() { return &reserved_range_; }
10652   int reserved_range_size() const;
10653   void clear_reserved_range();
10654   DescriptorProto_ReservedRange* add_reserved_range();
10655 
reserved_name() const10656   const std::vector<std::string>& reserved_name() const { return reserved_name_; }
mutable_reserved_name()10657   std::vector<std::string>* mutable_reserved_name() { return &reserved_name_; }
reserved_name_size() const10658   int reserved_name_size() const { return static_cast<int>(reserved_name_.size()); }
clear_reserved_name()10659   void clear_reserved_name() { reserved_name_.clear(); }
add_reserved_name(std::string value)10660   void add_reserved_name(std::string value) { reserved_name_.emplace_back(value); }
add_reserved_name()10661   std::string* add_reserved_name() { reserved_name_.emplace_back(); return &reserved_name_.back(); }
10662 
10663  private:
10664   std::string name_{};
10665   std::vector<FieldDescriptorProto> field_;
10666   std::vector<FieldDescriptorProto> extension_;
10667   std::vector<DescriptorProto> nested_type_;
10668   std::vector<EnumDescriptorProto> enum_type_;
10669   std::vector<OneofDescriptorProto> oneof_decl_;
10670   std::vector<DescriptorProto_ReservedRange> reserved_range_;
10671   std::vector<std::string> reserved_name_;
10672 
10673   // Allows to preserve unknown protobuf fields for compatibility
10674   // with future versions of .proto files.
10675   std::string unknown_fields_;
10676 
10677   std::bitset<11> _has_field_{};
10678 };
10679 
10680 
10681 class PERFETTO_EXPORT DescriptorProto_ReservedRange : public ::protozero::CppMessageObj {
10682  public:
10683   enum FieldNumbers {
10684     kStartFieldNumber = 1,
10685     kEndFieldNumber = 2,
10686   };
10687 
10688   DescriptorProto_ReservedRange();
10689   ~DescriptorProto_ReservedRange() override;
10690   DescriptorProto_ReservedRange(DescriptorProto_ReservedRange&&) noexcept;
10691   DescriptorProto_ReservedRange& operator=(DescriptorProto_ReservedRange&&);
10692   DescriptorProto_ReservedRange(const DescriptorProto_ReservedRange&);
10693   DescriptorProto_ReservedRange& operator=(const DescriptorProto_ReservedRange&);
10694   bool operator==(const DescriptorProto_ReservedRange&) const;
operator !=(const DescriptorProto_ReservedRange & other) const10695   bool operator!=(const DescriptorProto_ReservedRange& other) const { return !(*this == other); }
10696 
10697   bool ParseFromArray(const void*, size_t) override;
10698   std::string SerializeAsString() const override;
10699   std::vector<uint8_t> SerializeAsArray() const override;
10700   void Serialize(::protozero::Message*) const;
10701 
has_start() const10702   bool has_start() const { return _has_field_[1]; }
start() const10703   int32_t start() const { return start_; }
set_start(int32_t value)10704   void set_start(int32_t value) { start_ = value; _has_field_.set(1); }
10705 
has_end() const10706   bool has_end() const { return _has_field_[2]; }
end() const10707   int32_t end() const { return end_; }
set_end(int32_t value)10708   void set_end(int32_t value) { end_ = value; _has_field_.set(2); }
10709 
10710  private:
10711   int32_t start_{};
10712   int32_t end_{};
10713 
10714   // Allows to preserve unknown protobuf fields for compatibility
10715   // with future versions of .proto files.
10716   std::string unknown_fields_;
10717 
10718   std::bitset<3> _has_field_{};
10719 };
10720 
10721 
10722 class PERFETTO_EXPORT FileDescriptorProto : public ::protozero::CppMessageObj {
10723  public:
10724   enum FieldNumbers {
10725     kNameFieldNumber = 1,
10726     kPackageFieldNumber = 2,
10727     kDependencyFieldNumber = 3,
10728     kPublicDependencyFieldNumber = 10,
10729     kWeakDependencyFieldNumber = 11,
10730     kMessageTypeFieldNumber = 4,
10731     kEnumTypeFieldNumber = 5,
10732     kExtensionFieldNumber = 7,
10733   };
10734 
10735   FileDescriptorProto();
10736   ~FileDescriptorProto() override;
10737   FileDescriptorProto(FileDescriptorProto&&) noexcept;
10738   FileDescriptorProto& operator=(FileDescriptorProto&&);
10739   FileDescriptorProto(const FileDescriptorProto&);
10740   FileDescriptorProto& operator=(const FileDescriptorProto&);
10741   bool operator==(const FileDescriptorProto&) const;
operator !=(const FileDescriptorProto & other) const10742   bool operator!=(const FileDescriptorProto& other) const { return !(*this == other); }
10743 
10744   bool ParseFromArray(const void*, size_t) override;
10745   std::string SerializeAsString() const override;
10746   std::vector<uint8_t> SerializeAsArray() const override;
10747   void Serialize(::protozero::Message*) const;
10748 
has_name() const10749   bool has_name() const { return _has_field_[1]; }
name() const10750   const std::string& name() const { return name_; }
set_name(const std::string & value)10751   void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
10752 
has_package() const10753   bool has_package() const { return _has_field_[2]; }
package() const10754   const std::string& package() const { return package_; }
set_package(const std::string & value)10755   void set_package(const std::string& value) { package_ = value; _has_field_.set(2); }
10756 
dependency() const10757   const std::vector<std::string>& dependency() const { return dependency_; }
mutable_dependency()10758   std::vector<std::string>* mutable_dependency() { return &dependency_; }
dependency_size() const10759   int dependency_size() const { return static_cast<int>(dependency_.size()); }
clear_dependency()10760   void clear_dependency() { dependency_.clear(); }
add_dependency(std::string value)10761   void add_dependency(std::string value) { dependency_.emplace_back(value); }
add_dependency()10762   std::string* add_dependency() { dependency_.emplace_back(); return &dependency_.back(); }
10763 
public_dependency() const10764   const std::vector<int32_t>& public_dependency() const { return public_dependency_; }
mutable_public_dependency()10765   std::vector<int32_t>* mutable_public_dependency() { return &public_dependency_; }
public_dependency_size() const10766   int public_dependency_size() const { return static_cast<int>(public_dependency_.size()); }
clear_public_dependency()10767   void clear_public_dependency() { public_dependency_.clear(); }
add_public_dependency(int32_t value)10768   void add_public_dependency(int32_t value) { public_dependency_.emplace_back(value); }
add_public_dependency()10769   int32_t* add_public_dependency() { public_dependency_.emplace_back(); return &public_dependency_.back(); }
10770 
weak_dependency() const10771   const std::vector<int32_t>& weak_dependency() const { return weak_dependency_; }
mutable_weak_dependency()10772   std::vector<int32_t>* mutable_weak_dependency() { return &weak_dependency_; }
weak_dependency_size() const10773   int weak_dependency_size() const { return static_cast<int>(weak_dependency_.size()); }
clear_weak_dependency()10774   void clear_weak_dependency() { weak_dependency_.clear(); }
add_weak_dependency(int32_t value)10775   void add_weak_dependency(int32_t value) { weak_dependency_.emplace_back(value); }
add_weak_dependency()10776   int32_t* add_weak_dependency() { weak_dependency_.emplace_back(); return &weak_dependency_.back(); }
10777 
message_type() const10778   const std::vector<DescriptorProto>& message_type() const { return message_type_; }
mutable_message_type()10779   std::vector<DescriptorProto>* mutable_message_type() { return &message_type_; }
10780   int message_type_size() const;
10781   void clear_message_type();
10782   DescriptorProto* add_message_type();
10783 
enum_type() const10784   const std::vector<EnumDescriptorProto>& enum_type() const { return enum_type_; }
mutable_enum_type()10785   std::vector<EnumDescriptorProto>* mutable_enum_type() { return &enum_type_; }
10786   int enum_type_size() const;
10787   void clear_enum_type();
10788   EnumDescriptorProto* add_enum_type();
10789 
extension() const10790   const std::vector<FieldDescriptorProto>& extension() const { return extension_; }
mutable_extension()10791   std::vector<FieldDescriptorProto>* mutable_extension() { return &extension_; }
10792   int extension_size() const;
10793   void clear_extension();
10794   FieldDescriptorProto* add_extension();
10795 
10796  private:
10797   std::string name_{};
10798   std::string package_{};
10799   std::vector<std::string> dependency_;
10800   std::vector<int32_t> public_dependency_;
10801   std::vector<int32_t> weak_dependency_;
10802   std::vector<DescriptorProto> message_type_;
10803   std::vector<EnumDescriptorProto> enum_type_;
10804   std::vector<FieldDescriptorProto> extension_;
10805 
10806   // Allows to preserve unknown protobuf fields for compatibility
10807   // with future versions of .proto files.
10808   std::string unknown_fields_;
10809 
10810   std::bitset<12> _has_field_{};
10811 };
10812 
10813 
10814 class PERFETTO_EXPORT FileDescriptorSet : public ::protozero::CppMessageObj {
10815  public:
10816   enum FieldNumbers {
10817     kFileFieldNumber = 1,
10818   };
10819 
10820   FileDescriptorSet();
10821   ~FileDescriptorSet() override;
10822   FileDescriptorSet(FileDescriptorSet&&) noexcept;
10823   FileDescriptorSet& operator=(FileDescriptorSet&&);
10824   FileDescriptorSet(const FileDescriptorSet&);
10825   FileDescriptorSet& operator=(const FileDescriptorSet&);
10826   bool operator==(const FileDescriptorSet&) const;
operator !=(const FileDescriptorSet & other) const10827   bool operator!=(const FileDescriptorSet& other) const { return !(*this == other); }
10828 
10829   bool ParseFromArray(const void*, size_t) override;
10830   std::string SerializeAsString() const override;
10831   std::vector<uint8_t> SerializeAsArray() const override;
10832   void Serialize(::protozero::Message*) const;
10833 
file() const10834   const std::vector<FileDescriptorProto>& file() const { return file_; }
mutable_file()10835   std::vector<FileDescriptorProto>* mutable_file() { return &file_; }
10836   int file_size() const;
10837   void clear_file();
10838   FileDescriptorProto* add_file();
10839 
10840  private:
10841   std::vector<FileDescriptorProto> file_;
10842 
10843   // Allows to preserve unknown protobuf fields for compatibility
10844   // with future versions of .proto files.
10845   std::string unknown_fields_;
10846 
10847   std::bitset<2> _has_field_{};
10848 };
10849 
10850 }  // namespace perfetto
10851 }  // namespace protos
10852 }  // namespace gen
10853 
10854 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_DESCRIPTOR_PROTO_CPP_H_
10855 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
10856 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
10857 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
10858 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
10859 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
10860 #if defined(__GNUC__) || defined(__clang__)
10861 #pragma GCC diagnostic push
10862 #pragma GCC diagnostic ignored "-Wfloat-equal"
10863 #endif
10864 // gen_amalgamated expanded: #include "protos/perfetto/common/descriptor.gen.h"
10865 
10866 namespace perfetto {
10867 namespace protos {
10868 namespace gen {
10869 
10870 OneofOptions::OneofOptions() = default;
10871 OneofOptions::~OneofOptions() = default;
10872 OneofOptions::OneofOptions(const OneofOptions&) = default;
10873 OneofOptions& OneofOptions::operator=(const OneofOptions&) = default;
10874 OneofOptions::OneofOptions(OneofOptions&&) noexcept = default;
10875 OneofOptions& OneofOptions::operator=(OneofOptions&&) = default;
10876 
operator ==(const OneofOptions & other) const10877 bool OneofOptions::operator==(const OneofOptions& other) const {
10878   return unknown_fields_ == other.unknown_fields_;
10879 }
10880 
ParseFromArray(const void * raw,size_t size)10881 bool OneofOptions::ParseFromArray(const void* raw, size_t size) {
10882   unknown_fields_.clear();
10883   bool packed_error = false;
10884 
10885   ::protozero::ProtoDecoder dec(raw, size);
10886   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
10887     if (field.id() < _has_field_.size()) {
10888       _has_field_.set(field.id());
10889     }
10890     switch (field.id()) {
10891       default:
10892         field.SerializeAndAppendTo(&unknown_fields_);
10893         break;
10894     }
10895   }
10896   return !packed_error && !dec.bytes_left();
10897 }
10898 
SerializeAsString() const10899 std::string OneofOptions::SerializeAsString() const {
10900   ::protozero::HeapBuffered<::protozero::Message> msg;
10901   Serialize(msg.get());
10902   return msg.SerializeAsString();
10903 }
10904 
SerializeAsArray() const10905 std::vector<uint8_t> OneofOptions::SerializeAsArray() const {
10906   ::protozero::HeapBuffered<::protozero::Message> msg;
10907   Serialize(msg.get());
10908   return msg.SerializeAsArray();
10909 }
10910 
Serialize(::protozero::Message * msg) const10911 void OneofOptions::Serialize(::protozero::Message* msg) const {
10912   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
10913 }
10914 
10915 
10916 EnumValueDescriptorProto::EnumValueDescriptorProto() = default;
10917 EnumValueDescriptorProto::~EnumValueDescriptorProto() = default;
10918 EnumValueDescriptorProto::EnumValueDescriptorProto(const EnumValueDescriptorProto&) = default;
10919 EnumValueDescriptorProto& EnumValueDescriptorProto::operator=(const EnumValueDescriptorProto&) = default;
10920 EnumValueDescriptorProto::EnumValueDescriptorProto(EnumValueDescriptorProto&&) noexcept = default;
10921 EnumValueDescriptorProto& EnumValueDescriptorProto::operator=(EnumValueDescriptorProto&&) = default;
10922 
operator ==(const EnumValueDescriptorProto & other) const10923 bool EnumValueDescriptorProto::operator==(const EnumValueDescriptorProto& other) const {
10924   return unknown_fields_ == other.unknown_fields_
10925    && name_ == other.name_
10926    && number_ == other.number_;
10927 }
10928 
ParseFromArray(const void * raw,size_t size)10929 bool EnumValueDescriptorProto::ParseFromArray(const void* raw, size_t size) {
10930   unknown_fields_.clear();
10931   bool packed_error = false;
10932 
10933   ::protozero::ProtoDecoder dec(raw, size);
10934   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
10935     if (field.id() < _has_field_.size()) {
10936       _has_field_.set(field.id());
10937     }
10938     switch (field.id()) {
10939       case 1 /* name */:
10940         field.get(&name_);
10941         break;
10942       case 2 /* number */:
10943         field.get(&number_);
10944         break;
10945       default:
10946         field.SerializeAndAppendTo(&unknown_fields_);
10947         break;
10948     }
10949   }
10950   return !packed_error && !dec.bytes_left();
10951 }
10952 
SerializeAsString() const10953 std::string EnumValueDescriptorProto::SerializeAsString() const {
10954   ::protozero::HeapBuffered<::protozero::Message> msg;
10955   Serialize(msg.get());
10956   return msg.SerializeAsString();
10957 }
10958 
SerializeAsArray() const10959 std::vector<uint8_t> EnumValueDescriptorProto::SerializeAsArray() const {
10960   ::protozero::HeapBuffered<::protozero::Message> msg;
10961   Serialize(msg.get());
10962   return msg.SerializeAsArray();
10963 }
10964 
Serialize(::protozero::Message * msg) const10965 void EnumValueDescriptorProto::Serialize(::protozero::Message* msg) const {
10966   // Field 1: name
10967   if (_has_field_[1]) {
10968     msg->AppendString(1, name_);
10969   }
10970 
10971   // Field 2: number
10972   if (_has_field_[2]) {
10973     msg->AppendVarInt(2, number_);
10974   }
10975 
10976   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
10977 }
10978 
10979 
10980 EnumDescriptorProto::EnumDescriptorProto() = default;
10981 EnumDescriptorProto::~EnumDescriptorProto() = default;
10982 EnumDescriptorProto::EnumDescriptorProto(const EnumDescriptorProto&) = default;
10983 EnumDescriptorProto& EnumDescriptorProto::operator=(const EnumDescriptorProto&) = default;
10984 EnumDescriptorProto::EnumDescriptorProto(EnumDescriptorProto&&) noexcept = default;
10985 EnumDescriptorProto& EnumDescriptorProto::operator=(EnumDescriptorProto&&) = default;
10986 
operator ==(const EnumDescriptorProto & other) const10987 bool EnumDescriptorProto::operator==(const EnumDescriptorProto& other) const {
10988   return unknown_fields_ == other.unknown_fields_
10989    && name_ == other.name_
10990    && value_ == other.value_
10991    && reserved_name_ == other.reserved_name_;
10992 }
10993 
value_size() const10994 int EnumDescriptorProto::value_size() const { return static_cast<int>(value_.size()); }
clear_value()10995 void EnumDescriptorProto::clear_value() { value_.clear(); }
add_value()10996 EnumValueDescriptorProto* EnumDescriptorProto::add_value() { value_.emplace_back(); return &value_.back(); }
ParseFromArray(const void * raw,size_t size)10997 bool EnumDescriptorProto::ParseFromArray(const void* raw, size_t size) {
10998   value_.clear();
10999   reserved_name_.clear();
11000   unknown_fields_.clear();
11001   bool packed_error = false;
11002 
11003   ::protozero::ProtoDecoder dec(raw, size);
11004   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
11005     if (field.id() < _has_field_.size()) {
11006       _has_field_.set(field.id());
11007     }
11008     switch (field.id()) {
11009       case 1 /* name */:
11010         field.get(&name_);
11011         break;
11012       case 2 /* value */:
11013         value_.emplace_back();
11014         value_.back().ParseFromArray(field.data(), field.size());
11015         break;
11016       case 5 /* reserved_name */:
11017         reserved_name_.emplace_back();
11018         field.get(&reserved_name_.back());
11019         break;
11020       default:
11021         field.SerializeAndAppendTo(&unknown_fields_);
11022         break;
11023     }
11024   }
11025   return !packed_error && !dec.bytes_left();
11026 }
11027 
SerializeAsString() const11028 std::string EnumDescriptorProto::SerializeAsString() const {
11029   ::protozero::HeapBuffered<::protozero::Message> msg;
11030   Serialize(msg.get());
11031   return msg.SerializeAsString();
11032 }
11033 
SerializeAsArray() const11034 std::vector<uint8_t> EnumDescriptorProto::SerializeAsArray() const {
11035   ::protozero::HeapBuffered<::protozero::Message> msg;
11036   Serialize(msg.get());
11037   return msg.SerializeAsArray();
11038 }
11039 
Serialize(::protozero::Message * msg) const11040 void EnumDescriptorProto::Serialize(::protozero::Message* msg) const {
11041   // Field 1: name
11042   if (_has_field_[1]) {
11043     msg->AppendString(1, name_);
11044   }
11045 
11046   // Field 2: value
11047   for (auto& it : value_) {
11048     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
11049   }
11050 
11051   // Field 5: reserved_name
11052   for (auto& it : reserved_name_) {
11053     msg->AppendString(5, it);
11054   }
11055 
11056   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
11057 }
11058 
11059 
11060 OneofDescriptorProto::OneofDescriptorProto() = default;
11061 OneofDescriptorProto::~OneofDescriptorProto() = default;
11062 OneofDescriptorProto::OneofDescriptorProto(const OneofDescriptorProto&) = default;
11063 OneofDescriptorProto& OneofDescriptorProto::operator=(const OneofDescriptorProto&) = default;
11064 OneofDescriptorProto::OneofDescriptorProto(OneofDescriptorProto&&) noexcept = default;
11065 OneofDescriptorProto& OneofDescriptorProto::operator=(OneofDescriptorProto&&) = default;
11066 
operator ==(const OneofDescriptorProto & other) const11067 bool OneofDescriptorProto::operator==(const OneofDescriptorProto& other) const {
11068   return unknown_fields_ == other.unknown_fields_
11069    && name_ == other.name_
11070    && options_ == other.options_;
11071 }
11072 
ParseFromArray(const void * raw,size_t size)11073 bool OneofDescriptorProto::ParseFromArray(const void* raw, size_t size) {
11074   unknown_fields_.clear();
11075   bool packed_error = false;
11076 
11077   ::protozero::ProtoDecoder dec(raw, size);
11078   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
11079     if (field.id() < _has_field_.size()) {
11080       _has_field_.set(field.id());
11081     }
11082     switch (field.id()) {
11083       case 1 /* name */:
11084         field.get(&name_);
11085         break;
11086       case 2 /* options */:
11087         (*options_).ParseFromArray(field.data(), field.size());
11088         break;
11089       default:
11090         field.SerializeAndAppendTo(&unknown_fields_);
11091         break;
11092     }
11093   }
11094   return !packed_error && !dec.bytes_left();
11095 }
11096 
SerializeAsString() const11097 std::string OneofDescriptorProto::SerializeAsString() const {
11098   ::protozero::HeapBuffered<::protozero::Message> msg;
11099   Serialize(msg.get());
11100   return msg.SerializeAsString();
11101 }
11102 
SerializeAsArray() const11103 std::vector<uint8_t> OneofDescriptorProto::SerializeAsArray() const {
11104   ::protozero::HeapBuffered<::protozero::Message> msg;
11105   Serialize(msg.get());
11106   return msg.SerializeAsArray();
11107 }
11108 
Serialize(::protozero::Message * msg) const11109 void OneofDescriptorProto::Serialize(::protozero::Message* msg) const {
11110   // Field 1: name
11111   if (_has_field_[1]) {
11112     msg->AppendString(1, name_);
11113   }
11114 
11115   // Field 2: options
11116   if (_has_field_[2]) {
11117     (*options_).Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
11118   }
11119 
11120   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
11121 }
11122 
11123 
11124 FieldDescriptorProto::FieldDescriptorProto() = default;
11125 FieldDescriptorProto::~FieldDescriptorProto() = default;
11126 FieldDescriptorProto::FieldDescriptorProto(const FieldDescriptorProto&) = default;
11127 FieldDescriptorProto& FieldDescriptorProto::operator=(const FieldDescriptorProto&) = default;
11128 FieldDescriptorProto::FieldDescriptorProto(FieldDescriptorProto&&) noexcept = default;
11129 FieldDescriptorProto& FieldDescriptorProto::operator=(FieldDescriptorProto&&) = default;
11130 
operator ==(const FieldDescriptorProto & other) const11131 bool FieldDescriptorProto::operator==(const FieldDescriptorProto& other) const {
11132   return unknown_fields_ == other.unknown_fields_
11133    && name_ == other.name_
11134    && number_ == other.number_
11135    && label_ == other.label_
11136    && type_ == other.type_
11137    && type_name_ == other.type_name_
11138    && extendee_ == other.extendee_
11139    && default_value_ == other.default_value_
11140    && oneof_index_ == other.oneof_index_;
11141 }
11142 
ParseFromArray(const void * raw,size_t size)11143 bool FieldDescriptorProto::ParseFromArray(const void* raw, size_t size) {
11144   unknown_fields_.clear();
11145   bool packed_error = false;
11146 
11147   ::protozero::ProtoDecoder dec(raw, size);
11148   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
11149     if (field.id() < _has_field_.size()) {
11150       _has_field_.set(field.id());
11151     }
11152     switch (field.id()) {
11153       case 1 /* name */:
11154         field.get(&name_);
11155         break;
11156       case 3 /* number */:
11157         field.get(&number_);
11158         break;
11159       case 4 /* label */:
11160         field.get(&label_);
11161         break;
11162       case 5 /* type */:
11163         field.get(&type_);
11164         break;
11165       case 6 /* type_name */:
11166         field.get(&type_name_);
11167         break;
11168       case 2 /* extendee */:
11169         field.get(&extendee_);
11170         break;
11171       case 7 /* default_value */:
11172         field.get(&default_value_);
11173         break;
11174       case 9 /* oneof_index */:
11175         field.get(&oneof_index_);
11176         break;
11177       default:
11178         field.SerializeAndAppendTo(&unknown_fields_);
11179         break;
11180     }
11181   }
11182   return !packed_error && !dec.bytes_left();
11183 }
11184 
SerializeAsString() const11185 std::string FieldDescriptorProto::SerializeAsString() const {
11186   ::protozero::HeapBuffered<::protozero::Message> msg;
11187   Serialize(msg.get());
11188   return msg.SerializeAsString();
11189 }
11190 
SerializeAsArray() const11191 std::vector<uint8_t> FieldDescriptorProto::SerializeAsArray() const {
11192   ::protozero::HeapBuffered<::protozero::Message> msg;
11193   Serialize(msg.get());
11194   return msg.SerializeAsArray();
11195 }
11196 
Serialize(::protozero::Message * msg) const11197 void FieldDescriptorProto::Serialize(::protozero::Message* msg) const {
11198   // Field 1: name
11199   if (_has_field_[1]) {
11200     msg->AppendString(1, name_);
11201   }
11202 
11203   // Field 3: number
11204   if (_has_field_[3]) {
11205     msg->AppendVarInt(3, number_);
11206   }
11207 
11208   // Field 4: label
11209   if (_has_field_[4]) {
11210     msg->AppendVarInt(4, label_);
11211   }
11212 
11213   // Field 5: type
11214   if (_has_field_[5]) {
11215     msg->AppendVarInt(5, type_);
11216   }
11217 
11218   // Field 6: type_name
11219   if (_has_field_[6]) {
11220     msg->AppendString(6, type_name_);
11221   }
11222 
11223   // Field 2: extendee
11224   if (_has_field_[2]) {
11225     msg->AppendString(2, extendee_);
11226   }
11227 
11228   // Field 7: default_value
11229   if (_has_field_[7]) {
11230     msg->AppendString(7, default_value_);
11231   }
11232 
11233   // Field 9: oneof_index
11234   if (_has_field_[9]) {
11235     msg->AppendVarInt(9, oneof_index_);
11236   }
11237 
11238   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
11239 }
11240 
11241 
11242 DescriptorProto::DescriptorProto() = default;
11243 DescriptorProto::~DescriptorProto() = default;
11244 DescriptorProto::DescriptorProto(const DescriptorProto&) = default;
11245 DescriptorProto& DescriptorProto::operator=(const DescriptorProto&) = default;
11246 DescriptorProto::DescriptorProto(DescriptorProto&&) noexcept = default;
11247 DescriptorProto& DescriptorProto::operator=(DescriptorProto&&) = default;
11248 
operator ==(const DescriptorProto & other) const11249 bool DescriptorProto::operator==(const DescriptorProto& other) const {
11250   return unknown_fields_ == other.unknown_fields_
11251    && name_ == other.name_
11252    && field_ == other.field_
11253    && extension_ == other.extension_
11254    && nested_type_ == other.nested_type_
11255    && enum_type_ == other.enum_type_
11256    && oneof_decl_ == other.oneof_decl_
11257    && reserved_range_ == other.reserved_range_
11258    && reserved_name_ == other.reserved_name_;
11259 }
11260 
field_size() const11261 int DescriptorProto::field_size() const { return static_cast<int>(field_.size()); }
clear_field()11262 void DescriptorProto::clear_field() { field_.clear(); }
add_field()11263 FieldDescriptorProto* DescriptorProto::add_field() { field_.emplace_back(); return &field_.back(); }
extension_size() const11264 int DescriptorProto::extension_size() const { return static_cast<int>(extension_.size()); }
clear_extension()11265 void DescriptorProto::clear_extension() { extension_.clear(); }
add_extension()11266 FieldDescriptorProto* DescriptorProto::add_extension() { extension_.emplace_back(); return &extension_.back(); }
nested_type_size() const11267 int DescriptorProto::nested_type_size() const { return static_cast<int>(nested_type_.size()); }
clear_nested_type()11268 void DescriptorProto::clear_nested_type() { nested_type_.clear(); }
add_nested_type()11269 DescriptorProto* DescriptorProto::add_nested_type() { nested_type_.emplace_back(); return &nested_type_.back(); }
enum_type_size() const11270 int DescriptorProto::enum_type_size() const { return static_cast<int>(enum_type_.size()); }
clear_enum_type()11271 void DescriptorProto::clear_enum_type() { enum_type_.clear(); }
add_enum_type()11272 EnumDescriptorProto* DescriptorProto::add_enum_type() { enum_type_.emplace_back(); return &enum_type_.back(); }
oneof_decl_size() const11273 int DescriptorProto::oneof_decl_size() const { return static_cast<int>(oneof_decl_.size()); }
clear_oneof_decl()11274 void DescriptorProto::clear_oneof_decl() { oneof_decl_.clear(); }
add_oneof_decl()11275 OneofDescriptorProto* DescriptorProto::add_oneof_decl() { oneof_decl_.emplace_back(); return &oneof_decl_.back(); }
reserved_range_size() const11276 int DescriptorProto::reserved_range_size() const { return static_cast<int>(reserved_range_.size()); }
clear_reserved_range()11277 void DescriptorProto::clear_reserved_range() { reserved_range_.clear(); }
add_reserved_range()11278 DescriptorProto_ReservedRange* DescriptorProto::add_reserved_range() { reserved_range_.emplace_back(); return &reserved_range_.back(); }
ParseFromArray(const void * raw,size_t size)11279 bool DescriptorProto::ParseFromArray(const void* raw, size_t size) {
11280   field_.clear();
11281   extension_.clear();
11282   nested_type_.clear();
11283   enum_type_.clear();
11284   oneof_decl_.clear();
11285   reserved_range_.clear();
11286   reserved_name_.clear();
11287   unknown_fields_.clear();
11288   bool packed_error = false;
11289 
11290   ::protozero::ProtoDecoder dec(raw, size);
11291   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
11292     if (field.id() < _has_field_.size()) {
11293       _has_field_.set(field.id());
11294     }
11295     switch (field.id()) {
11296       case 1 /* name */:
11297         field.get(&name_);
11298         break;
11299       case 2 /* field */:
11300         field_.emplace_back();
11301         field_.back().ParseFromArray(field.data(), field.size());
11302         break;
11303       case 6 /* extension */:
11304         extension_.emplace_back();
11305         extension_.back().ParseFromArray(field.data(), field.size());
11306         break;
11307       case 3 /* nested_type */:
11308         nested_type_.emplace_back();
11309         nested_type_.back().ParseFromArray(field.data(), field.size());
11310         break;
11311       case 4 /* enum_type */:
11312         enum_type_.emplace_back();
11313         enum_type_.back().ParseFromArray(field.data(), field.size());
11314         break;
11315       case 8 /* oneof_decl */:
11316         oneof_decl_.emplace_back();
11317         oneof_decl_.back().ParseFromArray(field.data(), field.size());
11318         break;
11319       case 9 /* reserved_range */:
11320         reserved_range_.emplace_back();
11321         reserved_range_.back().ParseFromArray(field.data(), field.size());
11322         break;
11323       case 10 /* reserved_name */:
11324         reserved_name_.emplace_back();
11325         field.get(&reserved_name_.back());
11326         break;
11327       default:
11328         field.SerializeAndAppendTo(&unknown_fields_);
11329         break;
11330     }
11331   }
11332   return !packed_error && !dec.bytes_left();
11333 }
11334 
SerializeAsString() const11335 std::string DescriptorProto::SerializeAsString() const {
11336   ::protozero::HeapBuffered<::protozero::Message> msg;
11337   Serialize(msg.get());
11338   return msg.SerializeAsString();
11339 }
11340 
SerializeAsArray() const11341 std::vector<uint8_t> DescriptorProto::SerializeAsArray() const {
11342   ::protozero::HeapBuffered<::protozero::Message> msg;
11343   Serialize(msg.get());
11344   return msg.SerializeAsArray();
11345 }
11346 
Serialize(::protozero::Message * msg) const11347 void DescriptorProto::Serialize(::protozero::Message* msg) const {
11348   // Field 1: name
11349   if (_has_field_[1]) {
11350     msg->AppendString(1, name_);
11351   }
11352 
11353   // Field 2: field
11354   for (auto& it : field_) {
11355     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
11356   }
11357 
11358   // Field 6: extension
11359   for (auto& it : extension_) {
11360     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
11361   }
11362 
11363   // Field 3: nested_type
11364   for (auto& it : nested_type_) {
11365     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
11366   }
11367 
11368   // Field 4: enum_type
11369   for (auto& it : enum_type_) {
11370     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
11371   }
11372 
11373   // Field 8: oneof_decl
11374   for (auto& it : oneof_decl_) {
11375     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(8));
11376   }
11377 
11378   // Field 9: reserved_range
11379   for (auto& it : reserved_range_) {
11380     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(9));
11381   }
11382 
11383   // Field 10: reserved_name
11384   for (auto& it : reserved_name_) {
11385     msg->AppendString(10, it);
11386   }
11387 
11388   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
11389 }
11390 
11391 
11392 DescriptorProto_ReservedRange::DescriptorProto_ReservedRange() = default;
11393 DescriptorProto_ReservedRange::~DescriptorProto_ReservedRange() = default;
11394 DescriptorProto_ReservedRange::DescriptorProto_ReservedRange(const DescriptorProto_ReservedRange&) = default;
11395 DescriptorProto_ReservedRange& DescriptorProto_ReservedRange::operator=(const DescriptorProto_ReservedRange&) = default;
11396 DescriptorProto_ReservedRange::DescriptorProto_ReservedRange(DescriptorProto_ReservedRange&&) noexcept = default;
11397 DescriptorProto_ReservedRange& DescriptorProto_ReservedRange::operator=(DescriptorProto_ReservedRange&&) = default;
11398 
operator ==(const DescriptorProto_ReservedRange & other) const11399 bool DescriptorProto_ReservedRange::operator==(const DescriptorProto_ReservedRange& other) const {
11400   return unknown_fields_ == other.unknown_fields_
11401    && start_ == other.start_
11402    && end_ == other.end_;
11403 }
11404 
ParseFromArray(const void * raw,size_t size)11405 bool DescriptorProto_ReservedRange::ParseFromArray(const void* raw, size_t size) {
11406   unknown_fields_.clear();
11407   bool packed_error = false;
11408 
11409   ::protozero::ProtoDecoder dec(raw, size);
11410   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
11411     if (field.id() < _has_field_.size()) {
11412       _has_field_.set(field.id());
11413     }
11414     switch (field.id()) {
11415       case 1 /* start */:
11416         field.get(&start_);
11417         break;
11418       case 2 /* end */:
11419         field.get(&end_);
11420         break;
11421       default:
11422         field.SerializeAndAppendTo(&unknown_fields_);
11423         break;
11424     }
11425   }
11426   return !packed_error && !dec.bytes_left();
11427 }
11428 
SerializeAsString() const11429 std::string DescriptorProto_ReservedRange::SerializeAsString() const {
11430   ::protozero::HeapBuffered<::protozero::Message> msg;
11431   Serialize(msg.get());
11432   return msg.SerializeAsString();
11433 }
11434 
SerializeAsArray() const11435 std::vector<uint8_t> DescriptorProto_ReservedRange::SerializeAsArray() const {
11436   ::protozero::HeapBuffered<::protozero::Message> msg;
11437   Serialize(msg.get());
11438   return msg.SerializeAsArray();
11439 }
11440 
Serialize(::protozero::Message * msg) const11441 void DescriptorProto_ReservedRange::Serialize(::protozero::Message* msg) const {
11442   // Field 1: start
11443   if (_has_field_[1]) {
11444     msg->AppendVarInt(1, start_);
11445   }
11446 
11447   // Field 2: end
11448   if (_has_field_[2]) {
11449     msg->AppendVarInt(2, end_);
11450   }
11451 
11452   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
11453 }
11454 
11455 
11456 FileDescriptorProto::FileDescriptorProto() = default;
11457 FileDescriptorProto::~FileDescriptorProto() = default;
11458 FileDescriptorProto::FileDescriptorProto(const FileDescriptorProto&) = default;
11459 FileDescriptorProto& FileDescriptorProto::operator=(const FileDescriptorProto&) = default;
11460 FileDescriptorProto::FileDescriptorProto(FileDescriptorProto&&) noexcept = default;
11461 FileDescriptorProto& FileDescriptorProto::operator=(FileDescriptorProto&&) = default;
11462 
operator ==(const FileDescriptorProto & other) const11463 bool FileDescriptorProto::operator==(const FileDescriptorProto& other) const {
11464   return unknown_fields_ == other.unknown_fields_
11465    && name_ == other.name_
11466    && package_ == other.package_
11467    && dependency_ == other.dependency_
11468    && public_dependency_ == other.public_dependency_
11469    && weak_dependency_ == other.weak_dependency_
11470    && message_type_ == other.message_type_
11471    && enum_type_ == other.enum_type_
11472    && extension_ == other.extension_;
11473 }
11474 
message_type_size() const11475 int FileDescriptorProto::message_type_size() const { return static_cast<int>(message_type_.size()); }
clear_message_type()11476 void FileDescriptorProto::clear_message_type() { message_type_.clear(); }
add_message_type()11477 DescriptorProto* FileDescriptorProto::add_message_type() { message_type_.emplace_back(); return &message_type_.back(); }
enum_type_size() const11478 int FileDescriptorProto::enum_type_size() const { return static_cast<int>(enum_type_.size()); }
clear_enum_type()11479 void FileDescriptorProto::clear_enum_type() { enum_type_.clear(); }
add_enum_type()11480 EnumDescriptorProto* FileDescriptorProto::add_enum_type() { enum_type_.emplace_back(); return &enum_type_.back(); }
extension_size() const11481 int FileDescriptorProto::extension_size() const { return static_cast<int>(extension_.size()); }
clear_extension()11482 void FileDescriptorProto::clear_extension() { extension_.clear(); }
add_extension()11483 FieldDescriptorProto* FileDescriptorProto::add_extension() { extension_.emplace_back(); return &extension_.back(); }
ParseFromArray(const void * raw,size_t size)11484 bool FileDescriptorProto::ParseFromArray(const void* raw, size_t size) {
11485   dependency_.clear();
11486   public_dependency_.clear();
11487   weak_dependency_.clear();
11488   message_type_.clear();
11489   enum_type_.clear();
11490   extension_.clear();
11491   unknown_fields_.clear();
11492   bool packed_error = false;
11493 
11494   ::protozero::ProtoDecoder dec(raw, size);
11495   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
11496     if (field.id() < _has_field_.size()) {
11497       _has_field_.set(field.id());
11498     }
11499     switch (field.id()) {
11500       case 1 /* name */:
11501         field.get(&name_);
11502         break;
11503       case 2 /* package */:
11504         field.get(&package_);
11505         break;
11506       case 3 /* dependency */:
11507         dependency_.emplace_back();
11508         field.get(&dependency_.back());
11509         break;
11510       case 10 /* public_dependency */:
11511         public_dependency_.emplace_back();
11512         field.get(&public_dependency_.back());
11513         break;
11514       case 11 /* weak_dependency */:
11515         weak_dependency_.emplace_back();
11516         field.get(&weak_dependency_.back());
11517         break;
11518       case 4 /* message_type */:
11519         message_type_.emplace_back();
11520         message_type_.back().ParseFromArray(field.data(), field.size());
11521         break;
11522       case 5 /* enum_type */:
11523         enum_type_.emplace_back();
11524         enum_type_.back().ParseFromArray(field.data(), field.size());
11525         break;
11526       case 7 /* extension */:
11527         extension_.emplace_back();
11528         extension_.back().ParseFromArray(field.data(), field.size());
11529         break;
11530       default:
11531         field.SerializeAndAppendTo(&unknown_fields_);
11532         break;
11533     }
11534   }
11535   return !packed_error && !dec.bytes_left();
11536 }
11537 
SerializeAsString() const11538 std::string FileDescriptorProto::SerializeAsString() const {
11539   ::protozero::HeapBuffered<::protozero::Message> msg;
11540   Serialize(msg.get());
11541   return msg.SerializeAsString();
11542 }
11543 
SerializeAsArray() const11544 std::vector<uint8_t> FileDescriptorProto::SerializeAsArray() const {
11545   ::protozero::HeapBuffered<::protozero::Message> msg;
11546   Serialize(msg.get());
11547   return msg.SerializeAsArray();
11548 }
11549 
Serialize(::protozero::Message * msg) const11550 void FileDescriptorProto::Serialize(::protozero::Message* msg) const {
11551   // Field 1: name
11552   if (_has_field_[1]) {
11553     msg->AppendString(1, name_);
11554   }
11555 
11556   // Field 2: package
11557   if (_has_field_[2]) {
11558     msg->AppendString(2, package_);
11559   }
11560 
11561   // Field 3: dependency
11562   for (auto& it : dependency_) {
11563     msg->AppendString(3, it);
11564   }
11565 
11566   // Field 10: public_dependency
11567   for (auto& it : public_dependency_) {
11568     msg->AppendVarInt(10, it);
11569   }
11570 
11571   // Field 11: weak_dependency
11572   for (auto& it : weak_dependency_) {
11573     msg->AppendVarInt(11, it);
11574   }
11575 
11576   // Field 4: message_type
11577   for (auto& it : message_type_) {
11578     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
11579   }
11580 
11581   // Field 5: enum_type
11582   for (auto& it : enum_type_) {
11583     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(5));
11584   }
11585 
11586   // Field 7: extension
11587   for (auto& it : extension_) {
11588     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(7));
11589   }
11590 
11591   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
11592 }
11593 
11594 
11595 FileDescriptorSet::FileDescriptorSet() = default;
11596 FileDescriptorSet::~FileDescriptorSet() = default;
11597 FileDescriptorSet::FileDescriptorSet(const FileDescriptorSet&) = default;
11598 FileDescriptorSet& FileDescriptorSet::operator=(const FileDescriptorSet&) = default;
11599 FileDescriptorSet::FileDescriptorSet(FileDescriptorSet&&) noexcept = default;
11600 FileDescriptorSet& FileDescriptorSet::operator=(FileDescriptorSet&&) = default;
11601 
operator ==(const FileDescriptorSet & other) const11602 bool FileDescriptorSet::operator==(const FileDescriptorSet& other) const {
11603   return unknown_fields_ == other.unknown_fields_
11604    && file_ == other.file_;
11605 }
11606 
file_size() const11607 int FileDescriptorSet::file_size() const { return static_cast<int>(file_.size()); }
clear_file()11608 void FileDescriptorSet::clear_file() { file_.clear(); }
add_file()11609 FileDescriptorProto* FileDescriptorSet::add_file() { file_.emplace_back(); return &file_.back(); }
ParseFromArray(const void * raw,size_t size)11610 bool FileDescriptorSet::ParseFromArray(const void* raw, size_t size) {
11611   file_.clear();
11612   unknown_fields_.clear();
11613   bool packed_error = false;
11614 
11615   ::protozero::ProtoDecoder dec(raw, size);
11616   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
11617     if (field.id() < _has_field_.size()) {
11618       _has_field_.set(field.id());
11619     }
11620     switch (field.id()) {
11621       case 1 /* file */:
11622         file_.emplace_back();
11623         file_.back().ParseFromArray(field.data(), field.size());
11624         break;
11625       default:
11626         field.SerializeAndAppendTo(&unknown_fields_);
11627         break;
11628     }
11629   }
11630   return !packed_error && !dec.bytes_left();
11631 }
11632 
SerializeAsString() const11633 std::string FileDescriptorSet::SerializeAsString() const {
11634   ::protozero::HeapBuffered<::protozero::Message> msg;
11635   Serialize(msg.get());
11636   return msg.SerializeAsString();
11637 }
11638 
SerializeAsArray() const11639 std::vector<uint8_t> FileDescriptorSet::SerializeAsArray() const {
11640   ::protozero::HeapBuffered<::protozero::Message> msg;
11641   Serialize(msg.get());
11642   return msg.SerializeAsArray();
11643 }
11644 
Serialize(::protozero::Message * msg) const11645 void FileDescriptorSet::Serialize(::protozero::Message* msg) const {
11646   // Field 1: file
11647   for (auto& it : file_) {
11648     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
11649   }
11650 
11651   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
11652 }
11653 
11654 }  // namespace perfetto
11655 }  // namespace protos
11656 }  // namespace gen
11657 #if defined(__GNUC__) || defined(__clang__)
11658 #pragma GCC diagnostic pop
11659 #endif
11660 // gen_amalgamated begin source: gen/protos/perfetto/common/gpu_counter_descriptor.gen.cc
11661 // gen_amalgamated begin header: gen/protos/perfetto/common/gpu_counter_descriptor.gen.h
11662 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
11663 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_GPU_COUNTER_DESCRIPTOR_PROTO_CPP_H_
11664 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_GPU_COUNTER_DESCRIPTOR_PROTO_CPP_H_
11665 
11666 #include <stdint.h>
11667 #include <bitset>
11668 #include <vector>
11669 #include <string>
11670 #include <type_traits>
11671 
11672 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
11673 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
11674 // gen_amalgamated expanded: #include "perfetto/base/export.h"
11675 
11676 namespace perfetto {
11677 namespace protos {
11678 namespace gen {
11679 class GpuCounterDescriptor;
11680 class GpuCounterDescriptor_GpuCounterBlock;
11681 class GpuCounterDescriptor_GpuCounterSpec;
11682 enum GpuCounterDescriptor_GpuCounterGroup : int;
11683 enum GpuCounterDescriptor_MeasureUnit : int;
11684 }  // namespace perfetto
11685 }  // namespace protos
11686 }  // namespace gen
11687 
11688 namespace protozero {
11689 class Message;
11690 }  // namespace protozero
11691 
11692 namespace perfetto {
11693 namespace protos {
11694 namespace gen {
11695 enum GpuCounterDescriptor_GpuCounterGroup : int {
11696   GpuCounterDescriptor_GpuCounterGroup_UNCLASSIFIED = 0,
11697   GpuCounterDescriptor_GpuCounterGroup_SYSTEM = 1,
11698   GpuCounterDescriptor_GpuCounterGroup_VERTICES = 2,
11699   GpuCounterDescriptor_GpuCounterGroup_FRAGMENTS = 3,
11700   GpuCounterDescriptor_GpuCounterGroup_PRIMITIVES = 4,
11701   GpuCounterDescriptor_GpuCounterGroup_MEMORY = 5,
11702   GpuCounterDescriptor_GpuCounterGroup_COMPUTE = 6,
11703 };
11704 enum GpuCounterDescriptor_MeasureUnit : int {
11705   GpuCounterDescriptor_MeasureUnit_NONE = 0,
11706   GpuCounterDescriptor_MeasureUnit_BIT = 1,
11707   GpuCounterDescriptor_MeasureUnit_KILOBIT = 2,
11708   GpuCounterDescriptor_MeasureUnit_MEGABIT = 3,
11709   GpuCounterDescriptor_MeasureUnit_GIGABIT = 4,
11710   GpuCounterDescriptor_MeasureUnit_TERABIT = 5,
11711   GpuCounterDescriptor_MeasureUnit_PETABIT = 6,
11712   GpuCounterDescriptor_MeasureUnit_BYTE = 7,
11713   GpuCounterDescriptor_MeasureUnit_KILOBYTE = 8,
11714   GpuCounterDescriptor_MeasureUnit_MEGABYTE = 9,
11715   GpuCounterDescriptor_MeasureUnit_GIGABYTE = 10,
11716   GpuCounterDescriptor_MeasureUnit_TERABYTE = 11,
11717   GpuCounterDescriptor_MeasureUnit_PETABYTE = 12,
11718   GpuCounterDescriptor_MeasureUnit_HERTZ = 13,
11719   GpuCounterDescriptor_MeasureUnit_KILOHERTZ = 14,
11720   GpuCounterDescriptor_MeasureUnit_MEGAHERTZ = 15,
11721   GpuCounterDescriptor_MeasureUnit_GIGAHERTZ = 16,
11722   GpuCounterDescriptor_MeasureUnit_TERAHERTZ = 17,
11723   GpuCounterDescriptor_MeasureUnit_PETAHERTZ = 18,
11724   GpuCounterDescriptor_MeasureUnit_NANOSECOND = 19,
11725   GpuCounterDescriptor_MeasureUnit_MICROSECOND = 20,
11726   GpuCounterDescriptor_MeasureUnit_MILLISECOND = 21,
11727   GpuCounterDescriptor_MeasureUnit_SECOND = 22,
11728   GpuCounterDescriptor_MeasureUnit_MINUTE = 23,
11729   GpuCounterDescriptor_MeasureUnit_HOUR = 24,
11730   GpuCounterDescriptor_MeasureUnit_VERTEX = 25,
11731   GpuCounterDescriptor_MeasureUnit_PIXEL = 26,
11732   GpuCounterDescriptor_MeasureUnit_TRIANGLE = 27,
11733   GpuCounterDescriptor_MeasureUnit_PRIMITIVE = 38,
11734   GpuCounterDescriptor_MeasureUnit_FRAGMENT = 39,
11735   GpuCounterDescriptor_MeasureUnit_MILLIWATT = 28,
11736   GpuCounterDescriptor_MeasureUnit_WATT = 29,
11737   GpuCounterDescriptor_MeasureUnit_KILOWATT = 30,
11738   GpuCounterDescriptor_MeasureUnit_JOULE = 31,
11739   GpuCounterDescriptor_MeasureUnit_VOLT = 32,
11740   GpuCounterDescriptor_MeasureUnit_AMPERE = 33,
11741   GpuCounterDescriptor_MeasureUnit_CELSIUS = 34,
11742   GpuCounterDescriptor_MeasureUnit_FAHRENHEIT = 35,
11743   GpuCounterDescriptor_MeasureUnit_KELVIN = 36,
11744   GpuCounterDescriptor_MeasureUnit_PERCENT = 37,
11745   GpuCounterDescriptor_MeasureUnit_INSTRUCTION = 40,
11746 };
11747 
11748 class PERFETTO_EXPORT GpuCounterDescriptor : public ::protozero::CppMessageObj {
11749  public:
11750   using GpuCounterSpec = GpuCounterDescriptor_GpuCounterSpec;
11751   using GpuCounterBlock = GpuCounterDescriptor_GpuCounterBlock;
11752   using GpuCounterGroup = GpuCounterDescriptor_GpuCounterGroup;
11753   static constexpr auto UNCLASSIFIED = GpuCounterDescriptor_GpuCounterGroup_UNCLASSIFIED;
11754   static constexpr auto SYSTEM = GpuCounterDescriptor_GpuCounterGroup_SYSTEM;
11755   static constexpr auto VERTICES = GpuCounterDescriptor_GpuCounterGroup_VERTICES;
11756   static constexpr auto FRAGMENTS = GpuCounterDescriptor_GpuCounterGroup_FRAGMENTS;
11757   static constexpr auto PRIMITIVES = GpuCounterDescriptor_GpuCounterGroup_PRIMITIVES;
11758   static constexpr auto MEMORY = GpuCounterDescriptor_GpuCounterGroup_MEMORY;
11759   static constexpr auto COMPUTE = GpuCounterDescriptor_GpuCounterGroup_COMPUTE;
11760   static constexpr auto GpuCounterGroup_MIN = GpuCounterDescriptor_GpuCounterGroup_UNCLASSIFIED;
11761   static constexpr auto GpuCounterGroup_MAX = GpuCounterDescriptor_GpuCounterGroup_COMPUTE;
11762   using MeasureUnit = GpuCounterDescriptor_MeasureUnit;
11763   static constexpr auto NONE = GpuCounterDescriptor_MeasureUnit_NONE;
11764   static constexpr auto BIT = GpuCounterDescriptor_MeasureUnit_BIT;
11765   static constexpr auto KILOBIT = GpuCounterDescriptor_MeasureUnit_KILOBIT;
11766   static constexpr auto MEGABIT = GpuCounterDescriptor_MeasureUnit_MEGABIT;
11767   static constexpr auto GIGABIT = GpuCounterDescriptor_MeasureUnit_GIGABIT;
11768   static constexpr auto TERABIT = GpuCounterDescriptor_MeasureUnit_TERABIT;
11769   static constexpr auto PETABIT = GpuCounterDescriptor_MeasureUnit_PETABIT;
11770   static constexpr auto BYTE = GpuCounterDescriptor_MeasureUnit_BYTE;
11771   static constexpr auto KILOBYTE = GpuCounterDescriptor_MeasureUnit_KILOBYTE;
11772   static constexpr auto MEGABYTE = GpuCounterDescriptor_MeasureUnit_MEGABYTE;
11773   static constexpr auto GIGABYTE = GpuCounterDescriptor_MeasureUnit_GIGABYTE;
11774   static constexpr auto TERABYTE = GpuCounterDescriptor_MeasureUnit_TERABYTE;
11775   static constexpr auto PETABYTE = GpuCounterDescriptor_MeasureUnit_PETABYTE;
11776   static constexpr auto HERTZ = GpuCounterDescriptor_MeasureUnit_HERTZ;
11777   static constexpr auto KILOHERTZ = GpuCounterDescriptor_MeasureUnit_KILOHERTZ;
11778   static constexpr auto MEGAHERTZ = GpuCounterDescriptor_MeasureUnit_MEGAHERTZ;
11779   static constexpr auto GIGAHERTZ = GpuCounterDescriptor_MeasureUnit_GIGAHERTZ;
11780   static constexpr auto TERAHERTZ = GpuCounterDescriptor_MeasureUnit_TERAHERTZ;
11781   static constexpr auto PETAHERTZ = GpuCounterDescriptor_MeasureUnit_PETAHERTZ;
11782   static constexpr auto NANOSECOND = GpuCounterDescriptor_MeasureUnit_NANOSECOND;
11783   static constexpr auto MICROSECOND = GpuCounterDescriptor_MeasureUnit_MICROSECOND;
11784   static constexpr auto MILLISECOND = GpuCounterDescriptor_MeasureUnit_MILLISECOND;
11785   static constexpr auto SECOND = GpuCounterDescriptor_MeasureUnit_SECOND;
11786   static constexpr auto MINUTE = GpuCounterDescriptor_MeasureUnit_MINUTE;
11787   static constexpr auto HOUR = GpuCounterDescriptor_MeasureUnit_HOUR;
11788   static constexpr auto VERTEX = GpuCounterDescriptor_MeasureUnit_VERTEX;
11789   static constexpr auto PIXEL = GpuCounterDescriptor_MeasureUnit_PIXEL;
11790   static constexpr auto TRIANGLE = GpuCounterDescriptor_MeasureUnit_TRIANGLE;
11791   static constexpr auto PRIMITIVE = GpuCounterDescriptor_MeasureUnit_PRIMITIVE;
11792   static constexpr auto FRAGMENT = GpuCounterDescriptor_MeasureUnit_FRAGMENT;
11793   static constexpr auto MILLIWATT = GpuCounterDescriptor_MeasureUnit_MILLIWATT;
11794   static constexpr auto WATT = GpuCounterDescriptor_MeasureUnit_WATT;
11795   static constexpr auto KILOWATT = GpuCounterDescriptor_MeasureUnit_KILOWATT;
11796   static constexpr auto JOULE = GpuCounterDescriptor_MeasureUnit_JOULE;
11797   static constexpr auto VOLT = GpuCounterDescriptor_MeasureUnit_VOLT;
11798   static constexpr auto AMPERE = GpuCounterDescriptor_MeasureUnit_AMPERE;
11799   static constexpr auto CELSIUS = GpuCounterDescriptor_MeasureUnit_CELSIUS;
11800   static constexpr auto FAHRENHEIT = GpuCounterDescriptor_MeasureUnit_FAHRENHEIT;
11801   static constexpr auto KELVIN = GpuCounterDescriptor_MeasureUnit_KELVIN;
11802   static constexpr auto PERCENT = GpuCounterDescriptor_MeasureUnit_PERCENT;
11803   static constexpr auto INSTRUCTION = GpuCounterDescriptor_MeasureUnit_INSTRUCTION;
11804   static constexpr auto MeasureUnit_MIN = GpuCounterDescriptor_MeasureUnit_NONE;
11805   static constexpr auto MeasureUnit_MAX = GpuCounterDescriptor_MeasureUnit_INSTRUCTION;
11806   enum FieldNumbers {
11807     kSpecsFieldNumber = 1,
11808     kBlocksFieldNumber = 2,
11809     kMinSamplingPeriodNsFieldNumber = 3,
11810     kMaxSamplingPeriodNsFieldNumber = 4,
11811     kSupportsInstrumentedSamplingFieldNumber = 5,
11812   };
11813 
11814   GpuCounterDescriptor();
11815   ~GpuCounterDescriptor() override;
11816   GpuCounterDescriptor(GpuCounterDescriptor&&) noexcept;
11817   GpuCounterDescriptor& operator=(GpuCounterDescriptor&&);
11818   GpuCounterDescriptor(const GpuCounterDescriptor&);
11819   GpuCounterDescriptor& operator=(const GpuCounterDescriptor&);
11820   bool operator==(const GpuCounterDescriptor&) const;
operator !=(const GpuCounterDescriptor & other) const11821   bool operator!=(const GpuCounterDescriptor& other) const { return !(*this == other); }
11822 
11823   bool ParseFromArray(const void*, size_t) override;
11824   std::string SerializeAsString() const override;
11825   std::vector<uint8_t> SerializeAsArray() const override;
11826   void Serialize(::protozero::Message*) const;
11827 
specs() const11828   const std::vector<GpuCounterDescriptor_GpuCounterSpec>& specs() const { return specs_; }
mutable_specs()11829   std::vector<GpuCounterDescriptor_GpuCounterSpec>* mutable_specs() { return &specs_; }
11830   int specs_size() const;
11831   void clear_specs();
11832   GpuCounterDescriptor_GpuCounterSpec* add_specs();
11833 
blocks() const11834   const std::vector<GpuCounterDescriptor_GpuCounterBlock>& blocks() const { return blocks_; }
mutable_blocks()11835   std::vector<GpuCounterDescriptor_GpuCounterBlock>* mutable_blocks() { return &blocks_; }
11836   int blocks_size() const;
11837   void clear_blocks();
11838   GpuCounterDescriptor_GpuCounterBlock* add_blocks();
11839 
has_min_sampling_period_ns() const11840   bool has_min_sampling_period_ns() const { return _has_field_[3]; }
min_sampling_period_ns() const11841   uint64_t min_sampling_period_ns() const { return min_sampling_period_ns_; }
set_min_sampling_period_ns(uint64_t value)11842   void set_min_sampling_period_ns(uint64_t value) { min_sampling_period_ns_ = value; _has_field_.set(3); }
11843 
has_max_sampling_period_ns() const11844   bool has_max_sampling_period_ns() const { return _has_field_[4]; }
max_sampling_period_ns() const11845   uint64_t max_sampling_period_ns() const { return max_sampling_period_ns_; }
set_max_sampling_period_ns(uint64_t value)11846   void set_max_sampling_period_ns(uint64_t value) { max_sampling_period_ns_ = value; _has_field_.set(4); }
11847 
has_supports_instrumented_sampling() const11848   bool has_supports_instrumented_sampling() const { return _has_field_[5]; }
supports_instrumented_sampling() const11849   bool supports_instrumented_sampling() const { return supports_instrumented_sampling_; }
set_supports_instrumented_sampling(bool value)11850   void set_supports_instrumented_sampling(bool value) { supports_instrumented_sampling_ = value; _has_field_.set(5); }
11851 
11852  private:
11853   std::vector<GpuCounterDescriptor_GpuCounterSpec> specs_;
11854   std::vector<GpuCounterDescriptor_GpuCounterBlock> blocks_;
11855   uint64_t min_sampling_period_ns_{};
11856   uint64_t max_sampling_period_ns_{};
11857   bool supports_instrumented_sampling_{};
11858 
11859   // Allows to preserve unknown protobuf fields for compatibility
11860   // with future versions of .proto files.
11861   std::string unknown_fields_;
11862 
11863   std::bitset<6> _has_field_{};
11864 };
11865 
11866 
11867 class PERFETTO_EXPORT GpuCounterDescriptor_GpuCounterBlock : public ::protozero::CppMessageObj {
11868  public:
11869   enum FieldNumbers {
11870     kBlockIdFieldNumber = 1,
11871     kBlockCapacityFieldNumber = 2,
11872     kNameFieldNumber = 3,
11873     kDescriptionFieldNumber = 4,
11874     kCounterIdsFieldNumber = 5,
11875   };
11876 
11877   GpuCounterDescriptor_GpuCounterBlock();
11878   ~GpuCounterDescriptor_GpuCounterBlock() override;
11879   GpuCounterDescriptor_GpuCounterBlock(GpuCounterDescriptor_GpuCounterBlock&&) noexcept;
11880   GpuCounterDescriptor_GpuCounterBlock& operator=(GpuCounterDescriptor_GpuCounterBlock&&);
11881   GpuCounterDescriptor_GpuCounterBlock(const GpuCounterDescriptor_GpuCounterBlock&);
11882   GpuCounterDescriptor_GpuCounterBlock& operator=(const GpuCounterDescriptor_GpuCounterBlock&);
11883   bool operator==(const GpuCounterDescriptor_GpuCounterBlock&) const;
operator !=(const GpuCounterDescriptor_GpuCounterBlock & other) const11884   bool operator!=(const GpuCounterDescriptor_GpuCounterBlock& other) const { return !(*this == other); }
11885 
11886   bool ParseFromArray(const void*, size_t) override;
11887   std::string SerializeAsString() const override;
11888   std::vector<uint8_t> SerializeAsArray() const override;
11889   void Serialize(::protozero::Message*) const;
11890 
has_block_id() const11891   bool has_block_id() const { return _has_field_[1]; }
block_id() const11892   uint32_t block_id() const { return block_id_; }
set_block_id(uint32_t value)11893   void set_block_id(uint32_t value) { block_id_ = value; _has_field_.set(1); }
11894 
has_block_capacity() const11895   bool has_block_capacity() const { return _has_field_[2]; }
block_capacity() const11896   uint32_t block_capacity() const { return block_capacity_; }
set_block_capacity(uint32_t value)11897   void set_block_capacity(uint32_t value) { block_capacity_ = value; _has_field_.set(2); }
11898 
has_name() const11899   bool has_name() const { return _has_field_[3]; }
name() const11900   const std::string& name() const { return name_; }
set_name(const std::string & value)11901   void set_name(const std::string& value) { name_ = value; _has_field_.set(3); }
11902 
has_description() const11903   bool has_description() const { return _has_field_[4]; }
description() const11904   const std::string& description() const { return description_; }
set_description(const std::string & value)11905   void set_description(const std::string& value) { description_ = value; _has_field_.set(4); }
11906 
counter_ids() const11907   const std::vector<uint32_t>& counter_ids() const { return counter_ids_; }
mutable_counter_ids()11908   std::vector<uint32_t>* mutable_counter_ids() { return &counter_ids_; }
counter_ids_size() const11909   int counter_ids_size() const { return static_cast<int>(counter_ids_.size()); }
clear_counter_ids()11910   void clear_counter_ids() { counter_ids_.clear(); }
add_counter_ids(uint32_t value)11911   void add_counter_ids(uint32_t value) { counter_ids_.emplace_back(value); }
add_counter_ids()11912   uint32_t* add_counter_ids() { counter_ids_.emplace_back(); return &counter_ids_.back(); }
11913 
11914  private:
11915   uint32_t block_id_{};
11916   uint32_t block_capacity_{};
11917   std::string name_{};
11918   std::string description_{};
11919   std::vector<uint32_t> counter_ids_;
11920 
11921   // Allows to preserve unknown protobuf fields for compatibility
11922   // with future versions of .proto files.
11923   std::string unknown_fields_;
11924 
11925   std::bitset<6> _has_field_{};
11926 };
11927 
11928 
11929 class PERFETTO_EXPORT GpuCounterDescriptor_GpuCounterSpec : public ::protozero::CppMessageObj {
11930  public:
11931   enum FieldNumbers {
11932     kCounterIdFieldNumber = 1,
11933     kNameFieldNumber = 2,
11934     kDescriptionFieldNumber = 3,
11935     kIntPeakValueFieldNumber = 5,
11936     kDoublePeakValueFieldNumber = 6,
11937     kNumeratorUnitsFieldNumber = 7,
11938     kDenominatorUnitsFieldNumber = 8,
11939     kSelectByDefaultFieldNumber = 9,
11940     kGroupsFieldNumber = 10,
11941   };
11942 
11943   GpuCounterDescriptor_GpuCounterSpec();
11944   ~GpuCounterDescriptor_GpuCounterSpec() override;
11945   GpuCounterDescriptor_GpuCounterSpec(GpuCounterDescriptor_GpuCounterSpec&&) noexcept;
11946   GpuCounterDescriptor_GpuCounterSpec& operator=(GpuCounterDescriptor_GpuCounterSpec&&);
11947   GpuCounterDescriptor_GpuCounterSpec(const GpuCounterDescriptor_GpuCounterSpec&);
11948   GpuCounterDescriptor_GpuCounterSpec& operator=(const GpuCounterDescriptor_GpuCounterSpec&);
11949   bool operator==(const GpuCounterDescriptor_GpuCounterSpec&) const;
operator !=(const GpuCounterDescriptor_GpuCounterSpec & other) const11950   bool operator!=(const GpuCounterDescriptor_GpuCounterSpec& other) const { return !(*this == other); }
11951 
11952   bool ParseFromArray(const void*, size_t) override;
11953   std::string SerializeAsString() const override;
11954   std::vector<uint8_t> SerializeAsArray() const override;
11955   void Serialize(::protozero::Message*) const;
11956 
has_counter_id() const11957   bool has_counter_id() const { return _has_field_[1]; }
counter_id() const11958   uint32_t counter_id() const { return counter_id_; }
set_counter_id(uint32_t value)11959   void set_counter_id(uint32_t value) { counter_id_ = value; _has_field_.set(1); }
11960 
has_name() const11961   bool has_name() const { return _has_field_[2]; }
name() const11962   const std::string& name() const { return name_; }
set_name(const std::string & value)11963   void set_name(const std::string& value) { name_ = value; _has_field_.set(2); }
11964 
has_description() const11965   bool has_description() const { return _has_field_[3]; }
description() const11966   const std::string& description() const { return description_; }
set_description(const std::string & value)11967   void set_description(const std::string& value) { description_ = value; _has_field_.set(3); }
11968 
has_int_peak_value() const11969   bool has_int_peak_value() const { return _has_field_[5]; }
int_peak_value() const11970   int64_t int_peak_value() const { return int_peak_value_; }
set_int_peak_value(int64_t value)11971   void set_int_peak_value(int64_t value) { int_peak_value_ = value; _has_field_.set(5); }
11972 
has_double_peak_value() const11973   bool has_double_peak_value() const { return _has_field_[6]; }
double_peak_value() const11974   double double_peak_value() const { return double_peak_value_; }
set_double_peak_value(double value)11975   void set_double_peak_value(double value) { double_peak_value_ = value; _has_field_.set(6); }
11976 
numerator_units() const11977   const std::vector<GpuCounterDescriptor_MeasureUnit>& numerator_units() const { return numerator_units_; }
mutable_numerator_units()11978   std::vector<GpuCounterDescriptor_MeasureUnit>* mutable_numerator_units() { return &numerator_units_; }
numerator_units_size() const11979   int numerator_units_size() const { return static_cast<int>(numerator_units_.size()); }
clear_numerator_units()11980   void clear_numerator_units() { numerator_units_.clear(); }
add_numerator_units(GpuCounterDescriptor_MeasureUnit value)11981   void add_numerator_units(GpuCounterDescriptor_MeasureUnit value) { numerator_units_.emplace_back(value); }
add_numerator_units()11982   GpuCounterDescriptor_MeasureUnit* add_numerator_units() { numerator_units_.emplace_back(); return &numerator_units_.back(); }
11983 
denominator_units() const11984   const std::vector<GpuCounterDescriptor_MeasureUnit>& denominator_units() const { return denominator_units_; }
mutable_denominator_units()11985   std::vector<GpuCounterDescriptor_MeasureUnit>* mutable_denominator_units() { return &denominator_units_; }
denominator_units_size() const11986   int denominator_units_size() const { return static_cast<int>(denominator_units_.size()); }
clear_denominator_units()11987   void clear_denominator_units() { denominator_units_.clear(); }
add_denominator_units(GpuCounterDescriptor_MeasureUnit value)11988   void add_denominator_units(GpuCounterDescriptor_MeasureUnit value) { denominator_units_.emplace_back(value); }
add_denominator_units()11989   GpuCounterDescriptor_MeasureUnit* add_denominator_units() { denominator_units_.emplace_back(); return &denominator_units_.back(); }
11990 
has_select_by_default() const11991   bool has_select_by_default() const { return _has_field_[9]; }
select_by_default() const11992   bool select_by_default() const { return select_by_default_; }
set_select_by_default(bool value)11993   void set_select_by_default(bool value) { select_by_default_ = value; _has_field_.set(9); }
11994 
groups() const11995   const std::vector<GpuCounterDescriptor_GpuCounterGroup>& groups() const { return groups_; }
mutable_groups()11996   std::vector<GpuCounterDescriptor_GpuCounterGroup>* mutable_groups() { return &groups_; }
groups_size() const11997   int groups_size() const { return static_cast<int>(groups_.size()); }
clear_groups()11998   void clear_groups() { groups_.clear(); }
add_groups(GpuCounterDescriptor_GpuCounterGroup value)11999   void add_groups(GpuCounterDescriptor_GpuCounterGroup value) { groups_.emplace_back(value); }
add_groups()12000   GpuCounterDescriptor_GpuCounterGroup* add_groups() { groups_.emplace_back(); return &groups_.back(); }
12001 
12002  private:
12003   uint32_t counter_id_{};
12004   std::string name_{};
12005   std::string description_{};
12006   int64_t int_peak_value_{};
12007   double double_peak_value_{};
12008   std::vector<GpuCounterDescriptor_MeasureUnit> numerator_units_;
12009   std::vector<GpuCounterDescriptor_MeasureUnit> denominator_units_;
12010   bool select_by_default_{};
12011   std::vector<GpuCounterDescriptor_GpuCounterGroup> groups_;
12012 
12013   // Allows to preserve unknown protobuf fields for compatibility
12014   // with future versions of .proto files.
12015   std::string unknown_fields_;
12016 
12017   std::bitset<11> _has_field_{};
12018 };
12019 
12020 }  // namespace perfetto
12021 }  // namespace protos
12022 }  // namespace gen
12023 
12024 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_GPU_COUNTER_DESCRIPTOR_PROTO_CPP_H_
12025 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
12026 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
12027 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
12028 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
12029 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
12030 #if defined(__GNUC__) || defined(__clang__)
12031 #pragma GCC diagnostic push
12032 #pragma GCC diagnostic ignored "-Wfloat-equal"
12033 #endif
12034 // gen_amalgamated expanded: #include "protos/perfetto/common/gpu_counter_descriptor.gen.h"
12035 
12036 namespace perfetto {
12037 namespace protos {
12038 namespace gen {
12039 
12040 GpuCounterDescriptor::GpuCounterDescriptor() = default;
12041 GpuCounterDescriptor::~GpuCounterDescriptor() = default;
12042 GpuCounterDescriptor::GpuCounterDescriptor(const GpuCounterDescriptor&) = default;
12043 GpuCounterDescriptor& GpuCounterDescriptor::operator=(const GpuCounterDescriptor&) = default;
12044 GpuCounterDescriptor::GpuCounterDescriptor(GpuCounterDescriptor&&) noexcept = default;
12045 GpuCounterDescriptor& GpuCounterDescriptor::operator=(GpuCounterDescriptor&&) = default;
12046 
operator ==(const GpuCounterDescriptor & other) const12047 bool GpuCounterDescriptor::operator==(const GpuCounterDescriptor& other) const {
12048   return unknown_fields_ == other.unknown_fields_
12049    && specs_ == other.specs_
12050    && blocks_ == other.blocks_
12051    && min_sampling_period_ns_ == other.min_sampling_period_ns_
12052    && max_sampling_period_ns_ == other.max_sampling_period_ns_
12053    && supports_instrumented_sampling_ == other.supports_instrumented_sampling_;
12054 }
12055 
specs_size() const12056 int GpuCounterDescriptor::specs_size() const { return static_cast<int>(specs_.size()); }
clear_specs()12057 void GpuCounterDescriptor::clear_specs() { specs_.clear(); }
add_specs()12058 GpuCounterDescriptor_GpuCounterSpec* GpuCounterDescriptor::add_specs() { specs_.emplace_back(); return &specs_.back(); }
blocks_size() const12059 int GpuCounterDescriptor::blocks_size() const { return static_cast<int>(blocks_.size()); }
clear_blocks()12060 void GpuCounterDescriptor::clear_blocks() { blocks_.clear(); }
add_blocks()12061 GpuCounterDescriptor_GpuCounterBlock* GpuCounterDescriptor::add_blocks() { blocks_.emplace_back(); return &blocks_.back(); }
ParseFromArray(const void * raw,size_t size)12062 bool GpuCounterDescriptor::ParseFromArray(const void* raw, size_t size) {
12063   specs_.clear();
12064   blocks_.clear();
12065   unknown_fields_.clear();
12066   bool packed_error = false;
12067 
12068   ::protozero::ProtoDecoder dec(raw, size);
12069   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
12070     if (field.id() < _has_field_.size()) {
12071       _has_field_.set(field.id());
12072     }
12073     switch (field.id()) {
12074       case 1 /* specs */:
12075         specs_.emplace_back();
12076         specs_.back().ParseFromArray(field.data(), field.size());
12077         break;
12078       case 2 /* blocks */:
12079         blocks_.emplace_back();
12080         blocks_.back().ParseFromArray(field.data(), field.size());
12081         break;
12082       case 3 /* min_sampling_period_ns */:
12083         field.get(&min_sampling_period_ns_);
12084         break;
12085       case 4 /* max_sampling_period_ns */:
12086         field.get(&max_sampling_period_ns_);
12087         break;
12088       case 5 /* supports_instrumented_sampling */:
12089         field.get(&supports_instrumented_sampling_);
12090         break;
12091       default:
12092         field.SerializeAndAppendTo(&unknown_fields_);
12093         break;
12094     }
12095   }
12096   return !packed_error && !dec.bytes_left();
12097 }
12098 
SerializeAsString() const12099 std::string GpuCounterDescriptor::SerializeAsString() const {
12100   ::protozero::HeapBuffered<::protozero::Message> msg;
12101   Serialize(msg.get());
12102   return msg.SerializeAsString();
12103 }
12104 
SerializeAsArray() const12105 std::vector<uint8_t> GpuCounterDescriptor::SerializeAsArray() const {
12106   ::protozero::HeapBuffered<::protozero::Message> msg;
12107   Serialize(msg.get());
12108   return msg.SerializeAsArray();
12109 }
12110 
Serialize(::protozero::Message * msg) const12111 void GpuCounterDescriptor::Serialize(::protozero::Message* msg) const {
12112   // Field 1: specs
12113   for (auto& it : specs_) {
12114     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
12115   }
12116 
12117   // Field 2: blocks
12118   for (auto& it : blocks_) {
12119     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
12120   }
12121 
12122   // Field 3: min_sampling_period_ns
12123   if (_has_field_[3]) {
12124     msg->AppendVarInt(3, min_sampling_period_ns_);
12125   }
12126 
12127   // Field 4: max_sampling_period_ns
12128   if (_has_field_[4]) {
12129     msg->AppendVarInt(4, max_sampling_period_ns_);
12130   }
12131 
12132   // Field 5: supports_instrumented_sampling
12133   if (_has_field_[5]) {
12134     msg->AppendTinyVarInt(5, supports_instrumented_sampling_);
12135   }
12136 
12137   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
12138 }
12139 
12140 
12141 GpuCounterDescriptor_GpuCounterBlock::GpuCounterDescriptor_GpuCounterBlock() = default;
12142 GpuCounterDescriptor_GpuCounterBlock::~GpuCounterDescriptor_GpuCounterBlock() = default;
12143 GpuCounterDescriptor_GpuCounterBlock::GpuCounterDescriptor_GpuCounterBlock(const GpuCounterDescriptor_GpuCounterBlock&) = default;
12144 GpuCounterDescriptor_GpuCounterBlock& GpuCounterDescriptor_GpuCounterBlock::operator=(const GpuCounterDescriptor_GpuCounterBlock&) = default;
12145 GpuCounterDescriptor_GpuCounterBlock::GpuCounterDescriptor_GpuCounterBlock(GpuCounterDescriptor_GpuCounterBlock&&) noexcept = default;
12146 GpuCounterDescriptor_GpuCounterBlock& GpuCounterDescriptor_GpuCounterBlock::operator=(GpuCounterDescriptor_GpuCounterBlock&&) = default;
12147 
operator ==(const GpuCounterDescriptor_GpuCounterBlock & other) const12148 bool GpuCounterDescriptor_GpuCounterBlock::operator==(const GpuCounterDescriptor_GpuCounterBlock& other) const {
12149   return unknown_fields_ == other.unknown_fields_
12150    && block_id_ == other.block_id_
12151    && block_capacity_ == other.block_capacity_
12152    && name_ == other.name_
12153    && description_ == other.description_
12154    && counter_ids_ == other.counter_ids_;
12155 }
12156 
ParseFromArray(const void * raw,size_t size)12157 bool GpuCounterDescriptor_GpuCounterBlock::ParseFromArray(const void* raw, size_t size) {
12158   counter_ids_.clear();
12159   unknown_fields_.clear();
12160   bool packed_error = false;
12161 
12162   ::protozero::ProtoDecoder dec(raw, size);
12163   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
12164     if (field.id() < _has_field_.size()) {
12165       _has_field_.set(field.id());
12166     }
12167     switch (field.id()) {
12168       case 1 /* block_id */:
12169         field.get(&block_id_);
12170         break;
12171       case 2 /* block_capacity */:
12172         field.get(&block_capacity_);
12173         break;
12174       case 3 /* name */:
12175         field.get(&name_);
12176         break;
12177       case 4 /* description */:
12178         field.get(&description_);
12179         break;
12180       case 5 /* counter_ids */:
12181         counter_ids_.emplace_back();
12182         field.get(&counter_ids_.back());
12183         break;
12184       default:
12185         field.SerializeAndAppendTo(&unknown_fields_);
12186         break;
12187     }
12188   }
12189   return !packed_error && !dec.bytes_left();
12190 }
12191 
SerializeAsString() const12192 std::string GpuCounterDescriptor_GpuCounterBlock::SerializeAsString() const {
12193   ::protozero::HeapBuffered<::protozero::Message> msg;
12194   Serialize(msg.get());
12195   return msg.SerializeAsString();
12196 }
12197 
SerializeAsArray() const12198 std::vector<uint8_t> GpuCounterDescriptor_GpuCounterBlock::SerializeAsArray() const {
12199   ::protozero::HeapBuffered<::protozero::Message> msg;
12200   Serialize(msg.get());
12201   return msg.SerializeAsArray();
12202 }
12203 
Serialize(::protozero::Message * msg) const12204 void GpuCounterDescriptor_GpuCounterBlock::Serialize(::protozero::Message* msg) const {
12205   // Field 1: block_id
12206   if (_has_field_[1]) {
12207     msg->AppendVarInt(1, block_id_);
12208   }
12209 
12210   // Field 2: block_capacity
12211   if (_has_field_[2]) {
12212     msg->AppendVarInt(2, block_capacity_);
12213   }
12214 
12215   // Field 3: name
12216   if (_has_field_[3]) {
12217     msg->AppendString(3, name_);
12218   }
12219 
12220   // Field 4: description
12221   if (_has_field_[4]) {
12222     msg->AppendString(4, description_);
12223   }
12224 
12225   // Field 5: counter_ids
12226   for (auto& it : counter_ids_) {
12227     msg->AppendVarInt(5, it);
12228   }
12229 
12230   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
12231 }
12232 
12233 
12234 GpuCounterDescriptor_GpuCounterSpec::GpuCounterDescriptor_GpuCounterSpec() = default;
12235 GpuCounterDescriptor_GpuCounterSpec::~GpuCounterDescriptor_GpuCounterSpec() = default;
12236 GpuCounterDescriptor_GpuCounterSpec::GpuCounterDescriptor_GpuCounterSpec(const GpuCounterDescriptor_GpuCounterSpec&) = default;
12237 GpuCounterDescriptor_GpuCounterSpec& GpuCounterDescriptor_GpuCounterSpec::operator=(const GpuCounterDescriptor_GpuCounterSpec&) = default;
12238 GpuCounterDescriptor_GpuCounterSpec::GpuCounterDescriptor_GpuCounterSpec(GpuCounterDescriptor_GpuCounterSpec&&) noexcept = default;
12239 GpuCounterDescriptor_GpuCounterSpec& GpuCounterDescriptor_GpuCounterSpec::operator=(GpuCounterDescriptor_GpuCounterSpec&&) = default;
12240 
operator ==(const GpuCounterDescriptor_GpuCounterSpec & other) const12241 bool GpuCounterDescriptor_GpuCounterSpec::operator==(const GpuCounterDescriptor_GpuCounterSpec& other) const {
12242   return unknown_fields_ == other.unknown_fields_
12243    && counter_id_ == other.counter_id_
12244    && name_ == other.name_
12245    && description_ == other.description_
12246    && int_peak_value_ == other.int_peak_value_
12247    && double_peak_value_ == other.double_peak_value_
12248    && numerator_units_ == other.numerator_units_
12249    && denominator_units_ == other.denominator_units_
12250    && select_by_default_ == other.select_by_default_
12251    && groups_ == other.groups_;
12252 }
12253 
ParseFromArray(const void * raw,size_t size)12254 bool GpuCounterDescriptor_GpuCounterSpec::ParseFromArray(const void* raw, size_t size) {
12255   numerator_units_.clear();
12256   denominator_units_.clear();
12257   groups_.clear();
12258   unknown_fields_.clear();
12259   bool packed_error = false;
12260 
12261   ::protozero::ProtoDecoder dec(raw, size);
12262   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
12263     if (field.id() < _has_field_.size()) {
12264       _has_field_.set(field.id());
12265     }
12266     switch (field.id()) {
12267       case 1 /* counter_id */:
12268         field.get(&counter_id_);
12269         break;
12270       case 2 /* name */:
12271         field.get(&name_);
12272         break;
12273       case 3 /* description */:
12274         field.get(&description_);
12275         break;
12276       case 5 /* int_peak_value */:
12277         field.get(&int_peak_value_);
12278         break;
12279       case 6 /* double_peak_value */:
12280         field.get(&double_peak_value_);
12281         break;
12282       case 7 /* numerator_units */:
12283         numerator_units_.emplace_back();
12284         field.get(&numerator_units_.back());
12285         break;
12286       case 8 /* denominator_units */:
12287         denominator_units_.emplace_back();
12288         field.get(&denominator_units_.back());
12289         break;
12290       case 9 /* select_by_default */:
12291         field.get(&select_by_default_);
12292         break;
12293       case 10 /* groups */:
12294         groups_.emplace_back();
12295         field.get(&groups_.back());
12296         break;
12297       default:
12298         field.SerializeAndAppendTo(&unknown_fields_);
12299         break;
12300     }
12301   }
12302   return !packed_error && !dec.bytes_left();
12303 }
12304 
SerializeAsString() const12305 std::string GpuCounterDescriptor_GpuCounterSpec::SerializeAsString() const {
12306   ::protozero::HeapBuffered<::protozero::Message> msg;
12307   Serialize(msg.get());
12308   return msg.SerializeAsString();
12309 }
12310 
SerializeAsArray() const12311 std::vector<uint8_t> GpuCounterDescriptor_GpuCounterSpec::SerializeAsArray() const {
12312   ::protozero::HeapBuffered<::protozero::Message> msg;
12313   Serialize(msg.get());
12314   return msg.SerializeAsArray();
12315 }
12316 
Serialize(::protozero::Message * msg) const12317 void GpuCounterDescriptor_GpuCounterSpec::Serialize(::protozero::Message* msg) const {
12318   // Field 1: counter_id
12319   if (_has_field_[1]) {
12320     msg->AppendVarInt(1, counter_id_);
12321   }
12322 
12323   // Field 2: name
12324   if (_has_field_[2]) {
12325     msg->AppendString(2, name_);
12326   }
12327 
12328   // Field 3: description
12329   if (_has_field_[3]) {
12330     msg->AppendString(3, description_);
12331   }
12332 
12333   // Field 5: int_peak_value
12334   if (_has_field_[5]) {
12335     msg->AppendVarInt(5, int_peak_value_);
12336   }
12337 
12338   // Field 6: double_peak_value
12339   if (_has_field_[6]) {
12340     msg->AppendFixed(6, double_peak_value_);
12341   }
12342 
12343   // Field 7: numerator_units
12344   for (auto& it : numerator_units_) {
12345     msg->AppendVarInt(7, it);
12346   }
12347 
12348   // Field 8: denominator_units
12349   for (auto& it : denominator_units_) {
12350     msg->AppendVarInt(8, it);
12351   }
12352 
12353   // Field 9: select_by_default
12354   if (_has_field_[9]) {
12355     msg->AppendTinyVarInt(9, select_by_default_);
12356   }
12357 
12358   // Field 10: groups
12359   for (auto& it : groups_) {
12360     msg->AppendVarInt(10, it);
12361   }
12362 
12363   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
12364 }
12365 
12366 }  // namespace perfetto
12367 }  // namespace protos
12368 }  // namespace gen
12369 #if defined(__GNUC__) || defined(__clang__)
12370 #pragma GCC diagnostic pop
12371 #endif
12372 // gen_amalgamated begin source: gen/protos/perfetto/common/interceptor_descriptor.gen.cc
12373 // gen_amalgamated begin header: gen/protos/perfetto/common/interceptor_descriptor.gen.h
12374 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
12375 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_INTERCEPTOR_DESCRIPTOR_PROTO_CPP_H_
12376 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_INTERCEPTOR_DESCRIPTOR_PROTO_CPP_H_
12377 
12378 #include <stdint.h>
12379 #include <bitset>
12380 #include <vector>
12381 #include <string>
12382 #include <type_traits>
12383 
12384 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
12385 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
12386 // gen_amalgamated expanded: #include "perfetto/base/export.h"
12387 
12388 namespace perfetto {
12389 namespace protos {
12390 namespace gen {
12391 class InterceptorDescriptor;
12392 }  // namespace perfetto
12393 }  // namespace protos
12394 }  // namespace gen
12395 
12396 namespace protozero {
12397 class Message;
12398 }  // namespace protozero
12399 
12400 namespace perfetto {
12401 namespace protos {
12402 namespace gen {
12403 
12404 class PERFETTO_EXPORT InterceptorDescriptor : public ::protozero::CppMessageObj {
12405  public:
12406   enum FieldNumbers {
12407     kNameFieldNumber = 1,
12408   };
12409 
12410   InterceptorDescriptor();
12411   ~InterceptorDescriptor() override;
12412   InterceptorDescriptor(InterceptorDescriptor&&) noexcept;
12413   InterceptorDescriptor& operator=(InterceptorDescriptor&&);
12414   InterceptorDescriptor(const InterceptorDescriptor&);
12415   InterceptorDescriptor& operator=(const InterceptorDescriptor&);
12416   bool operator==(const InterceptorDescriptor&) const;
operator !=(const InterceptorDescriptor & other) const12417   bool operator!=(const InterceptorDescriptor& other) const { return !(*this == other); }
12418 
12419   bool ParseFromArray(const void*, size_t) override;
12420   std::string SerializeAsString() const override;
12421   std::vector<uint8_t> SerializeAsArray() const override;
12422   void Serialize(::protozero::Message*) const;
12423 
has_name() const12424   bool has_name() const { return _has_field_[1]; }
name() const12425   const std::string& name() const { return name_; }
set_name(const std::string & value)12426   void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
12427 
12428  private:
12429   std::string name_{};
12430 
12431   // Allows to preserve unknown protobuf fields for compatibility
12432   // with future versions of .proto files.
12433   std::string unknown_fields_;
12434 
12435   std::bitset<2> _has_field_{};
12436 };
12437 
12438 }  // namespace perfetto
12439 }  // namespace protos
12440 }  // namespace gen
12441 
12442 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_INTERCEPTOR_DESCRIPTOR_PROTO_CPP_H_
12443 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
12444 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
12445 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
12446 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
12447 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
12448 #if defined(__GNUC__) || defined(__clang__)
12449 #pragma GCC diagnostic push
12450 #pragma GCC diagnostic ignored "-Wfloat-equal"
12451 #endif
12452 // gen_amalgamated expanded: #include "protos/perfetto/common/interceptor_descriptor.gen.h"
12453 
12454 namespace perfetto {
12455 namespace protos {
12456 namespace gen {
12457 
12458 InterceptorDescriptor::InterceptorDescriptor() = default;
12459 InterceptorDescriptor::~InterceptorDescriptor() = default;
12460 InterceptorDescriptor::InterceptorDescriptor(const InterceptorDescriptor&) = default;
12461 InterceptorDescriptor& InterceptorDescriptor::operator=(const InterceptorDescriptor&) = default;
12462 InterceptorDescriptor::InterceptorDescriptor(InterceptorDescriptor&&) noexcept = default;
12463 InterceptorDescriptor& InterceptorDescriptor::operator=(InterceptorDescriptor&&) = default;
12464 
operator ==(const InterceptorDescriptor & other) const12465 bool InterceptorDescriptor::operator==(const InterceptorDescriptor& other) const {
12466   return unknown_fields_ == other.unknown_fields_
12467    && name_ == other.name_;
12468 }
12469 
ParseFromArray(const void * raw,size_t size)12470 bool InterceptorDescriptor::ParseFromArray(const void* raw, size_t size) {
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       default:
12484         field.SerializeAndAppendTo(&unknown_fields_);
12485         break;
12486     }
12487   }
12488   return !packed_error && !dec.bytes_left();
12489 }
12490 
SerializeAsString() const12491 std::string InterceptorDescriptor::SerializeAsString() const {
12492   ::protozero::HeapBuffered<::protozero::Message> msg;
12493   Serialize(msg.get());
12494   return msg.SerializeAsString();
12495 }
12496 
SerializeAsArray() const12497 std::vector<uint8_t> InterceptorDescriptor::SerializeAsArray() const {
12498   ::protozero::HeapBuffered<::protozero::Message> msg;
12499   Serialize(msg.get());
12500   return msg.SerializeAsArray();
12501 }
12502 
Serialize(::protozero::Message * msg) const12503 void InterceptorDescriptor::Serialize(::protozero::Message* msg) const {
12504   // Field 1: name
12505   if (_has_field_[1]) {
12506     msg->AppendString(1, name_);
12507   }
12508 
12509   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
12510 }
12511 
12512 }  // namespace perfetto
12513 }  // namespace protos
12514 }  // namespace gen
12515 #if defined(__GNUC__) || defined(__clang__)
12516 #pragma GCC diagnostic pop
12517 #endif
12518 // gen_amalgamated begin source: gen/protos/perfetto/common/observable_events.gen.cc
12519 // gen_amalgamated begin header: gen/protos/perfetto/common/observable_events.gen.h
12520 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
12521 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_OBSERVABLE_EVENTS_PROTO_CPP_H_
12522 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_OBSERVABLE_EVENTS_PROTO_CPP_H_
12523 
12524 #include <stdint.h>
12525 #include <bitset>
12526 #include <vector>
12527 #include <string>
12528 #include <type_traits>
12529 
12530 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
12531 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
12532 // gen_amalgamated expanded: #include "perfetto/base/export.h"
12533 
12534 namespace perfetto {
12535 namespace protos {
12536 namespace gen {
12537 class ObservableEvents;
12538 class ObservableEvents_DataSourceInstanceStateChange;
12539 enum ObservableEvents_Type : int;
12540 enum ObservableEvents_DataSourceInstanceState : int;
12541 }  // namespace perfetto
12542 }  // namespace protos
12543 }  // namespace gen
12544 
12545 namespace protozero {
12546 class Message;
12547 }  // namespace protozero
12548 
12549 namespace perfetto {
12550 namespace protos {
12551 namespace gen {
12552 enum ObservableEvents_Type : int {
12553   ObservableEvents_Type_TYPE_UNSPECIFIED = 0,
12554   ObservableEvents_Type_TYPE_DATA_SOURCES_INSTANCES = 1,
12555   ObservableEvents_Type_TYPE_ALL_DATA_SOURCES_STARTED = 2,
12556 };
12557 enum ObservableEvents_DataSourceInstanceState : int {
12558   ObservableEvents_DataSourceInstanceState_DATA_SOURCE_INSTANCE_STATE_STOPPED = 1,
12559   ObservableEvents_DataSourceInstanceState_DATA_SOURCE_INSTANCE_STATE_STARTED = 2,
12560 };
12561 
12562 class PERFETTO_EXPORT ObservableEvents : public ::protozero::CppMessageObj {
12563  public:
12564   using DataSourceInstanceStateChange = ObservableEvents_DataSourceInstanceStateChange;
12565   using Type = ObservableEvents_Type;
12566   static constexpr auto TYPE_UNSPECIFIED = ObservableEvents_Type_TYPE_UNSPECIFIED;
12567   static constexpr auto TYPE_DATA_SOURCES_INSTANCES = ObservableEvents_Type_TYPE_DATA_SOURCES_INSTANCES;
12568   static constexpr auto TYPE_ALL_DATA_SOURCES_STARTED = ObservableEvents_Type_TYPE_ALL_DATA_SOURCES_STARTED;
12569   static constexpr auto Type_MIN = ObservableEvents_Type_TYPE_UNSPECIFIED;
12570   static constexpr auto Type_MAX = ObservableEvents_Type_TYPE_ALL_DATA_SOURCES_STARTED;
12571   using DataSourceInstanceState = ObservableEvents_DataSourceInstanceState;
12572   static constexpr auto DATA_SOURCE_INSTANCE_STATE_STOPPED = ObservableEvents_DataSourceInstanceState_DATA_SOURCE_INSTANCE_STATE_STOPPED;
12573   static constexpr auto DATA_SOURCE_INSTANCE_STATE_STARTED = ObservableEvents_DataSourceInstanceState_DATA_SOURCE_INSTANCE_STATE_STARTED;
12574   static constexpr auto DataSourceInstanceState_MIN = ObservableEvents_DataSourceInstanceState_DATA_SOURCE_INSTANCE_STATE_STOPPED;
12575   static constexpr auto DataSourceInstanceState_MAX = ObservableEvents_DataSourceInstanceState_DATA_SOURCE_INSTANCE_STATE_STARTED;
12576   enum FieldNumbers {
12577     kInstanceStateChangesFieldNumber = 1,
12578     kAllDataSourcesStartedFieldNumber = 2,
12579   };
12580 
12581   ObservableEvents();
12582   ~ObservableEvents() override;
12583   ObservableEvents(ObservableEvents&&) noexcept;
12584   ObservableEvents& operator=(ObservableEvents&&);
12585   ObservableEvents(const ObservableEvents&);
12586   ObservableEvents& operator=(const ObservableEvents&);
12587   bool operator==(const ObservableEvents&) const;
operator !=(const ObservableEvents & other) const12588   bool operator!=(const ObservableEvents& other) const { return !(*this == other); }
12589 
12590   bool ParseFromArray(const void*, size_t) override;
12591   std::string SerializeAsString() const override;
12592   std::vector<uint8_t> SerializeAsArray() const override;
12593   void Serialize(::protozero::Message*) const;
12594 
instance_state_changes() const12595   const std::vector<ObservableEvents_DataSourceInstanceStateChange>& instance_state_changes() const { return instance_state_changes_; }
mutable_instance_state_changes()12596   std::vector<ObservableEvents_DataSourceInstanceStateChange>* mutable_instance_state_changes() { return &instance_state_changes_; }
12597   int instance_state_changes_size() const;
12598   void clear_instance_state_changes();
12599   ObservableEvents_DataSourceInstanceStateChange* add_instance_state_changes();
12600 
has_all_data_sources_started() const12601   bool has_all_data_sources_started() const { return _has_field_[2]; }
all_data_sources_started() const12602   bool all_data_sources_started() const { return all_data_sources_started_; }
set_all_data_sources_started(bool value)12603   void set_all_data_sources_started(bool value) { all_data_sources_started_ = value; _has_field_.set(2); }
12604 
12605  private:
12606   std::vector<ObservableEvents_DataSourceInstanceStateChange> instance_state_changes_;
12607   bool all_data_sources_started_{};
12608 
12609   // Allows to preserve unknown protobuf fields for compatibility
12610   // with future versions of .proto files.
12611   std::string unknown_fields_;
12612 
12613   std::bitset<3> _has_field_{};
12614 };
12615 
12616 
12617 class PERFETTO_EXPORT ObservableEvents_DataSourceInstanceStateChange : public ::protozero::CppMessageObj {
12618  public:
12619   enum FieldNumbers {
12620     kProducerNameFieldNumber = 1,
12621     kDataSourceNameFieldNumber = 2,
12622     kStateFieldNumber = 3,
12623   };
12624 
12625   ObservableEvents_DataSourceInstanceStateChange();
12626   ~ObservableEvents_DataSourceInstanceStateChange() override;
12627   ObservableEvents_DataSourceInstanceStateChange(ObservableEvents_DataSourceInstanceStateChange&&) noexcept;
12628   ObservableEvents_DataSourceInstanceStateChange& operator=(ObservableEvents_DataSourceInstanceStateChange&&);
12629   ObservableEvents_DataSourceInstanceStateChange(const ObservableEvents_DataSourceInstanceStateChange&);
12630   ObservableEvents_DataSourceInstanceStateChange& operator=(const ObservableEvents_DataSourceInstanceStateChange&);
12631   bool operator==(const ObservableEvents_DataSourceInstanceStateChange&) const;
operator !=(const ObservableEvents_DataSourceInstanceStateChange & other) const12632   bool operator!=(const ObservableEvents_DataSourceInstanceStateChange& other) const { return !(*this == other); }
12633 
12634   bool ParseFromArray(const void*, size_t) override;
12635   std::string SerializeAsString() const override;
12636   std::vector<uint8_t> SerializeAsArray() const override;
12637   void Serialize(::protozero::Message*) const;
12638 
has_producer_name() const12639   bool has_producer_name() const { return _has_field_[1]; }
producer_name() const12640   const std::string& producer_name() const { return producer_name_; }
set_producer_name(const std::string & value)12641   void set_producer_name(const std::string& value) { producer_name_ = value; _has_field_.set(1); }
12642 
has_data_source_name() const12643   bool has_data_source_name() const { return _has_field_[2]; }
data_source_name() const12644   const std::string& data_source_name() const { return data_source_name_; }
set_data_source_name(const std::string & value)12645   void set_data_source_name(const std::string& value) { data_source_name_ = value; _has_field_.set(2); }
12646 
has_state() const12647   bool has_state() const { return _has_field_[3]; }
state() const12648