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