1 // Copyright (C) 2019 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 // This file is automatically generated by gen_amalgamated. Do not edit.
16
17 // gen_amalgamated: predefined macros
18 #if !defined(GOOGLE_PROTOBUF_NO_RTTI)
19 #define GOOGLE_PROTOBUF_NO_RTTI
20 #endif
21 #if !defined(PERFETTO_IMPLEMENTATION)
22 #define PERFETTO_IMPLEMENTATION
23 #endif
24 #if !defined(GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER)
25 #define GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
26 #endif
27 #include "perfetto.h"
28 // gen_amalgamated begin source: src/base/file_utils.cc
29 // gen_amalgamated begin header: include/perfetto/ext/base/file_utils.h
30 // gen_amalgamated begin header: include/perfetto/ext/base/utils.h
31 /*
32 * Copyright (C) 2017 The Android Open Source Project
33 *
34 * Licensed under the Apache License, Version 2.0 (the "License");
35 * you may not use this file except in compliance with the License.
36 * You may obtain a copy of the License at
37 *
38 * http://www.apache.org/licenses/LICENSE-2.0
39 *
40 * Unless required by applicable law or agreed to in writing, software
41 * distributed under the License is distributed on an "AS IS" BASIS,
42 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
43 * See the License for the specific language governing permissions and
44 * limitations under the License.
45 */
46
47 #ifndef INCLUDE_PERFETTO_EXT_BASE_UTILS_H_
48 #define INCLUDE_PERFETTO_EXT_BASE_UTILS_H_
49
50 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
51 // gen_amalgamated expanded: #include "perfetto/base/compiler.h"
52
53 #include <errno.h>
54 #include <stddef.h>
55 #include <stdlib.h>
56 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
57 #include <sys/types.h>
58 #endif
59
60 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
61 PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
62 #include <unistd.h> // For getpagesize().
63 #elif PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
64 #include <mach/vm_page_size.h>
65 #endif
66
67 #include <atomic>
68
69 #define PERFETTO_EINTR(x) \
70 ([&] { \
71 decltype(x) eintr_wrapper_result; \
72 do { \
73 eintr_wrapper_result = (x); \
74 } while (eintr_wrapper_result == -1 && errno == EINTR); \
75 return eintr_wrapper_result; \
76 }())
77
78 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
79 // TODO(brucedawson) - create a ::perfetto::base::IOSize to replace this.
80 #if defined(_WIN64)
81 using ssize_t = __int64;
82 #else
83 using ssize_t = long;
84 #endif
85 #endif
86
87 namespace perfetto {
88 namespace base {
89
90 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
91 constexpr uid_t kInvalidUid = static_cast<uid_t>(-1);
92 constexpr pid_t kInvalidPid = static_cast<pid_t>(-1);
93 #endif
94
95 // Do not add new usages of kPageSize, consider using GetSysPageSize() below.
96 // TODO(primiano): over time the semantic of kPageSize became too ambiguous.
97 // Strictly speaking, this constant is incorrect on some new devices where the
98 // page size can be 16K (e.g., crbug.com/1116576). Unfortunately too much code
99 // ended up depending on kPageSize for purposes that are not strictly related
100 // with the kernel's mm subsystem.
101 constexpr size_t kPageSize = 4096;
102
103 // Returns the system's page size. Use this when dealing with mmap, madvise and
104 // similar mm-related syscalls.
GetSysPageSize()105 inline uint32_t GetSysPageSize() {
106 ignore_result(kPageSize); // Just to keep the amalgamated build happy.
107 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
108 PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
109 static std::atomic<uint32_t> page_size{0};
110 // This function might be called in hot paths. Avoid calling getpagesize() all
111 // the times, in many implementations getpagesize() calls sysconf() which is
112 // not cheap.
113 uint32_t cached_value = page_size.load(std::memory_order_relaxed);
114 if (PERFETTO_UNLIKELY(cached_value == 0)) {
115 cached_value = static_cast<uint32_t>(getpagesize());
116 page_size.store(cached_value, std::memory_order_relaxed);
117 }
118 return cached_value;
119 #elif PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
120 return static_cast<uint32_t>(vm_page_size);
121 #else
122 return 4096;
123 #endif
124 }
125
126 template <typename T>
ArraySize(const T & array)127 constexpr size_t ArraySize(const T& array) {
128 return sizeof(array) / sizeof(array[0]);
129 }
130
131 // Function object which invokes 'free' on its parameter, which must be
132 // a pointer. Can be used to store malloc-allocated pointers in std::unique_ptr:
133 //
134 // std::unique_ptr<int, base::FreeDeleter> foo_ptr(
135 // static_cast<int*>(malloc(sizeof(int))));
136 struct FreeDeleter {
operator ()perfetto::base::FreeDeleter137 inline void operator()(void* ptr) const { free(ptr); }
138 };
139
140 template <typename T>
AssumeLittleEndian(T value)141 constexpr T AssumeLittleEndian(T value) {
142 static_assert(__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__,
143 "Unimplemented on big-endian archs");
144 return value;
145 }
146
147 // Round up |size| to a multiple of |alignment| (must be a power of two).
148 template <size_t alignment>
AlignUp(size_t size)149 constexpr size_t AlignUp(size_t size) {
150 static_assert((alignment & (alignment - 1)) == 0, "alignment must be a pow2");
151 return (size + alignment - 1) & ~(alignment - 1);
152 }
153
IsAgain(int err)154 inline bool IsAgain(int err) {
155 return err == EAGAIN || err == EWOULDBLOCK;
156 }
157
158 } // namespace base
159 } // namespace perfetto
160
161 #endif // INCLUDE_PERFETTO_EXT_BASE_UTILS_H_
162 /*
163 * Copyright (C) 2018 The Android Open Source Project
164 *
165 * Licensed under the Apache License, Version 2.0 (the "License");
166 * you may not use this file except in compliance with the License.
167 * You may obtain a copy of the License at
168 *
169 * http://www.apache.org/licenses/LICENSE-2.0
170 *
171 * Unless required by applicable law or agreed to in writing, software
172 * distributed under the License is distributed on an "AS IS" BASIS,
173 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
174 * See the License for the specific language governing permissions and
175 * limitations under the License.
176 */
177
178 #ifndef INCLUDE_PERFETTO_EXT_BASE_FILE_UTILS_H_
179 #define INCLUDE_PERFETTO_EXT_BASE_FILE_UTILS_H_
180
181 #include <stddef.h>
182
183 #include <string>
184
185 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
186
187 namespace perfetto {
188 namespace base {
189
190 bool ReadFileDescriptor(int fd, std::string* out);
191 bool ReadFileStream(FILE* f, std::string* out);
192 bool ReadFile(const std::string& path, std::string* out);
193
194 // Call write until all data is written or an error is detected.
195 //
196 // man 2 write:
197 // If a write() is interrupted by a signal handler before any bytes are
198 // written, then the call fails with the error EINTR; if it is
199 // interrupted after at least one byte has been written, the call
200 // succeeds, and returns the number of bytes written.
201 ssize_t WriteAll(int fd, const void* buf, size_t count);
202
203 bool FlushFile(int fd);
204
205 } // namespace base
206 } // namespace perfetto
207
208 #endif // INCLUDE_PERFETTO_EXT_BASE_FILE_UTILS_H_
209 // gen_amalgamated begin header: include/perfetto/ext/base/scoped_file.h
210 /*
211 * Copyright (C) 2017 The Android Open Source Project
212 *
213 * Licensed under the Apache License, Version 2.0 (the "License");
214 * you may not use this file except in compliance with the License.
215 * You may obtain a copy of the License at
216 *
217 * http://www.apache.org/licenses/LICENSE-2.0
218 *
219 * Unless required by applicable law or agreed to in writing, software
220 * distributed under the License is distributed on an "AS IS" BASIS,
221 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
222 * See the License for the specific language governing permissions and
223 * limitations under the License.
224 */
225
226 #ifndef INCLUDE_PERFETTO_EXT_BASE_SCOPED_FILE_H_
227 #define INCLUDE_PERFETTO_EXT_BASE_SCOPED_FILE_H_
228
229 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
230
231 #include <fcntl.h>
232 #include <stdio.h>
233
234 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) && \
235 !PERFETTO_BUILDFLAG(PERFETTO_COMPILER_GCC)
236 #include <corecrt_io.h>
237 typedef int mode_t;
238 #else
239 #include <dirent.h>
240 #include <unistd.h>
241 #endif
242
243 #include <string>
244
245 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
246
247 namespace perfetto {
248 namespace base {
249
250 constexpr mode_t kInvalidMode = static_cast<mode_t>(-1);
251
252 // RAII classes for auto-releasing fds and dirs.
253 template <typename T,
254 int (*CloseFunction)(T),
255 T InvalidValue,
256 bool CheckClose = true>
257 class ScopedResource {
258 public:
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 t_ != InvalidValue; }
reset(T r=InvalidValue)272 void reset(T r = InvalidValue) {
273 if (t_ != InvalidValue) {
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
291 T t_;
292 };
293
294 using ScopedFile = ScopedResource<int, close, -1>;
OpenFile(const std::string & path,int flags,mode_t mode=kInvalidMode)295 inline static ScopedFile OpenFile(const std::string& path,
296 int flags,
297 mode_t mode = kInvalidMode) {
298 PERFETTO_DCHECK((flags & O_CREAT) == 0 || mode != kInvalidMode);
299 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
300 // Always use O_BINARY on Windows, to avoid silly EOL translations.
301 ScopedFile fd(open(path.c_str(), flags | O_BINARY, mode));
302 #else
303 // Always open a ScopedFile with O_CLOEXEC so we can safely fork and exec.
304 ScopedFile fd(open(path.c_str(), flags | O_CLOEXEC, mode));
305 #endif
306 return fd;
307 }
308 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
309 using ScopedDir = ScopedResource<DIR*, closedir, nullptr>;
310 #endif
311
312 using ScopedFstream = ScopedResource<FILE*, fclose, nullptr>;
313
314 } // namespace base
315 } // namespace perfetto
316
317 #endif // INCLUDE_PERFETTO_EXT_BASE_SCOPED_FILE_H_
318 /*
319 * Copyright (C) 2018 The Android Open Source Project
320 *
321 * Licensed under the Apache License, Version 2.0 (the "License");
322 * you may not use this file except in compliance with the License.
323 * You may obtain a copy of the License at
324 *
325 * http://www.apache.org/licenses/LICENSE-2.0
326 *
327 * Unless required by applicable law or agreed to in writing, software
328 * distributed under the License is distributed on an "AS IS" BASIS,
329 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
330 * See the License for the specific language governing permissions and
331 * limitations under the License.
332 */
333
334 #include <sys/stat.h>
335
336 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
337 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
338 // gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
339 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
340 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
341
342 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) || \
343 PERFETTO_BUILDFLAG(PERFETTO_COMPILER_GCC)
344 #include <unistd.h>
345 #else
346 #include <corecrt_io.h>
347 #include <io.h>
348 #endif
349
350 namespace perfetto {
351 namespace base {
352 namespace {
353 constexpr size_t kBufSize = 2048;
354 }
355
ReadFileDescriptor(int fd,std::string * out)356 bool ReadFileDescriptor(int fd, std::string* out) {
357 // Do not override existing data in string.
358 size_t i = out->size();
359
360 struct stat buf {};
361 if (fstat(fd, &buf) != -1) {
362 if (buf.st_size > 0)
363 out->resize(i + static_cast<size_t>(buf.st_size));
364 }
365
366 ssize_t bytes_read;
367 for (;;) {
368 if (out->size() < i + kBufSize)
369 out->resize(out->size() + kBufSize);
370
371 bytes_read = PERFETTO_EINTR(read(fd, &((*out)[i]), kBufSize));
372 if (bytes_read > 0) {
373 i += static_cast<size_t>(bytes_read);
374 } else {
375 out->resize(i);
376 return bytes_read == 0;
377 }
378 }
379 }
380
ReadFileStream(FILE * f,std::string * out)381 bool ReadFileStream(FILE* f, std::string* out) {
382 return ReadFileDescriptor(fileno(f), out);
383 }
384
ReadFile(const std::string & path,std::string * out)385 bool ReadFile(const std::string& path, std::string* out) {
386 base::ScopedFile fd = base::OpenFile(path, O_RDONLY);
387 if (!fd)
388 return false;
389
390 return ReadFileDescriptor(*fd, out);
391 }
392
WriteAll(int fd,const void * buf,size_t count)393 ssize_t WriteAll(int fd, const void* buf, size_t count) {
394 size_t written = 0;
395 while (written < count) {
396 ssize_t wr = PERFETTO_EINTR(
397 write(fd, static_cast<const char*>(buf) + written, count - written));
398 if (wr == 0)
399 break;
400 if (wr < 0)
401 return wr;
402 written += static_cast<size_t>(wr);
403 }
404 return static_cast<ssize_t>(written);
405 }
406
FlushFile(int fd)407 bool FlushFile(int fd) {
408 PERFETTO_DCHECK(fd != 0);
409 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
410 PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
411 return !PERFETTO_EINTR(fdatasync(fd));
412 #elif PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
413 return !PERFETTO_EINTR(_commit(fd));
414 #else
415 return !PERFETTO_EINTR(fsync(fd));
416 #endif
417 }
418
419 } // namespace base
420 } // namespace perfetto
421 // gen_amalgamated begin source: src/base/logging.cc
422 /*
423 * Copyright (C) 2019 The Android Open Source Project
424 *
425 * Licensed under the Apache License, Version 2.0 (the "License");
426 * you may not use this file except in compliance with the License.
427 * You may obtain a copy of the License at
428 *
429 * http://www.apache.org/licenses/LICENSE-2.0
430 *
431 * Unless required by applicable law or agreed to in writing, software
432 * distributed under the License is distributed on an "AS IS" BASIS,
433 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
434 * See the License for the specific language governing permissions and
435 * limitations under the License.
436 */
437
438 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
439
440 #include <stdarg.h>
441 #include <stdio.h>
442
443 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
444 #include <unistd.h> // For isatty()
445 #endif
446
447 #include <memory>
448
449 // gen_amalgamated expanded: #include "perfetto/base/time.h"
450
451 namespace perfetto {
452 namespace base {
453
454 namespace {
455 const char kReset[] = "\x1b[0m";
456 const char kDefault[] = "\x1b[39m";
457 const char kDim[] = "\x1b[2m";
458 const char kRed[] = "\x1b[31m";
459 const char kBoldGreen[] = "\x1b[1m\x1b[32m";
460 const char kLightGray[] = "\x1b[90m";
461
462 } // namespace
463
LogMessage(LogLev level,const char * fname,int line,const char * fmt,...)464 void LogMessage(LogLev level,
465 const char* fname,
466 int line,
467 const char* fmt,
468 ...) {
469 char stack_buf[512];
470 std::unique_ptr<char[]> large_buf;
471 char* log_msg = &stack_buf[0];
472
473 // By default use a stack allocated buffer because most log messages are quite
474 // short. In rare cases they can be larger (e.g. --help). In those cases we
475 // pay the cost of allocating the buffer on the heap.
476 for (size_t max_len = sizeof(stack_buf);;) {
477 va_list args;
478 va_start(args, fmt);
479 int res = vsnprintf(log_msg, max_len, fmt, args);
480 va_end(args);
481
482 // If for any reason the print fails, overwrite the message but still print
483 // it. The code below will attach the filename and line, which is still
484 // useful.
485 if (res < 0) {
486 strncpy(log_msg, "[printf format error]", max_len);
487 break;
488 }
489
490 // if res == max_len, vsnprintf saturated the input buffer. Retry with a
491 // larger buffer in that case (within reasonable limits).
492 if (res < static_cast<int>(max_len) || max_len >= 128 * 1024)
493 break;
494 max_len *= 4;
495 large_buf.reset(new char[max_len]);
496 log_msg = &large_buf[0];
497 }
498
499 const char* color = kDefault;
500 switch (level) {
501 case kLogDebug:
502 color = kDim;
503 break;
504 case kLogInfo:
505 color = kDefault;
506 break;
507 case kLogImportant:
508 color = kBoldGreen;
509 break;
510 case kLogError:
511 color = kRed;
512 break;
513 }
514
515 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) && \
516 !PERFETTO_BUILDFLAG(PERFETTO_OS_WASM)
517 static const bool use_colors = isatty(STDERR_FILENO);
518 #else
519 static const bool use_colors = false;
520 #endif
521
522 // Formats file.cc:line as a space-padded fixed width string. If the file name
523 // |fname| is too long, truncate it on the left-hand side.
524 char line_str[10];
525 size_t line_len =
526 static_cast<size_t>(snprintf(line_str, sizeof(line_str), "%d", line));
527
528 // 24 will be the width of the file.cc:line column in the log event.
529 char file_and_line[24];
530 size_t fname_len = strlen(fname);
531 size_t fname_max = sizeof(file_and_line) - line_len - 2; // 2 = ':' + '\0'.
532 size_t fname_offset = fname_len <= fname_max ? 0 : fname_len - fname_max;
533 int len = snprintf(file_and_line, sizeof(file_and_line), "%s:%s",
534 fname + fname_offset, line_str);
535 memset(&file_and_line[len], ' ', sizeof(file_and_line) - size_t(len));
536 file_and_line[sizeof(file_and_line) - 1] = '\0';
537
538 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
539 // Logcat has already timestamping, don't re-emit it.
540 __android_log_print(ANDROID_LOG_DEBUG + level, "perfetto", "%s %s",
541 file_and_line, log_msg);
542 #endif
543
544 // When printing on stderr, print also the timestamp. We don't really care
545 // about the actual time. We just need some reference clock that can be used
546 // to correlated events across differrent processses (e.g. traced and
547 // traced_probes). The wall time % 1000 is good enough.
548 char timestamp[32];
549 uint32_t t_ms = static_cast<uint32_t>(GetWallTimeMs().count());
550 uint32_t t_sec = t_ms / 1000;
551 t_ms -= t_sec * 1000;
552 t_sec = t_sec % 1000;
553 snprintf(timestamp, sizeof(timestamp), "[%03u.%03u] ", t_sec, t_ms);
554
555 if (use_colors) {
556 fprintf(stderr, "%s%s%s%s %s%s%s\n", kLightGray, timestamp, file_and_line,
557 kReset, color, log_msg, kReset);
558 } else {
559 fprintf(stderr, "%s%s %s\n", timestamp, file_and_line, log_msg);
560 }
561 }
562
563 } // namespace base
564 } // namespace perfetto
565 // gen_amalgamated begin source: src/base/metatrace.cc
566 // gen_amalgamated begin header: include/perfetto/ext/base/metatrace.h
567 // gen_amalgamated begin header: include/perfetto/ext/base/metatrace_events.h
568 /*
569 * Copyright (C) 2019 The Android Open Source Project
570 *
571 * Licensed under the Apache License, Version 2.0 (the "License");
572 * you may not use this file except in compliance with the License.
573 * You may obtain a copy of the License at
574 *
575 * http://www.apache.org/licenses/LICENSE-2.0
576 *
577 * Unless required by applicable law or agreed to in writing, software
578 * distributed under the License is distributed on an "AS IS" BASIS,
579 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
580 * See the License for the specific language governing permissions and
581 * limitations under the License.
582 */
583
584 #ifndef INCLUDE_PERFETTO_EXT_BASE_METATRACE_EVENTS_H_
585 #define INCLUDE_PERFETTO_EXT_BASE_METATRACE_EVENTS_H_
586
587 #include <stdint.h>
588
589 namespace perfetto {
590 namespace metatrace {
591
592 enum Tags : uint32_t {
593 TAG_NONE = 0,
594 TAG_ANY = uint32_t(-1),
595 TAG_FTRACE = 1 << 0,
596 TAG_PROC_POLLERS = 1 << 1,
597 TAG_TRACE_WRITER = 1 << 2,
598 TAG_TRACE_SERVICE = 1 << 3,
599 TAG_PRODUCER = 1 << 4,
600 };
601
602 // The macros below generate matching enums and arrays of string literals.
603 // This is to avoid maintaining string maps manually.
604
605 // clang-format off
606
607 // DO NOT remove or reshuffle items in this list, only append. The ID of these
608 // events are an ABI, the trace processor relies on these to open old traces.
609 #define PERFETTO_METATRACE_EVENTS(F) \
610 F(EVENT_ZERO_UNUSED), \
611 F(FTRACE_CPU_READER_READ), /*unused*/ \
612 F(FTRACE_DRAIN_CPUS), /*unused*/ \
613 F(FTRACE_UNBLOCK_READERS), /*unused*/ \
614 F(FTRACE_CPU_READ_NONBLOCK), /*unused*/ \
615 F(FTRACE_CPU_READ_BLOCK), /*unused*/ \
616 F(FTRACE_CPU_SPLICE_NONBLOCK), /*unused*/ \
617 F(FTRACE_CPU_SPLICE_BLOCK), /*unused*/ \
618 F(FTRACE_CPU_WAIT_CMD), /*unused*/ \
619 F(FTRACE_CPU_RUN_CYCLE), /*unused*/ \
620 F(FTRACE_CPU_FLUSH), \
621 F(FTRACE_CPU_DRAIN), /*unused*/ \
622 F(READ_SYS_STATS), \
623 F(PS_WRITE_ALL_PROCESSES), \
624 F(PS_ON_PIDS), \
625 F(PS_ON_RENAME_PIDS), \
626 F(PS_WRITE_ALL_PROCESS_STATS), \
627 F(TRACE_WRITER_COMMIT_STARTUP_WRITER_BATCH), \
628 F(FTRACE_READ_TICK), \
629 F(FTRACE_CPU_READ_CYCLE), \
630 F(FTRACE_CPU_READ_BATCH), \
631 F(KALLSYMS_PARSE), \
632 F(PROFILER_READ_TICK), \
633 F(PROFILER_READ_CPU), \
634 F(PROFILER_UNWIND_TICK), \
635 F(PROFILER_UNWIND_SAMPLE), \
636 F(PROFILER_UNWIND_INITIAL_ATTEMPT), \
637 F(PROFILER_UNWIND_ATTEMPT), \
638 F(PROFILER_MAPS_PARSE), \
639 F(PROFILER_MAPS_REPARSE), \
640 F(PROFILER_UNWIND_CACHE_CLEAR)
641
642 // Append only, see above.
643 //
644 // Values that aren't used as counters:
645 // * FTRACE_SERVICE_COMMIT_DATA is a bit-packed representation of an event, see
646 // tracing_service_impl.cc for the format.
647 // * PROFILER_UNWIND_CURRENT_PID represents the PID that is being unwound.
648 //
649 #define PERFETTO_METATRACE_COUNTERS(F) \
650 F(COUNTER_ZERO_UNUSED),\
651 F(FTRACE_PAGES_DRAINED), \
652 F(PS_PIDS_SCANNED), \
653 F(TRACE_SERVICE_COMMIT_DATA), \
654 F(PROFILER_UNWIND_QUEUE_SZ), \
655 F(PROFILER_UNWIND_CURRENT_PID)
656
657 // clang-format on
658
659 #define PERFETTO_METATRACE_IDENTITY(name) name
660 #define PERFETTO_METATRACE_TOSTRING(name) #name
661
662 enum Events : uint16_t {
663 PERFETTO_METATRACE_EVENTS(PERFETTO_METATRACE_IDENTITY),
664 EVENTS_MAX
665 };
666 constexpr char const* kEventNames[] = {
667 PERFETTO_METATRACE_EVENTS(PERFETTO_METATRACE_TOSTRING)};
668
669 enum Counters : uint16_t {
670 PERFETTO_METATRACE_COUNTERS(PERFETTO_METATRACE_IDENTITY),
671 COUNTERS_MAX
672 };
673 constexpr char const* kCounterNames[] = {
674 PERFETTO_METATRACE_COUNTERS(PERFETTO_METATRACE_TOSTRING)};
675
SuppressUnusedVarsInAmalgamatedBuild()676 inline void SuppressUnusedVarsInAmalgamatedBuild() {
677 (void)kCounterNames;
678 (void)kEventNames;
679 }
680
681 } // namespace metatrace
682 } // namespace perfetto
683
684 #endif // INCLUDE_PERFETTO_EXT_BASE_METATRACE_EVENTS_H_
685 // gen_amalgamated begin header: include/perfetto/ext/base/thread_annotations.h
686 /*
687 * Copyright (C) 2019 The Android Open Source Project
688 *
689 * Licensed under the Apache License, Version 2.0 (the "License");
690 * you may not use this file except in compliance with the License.
691 * You may obtain a copy of the License at
692 *
693 * http://www.apache.org/licenses/LICENSE-2.0
694 *
695 * Unless required by applicable law or agreed to in writing, software
696 * distributed under the License is distributed on an "AS IS" BASIS,
697 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
698 * See the License for the specific language governing permissions and
699 * limitations under the License.
700 */
701
702 #ifndef INCLUDE_PERFETTO_EXT_BASE_THREAD_ANNOTATIONS_H_
703 #define INCLUDE_PERFETTO_EXT_BASE_THREAD_ANNOTATIONS_H_
704
705 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
706
707 // Windows TSAN doesn't currently support these annotations.
708 #if defined(THREAD_SANITIZER) && !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
709 extern "C" {
710 void AnnotateBenignRaceSized(const char* file,
711 int line,
712 unsigned long address,
713 unsigned long size,
714 const char* description);
715 }
716
717 #define PERFETTO_ANNOTATE_BENIGN_RACE_SIZED(pointer, size, description) \
718 AnnotateBenignRaceSized(__FILE__, __LINE__, \
719 reinterpret_cast<unsigned long>(pointer), size, \
720 description);
721 #else // defined(ADDRESS_SANITIZER)
722 #define PERFETTO_ANNOTATE_BENIGN_RACE_SIZED(pointer, size, description)
723 #endif // defined(ADDRESS_SANITIZER)
724
725 #endif // INCLUDE_PERFETTO_EXT_BASE_THREAD_ANNOTATIONS_H_
726 /*
727 * Copyright (C) 2019 The Android Open Source Project
728 *
729 * Licensed under the Apache License, Version 2.0 (the "License");
730 * you may not use this file except in compliance with the License.
731 * You may obtain a copy of the License at
732 *
733 * http://www.apache.org/licenses/LICENSE-2.0
734 *
735 * Unless required by applicable law or agreed to in writing, software
736 * distributed under the License is distributed on an "AS IS" BASIS,
737 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
738 * See the License for the specific language governing permissions and
739 * limitations under the License.
740 */
741
742 #ifndef INCLUDE_PERFETTO_EXT_BASE_METATRACE_H_
743 #define INCLUDE_PERFETTO_EXT_BASE_METATRACE_H_
744
745 #include <array>
746 #include <atomic>
747 #include <functional>
748 #include <string>
749
750 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
751 // gen_amalgamated expanded: #include "perfetto/base/thread_utils.h"
752 // gen_amalgamated expanded: #include "perfetto/base/time.h"
753 // gen_amalgamated expanded: #include "perfetto/ext/base/metatrace_events.h"
754 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_annotations.h"
755 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
756
757 // A facility to trace execution of the perfetto codebase itself.
758 // The meta-tracing framework is organized into three layers:
759 //
760 // 1. A static ring-buffer in base/ (this file) that supports concurrent writes
761 // and a single reader.
762 // The responsibility of this layer is to store events and counters as
763 // efficiently as possible without re-entering any tracing code.
764 // This is really a static-storage-based ring-buffer based on a POD array.
765 // This layer does NOT deal with serializing the meta-trace buffer.
766 // It posts a task when it's half full and expects something outside of
767 // base/ to drain the ring-buffer and serialize it, eventually writing it
768 // into the trace itself, before it gets 100% full.
769 //
770 // 2. A class in tracing/core which takes care of serializing the meta-trace
771 // buffer into the trace using a TraceWriter. See metatrace_writer.h .
772 //
773 // 3. A data source in traced_probes that, when be enabled via the trace config,
774 // injects metatrace events into the trace. See metatrace_data_source.h .
775 //
776 // The available events and tags are defined in metatrace_events.h .
777
778 namespace perfetto {
779
780 namespace base {
781 class TaskRunner;
782 } // namespace base
783
784 namespace metatrace {
785
786 // Meta-tracing is organized in "tags" that can be selectively enabled. This is
787 // to enable meta-tracing only of one sub-system. This word has one "enabled"
788 // bit for each tag. 0 -> meta-tracing off.
789 extern std::atomic<uint32_t> g_enabled_tags;
790
791 // Time of the Enable() call. Used as a reference for keeping delta timestmaps
792 // in Record.
793 extern std::atomic<uint64_t> g_enabled_timestamp;
794
795 // Enables meta-tracing for one or more tags. Once enabled it will discard any
796 // further Enable() calls and return false until disabled,
797 // |read_task| is a closure that will be called enqueued |task_runner| when the
798 // meta-tracing ring buffer is half full. The task is expected to read the ring
799 // buffer using RingBuffer::GetReadIterator() and serialize the contents onto a
800 // file or into the trace itself.
801 // Must be called on the |task_runner| passed.
802 // |task_runner| must have static lifetime.
803 bool Enable(std::function<void()> read_task, base::TaskRunner*, uint32_t tags);
804
805 // Disables meta-tracing.
806 // Must be called on the same |task_runner| as Enable().
807 void Disable();
808
TraceTimeNowNs()809 inline uint64_t TraceTimeNowNs() {
810 return static_cast<uint64_t>(base::GetBootTimeNs().count());
811 }
812
813 // Returns a relaxed view of whether metatracing is enabled for the given tag.
814 // Useful for skipping unnecessary argument computation if metatracing is off.
IsEnabled(uint32_t tag)815 inline bool IsEnabled(uint32_t tag) {
816 auto enabled_tags = g_enabled_tags.load(std::memory_order_relaxed);
817 if (PERFETTO_LIKELY((enabled_tags & tag) == 0))
818 return false;
819 else
820 return true;
821 }
822
823 // Holds the data for a metatrace event or counter.
824 struct Record {
825 static constexpr uint16_t kTypeMask = 0x8000;
826 static constexpr uint16_t kTypeCounter = 0x8000;
827 static constexpr uint16_t kTypeEvent = 0;
828
timestamp_nsperfetto::metatrace::Record829 uint64_t timestamp_ns() const {
830 auto base_ns = g_enabled_timestamp.load(std::memory_order_relaxed);
831 PERFETTO_DCHECK(base_ns);
832 return base_ns + ((static_cast<uint64_t>(timestamp_ns_high) << 32) |
833 timestamp_ns_low);
834 }
835
set_timestampperfetto::metatrace::Record836 void set_timestamp(uint64_t ts) {
837 auto t_start = g_enabled_timestamp.load(std::memory_order_relaxed);
838 uint64_t diff = ts - t_start;
839 PERFETTO_DCHECK(diff < (1ull << 48));
840 timestamp_ns_low = static_cast<uint32_t>(diff);
841 timestamp_ns_high = static_cast<uint16_t>(diff >> 32);
842 }
843
844 // We can't just memset() this class because on MSVC std::atomic<> is not
845 // trivially constructible anymore. Also std::atomic<> has a deleted copy
846 // constructor so we cant just do "*this = Record()" either.
847 // See http://bit.ly/339Jlzd .
clearperfetto::metatrace::Record848 void clear() {
849 this->~Record();
850 new (this) Record();
851 }
852
853 // This field holds the type (counter vs event) in the MSB and event ID (as
854 // defined in metatrace_events.h) in the lowest 15 bits. It is also used also
855 // as a linearization point: this is always written after all the other
856 // fields with a release-store. This is so the reader can determine whether it
857 // can safely process the other event fields after a load-acquire.
858 std::atomic<uint16_t> type_and_id{};
859
860 // Timestamp is stored as a 48-bits value diffed against g_enabled_timestamp.
861 // This gives us 78 hours from Enabled().
862 uint16_t timestamp_ns_high = 0;
863 uint32_t timestamp_ns_low = 0;
864
865 uint32_t thread_id = 0;
866
867 union {
868 // Only one of the two elements can be zero initialized, clang complains
869 // about "initializing multiple members of union" otherwise.
870 uint32_t duration_ns = 0; // If type == event.
871 int32_t counter_value; // If type == counter.
872 };
873 };
874
875 // Hold the meta-tracing data into a statically allocated array.
876 // This class uses static storage (as opposite to being a singleton) to:
877 // - Have the guarantee of always valid storage, so that meta-tracing can be
878 // safely used in any part of the codebase, including base/ itself.
879 // - Avoid barriers that thread-safe static locals would require.
880 class RingBuffer {
881 public:
882 static constexpr size_t kCapacity = 4096; // 4096 * 16 bytes = 64K.
883
884 // This iterator is not idempotent and will bump the read index in the buffer
885 // at the end of the reads. There can be only one reader at any time.
886 // Usage: for (auto it = RingBuffer::GetReadIterator(); it; ++it) { it->... }
887 class ReadIterator {
888 public:
ReadIterator(ReadIterator && other)889 ReadIterator(ReadIterator&& other) {
890 PERFETTO_DCHECK(other.valid_);
891 cur_ = other.cur_;
892 end_ = other.end_;
893 valid_ = other.valid_;
894 other.valid_ = false;
895 }
896
~ReadIterator()897 ~ReadIterator() {
898 if (!valid_)
899 return;
900 PERFETTO_DCHECK(cur_ >= RingBuffer::rd_index_);
901 PERFETTO_DCHECK(cur_ <= RingBuffer::wr_index_);
902 RingBuffer::rd_index_.store(cur_, std::memory_order_release);
903 }
904
operator bool() const905 explicit operator bool() const { return cur_ < end_; }
operator ->() const906 const Record* operator->() const { return RingBuffer::At(cur_); }
operator *() const907 const Record& operator*() const { return *operator->(); }
908
909 // This is for ++it. it++ is deliberately not supported.
operator ++()910 ReadIterator& operator++() {
911 PERFETTO_DCHECK(cur_ < end_);
912 // Once a record has been read, mark it as free clearing its type_and_id,
913 // so if we encounter it in another read iteration while being written
914 // we know it's not fully written yet.
915 // The memory_order_relaxed below is enough because:
916 // - The reader is single-threaded and doesn't re-read the same records.
917 // - Before starting a read batch, the reader has an acquire barrier on
918 // |rd_index_|.
919 // - After terminating a read batch, the ~ReadIterator dtor updates the
920 // |rd_index_| with a release-store.
921 // - Reader and writer are typically kCapacity/2 apart. So unless an
922 // overrun happens a writer won't reuse a newly released record any time
923 // soon. If an overrun happens, everything is busted regardless.
924 At(cur_)->type_and_id.store(0, std::memory_order_relaxed);
925 ++cur_;
926 return *this;
927 }
928
929 private:
930 friend class RingBuffer;
ReadIterator(uint64_t begin,uint64_t end)931 ReadIterator(uint64_t begin, uint64_t end)
932 : cur_(begin), end_(end), valid_(true) {}
933 ReadIterator& operator=(const ReadIterator&) = delete;
934 ReadIterator(const ReadIterator&) = delete;
935
936 uint64_t cur_;
937 uint64_t end_;
938 bool valid_;
939 };
940
At(uint64_t index)941 static Record* At(uint64_t index) {
942 // Doesn't really have to be pow2, but if not the compiler will emit
943 // arithmetic operations to compute the modulo instead of a bitwise AND.
944 static_assert(!(kCapacity & (kCapacity - 1)), "kCapacity must be pow2");
945 PERFETTO_DCHECK(index >= rd_index_);
946 PERFETTO_DCHECK(index <= wr_index_);
947 return &records_[index % kCapacity];
948 }
949
950 // Must be called on the same task runner passed to Enable()
GetReadIterator()951 static ReadIterator GetReadIterator() {
952 PERFETTO_DCHECK(RingBuffer::IsOnValidTaskRunner());
953 return ReadIterator(rd_index_.load(std::memory_order_acquire),
954 wr_index_.load(std::memory_order_acquire));
955 }
956
957 static Record* AppendNewRecord();
958 static void Reset();
959
has_overruns()960 static bool has_overruns() {
961 return has_overruns_.load(std::memory_order_acquire);
962 }
963
964 // Can temporarily return a value >= kCapacity but is eventually consistent.
965 // This would happen in case of overruns until threads hit the --wr_index_
966 // in AppendNewRecord().
GetSizeForTesting()967 static uint64_t GetSizeForTesting() {
968 auto wr_index = wr_index_.load(std::memory_order_relaxed);
969 auto rd_index = rd_index_.load(std::memory_order_relaxed);
970 PERFETTO_DCHECK(wr_index >= rd_index);
971 return wr_index - rd_index;
972 }
973
974 private:
975 friend class ReadIterator;
976
977 // Returns true if the caller is on the task runner passed to Enable().
978 // Used only for DCHECKs.
979 static bool IsOnValidTaskRunner();
980
981 static std::array<Record, kCapacity> records_;
982 static std::atomic<bool> read_task_queued_;
983 static std::atomic<uint64_t> wr_index_;
984 static std::atomic<uint64_t> rd_index_;
985 static std::atomic<bool> has_overruns_;
986 static Record bankruptcy_record_; // Used in case of overruns.
987 };
988
TraceCounter(uint32_t tag,uint16_t id,int32_t value)989 inline void TraceCounter(uint32_t tag, uint16_t id, int32_t value) {
990 // memory_order_relaxed is okay because the storage has static lifetime.
991 // It is safe to accidentally log an event soon after disabling.
992 auto enabled_tags = g_enabled_tags.load(std::memory_order_relaxed);
993 if (PERFETTO_LIKELY((enabled_tags & tag) == 0))
994 return;
995 Record* record = RingBuffer::AppendNewRecord();
996 record->thread_id = static_cast<uint32_t>(base::GetThreadId());
997 record->set_timestamp(TraceTimeNowNs());
998 record->counter_value = value;
999 record->type_and_id.store(Record::kTypeCounter | id,
1000 std::memory_order_release);
1001 }
1002
1003 class ScopedEvent {
1004 public:
ScopedEvent(uint32_t tag,uint16_t event_id)1005 ScopedEvent(uint32_t tag, uint16_t event_id) {
1006 auto enabled_tags = g_enabled_tags.load(std::memory_order_relaxed);
1007 if (PERFETTO_LIKELY((enabled_tags & tag) == 0))
1008 return;
1009 event_id_ = event_id;
1010 record_ = RingBuffer::AppendNewRecord();
1011 record_->thread_id = static_cast<uint32_t>(base::GetThreadId());
1012 record_->set_timestamp(TraceTimeNowNs());
1013 }
1014
~ScopedEvent()1015 ~ScopedEvent() {
1016 if (PERFETTO_LIKELY(!record_))
1017 return;
1018 auto now = TraceTimeNowNs();
1019 record_->duration_ns = static_cast<uint32_t>(now - record_->timestamp_ns());
1020 record_->type_and_id.store(Record::kTypeEvent | event_id_,
1021 std::memory_order_release);
1022 }
1023
1024 private:
1025 Record* record_ = nullptr;
1026 uint16_t event_id_ = 0;
1027 ScopedEvent(const ScopedEvent&) = delete;
1028 ScopedEvent& operator=(const ScopedEvent&) = delete;
1029 };
1030
1031 // Boilerplate to derive a unique variable name for the event.
1032 #define PERFETTO_METATRACE_UID2(a, b) a##b
1033 #define PERFETTO_METATRACE_UID(x) PERFETTO_METATRACE_UID2(metatrace_, x)
1034
1035 #define PERFETTO_METATRACE_SCOPED(TAG, ID) \
1036 ::perfetto::metatrace::ScopedEvent PERFETTO_METATRACE_UID(__COUNTER__)( \
1037 ::perfetto::metatrace::TAG, ::perfetto::metatrace::ID)
1038
1039 #define PERFETTO_METATRACE_COUNTER(TAG, ID, VALUE) \
1040 ::perfetto::metatrace::TraceCounter(::perfetto::metatrace::TAG, \
1041 ::perfetto::metatrace::ID, \
1042 static_cast<int32_t>(VALUE))
1043
1044 } // namespace metatrace
1045 } // namespace perfetto
1046
1047 #endif // INCLUDE_PERFETTO_EXT_BASE_METATRACE_H_
1048 // gen_amalgamated begin header: include/perfetto/base/task_runner.h
1049 /*
1050 * Copyright (C) 2017 The Android Open Source Project
1051 *
1052 * Licensed under the Apache License, Version 2.0 (the "License");
1053 * you may not use this file except in compliance with the License.
1054 * You may obtain a copy of the License at
1055 *
1056 * http://www.apache.org/licenses/LICENSE-2.0
1057 *
1058 * Unless required by applicable law or agreed to in writing, software
1059 * distributed under the License is distributed on an "AS IS" BASIS,
1060 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1061 * See the License for the specific language governing permissions and
1062 * limitations under the License.
1063 */
1064
1065 #ifndef INCLUDE_PERFETTO_BASE_TASK_RUNNER_H_
1066 #define INCLUDE_PERFETTO_BASE_TASK_RUNNER_H_
1067
1068 #include <stdint.h>
1069
1070 #include <functional>
1071
1072 // gen_amalgamated expanded: #include "perfetto/base/export.h"
1073
1074 namespace perfetto {
1075 namespace base {
1076
1077 // A generic interface to allow the library clients to interleave the execution
1078 // of the tracing internals in their runtime environment.
1079 // The expectation is that all tasks, which are queued either via PostTask() or
1080 // AddFileDescriptorWatch(), are executed on the same sequence (either on the
1081 // same thread, or on a thread pool that gives sequencing guarantees).
1082 //
1083 // Tasks are never executed synchronously inside PostTask and there is a full
1084 // memory barrier between tasks.
1085 //
1086 // All methods of this interface can be called from any thread.
1087 class PERFETTO_EXPORT TaskRunner {
1088 public:
1089 virtual ~TaskRunner();
1090
1091 // Schedule a task for immediate execution. Immediate tasks are always
1092 // executed in the order they are posted. Can be called from any thread.
1093 virtual void PostTask(std::function<void()>) = 0;
1094
1095 // Schedule a task for execution after |delay_ms|. Note that there is no
1096 // strict ordering guarantee between immediate and delayed tasks. Can be
1097 // called from any thread.
1098 virtual void PostDelayedTask(std::function<void()>, uint32_t delay_ms) = 0;
1099
1100 // Schedule a task to run when |fd| becomes readable. The same |fd| can only
1101 // be monitored by one function. Note that this function only needs to be
1102 // implemented on platforms where the built-in ipc framework is used. Can be
1103 // called from any thread.
1104 // TODO(skyostil): Refactor this out of the shared interface.
1105 virtual void AddFileDescriptorWatch(int fd, std::function<void()>) = 0;
1106
1107 // Remove a previously scheduled watch for |fd|. If this is run on the target
1108 // thread of this TaskRunner, guarantees that the task registered to this fd
1109 // will not be executed after this function call. Can be called from any
1110 // thread.
1111 virtual void RemoveFileDescriptorWatch(int fd) = 0;
1112
1113 // Checks if the current thread is the same thread where the TaskRunner's task
1114 // run. This allows single threaded task runners (like the ones used in
1115 // perfetto) to inform the caller that anything posted will run on the same
1116 // thread/sequence. This can allow some callers to skip PostTask and instead
1117 // directly execute the code. Can be called from any thread.
1118 virtual bool RunsTasksOnCurrentThread() const = 0;
1119 };
1120
1121 } // namespace base
1122 } // namespace perfetto
1123
1124 #endif // INCLUDE_PERFETTO_BASE_TASK_RUNNER_H_
1125 /*
1126 * Copyright (C) 2018 The Android Open Source Project
1127 *
1128 * Licensed under the Apache License, Version 2.0 (the "License");
1129 * you may not use this file except in compliance with the License.
1130 * You may obtain a copy of the License at
1131 *
1132 * http://www.apache.org/licenses/LICENSE-2.0
1133 *
1134 * Unless required by applicable law or agreed to in writing, software
1135 * distributed under the License is distributed on an "AS IS" BASIS,
1136 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1137 * See the License for the specific language governing permissions and
1138 * limitations under the License.
1139 */
1140
1141 // gen_amalgamated expanded: #include "perfetto/ext/base/metatrace.h"
1142
1143 // gen_amalgamated expanded: #include "perfetto/base/compiler.h"
1144 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
1145 // gen_amalgamated expanded: #include "perfetto/base/time.h"
1146 // gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
1147
1148 namespace perfetto {
1149 namespace metatrace {
1150
1151 std::atomic<uint32_t> g_enabled_tags{0};
1152 std::atomic<uint64_t> g_enabled_timestamp{0};
1153
1154 // static members
1155 constexpr size_t RingBuffer::kCapacity;
1156 std::array<Record, RingBuffer::kCapacity> RingBuffer::records_;
1157 std::atomic<bool> RingBuffer::read_task_queued_;
1158 std::atomic<uint64_t> RingBuffer::wr_index_;
1159 std::atomic<uint64_t> RingBuffer::rd_index_;
1160 std::atomic<bool> RingBuffer::has_overruns_;
1161 Record RingBuffer::bankruptcy_record_;
1162
1163 constexpr uint16_t Record::kTypeMask;
1164 constexpr uint16_t Record::kTypeCounter;
1165 constexpr uint16_t Record::kTypeEvent;
1166
1167 namespace {
1168
1169 // std::function<> is not trivially de/constructible. This struct wraps it in a
1170 // heap-allocated struct to avoid static initializers.
1171 struct Delegate {
GetInstanceperfetto::metatrace::__anon7bab3a4f0411::Delegate1172 static Delegate* GetInstance() {
1173 static Delegate* instance = new Delegate();
1174 return instance;
1175 }
1176
1177 base::TaskRunner* task_runner = nullptr;
1178 std::function<void()> read_task;
1179 };
1180
1181 } // namespace
1182
Enable(std::function<void ()> read_task,base::TaskRunner * task_runner,uint32_t tags)1183 bool Enable(std::function<void()> read_task,
1184 base::TaskRunner* task_runner,
1185 uint32_t tags) {
1186 PERFETTO_DCHECK(read_task);
1187 PERFETTO_DCHECK(task_runner->RunsTasksOnCurrentThread());
1188 if (g_enabled_tags.load(std::memory_order_acquire))
1189 return false;
1190
1191 Delegate* dg = Delegate::GetInstance();
1192 dg->task_runner = task_runner;
1193 dg->read_task = std::move(read_task);
1194 RingBuffer::Reset();
1195 g_enabled_timestamp.store(TraceTimeNowNs(), std::memory_order_relaxed);
1196 g_enabled_tags.store(tags, std::memory_order_release);
1197 return true;
1198 }
1199
Disable()1200 void Disable() {
1201 g_enabled_tags.store(0, std::memory_order_release);
1202 Delegate* dg = Delegate::GetInstance();
1203 PERFETTO_DCHECK(!dg->task_runner ||
1204 dg->task_runner->RunsTasksOnCurrentThread());
1205 dg->task_runner = nullptr;
1206 dg->read_task = nullptr;
1207 }
1208
1209 // static
Reset()1210 void RingBuffer::Reset() {
1211 bankruptcy_record_.clear();
1212 for (Record& record : records_)
1213 record.clear();
1214 wr_index_ = 0;
1215 rd_index_ = 0;
1216 has_overruns_ = false;
1217 read_task_queued_ = false;
1218 }
1219
1220 // static
AppendNewRecord()1221 Record* RingBuffer::AppendNewRecord() {
1222 auto wr_index = wr_index_.fetch_add(1, std::memory_order_acq_rel);
1223
1224 // rd_index can only monotonically increase, we don't care if we read an
1225 // older value, we'll just hit the slow-path a bit earlier if it happens.
1226 auto rd_index = rd_index_.load(std::memory_order_relaxed);
1227
1228 PERFETTO_DCHECK(wr_index >= rd_index);
1229 auto size = wr_index - rd_index;
1230 if (PERFETTO_LIKELY(size < kCapacity / 2))
1231 return At(wr_index);
1232
1233 // Slow-path: Enqueue the read task and handle overruns.
1234 bool expected = false;
1235 if (RingBuffer::read_task_queued_.compare_exchange_strong(expected, true)) {
1236 Delegate* dg = Delegate::GetInstance();
1237 if (dg->task_runner) {
1238 dg->task_runner->PostTask([] {
1239 // Meta-tracing might have been disabled in the meantime.
1240 auto read_task = Delegate::GetInstance()->read_task;
1241 if (read_task)
1242 read_task();
1243 RingBuffer::read_task_queued_ = false;
1244 });
1245 }
1246 }
1247
1248 if (PERFETTO_LIKELY(size < kCapacity))
1249 return At(wr_index);
1250
1251 has_overruns_.store(true, std::memory_order_release);
1252 wr_index_.fetch_sub(1, std::memory_order_acq_rel);
1253
1254 // In the case of overflows, threads will race writing on the same memory
1255 // location and TSan will rightly complain. This is fine though because nobody
1256 // will read the bankruptcy record and it's designed to contain garbage.
1257 PERFETTO_ANNOTATE_BENIGN_RACE_SIZED(&bankruptcy_record_, sizeof(Record),
1258 "nothing reads bankruptcy_record_")
1259 return &bankruptcy_record_;
1260 }
1261
1262 // static
IsOnValidTaskRunner()1263 bool RingBuffer::IsOnValidTaskRunner() {
1264 auto* task_runner = Delegate::GetInstance()->task_runner;
1265 return task_runner && task_runner->RunsTasksOnCurrentThread();
1266 }
1267
1268 } // namespace metatrace
1269 } // namespace perfetto
1270 // gen_amalgamated begin source: src/base/paged_memory.cc
1271 // gen_amalgamated begin header: include/perfetto/ext/base/paged_memory.h
1272 // gen_amalgamated begin header: include/perfetto/ext/base/container_annotations.h
1273 /*
1274 * Copyright (C) 2018 The Android Open Source Project
1275 *
1276 * Licensed under the Apache License, Version 2.0 (the "License");
1277 * you may not use this file except in compliance with the License.
1278 * You may obtain a copy of the License at
1279 *
1280 * http://www.apache.org/licenses/LICENSE-2.0
1281 *
1282 * Unless required by applicable law or agreed to in writing, software
1283 * distributed under the License is distributed on an "AS IS" BASIS,
1284 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1285 * See the License for the specific language governing permissions and
1286 * limitations under the License.
1287 */
1288
1289 #ifndef INCLUDE_PERFETTO_EXT_BASE_CONTAINER_ANNOTATIONS_H_
1290 #define INCLUDE_PERFETTO_EXT_BASE_CONTAINER_ANNOTATIONS_H_
1291
1292 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
1293
1294 // Windows ASAN doesn't currently support these annotations.
1295 #if defined(ADDRESS_SANITIZER) && !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) && \
1296 !defined(ADDRESS_SANITIZER_WITHOUT_INSTRUMENTATION)
1297
1298 #define ANNOTATE_NEW_BUFFER(buffer, capacity, new_size) \
1299 if (buffer) { \
1300 __sanitizer_annotate_contiguous_container(buffer, (buffer) + (capacity), \
1301 (buffer) + (capacity), \
1302 (buffer) + (new_size)); \
1303 }
1304 #define ANNOTATE_DELETE_BUFFER(buffer, capacity, old_size) \
1305 if (buffer) { \
1306 __sanitizer_annotate_contiguous_container(buffer, (buffer) + (capacity), \
1307 (buffer) + (old_size), \
1308 (buffer) + (capacity)); \
1309 }
1310 #define ANNOTATE_CHANGE_SIZE(buffer, capacity, old_size, new_size) \
1311 if (buffer) { \
1312 __sanitizer_annotate_contiguous_container(buffer, (buffer) + (capacity), \
1313 (buffer) + (old_size), \
1314 (buffer) + (new_size)); \
1315 }
1316 #define ANNOTATE_CHANGE_CAPACITY(buffer, old_capacity, buffer_size, \
1317 new_capacity) \
1318 ANNOTATE_DELETE_BUFFER(buffer, old_capacity, buffer_size); \
1319 ANNOTATE_NEW_BUFFER(buffer, new_capacity, buffer_size);
1320 // Annotations require buffers to begin on an 8-byte boundary.
1321 #else // defined(ADDRESS_SANITIZER)
1322 #define ANNOTATE_NEW_BUFFER(buffer, capacity, new_size)
1323 #define ANNOTATE_DELETE_BUFFER(buffer, capacity, old_size)
1324 #define ANNOTATE_CHANGE_SIZE(buffer, capacity, old_size, new_size)
1325 #define ANNOTATE_CHANGE_CAPACITY(buffer, old_capacity, buffer_size, \
1326 new_capacity)
1327 #endif // defined(ADDRESS_SANITIZER)
1328
1329 #endif // INCLUDE_PERFETTO_EXT_BASE_CONTAINER_ANNOTATIONS_H_
1330 /*
1331 * Copyright (C) 2017 The Android Open Source Project
1332 *
1333 * Licensed under the Apache License, Version 2.0 (the "License");
1334 * you may not use this file except in compliance with the License.
1335 * You may obtain a copy of the License at
1336 *
1337 * http://www.apache.org/licenses/LICENSE-2.0
1338 *
1339 * Unless required by applicable law or agreed to in writing, software
1340 * distributed under the License is distributed on an "AS IS" BASIS,
1341 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1342 * See the License for the specific language governing permissions and
1343 * limitations under the License.
1344 */
1345
1346 #ifndef INCLUDE_PERFETTO_EXT_BASE_PAGED_MEMORY_H_
1347 #define INCLUDE_PERFETTO_EXT_BASE_PAGED_MEMORY_H_
1348
1349 #include <memory>
1350
1351 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
1352 // gen_amalgamated expanded: #include "perfetto/ext/base/container_annotations.h"
1353
1354 // We need to track the committed size on windows and when ASAN is enabled.
1355 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) || defined(ADDRESS_SANITIZER)
1356 #define TRACK_COMMITTED_SIZE() 1
1357 #else
1358 #define TRACK_COMMITTED_SIZE() 0
1359 #endif
1360
1361 namespace perfetto {
1362 namespace base {
1363
1364 class PagedMemory {
1365 public:
1366 // Initializes an invalid PagedMemory pointing to nullptr.
1367 PagedMemory();
1368
1369 ~PagedMemory();
1370
1371 PagedMemory(PagedMemory&& other) noexcept;
1372 PagedMemory& operator=(PagedMemory&& other);
1373
1374 enum AllocationFlags {
1375 // By default, Allocate() crashes if the underlying mmap fails (e.g., if out
1376 // of virtual address space). When this flag is provided, an invalid
1377 // PagedMemory pointing to nullptr is returned in this case instead.
1378 kMayFail = 1 << 0,
1379
1380 // By default, Allocate() commits the allocated memory immediately. When
1381 // this flag is provided, the memory virtual address space may only be
1382 // reserved and the user should call EnsureCommitted() before writing to
1383 // memory addresses.
1384 kDontCommit = 1 << 1,
1385 };
1386
1387 // Allocates |size| bytes using mmap(MAP_ANONYMOUS). The returned memory is
1388 // guaranteed to be page-aligned and guaranteed to be zeroed.
1389 // For |flags|, see the AllocationFlags enum above.
1390 static PagedMemory Allocate(size_t size, int flags = 0);
1391
1392 // Hint to the OS that the memory range is not needed and can be discarded.
1393 // The memory remains accessible and its contents may be retained, or they
1394 // may be zeroed. This function may be a NOP on some platforms. Returns true
1395 // if implemented.
1396 bool AdviseDontNeed(void* p, size_t size);
1397
1398 // Ensures that at least the first |committed_size| bytes of the allocated
1399 // memory region are committed. The implementation may commit memory in larger
1400 // chunks above |committed_size|. Crashes if the memory couldn't be committed.
1401 #if TRACK_COMMITTED_SIZE()
1402 void EnsureCommitted(size_t committed_size);
1403 #else // TRACK_COMMITTED_SIZE()
EnsureCommitted(size_t)1404 void EnsureCommitted(size_t /*committed_size*/) {}
1405 #endif // TRACK_COMMITTED_SIZE()
1406
Get() const1407 inline void* Get() const noexcept { return p_; }
IsValid() const1408 inline bool IsValid() const noexcept { return !!p_; }
size() const1409 inline size_t size() const noexcept { return size_; }
1410
1411 private:
1412 PagedMemory(char* p, size_t size);
1413
1414 PagedMemory(const PagedMemory&) = delete;
1415 // Defaulted for implementation of move constructor + assignment.
1416 PagedMemory& operator=(const PagedMemory&) = default;
1417
1418 char* p_ = nullptr;
1419
1420 // The size originally passed to Allocate(). The actual virtual memory
1421 // reservation will be larger due to: (i) guard pages; (ii) rounding up to
1422 // the system page size.
1423 size_t size_ = 0;
1424
1425 #if TRACK_COMMITTED_SIZE()
1426 size_t committed_size_ = 0u;
1427 #endif // TRACK_COMMITTED_SIZE()
1428 };
1429
1430 } // namespace base
1431 } // namespace perfetto
1432
1433 #endif // INCLUDE_PERFETTO_EXT_BASE_PAGED_MEMORY_H_
1434 /*
1435 * Copyright (C) 2017 The Android Open Source Project
1436 *
1437 * Licensed under the Apache License, Version 2.0 (the "License");
1438 * you may not use this file except in compliance with the License.
1439 * You may obtain a copy of the License at
1440 *
1441 * http://www.apache.org/licenses/LICENSE-2.0
1442 *
1443 * Unless required by applicable law or agreed to in writing, software
1444 * distributed under the License is distributed on an "AS IS" BASIS,
1445 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1446 * See the License for the specific language governing permissions and
1447 * limitations under the License.
1448 */
1449
1450 // gen_amalgamated expanded: #include "perfetto/ext/base/paged_memory.h"
1451
1452 #include <algorithm>
1453 #include <cmath>
1454
1455 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
1456 #include <Windows.h>
1457 #else // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
1458 #include <sys/mman.h>
1459 #endif // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
1460
1461 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
1462 // gen_amalgamated expanded: #include "perfetto/ext/base/container_annotations.h"
1463 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
1464
1465 namespace perfetto {
1466 namespace base {
1467
1468 namespace {
1469
1470 #if TRACK_COMMITTED_SIZE()
1471 constexpr size_t kCommitChunkSize = 4 * 1024 * 1024; // 4MB
1472 #endif
1473
RoundUpToSysPageSize(size_t req_size)1474 size_t RoundUpToSysPageSize(size_t req_size) {
1475 const size_t page_size = GetSysPageSize();
1476 return (req_size + page_size - 1) & ~(page_size - 1);
1477 }
1478
GuardSize()1479 size_t GuardSize() {
1480 return GetSysPageSize();
1481 }
1482
1483 } // namespace
1484
1485 // static
Allocate(size_t req_size,int flags)1486 PagedMemory PagedMemory::Allocate(size_t req_size, int flags) {
1487 size_t rounded_up_size = RoundUpToSysPageSize(req_size);
1488 PERFETTO_CHECK(rounded_up_size >= req_size);
1489 size_t outer_size = rounded_up_size + GuardSize() * 2;
1490 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
1491 void* ptr = VirtualAlloc(nullptr, outer_size, MEM_RESERVE, PAGE_NOACCESS);
1492 if (!ptr && (flags & kMayFail))
1493 return PagedMemory();
1494 PERFETTO_CHECK(ptr);
1495 char* usable_region = reinterpret_cast<char*>(ptr) + GuardSize();
1496 #else // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
1497 void* ptr = mmap(nullptr, outer_size, PROT_READ | PROT_WRITE,
1498 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
1499 if (ptr == MAP_FAILED && (flags & kMayFail))
1500 return PagedMemory();
1501 PERFETTO_CHECK(ptr && ptr != MAP_FAILED);
1502 char* usable_region = reinterpret_cast<char*>(ptr) + GuardSize();
1503 int res = mprotect(ptr, GuardSize(), PROT_NONE);
1504 res |= mprotect(usable_region + rounded_up_size, GuardSize(), PROT_NONE);
1505 PERFETTO_CHECK(res == 0);
1506 #endif // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
1507
1508 auto memory = PagedMemory(usable_region, req_size);
1509 #if TRACK_COMMITTED_SIZE()
1510 size_t initial_commit = req_size;
1511 if (flags & kDontCommit)
1512 initial_commit = std::min(initial_commit, kCommitChunkSize);
1513 memory.EnsureCommitted(initial_commit);
1514 #endif // TRACK_COMMITTED_SIZE()
1515 return memory;
1516 }
1517
PagedMemory()1518 PagedMemory::PagedMemory() {}
1519
1520 // clang-format off
PagedMemory(char * p,size_t size)1521 PagedMemory::PagedMemory(char* p, size_t size) : p_(p), size_(size) {
1522 ANNOTATE_NEW_BUFFER(p_, size_, committed_size_)
1523 }
1524
PagedMemory(PagedMemory && other)1525 PagedMemory::PagedMemory(PagedMemory&& other) noexcept {
1526 *this = other;
1527 other.p_ = nullptr;
1528 }
1529 // clang-format on
1530
operator =(PagedMemory && other)1531 PagedMemory& PagedMemory::operator=(PagedMemory&& other) {
1532 this->~PagedMemory();
1533 new (this) PagedMemory(std::move(other));
1534 return *this;
1535 }
1536
~PagedMemory()1537 PagedMemory::~PagedMemory() {
1538 if (!p_)
1539 return;
1540 PERFETTO_CHECK(size_);
1541 char* start = p_ - GuardSize();
1542 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
1543 BOOL res = VirtualFree(start, 0, MEM_RELEASE);
1544 PERFETTO_CHECK(res != 0);
1545 #else // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
1546 const size_t outer_size = RoundUpToSysPageSize(size_) + GuardSize() * 2;
1547 int res = munmap(start, outer_size);
1548 PERFETTO_CHECK(res == 0);
1549 #endif // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
1550 ANNOTATE_DELETE_BUFFER(p_, size_, committed_size_)
1551 }
1552
AdviseDontNeed(void * p,size_t size)1553 bool PagedMemory::AdviseDontNeed(void* p, size_t size) {
1554 PERFETTO_DCHECK(p_);
1555 PERFETTO_DCHECK(p >= p_);
1556 PERFETTO_DCHECK(static_cast<char*>(p) + size <= p_ + size_);
1557 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) || PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
1558 // Discarding pages on Windows has more CPU cost than is justified for the
1559 // possible memory savings.
1560 return false;
1561 #else // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) ||
1562 // PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
1563 // http://man7.org/linux/man-pages/man2/madvise.2.html
1564 int res = madvise(p, size, MADV_DONTNEED);
1565 PERFETTO_DCHECK(res == 0);
1566 return true;
1567 #endif // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) ||
1568 // PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
1569 }
1570
1571 #if TRACK_COMMITTED_SIZE()
EnsureCommitted(size_t committed_size)1572 void PagedMemory::EnsureCommitted(size_t committed_size) {
1573 PERFETTO_DCHECK(committed_size > 0u);
1574 PERFETTO_DCHECK(committed_size <= size_);
1575 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
1576 if (committed_size_ >= committed_size)
1577 return;
1578 // Rounding up.
1579 size_t delta = committed_size - committed_size_;
1580 size_t num_additional_chunks =
1581 (delta + kCommitChunkSize - 1) / kCommitChunkSize;
1582 PERFETTO_DCHECK(num_additional_chunks * kCommitChunkSize >= delta);
1583 // Don't commit more than the total size.
1584 size_t commit_size = std::min(num_additional_chunks * kCommitChunkSize,
1585 size_ - committed_size_);
1586 void* res = VirtualAlloc(p_ + committed_size_, commit_size, MEM_COMMIT,
1587 PAGE_READWRITE);
1588 PERFETTO_CHECK(res);
1589 ANNOTATE_CHANGE_SIZE(p_, size_, committed_size_,
1590 committed_size_ + commit_size)
1591 committed_size_ += commit_size;
1592 #else // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
1593 // mmap commits automatically as needed, so we only track here for ASAN.
1594 committed_size = std::max(committed_size_, committed_size);
1595 ANNOTATE_CHANGE_SIZE(p_, size_, committed_size_, committed_size)
1596 committed_size_ = committed_size;
1597 #endif // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
1598 }
1599 #endif // TRACK_COMMITTED_SIZE()
1600
1601 } // namespace base
1602 } // namespace perfetto
1603 // gen_amalgamated begin source: src/base/string_splitter.cc
1604 // gen_amalgamated begin header: include/perfetto/ext/base/string_splitter.h
1605 /*
1606 * Copyright (C) 2018 The Android Open Source Project
1607 *
1608 * Licensed under the Apache License, Version 2.0 (the "License");
1609 * you may not use this file except in compliance with the License.
1610 * You may obtain a copy of the License at
1611 *
1612 * http://www.apache.org/licenses/LICENSE-2.0
1613 *
1614 * Unless required by applicable law or agreed to in writing, software
1615 * distributed under the License is distributed on an "AS IS" BASIS,
1616 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1617 * See the License for the specific language governing permissions and
1618 * limitations under the License.
1619 */
1620
1621 #ifndef INCLUDE_PERFETTO_EXT_BASE_STRING_SPLITTER_H_
1622 #define INCLUDE_PERFETTO_EXT_BASE_STRING_SPLITTER_H_
1623
1624 #include <string>
1625
1626 namespace perfetto {
1627 namespace base {
1628
1629 // C++ version of strtok(). Splits a string without making copies or any heap
1630 // allocations. Destructs the original string passed in input.
1631 // Supports the special case of using \0 as a delimiter.
1632 // The token returned in output are valid as long as the input string is valid.
1633 class StringSplitter {
1634 public:
1635 // Can take ownership of the string if passed via std::move(), e.g.:
1636 // StringSplitter(std::move(str), '\n');
1637 StringSplitter(std::string, char delimiter);
1638
1639 // Splits a C-string. The input string will be forcefully null-terminated (so
1640 // str[size - 1] should be == '\0' or the last char will be truncated).
1641 StringSplitter(char* str, size_t size, char delimiter);
1642
1643 // Splits the current token from an outer StringSplitter instance. This is to
1644 // chain splitters as follows:
1645 // for (base::StringSplitter lines(x, '\n'); ss.Next();)
1646 // for (base::StringSplitter words(&lines, ' '); words.Next();)
1647 StringSplitter(StringSplitter*, char delimiter);
1648
1649 // Returns true if a token is found (in which case it will be stored in
1650 // cur_token()), false if no more tokens are found.
1651 bool Next();
1652
1653 // Returns the current token iff last call to Next() returned true. In this
1654 // case it guarantees that the returned string is always null terminated.
1655 // In all other cases (before the 1st call to Next() and after Next() returns
1656 // false) returns nullptr.
cur_token()1657 char* cur_token() { return cur_; }
1658
1659 // Returns the length of the current token (excluding the null terminator).
cur_token_size() const1660 size_t cur_token_size() const { return cur_size_; }
1661
1662 private:
1663 StringSplitter(const StringSplitter&) = delete;
1664 StringSplitter& operator=(const StringSplitter&) = delete;
1665 void Initialize(char* str, size_t size);
1666
1667 std::string str_;
1668 char* cur_;
1669 size_t cur_size_;
1670 char* next_;
1671 char* end_; // STL-style, points one past the last char.
1672 const char delimiter_;
1673 };
1674
1675 } // namespace base
1676 } // namespace perfetto
1677
1678 #endif // INCLUDE_PERFETTO_EXT_BASE_STRING_SPLITTER_H_
1679 /*
1680 * Copyright (C) 2018 The Android Open Source Project
1681 *
1682 * Licensed under the Apache License, Version 2.0 (the "License");
1683 * you may not use this file except in compliance with the License.
1684 * You may obtain a copy of the License at
1685 *
1686 * http://www.apache.org/licenses/LICENSE-2.0
1687 *
1688 * Unless required by applicable law or agreed to in writing, software
1689 * distributed under the License is distributed on an "AS IS" BASIS,
1690 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1691 * See the License for the specific language governing permissions and
1692 * limitations under the License.
1693 */
1694
1695 // gen_amalgamated expanded: #include "perfetto/ext/base/string_splitter.h"
1696
1697 #include <utility>
1698
1699 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
1700
1701 namespace perfetto {
1702 namespace base {
1703
StringSplitter(std::string str,char delimiter)1704 StringSplitter::StringSplitter(std::string str, char delimiter)
1705 : str_(std::move(str)), delimiter_(delimiter) {
1706 // It's legal to access str[str.size()] in C++11 (it always returns \0),
1707 // hence the +1 (which becomes just size() after the -1 in Initialize()).
1708 Initialize(&str_[0], str_.size() + 1);
1709 }
1710
StringSplitter(char * str,size_t size,char delimiter)1711 StringSplitter::StringSplitter(char* str, size_t size, char delimiter)
1712 : delimiter_(delimiter) {
1713 Initialize(str, size);
1714 }
1715
StringSplitter(StringSplitter * outer,char delimiter)1716 StringSplitter::StringSplitter(StringSplitter* outer, char delimiter)
1717 : delimiter_(delimiter) {
1718 Initialize(outer->cur_token(), outer->cur_token_size() + 1);
1719 }
1720
Initialize(char * str,size_t size)1721 void StringSplitter::Initialize(char* str, size_t size) {
1722 PERFETTO_DCHECK(!size || str);
1723 next_ = str;
1724 end_ = str + size;
1725 cur_ = nullptr;
1726 cur_size_ = 0;
1727 if (size)
1728 next_[size - 1] = '\0';
1729 }
1730
Next()1731 bool StringSplitter::Next() {
1732 for (; next_ < end_; next_++) {
1733 if (*next_ == delimiter_)
1734 continue;
1735 cur_ = next_;
1736 for (;; next_++) {
1737 if (*next_ == delimiter_) {
1738 cur_size_ = static_cast<size_t>(next_ - cur_);
1739 *(next_++) = '\0';
1740 break;
1741 }
1742 if (*next_ == '\0') {
1743 cur_size_ = static_cast<size_t>(next_ - cur_);
1744 next_ = end_;
1745 break;
1746 }
1747 }
1748 if (*cur_)
1749 return true;
1750 break;
1751 }
1752 cur_ = nullptr;
1753 cur_size_ = 0;
1754 return false;
1755 }
1756
1757 } // namespace base
1758 } // namespace perfetto
1759 // gen_amalgamated begin source: src/base/string_utils.cc
1760 // gen_amalgamated begin header: include/perfetto/ext/base/string_utils.h
1761 // gen_amalgamated begin header: include/perfetto/ext/base/optional.h
1762 /*
1763 * Copyright (C) 2018 The Android Open Source Project
1764 *
1765 * Licensed under the Apache License, Version 2.0 (the "License");
1766 * you may not use this file except in compliance with the License.
1767 * You may obtain a copy of the License at
1768 *
1769 * http://www.apache.org/licenses/LICENSE-2.0
1770 *
1771 * Unless required by applicable law or agreed to in writing, software
1772 * distributed under the License is distributed on an "AS IS" BASIS,
1773 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1774 * See the License for the specific language governing permissions and
1775 * limitations under the License.
1776 */
1777
1778 #ifndef INCLUDE_PERFETTO_EXT_BASE_OPTIONAL_H_
1779 #define INCLUDE_PERFETTO_EXT_BASE_OPTIONAL_H_
1780
1781 #include <functional>
1782 #include <type_traits>
1783 #include <utility>
1784
1785 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
1786
1787 namespace perfetto {
1788 namespace base {
1789
1790 // Specification:
1791 // http://en.cppreference.com/w/cpp/utility/optional/in_place_t
1792 struct in_place_t {};
1793
1794 // Specification:
1795 // http://en.cppreference.com/w/cpp/utility/optional/nullopt_t
1796 struct nullopt_t {
nullopt_tperfetto::base::nullopt_t1797 constexpr explicit nullopt_t(int) {}
1798 };
1799
1800 // Specification:
1801 // http://en.cppreference.com/w/cpp/utility/optional/in_place
1802 constexpr in_place_t in_place = {};
1803
1804 // Specification:
1805 // http://en.cppreference.com/w/cpp/utility/optional/nullopt
1806 constexpr nullopt_t nullopt(0);
1807
1808 // Forward declaration, which is referred by following helpers.
1809 template <typename T>
1810 class Optional;
1811
1812 namespace internal {
1813
1814 template <typename T, bool = std::is_trivially_destructible<T>::value>
1815 struct OptionalStorageBase {
1816 // Initializing |empty_| here instead of using default member initializing
1817 // to avoid errors in g++ 4.8.
OptionalStorageBaseperfetto::base::internal::OptionalStorageBase1818 constexpr OptionalStorageBase() : empty_('\0') {}
1819
1820 template <class... Args>
OptionalStorageBaseperfetto::base::internal::OptionalStorageBase1821 constexpr explicit OptionalStorageBase(in_place_t, Args&&... args)
1822 : is_populated_(true), value_(std::forward<Args>(args)...) {}
1823
1824 // When T is not trivially destructible we must call its
1825 // destructor before deallocating its memory.
1826 // Note that this hides the (implicitly declared) move constructor, which
1827 // would be used for constexpr move constructor in OptionalStorage<T>.
1828 // It is needed iff T is trivially move constructible. However, the current
1829 // is_trivially_{copy,move}_constructible implementation requires
1830 // is_trivially_destructible (which looks a bug, cf:
1831 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51452 and
1832 // http://cplusplus.github.io/LWG/lwg-active.html#2116), so it is not
1833 // necessary for this case at the moment. Please see also the destructor
1834 // comment in "is_trivially_destructible = true" specialization below.
~OptionalStorageBaseperfetto::base::internal::OptionalStorageBase1835 ~OptionalStorageBase() {
1836 if (is_populated_)
1837 value_.~T();
1838 }
1839
1840 template <class... Args>
Initperfetto::base::internal::OptionalStorageBase1841 void Init(Args&&... args) {
1842 PERFETTO_DCHECK(!is_populated_);
1843 ::new (&value_) T(std::forward<Args>(args)...);
1844 is_populated_ = true;
1845 }
1846
1847 bool is_populated_ = false;
1848 union {
1849 // |empty_| exists so that the union will always be initialized, even when
1850 // it doesn't contain a value. Union members must be initialized for the
1851 // constructor to be 'constexpr'.
1852 char empty_;
1853 T value_;
1854 };
1855 };
1856
1857 template <typename T>
1858 struct OptionalStorageBase<T, true /* trivially destructible */> {
1859 // Initializing |empty_| here instead of using default member initializing
1860 // to avoid errors in g++ 4.8.
OptionalStorageBaseperfetto::base::internal::OptionalStorageBase1861 constexpr OptionalStorageBase() : empty_('\0') {}
1862
1863 template <class... Args>
OptionalStorageBaseperfetto::base::internal::OptionalStorageBase1864 constexpr explicit OptionalStorageBase(in_place_t, Args&&... args)
1865 : is_populated_(true), value_(std::forward<Args>(args)...) {}
1866
1867 // When T is trivially destructible (i.e. its destructor does nothing) there
1868 // is no need to call it. Implicitly defined destructor is trivial, because
1869 // both members (bool and union containing only variants which are trivially
1870 // destructible) are trivially destructible.
1871 // Explicitly-defaulted destructor is also trivial, but do not use it here,
1872 // because it hides the implicit move constructor. It is needed to implement
1873 // constexpr move constructor in OptionalStorage iff T is trivially move
1874 // constructible. Note that, if T is trivially move constructible, the move
1875 // constructor of OptionalStorageBase<T> is also implicitly defined and it is
1876 // trivially move constructor. If T is not trivially move constructible,
1877 // "not declaring move constructor without destructor declaration" here means
1878 // "delete move constructor", which works because any move constructor of
1879 // OptionalStorage will not refer to it in that case.
1880
1881 template <class... Args>
Initperfetto::base::internal::OptionalStorageBase1882 void Init(Args&&... args) {
1883 PERFETTO_DCHECK(!is_populated_);
1884 ::new (&value_) T(std::forward<Args>(args)...);
1885 is_populated_ = true;
1886 }
1887
1888 bool is_populated_ = false;
1889 union {
1890 // |empty_| exists so that the union will always be initialized, even when
1891 // it doesn't contain a value. Union members must be initialized for the
1892 // constructor to be 'constexpr'.
1893 char empty_;
1894 T value_;
1895 };
1896 };
1897
1898 // Implement conditional constexpr copy and move constructors. These are
1899 // constexpr if is_trivially_{copy,move}_constructible<T>::value is true
1900 // respectively. If each is true, the corresponding constructor is defined as
1901 // "= default;", which generates a constexpr constructor (In this case,
1902 // the condition of constexpr-ness is satisfied because the base class also has
1903 // compiler generated constexpr {copy,move} constructors). Note that
1904 // placement-new is prohibited in constexpr.
1905 template <typename T, bool = std::is_trivially_copy_constructible<T>::value>
1906 struct OptionalStorage : OptionalStorageBase<T> {
1907 // This is no trivially {copy,move} constructible case. Other cases are
1908 // defined below as specializations.
1909
1910 // Accessing the members of template base class requires explicit
1911 // declaration.
1912 using OptionalStorageBase<T>::is_populated_;
1913 using OptionalStorageBase<T>::value_;
1914 using OptionalStorageBase<T>::Init;
1915
1916 // Inherit constructors (specifically, the in_place constructor).
1917 using OptionalStorageBase<T>::OptionalStorageBase;
1918
1919 // User defined constructor deletes the default constructor.
1920 // Define it explicitly.
1921 OptionalStorage() = default;
1922
OptionalStorageperfetto::base::internal::OptionalStorage1923 OptionalStorage(const OptionalStorage& other) : OptionalStorageBase<T>() {
1924 if (other.is_populated_)
1925 Init(other.value_);
1926 }
1927
OptionalStorageperfetto::base::internal::OptionalStorage1928 OptionalStorage(OptionalStorage&& other) noexcept(
1929 std::is_nothrow_move_constructible<T>::value) {
1930 if (other.is_populated_)
1931 Init(std::move(other.value_));
1932 }
1933 };
1934
1935 template <typename T>
1936 struct OptionalStorage<T, true /* trivially copy constructible */>
1937 : OptionalStorageBase<T> {
1938 using OptionalStorageBase<T>::is_populated_;
1939 using OptionalStorageBase<T>::value_;
1940 using OptionalStorageBase<T>::Init;
1941 using OptionalStorageBase<T>::OptionalStorageBase;
1942
1943 OptionalStorage() = default;
1944 OptionalStorage(const OptionalStorage& other) = default;
1945
OptionalStorageperfetto::base::internal::OptionalStorage1946 OptionalStorage(OptionalStorage&& other) noexcept(
1947 std::is_nothrow_move_constructible<T>::value) {
1948 if (other.is_populated_)
1949 Init(std::move(other.value_));
1950 }
1951 };
1952
1953 // Base class to support conditionally usable copy-/move- constructors
1954 // and assign operators.
1955 template <typename T>
1956 class OptionalBase {
1957 // This class provides implementation rather than public API, so everything
1958 // should be hidden. Often we use composition, but we cannot in this case
1959 // because of C++ language restriction.
1960 protected:
1961 constexpr OptionalBase() = default;
1962 constexpr OptionalBase(const OptionalBase& other) = default;
1963 constexpr OptionalBase(OptionalBase&& other) = default;
1964
1965 template <class... Args>
OptionalBase(in_place_t,Args &&...args)1966 constexpr explicit OptionalBase(in_place_t, Args&&... args)
1967 : storage_(in_place, std::forward<Args>(args)...) {}
1968
1969 // Implementation of converting constructors.
1970 template <typename U>
OptionalBase(const OptionalBase<U> & other)1971 explicit OptionalBase(const OptionalBase<U>& other) {
1972 if (other.storage_.is_populated_)
1973 storage_.Init(other.storage_.value_);
1974 }
1975
1976 template <typename U>
OptionalBase(OptionalBase<U> && other)1977 explicit OptionalBase(OptionalBase<U>&& other) {
1978 if (other.storage_.is_populated_)
1979 storage_.Init(std::move(other.storage_.value_));
1980 }
1981
1982 ~OptionalBase() = default;
1983
operator =(const OptionalBase & other)1984 OptionalBase& operator=(const OptionalBase& other) {
1985 CopyAssign(other);
1986 return *this;
1987 }
1988
operator =(OptionalBase && other)1989 OptionalBase& operator=(OptionalBase&& other) noexcept(
1990 std::is_nothrow_move_assignable<T>::value&&
1991 std::is_nothrow_move_constructible<T>::value) {
1992 MoveAssign(std::move(other));
1993 return *this;
1994 }
1995
1996 template <typename U>
CopyAssign(const OptionalBase<U> & other)1997 void CopyAssign(const OptionalBase<U>& other) {
1998 if (other.storage_.is_populated_)
1999 InitOrAssign(other.storage_.value_);
2000 else
2001 FreeIfNeeded();
2002 }
2003
2004 template <typename U>
MoveAssign(OptionalBase<U> && other)2005 void MoveAssign(OptionalBase<U>&& other) {
2006 if (other.storage_.is_populated_)
2007 InitOrAssign(std::move(other.storage_.value_));
2008 else
2009 FreeIfNeeded();
2010 }
2011
2012 template <typename U>
InitOrAssign(U && value)2013 void InitOrAssign(U&& value) {
2014 if (storage_.is_populated_)
2015 storage_.value_ = std::forward<U>(value);
2016 else
2017 storage_.Init(std::forward<U>(value));
2018 }
2019
FreeIfNeeded()2020 void FreeIfNeeded() {
2021 if (!storage_.is_populated_)
2022 return;
2023 storage_.value_.~T();
2024 storage_.is_populated_ = false;
2025 }
2026
2027 // For implementing conversion, allow access to other typed OptionalBase
2028 // class.
2029 template <typename U>
2030 friend class OptionalBase;
2031
2032 OptionalStorage<T> storage_;
2033 };
2034
2035 // The following {Copy,Move}{Constructible,Assignable} structs are helpers to
2036 // implement constructor/assign-operator overloading. Specifically, if T is
2037 // is not movable but copyable, Optional<T>'s move constructor should not
2038 // participate in overload resolution. This inheritance trick implements that.
2039 template <bool is_copy_constructible>
2040 struct CopyConstructible {};
2041
2042 template <>
2043 struct CopyConstructible<false> {
2044 constexpr CopyConstructible() = default;
2045 constexpr CopyConstructible(const CopyConstructible&) = delete;
2046 constexpr CopyConstructible(CopyConstructible&&) = default;
2047 CopyConstructible& operator=(const CopyConstructible&) = default;
2048 CopyConstructible& operator=(CopyConstructible&&) = default;
2049 };
2050
2051 template <bool is_move_constructible>
2052 struct MoveConstructible {};
2053
2054 template <>
2055 struct MoveConstructible<false> {
2056 constexpr MoveConstructible() = default;
2057 constexpr MoveConstructible(const MoveConstructible&) = default;
2058 constexpr MoveConstructible(MoveConstructible&&) = delete;
2059 MoveConstructible& operator=(const MoveConstructible&) = default;
2060 MoveConstructible& operator=(MoveConstructible&&) = default;
2061 };
2062
2063 template <bool is_copy_assignable>
2064 struct CopyAssignable {};
2065
2066 template <>
2067 struct CopyAssignable<false> {
2068 constexpr CopyAssignable() = default;
2069 constexpr CopyAssignable(const CopyAssignable&) = default;
2070 constexpr CopyAssignable(CopyAssignable&&) = default;
2071 CopyAssignable& operator=(const CopyAssignable&) = delete;
2072 CopyAssignable& operator=(CopyAssignable&&) = default;
2073 };
2074
2075 template <bool is_move_assignable>
2076 struct MoveAssignable {};
2077
2078 template <>
2079 struct MoveAssignable<false> {
2080 constexpr MoveAssignable() = default;
2081 constexpr MoveAssignable(const MoveAssignable&) = default;
2082 constexpr MoveAssignable(MoveAssignable&&) = default;
2083 MoveAssignable& operator=(const MoveAssignable&) = default;
2084 MoveAssignable& operator=(MoveAssignable&&) = delete;
2085 };
2086
2087 // Helper to conditionally enable converting constructors and assign operators.
2088 template <typename T, typename U>
2089 struct IsConvertibleFromOptional
2090 : std::integral_constant<
2091 bool,
2092 std::is_constructible<T, Optional<U>&>::value ||
2093 std::is_constructible<T, const Optional<U>&>::value ||
2094 std::is_constructible<T, Optional<U>&&>::value ||
2095 std::is_constructible<T, const Optional<U>&&>::value ||
2096 std::is_convertible<Optional<U>&, T>::value ||
2097 std::is_convertible<const Optional<U>&, T>::value ||
2098 std::is_convertible<Optional<U>&&, T>::value ||
2099 std::is_convertible<const Optional<U>&&, T>::value> {};
2100
2101 template <typename T, typename U>
2102 struct IsAssignableFromOptional
2103 : std::integral_constant<
2104 bool,
2105 IsConvertibleFromOptional<T, U>::value ||
2106 std::is_assignable<T&, Optional<U>&>::value ||
2107 std::is_assignable<T&, const Optional<U>&>::value ||
2108 std::is_assignable<T&, Optional<U>&&>::value ||
2109 std::is_assignable<T&, const Optional<U>&&>::value> {};
2110
2111 // Forward compatibility for C++17.
2112 // Introduce one more deeper nested namespace to avoid leaking using std::swap.
2113 namespace swappable_impl {
2114 using std::swap;
2115
2116 struct IsSwappableImpl {
2117 // Tests if swap can be called. Check<T&>(0) returns true_type iff swap is
2118 // available for T. Otherwise, Check's overload resolution falls back to
2119 // Check(...) declared below thanks to SFINAE, so returns false_type.
2120 template <typename T>
2121 static auto Check(int)
2122 -> decltype(swap(std::declval<T>(), std::declval<T>()), std::true_type());
2123
2124 template <typename T>
2125 static std::false_type Check(...);
2126 };
2127 } // namespace swappable_impl
2128
2129 template <typename T>
2130 struct IsSwappable : decltype(swappable_impl::IsSwappableImpl::Check<T&>(0)) {};
2131
2132 // Forward compatibility for C++20.
2133 template <typename T>
2134 using RemoveCvRefT =
2135 typename std::remove_cv<typename std::remove_reference<T>::type>::type;
2136
2137 } // namespace internal
2138
2139 // On Windows, by default, empty-base class optimization does not work,
2140 // which means even if the base class is empty struct, it still consumes one
2141 // byte for its body. __declspec(empty_bases) enables the optimization.
2142 // cf)
2143 // https://blogs.msdn.microsoft.com/vcblog/2016/03/30/optimizing-the-layout-of-empty-base-classes-in-vs2015-update-2-3/
2144 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) && \
2145 !PERFETTO_BUILDFLAG(PERFETTO_COMPILER_GCC)
2146 #define OPTIONAL_DECLSPEC_EMPTY_BASES __declspec(empty_bases)
2147 #else
2148 #define OPTIONAL_DECLSPEC_EMPTY_BASES
2149 #endif
2150
2151 // base::Optional is a Chromium version of the C++17 optional class:
2152 // std::optional documentation:
2153 // http://en.cppreference.com/w/cpp/utility/optional
2154 // Chromium documentation:
2155 // https://chromium.googlesource.com/chromium/src/+/master/docs/optional.md
2156 //
2157 // These are the differences between the specification and the implementation:
2158 // - Constructors do not use 'constexpr' as it is a C++14 extension.
2159 // - 'constexpr' might be missing in some places for reasons specified locally.
2160 // - No exceptions are thrown, because they are banned from Chromium.
2161 // Marked noexcept for only move constructor and move assign operators.
2162 // - All the non-members are in the 'base' namespace instead of 'std'.
2163 //
2164 // Note that T cannot have a constructor T(Optional<T>) etc. Optional<T>
2165 // PERFETTO_CHECKs T's constructor (specifically via IsConvertibleFromOptional),
2166 // and in the PERFETTO_CHECK whether T can be constructible from Optional<T>,
2167 // which is recursive so it does not work. As of Feb 2018, std::optional C++17
2168 // implementation in both clang and gcc has same limitation. MSVC SFINAE looks
2169 // to have different behavior, but anyway it reports an error, too.
2170 //
2171 // This file is a modified version of optional.h from Chromium at revision
2172 // 5e71bd454e60511c1293c0c686544aaa76094424. The changes remove C++14/C++17
2173 // specific code and replace with C++11 counterparts.
2174 template <typename T>
2175 class OPTIONAL_DECLSPEC_EMPTY_BASES Optional
2176 : public internal::OptionalBase<T>,
2177 public internal::CopyConstructible<std::is_copy_constructible<T>::value>,
2178 public internal::MoveConstructible<std::is_move_constructible<T>::value>,
2179 public internal::CopyAssignable<std::is_copy_constructible<T>::value &&
2180 std::is_copy_assignable<T>::value>,
2181 public internal::MoveAssignable<std::is_move_constructible<T>::value &&
2182 std::is_move_assignable<T>::value> {
2183 public:
2184 #undef OPTIONAL_DECLSPEC_EMPTY_BASES
2185 using value_type = T;
2186
2187 // Defer default/copy/move constructor implementation to OptionalBase.
2188 constexpr Optional() = default;
2189 constexpr Optional(const Optional& other) = default;
2190 constexpr Optional(Optional&& other) noexcept(
2191 std::is_nothrow_move_constructible<T>::value) = default;
2192
Optional(nullopt_t)2193 constexpr Optional(nullopt_t) {} // NOLINT(runtime/explicit)
2194
2195 // Converting copy constructor. "explicit" only if
2196 // std::is_convertible<const U&, T>::value is false. It is implemented by
2197 // declaring two almost same constructors, but that condition in enable_if_t
2198 // is different, so that either one is chosen, thanks to SFINAE.
2199 template <typename U,
2200 typename std::enable_if<
2201 std::is_constructible<T, const U&>::value &&
2202 !internal::IsConvertibleFromOptional<T, U>::value &&
2203 std::is_convertible<const U&, T>::value,
2204 bool>::type = false>
Optional(const Optional<U> & other)2205 Optional(const Optional<U>& other) : internal::OptionalBase<T>(other) {}
2206
2207 template <typename U,
2208 typename std::enable_if<
2209 std::is_constructible<T, const U&>::value &&
2210 !internal::IsConvertibleFromOptional<T, U>::value &&
2211 !std::is_convertible<const U&, T>::value,
2212 bool>::type = false>
Optional(const Optional<U> & other)2213 explicit Optional(const Optional<U>& other)
2214 : internal::OptionalBase<T>(other) {}
2215
2216 // Converting move constructor. Similar to converting copy constructor,
2217 // declaring two (explicit and non-explicit) constructors.
2218 template <typename U,
2219 typename std::enable_if<
2220 std::is_constructible<T, U&&>::value &&
2221 !internal::IsConvertibleFromOptional<T, U>::value &&
2222 std::is_convertible<U&&, T>::value,
2223 bool>::type = false>
Optional(Optional<U> && other)2224 Optional(Optional<U>&& other) : internal::OptionalBase<T>(std::move(other)) {}
2225
2226 template <typename U,
2227 typename std::enable_if<
2228 std::is_constructible<T, U&&>::value &&
2229 !internal::IsConvertibleFromOptional<T, U>::value &&
2230 !std::is_convertible<U&&, T>::value,
2231 bool>::type = false>
Optional(Optional<U> && other)2232 explicit Optional(Optional<U>&& other)
2233 : internal::OptionalBase<T>(std::move(other)) {}
2234
2235 template <class... Args>
Optional(in_place_t,Args &&...args)2236 constexpr explicit Optional(in_place_t, Args&&... args)
2237 : internal::OptionalBase<T>(in_place, std::forward<Args>(args)...) {}
2238
2239 template <class U,
2240 class... Args,
2241 class = typename std::enable_if<
2242 std::is_constructible<value_type,
2243 std::initializer_list<U>&,
2244 Args...>::value>::type>
Optional(in_place_t,std::initializer_list<U> il,Args &&...args)2245 constexpr explicit Optional(in_place_t,
2246 std::initializer_list<U> il,
2247 Args&&... args)
2248 : internal::OptionalBase<T>(in_place, il, std::forward<Args>(args)...) {}
2249
2250 // Forward value constructor. Similar to converting constructors,
2251 // conditionally explicit.
2252 template <
2253 typename U = value_type,
2254 typename std::enable_if<
2255 std::is_constructible<T, U&&>::value &&
2256 !std::is_same<internal::RemoveCvRefT<U>, in_place_t>::value &&
2257 !std::is_same<internal::RemoveCvRefT<U>, Optional<T>>::value &&
2258 std::is_convertible<U&&, T>::value,
2259 bool>::type = false>
Optional(U && value)2260 constexpr Optional(U&& value)
2261 : internal::OptionalBase<T>(in_place, std::forward<U>(value)) {}
2262
2263 template <
2264 typename U = value_type,
2265 typename std::enable_if<
2266 std::is_constructible<T, U&&>::value &&
2267 !std::is_same<internal::RemoveCvRefT<U>, in_place_t>::value &&
2268 !std::is_same<internal::RemoveCvRefT<U>, Optional<T>>::value &&
2269 !std::is_convertible<U&&, T>::value,
2270 bool>::type = false>
Optional(U && value)2271 constexpr explicit Optional(U&& value)
2272 : internal::OptionalBase<T>(in_place, std::forward<U>(value)) {}
2273
2274 ~Optional() = default;
2275
2276 // Defer copy-/move- assign operator implementation to OptionalBase.
2277 Optional& operator=(const Optional& other) = default;
2278 Optional& operator=(Optional&& other) noexcept(
2279 std::is_nothrow_move_assignable<T>::value&&
2280 std::is_nothrow_move_constructible<T>::value) = default;
2281
operator =(nullopt_t)2282 Optional& operator=(nullopt_t) {
2283 FreeIfNeeded();
2284 return *this;
2285 }
2286
2287 // Perfect-forwarded assignment.
2288 template <typename U>
2289 typename std::enable_if<
2290 !std::is_same<internal::RemoveCvRefT<U>, Optional<T>>::value &&
2291 std::is_constructible<T, U>::value &&
2292 std::is_assignable<T&, U>::value &&
2293 (!std::is_scalar<T>::value ||
2294 !std::is_same<typename std::decay<U>::type, T>::value),
2295 Optional&>::type
operator =(U && value)2296 operator=(U&& value) {
2297 InitOrAssign(std::forward<U>(value));
2298 return *this;
2299 }
2300
2301 // Copy assign the state of other.
2302 template <typename U>
2303 typename std::enable_if<!internal::IsAssignableFromOptional<T, U>::value &&
2304 std::is_constructible<T, const U&>::value &&
2305 std::is_assignable<T&, const U&>::value,
2306 Optional&>::type
operator =(const Optional<U> & other)2307 operator=(const Optional<U>& other) {
2308 CopyAssign(other);
2309 return *this;
2310 }
2311
2312 // Move assign the state of other.
2313 template <typename U>
2314 typename std::enable_if<!internal::IsAssignableFromOptional<T, U>::value &&
2315 std::is_constructible<T, U>::value &&
2316 std::is_assignable<T&, U>::value,
2317 Optional&>::type
operator =(Optional<U> && other)2318 operator=(Optional<U>&& other) {
2319 MoveAssign(std::move(other));
2320 return *this;
2321 }
2322
operator ->() const2323 const T* operator->() const {
2324 PERFETTO_DCHECK(storage_.is_populated_);
2325 return &storage_.value_;
2326 }
2327
operator ->()2328 T* operator->() {
2329 PERFETTO_DCHECK(storage_.is_populated_);
2330 return &storage_.value_;
2331 }
2332
operator *() const2333 const T& operator*() const& {
2334 PERFETTO_DCHECK(storage_.is_populated_);
2335 return storage_.value_;
2336 }
2337
operator *()2338 T& operator*() & {
2339 PERFETTO_DCHECK(storage_.is_populated_);
2340 return storage_.value_;
2341 }
2342
operator *() const2343 const T&& operator*() const&& {
2344 PERFETTO_DCHECK(storage_.is_populated_);
2345 return std::move(storage_.value_);
2346 }
2347
operator *()2348 T&& operator*() && {
2349 PERFETTO_DCHECK(storage_.is_populated_);
2350 return std::move(storage_.value_);
2351 }
2352
operator bool() const2353 constexpr explicit operator bool() const { return storage_.is_populated_; }
2354
has_value() const2355 constexpr bool has_value() const { return storage_.is_populated_; }
2356
value()2357 T& value() & {
2358 PERFETTO_CHECK(storage_.is_populated_);
2359 return storage_.value_;
2360 }
2361
value() const2362 const T& value() const& {
2363 PERFETTO_CHECK(storage_.is_populated_);
2364 return storage_.value_;
2365 }
2366
value()2367 T&& value() && {
2368 PERFETTO_CHECK(storage_.is_populated_);
2369 return std::move(storage_.value_);
2370 }
2371
value() const2372 const T&& value() const&& {
2373 PERFETTO_CHECK(storage_.is_populated_);
2374 return std::move(storage_.value_);
2375 }
2376
2377 template <class U>
value_or(U && default_value) const2378 constexpr T value_or(U&& default_value) const& {
2379 static_assert(std::is_convertible<U, T>::value,
2380 "U must be convertible to T");
2381 return storage_.is_populated_
2382 ? storage_.value_
2383 : static_cast<T>(std::forward<U>(default_value));
2384 }
2385
2386 template <class U>
value_or(U && default_value)2387 T value_or(U&& default_value) && {
2388 static_assert(std::is_convertible<U, T>::value,
2389 "U must be convertible to T");
2390 return storage_.is_populated_
2391 ? std::move(storage_.value_)
2392 : static_cast<T>(std::forward<U>(default_value));
2393 }
2394
swap(Optional & other)2395 void swap(Optional& other) {
2396 if (!storage_.is_populated_ && !other.storage_.is_populated_)
2397 return;
2398
2399 if (storage_.is_populated_ != other.storage_.is_populated_) {
2400 if (storage_.is_populated_) {
2401 other.storage_.Init(std::move(storage_.value_));
2402 FreeIfNeeded();
2403 } else {
2404 storage_.Init(std::move(other.storage_.value_));
2405 other.FreeIfNeeded();
2406 }
2407 return;
2408 }
2409
2410 PERFETTO_DCHECK(storage_.is_populated_ && other.storage_.is_populated_);
2411 using std::swap;
2412 swap(**this, *other);
2413 }
2414
reset()2415 void reset() { FreeIfNeeded(); }
2416
2417 template <class... Args>
emplace(Args &&...args)2418 T& emplace(Args&&... args) {
2419 FreeIfNeeded();
2420 storage_.Init(std::forward<Args>(args)...);
2421 return storage_.value_;
2422 }
2423
2424 template <class U, class... Args>
2425 typename std::enable_if<
2426 std::is_constructible<T, std::initializer_list<U>&, Args&&...>::value,
2427 T&>::type
emplace(std::initializer_list<U> il,Args &&...args)2428 emplace(std::initializer_list<U> il, Args&&... args) {
2429 FreeIfNeeded();
2430 storage_.Init(il, std::forward<Args>(args)...);
2431 return storage_.value_;
2432 }
2433
2434 private:
2435 // Accessing template base class's protected member needs explicit
2436 // declaration to do so.
2437 using internal::OptionalBase<T>::CopyAssign;
2438 using internal::OptionalBase<T>::FreeIfNeeded;
2439 using internal::OptionalBase<T>::InitOrAssign;
2440 using internal::OptionalBase<T>::MoveAssign;
2441 using internal::OptionalBase<T>::storage_;
2442 };
2443
2444 // Here after defines comparation operators. The definition follows
2445 // http://en.cppreference.com/w/cpp/utility/optional/operator_cmp
2446 // while bool() casting is replaced by has_value() to meet the chromium
2447 // style guide.
2448 template <class T, class U>
operator ==(const Optional<T> & lhs,const Optional<U> & rhs)2449 bool operator==(const Optional<T>& lhs, const Optional<U>& rhs) {
2450 if (lhs.has_value() != rhs.has_value())
2451 return false;
2452 if (!lhs.has_value())
2453 return true;
2454 return *lhs == *rhs;
2455 }
2456
2457 template <class T, class U>
operator !=(const Optional<T> & lhs,const Optional<U> & rhs)2458 bool operator!=(const Optional<T>& lhs, const Optional<U>& rhs) {
2459 if (lhs.has_value() != rhs.has_value())
2460 return true;
2461 if (!lhs.has_value())
2462 return false;
2463 return *lhs != *rhs;
2464 }
2465
2466 template <class T, class U>
operator <(const Optional<T> & lhs,const Optional<U> & rhs)2467 bool operator<(const Optional<T>& lhs, const Optional<U>& rhs) {
2468 if (!rhs.has_value())
2469 return false;
2470 if (!lhs.has_value())
2471 return true;
2472 return *lhs < *rhs;
2473 }
2474
2475 template <class T, class U>
operator <=(const Optional<T> & lhs,const Optional<U> & rhs)2476 bool operator<=(const Optional<T>& lhs, const Optional<U>& rhs) {
2477 if (!lhs.has_value())
2478 return true;
2479 if (!rhs.has_value())
2480 return false;
2481 return *lhs <= *rhs;
2482 }
2483
2484 template <class T, class U>
operator >(const Optional<T> & lhs,const Optional<U> & rhs)2485 bool operator>(const Optional<T>& lhs, const Optional<U>& rhs) {
2486 if (!lhs.has_value())
2487 return false;
2488 if (!rhs.has_value())
2489 return true;
2490 return *lhs > *rhs;
2491 }
2492
2493 template <class T, class U>
operator >=(const Optional<T> & lhs,const Optional<U> & rhs)2494 bool operator>=(const Optional<T>& lhs, const Optional<U>& rhs) {
2495 if (!rhs.has_value())
2496 return true;
2497 if (!lhs.has_value())
2498 return false;
2499 return *lhs >= *rhs;
2500 }
2501
2502 template <class T>
operator ==(const Optional<T> & opt,nullopt_t)2503 constexpr bool operator==(const Optional<T>& opt, nullopt_t) {
2504 return !opt;
2505 }
2506
2507 template <class T>
operator ==(nullopt_t,const Optional<T> & opt)2508 constexpr bool operator==(nullopt_t, const Optional<T>& opt) {
2509 return !opt;
2510 }
2511
2512 template <class T>
operator !=(const Optional<T> & opt,nullopt_t)2513 constexpr bool operator!=(const Optional<T>& opt, nullopt_t) {
2514 return opt.has_value();
2515 }
2516
2517 template <class T>
operator !=(nullopt_t,const Optional<T> & opt)2518 constexpr bool operator!=(nullopt_t, const Optional<T>& opt) {
2519 return opt.has_value();
2520 }
2521
2522 template <class T>
operator <(const Optional<T> &,nullopt_t)2523 constexpr bool operator<(const Optional<T>&, nullopt_t) {
2524 return false;
2525 }
2526
2527 template <class T>
operator <(nullopt_t,const Optional<T> & opt)2528 constexpr bool operator<(nullopt_t, const Optional<T>& opt) {
2529 return opt.has_value();
2530 }
2531
2532 template <class T>
operator <=(const Optional<T> & opt,nullopt_t)2533 constexpr bool operator<=(const Optional<T>& opt, nullopt_t) {
2534 return !opt;
2535 }
2536
2537 template <class T>
operator <=(nullopt_t,const Optional<T> &)2538 constexpr bool operator<=(nullopt_t, const Optional<T>&) {
2539 return true;
2540 }
2541
2542 template <class T>
operator >(const Optional<T> & opt,nullopt_t)2543 constexpr bool operator>(const Optional<T>& opt, nullopt_t) {
2544 return opt.has_value();
2545 }
2546
2547 template <class T>
operator >(nullopt_t,const Optional<T> &)2548 constexpr bool operator>(nullopt_t, const Optional<T>&) {
2549 return false;
2550 }
2551
2552 template <class T>
operator >=(const Optional<T> &,nullopt_t)2553 constexpr bool operator>=(const Optional<T>&, nullopt_t) {
2554 return true;
2555 }
2556
2557 template <class T>
operator >=(nullopt_t,const Optional<T> & opt)2558 constexpr bool operator>=(nullopt_t, const Optional<T>& opt) {
2559 return !opt;
2560 }
2561
2562 template <class T, class U>
operator ==(const Optional<T> & opt,const U & value)2563 constexpr bool operator==(const Optional<T>& opt, const U& value) {
2564 return opt.has_value() ? *opt == value : false;
2565 }
2566
2567 template <class T, class U>
operator ==(const U & value,const Optional<T> & opt)2568 constexpr bool operator==(const U& value, const Optional<T>& opt) {
2569 return opt.has_value() ? value == *opt : false;
2570 }
2571
2572 template <class T, class U>
operator !=(const Optional<T> & opt,const U & value)2573 constexpr bool operator!=(const Optional<T>& opt, const U& value) {
2574 return opt.has_value() ? *opt != value : true;
2575 }
2576
2577 template <class T, class U>
operator !=(const U & value,const Optional<T> & opt)2578 constexpr bool operator!=(const U& value, const Optional<T>& opt) {
2579 return opt.has_value() ? value != *opt : true;
2580 }
2581
2582 template <class T, class U>
operator <(const Optional<T> & opt,const U & value)2583 constexpr bool operator<(const Optional<T>& opt, const U& value) {
2584 return opt.has_value() ? *opt < value : true;
2585 }
2586
2587 template <class T, class U>
operator <(const U & value,const Optional<T> & opt)2588 constexpr bool operator<(const U& value, const Optional<T>& opt) {
2589 return opt.has_value() ? value < *opt : false;
2590 }
2591
2592 template <class T, class U>
operator <=(const Optional<T> & opt,const U & value)2593 constexpr bool operator<=(const Optional<T>& opt, const U& value) {
2594 return opt.has_value() ? *opt <= value : true;
2595 }
2596
2597 template <class T, class U>
operator <=(const U & value,const Optional<T> & opt)2598 constexpr bool operator<=(const U& value, const Optional<T>& opt) {
2599 return opt.has_value() ? value <= *opt : false;
2600 }
2601
2602 template <class T, class U>
operator >(const Optional<T> & opt,const U & value)2603 constexpr bool operator>(const Optional<T>& opt, const U& value) {
2604 return opt.has_value() ? *opt > value : false;
2605 }
2606
2607 template <class T, class U>
operator >(const U & value,const Optional<T> & opt)2608 constexpr bool operator>(const U& value, const Optional<T>& opt) {
2609 return opt.has_value() ? value > *opt : true;
2610 }
2611
2612 template <class T, class U>
operator >=(const Optional<T> & opt,const U & value)2613 constexpr bool operator>=(const Optional<T>& opt, const U& value) {
2614 return opt.has_value() ? *opt >= value : false;
2615 }
2616
2617 template <class T, class U>
operator >=(const U & value,const Optional<T> & opt)2618 constexpr bool operator>=(const U& value, const Optional<T>& opt) {
2619 return opt.has_value() ? value >= *opt : true;
2620 }
2621
2622 template <class T>
make_optional(T && value)2623 constexpr Optional<typename std::decay<T>::type> make_optional(T&& value) {
2624 return Optional<typename std::decay<T>::type>(std::forward<T>(value));
2625 }
2626
2627 template <class T, class... Args>
make_optional(Args &&...args)2628 constexpr Optional<T> make_optional(Args&&... args) {
2629 return Optional<T>(in_place, std::forward<Args>(args)...);
2630 }
2631
2632 template <class T, class U, class... Args>
make_optional(std::initializer_list<U> il,Args &&...args)2633 constexpr Optional<T> make_optional(std::initializer_list<U> il,
2634 Args&&... args) {
2635 return Optional<T>(in_place, il, std::forward<Args>(args)...);
2636 }
2637
2638 // Partial specialization for a function template is not allowed. Also, it is
2639 // not allowed to add overload function to std namespace, while it is allowed
2640 // to specialize the template in std. Thus, swap() (kind of) overloading is
2641 // defined in base namespace, instead.
2642 template <class T>
2643 typename std::enable_if<std::is_move_constructible<T>::value &&
2644 internal::IsSwappable<T>::value>::type
swap(Optional<T> & lhs,Optional<T> & rhs)2645 swap(Optional<T>& lhs, Optional<T>& rhs) {
2646 lhs.swap(rhs);
2647 }
2648
2649 } // namespace base
2650 } // namespace perfetto
2651
2652 namespace std {
2653
2654 template <class T>
2655 struct hash<perfetto::base::Optional<T>> {
operator ()std::hash2656 size_t operator()(const perfetto::base::Optional<T>& opt) const {
2657 return opt == perfetto::base::nullopt ? 0 : std::hash<T>()(*opt);
2658 }
2659 };
2660
2661 } // namespace std
2662
2663 #endif // INCLUDE_PERFETTO_EXT_BASE_OPTIONAL_H_
2664 // gen_amalgamated begin header: include/perfetto/ext/base/string_view.h
2665 // gen_amalgamated begin header: include/perfetto/ext/base/hash.h
2666 /*
2667 * Copyright (C) 2019 The Android Open Source Project
2668 *
2669 * Licensed under the Apache License, Version 2.0 (the "License");
2670 * you may not use this file except in compliance with the License.
2671 * You may obtain a copy of the License at
2672 *
2673 * http://www.apache.org/licenses/LICENSE-2.0
2674 *
2675 * Unless required by applicable law or agreed to in writing, software
2676 * distributed under the License is distributed on an "AS IS" BASIS,
2677 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2678 * See the License for the specific language governing permissions and
2679 * limitations under the License.
2680 */
2681
2682 #ifndef INCLUDE_PERFETTO_EXT_BASE_HASH_H_
2683 #define INCLUDE_PERFETTO_EXT_BASE_HASH_H_
2684
2685 #include <stddef.h>
2686 #include <stdint.h>
2687 #include <type_traits>
2688
2689 namespace perfetto {
2690 namespace base {
2691
2692 // A helper class which computes a 64-bit hash of the input data.
2693 // The algorithm used is FNV-1a as it is fast and easy to implement and has
2694 // relatively few collisions.
2695 // WARNING: This hash function should not be used for any cryptographic purpose.
2696 class Hash {
2697 public:
2698 // Creates an empty hash object
Hash()2699 Hash() {}
2700
2701 // Hashes a numeric value.
2702 template <typename T,
2703 typename std::enable_if<std::is_arithmetic<T>::value>* = nullptr>
Update(T data)2704 void Update(T data) {
2705 Update(reinterpret_cast<const char*>(&data), sizeof(data));
2706 }
2707
2708 // Hashes a byte array.
Update(const char * data,size_t size)2709 void Update(const char* data, size_t size) {
2710 for (size_t i = 0; i < size; i++) {
2711 result_ ^= static_cast<uint8_t>(data[i]);
2712 result_ *= kFnv1a64Prime;
2713 }
2714 }
2715
digest()2716 uint64_t digest() { return result_; }
2717
2718 private:
2719 static constexpr uint64_t kFnv1a64OffsetBasis = 0xcbf29ce484222325;
2720 static constexpr uint64_t kFnv1a64Prime = 0x100000001b3;
2721
2722 uint64_t result_ = kFnv1a64OffsetBasis;
2723 };
2724
2725 } // namespace base
2726 } // namespace perfetto
2727
2728 #endif // INCLUDE_PERFETTO_EXT_BASE_HASH_H_
2729 /*
2730 * Copyright (C) 2018 The Android Open Source Project
2731 *
2732 * Licensed under the Apache License, Version 2.0 (the "License");
2733 * you may not use this file except in compliance with the License.
2734 * You may obtain a copy of the License at
2735 *
2736 * http://www.apache.org/licenses/LICENSE-2.0
2737 *
2738 * Unless required by applicable law or agreed to in writing, software
2739 * distributed under the License is distributed on an "AS IS" BASIS,
2740 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2741 * See the License for the specific language governing permissions and
2742 * limitations under the License.
2743 */
2744
2745 #ifndef INCLUDE_PERFETTO_EXT_BASE_STRING_VIEW_H_
2746 #define INCLUDE_PERFETTO_EXT_BASE_STRING_VIEW_H_
2747
2748 #include <string.h>
2749
2750 #include <algorithm>
2751 #include <string>
2752
2753 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
2754 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
2755 // gen_amalgamated expanded: #include "perfetto/ext/base/hash.h"
2756
2757 namespace perfetto {
2758 namespace base {
2759
2760 // A string-like object that refers to a non-owned piece of memory.
2761 // Strings are internally NOT null terminated.
2762 class StringView {
2763 public:
2764 static constexpr size_t npos = static_cast<size_t>(-1);
2765
StringView()2766 StringView() : data_(nullptr), size_(0) {}
2767 StringView(const StringView&) = default;
2768 StringView& operator=(const StringView&) = default;
StringView(const char * data,size_t size)2769 StringView(const char* data, size_t size) : data_(data), size_(size) {
2770 PERFETTO_DCHECK(size == 0 || data != nullptr);
2771 }
2772
2773 // Allow implicit conversion from any class that has a |data| and |size| field
2774 // and has the kConvertibleToStringView trait (e.g., protozero::ConstChars).
2775 template <typename T, typename = std::enable_if<T::kConvertibleToStringView>>
StringView(const T & x)2776 StringView(const T& x) : StringView(x.data, x.size) {
2777 PERFETTO_DCHECK(x.size == 0 || x.data != nullptr);
2778 }
2779
2780 // Creates a StringView from a null-terminated C string.
2781 // Deliberately not "explicit".
StringView(const char * cstr)2782 StringView(const char* cstr) : data_(cstr), size_(strlen(cstr)) {
2783 PERFETTO_DCHECK(cstr != nullptr);
2784 }
2785
2786 // This instead has to be explicit, as creating a StringView out of a
2787 // std::string can be subtle.
StringView(const std::string & str)2788 explicit StringView(const std::string& str)
2789 : data_(str.data()), size_(str.size()) {}
2790
empty() const2791 bool empty() const { return size_ == 0; }
size() const2792 size_t size() const { return size_; }
data() const2793 const char* data() const { return data_; }
begin() const2794 const char* begin() const { return data_; }
end() const2795 const char* end() const { return data_ + size_; }
2796
at(size_t pos) const2797 char at(size_t pos) const {
2798 PERFETTO_DCHECK(pos < size_);
2799 return data_[pos];
2800 }
2801
find(char c,size_t start_pos=0) const2802 size_t find(char c, size_t start_pos = 0) const {
2803 for (size_t i = start_pos; i < size_; ++i) {
2804 if (data_[i] == c)
2805 return i;
2806 }
2807 return npos;
2808 }
2809
find(const StringView & str,size_t start_pos=0) const2810 size_t find(const StringView& str, size_t start_pos = 0) const {
2811 if (start_pos > size())
2812 return npos;
2813 auto it = std::search(begin() + start_pos, end(), str.begin(), str.end());
2814 size_t pos = static_cast<size_t>(it - begin());
2815 return pos + str.size() <= size() ? pos : npos;
2816 }
2817
find(const char * str,size_t start_pos=0) const2818 size_t find(const char* str, size_t start_pos = 0) const {
2819 return find(StringView(str), start_pos);
2820 }
2821
rfind(char c) const2822 size_t rfind(char c) const {
2823 for (size_t i = size_; i > 0; --i) {
2824 if (data_[i - 1] == c)
2825 return i - 1;
2826 }
2827 return npos;
2828 }
2829
substr(size_t pos,size_t count=npos) const2830 StringView substr(size_t pos, size_t count = npos) const {
2831 if (pos >= size_)
2832 return StringView("", 0);
2833 size_t rcount = std::min(count, size_ - pos);
2834 return StringView(data_ + pos, rcount);
2835 }
2836
CaseInsensitiveEq(const StringView & other)2837 bool CaseInsensitiveEq(const StringView& other) {
2838 if (size() != other.size())
2839 return false;
2840 if (size() == 0)
2841 return true;
2842 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
2843 return _strnicmp(data(), other.data(), size()) == 0;
2844 #else
2845 return strncasecmp(data(), other.data(), size()) == 0;
2846 #endif
2847 }
2848
ToStdString() const2849 std::string ToStdString() const {
2850 return data_ == nullptr ? "" : std::string(data_, size_);
2851 }
2852
Hash() const2853 uint64_t Hash() const {
2854 base::Hash hasher;
2855 hasher.Update(data_, size_);
2856 return hasher.digest();
2857 }
2858
2859 private:
2860 const char* data_ = nullptr;
2861 size_t size_ = 0;
2862 };
2863
operator ==(const StringView & x,const StringView & y)2864 inline bool operator==(const StringView& x, const StringView& y) {
2865 if (x.size() != y.size())
2866 return false;
2867 if (x.size() == 0)
2868 return true;
2869 return memcmp(x.data(), y.data(), x.size()) == 0;
2870 }
2871
operator !=(const StringView & x,const StringView & y)2872 inline bool operator!=(const StringView& x, const StringView& y) {
2873 return !(x == y);
2874 }
2875
operator <(const StringView & x,const StringView & y)2876 inline bool operator<(const StringView& x, const StringView& y) {
2877 auto size = std::min(x.size(), y.size());
2878 if (size == 0)
2879 return x.size() < y.size();
2880 int result = memcmp(x.data(), y.data(), size);
2881 return result < 0 || (result == 0 && x.size() < y.size());
2882 }
2883
operator >=(const StringView & x,const StringView & y)2884 inline bool operator>=(const StringView& x, const StringView& y) {
2885 return !(x < y);
2886 }
2887
operator >(const StringView & x,const StringView & y)2888 inline bool operator>(const StringView& x, const StringView& y) {
2889 return y < x;
2890 }
2891
operator <=(const StringView & x,const StringView & y)2892 inline bool operator<=(const StringView& x, const StringView& y) {
2893 return !(y < x);
2894 }
2895
2896 } // namespace base
2897 } // namespace perfetto
2898
2899 namespace std {
2900
2901 template <>
2902 struct hash<::perfetto::base::StringView> {
operator ()std::hash2903 size_t operator()(const ::perfetto::base::StringView& sv) const {
2904 return static_cast<size_t>(sv.Hash());
2905 }
2906 };
2907
2908 } // namespace std
2909
2910 #endif // INCLUDE_PERFETTO_EXT_BASE_STRING_VIEW_H_
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 #ifndef INCLUDE_PERFETTO_EXT_BASE_STRING_UTILS_H_
2928 #define INCLUDE_PERFETTO_EXT_BASE_STRING_UTILS_H_
2929
2930 #include <string>
2931 #include <vector>
2932
2933 #include <inttypes.h>
2934 #include <stdlib.h>
2935
2936 // gen_amalgamated expanded: #include "perfetto/ext/base/optional.h"
2937 // gen_amalgamated expanded: #include "perfetto/ext/base/string_view.h"
2938
2939 namespace perfetto {
2940 namespace base {
2941
Lowercase(char c)2942 inline char Lowercase(char c) {
2943 return ('A' <= c && c <= 'Z') ? static_cast<char>(c - ('A' - 'a')) : c;
2944 }
2945
Uppercase(char c)2946 inline char Uppercase(char c) {
2947 return ('a' <= c && c <= 'z') ? static_cast<char>(c + ('A' - 'a')) : c;
2948 }
2949
CStringToUInt32(const char * s,int base=10)2950 inline Optional<uint32_t> CStringToUInt32(const char* s, int base = 10) {
2951 char* endptr = nullptr;
2952 auto value = static_cast<uint32_t>(strtoul(s, &endptr, base));
2953 return (*s && !*endptr) ? base::make_optional(value) : base::nullopt;
2954 }
2955
CStringToInt32(const char * s,int base=10)2956 inline Optional<int32_t> CStringToInt32(const char* s, int base = 10) {
2957 char* endptr = nullptr;
2958 auto value = static_cast<int32_t>(strtol(s, &endptr, base));
2959 return (*s && !*endptr) ? base::make_optional(value) : base::nullopt;
2960 }
2961
2962 // Note: it saturates to 7fffffffffffffff if parsing a hex number >= 0x8000...
CStringToInt64(const char * s,int base=10)2963 inline Optional<int64_t> CStringToInt64(const char* s, int base = 10) {
2964 char* endptr = nullptr;
2965 auto value = static_cast<int64_t>(strtoll(s, &endptr, base));
2966 return (*s && !*endptr) ? base::make_optional(value) : base::nullopt;
2967 }
2968
CStringToUInt64(const char * s,int base=10)2969 inline Optional<uint64_t> CStringToUInt64(const char* s, int base = 10) {
2970 char* endptr = nullptr;
2971 auto value = static_cast<uint64_t>(strtoull(s, &endptr, base));
2972 return (*s && !*endptr) ? base::make_optional(value) : base::nullopt;
2973 }
2974
CStringToDouble(const char * s)2975 inline Optional<double> CStringToDouble(const char* s) {
2976 char* endptr = nullptr;
2977 double value = strtod(s, &endptr);
2978 Optional<double> result(base::nullopt);
2979 if (*s != '\0' && *endptr == '\0')
2980 result = value;
2981 return result;
2982 }
2983
StringToUInt32(const std::string & s,int base=10)2984 inline Optional<uint32_t> StringToUInt32(const std::string& s, int base = 10) {
2985 return CStringToUInt32(s.c_str(), base);
2986 }
2987
StringToInt32(const std::string & s,int base=10)2988 inline Optional<int32_t> StringToInt32(const std::string& s, int base = 10) {
2989 return CStringToInt32(s.c_str(), base);
2990 }
2991
StringToUInt64(const std::string & s,int base=10)2992 inline Optional<uint64_t> StringToUInt64(const std::string& s, int base = 10) {
2993 return CStringToUInt64(s.c_str(), base);
2994 }
2995
StringToInt64(const std::string & s,int base=10)2996 inline Optional<int64_t> StringToInt64(const std::string& s, int base = 10) {
2997 return CStringToInt64(s.c_str(), base);
2998 }
2999
StringToDouble(const std::string & s)3000 inline Optional<double> StringToDouble(const std::string& s) {
3001 return CStringToDouble(s.c_str());
3002 }
3003
3004 bool StartsWith(const std::string& str, const std::string& prefix);
3005 bool EndsWith(const std::string& str, const std::string& suffix);
3006 bool Contains(const std::string& haystack, const std::string& needle);
3007 size_t Find(const StringView& needle, const StringView& haystack);
3008 bool CaseInsensitiveEqual(const std::string& first, const std::string& second);
3009 std::string Join(const std::vector<std::string>& parts,
3010 const std::string& delim);
3011 std::vector<std::string> SplitString(const std::string& text,
3012 const std::string& delimiter);
3013 std::string StripPrefix(const std::string& str, const std::string& prefix);
3014 std::string StripSuffix(const std::string& str, const std::string& suffix);
3015 std::string ToLower(const std::string& str);
3016 std::string ToUpper(const std::string& str);
3017 std::string StripChars(const std::string& str,
3018 const std::string& chars,
3019 char replacement);
3020 std::string ToHex(const char* data, size_t size);
ToHex(const std::string & s)3021 inline std::string ToHex(const std::string& s) {
3022 return ToHex(s.c_str(), s.size());
3023 }
3024 std::string IntToHexString(uint32_t number);
3025 std::string ReplaceAll(std::string str,
3026 const std::string& to_replace,
3027 const std::string& replacement);
3028 std::string TrimLeading(const std::string& str);
3029
3030 } // namespace base
3031 } // namespace perfetto
3032
3033 #endif // INCLUDE_PERFETTO_EXT_BASE_STRING_UTILS_H_
3034 /*
3035 * Copyright (C) 2018 The Android Open Source Project
3036 *
3037 * Licensed under the Apache License, Version 2.0 (the "License");
3038 * you may not use this file except in compliance with the License.
3039 * You may obtain a copy of the License at
3040 *
3041 * http://www.apache.org/licenses/LICENSE-2.0
3042 *
3043 * Unless required by applicable law or agreed to in writing, software
3044 * distributed under the License is distributed on an "AS IS" BASIS,
3045 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3046 * See the License for the specific language governing permissions and
3047 * limitations under the License.
3048 */
3049
3050 // gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
3051
3052 #include <string.h>
3053
3054 #include <algorithm>
3055
3056 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
3057
3058 namespace perfetto {
3059 namespace base {
3060
StartsWith(const std::string & str,const std::string & prefix)3061 bool StartsWith(const std::string& str, const std::string& prefix) {
3062 return str.compare(0, prefix.length(), prefix) == 0;
3063 }
3064
EndsWith(const std::string & str,const std::string & suffix)3065 bool EndsWith(const std::string& str, const std::string& suffix) {
3066 if (suffix.size() > str.size())
3067 return false;
3068 return str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
3069 }
3070
Contains(const std::string & haystack,const std::string & needle)3071 bool Contains(const std::string& haystack, const std::string& needle) {
3072 return haystack.find(needle) != std::string::npos;
3073 }
3074
Find(const StringView & needle,const StringView & haystack)3075 size_t Find(const StringView& needle, const StringView& haystack) {
3076 if (needle.size() == 0)
3077 return 0;
3078 if (needle.size() > haystack.size())
3079 return std::string::npos;
3080 for (size_t i = 0; i < haystack.size() - (needle.size() - 1); ++i) {
3081 if (strncmp(haystack.data() + i, needle.data(), needle.size()) == 0)
3082 return i;
3083 }
3084 return std::string::npos;
3085 }
3086
CaseInsensitiveEqual(const std::string & first,const std::string & second)3087 bool CaseInsensitiveEqual(const std::string& first, const std::string& second) {
3088 return first.size() == second.size() &&
3089 std::equal(
3090 first.begin(), first.end(), second.begin(),
3091 [](char a, char b) { return Lowercase(a) == Lowercase(b); });
3092 }
3093
Join(const std::vector<std::string> & parts,const std::string & delim)3094 std::string Join(const std::vector<std::string>& parts,
3095 const std::string& delim) {
3096 std::string acc;
3097 for (size_t i = 0; i < parts.size(); ++i) {
3098 acc += parts[i];
3099 if (i + 1 != parts.size()) {
3100 acc += delim;
3101 }
3102 }
3103 return acc;
3104 }
3105
SplitString(const std::string & text,const std::string & delimiter)3106 std::vector<std::string> SplitString(const std::string& text,
3107 const std::string& delimiter) {
3108 PERFETTO_CHECK(!delimiter.empty());
3109
3110 std::vector<std::string> output;
3111 size_t start = 0;
3112 size_t next;
3113 for (;;) {
3114 next = std::min(text.find(delimiter, start), text.size());
3115 if (next > start)
3116 output.emplace_back(&text[start], next - start);
3117 start = next + delimiter.size();
3118 if (start >= text.size())
3119 break;
3120 }
3121 return output;
3122 }
3123
StripPrefix(const std::string & str,const std::string & prefix)3124 std::string StripPrefix(const std::string& str, const std::string& prefix) {
3125 return StartsWith(str, prefix) ? str.substr(prefix.size()) : str;
3126 }
3127
StripSuffix(const std::string & str,const std::string & suffix)3128 std::string StripSuffix(const std::string& str, const std::string& suffix) {
3129 return EndsWith(str, suffix) ? str.substr(0, str.size() - suffix.size())
3130 : str;
3131 }
3132
ToUpper(const std::string & str)3133 std::string ToUpper(const std::string& str) {
3134 // Don't use toupper(), it depends on the locale.
3135 std::string res(str);
3136 auto end = res.end();
3137 for (auto c = res.begin(); c != end; ++c)
3138 *c = Uppercase(*c);
3139 return res;
3140 }
3141
ToLower(const std::string & str)3142 std::string ToLower(const std::string& str) {
3143 // Don't use tolower(), it depends on the locale.
3144 std::string res(str);
3145 auto end = res.end();
3146 for (auto c = res.begin(); c != end; ++c)
3147 *c = Lowercase(*c);
3148 return res;
3149 }
3150
ToHex(const char * data,size_t size)3151 std::string ToHex(const char* data, size_t size) {
3152 std::string hex(2 * size + 1, 'x');
3153 for (size_t i = 0; i < size; ++i) {
3154 // snprintf prints 3 characters, the two hex digits and a null byte. As we
3155 // write left to right, we keep overwriting the nullbytes, except for the
3156 // last call to snprintf.
3157 snprintf(&(hex[2 * i]), 3, "%02hhx", data[i]);
3158 }
3159 // Remove the trailing nullbyte produced by the last snprintf.
3160 hex.resize(2 * size);
3161 return hex;
3162 }
3163
IntToHexString(uint32_t number)3164 std::string IntToHexString(uint32_t number) {
3165 size_t max_size = 11; // Max uint32 is 0xFFFFFFFF + 1 for null byte.
3166 std::string buf;
3167 buf.resize(max_size);
3168 auto final_size = snprintf(&buf[0], max_size, "0x%02x", number);
3169 PERFETTO_DCHECK(final_size >= 0);
3170 buf.resize(static_cast<size_t>(final_size)); // Cuts off the final null byte.
3171 return buf;
3172 }
3173
StripChars(const std::string & str,const std::string & chars,char replacement)3174 std::string StripChars(const std::string& str,
3175 const std::string& chars,
3176 char replacement) {
3177 std::string res(str);
3178 const char* start = res.c_str();
3179 const char* remove = chars.c_str();
3180 for (const char* c = strpbrk(start, remove); c; c = strpbrk(c + 1, remove))
3181 res[static_cast<uintptr_t>(c - start)] = replacement;
3182 return res;
3183 }
3184
ReplaceAll(std::string str,const std::string & to_replace,const std::string & replacement)3185 std::string ReplaceAll(std::string str,
3186 const std::string& to_replace,
3187 const std::string& replacement) {
3188 PERFETTO_CHECK(!to_replace.empty());
3189 size_t pos = 0;
3190 while ((pos = str.find(to_replace, pos)) != std::string::npos) {
3191 str.replace(pos, to_replace.length(), replacement);
3192 pos += replacement.length();
3193 }
3194 return str;
3195 }
3196
TrimLeading(const std::string & str)3197 std::string TrimLeading(const std::string& str) {
3198 size_t idx = str.find_first_not_of(' ');
3199 return idx == std::string::npos ? str : str.substr(idx);
3200 }
3201
3202 } // namespace base
3203 } // namespace perfetto
3204 // gen_amalgamated begin source: src/base/string_view.cc
3205 /*
3206 * Copyright (C) 2019 The Android Open Source Project
3207 *
3208 * Licensed under the Apache License, Version 2.0 (the "License");
3209 * you may not use this file except in compliance with the License.
3210 * You may obtain a copy of the License at
3211 *
3212 * http://www.apache.org/licenses/LICENSE-2.0
3213 *
3214 * Unless required by applicable law or agreed to in writing, software
3215 * distributed under the License is distributed on an "AS IS" BASIS,
3216 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3217 * See the License for the specific language governing permissions and
3218 * limitations under the License.
3219 */
3220
3221 // gen_amalgamated expanded: #include "perfetto/ext/base/string_view.h"
3222
3223 namespace perfetto {
3224 namespace base {
3225
3226 // static
3227 constexpr size_t StringView::npos;
3228
3229 } // namespace base
3230 } // namespace perfetto
3231 // gen_amalgamated begin source: src/base/subprocess.cc
3232 // gen_amalgamated begin header: include/perfetto/ext/base/subprocess.h
3233 // gen_amalgamated begin header: include/perfetto/ext/base/pipe.h
3234 /*
3235 * Copyright (C) 2018 The Android Open Source Project
3236 *
3237 * Licensed under the Apache License, Version 2.0 (the "License");
3238 * you may not use this file except in compliance with the License.
3239 * You may obtain a copy of the License at
3240 *
3241 * http://www.apache.org/licenses/LICENSE-2.0
3242 *
3243 * Unless required by applicable law or agreed to in writing, software
3244 * distributed under the License is distributed on an "AS IS" BASIS,
3245 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3246 * See the License for the specific language governing permissions and
3247 * limitations under the License.
3248 */
3249
3250 #ifndef INCLUDE_PERFETTO_EXT_BASE_PIPE_H_
3251 #define INCLUDE_PERFETTO_EXT_BASE_PIPE_H_
3252
3253 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
3254
3255 namespace perfetto {
3256 namespace base {
3257
3258 class Pipe {
3259 public:
3260 enum Flags {
3261 kBothBlock = 0,
3262 kBothNonBlock,
3263 kRdNonBlock,
3264 kWrNonBlock,
3265 };
3266
3267 static Pipe Create(Flags = kBothBlock);
3268
3269 Pipe();
3270 Pipe(Pipe&&) noexcept;
3271 Pipe& operator=(Pipe&&);
3272
3273 ScopedFile rd;
3274 ScopedFile wr;
3275 };
3276
3277 } // namespace base
3278 } // namespace perfetto
3279
3280 #endif // INCLUDE_PERFETTO_EXT_BASE_PIPE_H_
3281 /*
3282 * Copyright (C) 2020 The Android Open Source Project
3283 *
3284 * Licensed under the Apache License, Version 2.0 (the "License");
3285 * you may not use this file except in compliance with the License.
3286 * You may obtain a copy of the License at
3287 *
3288 * http://www.apache.org/licenses/LICENSE-2.0
3289 *
3290 * Unless required by applicable law or agreed to in writing, software
3291 * distributed under the License is distributed on an "AS IS" BASIS,
3292 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3293 * See the License for the specific language governing permissions and
3294 * limitations under the License.
3295 */
3296
3297 #ifndef INCLUDE_PERFETTO_EXT_BASE_SUBPROCESS_H_
3298 #define INCLUDE_PERFETTO_EXT_BASE_SUBPROCESS_H_
3299
3300 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
3301
3302 // This is a #if as opposite to a GN condition, because GN conditions aren't propagated when
3303 // translating to Bazel or other build systems, as they get resolved at translation time. Without
3304 // this, the Bazel build breaks on Windows.
3305 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
3306 PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
3307 PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
3308 #define PERFETTO_HAS_SUBPROCESS() 1
3309 #else
3310 #define PERFETTO_HAS_SUBPROCESS() 0
3311 #endif
3312
3313 #include <functional>
3314 #include <initializer_list>
3315 #include <string>
3316 #include <thread>
3317 #include <vector>
3318
3319 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
3320 // gen_amalgamated expanded: #include "perfetto/base/proc_utils.h"
3321 // gen_amalgamated expanded: #include "perfetto/ext/base/pipe.h"
3322 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
3323
3324 namespace perfetto {
3325 namespace base {
3326
3327 // Handles creation and lifecycle management of subprocesses, taking care of
3328 // all subtleties involved in handling processes on UNIX.
3329 // This class allows to deal with macro two use-cases:
3330 // 1) fork() + exec() equivalent: for spawning a brand new process image.
3331 // This happens when |args.exec_cmd| is not empty.
3332 // This is safe to use even in a multi-threaded environment.
3333 // 2) fork(): for spawning a process and running a function.
3334 // This happens when |args.entrypoint_for_testing| is not empty.
3335 // This is intended only for tests as it is extremely subtle.
3336 // This mode must be used with extreme care. Before the entrypoint is
3337 // invoked all file descriptors other than stdin/out/err and the ones
3338 // specified in |args.preserve_fds| will be closed, to avoid each process
3339 // retaining a dupe of other subprocesses pipes. This however means that
3340 // any non trivial calls (including logging) must be avoided as they might
3341 // refer to FDs that are now closed. The entrypoint should really be used
3342 // just to signal a pipe or similar for synchronizing sequencing in tests.
3343
3344 //
3345 // This class allows to control stdin/out/err pipe redirection and takes care
3346 // of keeping all the pipes pumped (stdin) / drained (stdout/err), in a similar
3347 // fashion of python's subprocess.Communicate()
3348 // stdin: is always piped and closed once the |args.input| buffer is written.
3349 // stdout/err can be either:
3350 // - dup()ed onto the parent process stdout/err.
3351 // - redirected onto /dev/null.
3352 // - piped onto a buffer (see output() method). There is only one output
3353 // buffer in total. If both stdout and stderr are set to kBuffer mode, they
3354 // will be merged onto the same. There doesn't seem any use case where they
3355 // are needed distinctly.
3356 //
3357 // Some caveats worth mentioning:
3358 // - It always waitpid()s, to avoid leaving zombies around. If the process is
3359 // not terminated by the time the destructor is reached, the dtor will
3360 // send a SIGKILL and wait for the termination.
3361 // - After fork()-ing it will close all file descriptors, preserving only
3362 // stdin/out/err and the fds listed in |args.preserve_fds|.
3363 // - On Linux/Android, the child process will be SIGKILL-ed if the calling
3364 // thread exists, even if the Subprocess is std::move()-d onto another thread.
3365 // This happens by virtue PR_SET_PDEATHSIG, which is used to avoid that
3366 // child processes are leaked in the case of a crash of the parent (frequent
3367 // in tests). However, the child process might still be leaked if execing
3368 // a setuid/setgid binary (see man 2 prctl).
3369 //
3370 // Usage:
3371 // base::Subprocess p({"/bin/cat", "-"});
3372 // (or equivalently:
3373 // base::Subprocess p;
3374 // p.args.exec_cmd.push_back("/bin/cat");
3375 // p.args.exec_cmd.push_back("-");
3376 // )
3377 // p.args.stdout_mode = base::Subprocess::kBuffer;
3378 // p.args.stderr_mode = base::Subprocess::kInherit;
3379 // p.args.input = "stdin contents";
3380 // p.Call();
3381 // (or equivalently:
3382 // p.Start();
3383 // p.Wait();
3384 // )
3385 // EXPECT_EQ(p.status(), base::Subprocess::kExited);
3386 // EXPECT_EQ(p.returncode(), 0);
3387 class Subprocess {
3388 public:
3389 enum Status {
3390 kNotStarted = 0, // Before calling Start() or Call().
3391 kRunning, // After calling Start(), before Wait().
3392 kExited, // The subprocess exited (either succesully or not).
3393 kKilledBySignal, // The subprocess has been killed by a signal.
3394 };
3395
3396 enum OutputMode {
3397 kInherit = 0, // Inherit's the caller process stdout/stderr.
3398 kDevNull, // dup() onto /dev/null
3399 kBuffer, // dup() onto a pipe and move it into the output() buffer.
3400 kFd, // dup() onto the passed args.fd.
3401 };
3402
3403 // Input arguments for configuring the subprocess behavior.
3404 struct Args {
Argsperfetto::base::Subprocess::Args3405 Args(std::initializer_list<std::string> _cmd = {}) : exec_cmd(_cmd) {}
3406 Args(Args&&) noexcept;
3407 Args& operator=(Args&&);
3408 // If non-empty this will cause an exec() when Start()/Call() are called.
3409 std::vector<std::string> exec_cmd;
3410
3411 // If non-empty, it changes the argv[0] argument passed to exec. If
3412 // unset, argv[0] == exec_cmd[0]. This is to handle cases like:
3413 // exec_cmd = {"/proc/self/exec"}, argv0: "my_custom_test_override".
3414 std::string argv0_override;
3415
3416 // If non-empty this will be invoked on the fork()-ed child process, after
3417 // stdin/out/err has been redirected and all other file descriptor are
3418 // closed.
3419 // It is valid to specify both |exec_cmd| AND |entrypoint_for_testing|.
3420 // In this case |entrypoint_for_testing| will be invoked just before the
3421 // exec() call, but after having closed all fds % stdin/out/err.
3422 // This is for synchronization barriers in tests.
3423 std::function<void()> entrypoint_for_testing;
3424
3425 // If non-empty, replaces the environment passed to exec().
3426 std::vector<std::string> env;
3427
3428 // The file descriptors in this list will not be closed.
3429 std::vector<int> preserve_fds;
3430
3431 // The data to push in the child process stdin.
3432 std::string input;
3433
3434 OutputMode stdout_mode = kInherit;
3435 OutputMode stderr_mode = kInherit;
3436
3437 base::ScopedFile out_fd;
3438
3439 // Returns " ".join(exec_cmd), quoting arguments.
3440 std::string GetCmdString() const;
3441 };
3442
3443 struct ResourceUsage {
3444 uint32_t cpu_utime_ms = 0;
3445 uint32_t cpu_stime_ms = 0;
3446 uint32_t max_rss_kb = 0;
3447 uint32_t min_page_faults = 0;
3448 uint32_t maj_page_faults = 0;
3449 uint32_t vol_ctx_switch = 0;
3450 uint32_t invol_ctx_switch = 0;
3451
cpu_time_msperfetto::base::Subprocess::ResourceUsage3452 uint32_t cpu_time_ms() const { return cpu_utime_ms + cpu_stime_ms; }
3453 };
3454
3455 explicit Subprocess(std::initializer_list<std::string> exec_cmd = {});
3456 Subprocess(Subprocess&&) noexcept;
3457 Subprocess& operator=(Subprocess&&);
3458 ~Subprocess(); // It will KillAndWaitForTermination() if still alive.
3459
3460 // Starts the subprocess but doesn't wait for its termination. The caller
3461 // is expected to either call Wait() or Poll() after this call.
3462 void Start();
3463
3464 // Wait for process termination. Can be called more than once.
3465 // Args:
3466 // |timeout_ms| = 0: wait indefinitely.
3467 // |timeout_ms| > 0: wait for at most |timeout_ms|.
3468 // Returns:
3469 // True: The process terminated. See status() and returncode().
3470 // False: Timeout reached, the process is still running. In this case the
3471 // process will be left in the kRunning state.
3472 bool Wait(int timeout_ms = 0);
3473
3474 // Equivalent of Start() + Wait();
3475 // Returns true if the process exited cleanly with return code 0. False in
3476 // any othe case.
3477 bool Call(int timeout_ms = 0);
3478
3479 Status Poll();
3480
3481 // Sends a signal (SIGKILL if not specified) and wait for process termination.
3482 void KillAndWaitForTermination(int sig_num = 0);
3483
pid() const3484 PlatformProcessId pid() const { return s_.pid; }
3485
3486 // The accessors below are updated only after a call to Poll(), Wait() or
3487 // KillAndWaitForTermination().
3488 // In most cases you want to call Poll() rather than these accessors.
3489
status() const3490 Status status() const { return s_.status; }
returncode() const3491 int returncode() const { return s_.returncode; }
3492
3493 // This contains both stdout and stderr (if the corresponding _mode ==
3494 // kBuffer). It's non-const so the caller can std::move() it.
output()3495 std::string& output() { return s_.output; }
rusage() const3496 const ResourceUsage& rusage() const { return *s_.rusage; }
3497
3498 Args args;
3499
3500 private:
3501 Subprocess(const Subprocess&) = delete;
3502 Subprocess& operator=(const Subprocess&) = delete;
3503 void TryPushStdin();
3504 void TryReadStdoutAndErr();
3505 void TryReadExitStatus();
3506 void KillAtMostOnce();
3507 bool PollInternal(int poll_timeout_ms);
3508
3509 // This is to deal robustly with the move operators, without having to
3510 // manually maintain member-wise move instructions.
3511 struct MovableState {
3512 base::Pipe stdin_pipe;
3513 base::Pipe stdouterr_pipe;
3514 base::Pipe exit_status_pipe;
3515 PlatformProcessId pid;
3516 size_t input_written = 0;
3517 Status status = kNotStarted;
3518 int returncode = -1;
3519 std::string output; // Stdin+stderr. Only when kBuffer.
3520 std::thread waitpid_thread;
3521 std::unique_ptr<ResourceUsage> rusage;
3522 };
3523
3524 MovableState s_;
3525 };
3526
3527 } // namespace base
3528 } // namespace perfetto
3529
3530 #endif // INCLUDE_PERFETTO_EXT_BASE_SUBPROCESS_H_
3531 /*
3532 * Copyright (C) 2020 The Android Open Source Project
3533 *
3534 * Licensed under the Apache License, Version 2.0 (the "License");
3535 * you may not use this file except in compliance with the License.
3536 * You may obtain a copy of the License at
3537 *
3538 * http://www.apache.org/licenses/LICENSE-2.0
3539 *
3540 * Unless required by applicable law or agreed to in writing, software
3541 * distributed under the License is distributed on an "AS IS" BASIS,
3542 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3543 * See the License for the specific language governing permissions and
3544 * limitations under the License.
3545 */
3546
3547 // gen_amalgamated expanded: #include "perfetto/ext/base/subprocess.h"
3548
3549 #if PERFETTO_HAS_SUBPROCESS()
3550
3551 #include <poll.h>
3552 #include <signal.h>
3553 #include <stdio.h>
3554 #include <sys/resource.h>
3555 #include <sys/types.h>
3556 #include <sys/wait.h>
3557 #include <unistd.h>
3558
3559 #include <algorithm>
3560 #include <thread>
3561 #include <tuple>
3562
3563 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
3564 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
3565 // gen_amalgamated expanded: #include "perfetto/base/time.h"
3566 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
3567
3568 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
3569 PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
3570 #include <sys/prctl.h>
3571 #endif
3572
3573 // In MacOS this is not defined in any header.
3574 extern "C" char** environ;
3575
3576 namespace perfetto {
3577 namespace base {
3578
3579 namespace {
3580
3581 struct ChildProcessArgs {
3582 Subprocess::Args* create_args;
3583 const char* exec_cmd = nullptr;
3584 std::vector<char*> argv;
3585 std::vector<char*> env;
3586 int stdin_pipe_rd = -1;
3587 int stdouterr_pipe_wr = -1;
3588 };
3589
3590 // Don't add any dynamic allocation in this function. This will be invoked
3591 // under a fork(), potentially in a state where the allocator lock is held.
ChildProcess(ChildProcessArgs * args)3592 void __attribute__((noreturn)) ChildProcess(ChildProcessArgs* args) {
3593 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
3594 PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
3595 // In no case we want a child process to outlive its parent process. This is
3596 // relevant for tests, so that a test failure/crash doesn't leave child
3597 // processes around that get reparented to init.
3598 prctl(PR_SET_PDEATHSIG, SIGKILL);
3599 #endif
3600
3601 auto die = [args](const char* err) __attribute__((noreturn)) {
3602 base::ignore_result(write(args->stdouterr_pipe_wr, err, strlen(err)));
3603 base::ignore_result(write(args->stdouterr_pipe_wr, "\n", 1));
3604 // From https://www.gnu.org/software/libc/manual/html_node/Exit-Status.html
3605 // "In particular, the value 128 is used to indicate failure to execute
3606 // another program in a subprocess. This convention is not universally
3607 // obeyed, but it is a good idea to follow it in your programs."
3608 _exit(128);
3609 };
3610
3611 auto set_fd_close_on_exec = [&die](int fd, bool close_on_exec) {
3612 int flags = fcntl(fd, F_GETFD, 0);
3613 if (flags < 0)
3614 die("fcntl(F_GETFD) failed");
3615 flags = close_on_exec ? (flags | FD_CLOEXEC) : (flags & ~FD_CLOEXEC);
3616 if (fcntl(fd, F_SETFD, flags) < 0)
3617 die("fcntl(F_SETFD) failed");
3618 };
3619
3620 if (getppid() == 1)
3621 die("terminating because parent process died");
3622
3623 if (dup2(args->stdin_pipe_rd, STDIN_FILENO) == -1)
3624 die("Failed to dup2(STDIN)");
3625 close(args->stdin_pipe_rd);
3626
3627 switch (args->create_args->stdout_mode) {
3628 case Subprocess::kInherit:
3629 break;
3630 case Subprocess::kDevNull: {
3631 if (dup2(open("/dev/null", O_RDWR), STDOUT_FILENO) == -1)
3632 die("Failed to dup2(STDOUT)");
3633 break;
3634 }
3635 case Subprocess::kBuffer:
3636 if (dup2(args->stdouterr_pipe_wr, STDOUT_FILENO) == -1)
3637 die("Failed to dup2(STDOUT)");
3638 break;
3639 case Subprocess::kFd:
3640 if (dup2(*args->create_args->out_fd, STDOUT_FILENO) == -1)
3641 die("Failed to dup2(STDOUT)");
3642 break;
3643 }
3644
3645 switch (args->create_args->stderr_mode) {
3646 case Subprocess::kInherit:
3647 break;
3648 case Subprocess::kDevNull: {
3649 if (dup2(open("/dev/null", O_RDWR), STDERR_FILENO) == -1)
3650 die("Failed to dup2(STDERR)");
3651 break;
3652 }
3653 case Subprocess::kBuffer:
3654 if (dup2(args->stdouterr_pipe_wr, STDERR_FILENO) == -1)
3655 die("Failed to dup2(STDERR)");
3656 break;
3657 case Subprocess::kFd:
3658 if (dup2(*args->create_args->out_fd, STDERR_FILENO) == -1)
3659 die("Failed to dup2(STDERR)");
3660 break;
3661 }
3662
3663 // Close all FDs % stdin/out/err and the ones that the client explicitly
3664 // asked to retain. The reason for this is twofold:
3665 // 1. For exec-only (i.e. entrypoint == empty) cases: it avoids leaking FDs
3666 // that didn't get marked as O_CLOEXEC by accident.
3667 // 2. In fork() mode (entrypoint not empty) avoids retaining a dup of eventfds
3668 // that would prevent the parent process to receive EOFs (tests usually use
3669 // pipes as a synchronization mechanism between subprocesses).
3670 const auto& preserve_fds = args->create_args->preserve_fds;
3671 for (int i = 0; i < 512; i++) {
3672 if (i != STDIN_FILENO && i != STDERR_FILENO && i != STDOUT_FILENO &&
3673 i != args->stdouterr_pipe_wr &&
3674 !std::count(preserve_fds.begin(), preserve_fds.end(), i)) {
3675 close(i);
3676 }
3677 }
3678
3679 // Clears O_CLOEXEC from stdin/out/err. These are the only FDs that we want
3680 // to be preserved after the exec().
3681 set_fd_close_on_exec(STDIN_FILENO, false);
3682 set_fd_close_on_exec(STDOUT_FILENO, false);
3683 set_fd_close_on_exec(STDERR_FILENO, false);
3684
3685 // If the caller specified a std::function entrypoint, run that first.
3686 if (args->create_args->entrypoint_for_testing)
3687 args->create_args->entrypoint_for_testing();
3688
3689 // If the caller specified only an entrypoint, without any args, exit now.
3690 // Otherwise proceed with the exec() below.
3691 if (!args->exec_cmd)
3692 _exit(0);
3693
3694 // If |args[0]| is a path use execv() (which takes a path), othewise use
3695 // exevp(), which uses the shell and follows PATH.
3696 if (strchr(args->exec_cmd, '/')) {
3697 char** env = args->env.empty() ? environ : args->env.data();
3698 execve(args->exec_cmd, args->argv.data(), env);
3699 } else {
3700 // There is no execvpe() on Mac.
3701 if (!args->env.empty())
3702 die("A full path is required for |exec_cmd| when setting |env|");
3703 execvp(args->exec_cmd, args->argv.data());
3704 }
3705
3706 // Reached only if execv fails.
3707 die("execve() failed");
3708 }
3709
3710 } // namespace
3711
3712 Subprocess::Args::Args(Args&&) noexcept = default;
3713 Subprocess::Args& Subprocess::Args::operator=(Args&&) = default;
3714
Subprocess(std::initializer_list<std::string> a)3715 Subprocess::Subprocess(std::initializer_list<std::string> a) : args(a) {
3716 s_.rusage.reset(new ResourceUsage());
3717 }
3718
Subprocess(Subprocess && other)3719 Subprocess::Subprocess(Subprocess&& other) noexcept {
3720 static_assert(sizeof(Subprocess) == sizeof(std::tuple<MovableState, Args>),
3721 "base::Subprocess' move ctor needs updating");
3722 s_ = std::move(other.s_);
3723 args = std::move(other.args);
3724
3725 // Reset the state of the moved-from object.
3726 other.s_.status = kNotStarted; // So the dtor doesn't try to kill().
3727 other.~Subprocess();
3728 new (&other) Subprocess();
3729 }
3730
operator =(Subprocess && other)3731 Subprocess& Subprocess::operator=(Subprocess&& other) {
3732 this->~Subprocess();
3733 new (this) Subprocess(std::move(other));
3734 return *this;
3735 }
3736
~Subprocess()3737 Subprocess::~Subprocess() {
3738 if (s_.status == kRunning)
3739 KillAndWaitForTermination();
3740 PERFETTO_CHECK(!s_.waitpid_thread.joinable());
3741 }
3742
Start()3743 void Subprocess::Start() {
3744 ChildProcessArgs proc_args;
3745 proc_args.create_args = &args;
3746
3747 // Setup argv.
3748 if (!args.exec_cmd.empty()) {
3749 proc_args.exec_cmd = args.exec_cmd[0].c_str();
3750 for (const std::string& arg : args.exec_cmd)
3751 proc_args.argv.push_back(const_cast<char*>(arg.c_str()));
3752 proc_args.argv.push_back(nullptr);
3753
3754 if (!args.argv0_override.empty())
3755 proc_args.argv[0] = const_cast<char*>(args.argv0_override.c_str());
3756 }
3757
3758 // Setup env.
3759 if (!args.env.empty()) {
3760 for (const std::string& str : args.env)
3761 proc_args.env.push_back(const_cast<char*>(str.c_str()));
3762 proc_args.env.push_back(nullptr);
3763 }
3764
3765 // Setup the pipes for stdin/err redirection.
3766 s_.stdin_pipe = base::Pipe::Create(base::Pipe::kWrNonBlock);
3767 proc_args.stdin_pipe_rd = *s_.stdin_pipe.rd;
3768 s_.stdouterr_pipe = base::Pipe::Create(base::Pipe::kRdNonBlock);
3769 proc_args.stdouterr_pipe_wr = *s_.stdouterr_pipe.wr;
3770
3771 // Spawn the child process that will exec().
3772 s_.pid = fork();
3773 PERFETTO_CHECK(s_.pid >= 0);
3774 if (s_.pid == 0) {
3775 // Close the parent-ends of the pipes.
3776 s_.stdin_pipe.wr.reset();
3777 s_.stdouterr_pipe.rd.reset();
3778 ChildProcess(&proc_args);
3779 // ChildProcess() doesn't return, not even in case of failures.
3780 PERFETTO_FATAL("not reached");
3781 }
3782
3783 s_.status = kRunning;
3784
3785 // Close the child-end of the pipes.
3786 // Deliberately NOT closing the s_.stdin_pipe.rd. This is to avoid crashing
3787 // with a SIGPIPE if the process exits without consuming its stdin, while
3788 // the parent tries to write() on the other end of the stdin pipe.
3789 s_.stdouterr_pipe.wr.reset();
3790
3791 // Spawn a thread that is blocked on waitpid() and writes the termination
3792 // status onto a pipe. The problem here is that waipid() doesn't have a
3793 // timeout option and can't be passed to poll(). The alternative would be
3794 // using a SIGCHLD handler, but anecdotally signal handlers introduce more
3795 // problems than what they solve.
3796 s_.exit_status_pipe = base::Pipe::Create(base::Pipe::kRdNonBlock);
3797
3798 // Both ends of the pipe are closed after the thread.join().
3799 int pid = s_.pid;
3800 int exit_status_pipe_wr = s_.exit_status_pipe.wr.release();
3801 auto* rusage = s_.rusage.get();
3802 s_.waitpid_thread = std::thread([pid, exit_status_pipe_wr, rusage] {
3803 int pid_stat = -1;
3804 struct rusage usg {};
3805 int wait_res = PERFETTO_EINTR(wait4(pid, &pid_stat, 0, &usg));
3806 PERFETTO_CHECK(wait_res == pid);
3807
3808 auto tv_to_ms = [](const struct timeval& tv) {
3809 return static_cast<uint32_t>(tv.tv_sec * 1000 + tv.tv_usec / 1000);
3810 };
3811 rusage->cpu_utime_ms = tv_to_ms(usg.ru_utime);
3812 rusage->cpu_stime_ms = tv_to_ms(usg.ru_stime);
3813 rusage->max_rss_kb = static_cast<uint32_t>(usg.ru_maxrss) / 1000;
3814 rusage->min_page_faults = static_cast<uint32_t>(usg.ru_minflt);
3815 rusage->maj_page_faults = static_cast<uint32_t>(usg.ru_majflt);
3816 rusage->vol_ctx_switch = static_cast<uint32_t>(usg.ru_nvcsw);
3817 rusage->invol_ctx_switch = static_cast<uint32_t>(usg.ru_nivcsw);
3818
3819 base::ignore_result(PERFETTO_EINTR(
3820 write(exit_status_pipe_wr, &pid_stat, sizeof(pid_stat))));
3821 PERFETTO_CHECK(close(exit_status_pipe_wr) == 0 || errno == EINTR);
3822 });
3823 }
3824
Poll()3825 Subprocess::Status Subprocess::Poll() {
3826 if (s_.status != kRunning)
3827 return s_.status; // Nothing to poll.
3828 while (PollInternal(0 /* don't block*/)) {
3829 }
3830 return s_.status;
3831 }
3832
3833 // |timeout_ms| semantic:
3834 // -1: Block indefinitely.
3835 // 0: Don't block, return immediately.
3836 // >0: Block for at most X ms.
3837 // Returns:
3838 // True: Read at least one fd (so there might be more queued).
3839 // False: if all fds reached quiescent (no data to read/write).
PollInternal(int poll_timeout_ms)3840 bool Subprocess::PollInternal(int poll_timeout_ms) {
3841 struct pollfd fds[3]{};
3842 size_t num_fds = 0;
3843 if (s_.exit_status_pipe.rd) {
3844 fds[num_fds].fd = *s_.exit_status_pipe.rd;
3845 fds[num_fds].events = POLLIN;
3846 num_fds++;
3847 }
3848 if (s_.stdouterr_pipe.rd) {
3849 fds[num_fds].fd = *s_.stdouterr_pipe.rd;
3850 fds[num_fds].events = POLLIN;
3851 num_fds++;
3852 }
3853 if (s_.stdin_pipe.wr) {
3854 fds[num_fds].fd = *s_.stdin_pipe.wr;
3855 fds[num_fds].events = POLLOUT;
3856 num_fds++;
3857 }
3858
3859 if (num_fds == 0)
3860 return false;
3861
3862 auto nfds = static_cast<nfds_t>(num_fds);
3863 int poll_res = PERFETTO_EINTR(poll(fds, nfds, poll_timeout_ms));
3864 PERFETTO_CHECK(poll_res >= 0);
3865
3866 TryReadStdoutAndErr();
3867 TryPushStdin();
3868 TryReadExitStatus();
3869
3870 return poll_res > 0;
3871 }
3872
Wait(int timeout_ms)3873 bool Subprocess::Wait(int timeout_ms) {
3874 PERFETTO_CHECK(s_.status != kNotStarted);
3875
3876 // Break out of the loop only after both conditions are satisfied:
3877 // - All stdout/stderr data has been read (if kBuffer).
3878 // - The process exited.
3879 // Note that the two events can happen arbitrary order. After the process
3880 // exits, there might be still data in the pipe buffer, which we want to
3881 // read fully.
3882 //
3883 // Instead, don't wait on the stdin to be fully written. The child process
3884 // might exit prematurely (or crash). If that happens, we can end up in a
3885 // state where the write(stdin_pipe_.wr) will never unblock.
3886
3887 const int64_t t_start = base::GetWallTimeMs().count();
3888 while (s_.exit_status_pipe.rd || s_.stdouterr_pipe.rd) {
3889 int poll_timeout_ms = -1; // Block until a FD is ready.
3890 if (timeout_ms > 0) {
3891 const int64_t now = GetWallTimeMs().count();
3892 poll_timeout_ms = timeout_ms - static_cast<int>(now - t_start);
3893 if (poll_timeout_ms <= 0)
3894 return false;
3895 }
3896 PollInternal(poll_timeout_ms);
3897 } // while(...)
3898 return true;
3899 }
3900
Call(int timeout_ms)3901 bool Subprocess::Call(int timeout_ms) {
3902 PERFETTO_CHECK(s_.status == kNotStarted);
3903 Start();
3904
3905 if (!Wait(timeout_ms)) {
3906 KillAndWaitForTermination();
3907 // TryReadExitStatus must have joined the thread.
3908 PERFETTO_DCHECK(!s_.waitpid_thread.joinable());
3909 }
3910 PERFETTO_DCHECK(s_.status != kRunning);
3911 return s_.status == kExited && s_.returncode == 0;
3912 }
3913
TryReadExitStatus()3914 void Subprocess::TryReadExitStatus() {
3915 if (!s_.exit_status_pipe.rd)
3916 return;
3917
3918 int pid_stat = -1;
3919 int64_t rsize = PERFETTO_EINTR(
3920 read(*s_.exit_status_pipe.rd, &pid_stat, sizeof(pid_stat)));
3921 if (rsize < 0 && errno == EAGAIN)
3922 return;
3923
3924 if (rsize > 0) {
3925 PERFETTO_CHECK(rsize == sizeof(pid_stat));
3926 } else if (rsize < 0) {
3927 PERFETTO_PLOG("Subprocess read(s_.exit_status_pipe) failed");
3928 }
3929 s_.waitpid_thread.join();
3930 s_.exit_status_pipe.rd.reset();
3931
3932 if (WIFEXITED(pid_stat)) {
3933 s_.returncode = WEXITSTATUS(pid_stat);
3934 s_.status = kExited;
3935 } else if (WIFSIGNALED(pid_stat)) {
3936 s_.returncode = 128 + WTERMSIG(pid_stat); // Follow bash convention.
3937 s_.status = kKilledBySignal;
3938 } else {
3939 PERFETTO_FATAL("waitpid() returned an unexpected value (0x%x)", pid_stat);
3940 }
3941 }
3942
3943 // If the stidn pipe is still open, push input data and close it at the end.
TryPushStdin()3944 void Subprocess::TryPushStdin() {
3945 if (!s_.stdin_pipe.wr)
3946 return;
3947
3948 PERFETTO_DCHECK(args.input.empty() || s_.input_written < args.input.size());
3949 if (args.input.size()) {
3950 int64_t wsize =
3951 PERFETTO_EINTR(write(*s_.stdin_pipe.wr, &args.input[s_.input_written],
3952 args.input.size() - s_.input_written));
3953 if (wsize < 0 && errno == EAGAIN)
3954 return;
3955
3956 if (wsize >= 0) {
3957 // Whether write() can return 0 is one of the greatest mysteries of UNIX.
3958 // Just ignore it.
3959 s_.input_written += static_cast<size_t>(wsize);
3960 } else {
3961 PERFETTO_PLOG("Subprocess write(stdin) failed");
3962 s_.stdin_pipe.wr.reset();
3963 }
3964 }
3965 PERFETTO_DCHECK(s_.input_written <= args.input.size());
3966 if (s_.input_written == args.input.size())
3967 s_.stdin_pipe.wr.reset(); // Close stdin.
3968 }
3969
TryReadStdoutAndErr()3970 void Subprocess::TryReadStdoutAndErr() {
3971 if (!s_.stdouterr_pipe.rd)
3972 return;
3973 char buf[4096];
3974 int64_t rsize = PERFETTO_EINTR(read(*s_.stdouterr_pipe.rd, buf, sizeof(buf)));
3975 if (rsize < 0 && errno == EAGAIN)
3976 return;
3977
3978 if (rsize > 0) {
3979 s_.output.append(buf, static_cast<size_t>(rsize));
3980 } else if (rsize == 0 /* EOF */) {
3981 s_.stdouterr_pipe.rd.reset();
3982 } else {
3983 PERFETTO_PLOG("Subprocess read(stdout/err) failed");
3984 s_.stdouterr_pipe.rd.reset();
3985 }
3986 }
3987
KillAndWaitForTermination(int sig_num)3988 void Subprocess::KillAndWaitForTermination(int sig_num) {
3989 kill(s_.pid, sig_num ? sig_num : SIGKILL);
3990 Wait();
3991 }
3992
GetCmdString() const3993 std::string Subprocess::Args::GetCmdString() const {
3994 std::string str;
3995 for (size_t i = 0; i < exec_cmd.size(); i++) {
3996 str += i > 0 ? " \"" : "";
3997 str += exec_cmd[i];
3998 str += i > 0 ? "\"" : "";
3999 }
4000 return str;
4001 }
4002
4003 } // namespace base
4004 } // namespace perfetto
4005
4006 #endif // PERFETTO_HAS_SUBPROCESS()
4007 // gen_amalgamated begin source: src/base/thread_checker.cc
4008 // gen_amalgamated begin header: include/perfetto/ext/base/thread_checker.h
4009 /*
4010 * Copyright (C) 2017 The Android Open Source Project
4011 *
4012 * Licensed under the Apache License, Version 2.0 (the "License");
4013 * you may not use this file except in compliance with the License.
4014 * You may obtain a copy of the License at
4015 *
4016 * http://www.apache.org/licenses/LICENSE-2.0
4017 *
4018 * Unless required by applicable law or agreed to in writing, software
4019 * distributed under the License is distributed on an "AS IS" BASIS,
4020 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4021 * See the License for the specific language governing permissions and
4022 * limitations under the License.
4023 */
4024
4025 #ifndef INCLUDE_PERFETTO_EXT_BASE_THREAD_CHECKER_H_
4026 #define INCLUDE_PERFETTO_EXT_BASE_THREAD_CHECKER_H_
4027
4028 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
4029
4030 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
4031 #include <pthread.h>
4032 #endif
4033 #include <atomic>
4034
4035 // gen_amalgamated expanded: #include "perfetto/base/export.h"
4036 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
4037 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
4038
4039 namespace perfetto {
4040 namespace base {
4041
4042 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
4043 using ThreadID = unsigned long;
4044 #else
4045 using ThreadID = pthread_t;
4046 #endif
4047
4048 class PERFETTO_EXPORT ThreadChecker {
4049 public:
4050 ThreadChecker();
4051 ~ThreadChecker();
4052 ThreadChecker(const ThreadChecker&);
4053 ThreadChecker& operator=(const ThreadChecker&);
4054 bool CalledOnValidThread() const PERFETTO_WARN_UNUSED_RESULT;
4055 void DetachFromThread();
4056
4057 private:
4058 mutable std::atomic<ThreadID> thread_id_;
4059 };
4060
4061 #if PERFETTO_DCHECK_IS_ON() && !PERFETTO_BUILDFLAG(PERFETTO_CHROMIUM_BUILD)
4062 // TODO(primiano) Use Chromium's thread checker in Chromium.
4063 #define PERFETTO_THREAD_CHECKER(name) base::ThreadChecker name;
4064 #define PERFETTO_DCHECK_THREAD(name) \
4065 PERFETTO_DCHECK((name).CalledOnValidThread())
4066 #define PERFETTO_DETACH_FROM_THREAD(name) (name).DetachFromThread()
4067 #else
4068 #define PERFETTO_THREAD_CHECKER(name)
4069 #define PERFETTO_DCHECK_THREAD(name)
4070 #define PERFETTO_DETACH_FROM_THREAD(name)
4071 #endif // PERFETTO_DCHECK_IS_ON()
4072
4073 } // namespace base
4074 } // namespace perfetto
4075
4076 #endif // INCLUDE_PERFETTO_EXT_BASE_THREAD_CHECKER_H_
4077 /*
4078 * Copyright (C) 2017 The Android Open Source Project
4079 *
4080 * Licensed under the Apache License, Version 2.0 (the "License");
4081 * you may not use this file except in compliance with the License.
4082 * You may obtain a copy of the License at
4083 *
4084 * http://www.apache.org/licenses/LICENSE-2.0
4085 *
4086 * Unless required by applicable law or agreed to in writing, software
4087 * distributed under the License is distributed on an "AS IS" BASIS,
4088 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4089 * See the License for the specific language governing permissions and
4090 * limitations under the License.
4091 */
4092
4093 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_checker.h"
4094
4095 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
4096 #include <Windows.h>
4097 #endif
4098
4099 namespace perfetto {
4100 namespace base {
4101
4102 namespace {
4103 constexpr ThreadID kDetached{};
4104
CurrentThreadId()4105 ThreadID CurrentThreadId() {
4106 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
4107 return ::GetCurrentThreadId();
4108 #else
4109 return pthread_self();
4110 #endif
4111 }
4112 } // namespace
4113
ThreadChecker()4114 ThreadChecker::ThreadChecker() {
4115 thread_id_.store(CurrentThreadId());
4116 }
4117
4118 ThreadChecker::~ThreadChecker() = default;
4119
ThreadChecker(const ThreadChecker & other)4120 ThreadChecker::ThreadChecker(const ThreadChecker& other) {
4121 thread_id_ = other.thread_id_.load();
4122 }
4123
operator =(const ThreadChecker & other)4124 ThreadChecker& ThreadChecker::operator=(const ThreadChecker& other) {
4125 thread_id_ = other.thread_id_.load();
4126 return *this;
4127 }
4128
CalledOnValidThread() const4129 bool ThreadChecker::CalledOnValidThread() const {
4130 auto self = CurrentThreadId();
4131
4132 // Will re-attach if previously detached using DetachFromThread().
4133 auto prev_value = kDetached;
4134 if (thread_id_.compare_exchange_strong(prev_value, self))
4135 return true;
4136 return prev_value == self;
4137 }
4138
DetachFromThread()4139 void ThreadChecker::DetachFromThread() {
4140 thread_id_.store(kDetached);
4141 }
4142
4143 } // namespace base
4144 } // namespace perfetto
4145 // gen_amalgamated begin source: src/base/time.cc
4146 /*
4147 * Copyright (C) 2018 The Android Open Source Project
4148 *
4149 * Licensed under the Apache License, Version 2.0 (the "License");
4150 * you may not use this file except in compliance with the License.
4151 * You may obtain a copy of the License at
4152 *
4153 * http://www.apache.org/licenses/LICENSE-2.0
4154 *
4155 * Unless required by applicable law or agreed to in writing, software
4156 * distributed under the License is distributed on an "AS IS" BASIS,
4157 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4158 * See the License for the specific language governing permissions and
4159 * limitations under the License.
4160 */
4161
4162 // gen_amalgamated expanded: #include "perfetto/base/time.h"
4163 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
4164
4165 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
4166 #include <Windows.h>
4167 #else
4168 #include <unistd.h>
4169 #endif
4170
4171 namespace perfetto {
4172 namespace base {
4173
4174 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
4175
GetWallTimeNs()4176 TimeNanos GetWallTimeNs() {
4177 LARGE_INTEGER freq;
4178 ::QueryPerformanceFrequency(&freq);
4179 LARGE_INTEGER counter;
4180 ::QueryPerformanceCounter(&counter);
4181 double elapsed_nanoseconds = (1e9 * counter.QuadPart) / freq.QuadPart;
4182 return TimeNanos(static_cast<uint64_t>(elapsed_nanoseconds));
4183 }
4184
GetThreadCPUTimeNs()4185 TimeNanos GetThreadCPUTimeNs() {
4186 FILETIME dummy, kernel_ftime, user_ftime;
4187 ::GetThreadTimes(GetCurrentThread(), &dummy, &dummy, &kernel_ftime,
4188 &user_ftime);
4189 uint64_t kernel_time = kernel_ftime.dwHighDateTime * 0x100000000 +
4190 kernel_ftime.dwLowDateTime;
4191 uint64_t user_time = user_ftime.dwHighDateTime * 0x100000000 +
4192 user_ftime.dwLowDateTime;
4193
4194 return TimeNanos((kernel_time + user_time) * 100);
4195 }
4196
SleepMicroseconds(unsigned interval_us)4197 void SleepMicroseconds(unsigned interval_us) {
4198 // The Windows Sleep function takes a millisecond count. Round up so that
4199 // short sleeps don't turn into a busy wait. Note that the sleep granularity
4200 // on Windows can dynamically vary from 1 ms to ~16 ms, so don't count on this
4201 // being a short sleep.
4202 ::Sleep(static_cast<DWORD>((interval_us + 999) / 1000));
4203 }
4204
4205 #else // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
4206
4207 void SleepMicroseconds(unsigned interval_us) {
4208 ::usleep(static_cast<useconds_t>(interval_us));
4209 }
4210
4211 #endif // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
4212
4213 } // namespace base
4214 } // namespace perfetto
4215 // gen_amalgamated begin source: src/base/uuid.cc
4216 // gen_amalgamated begin header: include/perfetto/ext/base/uuid.h
4217 /*
4218 * Copyright (C) 2019 The Android Open Source Project
4219 *
4220 * Licensed under the Apache License, Version 2.0 (the "License");
4221 * you may not use this file except in compliance with the License.
4222 * You may obtain a copy of the License at
4223 *
4224 * http://www.apache.org/licenses/LICENSE-2.0
4225 *
4226 * Unless required by applicable law or agreed to in writing, software
4227 * distributed under the License is distributed on an "AS IS" BASIS,
4228 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4229 * See the License for the specific language governing permissions and
4230 * limitations under the License.
4231 */
4232
4233 #ifndef INCLUDE_PERFETTO_EXT_BASE_UUID_H_
4234 #define INCLUDE_PERFETTO_EXT_BASE_UUID_H_
4235
4236 #include <array>
4237 #include <string>
4238
4239 // gen_amalgamated expanded: #include "perfetto/ext/base/optional.h"
4240
4241 namespace perfetto {
4242 namespace base {
4243
4244 class Uuid {
4245 public:
4246 explicit Uuid(const std::string& s);
4247 explicit Uuid(int64_t lsb, int64_t msb);
4248 Uuid();
4249
data()4250 std::array<uint8_t, 16>* data() { return &data_; }
data() const4251 const std::array<uint8_t, 16>* data() const { return &data_; }
4252
operator ==(const Uuid & other) const4253 bool operator==(const Uuid& other) const { return data_ == other.data_; }
4254
operator !=(const Uuid & other) const4255 bool operator!=(const Uuid& other) const { return !(*this == other); }
4256
msb() const4257 int64_t msb() const {
4258 int64_t result;
4259 memcpy(&result, data_.data() + 8, 8);
4260 return result;
4261 }
4262
lsb() const4263 int64_t lsb() const {
4264 int64_t result;
4265 memcpy(&result, data_.data(), 8);
4266 return result;
4267 }
4268
set_lsb_msb(int64_t lsb,int64_t msb)4269 void set_lsb_msb(int64_t lsb, int64_t msb) {
4270 set_lsb(lsb);
4271 set_msb(msb);
4272 }
set_msb(int64_t msb)4273 void set_msb(int64_t msb) { memcpy(data_.data() + 8, &msb, 8); }
set_lsb(int64_t lsb)4274 void set_lsb(int64_t lsb) { memcpy(data_.data(), &lsb, 8); }
4275
4276 std::string ToString() const;
4277 std::string ToPrettyString() const;
4278
4279 private:
4280 std::array<uint8_t, 16> data_{};
4281 };
4282
4283 Uuid Uuidv4();
4284
4285 } // namespace base
4286 } // namespace perfetto
4287
4288 #endif // INCLUDE_PERFETTO_EXT_BASE_UUID_H_
4289 /*
4290 * Copyright (C) 2019 The Android Open Source Project
4291 *
4292 * Licensed under the Apache License, Version 2.0 (the "License");
4293 * you may not use this file except in compliance with the License.
4294 * You may obtain a copy of the License at
4295 *
4296 * http://www.apache.org/licenses/LICENSE-2.0
4297 *
4298 * Unless required by applicable law or agreed to in writing, software
4299 * distributed under the License is distributed on an "AS IS" BASIS,
4300 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4301 * See the License for the specific language governing permissions and
4302 * limitations under the License.
4303 */
4304
4305 // gen_amalgamated expanded: #include "perfetto/ext/base/uuid.h"
4306
4307 #include <random>
4308
4309 // gen_amalgamated expanded: #include "perfetto/base/time.h"
4310
4311 namespace perfetto {
4312 namespace base {
4313 namespace {
4314
4315 constexpr char kHexmap[] = {'0', '1', '2', '3', '4', '5', '6', '7',
4316 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
4317 } // namespace
4318
4319 // See https://www.ietf.org/rfc/rfc4122.txt
Uuidv4()4320 Uuid Uuidv4() {
4321 static std::minstd_rand rng(static_cast<uint32_t>(GetBootTimeNs().count()));
4322 Uuid uuid;
4323 auto& data = *uuid.data();
4324
4325 for (size_t i = 0; i < 16; ++i)
4326 data[i] = static_cast<uint8_t>(rng());
4327
4328 // version:
4329 data[6] = (data[6] & 0x0f) | 0x40;
4330 // clock_seq_hi_and_reserved:
4331 data[8] = (data[8] & 0x3f) | 0x80;
4332
4333 return uuid;
4334 }
4335
Uuid()4336 Uuid::Uuid() {}
4337
Uuid(const std::string & s)4338 Uuid::Uuid(const std::string& s) {
4339 PERFETTO_CHECK(s.size() == data_.size());
4340 memcpy(data_.data(), s.data(), s.size());
4341 }
4342
Uuid(int64_t lsb,int64_t msb)4343 Uuid::Uuid(int64_t lsb, int64_t msb) {
4344 set_lsb_msb(lsb, msb);
4345 }
4346
ToString() const4347 std::string Uuid::ToString() const {
4348 return std::string(reinterpret_cast<const char*>(data_.data()), data_.size());
4349 }
4350
ToPrettyString() const4351 std::string Uuid::ToPrettyString() const {
4352 std::string s(data_.size() * 2 + 4, '-');
4353 // Format is 123e4567-e89b-12d3-a456-426655443322.
4354 size_t j = 0;
4355 for (size_t i = 0; i < data_.size(); ++i) {
4356 if (i == 4 || i == 6 || i == 8 || i == 10)
4357 j++;
4358 s[2 * i + j] = kHexmap[(data_[data_.size() - i - 1] & 0xf0) >> 4];
4359 s[2 * i + 1 + j] = kHexmap[(data_[data_.size() - i - 1] & 0x0f)];
4360 }
4361 return s;
4362 }
4363
4364 } // namespace base
4365 } // namespace perfetto
4366 // gen_amalgamated begin source: src/base/virtual_destructors.cc
4367 /*
4368 * Copyright (C) 2017 The Android Open Source Project
4369 *
4370 * Licensed under the Apache License, Version 2.0 (the "License");
4371 * you may not use this file except in compliance with the License.
4372 * You may obtain a copy of the License at
4373 *
4374 * http://www.apache.org/licenses/LICENSE-2.0
4375 *
4376 * Unless required by applicable law or agreed to in writing, software
4377 * distributed under the License is distributed on an "AS IS" BASIS,
4378 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4379 * See the License for the specific language governing permissions and
4380 * limitations under the License.
4381 */
4382
4383 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
4384
4385 // This translation unit contains the definitions for the destructor of pure
4386 // virtual interfaces for the current build target. The alternative would be
4387 // introducing a one-liner .cc file for each pure virtual interface, which is
4388 // overkill. This is for compliance with -Wweak-vtables.
4389
4390 namespace perfetto {
4391 namespace base {
4392
4393 TaskRunner::~TaskRunner() = default;
4394
4395 } // namespace base
4396 } // namespace perfetto
4397 // gen_amalgamated begin source: src/base/waitable_event.cc
4398 // gen_amalgamated begin header: include/perfetto/ext/base/waitable_event.h
4399 /*
4400 * Copyright (C) 2019 The Android Open Source Project
4401 *
4402 * Licensed under the Apache License, Version 2.0 (the "License");
4403 * you may not use this file except in compliance with the License.
4404 * You may obtain a copy of the License at
4405 *
4406 * http://www.apache.org/licenses/LICENSE-2.0
4407 *
4408 * Unless required by applicable law or agreed to in writing, software
4409 * distributed under the License is distributed on an "AS IS" BASIS,
4410 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4411 * See the License for the specific language governing permissions and
4412 * limitations under the License.
4413 */
4414
4415 #ifndef INCLUDE_PERFETTO_EXT_BASE_WAITABLE_EVENT_H_
4416 #define INCLUDE_PERFETTO_EXT_BASE_WAITABLE_EVENT_H_
4417
4418 #include <condition_variable>
4419 #include <mutex>
4420
4421 namespace perfetto {
4422 namespace base {
4423
4424 // A waitable event for cross-thread synchronization.
4425 // All methods on this class can be called from any thread.
4426 class WaitableEvent {
4427 public:
4428 WaitableEvent();
4429 ~WaitableEvent();
4430 WaitableEvent(const WaitableEvent&) = delete;
4431 WaitableEvent operator=(const WaitableEvent&) = delete;
4432
4433 // Synchronously block until the event is notified.
4434 void Wait();
4435
4436 // Signal the event, waking up blocked waiters.
4437 void Notify();
4438
4439 private:
4440 std::mutex mutex_;
4441 std::condition_variable event_;
4442 bool notified_ = false;
4443 };
4444
4445 } // namespace base
4446 } // namespace perfetto
4447
4448 #endif // INCLUDE_PERFETTO_EXT_BASE_WAITABLE_EVENT_H_
4449 /*
4450 * Copyright (C) 2019 The Android Open Source Project
4451 *
4452 * Licensed under the Apache License, Version 2.0 (the "License");
4453 * you may not use this file except in compliance with the License.
4454 * You may obtain a copy of the License at
4455 *
4456 * http://www.apache.org/licenses/LICENSE-2.0
4457 *
4458 * Unless required by applicable law or agreed to in writing, software
4459 * distributed under the License is distributed on an "AS IS" BASIS,
4460 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4461 * See the License for the specific language governing permissions and
4462 * limitations under the License.
4463 */
4464
4465 // gen_amalgamated expanded: #include "perfetto/ext/base/waitable_event.h"
4466
4467 namespace perfetto {
4468 namespace base {
4469
4470 WaitableEvent::WaitableEvent() = default;
4471 WaitableEvent::~WaitableEvent() = default;
4472
Wait()4473 void WaitableEvent::Wait() {
4474 std::unique_lock<std::mutex> lock(mutex_);
4475 return event_.wait(lock, [this] { return notified_; });
4476 }
4477
Notify()4478 void WaitableEvent::Notify() {
4479 std::unique_lock<std::mutex> lock(mutex_);
4480 notified_ = true;
4481 event_.notify_all();
4482 }
4483
4484 } // namespace base
4485 } // namespace perfetto
4486 // gen_amalgamated begin source: src/base/watchdog_posix.cc
4487 // gen_amalgamated begin header: include/perfetto/ext/base/watchdog.h
4488 // gen_amalgamated begin header: include/perfetto/ext/base/watchdog_noop.h
4489 /*
4490 * Copyright (C) 2018 The Android Open Source Project
4491 *
4492 * Licensed under the Apache License, Version 2.0 (the "License");
4493 * you may not use this file except in compliance with the License.
4494 * You may obtain a copy of the License at
4495 *
4496 * http://www.apache.org/licenses/LICENSE-2.0
4497 *
4498 * Unless required by applicable law or agreed to in writing, software
4499 * distributed under the License is distributed on an "AS IS" BASIS,
4500 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4501 * See the License for the specific language governing permissions and
4502 * limitations under the License.
4503 */
4504
4505 #ifndef INCLUDE_PERFETTO_EXT_BASE_WATCHDOG_NOOP_H_
4506 #define INCLUDE_PERFETTO_EXT_BASE_WATCHDOG_NOOP_H_
4507
4508 #include <stdint.h>
4509
4510 namespace perfetto {
4511 namespace base {
4512
4513 class Watchdog {
4514 public:
4515 class Timer {
4516 public:
4517 // Define an empty dtor to avoid "unused variable" errors on the call site.
Timer()4518 Timer() {}
Timer(const Timer &)4519 Timer(const Timer&) {}
~Timer()4520 ~Timer() {}
4521 };
GetInstance()4522 static Watchdog* GetInstance() {
4523 static Watchdog* watchdog = new Watchdog();
4524 return watchdog;
4525 }
CreateFatalTimer(uint32_t)4526 Timer CreateFatalTimer(uint32_t /*ms*/) { return Timer(); }
Start()4527 void Start() {}
SetMemoryLimit(uint64_t,uint32_t)4528 void SetMemoryLimit(uint64_t /*bytes*/, uint32_t /*window_ms*/) {}
SetCpuLimit(uint32_t,uint32_t)4529 void SetCpuLimit(uint32_t /*percentage*/, uint32_t /*window_ms*/) {}
4530 };
4531
4532 } // namespace base
4533 } // namespace perfetto
4534
4535 #endif // INCLUDE_PERFETTO_EXT_BASE_WATCHDOG_NOOP_H_
4536 /*
4537 * Copyright (C) 2018 The Android Open Source Project
4538 *
4539 * Licensed under the Apache License, Version 2.0 (the "License");
4540 * you may not use this file except in compliance with the License.
4541 * You may obtain a copy of the License at
4542 *
4543 * http://www.apache.org/licenses/LICENSE-2.0
4544 *
4545 * Unless required by applicable law or agreed to in writing, software
4546 * distributed under the License is distributed on an "AS IS" BASIS,
4547 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4548 * See the License for the specific language governing permissions and
4549 * limitations under the License.
4550 */
4551
4552 #ifndef INCLUDE_PERFETTO_EXT_BASE_WATCHDOG_H_
4553 #define INCLUDE_PERFETTO_EXT_BASE_WATCHDOG_H_
4554
4555 #include <functional>
4556
4557 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
4558
4559 // The POSIX watchdog is only supported on Linux and Android in non-embedder
4560 // builds.
4561 #if PERFETTO_BUILDFLAG(PERFETTO_WATCHDOG)
4562 // gen_amalgamated expanded: #include "perfetto/ext/base/watchdog_posix.h"
4563 #else
4564 // gen_amalgamated expanded: #include "perfetto/ext/base/watchdog_noop.h"
4565 #endif
4566
4567 namespace perfetto {
4568 namespace base {
4569
4570 // Make the limits more relaxed on desktop, where multi-GB traces are likely.
4571 // Multi-GB traces can take bursts of cpu time to write into disk at the end of
4572 // the trace.
4573 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
4574 constexpr uint32_t kWatchdogDefaultCpuLimit = 75;
4575 constexpr uint32_t kWatchdogDefaultCpuWindow = 5 * 60 * 1000; // 5 minutes.
4576 #else
4577 constexpr uint32_t kWatchdogDefaultCpuLimit = 90;
4578 constexpr uint32_t kWatchdogDefaultCpuWindow = 10 * 60 * 1000; // 10 minutes.
4579 #endif
4580
4581 // The default memory margin we give to our processes. This is used as as a
4582 // constant to put on top of the trace buffers.
4583 constexpr uint64_t kWatchdogDefaultMemorySlack = 32 * 1024 * 1024; // 32 MiB.
4584 constexpr uint32_t kWatchdogDefaultMemoryWindow = 30 * 1000; // 30 seconds.
4585
RunTaskWithWatchdogGuard(const std::function<void ()> & task)4586 inline void RunTaskWithWatchdogGuard(const std::function<void()>& task) {
4587 // Maximum time a single task can take in a TaskRunner before the
4588 // program suicides.
4589 constexpr int64_t kWatchdogMillis = 30000; // 30s
4590
4591 Watchdog::Timer handle =
4592 base::Watchdog::GetInstance()->CreateFatalTimer(kWatchdogMillis);
4593 task();
4594
4595 // Suppress unused variable warnings in the client library amalgamated build.
4596 (void)kWatchdogDefaultCpuLimit;
4597 (void)kWatchdogDefaultCpuWindow;
4598 (void)kWatchdogDefaultMemorySlack;
4599 (void)kWatchdogDefaultMemoryWindow;
4600 }
4601
4602 } // namespace base
4603 } // namespace perfetto
4604
4605 #endif // INCLUDE_PERFETTO_EXT_BASE_WATCHDOG_H_
4606 /*
4607 * Copyright (C) 2018 The Android Open Source Project
4608 *
4609 * Licensed under the Apache License, Version 2.0 (the "License");
4610 * you may not use this file except in compliance with the License.
4611 * You may obtain a copy of the License at
4612 *
4613 * http://www.apache.org/licenses/LICENSE-2.0
4614 *
4615 * Unless required by applicable law or agreed to in writing, software
4616 * distributed under the License is distributed on an "AS IS" BASIS,
4617 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4618 * See the License for the specific language governing permissions and
4619 * limitations under the License.
4620 */
4621
4622 // gen_amalgamated expanded: #include "perfetto/ext/base/watchdog.h"
4623
4624 #if PERFETTO_BUILDFLAG(PERFETTO_WATCHDOG)
4625
4626 #include <fcntl.h>
4627 #include <inttypes.h>
4628 #include <signal.h>
4629 #include <stdint.h>
4630
4631 #include <fstream>
4632 #include <thread>
4633
4634 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
4635 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
4636 // gen_amalgamated expanded: #include "perfetto/base/thread_utils.h"
4637 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
4638 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
4639
4640 namespace perfetto {
4641 namespace base {
4642
4643 namespace {
4644
4645 constexpr uint32_t kDefaultPollingInterval = 30 * 1000;
4646
IsMultipleOf(uint32_t number,uint32_t divisor)4647 bool IsMultipleOf(uint32_t number, uint32_t divisor) {
4648 return number >= divisor && number % divisor == 0;
4649 }
4650
MeanForArray(const uint64_t array[],size_t size)4651 double MeanForArray(const uint64_t array[], size_t size) {
4652 uint64_t total = 0;
4653 for (size_t i = 0; i < size; i++) {
4654 total += array[i];
4655 }
4656 return static_cast<double>(total / size);
4657
4658 }
4659
4660 } // namespace
4661
ReadProcStat(int fd,ProcStat * out)4662 bool ReadProcStat(int fd, ProcStat* out) {
4663 char c[512];
4664 size_t c_pos = 0;
4665 while (c_pos < sizeof(c) - 1) {
4666 ssize_t rd = PERFETTO_EINTR(read(fd, c + c_pos, sizeof(c) - c_pos));
4667 if (rd < 0) {
4668 PERFETTO_ELOG("Failed to read stat file to enforce resource limits.");
4669 return false;
4670 }
4671 if (rd == 0)
4672 break;
4673 c_pos += static_cast<size_t>(rd);
4674 }
4675 PERFETTO_CHECK(c_pos < sizeof(c));
4676 c[c_pos] = '\0';
4677
4678 if (sscanf(c,
4679 "%*d %*s %*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u %lu"
4680 "%lu %*d %*d %*d %*d %*d %*d %*u %*u %ld",
4681 &out->utime, &out->stime, &out->rss_pages) != 3) {
4682 PERFETTO_ELOG("Invalid stat format: %s", c);
4683 return false;
4684 }
4685 return true;
4686 }
4687
Watchdog(uint32_t polling_interval_ms)4688 Watchdog::Watchdog(uint32_t polling_interval_ms)
4689 : polling_interval_ms_(polling_interval_ms) {}
4690
~Watchdog()4691 Watchdog::~Watchdog() {
4692 if (!thread_.joinable()) {
4693 PERFETTO_DCHECK(!enabled_);
4694 return;
4695 }
4696 PERFETTO_DCHECK(enabled_);
4697 enabled_ = false;
4698 exit_signal_.notify_one();
4699 thread_.join();
4700 }
4701
GetInstance()4702 Watchdog* Watchdog::GetInstance() {
4703 static Watchdog* watchdog = new Watchdog(kDefaultPollingInterval);
4704 return watchdog;
4705 }
4706
CreateFatalTimer(uint32_t ms)4707 Watchdog::Timer Watchdog::CreateFatalTimer(uint32_t ms) {
4708 if (!enabled_.load(std::memory_order_relaxed))
4709 return Watchdog::Timer(0);
4710
4711 return Watchdog::Timer(ms);
4712 }
4713
Start()4714 void Watchdog::Start() {
4715 std::lock_guard<std::mutex> guard(mutex_);
4716 if (thread_.joinable()) {
4717 PERFETTO_DCHECK(enabled_);
4718 } else {
4719 PERFETTO_DCHECK(!enabled_);
4720
4721 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
4722 PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
4723 // Kick the thread to start running but only on Android or Linux.
4724 enabled_ = true;
4725 thread_ = std::thread(&Watchdog::ThreadMain, this);
4726 #endif
4727 }
4728 }
4729
SetMemoryLimit(uint64_t bytes,uint32_t window_ms)4730 void Watchdog::SetMemoryLimit(uint64_t bytes, uint32_t window_ms) {
4731 // Update the fields under the lock.
4732 std::lock_guard<std::mutex> guard(mutex_);
4733
4734 PERFETTO_CHECK(IsMultipleOf(window_ms, polling_interval_ms_) || bytes == 0);
4735
4736 size_t size = bytes == 0 ? 0 : window_ms / polling_interval_ms_ + 1;
4737 memory_window_bytes_.Reset(size);
4738 memory_limit_bytes_ = bytes;
4739 }
4740
SetCpuLimit(uint32_t percentage,uint32_t window_ms)4741 void Watchdog::SetCpuLimit(uint32_t percentage, uint32_t window_ms) {
4742 std::lock_guard<std::mutex> guard(mutex_);
4743
4744 PERFETTO_CHECK(percentage <= 100);
4745 PERFETTO_CHECK(IsMultipleOf(window_ms, polling_interval_ms_) ||
4746 percentage == 0);
4747
4748 size_t size = percentage == 0 ? 0 : window_ms / polling_interval_ms_ + 1;
4749 cpu_window_time_ticks_.Reset(size);
4750 cpu_limit_percentage_ = percentage;
4751 }
4752
ThreadMain()4753 void Watchdog::ThreadMain() {
4754 base::ScopedFile stat_fd(base::OpenFile("/proc/self/stat", O_RDONLY));
4755 if (!stat_fd) {
4756 PERFETTO_ELOG("Failed to open stat file to enforce resource limits.");
4757 return;
4758 }
4759
4760 std::unique_lock<std::mutex> guard(mutex_);
4761 for (;;) {
4762 exit_signal_.wait_for(guard,
4763 std::chrono::milliseconds(polling_interval_ms_));
4764 if (!enabled_)
4765 return;
4766
4767 lseek(stat_fd.get(), 0, SEEK_SET);
4768
4769 ProcStat stat;
4770 if (!ReadProcStat(stat_fd.get(), &stat)) {
4771 return;
4772 }
4773
4774 uint64_t cpu_time = stat.utime + stat.stime;
4775 uint64_t rss_bytes =
4776 static_cast<uint64_t>(stat.rss_pages) * base::GetSysPageSize();
4777
4778 CheckMemory(rss_bytes);
4779 CheckCpu(cpu_time);
4780 }
4781 }
4782
CheckMemory(uint64_t rss_bytes)4783 void Watchdog::CheckMemory(uint64_t rss_bytes) {
4784 if (memory_limit_bytes_ == 0)
4785 return;
4786
4787 // Add the current stat value to the ring buffer and check that the mean
4788 // remains under our threshold.
4789 if (memory_window_bytes_.Push(rss_bytes)) {
4790 if (memory_window_bytes_.Mean() > static_cast<double>(memory_limit_bytes_)) {
4791 PERFETTO_ELOG(
4792 "Memory watchdog trigger. Memory window of %f bytes is above the "
4793 "%" PRIu64 " bytes limit.",
4794 memory_window_bytes_.Mean(), memory_limit_bytes_);
4795 kill(getpid(), SIGABRT);
4796 }
4797 }
4798 }
4799
CheckCpu(uint64_t cpu_time)4800 void Watchdog::CheckCpu(uint64_t cpu_time) {
4801 if (cpu_limit_percentage_ == 0)
4802 return;
4803
4804 // Add the cpu time to the ring buffer.
4805 if (cpu_window_time_ticks_.Push(cpu_time)) {
4806 // Compute the percentage over the whole window and check that it remains
4807 // under the threshold.
4808 uint64_t difference_ticks = cpu_window_time_ticks_.NewestWhenFull() -
4809 cpu_window_time_ticks_.OldestWhenFull();
4810 double window_interval_ticks =
4811 (static_cast<double>(WindowTimeForRingBuffer(cpu_window_time_ticks_)) /
4812 1000.0) *
4813 static_cast<double>(sysconf(_SC_CLK_TCK));
4814 double percentage = static_cast<double>(difference_ticks) /
4815 static_cast<double>(window_interval_ticks) * 100;
4816 if (percentage > cpu_limit_percentage_) {
4817 PERFETTO_ELOG("CPU watchdog trigger. %f%% CPU use is above the %" PRIu32
4818 "%% CPU limit.",
4819 percentage, cpu_limit_percentage_);
4820 kill(getpid(), SIGABRT);
4821 }
4822 }
4823 }
4824
WindowTimeForRingBuffer(const WindowedInterval & window)4825 uint32_t Watchdog::WindowTimeForRingBuffer(const WindowedInterval& window) {
4826 return static_cast<uint32_t>(window.size() - 1) * polling_interval_ms_;
4827 }
4828
Push(uint64_t sample)4829 bool Watchdog::WindowedInterval::Push(uint64_t sample) {
4830 // Add the sample to the current position in the ring buffer.
4831 buffer_[position_] = sample;
4832
4833 // Update the position with next one circularily.
4834 position_ = (position_ + 1) % size_;
4835
4836 // Set the filled flag the first time we wrap.
4837 filled_ = filled_ || position_ == 0;
4838 return filled_;
4839 }
4840
Mean() const4841 double Watchdog::WindowedInterval::Mean() const {
4842 return MeanForArray(buffer_.get(), size_);
4843 }
4844
Clear()4845 void Watchdog::WindowedInterval::Clear() {
4846 position_ = 0;
4847 buffer_.reset(new uint64_t[size_]());
4848 }
4849
Reset(size_t new_size)4850 void Watchdog::WindowedInterval::Reset(size_t new_size) {
4851 position_ = 0;
4852 size_ = new_size;
4853 buffer_.reset(new_size == 0 ? nullptr : new uint64_t[new_size]());
4854 }
4855
Timer(uint32_t ms)4856 Watchdog::Timer::Timer(uint32_t ms) {
4857 if (!ms)
4858 return; // No-op timer created when the watchdog is disabled.
4859
4860 struct sigevent sev = {};
4861 sev.sigev_notify = SIGEV_THREAD_ID;
4862 sev._sigev_un._tid = base::GetThreadId();
4863 sev.sigev_signo = SIGABRT;
4864 PERFETTO_CHECK(timer_create(CLOCK_MONOTONIC, &sev, &timerid_) != -1);
4865 struct itimerspec its = {};
4866 its.it_value.tv_sec = ms / 1000;
4867 its.it_value.tv_nsec = 1000000L * (ms % 1000);
4868 PERFETTO_CHECK(timer_settime(timerid_, 0, &its, nullptr) != -1);
4869 }
4870
~Timer()4871 Watchdog::Timer::~Timer() {
4872 if (timerid_ != nullptr) {
4873 timer_delete(timerid_);
4874 }
4875 }
4876
Timer(Timer && other)4877 Watchdog::Timer::Timer(Timer&& other) noexcept {
4878 timerid_ = other.timerid_;
4879 other.timerid_ = nullptr;
4880 }
4881
4882 } // namespace base
4883 } // namespace perfetto
4884
4885 #endif // PERFETTO_BUILDFLAG(PERFETTO_WATCHDOG)
4886 // gen_amalgamated begin source: src/base/event_fd.cc
4887 // gen_amalgamated begin header: include/perfetto/ext/base/event_fd.h
4888 /*
4889 * Copyright (C) 2018 The Android Open Source Project
4890 *
4891 * Licensed under the Apache License, Version 2.0 (the "License");
4892 * you may not use this file except in compliance with the License.
4893 * You may obtain a copy of the License at
4894 *
4895 * http://www.apache.org/licenses/LICENSE-2.0
4896 *
4897 * Unless required by applicable law or agreed to in writing, software
4898 * distributed under the License is distributed on an "AS IS" BASIS,
4899 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4900 * See the License for the specific language governing permissions and
4901 * limitations under the License.
4902 */
4903
4904 #ifndef INCLUDE_PERFETTO_EXT_BASE_EVENT_FD_H_
4905 #define INCLUDE_PERFETTO_EXT_BASE_EVENT_FD_H_
4906
4907 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
4908 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
4909
4910 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
4911 PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
4912 #define PERFETTO_USE_EVENTFD() 1
4913 #else
4914 #define PERFETTO_USE_EVENTFD() 0
4915 #endif
4916
4917 namespace perfetto {
4918 namespace base {
4919
4920 // A waitable event that can be used with poll/select.
4921 // This is really a wrapper around eventfd_create with a pipe-based fallback
4922 // for other platforms where eventfd is not supported.
4923 class EventFd {
4924 public:
4925 EventFd();
4926 ~EventFd();
4927 EventFd(EventFd&&) noexcept = default;
4928 EventFd& operator=(EventFd&&) = default;
4929
4930 // The non-blocking file descriptor that can be polled to wait for the event.
fd() const4931 int fd() const { return fd_.get(); }
4932
4933 // Can be called from any thread.
4934 void Notify();
4935
4936 // Can be called from any thread. If more Notify() are queued a Clear() call
4937 // can clear all of them (up to 16 per call).
4938 void Clear();
4939
4940 private:
4941 // The eventfd, when eventfd is supported, otherwise this is the read end of
4942 // the pipe for fallback mode.
4943 ScopedFile fd_;
4944
4945 #if !PERFETTO_USE_EVENTFD()
4946 // The write end of the wakeup pipe.
4947 ScopedFile write_fd_;
4948 #endif
4949 };
4950
4951 } // namespace base
4952 } // namespace perfetto
4953
4954 #endif // INCLUDE_PERFETTO_EXT_BASE_EVENT_FD_H_
4955 /*
4956 * Copyright (C) 2018 The Android Open Source Project
4957 *
4958 * Licensed under the Apache License, Version 2.0 (the "License");
4959 * you may not use this file except in compliance with the License.
4960 * You may obtain a copy of the License at
4961 *
4962 * http://www.apache.org/licenses/LICENSE-2.0
4963 *
4964 * Unless required by applicable law or agreed to in writing, software
4965 * distributed under the License is distributed on an "AS IS" BASIS,
4966 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4967 * See the License for the specific language governing permissions and
4968 * limitations under the License.
4969 */
4970
4971 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
4972 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
4973
4974 #include <stdint.h>
4975 #include <unistd.h>
4976
4977 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
4978 // gen_amalgamated expanded: #include "perfetto/ext/base/event_fd.h"
4979 // gen_amalgamated expanded: #include "perfetto/ext/base/pipe.h"
4980 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
4981
4982 #if PERFETTO_USE_EVENTFD()
4983 #include <sys/eventfd.h>
4984 #endif
4985
4986 namespace perfetto {
4987 namespace base {
4988
EventFd()4989 EventFd::EventFd() {
4990 #if PERFETTO_USE_EVENTFD()
4991 fd_.reset(eventfd(/* start value */ 0, EFD_CLOEXEC | EFD_NONBLOCK));
4992 PERFETTO_CHECK(fd_);
4993 #else
4994 // Make the pipe non-blocking so that we never block the waking thread (either
4995 // the main thread or another one) when scheduling a wake-up.
4996 Pipe pipe = Pipe::Create(Pipe::kBothNonBlock);
4997 fd_ = std::move(pipe.rd);
4998 write_fd_ = std::move(pipe.wr);
4999 #endif // !PERFETTO_USE_EVENTFD()
5000 }
5001
5002 EventFd::~EventFd() = default;
5003
Notify()5004 void EventFd::Notify() {
5005 const uint64_t value = 1;
5006
5007 #if PERFETTO_USE_EVENTFD()
5008 ssize_t ret = write(fd_.get(), &value, sizeof(value));
5009 #else
5010 ssize_t ret = write(write_fd_.get(), &value, sizeof(uint8_t));
5011 #endif
5012
5013 if (ret <= 0 && errno != EAGAIN) {
5014 PERFETTO_DFATAL("write()");
5015 }
5016 }
5017
Clear()5018 void EventFd::Clear() {
5019 #if PERFETTO_USE_EVENTFD()
5020 uint64_t value;
5021 ssize_t ret = read(fd_.get(), &value, sizeof(value));
5022 #else
5023 // Drain the byte(s) written to the wake-up pipe. We can potentially read
5024 // more than one byte if several wake-ups have been scheduled.
5025 char buffer[16];
5026 ssize_t ret = read(fd_.get(), &buffer[0], sizeof(buffer));
5027 #endif
5028 if (ret <= 0 && errno != EAGAIN)
5029 PERFETTO_DPLOG("read()");
5030 }
5031
5032 } // namespace base
5033 } // namespace perfetto
5034
5035 #endif // !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
5036 // gen_amalgamated begin source: src/base/pipe.cc
5037 /*
5038 * Copyright (C) 2018 The Android Open Source Project
5039 *
5040 * Licensed under the Apache License, Version 2.0 (the "License");
5041 * you may not use this file except in compliance with the License.
5042 * You may obtain a copy of the License at
5043 *
5044 * http://www.apache.org/licenses/LICENSE-2.0
5045 *
5046 * Unless required by applicable law or agreed to in writing, software
5047 * distributed under the License is distributed on an "AS IS" BASIS,
5048 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5049 * See the License for the specific language governing permissions and
5050 * limitations under the License.
5051 */
5052
5053 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
5054 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
5055
5056 // gen_amalgamated expanded: #include "perfetto/ext/base/pipe.h"
5057
5058 #include <sys/types.h>
5059 #include <unistd.h>
5060
5061 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
5062
5063 namespace perfetto {
5064 namespace base {
5065
5066 Pipe::Pipe() = default;
5067 Pipe::Pipe(Pipe&&) noexcept = default;
5068 Pipe& Pipe::operator=(Pipe&&) = default;
5069
Create(Flags flags)5070 Pipe Pipe::Create(Flags flags) {
5071 int fds[2];
5072 PERFETTO_CHECK(pipe(fds) == 0);
5073 Pipe p;
5074 p.rd.reset(fds[0]);
5075 p.wr.reset(fds[1]);
5076
5077 PERFETTO_CHECK(fcntl(*p.rd, F_SETFD, FD_CLOEXEC) == 0);
5078 PERFETTO_CHECK(fcntl(*p.wr, F_SETFD, FD_CLOEXEC) == 0);
5079
5080 if (flags == kBothNonBlock || flags == kRdNonBlock) {
5081 int cur_flags = fcntl(*p.rd, F_GETFL, 0);
5082 PERFETTO_CHECK(cur_flags >= 0);
5083 PERFETTO_CHECK(fcntl(*p.rd, F_SETFL, cur_flags | O_NONBLOCK) == 0);
5084 }
5085
5086 if (flags == kBothNonBlock || flags == kWrNonBlock) {
5087 int cur_flags = fcntl(*p.wr, F_GETFL, 0);
5088 PERFETTO_CHECK(cur_flags >= 0);
5089 PERFETTO_CHECK(fcntl(*p.wr, F_SETFL, cur_flags | O_NONBLOCK) == 0);
5090 }
5091 return p;
5092 }
5093
5094 } // namespace base
5095 } // namespace perfetto
5096
5097 #endif // !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
5098 // gen_amalgamated begin source: src/base/temp_file.cc
5099 // gen_amalgamated begin header: include/perfetto/ext/base/temp_file.h
5100 /*
5101 * Copyright (C) 2018 The Android Open Source Project
5102 *
5103 * Licensed under the Apache License, Version 2.0 (the "License");
5104 * you may not use this file except in compliance with the License.
5105 * You may obtain a copy of the License at
5106 *
5107 * http://www.apache.org/licenses/LICENSE-2.0
5108 *
5109 * Unless required by applicable law or agreed to in writing, software
5110 * distributed under the License is distributed on an "AS IS" BASIS,
5111 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5112 * See the License for the specific language governing permissions and
5113 * limitations under the License.
5114 */
5115
5116 #ifndef INCLUDE_PERFETTO_EXT_BASE_TEMP_FILE_H_
5117 #define INCLUDE_PERFETTO_EXT_BASE_TEMP_FILE_H_
5118
5119 #include <string>
5120
5121 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
5122
5123 namespace perfetto {
5124 namespace base {
5125
5126 std::string GetSysTempDir();
5127
5128 class TempFile {
5129 public:
5130 static TempFile CreateUnlinked();
5131 static TempFile Create();
5132
5133 TempFile(TempFile&&) noexcept;
5134 TempFile& operator=(TempFile&&);
5135 ~TempFile();
5136
path() const5137 const std::string& path() const { return path_; }
fd() const5138 int fd() const { return *fd_; }
operator *() const5139 int operator*() const { return *fd_; }
5140
5141 // Unlinks the file from the filesystem but keeps the fd() open.
5142 // It is safe to call this multiple times.
5143 void Unlink();
5144
5145 // Releases the underlying file descriptor. Will unlink the file from the
5146 // filesystem if it was created via CreateUnlinked().
5147 ScopedFile ReleaseFD();
5148
5149 private:
5150 TempFile();
5151 TempFile(const TempFile&) = delete;
5152 TempFile& operator=(const TempFile&) = delete;
5153
5154 ScopedFile fd_;
5155 std::string path_;
5156 };
5157
5158 class TempDir {
5159 public:
5160 static TempDir Create();
5161
5162 TempDir(TempDir&&) noexcept;
5163 TempDir& operator=(TempDir&&);
5164 ~TempDir();
5165
path() const5166 const std::string& path() const { return path_; }
5167
5168 private:
5169 TempDir();
5170 TempDir(const TempDir&) = delete;
5171 TempDir& operator=(const TempDir&) = delete;
5172
5173 std::string path_;
5174 };
5175
5176 } // namespace base
5177 } // namespace perfetto
5178
5179 #endif // INCLUDE_PERFETTO_EXT_BASE_TEMP_FILE_H_
5180 /*
5181 * Copyright (C) 2018 The Android Open Source Project
5182 *
5183 * Licensed under the Apache License, Version 2.0 (the "License");
5184 * you may not use this file except in compliance with the License.
5185 * You may obtain a copy of the License at
5186 *
5187 * http://www.apache.org/licenses/LICENSE-2.0
5188 *
5189 * Unless required by applicable law or agreed to in writing, software
5190 * distributed under the License is distributed on an "AS IS" BASIS,
5191 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5192 * See the License for the specific language governing permissions and
5193 * limitations under the License.
5194 */
5195
5196 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
5197 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
5198
5199 // gen_amalgamated expanded: #include "perfetto/ext/base/temp_file.h"
5200
5201 #include <stdlib.h>
5202 #include <unistd.h>
5203
5204 // gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
5205
5206 namespace perfetto {
5207 namespace base {
5208
GetSysTempDir()5209 std::string GetSysTempDir() {
5210 const char* tmpdir = getenv("TMPDIR");
5211 if (tmpdir)
5212 return base::StripSuffix(tmpdir, "/");
5213 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
5214 return "/data/local/tmp";
5215 #else
5216 return "/tmp";
5217 #endif
5218 }
5219
5220 // static
Create()5221 TempFile TempFile::Create() {
5222 TempFile temp_file;
5223 temp_file.path_ = GetSysTempDir() + "/perfetto-XXXXXXXX";
5224 temp_file.fd_.reset(mkstemp(&temp_file.path_[0]));
5225 if (PERFETTO_UNLIKELY(!temp_file.fd_)) {
5226 PERFETTO_FATAL("Could not create temp file %s", temp_file.path_.c_str());
5227 }
5228 return temp_file;
5229 }
5230
5231 // static
CreateUnlinked()5232 TempFile TempFile::CreateUnlinked() {
5233 TempFile temp_file = TempFile::Create();
5234 temp_file.Unlink();
5235 return temp_file;
5236 }
5237
5238 TempFile::TempFile() = default;
5239
~TempFile()5240 TempFile::~TempFile() {
5241 Unlink();
5242 }
5243
ReleaseFD()5244 ScopedFile TempFile::ReleaseFD() {
5245 Unlink();
5246 return std::move(fd_);
5247 }
5248
Unlink()5249 void TempFile::Unlink() {
5250 if (path_.empty())
5251 return;
5252 PERFETTO_CHECK(unlink(path_.c_str()) == 0);
5253 path_.clear();
5254 }
5255
5256 TempFile::TempFile(TempFile&&) noexcept = default;
5257 TempFile& TempFile::operator=(TempFile&&) = default;
5258
5259 // static
Create()5260 TempDir TempDir::Create() {
5261 TempDir temp_dir;
5262 temp_dir.path_ = GetSysTempDir() + "/perfetto-XXXXXXXX";
5263 PERFETTO_CHECK(mkdtemp(&temp_dir.path_[0]));
5264 return temp_dir;
5265 }
5266
5267 TempDir::TempDir() = default;
5268
~TempDir()5269 TempDir::~TempDir() {
5270 PERFETTO_CHECK(rmdir(path_.c_str()) == 0);
5271 }
5272
5273 } // namespace base
5274 } // namespace perfetto
5275
5276 #endif // !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
5277 // gen_amalgamated begin source: src/base/thread_task_runner.cc
5278 // gen_amalgamated begin header: include/perfetto/ext/base/thread_task_runner.h
5279 // gen_amalgamated begin header: include/perfetto/ext/base/unix_task_runner.h
5280 /*
5281 * Copyright (C) 2017 The Android Open Source Project
5282 *
5283 * Licensed under the Apache License, Version 2.0 (the "License");
5284 * you may not use this file except in compliance with the License.
5285 * You may obtain a copy of the License at
5286 *
5287 * http://www.apache.org/licenses/LICENSE-2.0
5288 *
5289 * Unless required by applicable law or agreed to in writing, software
5290 * distributed under the License is distributed on an "AS IS" BASIS,
5291 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5292 * See the License for the specific language governing permissions and
5293 * limitations under the License.
5294 */
5295
5296 #ifndef INCLUDE_PERFETTO_EXT_BASE_UNIX_TASK_RUNNER_H_
5297 #define INCLUDE_PERFETTO_EXT_BASE_UNIX_TASK_RUNNER_H_
5298
5299 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
5300 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
5301 // gen_amalgamated expanded: #include "perfetto/base/thread_utils.h"
5302 // gen_amalgamated expanded: #include "perfetto/base/time.h"
5303 // gen_amalgamated expanded: #include "perfetto/ext/base/event_fd.h"
5304 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
5305 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_checker.h"
5306
5307 #include <poll.h>
5308 #include <chrono>
5309 #include <deque>
5310 #include <map>
5311 #include <mutex>
5312 #include <vector>
5313
5314 namespace perfetto {
5315 namespace base {
5316
5317 // Runs a task runner on the current thread.
5318 //
5319 // Implementation note: we currently assume (and enforce in debug builds) that
5320 // Run() is called from the thread that constructed the UnixTaskRunner. This is
5321 // not strictly necessary, and we could instead track the thread that invokes
5322 // Run(). However, a related property that *might* be important to enforce is
5323 // that the destructor runs on the task-running thread. Otherwise, if there are
5324 // still-pending tasks at the time of destruction, we would destroy those
5325 // outside of the task thread (which might be unexpected to the caller). On the
5326 // other hand, the std::function task interface discourages use of any
5327 // resource-owning tasks (as the callable needs to be copyable), so this might
5328 // not be important in practice.
5329 //
5330 // TODO(rsavitski): consider adding a thread-check in the destructor, after
5331 // auditing existing usages.
5332 class UnixTaskRunner : public TaskRunner {
5333 public:
5334 UnixTaskRunner();
5335 ~UnixTaskRunner() override;
5336
5337 // Start executing tasks. Doesn't return until Quit() is called. Run() may be
5338 // called multiple times on the same task runner.
5339 void Run();
5340 void Quit();
5341
5342 // Checks whether there are any pending immediate tasks to run. Note that
5343 // delayed tasks don't count even if they are due to run.
5344 bool IsIdleForTesting();
5345
5346 // TaskRunner implementation:
5347 void PostTask(std::function<void()>) override;
5348 void PostDelayedTask(std::function<void()>, uint32_t delay_ms) override;
5349 void AddFileDescriptorWatch(int fd, std::function<void()>) override;
5350 void RemoveFileDescriptorWatch(int fd) override;
5351 bool RunsTasksOnCurrentThread() const override;
5352
5353 // Returns true if the task runner is quitting, or has quit and hasn't been
5354 // restarted since. Exposed primarily for ThreadTaskRunner, not necessary for
5355 // normal use of this class.
5356 bool QuitCalled();
5357
5358 private:
5359 void WakeUp();
5360
5361 void UpdateWatchTasksLocked();
5362
5363 int GetDelayMsToNextTaskLocked() const;
5364 void RunImmediateAndDelayedTask();
5365 void PostFileDescriptorWatches();
5366 void RunFileDescriptorWatch(int fd);
5367
5368 ThreadChecker thread_checker_;
5369 PlatformThreadId created_thread_id_ = GetThreadId();
5370
5371 // On Linux, an eventfd(2) used to waking up the task runner when a new task
5372 // is posted. Otherwise the read end of a pipe used for the same purpose.
5373 EventFd event_;
5374
5375 std::vector<struct pollfd> poll_fds_;
5376
5377 // --- Begin lock-protected members ---
5378
5379 std::mutex lock_;
5380
5381 std::deque<std::function<void()>> immediate_tasks_;
5382 std::multimap<TimeMillis, std::function<void()>> delayed_tasks_;
5383 bool quit_ = false;
5384
5385 struct WatchTask {
5386 std::function<void()> callback;
5387 size_t poll_fd_index; // Index into |poll_fds_|.
5388 };
5389
5390 std::map<int, WatchTask> watch_tasks_;
5391 bool watch_tasks_changed_ = false;
5392
5393 // --- End lock-protected members ---
5394 };
5395
5396 } // namespace base
5397 } // namespace perfetto
5398
5399 #endif // INCLUDE_PERFETTO_EXT_BASE_UNIX_TASK_RUNNER_H_
5400 /*
5401 * Copyright (C) 2019 The Android Open Source Project
5402 *
5403 * Licensed under the Apache License, Version 2.0 (the "License");
5404 * you may not use this file except in compliance with the License.
5405 * You may obtain a copy of the License at
5406 *
5407 * http://www.apache.org/licenses/LICENSE-2.0
5408 *
5409 * Unless required by applicable law or agreed to in writing, software
5410 * distributed under the License is distributed on an "AS IS" BASIS,
5411 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5412 * See the License for the specific language governing permissions and
5413 * limitations under the License.
5414 */
5415
5416 #ifndef INCLUDE_PERFETTO_EXT_BASE_THREAD_TASK_RUNNER_H_
5417 #define INCLUDE_PERFETTO_EXT_BASE_THREAD_TASK_RUNNER_H_
5418
5419 #include <functional>
5420 #include <thread>
5421
5422 // gen_amalgamated expanded: #include "perfetto/ext/base/unix_task_runner.h"
5423
5424 namespace perfetto {
5425 namespace base {
5426
5427 // A UnixTaskRunner backed by a dedicated task thread. Shuts down the runner and
5428 // joins the thread upon destruction. Can be moved to transfer ownership.
5429 //
5430 // Guarantees that:
5431 // * the UnixTaskRunner will be constructed and destructed on the task thread.
5432 // * the task thread will live for the lifetime of the UnixTaskRunner.
5433 //
5434 class ThreadTaskRunner {
5435 public:
CreateAndStart(const std::string & name="")5436 static ThreadTaskRunner CreateAndStart(const std::string& name = "") {
5437 return ThreadTaskRunner(name);
5438 }
5439
5440 ThreadTaskRunner(const ThreadTaskRunner&) = delete;
5441 ThreadTaskRunner& operator=(const ThreadTaskRunner&) = delete;
5442
5443 ThreadTaskRunner(ThreadTaskRunner&&) noexcept;
5444 ThreadTaskRunner& operator=(ThreadTaskRunner&&);
5445 ~ThreadTaskRunner();
5446
5447 // Executes the given function on the task runner thread and blocks the caller
5448 // thread until the function has run.
5449 void PostTaskAndWaitForTesting(std::function<void()>);
5450
5451 // Can be called from another thread to get the CPU time of the thread the
5452 // task-runner is executing on.
5453 uint64_t GetThreadCPUTimeNsForTesting();
5454
5455 // Returns a pointer to the UnixTaskRunner, which is valid for the lifetime of
5456 // this ThreadTaskRunner object (unless this object is moved-from, in which
5457 // case the pointer remains valid for the lifetime of the new owning
5458 // ThreadTaskRunner).
5459 //
5460 // Warning: do not call Quit() on the returned runner pointer, the termination
5461 // should be handled exclusively by this class' destructor.
get() const5462 UnixTaskRunner* get() const { return task_runner_; }
5463
5464 private:
5465 explicit ThreadTaskRunner(const std::string& name);
5466 void RunTaskThread(std::function<void(UnixTaskRunner*)> initializer);
5467
5468 std::thread thread_;
5469 std::string name_;
5470 UnixTaskRunner* task_runner_ = nullptr;
5471 };
5472
5473 } // namespace base
5474 } // namespace perfetto
5475
5476 #endif // INCLUDE_PERFETTO_EXT_BASE_THREAD_TASK_RUNNER_H_
5477 // gen_amalgamated begin header: include/perfetto/ext/base/thread_utils.h
5478 /*
5479 * Copyright (C) 2020 The Android Open Source Project
5480 *
5481 * Licensed under the Apache License, Version 2.0 (the "License");
5482 * you may not use this file except in compliance with the License.
5483 * You may obtain a copy of the License at
5484 *
5485 * http://www.apache.org/licenses/LICENSE-2.0
5486 *
5487 * Unless required by applicable law or agreed to in writing, software
5488 * distributed under the License is distributed on an "AS IS" BASIS,
5489 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5490 * See the License for the specific language governing permissions and
5491 * limitations under the License.
5492 */
5493
5494 #ifndef INCLUDE_PERFETTO_EXT_BASE_THREAD_UTILS_H_
5495 #define INCLUDE_PERFETTO_EXT_BASE_THREAD_UTILS_H_
5496
5497 #include <string>
5498
5499 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
5500
5501 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
5502 PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
5503 PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
5504 #include <pthread.h>
5505 #include <string.h>
5506 #include <algorithm>
5507 #endif
5508
5509 // Internal implementation utils that aren't as widely useful/supported as
5510 // base/thread_utils.h.
5511
5512 namespace perfetto {
5513 namespace base {
5514
5515 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
5516 PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
5517 PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
5518 // Sets the "comm" of the calling thread to the first 15 chars of the given
5519 // string.
MaybeSetThreadName(const std::string & name)5520 inline bool MaybeSetThreadName(const std::string& name) {
5521 char buf[16] = {};
5522 size_t sz = std::min(name.size(), static_cast<size_t>(15));
5523 strncpy(buf, name.c_str(), sz);
5524
5525 #if PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
5526 return pthread_setname_np(buf) == 0;
5527 #else
5528 return pthread_setname_np(pthread_self(), buf) == 0;
5529 #endif
5530 }
5531 #else
5532 inline void MaybeSetThreadName(const std::string&) {}
5533 #endif
5534
5535 } // namespace base
5536 } // namespace perfetto
5537
5538 #endif // INCLUDE_PERFETTO_EXT_BASE_THREAD_UTILS_H_
5539 /*
5540 * Copyright (C) 2019 The Android Open Source Project
5541 *
5542 * Licensed under the Apache License, Version 2.0 (the "License");
5543 * you may not use this file except in compliance with the License.
5544 * You may obtain a copy of the License at
5545 *
5546 * http://www.apache.org/licenses/LICENSE-2.0
5547 *
5548 * Unless required by applicable law or agreed to in writing, software
5549 * distributed under the License is distributed on an "AS IS" BASIS,
5550 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5551 * See the License for the specific language governing permissions and
5552 * limitations under the License.
5553 */
5554
5555 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
5556 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
5557
5558 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_task_runner.h"
5559
5560 #include <condition_variable>
5561 #include <functional>
5562 #include <mutex>
5563 #include <thread>
5564
5565 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
5566 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_utils.h"
5567 // gen_amalgamated expanded: #include "perfetto/ext/base/unix_task_runner.h"
5568
5569 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
5570 PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
5571 #include <sys/prctl.h>
5572 #endif
5573
5574 namespace perfetto {
5575 namespace base {
5576
ThreadTaskRunner(ThreadTaskRunner && other)5577 ThreadTaskRunner::ThreadTaskRunner(ThreadTaskRunner&& other) noexcept
5578 : thread_(std::move(other.thread_)), task_runner_(other.task_runner_) {
5579 other.task_runner_ = nullptr;
5580 }
5581
operator =(ThreadTaskRunner && other)5582 ThreadTaskRunner& ThreadTaskRunner::operator=(ThreadTaskRunner&& other) {
5583 this->~ThreadTaskRunner();
5584 new (this) ThreadTaskRunner(std::move(other));
5585 return *this;
5586 }
5587
~ThreadTaskRunner()5588 ThreadTaskRunner::~ThreadTaskRunner() {
5589 if (task_runner_) {
5590 PERFETTO_CHECK(!task_runner_->QuitCalled());
5591 task_runner_->Quit();
5592
5593 PERFETTO_DCHECK(thread_.joinable());
5594 }
5595 if (thread_.joinable())
5596 thread_.join();
5597 }
5598
ThreadTaskRunner(const std::string & name)5599 ThreadTaskRunner::ThreadTaskRunner(const std::string& name) : name_(name) {
5600 std::mutex init_lock;
5601 std::condition_variable init_cv;
5602
5603 std::function<void(UnixTaskRunner*)> initializer =
5604 [this, &init_lock, &init_cv](UnixTaskRunner* task_runner) {
5605 std::lock_guard<std::mutex> lock(init_lock);
5606 task_runner_ = task_runner;
5607 // Notify while still holding the lock, as init_cv ceases to exist as
5608 // soon as the main thread observes a non-null task_runner_, and it can
5609 // wake up spuriously (i.e. before the notify if we had unlocked before
5610 // notifying).
5611 init_cv.notify_one();
5612 };
5613
5614 thread_ = std::thread(&ThreadTaskRunner::RunTaskThread, this,
5615 std::move(initializer));
5616
5617 std::unique_lock<std::mutex> lock(init_lock);
5618 init_cv.wait(lock, [this] { return !!task_runner_; });
5619 }
5620
RunTaskThread(std::function<void (UnixTaskRunner *)> initializer)5621 void ThreadTaskRunner::RunTaskThread(
5622 std::function<void(UnixTaskRunner*)> initializer) {
5623 if (!name_.empty()) {
5624 base::MaybeSetThreadName(name_);
5625 }
5626
5627 UnixTaskRunner task_runner;
5628 task_runner.PostTask(std::bind(std::move(initializer), &task_runner));
5629 task_runner.Run();
5630 }
5631
PostTaskAndWaitForTesting(std::function<void ()> fn)5632 void ThreadTaskRunner::PostTaskAndWaitForTesting(std::function<void()> fn) {
5633 std::mutex mutex;
5634 std::condition_variable cv;
5635
5636 std::unique_lock<std::mutex> lock(mutex);
5637 bool done = false;
5638 task_runner_->PostTask([&mutex, &cv, &done, &fn] {
5639 fn();
5640
5641 std::lock_guard<std::mutex> inner_lock(mutex);
5642 done = true;
5643 cv.notify_one();
5644 });
5645 cv.wait(lock, [&done] { return done; });
5646 }
5647
GetThreadCPUTimeNsForTesting()5648 uint64_t ThreadTaskRunner::GetThreadCPUTimeNsForTesting() {
5649 uint64_t thread_time_ns = 0;
5650 PostTaskAndWaitForTesting([&thread_time_ns] {
5651 thread_time_ns = static_cast<uint64_t>(base::GetThreadCPUTimeNs().count());
5652 });
5653 return thread_time_ns;
5654 }
5655
5656 } // namespace base
5657 } // namespace perfetto
5658
5659 #endif // !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
5660 // gen_amalgamated begin source: src/base/unix_task_runner.cc
5661 /*
5662 * Copyright (C) 2017 The Android Open Source Project
5663 *
5664 * Licensed under the Apache License, Version 2.0 (the "License");
5665 * you may not use this file except in compliance with the License.
5666 * You may obtain a copy of the License at
5667 *
5668 * http://www.apache.org/licenses/LICENSE-2.0
5669 *
5670 * Unless required by applicable law or agreed to in writing, software
5671 * distributed under the License is distributed on an "AS IS" BASIS,
5672 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5673 * See the License for the specific language governing permissions and
5674 * limitations under the License.
5675 */
5676
5677 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
5678 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
5679
5680 // gen_amalgamated expanded: #include "perfetto/ext/base/unix_task_runner.h"
5681
5682 #include <errno.h>
5683 #include <stdlib.h>
5684 #include <unistd.h>
5685
5686 #include <limits>
5687
5688 // gen_amalgamated expanded: #include "perfetto/ext/base/watchdog.h"
5689
5690 namespace perfetto {
5691 namespace base {
5692
UnixTaskRunner()5693 UnixTaskRunner::UnixTaskRunner() {
5694 AddFileDescriptorWatch(event_.fd(), [] {
5695 // Not reached -- see PostFileDescriptorWatches().
5696 PERFETTO_DFATAL("Should be unreachable.");
5697 });
5698 }
5699
5700 UnixTaskRunner::~UnixTaskRunner() = default;
5701
WakeUp()5702 void UnixTaskRunner::WakeUp() {
5703 event_.Notify();
5704 }
5705
Run()5706 void UnixTaskRunner::Run() {
5707 PERFETTO_DCHECK_THREAD(thread_checker_);
5708 created_thread_id_ = GetThreadId();
5709 quit_ = false;
5710 for (;;) {
5711 int poll_timeout_ms;
5712 {
5713 std::lock_guard<std::mutex> lock(lock_);
5714 if (quit_)
5715 return;
5716 poll_timeout_ms = GetDelayMsToNextTaskLocked();
5717 UpdateWatchTasksLocked();
5718 }
5719 int ret = PERFETTO_EINTR(poll(
5720 &poll_fds_[0], static_cast<nfds_t>(poll_fds_.size()), poll_timeout_ms));
5721 PERFETTO_CHECK(ret >= 0);
5722
5723 // To avoid starvation we always interleave all types of tasks -- immediate,
5724 // delayed and file descriptor watches.
5725 PostFileDescriptorWatches();
5726 RunImmediateAndDelayedTask();
5727 }
5728 }
5729
Quit()5730 void UnixTaskRunner::Quit() {
5731 std::lock_guard<std::mutex> lock(lock_);
5732 quit_ = true;
5733 WakeUp();
5734 }
5735
QuitCalled()5736 bool UnixTaskRunner::QuitCalled() {
5737 std::lock_guard<std::mutex> lock(lock_);
5738 return quit_;
5739 }
5740
IsIdleForTesting()5741 bool UnixTaskRunner::IsIdleForTesting() {
5742 std::lock_guard<std::mutex> lock(lock_);
5743 return immediate_tasks_.empty();
5744 }
5745
UpdateWatchTasksLocked()5746 void UnixTaskRunner::UpdateWatchTasksLocked() {
5747 PERFETTO_DCHECK_THREAD(thread_checker_);
5748 if (!watch_tasks_changed_)
5749 return;
5750 watch_tasks_changed_ = false;
5751 poll_fds_.clear();
5752 for (auto& it : watch_tasks_) {
5753 it.second.poll_fd_index = poll_fds_.size();
5754 poll_fds_.push_back({it.first, POLLIN | POLLHUP, 0});
5755 }
5756 }
5757
RunImmediateAndDelayedTask()5758 void UnixTaskRunner::RunImmediateAndDelayedTask() {
5759 // If locking overhead becomes an issue, add a separate work queue.
5760 std::function<void()> immediate_task;
5761 std::function<void()> delayed_task;
5762 TimeMillis now = GetWallTimeMs();
5763 {
5764 std::lock_guard<std::mutex> lock(lock_);
5765 if (!immediate_tasks_.empty()) {
5766 immediate_task = std::move(immediate_tasks_.front());
5767 immediate_tasks_.pop_front();
5768 }
5769 if (!delayed_tasks_.empty()) {
5770 auto it = delayed_tasks_.begin();
5771 if (now >= it->first) {
5772 delayed_task = std::move(it->second);
5773 delayed_tasks_.erase(it);
5774 }
5775 }
5776 }
5777
5778 errno = 0;
5779 if (immediate_task)
5780 RunTaskWithWatchdogGuard(immediate_task);
5781 errno = 0;
5782 if (delayed_task)
5783 RunTaskWithWatchdogGuard(delayed_task);
5784 }
5785
PostFileDescriptorWatches()5786 void UnixTaskRunner::PostFileDescriptorWatches() {
5787 PERFETTO_DCHECK_THREAD(thread_checker_);
5788 for (size_t i = 0; i < poll_fds_.size(); i++) {
5789 if (!(poll_fds_[i].revents & (POLLIN | POLLHUP)))
5790 continue;
5791 poll_fds_[i].revents = 0;
5792
5793 // The wake-up event is handled inline to avoid an infinite recursion of
5794 // posted tasks.
5795 if (poll_fds_[i].fd == event_.fd()) {
5796 event_.Clear();
5797 continue;
5798 }
5799
5800 // Binding to |this| is safe since we are the only object executing the
5801 // task.
5802 PostTask(std::bind(&UnixTaskRunner::RunFileDescriptorWatch, this,
5803 poll_fds_[i].fd));
5804
5805 // Make the fd negative while a posted task is pending. This makes poll(2)
5806 // ignore the fd.
5807 PERFETTO_DCHECK(poll_fds_[i].fd >= 0);
5808 poll_fds_[i].fd = -poll_fds_[i].fd;
5809 }
5810 }
5811
RunFileDescriptorWatch(int fd)5812 void UnixTaskRunner::RunFileDescriptorWatch(int fd) {
5813 std::function<void()> task;
5814 {
5815 std::lock_guard<std::mutex> lock(lock_);
5816 auto it = watch_tasks_.find(fd);
5817 if (it == watch_tasks_.end())
5818 return;
5819 // Make poll(2) pay attention to the fd again. Since another thread may have
5820 // updated this watch we need to refresh the set first.
5821 UpdateWatchTasksLocked();
5822 size_t fd_index = it->second.poll_fd_index;
5823 PERFETTO_DCHECK(fd_index < poll_fds_.size());
5824 PERFETTO_DCHECK(::abs(poll_fds_[fd_index].fd) == fd);
5825 poll_fds_[fd_index].fd = fd;
5826 task = it->second.callback;
5827 }
5828 errno = 0;
5829 RunTaskWithWatchdogGuard(task);
5830 }
5831
GetDelayMsToNextTaskLocked() const5832 int UnixTaskRunner::GetDelayMsToNextTaskLocked() const {
5833 PERFETTO_DCHECK_THREAD(thread_checker_);
5834 if (!immediate_tasks_.empty())
5835 return 0;
5836 if (!delayed_tasks_.empty()) {
5837 TimeMillis diff = delayed_tasks_.begin()->first - GetWallTimeMs();
5838 return std::max(0, static_cast<int>(diff.count()));
5839 }
5840 return -1;
5841 }
5842
PostTask(std::function<void ()> task)5843 void UnixTaskRunner::PostTask(std::function<void()> task) {
5844 bool was_empty;
5845 {
5846 std::lock_guard<std::mutex> lock(lock_);
5847 was_empty = immediate_tasks_.empty();
5848 immediate_tasks_.push_back(std::move(task));
5849 }
5850 if (was_empty)
5851 WakeUp();
5852 }
5853
PostDelayedTask(std::function<void ()> task,uint32_t delay_ms)5854 void UnixTaskRunner::PostDelayedTask(std::function<void()> task,
5855 uint32_t delay_ms) {
5856 TimeMillis runtime = GetWallTimeMs() + TimeMillis(delay_ms);
5857 {
5858 std::lock_guard<std::mutex> lock(lock_);
5859 delayed_tasks_.insert(std::make_pair(runtime, std::move(task)));
5860 }
5861 WakeUp();
5862 }
5863
AddFileDescriptorWatch(int fd,std::function<void ()> task)5864 void UnixTaskRunner::AddFileDescriptorWatch(int fd,
5865 std::function<void()> task) {
5866 PERFETTO_DCHECK(fd >= 0);
5867 {
5868 std::lock_guard<std::mutex> lock(lock_);
5869 PERFETTO_DCHECK(!watch_tasks_.count(fd));
5870 watch_tasks_[fd] = {std::move(task), SIZE_MAX};
5871 watch_tasks_changed_ = true;
5872 }
5873 WakeUp();
5874 }
5875
RemoveFileDescriptorWatch(int fd)5876 void UnixTaskRunner::RemoveFileDescriptorWatch(int fd) {
5877 PERFETTO_DCHECK(fd >= 0);
5878 {
5879 std::lock_guard<std::mutex> lock(lock_);
5880 PERFETTO_DCHECK(watch_tasks_.count(fd));
5881 watch_tasks_.erase(fd);
5882 watch_tasks_changed_ = true;
5883 }
5884 // No need to schedule a wake-up for this.
5885 }
5886
RunsTasksOnCurrentThread() const5887 bool UnixTaskRunner::RunsTasksOnCurrentThread() const {
5888 return GetThreadId() == created_thread_id_;
5889 }
5890
5891 } // namespace base
5892 } // namespace perfetto
5893
5894 #endif // !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
5895 // gen_amalgamated begin source: src/protozero/field.cc
5896 /*
5897 * Copyright (C) 2019 The Android Open Source Project
5898 *
5899 * Licensed under the Apache License, Version 2.0 (the "License");
5900 * you may not use this file except in compliance with the License.
5901 * You may obtain a copy of the License at
5902 *
5903 * http://www.apache.org/licenses/LICENSE-2.0
5904 *
5905 * Unless required by applicable law or agreed to in writing, software
5906 * distributed under the License is distributed on an "AS IS" BASIS,
5907 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5908 * See the License for the specific language governing permissions and
5909 * limitations under the License.
5910 */
5911
5912 // gen_amalgamated expanded: #include "perfetto/protozero/field.h"
5913
5914 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
5915
5916 #if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__
5917 // The memcpy() for fixed32/64 below needs to be adjusted if we want to
5918 // support big endian CPUs. There doesn't seem to be a compelling need today.
5919 #error Unimplemented for big endian archs.
5920 #endif
5921
5922 namespace protozero {
5923
5924 template <typename Container>
SerializeAndAppendToInternal(Container * dst) const5925 void Field::SerializeAndAppendToInternal(Container* dst) const {
5926 namespace pu = proto_utils;
5927 size_t initial_size = dst->size();
5928 dst->resize(initial_size + pu::kMaxSimpleFieldEncodedSize + size_);
5929 uint8_t* start = reinterpret_cast<uint8_t*>(&(*dst)[initial_size]);
5930 uint8_t* wptr = start;
5931 switch (type_) {
5932 case static_cast<int>(pu::ProtoWireType::kVarInt): {
5933 wptr = pu::WriteVarInt(pu::MakeTagVarInt(id_), wptr);
5934 wptr = pu::WriteVarInt(int_value_, wptr);
5935 break;
5936 }
5937 case static_cast<int>(pu::ProtoWireType::kFixed32): {
5938 wptr = pu::WriteVarInt(pu::MakeTagFixed<uint32_t>(id_), wptr);
5939 uint32_t value32 = static_cast<uint32_t>(int_value_);
5940 memcpy(wptr, &value32, sizeof(value32));
5941 wptr += sizeof(uint32_t);
5942 break;
5943 }
5944 case static_cast<int>(pu::ProtoWireType::kFixed64): {
5945 wptr = pu::WriteVarInt(pu::MakeTagFixed<uint64_t>(id_), wptr);
5946 memcpy(wptr, &int_value_, sizeof(int_value_));
5947 wptr += sizeof(uint64_t);
5948 break;
5949 }
5950 case static_cast<int>(pu::ProtoWireType::kLengthDelimited): {
5951 ConstBytes payload = as_bytes();
5952 wptr = pu::WriteVarInt(pu::MakeTagLengthDelimited(id_), wptr);
5953 wptr = pu::WriteVarInt(payload.size, wptr);
5954 memcpy(wptr, payload.data, payload.size);
5955 wptr += payload.size;
5956 break;
5957 }
5958 default:
5959 PERFETTO_FATAL("Unknown field type %u", type_);
5960 }
5961 size_t written_size = static_cast<size_t>(wptr - start);
5962 PERFETTO_DCHECK(written_size > 0 && written_size < pu::kMaxMessageLength);
5963 PERFETTO_DCHECK(initial_size + written_size <= dst->size());
5964 dst->resize(initial_size + written_size);
5965 }
5966
SerializeAndAppendTo(std::string * dst) const5967 void Field::SerializeAndAppendTo(std::string* dst) const {
5968 SerializeAndAppendToInternal(dst);
5969 }
5970
SerializeAndAppendTo(std::vector<uint8_t> * dst) const5971 void Field::SerializeAndAppendTo(std::vector<uint8_t>* dst) const {
5972 SerializeAndAppendToInternal(dst);
5973 }
5974
5975 } // namespace protozero
5976 // gen_amalgamated begin source: src/protozero/message.cc
5977 /*
5978 * Copyright (C) 2017 The Android Open Source Project
5979 *
5980 * Licensed under the Apache License, Version 2.0 (the "License");
5981 * you may not use this file except in compliance with the License.
5982 * You may obtain a copy of the License at
5983 *
5984 * http://www.apache.org/licenses/LICENSE-2.0
5985 *
5986 * Unless required by applicable law or agreed to in writing, software
5987 * distributed under the License is distributed on an "AS IS" BASIS,
5988 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5989 * See the License for the specific language governing permissions and
5990 * limitations under the License.
5991 */
5992
5993 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
5994
5995 #include <atomic>
5996 #include <type_traits>
5997
5998 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
5999 // gen_amalgamated expanded: #include "perfetto/protozero/message_arena.h"
6000 // gen_amalgamated expanded: #include "perfetto/protozero/message_handle.h"
6001
6002 #if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__
6003 // The memcpy() for float and double below needs to be adjusted if we want to
6004 // support big endian CPUs. There doesn't seem to be a compelling need today.
6005 #error Unimplemented for big endian archs.
6006 #endif
6007
6008 namespace protozero {
6009
6010 namespace {
6011
6012 #if PERFETTO_DCHECK_IS_ON()
6013 std::atomic<uint32_t> g_generation;
6014 #endif
6015
6016 } // namespace
6017
6018 // Do NOT put any code in the constructor or use default initialization.
6019 // Use the Reset() method below instead.
6020
6021 // This method is called to initialize both root and nested messages.
Reset(ScatteredStreamWriter * stream_writer,MessageArena * arena)6022 void Message::Reset(ScatteredStreamWriter* stream_writer, MessageArena* arena) {
6023 // Older versions of libstdcxx don't have is_trivially_constructible.
6024 #if !defined(__GLIBCXX__) || __GLIBCXX__ >= 20170516
6025 static_assert(std::is_trivially_constructible<Message>::value,
6026 "Message must be trivially constructible");
6027 #endif
6028
6029 static_assert(std::is_trivially_destructible<Message>::value,
6030 "Message must be trivially destructible");
6031 stream_writer_ = stream_writer;
6032 arena_ = arena;
6033 size_ = 0;
6034 size_field_ = nullptr;
6035 size_already_written_ = 0;
6036 nested_message_ = nullptr;
6037 finalized_ = false;
6038 #if PERFETTO_DCHECK_IS_ON()
6039 handle_ = nullptr;
6040 generation_ = g_generation.fetch_add(1, std::memory_order_relaxed);
6041 #endif
6042 }
6043
AppendString(uint32_t field_id,const char * str)6044 void Message::AppendString(uint32_t field_id, const char* str) {
6045 AppendBytes(field_id, str, strlen(str));
6046 }
6047
AppendBytes(uint32_t field_id,const void * src,size_t size)6048 void Message::AppendBytes(uint32_t field_id, const void* src, size_t size) {
6049 if (nested_message_)
6050 EndNestedMessage();
6051
6052 PERFETTO_DCHECK(size < proto_utils::kMaxMessageLength);
6053 // Write the proto preamble (field id, type and length of the field).
6054 uint8_t buffer[proto_utils::kMaxSimpleFieldEncodedSize];
6055 uint8_t* pos = buffer;
6056 pos = proto_utils::WriteVarInt(proto_utils::MakeTagLengthDelimited(field_id),
6057 pos);
6058 pos = proto_utils::WriteVarInt(static_cast<uint32_t>(size), pos);
6059 WriteToStream(buffer, pos);
6060
6061 const uint8_t* src_u8 = reinterpret_cast<const uint8_t*>(src);
6062 WriteToStream(src_u8, src_u8 + size);
6063 }
6064
AppendScatteredBytes(uint32_t field_id,ContiguousMemoryRange * ranges,size_t num_ranges)6065 size_t Message::AppendScatteredBytes(uint32_t field_id,
6066 ContiguousMemoryRange* ranges,
6067 size_t num_ranges) {
6068 size_t size = 0;
6069 for (size_t i = 0; i < num_ranges; ++i) {
6070 size += ranges[i].size();
6071 }
6072
6073 PERFETTO_DCHECK(size < proto_utils::kMaxMessageLength);
6074
6075 uint8_t buffer[proto_utils::kMaxSimpleFieldEncodedSize];
6076 uint8_t* pos = buffer;
6077 pos = proto_utils::WriteVarInt(proto_utils::MakeTagLengthDelimited(field_id),
6078 pos);
6079 pos = proto_utils::WriteVarInt(static_cast<uint32_t>(size), pos);
6080 WriteToStream(buffer, pos);
6081
6082 for (size_t i = 0; i < num_ranges; ++i) {
6083 auto& range = ranges[i];
6084 WriteToStream(range.begin, range.end);
6085 }
6086
6087 return size;
6088 }
6089
Finalize()6090 uint32_t Message::Finalize() {
6091 if (finalized_)
6092 return size_;
6093
6094 if (nested_message_)
6095 EndNestedMessage();
6096
6097 // Write the length of the nested message a posteriori, using a leading-zero
6098 // redundant varint encoding.
6099 if (size_field_) {
6100 PERFETTO_DCHECK(!finalized_);
6101 PERFETTO_DCHECK(size_ < proto_utils::kMaxMessageLength);
6102 PERFETTO_DCHECK(size_ >= size_already_written_);
6103 proto_utils::WriteRedundantVarInt(size_ - size_already_written_,
6104 size_field_);
6105 size_field_ = nullptr;
6106 }
6107
6108 finalized_ = true;
6109 #if PERFETTO_DCHECK_IS_ON()
6110 if (handle_)
6111 handle_->reset_message();
6112 #endif
6113
6114 return size_;
6115 }
6116
BeginNestedMessageInternal(uint32_t field_id)6117 Message* Message::BeginNestedMessageInternal(uint32_t field_id) {
6118 if (nested_message_)
6119 EndNestedMessage();
6120
6121 // Write the proto preamble for the nested message.
6122 uint8_t data[proto_utils::kMaxTagEncodedSize];
6123 uint8_t* data_end = proto_utils::WriteVarInt(
6124 proto_utils::MakeTagLengthDelimited(field_id), data);
6125 WriteToStream(data, data_end);
6126
6127 Message* message = arena_->NewMessage();
6128 message->Reset(stream_writer_, arena_);
6129
6130 // The length of the nested message cannot be known upfront. So right now
6131 // just reserve the bytes to encode the size after the nested message is done.
6132 message->set_size_field(
6133 stream_writer_->ReserveBytes(proto_utils::kMessageLengthFieldSize));
6134 size_ += proto_utils::kMessageLengthFieldSize;
6135
6136 nested_message_ = message;
6137 return message;
6138 }
6139
EndNestedMessage()6140 void Message::EndNestedMessage() {
6141 size_ += nested_message_->Finalize();
6142 arena_->DeleteLastMessage(nested_message_);
6143 nested_message_ = nullptr;
6144 }
6145
6146 } // namespace protozero
6147 // gen_amalgamated begin source: src/protozero/message_arena.cc
6148 /*
6149 * Copyright (C) 2020 The Android Open Source Project
6150 *
6151 * Licensed under the Apache License, Version 2.0 (the "License");
6152 * you may not use this file except in compliance with the License.
6153 * You may obtain a copy of the License at
6154 *
6155 * http://www.apache.org/licenses/LICENSE-2.0
6156 *
6157 * Unless required by applicable law or agreed to in writing, software
6158 * distributed under the License is distributed on an "AS IS" BASIS,
6159 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6160 * See the License for the specific language governing permissions and
6161 * limitations under the License.
6162 */
6163
6164 // gen_amalgamated expanded: #include "perfetto/protozero/message_arena.h"
6165
6166 #include <atomic>
6167 #include <type_traits>
6168
6169 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
6170 // gen_amalgamated expanded: #include "perfetto/protozero/message_handle.h"
6171
6172 namespace protozero {
6173
MessageArena()6174 MessageArena::MessageArena() {
6175 // The code below assumes that there is always at least one block.
6176 blocks_.emplace_front();
6177 static_assert(std::alignment_of<decltype(blocks_.back().storage[0])>::value >=
6178 alignof(Message),
6179 "MessageArea's storage is not properly aligned");
6180 }
6181
6182 MessageArena::~MessageArena() = default;
6183
NewMessage()6184 Message* MessageArena::NewMessage() {
6185 PERFETTO_DCHECK(!blocks_.empty()); // Should never become empty.
6186
6187 Block* block = &blocks_.back();
6188 if (PERFETTO_UNLIKELY(block->entries >= Block::kCapacity)) {
6189 blocks_.emplace_back();
6190 block = &blocks_.back();
6191 }
6192 const auto idx = block->entries++;
6193 void* storage = &block->storage[idx];
6194 PERFETTO_ASAN_UNPOISON(storage, sizeof(Message));
6195 return new (storage) Message();
6196 }
6197
DeleteLastMessageInternal()6198 void MessageArena::DeleteLastMessageInternal() {
6199 PERFETTO_DCHECK(!blocks_.empty()); // Should never be empty, see below.
6200 Block* block = &blocks_.back();
6201 PERFETTO_DCHECK(block->entries > 0);
6202
6203 // This is the reason why there is no ~Message() call here.
6204 // MessageArea::Reset() (see header) also relies on dtor being trivial.
6205 static_assert(std::is_trivially_destructible<Message>::value,
6206 "Message must be trivially destructible");
6207
6208 --block->entries;
6209 PERFETTO_ASAN_POISON(&block->storage[block->entries], sizeof(Message));
6210
6211 // Don't remove the first block to avoid malloc/free calls when the root
6212 // message is reset. Hitting the allocator all the times is a waste of time.
6213 if (block->entries == 0 && blocks_.size() > 1) {
6214 blocks_.pop_back();
6215 }
6216 }
6217
6218 } // namespace protozero
6219 // gen_amalgamated begin source: src/protozero/message_handle.cc
6220 /*
6221 * Copyright (C) 2017 The Android Open Source Project
6222 *
6223 * Licensed under the Apache License, Version 2.0 (the "License");
6224 * you may not use this file except in compliance with the License.
6225 * You may obtain a copy of the License at
6226 *
6227 * http://www.apache.org/licenses/LICENSE-2.0
6228 *
6229 * Unless required by applicable law or agreed to in writing, software
6230 * distributed under the License is distributed on an "AS IS" BASIS,
6231 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6232 * See the License for the specific language governing permissions and
6233 * limitations under the License.
6234 */
6235
6236 // gen_amalgamated expanded: #include "perfetto/protozero/message_handle.h"
6237
6238 #include <utility>
6239
6240 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
6241
6242 namespace protozero {
6243
MessageHandleBase(Message * message)6244 MessageHandleBase::MessageHandleBase(Message* message) : message_(message) {
6245 #if PERFETTO_DCHECK_IS_ON()
6246 generation_ = message_ ? message->generation_ : 0;
6247 if (message_)
6248 message_->set_handle(this);
6249 #endif
6250 }
6251
~MessageHandleBase()6252 MessageHandleBase::~MessageHandleBase() {
6253 if (message_) {
6254 #if PERFETTO_DCHECK_IS_ON()
6255 PERFETTO_DCHECK(generation_ == message_->generation_);
6256 #endif
6257 FinalizeMessage();
6258 }
6259 }
6260
MessageHandleBase(MessageHandleBase && other)6261 MessageHandleBase::MessageHandleBase(MessageHandleBase&& other) noexcept {
6262 Move(std::move(other));
6263 }
6264
operator =(MessageHandleBase && other)6265 MessageHandleBase& MessageHandleBase::operator=(MessageHandleBase&& other) {
6266 // If the current handle was pointing to a message and is being reset to a new
6267 // one, finalize the old message. However, if the other message is the same as
6268 // the one we point to, don't finalize.
6269 if (message_ && message_ != other.message_)
6270 FinalizeMessage();
6271 Move(std::move(other));
6272 return *this;
6273 }
6274
Move(MessageHandleBase && other)6275 void MessageHandleBase::Move(MessageHandleBase&& other) {
6276 message_ = other.message_;
6277 other.message_ = nullptr;
6278 #if PERFETTO_DCHECK_IS_ON()
6279 if (message_) {
6280 generation_ = message_->generation_;
6281 message_->set_handle(this);
6282 }
6283 #endif
6284 }
6285
6286 } // namespace protozero
6287 // gen_amalgamated begin source: src/protozero/packed_repeated_fields.cc
6288 /*
6289 * Copyright (C) 2017 The Android Open Source Project
6290 *
6291 * Licensed under the Apache License, Version 2.0 (the "License");
6292 * you may not use this file except in compliance with the License.
6293 * You may obtain a copy of the License at
6294 *
6295 * http://www.apache.org/licenses/LICENSE-2.0
6296 *
6297 * Unless required by applicable law or agreed to in writing, software
6298 * distributed under the License is distributed on an "AS IS" BASIS,
6299 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6300 * See the License for the specific language governing permissions and
6301 * limitations under the License.
6302 */
6303
6304 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
6305
6306 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
6307
6308 namespace protozero {
6309
6310 // static
6311 constexpr size_t PackedBufferBase::kOnStackStorageSize;
6312
GrowSlowpath()6313 void PackedBufferBase::GrowSlowpath() {
6314 size_t write_off = static_cast<size_t>(write_ptr_ - storage_begin_);
6315 size_t old_size = static_cast<size_t>(storage_end_ - storage_begin_);
6316 size_t new_size = old_size < 65536 ? (old_size * 2) : (old_size * 3 / 2);
6317 new_size = perfetto::base::AlignUp<4096>(new_size);
6318 std::unique_ptr<uint8_t[]> new_buf(new uint8_t[new_size]);
6319 memcpy(new_buf.get(), storage_begin_, old_size);
6320 heap_buf_ = std::move(new_buf);
6321 storage_begin_ = heap_buf_.get();
6322 storage_end_ = storage_begin_ + new_size;
6323 write_ptr_ = storage_begin_ + write_off;
6324 }
6325
Reset()6326 void PackedBufferBase::Reset() {
6327 heap_buf_.reset();
6328 storage_begin_ = reinterpret_cast<uint8_t*>(&stack_buf_[0]);
6329 storage_end_ = reinterpret_cast<uint8_t*>(&stack_buf_[kOnStackStorageSize]);
6330 write_ptr_ = storage_begin_;
6331 }
6332
6333 } // namespace protozero
6334 // gen_amalgamated begin source: src/protozero/proto_decoder.cc
6335 /*
6336 * Copyright (C) 2018 The Android Open Source Project
6337 *
6338 * Licensed under the Apache License, Version 2.0 (the "License");
6339 * you may not use this file except in compliance with the License.
6340 * You may obtain a copy of the License at
6341 *
6342 * http://www.apache.org/licenses/LICENSE-2.0
6343 *
6344 * Unless required by applicable law or agreed to in writing, software
6345 * distributed under the License is distributed on an "AS IS" BASIS,
6346 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6347 * See the License for the specific language governing permissions and
6348 * limitations under the License.
6349 */
6350
6351 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
6352
6353 #include <string.h>
6354 #include <limits>
6355
6356 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
6357 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
6358 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
6359
6360 namespace protozero {
6361
6362 using namespace proto_utils;
6363
6364 #if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__
6365 #error Unimplemented for big endian archs.
6366 #endif
6367
6368 namespace {
6369
6370 struct ParseFieldResult {
6371 enum ParseResult { kAbort, kSkip, kOk };
6372 ParseResult parse_res;
6373 const uint8_t* next;
6374 Field field;
6375 };
6376
6377 // Parses one field and returns the field itself and a pointer to the next
6378 // field to parse. If parsing fails, the returned |next| == |buffer|.
6379 PERFETTO_ALWAYS_INLINE ParseFieldResult
ParseOneField(const uint8_t * const buffer,const uint8_t * const end)6380 ParseOneField(const uint8_t* const buffer, const uint8_t* const end) {
6381 ParseFieldResult res{ParseFieldResult::kAbort, buffer, Field{}};
6382
6383 // The first byte of a proto field is structured as follows:
6384 // The least 3 significant bits determine the field type.
6385 // The most 5 significant bits determine the field id. If MSB == 1, the
6386 // field id continues on the next bytes following the VarInt encoding.
6387 const uint8_t kFieldTypeNumBits = 3;
6388 const uint64_t kFieldTypeMask = (1 << kFieldTypeNumBits) - 1; // 0000 0111;
6389 const uint8_t* pos = buffer;
6390
6391 // If we've already hit the end, just return an invalid field.
6392 if (PERFETTO_UNLIKELY(pos >= end))
6393 return res;
6394
6395 uint64_t preamble = 0;
6396 if (PERFETTO_LIKELY(*pos < 0x80)) { // Fastpath for fields with ID < 16.
6397 preamble = *(pos++);
6398 } else {
6399 const uint8_t* next = ParseVarInt(pos, end, &preamble);
6400 if (PERFETTO_UNLIKELY(pos == next))
6401 return res;
6402 pos = next;
6403 }
6404
6405 uint32_t field_id = static_cast<uint32_t>(preamble >> kFieldTypeNumBits);
6406 if (field_id == 0 || pos >= end)
6407 return res;
6408
6409 auto field_type = static_cast<uint8_t>(preamble & kFieldTypeMask);
6410 const uint8_t* new_pos = pos;
6411 uint64_t int_value = 0;
6412 uint64_t size = 0;
6413
6414 switch (field_type) {
6415 case static_cast<uint8_t>(ProtoWireType::kVarInt): {
6416 new_pos = ParseVarInt(pos, end, &int_value);
6417
6418 // new_pos not being greater than pos means ParseVarInt could not fully
6419 // parse the number. This is because we are out of space in the buffer.
6420 // Set the id to zero and return but don't update the offset so a future
6421 // read can read this field.
6422 if (PERFETTO_UNLIKELY(new_pos == pos))
6423 return res;
6424
6425 break;
6426 }
6427
6428 case static_cast<uint8_t>(ProtoWireType::kLengthDelimited): {
6429 uint64_t payload_length;
6430 new_pos = ParseVarInt(pos, end, &payload_length);
6431 if (PERFETTO_UNLIKELY(new_pos == pos))
6432 return res;
6433
6434 // ParseVarInt guarantees that |new_pos| <= |end| when it succeeds;
6435 if (payload_length > static_cast<uint64_t>(end - new_pos))
6436 return res;
6437
6438 const uintptr_t payload_start = reinterpret_cast<uintptr_t>(new_pos);
6439 int_value = payload_start;
6440 size = payload_length;
6441 new_pos += payload_length;
6442 break;
6443 }
6444
6445 case static_cast<uint8_t>(ProtoWireType::kFixed64): {
6446 new_pos = pos + sizeof(uint64_t);
6447 if (PERFETTO_UNLIKELY(new_pos > end))
6448 return res;
6449 memcpy(&int_value, pos, sizeof(uint64_t));
6450 break;
6451 }
6452
6453 case static_cast<uint8_t>(ProtoWireType::kFixed32): {
6454 new_pos = pos + sizeof(uint32_t);
6455 if (PERFETTO_UNLIKELY(new_pos > end))
6456 return res;
6457 memcpy(&int_value, pos, sizeof(uint32_t));
6458 break;
6459 }
6460
6461 default:
6462 PERFETTO_DLOG("Invalid proto field type: %u", field_type);
6463 return res;
6464 }
6465
6466 res.next = new_pos;
6467
6468 if (PERFETTO_UNLIKELY(field_id > std::numeric_limits<uint16_t>::max())) {
6469 PERFETTO_DLOG("Skipping field %" PRIu32 " because its id > 0xFFFF",
6470 field_id);
6471 res.parse_res = ParseFieldResult::kSkip;
6472 return res;
6473 }
6474
6475 if (PERFETTO_UNLIKELY(size > proto_utils::kMaxMessageLength)) {
6476 PERFETTO_DLOG("Skipping field %" PRIu32 " because it's too big (%" PRIu64
6477 " KB)",
6478 field_id, size / 1024);
6479 res.parse_res = ParseFieldResult::kSkip;
6480 return res;
6481 }
6482
6483 res.parse_res = ParseFieldResult::kOk;
6484 res.field.initialize(static_cast<uint16_t>(field_id), field_type, int_value,
6485 static_cast<uint32_t>(size));
6486 return res;
6487 }
6488
6489 } // namespace
6490
FindField(uint32_t field_id)6491 Field ProtoDecoder::FindField(uint32_t field_id) {
6492 Field res{};
6493 auto old_position = read_ptr_;
6494 read_ptr_ = begin_;
6495 for (auto f = ReadField(); f.valid(); f = ReadField()) {
6496 if (f.id() == field_id) {
6497 res = f;
6498 break;
6499 }
6500 }
6501 read_ptr_ = old_position;
6502 return res;
6503 }
6504
6505 PERFETTO_ALWAYS_INLINE
ReadField()6506 Field ProtoDecoder::ReadField() {
6507 ParseFieldResult res;
6508 do {
6509 res = ParseOneField(read_ptr_, end_);
6510 read_ptr_ = res.next;
6511 } while (PERFETTO_UNLIKELY(res.parse_res == ParseFieldResult::kSkip));
6512 return res.field;
6513 }
6514
ParseAllFields()6515 void TypedProtoDecoderBase::ParseAllFields() {
6516 const uint8_t* cur = begin_;
6517 ParseFieldResult res;
6518 for (;;) {
6519 res = ParseOneField(cur, end_);
6520 PERFETTO_DCHECK(res.parse_res != ParseFieldResult::kOk || res.next != cur);
6521 cur = res.next;
6522 if (PERFETTO_UNLIKELY(res.parse_res == ParseFieldResult::kSkip)) {
6523 continue;
6524 } else if (PERFETTO_UNLIKELY(res.parse_res == ParseFieldResult::kAbort)) {
6525 break;
6526 }
6527 PERFETTO_DCHECK(res.parse_res == ParseFieldResult::kOk);
6528 PERFETTO_DCHECK(res.field.valid());
6529 auto field_id = res.field.id();
6530 if (PERFETTO_UNLIKELY(field_id >= num_fields_))
6531 continue;
6532
6533 Field* fld = &fields_[field_id];
6534 if (PERFETTO_LIKELY(!fld->valid())) {
6535 // This is the first time we see this field.
6536 *fld = std::move(res.field);
6537 } else {
6538 // Repeated field case.
6539 // In this case we need to:
6540 // 1. Append the last value of the field to end of the repeated field
6541 // storage.
6542 // 2. Replace the default instance at offset |field_id| with the current
6543 // value. This is because in case of repeated field a call to Get(X) is
6544 // supposed to return the last value of X, not the first one.
6545 // This is so that the RepeatedFieldIterator will iterate in the right
6546 // order, see comments on RepeatedFieldIterator.
6547 if (PERFETTO_UNLIKELY(size_ >= capacity_)) {
6548 ExpandHeapStorage();
6549 // ExpandHeapStorage moves fields_ so we need to update the ptr to fld:
6550 fld = &fields_[field_id];
6551 PERFETTO_DCHECK(size_ < capacity_);
6552 }
6553 fields_[size_++] = *fld;
6554 *fld = std::move(res.field);
6555 }
6556 }
6557 read_ptr_ = res.next;
6558 }
6559
ExpandHeapStorage()6560 void TypedProtoDecoderBase::ExpandHeapStorage() {
6561 uint32_t new_capacity = capacity_ * 2;
6562 PERFETTO_CHECK(new_capacity > size_);
6563 std::unique_ptr<Field[]> new_storage(new Field[new_capacity]);
6564
6565 static_assert(std::is_trivially_copyable<Field>::value,
6566 "Field must be trivially copyable");
6567 memcpy(&new_storage[0], fields_, sizeof(Field) * size_);
6568
6569 heap_storage_ = std::move(new_storage);
6570 fields_ = &heap_storage_[0];
6571 capacity_ = new_capacity;
6572 }
6573
6574 } // namespace protozero
6575 // gen_amalgamated begin source: src/protozero/scattered_heap_buffer.cc
6576 /*
6577 * Copyright (C) 2017 The Android Open Source Project
6578 *
6579 * Licensed under the Apache License, Version 2.0 (the "License");
6580 * you may not use this file except in compliance with the License.
6581 * You may obtain a copy of the License at
6582 *
6583 * http://www.apache.org/licenses/LICENSE-2.0
6584 *
6585 * Unless required by applicable law or agreed to in writing, software
6586 * distributed under the License is distributed on an "AS IS" BASIS,
6587 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6588 * See the License for the specific language governing permissions and
6589 * limitations under the License.
6590 */
6591
6592 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
6593
6594 #include <algorithm>
6595
6596 namespace protozero {
6597
Slice()6598 ScatteredHeapBuffer::Slice::Slice()
6599 : buffer_(nullptr), size_(0u), unused_bytes_(0u) {}
6600
Slice(size_t size)6601 ScatteredHeapBuffer::Slice::Slice(size_t size)
6602 : buffer_(std::unique_ptr<uint8_t[]>(new uint8_t[size])),
6603 size_(size),
6604 unused_bytes_(size) {
6605 PERFETTO_DCHECK(size);
6606 Clear();
6607 }
6608
6609 ScatteredHeapBuffer::Slice::Slice(Slice&& slice) noexcept = default;
6610
6611 ScatteredHeapBuffer::Slice::~Slice() = default;
6612
6613 ScatteredHeapBuffer::Slice& ScatteredHeapBuffer::Slice::operator=(Slice&&) =
6614 default;
6615
Clear()6616 void ScatteredHeapBuffer::Slice::Clear() {
6617 unused_bytes_ = size_;
6618 #if PERFETTO_DCHECK_IS_ON()
6619 memset(start(), 0xff, size_);
6620 #endif // PERFETTO_DCHECK_IS_ON()
6621 }
6622
ScatteredHeapBuffer(size_t initial_slice_size_bytes,size_t maximum_slice_size_bytes)6623 ScatteredHeapBuffer::ScatteredHeapBuffer(size_t initial_slice_size_bytes,
6624 size_t maximum_slice_size_bytes)
6625 : next_slice_size_(initial_slice_size_bytes),
6626 maximum_slice_size_(maximum_slice_size_bytes) {
6627 PERFETTO_DCHECK(next_slice_size_ && maximum_slice_size_);
6628 PERFETTO_DCHECK(maximum_slice_size_ >= initial_slice_size_bytes);
6629 }
6630
6631 ScatteredHeapBuffer::~ScatteredHeapBuffer() = default;
6632
GetNewBuffer()6633 protozero::ContiguousMemoryRange ScatteredHeapBuffer::GetNewBuffer() {
6634 PERFETTO_CHECK(writer_);
6635 AdjustUsedSizeOfCurrentSlice();
6636
6637 if (cached_slice_.start()) {
6638 slices_.push_back(std::move(cached_slice_));
6639 PERFETTO_DCHECK(!cached_slice_.start());
6640 } else {
6641 slices_.emplace_back(next_slice_size_);
6642 }
6643 next_slice_size_ = std::min(maximum_slice_size_, next_slice_size_ * 2);
6644 return slices_.back().GetTotalRange();
6645 }
6646
StitchSlices()6647 std::vector<uint8_t> ScatteredHeapBuffer::StitchSlices() {
6648 AdjustUsedSizeOfCurrentSlice();
6649 std::vector<uint8_t> buffer;
6650 for (const auto& slice : slices_) {
6651 auto used_range = slice.GetUsedRange();
6652 buffer.insert(buffer.end(), used_range.begin, used_range.end);
6653 }
6654 return buffer;
6655 }
6656
GetRanges()6657 std::vector<protozero::ContiguousMemoryRange> ScatteredHeapBuffer::GetRanges() {
6658 AdjustUsedSizeOfCurrentSlice();
6659 std::vector<protozero::ContiguousMemoryRange> ranges;
6660 for (const auto& slice : slices_)
6661 ranges.push_back(slice.GetUsedRange());
6662 return ranges;
6663 }
6664
AdjustUsedSizeOfCurrentSlice()6665 void ScatteredHeapBuffer::AdjustUsedSizeOfCurrentSlice() {
6666 if (!slices_.empty())
6667 slices_.back().set_unused_bytes(writer_->bytes_available());
6668 }
6669
GetTotalSize()6670 size_t ScatteredHeapBuffer::GetTotalSize() {
6671 size_t total_size = 0;
6672 for (auto& slice : slices_) {
6673 total_size += slice.size();
6674 }
6675 return total_size;
6676 }
6677
Reset()6678 void ScatteredHeapBuffer::Reset() {
6679 if (slices_.empty())
6680 return;
6681 cached_slice_ = std::move(slices_.front());
6682 cached_slice_.Clear();
6683 slices_.clear();
6684 }
6685
6686 } // namespace protozero
6687 // gen_amalgamated begin source: src/protozero/scattered_stream_null_delegate.cc
6688 // gen_amalgamated begin header: include/perfetto/protozero/scattered_stream_null_delegate.h
6689 /*
6690 * Copyright (C) 2018 The Android Open Source Project
6691 *
6692 * Licensed under the Apache License, Version 2.0 (the "License");
6693 * you may not use this file except in compliance with the License.
6694 * You may obtain a copy of the License at
6695 *
6696 * http://www.apache.org/licenses/LICENSE-2.0
6697 *
6698 * Unless required by applicable law or agreed to in writing, software
6699 * distributed under the License is distributed on an "AS IS" BASIS,
6700 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6701 * See the License for the specific language governing permissions and
6702 * limitations under the License.
6703 */
6704
6705 #ifndef INCLUDE_PERFETTO_PROTOZERO_SCATTERED_STREAM_NULL_DELEGATE_H_
6706 #define INCLUDE_PERFETTO_PROTOZERO_SCATTERED_STREAM_NULL_DELEGATE_H_
6707
6708 #include <memory>
6709 #include <vector>
6710
6711 // gen_amalgamated expanded: #include "perfetto/base/export.h"
6712 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
6713 // gen_amalgamated expanded: #include "perfetto/protozero/contiguous_memory_range.h"
6714 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_stream_writer.h"
6715
6716 namespace protozero {
6717
6718 class PERFETTO_EXPORT ScatteredStreamWriterNullDelegate
6719 : public ScatteredStreamWriter::Delegate {
6720 public:
6721 explicit ScatteredStreamWriterNullDelegate(size_t chunk_size);
6722 ~ScatteredStreamWriterNullDelegate() override;
6723
6724 // protozero::ScatteredStreamWriter::Delegate implementation.
6725 ContiguousMemoryRange GetNewBuffer() override;
6726
6727 private:
6728 const size_t chunk_size_;
6729 std::unique_ptr<uint8_t[]> chunk_;
6730 };
6731
6732 } // namespace protozero
6733
6734 #endif // INCLUDE_PERFETTO_PROTOZERO_SCATTERED_STREAM_NULL_DELEGATE_H_
6735 /*
6736 * Copyright (C) 2018 The Android Open Source Project
6737 *
6738 * Licensed under the Apache License, Version 2.0 (the "License");
6739 * you may not use this file except in compliance with the License.
6740 * You may obtain a copy of the License at
6741 *
6742 * http://www.apache.org/licenses/LICENSE-2.0
6743 *
6744 * Unless required by applicable law or agreed to in writing, software
6745 * distributed under the License is distributed on an "AS IS" BASIS,
6746 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6747 * See the License for the specific language governing permissions and
6748 * limitations under the License.
6749 */
6750
6751 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_stream_null_delegate.h"
6752
6753 namespace protozero {
6754
6755 // An implementation of ScatteredStreamWriter::Delegate which always returns
6756 // the same piece of memory.
6757 // This is used when we need to no-op the writers (e.g. during teardown or in
6758 // case of resource exhaustion), avoiding that the clients have to deal with
6759 // nullptr checks.
ScatteredStreamWriterNullDelegate(size_t chunk_size)6760 ScatteredStreamWriterNullDelegate::ScatteredStreamWriterNullDelegate(
6761 size_t chunk_size)
6762 : chunk_size_(chunk_size),
6763 chunk_(std::unique_ptr<uint8_t[]>(new uint8_t[chunk_size_])) {}
6764
~ScatteredStreamWriterNullDelegate()6765 ScatteredStreamWriterNullDelegate::~ScatteredStreamWriterNullDelegate() {}
6766
GetNewBuffer()6767 ContiguousMemoryRange ScatteredStreamWriterNullDelegate::GetNewBuffer() {
6768 return {chunk_.get(), chunk_.get() + chunk_size_};
6769 }
6770
6771 } // namespace protozero
6772 // gen_amalgamated begin source: src/protozero/scattered_stream_writer.cc
6773 /*
6774 * Copyright (C) 2017 The Android Open Source Project
6775 *
6776 * Licensed under the Apache License, Version 2.0 (the "License");
6777 * you may not use this file except in compliance with the License.
6778 * You may obtain a copy of the License at
6779 *
6780 * http://www.apache.org/licenses/LICENSE-2.0
6781 *
6782 * Unless required by applicable law or agreed to in writing, software
6783 * distributed under the License is distributed on an "AS IS" BASIS,
6784 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6785 * See the License for the specific language governing permissions and
6786 * limitations under the License.
6787 */
6788
6789 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_stream_writer.h"
6790
6791 #include <algorithm>
6792
6793 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
6794
6795 namespace protozero {
6796
~Delegate()6797 ScatteredStreamWriter::Delegate::~Delegate() {}
6798
ScatteredStreamWriter(Delegate * delegate)6799 ScatteredStreamWriter::ScatteredStreamWriter(Delegate* delegate)
6800 : delegate_(delegate),
6801 cur_range_({nullptr, nullptr}),
6802 write_ptr_(nullptr) {}
6803
~ScatteredStreamWriter()6804 ScatteredStreamWriter::~ScatteredStreamWriter() {}
6805
Reset(ContiguousMemoryRange range)6806 void ScatteredStreamWriter::Reset(ContiguousMemoryRange range) {
6807 written_previously_ += static_cast<uint64_t>(write_ptr_ - cur_range_.begin);
6808 cur_range_ = range;
6809 write_ptr_ = range.begin;
6810 PERFETTO_DCHECK(!write_ptr_ || write_ptr_ < cur_range_.end);
6811 }
6812
Extend()6813 void ScatteredStreamWriter::Extend() {
6814 Reset(delegate_->GetNewBuffer());
6815 }
6816
WriteBytesSlowPath(const uint8_t * src,size_t size)6817 void ScatteredStreamWriter::WriteBytesSlowPath(const uint8_t* src,
6818 size_t size) {
6819 size_t bytes_left = size;
6820 while (bytes_left > 0) {
6821 if (write_ptr_ >= cur_range_.end)
6822 Extend();
6823 const size_t burst_size = std::min(bytes_available(), bytes_left);
6824 WriteBytesUnsafe(src, burst_size);
6825 bytes_left -= burst_size;
6826 src += burst_size;
6827 }
6828 }
6829
6830 // TODO(primiano): perf optimization: I suspect that at the end this will always
6831 // be called with |size| == 4, in which case we might just hardcode it.
ReserveBytes(size_t size)6832 uint8_t* ScatteredStreamWriter::ReserveBytes(size_t size) {
6833 if (write_ptr_ + size > cur_range_.end) {
6834 // Assume the reservations are always < Delegate::GetNewBuffer().size(),
6835 // so that one single call to Extend() will definitely give enough headroom.
6836 Extend();
6837 PERFETTO_DCHECK(write_ptr_ + size <= cur_range_.end);
6838 }
6839 uint8_t* begin = write_ptr_;
6840 write_ptr_ += size;
6841 #if PERFETTO_DCHECK_IS_ON()
6842 memset(begin, 0, size);
6843 #endif
6844 return begin;
6845 }
6846
6847 } // namespace protozero
6848 // gen_amalgamated begin source: src/protozero/static_buffer.cc
6849 // gen_amalgamated begin header: include/perfetto/protozero/static_buffer.h
6850 /*
6851 * Copyright (C) 2019 The Android Open Source Project
6852 *
6853 * Licensed under the Apache License, Version 2.0 (the "License");
6854 * you may not use this file except in compliance with the License.
6855 * You may obtain a copy of the License at
6856 *
6857 * http://www.apache.org/licenses/LICENSE-2.0
6858 *
6859 * Unless required by applicable law or agreed to in writing, software
6860 * distributed under the License is distributed on an "AS IS" BASIS,
6861 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6862 * See the License for the specific language governing permissions and
6863 * limitations under the License.
6864 */
6865
6866 #ifndef INCLUDE_PERFETTO_PROTOZERO_STATIC_BUFFER_H_
6867 #define INCLUDE_PERFETTO_PROTOZERO_STATIC_BUFFER_H_
6868
6869 #include <memory>
6870 #include <string>
6871 #include <vector>
6872
6873 // gen_amalgamated expanded: #include "perfetto/base/export.h"
6874 // gen_amalgamated expanded: #include "perfetto/protozero/root_message.h"
6875 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_stream_writer.h"
6876
6877 namespace protozero {
6878
6879 class Message;
6880
6881 // A simple implementation of ScatteredStreamWriter::Delegate backed by a
6882 // fixed-size buffer. It doesn't support expansion. The caller needs to ensure
6883 // to never write more than the size of the buffer. Will CHECK() otherwise.
6884 class PERFETTO_EXPORT StaticBufferDelegate
6885 : public ScatteredStreamWriter::Delegate {
6886 public:
StaticBufferDelegate(uint8_t * buf,size_t len)6887 StaticBufferDelegate(uint8_t* buf, size_t len) : range_{buf, buf + len} {}
6888 ~StaticBufferDelegate() override;
6889
6890 // ScatteredStreamWriter::Delegate implementation.
6891 ContiguousMemoryRange GetNewBuffer() override;
6892
6893 ContiguousMemoryRange const range_;
6894 bool get_new_buffer_called_once_ = false;
6895 };
6896
6897 // Helper function to create protozero messages backed by a fixed-size buffer
6898 // in one line. You can write:
6899 // protozero::Static<protozero::MyMessage> msg(buf.data(), buf.size());
6900 // msg->set_stuff(...);
6901 // size_t bytes_encoded = msg.Finalize();
6902 template <typename T /* protozero::Message */>
6903 class StaticBuffered {
6904 public:
StaticBuffered(void * buf,size_t len)6905 StaticBuffered(void* buf, size_t len)
6906 : delegate_(reinterpret_cast<uint8_t*>(buf), len), writer_(&delegate_) {
6907 msg_.Reset(&writer_);
6908 }
6909
6910 // This can't be neither copied nor moved because Message hands out pointers
6911 // to itself when creating submessages.
6912 StaticBuffered(const StaticBuffered&) = delete;
6913 StaticBuffered& operator=(const StaticBuffered&) = delete;
6914 StaticBuffered(StaticBuffered&&) = delete;
6915 StaticBuffered& operator=(StaticBuffered&&) = delete;
6916
get()6917 T* get() { return &msg_; }
operator ->()6918 T* operator->() { return &msg_; }
6919
6920 // The lack of a size() method is deliberate. It's to prevent that one
6921 // accidentally calls size() before Finalize().
6922
6923 // Returns the number of encoded bytes (<= the size passed in the ctor).
Finalize()6924 size_t Finalize() {
6925 msg_.Finalize();
6926 return static_cast<size_t>(writer_.write_ptr() - delegate_.range_.begin);
6927 }
6928
6929 private:
6930 StaticBufferDelegate delegate_;
6931 ScatteredStreamWriter writer_;
6932 RootMessage<T> msg_;
6933 };
6934
6935 // Helper function to create stack-based protozero messages in one line.
6936 // You can write:
6937 // protozero::StackBuffered<protozero::MyMessage, 16> msg;
6938 // msg->set_stuff(...);
6939 // size_t bytes_encoded = msg.Finalize();
6940 template <typename T /* protozero::Message */, size_t N>
6941 class StackBuffered : public StaticBuffered<T> {
6942 public:
StackBuffered()6943 StackBuffered() : StaticBuffered<T>(&buf_[0], N) {}
6944
6945 private:
6946 uint8_t buf_[N]; // Deliberately not initialized.
6947 };
6948
6949 } // namespace protozero
6950
6951 #endif // INCLUDE_PERFETTO_PROTOZERO_STATIC_BUFFER_H_
6952 /*
6953 * Copyright (C) 2019 The Android Open Source Project
6954 *
6955 * Licensed under the Apache License, Version 2.0 (the "License");
6956 * you may not use this file except in compliance with the License.
6957 * You may obtain a copy of the License at
6958 *
6959 * http://www.apache.org/licenses/LICENSE-2.0
6960 *
6961 * Unless required by applicable law or agreed to in writing, software
6962 * distributed under the License is distributed on an "AS IS" BASIS,
6963 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6964 * See the License for the specific language governing permissions and
6965 * limitations under the License.
6966 */
6967
6968 // gen_amalgamated expanded: #include "perfetto/protozero/static_buffer.h"
6969
6970 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
6971
6972 namespace protozero {
6973
6974 StaticBufferDelegate::~StaticBufferDelegate() = default;
6975
GetNewBuffer()6976 ContiguousMemoryRange StaticBufferDelegate::GetNewBuffer() {
6977 if (get_new_buffer_called_once_) {
6978 // This is the 2nd time GetNewBuffer is called. The estimate is wrong. We
6979 // shouldn't try to grow the buffer after the initial call.
6980 PERFETTO_FATAL("Static buffer too small");
6981 }
6982 get_new_buffer_called_once_ = true;
6983 return range_;
6984 }
6985
6986 } // namespace protozero
6987 // gen_amalgamated begin source: src/protozero/virtual_destructors.cc
6988 /*
6989 * Copyright (C) 2019 The Android Open Source Project
6990 *
6991 * Licensed under the Apache License, Version 2.0 (the "License");
6992 * you may not use this file except in compliance with the License.
6993 * You may obtain a copy of the License at
6994 *
6995 * http://www.apache.org/licenses/LICENSE-2.0
6996 *
6997 * Unless required by applicable law or agreed to in writing, software
6998 * distributed under the License is distributed on an "AS IS" BASIS,
6999 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
7000 * See the License for the specific language governing permissions and
7001 * limitations under the License.
7002 */
7003
7004 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
7005
7006 namespace protozero {
7007
7008 CppMessageObj::~CppMessageObj() = default;
7009
7010 } // namespace protozero
7011 // gen_amalgamated begin source: gen/protos/perfetto/common/android_log_constants.gen.cc
7012 // gen_amalgamated begin header: gen/protos/perfetto/common/android_log_constants.gen.h
7013 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
7014 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_ANDROID_LOG_CONSTANTS_PROTO_CPP_H_
7015 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_ANDROID_LOG_CONSTANTS_PROTO_CPP_H_
7016
7017 #include <stdint.h>
7018 #include <bitset>
7019 #include <vector>
7020 #include <string>
7021 #include <type_traits>
7022
7023 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
7024 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
7025 // gen_amalgamated expanded: #include "perfetto/base/export.h"
7026
7027 namespace perfetto {
7028 namespace protos {
7029 namespace gen {
7030 enum AndroidLogId : int;
7031 enum AndroidLogPriority : int;
7032 } // namespace perfetto
7033 } // namespace protos
7034 } // namespace gen
7035
7036 namespace protozero {
7037 class Message;
7038 } // namespace protozero
7039
7040 namespace perfetto {
7041 namespace protos {
7042 namespace gen {
7043 enum AndroidLogId : int {
7044 LID_DEFAULT = 0,
7045 LID_RADIO = 1,
7046 LID_EVENTS = 2,
7047 LID_SYSTEM = 3,
7048 LID_CRASH = 4,
7049 LID_STATS = 5,
7050 LID_SECURITY = 6,
7051 LID_KERNEL = 7,
7052 };
7053 enum AndroidLogPriority : int {
7054 PRIO_UNSPECIFIED = 0,
7055 PRIO_UNUSED = 1,
7056 PRIO_VERBOSE = 2,
7057 PRIO_DEBUG = 3,
7058 PRIO_INFO = 4,
7059 PRIO_WARN = 5,
7060 PRIO_ERROR = 6,
7061 PRIO_FATAL = 7,
7062 };
7063 } // namespace perfetto
7064 } // namespace protos
7065 } // namespace gen
7066
7067 #endif // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_ANDROID_LOG_CONSTANTS_PROTO_CPP_H_
7068 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
7069 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
7070 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
7071 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
7072 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
7073 #pragma GCC diagnostic push
7074 #pragma GCC diagnostic ignored "-Wfloat-equal"
7075 // gen_amalgamated expanded: #include "protos/perfetto/common/android_log_constants.gen.h"
7076
7077 namespace perfetto {
7078 namespace protos {
7079 namespace gen {
7080 } // namespace perfetto
7081 } // namespace protos
7082 } // namespace gen
7083 #pragma GCC diagnostic pop
7084 // gen_amalgamated begin source: gen/protos/perfetto/common/builtin_clock.gen.cc
7085 // gen_amalgamated begin header: gen/protos/perfetto/common/builtin_clock.gen.h
7086 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
7087 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_BUILTIN_CLOCK_PROTO_CPP_H_
7088 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_BUILTIN_CLOCK_PROTO_CPP_H_
7089
7090 #include <stdint.h>
7091 #include <bitset>
7092 #include <vector>
7093 #include <string>
7094 #include <type_traits>
7095
7096 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
7097 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
7098 // gen_amalgamated expanded: #include "perfetto/base/export.h"
7099
7100 namespace perfetto {
7101 namespace protos {
7102 namespace gen {
7103 enum BuiltinClock : int;
7104 } // namespace perfetto
7105 } // namespace protos
7106 } // namespace gen
7107
7108 namespace protozero {
7109 class Message;
7110 } // namespace protozero
7111
7112 namespace perfetto {
7113 namespace protos {
7114 namespace gen {
7115 enum BuiltinClock : int {
7116 BUILTIN_CLOCK_UNKNOWN = 0,
7117 BUILTIN_CLOCK_REALTIME = 1,
7118 BUILTIN_CLOCK_REALTIME_COARSE = 2,
7119 BUILTIN_CLOCK_MONOTONIC = 3,
7120 BUILTIN_CLOCK_MONOTONIC_COARSE = 4,
7121 BUILTIN_CLOCK_MONOTONIC_RAW = 5,
7122 BUILTIN_CLOCK_BOOTTIME = 6,
7123 BUILTIN_CLOCK_MAX_ID = 63,
7124 };
7125 } // namespace perfetto
7126 } // namespace protos
7127 } // namespace gen
7128
7129 #endif // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_BUILTIN_CLOCK_PROTO_CPP_H_
7130 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
7131 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
7132 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
7133 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
7134 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
7135 #pragma GCC diagnostic push
7136 #pragma GCC diagnostic ignored "-Wfloat-equal"
7137 // gen_amalgamated expanded: #include "protos/perfetto/common/builtin_clock.gen.h"
7138
7139 namespace perfetto {
7140 namespace protos {
7141 namespace gen {
7142 } // namespace perfetto
7143 } // namespace protos
7144 } // namespace gen
7145 #pragma GCC diagnostic pop
7146 // gen_amalgamated begin source: gen/protos/perfetto/common/commit_data_request.gen.cc
7147 // gen_amalgamated begin header: gen/protos/perfetto/common/commit_data_request.gen.h
7148 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
7149 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_COMMIT_DATA_REQUEST_PROTO_CPP_H_
7150 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_COMMIT_DATA_REQUEST_PROTO_CPP_H_
7151
7152 #include <stdint.h>
7153 #include <bitset>
7154 #include <vector>
7155 #include <string>
7156 #include <type_traits>
7157
7158 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
7159 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
7160 // gen_amalgamated expanded: #include "perfetto/base/export.h"
7161
7162 namespace perfetto {
7163 namespace protos {
7164 namespace gen {
7165 class CommitDataRequest;
7166 class CommitDataRequest_ChunkToPatch;
7167 class CommitDataRequest_ChunkToPatch_Patch;
7168 class CommitDataRequest_ChunksToMove;
7169 } // namespace perfetto
7170 } // namespace protos
7171 } // namespace gen
7172
7173 namespace protozero {
7174 class Message;
7175 } // namespace protozero
7176
7177 namespace perfetto {
7178 namespace protos {
7179 namespace gen {
7180
7181 class PERFETTO_EXPORT CommitDataRequest : public ::protozero::CppMessageObj {
7182 public:
7183 using ChunksToMove = CommitDataRequest_ChunksToMove;
7184 using ChunkToPatch = CommitDataRequest_ChunkToPatch;
7185 enum FieldNumbers {
7186 kChunksToMoveFieldNumber = 1,
7187 kChunksToPatchFieldNumber = 2,
7188 kFlushRequestIdFieldNumber = 3,
7189 };
7190
7191 CommitDataRequest();
7192 ~CommitDataRequest() override;
7193 CommitDataRequest(CommitDataRequest&&) noexcept;
7194 CommitDataRequest& operator=(CommitDataRequest&&);
7195 CommitDataRequest(const CommitDataRequest&);
7196 CommitDataRequest& operator=(const CommitDataRequest&);
7197 bool operator==(const CommitDataRequest&) const;
operator !=(const CommitDataRequest & other) const7198 bool operator!=(const CommitDataRequest& other) const { return !(*this == other); }
7199
7200 bool ParseFromArray(const void*, size_t) override;
7201 std::string SerializeAsString() const override;
7202 std::vector<uint8_t> SerializeAsArray() const override;
7203 void Serialize(::protozero::Message*) const;
7204
chunks_to_move_size() const7205 int chunks_to_move_size() const { return static_cast<int>(chunks_to_move_.size()); }
chunks_to_move() const7206 const std::vector<CommitDataRequest_ChunksToMove>& chunks_to_move() const { return chunks_to_move_; }
mutable_chunks_to_move()7207 std::vector<CommitDataRequest_ChunksToMove>* mutable_chunks_to_move() { return &chunks_to_move_; }
clear_chunks_to_move()7208 void clear_chunks_to_move() { chunks_to_move_.clear(); }
add_chunks_to_move()7209 CommitDataRequest_ChunksToMove* add_chunks_to_move() { chunks_to_move_.emplace_back(); return &chunks_to_move_.back(); }
7210
chunks_to_patch_size() const7211 int chunks_to_patch_size() const { return static_cast<int>(chunks_to_patch_.size()); }
chunks_to_patch() const7212 const std::vector<CommitDataRequest_ChunkToPatch>& chunks_to_patch() const { return chunks_to_patch_; }
mutable_chunks_to_patch()7213 std::vector<CommitDataRequest_ChunkToPatch>* mutable_chunks_to_patch() { return &chunks_to_patch_; }
clear_chunks_to_patch()7214 void clear_chunks_to_patch() { chunks_to_patch_.clear(); }
add_chunks_to_patch()7215 CommitDataRequest_ChunkToPatch* add_chunks_to_patch() { chunks_to_patch_.emplace_back(); return &chunks_to_patch_.back(); }
7216
has_flush_request_id() const7217 bool has_flush_request_id() const { return _has_field_[3]; }
flush_request_id() const7218 uint64_t flush_request_id() const { return flush_request_id_; }
set_flush_request_id(uint64_t value)7219 void set_flush_request_id(uint64_t value) { flush_request_id_ = value; _has_field_.set(3); }
7220
7221 private:
7222 std::vector<CommitDataRequest_ChunksToMove> chunks_to_move_;
7223 std::vector<CommitDataRequest_ChunkToPatch> chunks_to_patch_;
7224 uint64_t flush_request_id_{};
7225
7226 // Allows to preserve unknown protobuf fields for compatibility
7227 // with future versions of .proto files.
7228 std::string unknown_fields_;
7229
7230 std::bitset<4> _has_field_{};
7231 };
7232
7233
7234 class PERFETTO_EXPORT CommitDataRequest_ChunkToPatch : public ::protozero::CppMessageObj {
7235 public:
7236 using Patch = CommitDataRequest_ChunkToPatch_Patch;
7237 enum FieldNumbers {
7238 kTargetBufferFieldNumber = 1,
7239 kWriterIdFieldNumber = 2,
7240 kChunkIdFieldNumber = 3,
7241 kPatchesFieldNumber = 4,
7242 kHasMorePatchesFieldNumber = 5,
7243 };
7244
7245 CommitDataRequest_ChunkToPatch();
7246 ~CommitDataRequest_ChunkToPatch() override;
7247 CommitDataRequest_ChunkToPatch(CommitDataRequest_ChunkToPatch&&) noexcept;
7248 CommitDataRequest_ChunkToPatch& operator=(CommitDataRequest_ChunkToPatch&&);
7249 CommitDataRequest_ChunkToPatch(const CommitDataRequest_ChunkToPatch&);
7250 CommitDataRequest_ChunkToPatch& operator=(const CommitDataRequest_ChunkToPatch&);
7251 bool operator==(const CommitDataRequest_ChunkToPatch&) const;
operator !=(const CommitDataRequest_ChunkToPatch & other) const7252 bool operator!=(const CommitDataRequest_ChunkToPatch& other) const { return !(*this == other); }
7253
7254 bool ParseFromArray(const void*, size_t) override;
7255 std::string SerializeAsString() const override;
7256 std::vector<uint8_t> SerializeAsArray() const override;
7257 void Serialize(::protozero::Message*) const;
7258
has_target_buffer() const7259 bool has_target_buffer() const { return _has_field_[1]; }
target_buffer() const7260 uint32_t target_buffer() const { return target_buffer_; }
set_target_buffer(uint32_t value)7261 void set_target_buffer(uint32_t value) { target_buffer_ = value; _has_field_.set(1); }
7262
has_writer_id() const7263 bool has_writer_id() const { return _has_field_[2]; }
writer_id() const7264 uint32_t writer_id() const { return writer_id_; }
set_writer_id(uint32_t value)7265 void set_writer_id(uint32_t value) { writer_id_ = value; _has_field_.set(2); }
7266
has_chunk_id() const7267 bool has_chunk_id() const { return _has_field_[3]; }
chunk_id() const7268 uint32_t chunk_id() const { return chunk_id_; }
set_chunk_id(uint32_t value)7269 void set_chunk_id(uint32_t value) { chunk_id_ = value; _has_field_.set(3); }
7270
patches_size() const7271 int patches_size() const { return static_cast<int>(patches_.size()); }
patches() const7272 const std::vector<CommitDataRequest_ChunkToPatch_Patch>& patches() const { return patches_; }
mutable_patches()7273 std::vector<CommitDataRequest_ChunkToPatch_Patch>* mutable_patches() { return &patches_; }
clear_patches()7274 void clear_patches() { patches_.clear(); }
add_patches()7275 CommitDataRequest_ChunkToPatch_Patch* add_patches() { patches_.emplace_back(); return &patches_.back(); }
7276
has_has_more_patches() const7277 bool has_has_more_patches() const { return _has_field_[5]; }
has_more_patches() const7278 bool has_more_patches() const { return has_more_patches_; }
set_has_more_patches(bool value)7279 void set_has_more_patches(bool value) { has_more_patches_ = value; _has_field_.set(5); }
7280
7281 private:
7282 uint32_t target_buffer_{};
7283 uint32_t writer_id_{};
7284 uint32_t chunk_id_{};
7285 std::vector<CommitDataRequest_ChunkToPatch_Patch> patches_;
7286 bool has_more_patches_{};
7287
7288 // Allows to preserve unknown protobuf fields for compatibility
7289 // with future versions of .proto files.
7290 std::string unknown_fields_;
7291
7292 std::bitset<6> _has_field_{};
7293 };
7294
7295
7296 class PERFETTO_EXPORT CommitDataRequest_ChunkToPatch_Patch : public ::protozero::CppMessageObj {
7297 public:
7298 enum FieldNumbers {
7299 kOffsetFieldNumber = 1,
7300 kDataFieldNumber = 2,
7301 };
7302
7303 CommitDataRequest_ChunkToPatch_Patch();
7304 ~CommitDataRequest_ChunkToPatch_Patch() override;
7305 CommitDataRequest_ChunkToPatch_Patch(CommitDataRequest_ChunkToPatch_Patch&&) noexcept;
7306 CommitDataRequest_ChunkToPatch_Patch& operator=(CommitDataRequest_ChunkToPatch_Patch&&);
7307 CommitDataRequest_ChunkToPatch_Patch(const CommitDataRequest_ChunkToPatch_Patch&);
7308 CommitDataRequest_ChunkToPatch_Patch& operator=(const CommitDataRequest_ChunkToPatch_Patch&);
7309 bool operator==(const CommitDataRequest_ChunkToPatch_Patch&) const;
operator !=(const CommitDataRequest_ChunkToPatch_Patch & other) const7310 bool operator!=(const CommitDataRequest_ChunkToPatch_Patch& other) const { return !(*this == other); }
7311
7312 bool ParseFromArray(const void*, size_t) override;
7313 std::string SerializeAsString() const override;
7314 std::vector<uint8_t> SerializeAsArray() const override;
7315 void Serialize(::protozero::Message*) const;
7316
has_offset() const7317 bool has_offset() const { return _has_field_[1]; }
offset() const7318 uint32_t offset() const { return offset_; }
set_offset(uint32_t value)7319 void set_offset(uint32_t value) { offset_ = value; _has_field_.set(1); }
7320
has_data() const7321 bool has_data() const { return _has_field_[2]; }
data() const7322 const std::string& data() const { return data_; }
set_data(const std::string & value)7323 void set_data(const std::string& value) { data_ = value; _has_field_.set(2); }
set_data(const void * p,size_t s)7324 void set_data(const void* p, size_t s) { data_.assign(reinterpret_cast<const char*>(p), s); _has_field_.set(2); }
7325
7326 private:
7327 uint32_t offset_{};
7328 std::string data_{};
7329
7330 // Allows to preserve unknown protobuf fields for compatibility
7331 // with future versions of .proto files.
7332 std::string unknown_fields_;
7333
7334 std::bitset<3> _has_field_{};
7335 };
7336
7337
7338 class PERFETTO_EXPORT CommitDataRequest_ChunksToMove : public ::protozero::CppMessageObj {
7339 public:
7340 enum FieldNumbers {
7341 kPageFieldNumber = 1,
7342 kChunkFieldNumber = 2,
7343 kTargetBufferFieldNumber = 3,
7344 };
7345
7346 CommitDataRequest_ChunksToMove();
7347 ~CommitDataRequest_ChunksToMove() override;
7348 CommitDataRequest_ChunksToMove(CommitDataRequest_ChunksToMove&&) noexcept;
7349 CommitDataRequest_ChunksToMove& operator=(CommitDataRequest_ChunksToMove&&);
7350 CommitDataRequest_ChunksToMove(const CommitDataRequest_ChunksToMove&);
7351 CommitDataRequest_ChunksToMove& operator=(const CommitDataRequest_ChunksToMove&);
7352 bool operator==(const CommitDataRequest_ChunksToMove&) const;
operator !=(const CommitDataRequest_ChunksToMove & other) const7353 bool operator!=(const CommitDataRequest_ChunksToMove& other) const { return !(*this == other); }
7354
7355 bool ParseFromArray(const void*, size_t) override;
7356 std::string SerializeAsString() const override;
7357 std::vector<uint8_t> SerializeAsArray() const override;
7358 void Serialize(::protozero::Message*) const;
7359
has_page() const7360 bool has_page() const { return _has_field_[1]; }
page() const7361 uint32_t page() const { return page_; }
set_page(uint32_t value)7362 void set_page(uint32_t value) { page_ = value; _has_field_.set(1); }
7363
has_chunk() const7364 bool has_chunk() const { return _has_field_[2]; }
chunk() const7365 uint32_t chunk() const { return chunk_; }
set_chunk(uint32_t value)7366 void set_chunk(uint32_t value) { chunk_ = value; _has_field_.set(2); }
7367
has_target_buffer() const7368 bool has_target_buffer() const { return _has_field_[3]; }
target_buffer() const7369 uint32_t target_buffer() const { return target_buffer_; }
set_target_buffer(uint32_t value)7370 void set_target_buffer(uint32_t value) { target_buffer_ = value; _has_field_.set(3); }
7371
7372 private:
7373 uint32_t page_{};
7374 uint32_t chunk_{};
7375 uint32_t target_buffer_{};
7376
7377 // Allows to preserve unknown protobuf fields for compatibility
7378 // with future versions of .proto files.
7379 std::string unknown_fields_;
7380
7381 std::bitset<4> _has_field_{};
7382 };
7383
7384 } // namespace perfetto
7385 } // namespace protos
7386 } // namespace gen
7387
7388 #endif // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_COMMIT_DATA_REQUEST_PROTO_CPP_H_
7389 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
7390 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
7391 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
7392 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
7393 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
7394 #pragma GCC diagnostic push
7395 #pragma GCC diagnostic ignored "-Wfloat-equal"
7396 // gen_amalgamated expanded: #include "protos/perfetto/common/commit_data_request.gen.h"
7397
7398 namespace perfetto {
7399 namespace protos {
7400 namespace gen {
7401
7402 CommitDataRequest::CommitDataRequest() = default;
7403 CommitDataRequest::~CommitDataRequest() = default;
7404 CommitDataRequest::CommitDataRequest(const CommitDataRequest&) = default;
7405 CommitDataRequest& CommitDataRequest::operator=(const CommitDataRequest&) = default;
7406 CommitDataRequest::CommitDataRequest(CommitDataRequest&&) noexcept = default;
7407 CommitDataRequest& CommitDataRequest::operator=(CommitDataRequest&&) = default;
7408
operator ==(const CommitDataRequest & other) const7409 bool CommitDataRequest::operator==(const CommitDataRequest& other) const {
7410 return unknown_fields_ == other.unknown_fields_
7411 && chunks_to_move_ == other.chunks_to_move_
7412 && chunks_to_patch_ == other.chunks_to_patch_
7413 && flush_request_id_ == other.flush_request_id_;
7414 }
7415
ParseFromArray(const void * raw,size_t size)7416 bool CommitDataRequest::ParseFromArray(const void* raw, size_t size) {
7417 chunks_to_move_.clear();
7418 chunks_to_patch_.clear();
7419 unknown_fields_.clear();
7420 bool packed_error = false;
7421
7422 ::protozero::ProtoDecoder dec(raw, size);
7423 for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
7424 if (field.id() < _has_field_.size()) {
7425 _has_field_.set(field.id());
7426 }
7427 switch (field.id()) {
7428 case 1 /* chunks_to_move */:
7429 chunks_to_move_.emplace_back();
7430 chunks_to_move_.back().ParseFromString(field.as_std_string());
7431 break;
7432 case 2 /* chunks_to_patch */:
7433 chunks_to_patch_.emplace_back();
7434 chunks_to_patch_.back().ParseFromString(field.as_std_string());
7435 break;
7436 case 3 /* flush_request_id */:
7437 field.get(&flush_request_id_);
7438 break;
7439 default:
7440 field.SerializeAndAppendTo(&unknown_fields_);
7441 break;
7442 }
7443 }
7444 return !packed_error && !dec.bytes_left();
7445 }
7446
SerializeAsString() const7447 std::string CommitDataRequest::SerializeAsString() const {
7448 ::protozero::HeapBuffered<::protozero::Message> msg;
7449 Serialize(msg.get());
7450 return msg.SerializeAsString();
7451 }
7452
SerializeAsArray() const7453 std::vector<uint8_t> CommitDataRequest::SerializeAsArray() const {
7454 ::protozero::HeapBuffered<::protozero::Message> msg;
7455 Serialize(msg.get());
7456 return msg.SerializeAsArray();
7457 }
7458
Serialize(::protozero::Message * msg) const7459 void CommitDataRequest::Serialize(::protozero::Message* msg) const {
7460 // Field 1: chunks_to_move
7461 for (auto& it : chunks_to_move_) {
7462 it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
7463 }
7464
7465 // Field 2: chunks_to_patch
7466 for (auto& it : chunks_to_patch_) {
7467 it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
7468 }
7469
7470 // Field 3: flush_request_id
7471 if (_has_field_[3]) {
7472 msg->AppendVarInt(3, flush_request_id_);
7473 }
7474
7475 msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
7476 }
7477
7478
7479 CommitDataRequest_ChunkToPatch::CommitDataRequest_ChunkToPatch() = default;
7480 CommitDataRequest_ChunkToPatch::~CommitDataRequest_ChunkToPatch() = default;
7481 CommitDataRequest_ChunkToPatch::CommitDataRequest_ChunkToPatch(const CommitDataRequest_ChunkToPatch&) = default;
7482 CommitDataRequest_ChunkToPatch& CommitDataRequest_ChunkToPatch::operator=(const CommitDataRequest_ChunkToPatch&) = default;
7483 CommitDataRequest_ChunkToPatch::CommitDataRequest_ChunkToPatch(CommitDataRequest_ChunkToPatch&&) noexcept = default;
7484 CommitDataRequest_ChunkToPatch& CommitDataRequest_ChunkToPatch::operator=(CommitDataRequest_ChunkToPatch&&) = default;
7485
operator ==(const CommitDataRequest_ChunkToPatch & other) const7486 bool CommitDataRequest_ChunkToPatch::operator==(const CommitDataRequest_ChunkToPatch& other) const {
7487 return unknown_fields_ == other.unknown_fields_
7488 && target_buffer_ == other.target_buffer_
7489 && writer_id_ == other.writer_id_
7490 && chunk_id_ == other.chunk_id_
7491 && patches_ == other.patches_
7492 && has_more_patches_ == other.has_more_patches_;
7493 }
7494
ParseFromArray(const void * raw,size_t size)7495 bool CommitDataRequest_ChunkToPatch::ParseFromArray(const void* raw, size_t size) {
7496 patches_.clear();
7497 unknown_fields_.clear();
7498 bool packed_error = false;
7499
7500 ::protozero::ProtoDecoder dec(raw, size);
7501 for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
7502 if (field.id() < _has_field_.size()) {
7503 _has_field_.set(field.id());
7504 }
7505 switch (field.id()) {
7506 case 1 /* target_buffer */:
7507 field.get(&target_buffer_);
7508 break;
7509 case 2 /* writer_id */:
7510 field.get(&writer_id_);
7511 break;
7512 case 3 /* chunk_id */:
7513 field.get(&chunk_id_);
7514 break;
7515 case 4 /* patches */:
7516 patches_.emplace_back();
7517 patches_.back().ParseFromString(field.as_std_string());
7518 break;
7519 case 5 /* has_more_patches */:
7520 field.get(&has_more_patches_);
7521 break;
7522 default:
7523 field.SerializeAndAppendTo(&unknown_fields_);
7524 break;
7525 }
7526 }
7527 return !packed_error && !dec.bytes_left();
7528 }
7529
SerializeAsString() const7530 std::string CommitDataRequest_ChunkToPatch::SerializeAsString() const {
7531 ::protozero::HeapBuffered<::protozero::Message> msg;
7532 Serialize(msg.get());
7533 return msg.SerializeAsString();
7534 }
7535
SerializeAsArray() const7536 std::vector<uint8_t> CommitDataRequest_ChunkToPatch::SerializeAsArray() const {
7537 ::protozero::HeapBuffered<::protozero::Message> msg;
7538 Serialize(msg.get());
7539 return msg.SerializeAsArray();
7540 }
7541
Serialize(::protozero::Message * msg) const7542 void CommitDataRequest_ChunkToPatch::Serialize(::protozero::Message* msg) const {
7543 // Field 1: target_buffer
7544 if (_has_field_[1]) {
7545 msg->AppendVarInt(1, target_buffer_);
7546 }
7547
7548 // Field 2: writer_id
7549 if (_has_field_[2]) {
7550 msg->AppendVarInt(2, writer_id_);
7551 }
7552
7553 // Field 3: chunk_id
7554 if (_has_field_[3]) {
7555 msg->AppendVarInt(3, chunk_id_);
7556 }
7557
7558 // Field 4: patches
7559 for (auto& it : patches_) {
7560 it.Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
7561 }
7562
7563 // Field 5: has_more_patches
7564 if (_has_field_[5]) {
7565 msg->AppendTinyVarInt(5, has_more_patches_);
7566 }
7567
7568 msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
7569 }
7570
7571
7572 CommitDataRequest_ChunkToPatch_Patch::CommitDataRequest_ChunkToPatch_Patch() = default;
7573 CommitDataRequest_ChunkToPatch_Patch::~CommitDataRequest_ChunkToPatch_Patch() = default;
7574 CommitDataRequest_ChunkToPatch_Patch::CommitDataRequest_ChunkToPatch_Patch(const CommitDataRequest_ChunkToPatch_Patch&) = default;
7575 CommitDataRequest_ChunkToPatch_Patch& CommitDataRequest_ChunkToPatch_Patch::operator=(const CommitDataRequest_ChunkToPatch_Patch&) = default;
7576 CommitDataRequest_ChunkToPatch_Patch::CommitDataRequest_ChunkToPatch_Patch(CommitDataRequest_ChunkToPatch_Patch&&) noexcept = default;
7577 CommitDataRequest_ChunkToPatch_Patch& CommitDataRequest_ChunkToPatch_Patch::operator=(CommitDataRequest_ChunkToPatch_Patch&&) = default;
7578
operator ==(const CommitDataRequest_ChunkToPatch_Patch & other) const7579 bool CommitDataRequest_ChunkToPatch_Patch::operator==(const CommitDataRequest_ChunkToPatch_Patch& other) const {
7580 return unknown_fields_ == other.unknown_fields_
7581 && offset_ == other.offset_
7582 && data_ == other.data_;
7583 }
7584
ParseFromArray(const void * raw,size_t size)7585 bool CommitDataRequest_ChunkToPatch_Patch::ParseFromArray(const void* raw, size_t size) {
7586 unknown_fields_.clear();
7587 bool packed_error = false;
7588
7589 ::protozero::ProtoDecoder dec(raw, size);
7590 for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
7591 if (field.id() < _has_field_.size()) {
7592 _has_field_.set(field.id());
7593 }
7594 switch (field.id()) {
7595 case 1 /* offset */:
7596 field.get(&offset_);
7597 break;
7598 case 2 /* data */:
7599 field.get(&data_);
7600 break;
7601 default:
7602 field.SerializeAndAppendTo(&unknown_fields_);
7603 break;
7604 }
7605 }
7606 return !packed_error && !dec.bytes_left();
7607 }
7608
SerializeAsString() const7609 std::string CommitDataRequest_ChunkToPatch_Patch::SerializeAsString() const {
7610 ::protozero::HeapBuffered<::protozero::Message> msg;
7611 Serialize(msg.get());
7612 return msg.SerializeAsString();
7613 }
7614
SerializeAsArray() const7615 std::vector<uint8_t> CommitDataRequest_ChunkToPatch_Patch::SerializeAsArray() const {
7616 ::protozero::HeapBuffered<::protozero::Message> msg;
7617 Serialize(msg.get());
7618 return msg.SerializeAsArray();
7619 }
7620
Serialize(::protozero::Message * msg) const7621 void CommitDataRequest_ChunkToPatch_Patch::Serialize(::protozero::Message* msg) const {
7622 // Field 1: offset
7623 if (_has_field_[1]) {
7624 msg->AppendVarInt(1, offset_);
7625 }
7626
7627 // Field 2: data
7628 if (_has_field_[2]) {
7629 msg->AppendString(2, data_);
7630 }
7631
7632 msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
7633 }
7634
7635
7636 CommitDataRequest_ChunksToMove::CommitDataRequest_ChunksToMove() = default;
7637 CommitDataRequest_ChunksToMove::~CommitDataRequest_ChunksToMove() = default;
7638 CommitDataRequest_ChunksToMove::CommitDataRequest_ChunksToMove(const CommitDataRequest_ChunksToMove&) = default;
7639 CommitDataRequest_ChunksToMove& CommitDataRequest_ChunksToMove::operator=(const CommitDataRequest_ChunksToMove&) = default;
7640 CommitDataRequest_ChunksToMove::CommitDataRequest_ChunksToMove(CommitDataRequest_ChunksToMove&&) noexcept = default;
7641 CommitDataRequest_ChunksToMove& CommitDataRequest_ChunksToMove::operator=(CommitDataRequest_ChunksToMove&&) = default;
7642
operator ==(const CommitDataRequest_ChunksToMove & other) const7643 bool CommitDataRequest_ChunksToMove::operator==(const CommitDataRequest_ChunksToMove& other) const {
7644 return unknown_fields_ == other.unknown_fields_
7645 && page_ == other.page_
7646 && chunk_ == other.chunk_
7647 && target_buffer_ == other.target_buffer_;
7648 }
7649
ParseFromArray(const void * raw,size_t size)7650 bool CommitDataRequest_ChunksToMove::ParseFromArray(const void* raw, size_t size) {
7651 unknown_fields_.clear();
7652 bool packed_error = false;
7653
7654 ::protozero::ProtoDecoder dec(raw, size);
7655 for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
7656 if (field.id() < _has_field_.size()) {
7657 _has_field_.set(field.id());
7658 }
7659 switch (field.id()) {
7660 case 1 /* page */:
7661 field.get(&page_);
7662 break;
7663 case 2 /* chunk */:
7664 field.get(&chunk_);
7665 break;
7666 case 3 /* target_buffer */:
7667 field.get(&target_buffer_);
7668 break;
7669 default:
7670 field.SerializeAndAppendTo(&unknown_fields_);
7671 break;
7672 }
7673 }
7674 return !packed_error && !dec.bytes_left();
7675 }
7676
SerializeAsString() const7677 std::string CommitDataRequest_ChunksToMove::SerializeAsString() const {
7678 ::protozero::HeapBuffered<::protozero::Message> msg;
7679 Serialize(msg.get());
7680 return msg.SerializeAsString();
7681 }
7682
SerializeAsArray() const7683 std::vector<uint8_t> CommitDataRequest_ChunksToMove::SerializeAsArray() const {
7684 ::protozero::HeapBuffered<::protozero::Message> msg;
7685 Serialize(msg.get());
7686 return msg.SerializeAsArray();
7687 }
7688
Serialize(::protozero::Message * msg) const7689 void CommitDataRequest_ChunksToMove::Serialize(::protozero::Message* msg) const {
7690 // Field 1: page
7691 if (_has_field_[1]) {
7692 msg->AppendVarInt(1, page_);
7693 }
7694
7695 // Field 2: chunk
7696 if (_has_field_[2]) {
7697 msg->AppendVarInt(2, chunk_);
7698 }
7699
7700 // Field 3: target_buffer
7701 if (_has_field_[3]) {
7702 msg->AppendVarInt(3, target_buffer_);
7703 }
7704
7705 msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
7706 }
7707
7708 } // namespace perfetto
7709 } // namespace protos
7710 } // namespace gen
7711 #pragma GCC diagnostic pop
7712 // gen_amalgamated begin source: gen/protos/perfetto/common/data_source_descriptor.gen.cc
7713 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
7714 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
7715 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
7716 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
7717 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
7718 #pragma GCC diagnostic push
7719 #pragma GCC diagnostic ignored "-Wfloat-equal"
7720 // gen_amalgamated expanded: #include "protos/perfetto/common/data_source_descriptor.gen.h"
7721
7722 namespace perfetto {
7723 namespace protos {
7724 namespace gen {
7725
7726 DataSourceDescriptor::DataSourceDescriptor() = default;
7727 DataSourceDescriptor::~DataSourceDescriptor() = default;
7728 DataSourceDescriptor::DataSourceDescriptor(const DataSourceDescriptor&) = default;
7729 DataSourceDescriptor& DataSourceDescriptor::operator=(const DataSourceDescriptor&) = default;
7730 DataSourceDescriptor::DataSourceDescriptor(DataSourceDescriptor&&) noexcept = default;
7731 DataSourceDescriptor& DataSourceDescriptor::operator=(DataSourceDescriptor&&) = default;
7732
operator ==(const DataSourceDescriptor & other) const7733 bool DataSourceDescriptor::operator==(const DataSourceDescriptor& other) const {
7734 return unknown_fields_ == other.unknown_fields_
7735 && name_ == other.name_
7736 && will_notify_on_stop_ == other.will_notify_on_stop_
7737 && will_notify_on_start_ == other.will_notify_on_start_
7738 && handles_incremental_state_clear_ == other.handles_incremental_state_clear_
7739 && gpu_counter_descriptor_ == other.gpu_counter_descriptor_
7740 && track_event_descriptor_ == other.track_event_descriptor_;
7741 }
7742
ParseFromArray(const void * raw,size_t size)7743 bool DataSourceDescriptor::ParseFromArray(const void* raw, size_t size) {
7744 unknown_fields_.clear();
7745 bool packed_error = false;
7746
7747 ::protozero::ProtoDecoder dec(raw, size);
7748 for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
7749 if (field.id() < _has_field_.size()) {
7750 _has_field_.set(field.id());
7751 }
7752 switch (field.id()) {
7753 case 1 /* name */:
7754 field.get(&name_);
7755 break;
7756 case 2 /* will_notify_on_stop */:
7757 field.get(&will_notify_on_stop_);
7758 break;
7759 case 3 /* will_notify_on_start */:
7760 field.get(&will_notify_on_start_);
7761 break;
7762 case 4 /* handles_incremental_state_clear */:
7763 field.get(&handles_incremental_state_clear_);
7764 break;
7765 case 5 /* gpu_counter_descriptor */:
7766 gpu_counter_descriptor_ = field.as_std_string();
7767 break;
7768 case 6 /* track_event_descriptor */:
7769 track_event_descriptor_ = field.as_std_string();
7770 break;
7771 default:
7772 field.SerializeAndAppendTo(&unknown_fields_);
7773 break;
7774 }
7775 }
7776 return !packed_error && !dec.bytes_left();
7777 }
7778
SerializeAsString() const7779 std::string DataSourceDescriptor::SerializeAsString() const {
7780 ::protozero::HeapBuffered<::protozero::Message> msg;
7781 Serialize(msg.get());
7782 return msg.SerializeAsString();
7783 }
7784
SerializeAsArray() const7785 std::vector<uint8_t> DataSourceDescriptor::SerializeAsArray() const {
7786 ::protozero::HeapBuffered<::protozero::Message> msg;
7787 Serialize(msg.get());
7788 return msg.SerializeAsArray();
7789 }
7790
Serialize(::protozero::Message * msg) const7791 void DataSourceDescriptor::Serialize(::protozero::Message* msg) const {
7792 // Field 1: name
7793 if (_has_field_[1]) {
7794 msg->AppendString(1, name_);
7795 }
7796
7797 // Field 2: will_notify_on_stop
7798 if (_has_field_[2]) {
7799 msg->AppendTinyVarInt(2, will_notify_on_stop_);
7800 }
7801
7802 // Field 3: will_notify_on_start
7803 if (_has_field_[3]) {
7804 msg->AppendTinyVarInt(3, will_notify_on_start_);
7805 }
7806
7807 // Field 4: handles_incremental_state_clear
7808 if (_has_field_[4]) {
7809 msg->AppendTinyVarInt(4, handles_incremental_state_clear_);
7810 }
7811
7812 // Field 5: gpu_counter_descriptor
7813 if (_has_field_[5]) {
7814 msg->AppendString(5, gpu_counter_descriptor_);
7815 }
7816
7817 // Field 6: track_event_descriptor
7818 if (_has_field_[6]) {
7819 msg->AppendString(6, track_event_descriptor_);
7820 }
7821
7822 msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
7823 }
7824
7825 } // namespace perfetto
7826 } // namespace protos
7827 } // namespace gen
7828 #pragma GCC diagnostic pop
7829 // gen_amalgamated begin source: gen/protos/perfetto/common/descriptor.gen.cc
7830 // gen_amalgamated begin header: gen/protos/perfetto/common/descriptor.gen.h
7831 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
7832 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_DESCRIPTOR_PROTO_CPP_H_
7833 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_DESCRIPTOR_PROTO_CPP_H_
7834
7835 #include <stdint.h>
7836 #include <bitset>
7837 #include <vector>
7838 #include <string>
7839 #include <type_traits>
7840
7841 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
7842 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
7843 // gen_amalgamated expanded: #include "perfetto/base/export.h"
7844
7845 namespace perfetto {
7846 namespace protos {
7847 namespace gen {
7848 class OneofOptions;
7849 class EnumValueDescriptorProto;
7850 class EnumDescriptorProto;
7851 class OneofDescriptorProto;
7852 class FieldDescriptorProto;
7853 class DescriptorProto;
7854 class DescriptorProto_ReservedRange;
7855 class FileDescriptorProto;
7856 class FileDescriptorSet;
7857 enum FieldDescriptorProto_Type : int;
7858 enum FieldDescriptorProto_Label : int;
7859 } // namespace perfetto
7860 } // namespace protos
7861 } // namespace gen
7862
7863 namespace protozero {
7864 class Message;
7865 } // namespace protozero
7866
7867 namespace perfetto {
7868 namespace protos {
7869 namespace gen {
7870 enum FieldDescriptorProto_Type : int {
7871 FieldDescriptorProto_Type_TYPE_DOUBLE = 1,
7872 FieldDescriptorProto_Type_TYPE_FLOAT = 2,
7873 FieldDescriptorProto_Type_TYPE_INT64 = 3,
7874 FieldDescriptorProto_Type_TYPE_UINT64 = 4,
7875 FieldDescriptorProto_Type_TYPE_INT32 = 5,
7876 FieldDescriptorProto_Type_TYPE_FIXED64 = 6,
7877 FieldDescriptorProto_Type_TYPE_FIXED32 = 7,
7878 FieldDescriptorProto_Type_TYPE_BOOL = 8,
7879 FieldDescriptorProto_Type_TYPE_STRING = 9,
7880 FieldDescriptorProto_Type_TYPE_GROUP = 10,
7881 FieldDescriptorProto_Type_TYPE_MESSAGE = 11,
7882 FieldDescriptorProto_Type_TYPE_BYTES = 12,
7883 FieldDescriptorProto_Type_TYPE_UINT32 = 13,
7884 FieldDescriptorProto_Type_TYPE_ENUM = 14,
7885 FieldDescriptorProto_Type_TYPE_SFIXED32 = 15,
7886 FieldDescriptorProto_Type_TYPE_SFIXED64 = 16,
7887 FieldDescriptorProto_Type_TYPE_SINT32 = 17,
7888 FieldDescriptorProto_Type_TYPE_SINT64 = 18,
7889 };
7890 enum FieldDescriptorProto_Label : int {
7891 FieldDescriptorProto_Label_LABEL_OPTIONAL = 1,
7892 FieldDescriptorProto_Label_LABEL_REQUIRED = 2,
7893 FieldDescriptorProto_Label_LABEL_REPEATED = 3,
7894 };
7895
7896 class PERFETTO_EXPORT OneofOptions : public ::protozero::CppMessageObj {
7897 public:
7898 enum FieldNumbers {
7899 };
7900
7901 OneofOptions();
7902 ~OneofOptions() override;
7903 OneofOptions(OneofOptions&&) noexcept;
7904 OneofOptions& operator=(OneofOptions&&);
7905 OneofOptions(const OneofOptions&);
7906 OneofOptions& operator=(const OneofOptions&);
7907 bool operator==(const OneofOptions&) const;
operator !=(const OneofOptions & other) const7908 bool operator!=(const OneofOptions& other) const { return !(*this == other); }
7909
7910 bool ParseFromArray(const void*, size_t) override;
7911 std::string SerializeAsString() const override;
7912 std::vector<uint8_t> SerializeAsArray() const override;
7913 void Serialize(::protozero::Message*) const;
7914
7915 private:
7916
7917 // Allows to preserve unknown protobuf fields for compatibility
7918 // with future versions of .proto files.
7919 std::string unknown_fields_;
7920
7921 std::bitset<2> _has_field_{};
7922 };
7923
7924
7925 class PERFETTO_EXPORT EnumValueDescriptorProto : public ::protozero::CppMessageObj {
7926 public:
7927 enum FieldNumbers {
7928 kNameFieldNumber = 1,
7929 kNumberFieldNumber = 2,
7930 };
7931
7932 EnumValueDescriptorProto();
7933 ~EnumValueDescriptorProto() override;
7934 EnumValueDescriptorProto(EnumValueDescriptorProto&&) noexcept;
7935 EnumValueDescriptorProto& operator=(EnumValueDescriptorProto&&);
7936 EnumValueDescriptorProto(const EnumValueDescriptorProto&);
7937 EnumValueDescriptorProto& operator=(const EnumValueDescriptorProto&);
7938 bool operator==(const EnumValueDescriptorProto&) const;
operator !=(const EnumValueDescriptorProto & other) const7939 bool operator!=(const EnumValueDescriptorProto& other) const { return !(*this == other); }
7940
7941 bool ParseFromArray(const void*, size_t) override;
7942 std::string SerializeAsString() const override;
7943 std::vector<uint8_t> SerializeAsArray() const override;
7944 void Serialize(::protozero::Message*) const;
7945
has_name() const7946 bool has_name() const { return _has_field_[1]; }
name() const7947 const std::string& name() const { return name_; }
set_name(const std::string & value)7948 void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
7949
has_number() const7950 bool has_number() const { return _has_field_[2]; }
number() const7951 int32_t number() const { return number_; }
set_number(int32_t value)7952 void set_number(int32_t value) { number_ = value; _has_field_.set(2); }
7953
7954 private:
7955 std::string name_{};
7956 int32_t number_{};
7957
7958 // Allows to preserve unknown protobuf fields for compatibility
7959 // with future versions of .proto files.
7960 std::string unknown_fields_;
7961
7962 std::bitset<3> _has_field_{};
7963 };
7964
7965
7966 class PERFETTO_EXPORT EnumDescriptorProto : public ::protozero::CppMessageObj {
7967 public:
7968 enum FieldNumbers {
7969 kNameFieldNumber = 1,
7970 kValueFieldNumber = 2,
7971 kReservedNameFieldNumber = 5,
7972 };
7973
7974 EnumDescriptorProto();
7975 ~EnumDescriptorProto() override;
7976 EnumDescriptorProto(EnumDescriptorProto&&) noexcept;
7977 EnumDescriptorProto& operator=(EnumDescriptorProto&&);
7978 EnumDescriptorProto(const EnumDescriptorProto&);
7979 EnumDescriptorProto& operator=(const EnumDescriptorProto&);
7980 bool operator==(const EnumDescriptorProto&) const;
operator !=(const EnumDescriptorProto & other) const7981 bool operator!=(const EnumDescriptorProto& other) const { return !(*this == other); }
7982
7983 bool ParseFromArray(const void*, size_t) override;
7984 std::string SerializeAsString() const override;
7985 std::vector<uint8_t> SerializeAsArray() const override;
7986 void Serialize(::protozero::Message*) const;
7987
has_name() const7988 bool has_name() const { return _has_field_[1]; }
name() const7989 const std::string& name() const { return name_; }
set_name(const std::string & value)7990 void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
7991
value_size() const7992 int value_size() const { return static_cast<int>(value_.size()); }
value() const7993 const std::vector<EnumValueDescriptorProto>& value() const { return value_; }
mutable_value()7994 std::vector<EnumValueDescriptorProto>* mutable_value() { return &value_; }
clear_value()7995 void clear_value() { value_.clear(); }
add_value()7996 EnumValueDescriptorProto* add_value() { value_.emplace_back(); return &value_.back(); }
7997
reserved_name_size() const7998 int reserved_name_size() const { return static_cast<int>(reserved_name_.size()); }
reserved_name() const7999 const std::vector<std::string>& reserved_name() const { return reserved_name_; }
mutable_reserved_name()8000 std::vector<std::string>* mutable_reserved_name() { return &reserved_name_; }
clear_reserved_name()8001 void clear_reserved_name() { reserved_name_.clear(); }
add_reserved_name(std::string value)8002 void add_reserved_name(std::string value) { reserved_name_.emplace_back(value); }
add_reserved_name()8003 std::string* add_reserved_name() { reserved_name_.emplace_back(); return &reserved_name_.back(); }
8004
8005 private:
8006 std::string name_{};
8007 std::vector<EnumValueDescriptorProto> value_;
8008 std::vector<std::string> reserved_name_;
8009
8010 // Allows to preserve unknown protobuf fields for compatibility
8011 // with future versions of .proto files.
8012 std::string unknown_fields_;
8013
8014 std::bitset<6> _has_field_{};
8015 };
8016
8017
8018 class PERFETTO_EXPORT OneofDescriptorProto : public ::protozero::CppMessageObj {
8019 public:
8020 enum FieldNumbers {
8021 kNameFieldNumber = 1,
8022 kOptionsFieldNumber = 2,
8023 };
8024
8025 OneofDescriptorProto();
8026 ~OneofDescriptorProto() override;
8027 OneofDescriptorProto(OneofDescriptorProto&&) noexcept;
8028 OneofDescriptorProto& operator=(OneofDescriptorProto&&);
8029 OneofDescriptorProto(const OneofDescriptorProto&);
8030 OneofDescriptorProto& operator=(const OneofDescriptorProto&);
8031 bool operator==(const OneofDescriptorProto&) const;
operator !=(const OneofDescriptorProto & other) const8032 bool operator!=(const OneofDescriptorProto& other) const { return !(*this == other); }
8033
8034 bool ParseFromArray(const void*, size_t) override;
8035 std::string SerializeAsString() const override;
8036 std::vector<uint8_t> SerializeAsArray() const override;
8037 void Serialize(::protozero::Message*) const;
8038
has_name() const8039 bool has_name() const { return _has_field_[1]; }
name() const8040 const std::string& name() const { return name_; }
set_name(const std::string & value)8041 void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
8042
has_options() const8043 bool has_options() const { return _has_field_[2]; }
options() const8044 const OneofOptions& options() const { return *options_; }
mutable_options()8045 OneofOptions* mutable_options() { _has_field_.set(2); return options_.get(); }
8046
8047 private:
8048 std::string name_{};
8049 ::protozero::CopyablePtr<OneofOptions> options_;
8050
8051 // Allows to preserve unknown protobuf fields for compatibility
8052 // with future versions of .proto files.
8053 std::string unknown_fields_;
8054
8055 std::bitset<3> _has_field_{};
8056 };
8057
8058
8059 class PERFETTO_EXPORT FieldDescriptorProto : public ::protozero::CppMessageObj {
8060 public:
8061 using Type = FieldDescriptorProto_Type;
8062 static constexpr auto TYPE_DOUBLE = FieldDescriptorProto_Type_TYPE_DOUBLE;
8063 static constexpr auto TYPE_FLOAT = FieldDescriptorProto_Type_TYPE_FLOAT;
8064 static constexpr auto TYPE_INT64 = FieldDescriptorProto_Type_TYPE_INT64;
8065 static constexpr auto TYPE_UINT64 = FieldDescriptorProto_Type_TYPE_UINT64;
8066 static constexpr auto TYPE_INT32 = FieldDescriptorProto_Type_TYPE_INT32;
8067 static constexpr auto TYPE_FIXED64 = FieldDescriptorProto_Type_TYPE_FIXED64;
8068 static constexpr auto TYPE_FIXED32 = FieldDescriptorProto_Type_TYPE_FIXED32;
8069 static constexpr auto TYPE_BOOL = FieldDescriptorProto_Type_TYPE_BOOL;
8070 static constexpr auto TYPE_STRING = FieldDescriptorProto_Type_TYPE_STRING;
8071 static constexpr auto TYPE_GROUP = FieldDescriptorProto_Type_TYPE_GROUP;
8072 static constexpr auto TYPE_MESSAGE = FieldDescriptorProto_Type_TYPE_MESSAGE;
8073 static constexpr auto TYPE_BYTES = FieldDescriptorProto_Type_TYPE_BYTES;
8074 static constexpr auto TYPE_UINT32 = FieldDescriptorProto_Type_TYPE_UINT32;
8075 static constexpr auto TYPE_ENUM = FieldDescriptorProto_Type_TYPE_ENUM;
8076 static constexpr auto TYPE_SFIXED32 = FieldDescriptorProto_Type_TYPE_SFIXED32;
8077 static constexpr auto TYPE_SFIXED64 = FieldDescriptorProto_Type_TYPE_SFIXED64;
8078 static constexpr auto TYPE_SINT32 = FieldDescriptorProto_Type_TYPE_SINT32;
8079 static constexpr auto TYPE_SINT64 = FieldDescriptorProto_Type_TYPE_SINT64;
8080 static constexpr auto Type_MIN = FieldDescriptorProto_Type_TYPE_DOUBLE;
8081 static constexpr auto Type_MAX = FieldDescriptorProto_Type_TYPE_SINT64;
8082 using Label = FieldDescriptorProto_Label;
8083 static constexpr auto LABEL_OPTIONAL = FieldDescriptorProto_Label_LABEL_OPTIONAL;
8084 static constexpr auto LABEL_REQUIRED = FieldDescriptorProto_Label_LABEL_REQUIRED;
8085 static constexpr auto LABEL_REPEATED = FieldDescriptorProto_Label_LABEL_REPEATED;
8086 static constexpr auto Label_MIN = FieldDescriptorProto_Label_LABEL_OPTIONAL;
8087 static constexpr auto Label_MAX = FieldDescriptorProto_Label_LABEL_REPEATED;
8088 enum FieldNumbers {
8089 kNameFieldNumber = 1,
8090 kNumberFieldNumber = 3,
8091 kLabelFieldNumber = 4,
8092 kTypeFieldNumber = 5,
8093 kTypeNameFieldNumber = 6,
8094 kExtendeeFieldNumber = 2,
8095 kDefaultValueFieldNumber = 7,
8096 kOneofIndexFieldNumber = 9,
8097 };
8098
8099 FieldDescriptorProto();
8100 ~FieldDescriptorProto() override;
8101 FieldDescriptorProto(FieldDescriptorProto&&) noexcept;
8102 FieldDescriptorProto& operator=(FieldDescriptorProto&&);
8103 FieldDescriptorProto(const FieldDescriptorProto&);
8104 FieldDescriptorProto& operator=(const FieldDescriptorProto&);
8105 bool operator==(const FieldDescriptorProto&) const;
operator !=(const FieldDescriptorProto & other) const8106 bool operator!=(const FieldDescriptorProto& other) const { return !(*this == other); }
8107
8108 bool ParseFromArray(const void*, size_t) override;
8109 std::string SerializeAsString() const override;
8110 std::vector<uint8_t> SerializeAsArray() const override;
8111 void Serialize(::protozero::Message*) const;
8112
has_name() const8113 bool has_name() const { return _has_field_[1]; }
name() const8114 const std::string& name() const { return name_; }
set_name(const std::string & value)8115 void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
8116
has_number() const8117 bool has_number() const { return _has_field_[3]; }
number() const8118 int32_t number() const { return number_; }
set_number(int32_t value)8119 void set_number(int32_t value) { number_ = value; _has_field_.set(3); }
8120
has_label() const8121 bool has_label() const { return _has_field_[4]; }
label() const8122 FieldDescriptorProto_Label label() const { return label_; }
set_label(FieldDescriptorProto_Label value)8123 void set_label(FieldDescriptorProto_Label value) { label_ = value; _has_field_.set(4); }
8124
has_type() const8125 bool has_type() const { return _has_field_[5]; }
type() const8126 FieldDescriptorProto_Type type() const { return type_; }
set_type(FieldDescriptorProto_Type value)8127 void set_type(FieldDescriptorProto_Type value) { type_ = value; _has_field_.set(5); }
8128
has_type_name() const8129 bool has_type_name() const { return _has_field_[6]; }
type_name() const8130 const std::string& type_name() const { return type_name_; }
set_type_name(const std::string & value)8131 void set_type_name(const std::string& value) { type_name_ = value; _has_field_.set(6); }
8132
has_extendee() const8133 bool has_extendee() const { return _has_field_[2]; }
extendee() const8134 const std::string& extendee() const { return extendee_; }
set_extendee(const std::string & value)8135 void set_extendee(const std::string& value) { extendee_ = value; _has_field_.set(2); }
8136
has_default_value() const8137 bool has_default_value() const { return _has_field_[7]; }
default_value() const8138 const std::string& default_value() const { return default_value_; }
set_default_value(const std::string & value)8139 void set_default_value(const std::string& value) { default_value_ = value; _has_field_.set(7); }
8140
has_oneof_index() const8141 bool has_oneof_index() const { return _has_field_[9]; }
oneof_index() const8142 int32_t oneof_index() const { return oneof_index_; }
set_oneof_index(int32_t value)8143 void set_oneof_index(int32_t value) { oneof_index_ = value; _has_field_.set(9); }
8144
8145 private:
8146 std::string name_{};
8147 int32_t number_{};
8148 FieldDescriptorProto_Label label_{};
8149 FieldDescriptorProto_Type type_{};
8150 std::string type_name_{};
8151 std::string extendee_{};
8152 std::string default_value_{};
8153 int32_t oneof_index_{};
8154
8155 // Allows to preserve unknown protobuf fields for compatibility
8156 // with future versions of .proto files.
8157 std::string unknown_fields_;
8158
8159 std::bitset<10> _has_field_{};
8160 };
8161
8162
8163 class PERFETTO_EXPORT DescriptorProto : public ::protozero::CppMessageObj {
8164 public:
8165 using ReservedRange = DescriptorProto_ReservedRange;
8166 enum FieldNumbers {
8167 kNameFieldNumber = 1,
8168 kFieldFieldNumber = 2,
8169 kExtensionFieldNumber = 6,
8170 kNestedTypeFieldNumber = 3,
8171 kEnumTypeFieldNumber = 4,
8172 kOneofDeclFieldNumber = 8,
8173 kReservedRangeFieldNumber = 9,
8174 kReservedNameFieldNumber = 10,
8175 };
8176
8177 DescriptorProto();
8178 ~DescriptorProto() override;
8179 DescriptorProto(DescriptorProto&&) noexcept;
8180 DescriptorProto& operator=(DescriptorProto&&);
8181 DescriptorProto(const DescriptorProto&);
8182 DescriptorProto& operator=(const DescriptorProto&);
8183 bool operator==(const DescriptorProto&) const;
operator !=(const DescriptorProto & other) const8184 bool operator!=(const DescriptorProto& other) const { return !(*this == other); }
8185
8186 bool ParseFromArray(const void*, size_t) override;
8187 std::string SerializeAsString() const override;
8188 std::vector<uint8_t> SerializeAsArray() const override;
8189 void Serialize(::protozero::Message*) const;
8190
has_name() const8191 bool has_name() const { return _has_field_[1]; }
name() const8192 const std::string& name() const { return name_; }
set_name(const std::string & value)8193 void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
8194
field_size() const8195 int field_size() const { return static_cast<int>(field_.size()); }
field() const8196 const std::vector<FieldDescriptorProto>& field() const { return field_; }
mutable_field()8197 std::vector<FieldDescriptorProto>* mutable_field() { return &field_; }
clear_field()8198 void clear_field() { field_.clear(); }
add_field()8199 FieldDescriptorProto* add_field() { field_.emplace_back(); return &field_.back(); }
8200
extension_size() const8201 int extension_size() const { return static_cast<int>(extension_.size()); }
extension() const8202 const std::vector<FieldDescriptorProto>& extension() const { return extension_; }
mutable_extension()8203 std::vector<FieldDescriptorProto>* mutable_extension() { return &extension_; }
clear_extension()8204 void clear_extension() { extension_.clear(); }
add_extension()8205 FieldDescriptorProto* add_extension() { extension_.emplace_back(); return &extension_.back(); }
8206
nested_type_size() const8207 int nested_type_size() const { return static_cast<int>(nested_type_.size()); }
nested_type() const8208 const std::vector<DescriptorProto>& nested_type() const { return nested_type_; }
mutable_nested_type()8209 std::vector<DescriptorProto>* mutable_nested_type() { return &nested_type_; }
clear_nested_type()8210 void clear_nested_type() { nested_type_.clear(); }
add_nested_type()8211 DescriptorProto* add_nested_type() { nested_type_.emplace_back(); return &nested_type_.back(); }
8212
enum_type_size() const8213 int enum_type_size() const { return static_cast<int>(enum_type_.size()); }
enum_type() const8214 const std::vector<EnumDescriptorProto>& enum_type() const { return enum_type_; }
mutable_enum_type()8215 std::vector<EnumDescriptorProto>* mutable_enum_type() { return &enum_type_; }
clear_enum_type()8216 void clear_enum_type() { enum_type_.clear(); }
add_enum_type()8217 EnumDescriptorProto* add_enum_type() { enum_type_.emplace_back(); return &enum_type_.back(); }
8218
oneof_decl_size() const8219 int oneof_decl_size() const { return static_cast<int>(oneof_decl_.size()); }
oneof_decl() const8220 const std::vector<OneofDescriptorProto>& oneof_decl() const { return oneof_decl_; }
mutable_oneof_decl()8221 std::vector<OneofDescriptorProto>* mutable_oneof_decl() { return &oneof_decl_; }
clear_oneof_decl()8222 void clear_oneof_decl() { oneof_decl_.clear(); }
add_oneof_decl()8223 OneofDescriptorProto* add_oneof_decl() { oneof_decl_.emplace_back(); return &oneof_decl_.back(); }
8224
reserved_range_size() const8225 int reserved_range_size() const { return static_cast<int>(reserved_range_.size()); }
reserved_range() const8226 const std::vector<DescriptorProto_ReservedRange>& reserved_range() const { return reserved_range_; }
mutable_reserved_range()8227 std::vector<DescriptorProto_ReservedRange>* mutable_reserved_range() { return &reserved_range_; }
clear_reserved_range()8228 void clear_reserved_range() { reserved_range_.clear(); }
add_reserved_range()8229 DescriptorProto_ReservedRange* add_reserved_range() { reserved_range_.emplace_back(); return &reserved_range_.back(); }
8230
reserved_name_size() const8231 int reserved_name_size() const { return static_cast<int>(reserved_name_.size()); }
reserved_name() const8232 const std::vector<std::string>& reserved_name() const { return reserved_name_; }
mutable_reserved_name()8233 std::vector<std::string>* mutable_reserved_name() { return &reserved_name_; }
clear_reserved_name()8234 void clear_reserved_name() { reserved_name_.clear(); }
add_reserved_name(std::string value)8235 void add_reserved_name(std::string value) { reserved_name_.emplace_back(value); }
add_reserved_name()8236 std::string* add_reserved_name() { reserved_name_.emplace_back(); return &reserved_name_.back(); }
8237
8238 private:
8239 std::string name_{};
8240 std::vector<FieldDescriptorProto> field_;
8241 std::vector<FieldDescriptorProto> extension_;
8242 std::vector<DescriptorProto> nested_type_;
8243 std::vector<EnumDescriptorProto> enum_type_;
8244 std::vector<OneofDescriptorProto> oneof_decl_;
8245 std::vector<DescriptorProto_ReservedRange> reserved_range_;
8246 std::vector<std::string> reserved_name_;
8247
8248 // Allows to preserve unknown protobuf fields for compatibility
8249 // with future versions of .proto files.
8250 std::string unknown_fields_;
8251
8252 std::bitset<11> _has_field_{};
8253 };
8254
8255
8256 class PERFETTO_EXPORT DescriptorProto_ReservedRange : public ::protozero::CppMessageObj {
8257 public:
8258 enum FieldNumbers {
8259 kStartFieldNumber = 1,
8260 kEndFieldNumber = 2,
8261 };
8262
8263 DescriptorProto_ReservedRange();
8264 ~DescriptorProto_ReservedRange() override;
8265 DescriptorProto_ReservedRange(DescriptorProto_ReservedRange&&) noexcept;
8266 DescriptorProto_ReservedRange& operator=(DescriptorProto_ReservedRange&&);
8267 DescriptorProto_ReservedRange(const DescriptorProto_ReservedRange&);
8268 DescriptorProto_ReservedRange& operator=(const DescriptorProto_ReservedRange&);
8269 bool operator==(const DescriptorProto_ReservedRange&) const;
operator !=(const DescriptorProto_ReservedRange & other) const8270 bool operator!=(const DescriptorProto_ReservedRange& other) const { return !(*this == other); }
8271
8272 bool ParseFromArray(const void*, size_t) override;
8273 std::string SerializeAsString() const override;
8274 std::vector<uint8_t> SerializeAsArray() const override;
8275 void Serialize(::protozero::Message*) const;
8276
has_start() const8277 bool has_start() const { return _has_field_[1]; }
start() const8278 int32_t start() const { return start_; }
set_start(int32_t value)8279 void set_start(int32_t value) { start_ = value; _has_field_.set(1); }
8280
has_end() const8281 bool has_end() const { return _has_field_[2]; }
end() const8282 int32_t end() const { return end_; }
set_end(int32_t value)8283 void set_end(int32_t value) { end_ = value; _has_field_.set(2); }
8284
8285 private:
8286 int32_t start_{};
8287 int32_t end_{};
8288
8289 // Allows to preserve unknown protobuf fields for compatibility
8290 // with future versions of .proto files.
8291 std::string unknown_fields_;
8292
8293 std::bitset<3> _has_field_{};
8294 };
8295
8296
8297 class PERFETTO_EXPORT FileDescriptorProto : public ::protozero::CppMessageObj {
8298 public:
8299 enum FieldNumbers {
8300 kNameFieldNumber = 1,
8301 kPackageFieldNumber = 2,
8302 kDependencyFieldNumber = 3,
8303 kPublicDependencyFieldNumber = 10,
8304 kWeakDependencyFieldNumber = 11,
8305 kMessageTypeFieldNumber = 4,
8306 kEnumTypeFieldNumber = 5,
8307 kExtensionFieldNumber = 7,
8308 };
8309
8310 FileDescriptorProto();
8311 ~FileDescriptorProto() override;
8312 FileDescriptorProto(FileDescriptorProto&&) noexcept;
8313 FileDescriptorProto& operator=(FileDescriptorProto&&);
8314 FileDescriptorProto(const FileDescriptorProto&);
8315 FileDescriptorProto& operator=(const FileDescriptorProto&);
8316 bool operator==(const FileDescriptorProto&) const;
operator !=(const FileDescriptorProto & other) const8317 bool operator!=(const FileDescriptorProto& other) const { return !(*this == other); }
8318
8319 bool ParseFromArray(const void*, size_t) override;
8320 std::string SerializeAsString() const override;
8321 std::vector<uint8_t> SerializeAsArray() const override;
8322 void Serialize(::protozero::Message*) const;
8323
has_name() const8324 bool has_name() const { return _has_field_[1]; }
name() const8325 const std::string& name() const { return name_; }
set_name(const std::string & value)8326 void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
8327
has_package() const8328 bool has_package() const { return _has_field_[2]; }
package() const8329 const std::string& package() const { return package_; }
set_package(const std::string & value)8330 void set_package(const std::string& value) { package_ = value; _has_field_.set(2); }
8331
dependency_size() const8332 int dependency_size() const { return static_cast<int>(dependency_.size()); }
dependency() const8333 const std::vector<std::string>& dependency() const { return dependency_; }
mutable_dependency()8334 std::vector<std::string>* mutable_dependency() { return &dependency_; }
clear_dependency()8335 void clear_dependency() { dependency_.clear(); }
add_dependency(std::string value)8336 void add_dependency(std::string value) { dependency_.emplace_back(value); }
add_dependency()8337 std::string* add_dependency() { dependency_.emplace_back(); return &dependency_.back(); }
8338
public_dependency_size() const8339 int public_dependency_size() const { return static_cast<int>(public_dependency_.size()); }
public_dependency() const8340 const std::vector<int32_t>& public_dependency() const { return public_dependency_; }
mutable_public_dependency()8341 std::vector<int32_t>* mutable_public_dependency() { return &public_dependency_; }
clear_public_dependency()8342 void clear_public_dependency() { public_dependency_.clear(); }
add_public_dependency(int32_t value)8343 void add_public_dependency(int32_t value) { public_dependency_.emplace_back(value); }
add_public_dependency()8344 int32_t* add_public_dependency() { public_dependency_.emplace_back(); return &public_dependency_.back(); }
8345
weak_dependency_size() const8346 int weak_dependency_size() const { return static_cast<int>(weak_dependency_.size()); }
weak_dependency() const8347 const std::vector<int32_t>& weak_dependency() const { return weak_dependency_; }
mutable_weak_dependency()8348 std::vector<int32_t>* mutable_weak_dependency() { return &weak_dependency_; }
clear_weak_dependency()8349 void clear_weak_dependency() { weak_dependency_.clear(); }
add_weak_dependency(int32_t value)8350 void add_weak_dependency(int32_t value) { weak_dependency_.emplace_back(value); }
add_weak_dependency()8351 int32_t* add_weak_dependency() { weak_dependency_.emplace_back(); return &weak_dependency_.back(); }
8352
message_type_size() const8353 int message_type_size() const { return static_cast<int>(message_type_.size()); }
message_type() const8354 const std::vector<DescriptorProto>& message_type() const { return message_type_; }
mutable_message_type()8355 std::vector<DescriptorProto>* mutable_message_type() { return &message_type_; }
clear_message_type()8356 void clear_message_type() { message_type_.clear(); }
add_message_type()8357 DescriptorProto* add_message_type() { message_type_.emplace_back(); return &message_type_.back(); }
8358
enum_type_size() const8359 int enum_type_size() const { return static_cast<int>(enum_type_.size()); }
enum_type() const8360 const std::vector<EnumDescriptorProto>& enum_type() const { return enum_type_; }
mutable_enum_type()8361 std::vector<EnumDescriptorProto>* mutable_enum_type() { return &enum_type_; }
clear_enum_type()8362 void clear_enum_type() { enum_type_.clear(); }
add_enum_type()8363 EnumDescriptorProto* add_enum_type() { enum_type_.emplace_back(); return &enum_type_.back(); }
8364
extension_size() const8365 int extension_size() const { return static_cast<int>(extension_.size()); }
extension() const8366 const std::vector<FieldDescriptorProto>& extension() const { return extension_; }
mutable_extension()8367 std::vector<FieldDescriptorProto>* mutable_extension() { return &extension_; }
clear_extension()8368 void clear_extension() { extension_.clear(); }
add_extension()8369 FieldDescriptorProto* add_extension() { extension_.emplace_back(); return &extension_.back(); }
8370
8371 private:
8372 std::string name_{};
8373 std::string package_{};
8374 std::vector<std::string> dependency_;
8375 std::vector<int32_t> public_dependency_;
8376 std::vector<int32_t> weak_dependency_;
8377 std::vector<DescriptorProto> message_type_;
8378 std::vector<EnumDescriptorProto> enum_type_;
8379 std::vector<FieldDescriptorProto> extension_;
8380
8381 // Allows to preserve unknown protobuf fields for compatibility
8382 // with future versions of .proto files.
8383 std::string unknown_fields_;
8384
8385 std::bitset<12> _has_field_{};
8386 };
8387
8388
8389 class PERFETTO_EXPORT FileDescriptorSet : public ::protozero::CppMessageObj {
8390 public:
8391 enum FieldNumbers {
8392 kFileFieldNumber = 1,
8393 };
8394
8395 FileDescriptorSet();
8396 ~FileDescriptorSet() override;
8397 FileDescriptorSet(FileDescriptorSet&&) noexcept;
8398 FileDescriptorSet& operator=(FileDescriptorSet&&);
8399 FileDescriptorSet(const FileDescriptorSet&);
8400 FileDescriptorSet& operator=(const FileDescriptorSet&);
8401 bool operator==(const FileDescriptorSet&) const;
operator !=(const FileDescriptorSet & other) const8402 bool operator!=(const FileDescriptorSet& other) const { return !(*this == other); }
8403
8404 bool ParseFromArray(const void*, size_t) override;
8405 std::string SerializeAsString() const override;
8406 std::vector<uint8_t> SerializeAsArray() const override;
8407 void Serialize(::protozero::Message*) const;
8408
file_size() const8409 int file_size() const { return static_cast<int>(file_.size()); }
file() const8410 const std::vector<FileDescriptorProto>& file() const { return file_; }
mutable_file()8411 std::vector<FileDescriptorProto>* mutable_file() { return &file_; }
clear_file()8412 void clear_file() { file_.clear(); }
add_file()8413 FileDescriptorProto* add_file() { file_.emplace_back(); return &file_.back(); }
8414
8415 private:
8416 std::vector<FileDescriptorProto> file_;
8417
8418 // Allows to preserve unknown protobuf fields for compatibility
8419 // with future versions of .proto files.
8420 std::string unknown_fields_;
8421
8422 std::bitset<2> _has_field_{};
8423 };
8424
8425 } // namespace perfetto
8426 } // namespace protos
8427 } // namespace gen
8428
8429 #endif // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_DESCRIPTOR_PROTO_CPP_H_
8430 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
8431 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
8432 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
8433 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
8434 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
8435 #pragma GCC diagnostic push
8436 #pragma GCC diagnostic ignored "-Wfloat-equal"
8437 // gen_amalgamated expanded: #include "protos/perfetto/common/descriptor.gen.h"
8438
8439 namespace perfetto {
8440 namespace protos {
8441 namespace gen {
8442
8443 OneofOptions::OneofOptions() = default;
8444 OneofOptions::~OneofOptions() = default;
8445 OneofOptions::OneofOptions(const OneofOptions&) = default;
8446 OneofOptions& OneofOptions::operator=(const OneofOptions&) = default;
8447 OneofOptions::OneofOptions(OneofOptions&&) noexcept = default;
8448 OneofOptions& OneofOptions::operator=(OneofOptions&&) = default;
8449
operator ==(const OneofOptions & other) const8450 bool OneofOptions::operator==(const OneofOptions& other) const {
8451 return unknown_fields_ == other.unknown_fields_;
8452 }
8453
ParseFromArray(const void * raw,size_t size)8454 bool OneofOptions::ParseFromArray(const void* raw, size_t size) {
8455 unknown_fields_.clear();
8456 bool packed_error = false;
8457
8458 ::protozero::ProtoDecoder dec(raw, size);
8459 for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
8460 if (field.id() < _has_field_.size()) {
8461 _has_field_.set(field.id());
8462 }
8463 switch (field.id()) {
8464 default:
8465 field.SerializeAndAppendTo(&unknown_fields_);
8466 break;
8467 }
8468 }
8469 return !packed_error && !dec.bytes_left();
8470 }
8471
SerializeAsString() const8472 std::string OneofOptions::SerializeAsString() const {
8473 ::protozero::HeapBuffered<::protozero::Message> msg;
8474 Serialize(msg.get());
8475 return msg.SerializeAsString();
8476 }
8477
SerializeAsArray() const8478 std::vector<uint8_t> OneofOptions::SerializeAsArray() const {
8479 ::protozero::HeapBuffered<::protozero::Message> msg;
8480 Serialize(msg.get());
8481 return msg.SerializeAsArray();
8482 }
8483
Serialize(::protozero::Message * msg) const8484 void OneofOptions::Serialize(::protozero::Message* msg) const {
8485 msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
8486 }
8487
8488
8489 EnumValueDescriptorProto::EnumValueDescriptorProto() = default;
8490 EnumValueDescriptorProto::~EnumValueDescriptorProto() = default;
8491 EnumValueDescriptorProto::EnumValueDescriptorProto(const EnumValueDescriptorProto&) = default;
8492 EnumValueDescriptorProto& EnumValueDescriptorProto::operator=(const EnumValueDescriptorProto&) = default;
8493 EnumValueDescriptorProto::EnumValueDescriptorProto(EnumValueDescriptorProto&&) noexcept = default;
8494 EnumValueDescriptorProto& EnumValueDescriptorProto::operator=(EnumValueDescriptorProto&&) = default;
8495
operator ==(const EnumValueDescriptorProto & other) const8496 bool EnumValueDescriptorProto::operator==(const EnumValueDescriptorProto& other) const {
8497 return unknown_fields_ == other.unknown_fields_
8498 && name_ == other.name_
8499 && number_ == other.number_;
8500 }
8501
ParseFromArray(const void * raw,size_t size)8502 bool EnumValueDescriptorProto::ParseFromArray(const void* raw, size_t size) {
8503 unknown_fields_.clear();
8504 bool packed_error = false;
8505
8506 ::protozero::ProtoDecoder dec(raw, size);
8507 for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
8508 if (field.id() < _has_field_.size()) {
8509 _has_field_.set(field.id());
8510 }
8511 switch (field.id()) {
8512 case 1 /* name */:
8513 field.get(&name_);
8514 break;
8515 case 2 /* number */:
8516 field.get(&number_);
8517 break;
8518 default:
8519 field.SerializeAndAppendTo(&unknown_fields_);
8520 break;
8521 }
8522 }
8523 return !packed_error && !dec.bytes_left();
8524 }
8525
SerializeAsString() const8526 std::string EnumValueDescriptorProto::SerializeAsString() const {
8527 ::protozero::HeapBuffered<::protozero::Message> msg;
8528 Serialize(msg.get());
8529 return msg.SerializeAsString();
8530 }
8531
SerializeAsArray() const8532 std::vector<uint8_t> EnumValueDescriptorProto::SerializeAsArray() const {
8533 ::protozero::HeapBuffered<::protozero::Message> msg;
8534 Serialize(msg.get());
8535 return msg.SerializeAsArray();
8536 }
8537
Serialize(::protozero::Message * msg) const8538 void EnumValueDescriptorProto::Serialize(::protozero::Message* msg) const {
8539 // Field 1: name
8540 if (_has_field_[1]) {
8541 msg->AppendString(1, name_);
8542 }
8543
8544 // Field 2: number
8545 if (_has_field_[2]) {
8546 msg->AppendVarInt(2, number_);
8547 }
8548
8549 msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
8550 }
8551
8552
8553 EnumDescriptorProto::EnumDescriptorProto() = default;
8554 EnumDescriptorProto::~EnumDescriptorProto() = default;
8555 EnumDescriptorProto::EnumDescriptorProto(const EnumDescriptorProto&) = default;
8556 EnumDescriptorProto& EnumDescriptorProto::operator=(const EnumDescriptorProto&) = default;
8557 EnumDescriptorProto::EnumDescriptorProto(EnumDescriptorProto&&) noexcept = default;
8558 EnumDescriptorProto& EnumDescriptorProto::operator=(EnumDescriptorProto&&) = default;
8559
operator ==(const EnumDescriptorProto & other) const8560 bool EnumDescriptorProto::operator==(const EnumDescriptorProto& other) const {
8561 return unknown_fields_ == other.unknown_fields_
8562 && name_ == other.name_
8563 && value_ == other.value_
8564 && reserved_name_ == other.reserved_name_;
8565 }
8566
ParseFromArray(const void * raw,size_t size)8567 bool EnumDescriptorProto::ParseFromArray(const void* raw, size_t size) {
8568 value_.clear();
8569 reserved_name_.clear();
8570 unknown_fields_.clear();
8571 bool packed_error = false;
8572
8573 ::protozero::ProtoDecoder dec(raw, size);
8574 for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
8575 if (field.id() < _has_field_.size()) {
8576 _has_field_.set(field.id());
8577 }
8578 switch (field.id()) {
8579 case 1 /* name */:
8580 field.get(&name_);
8581 break;
8582 case 2 /* value */:
8583 value_.emplace_back();
8584 value_.back().ParseFromString(field.as_std_string());
8585 break;
8586 case 5 /* reserved_name */:
8587 reserved_name_.emplace_back();
8588 field.get(&reserved_name_.back());
8589 break;
8590 default:
8591 field.SerializeAndAppendTo(&unknown_fields_);
8592 break;
8593 }
8594 }
8595 return !packed_error && !dec.bytes_left();
8596 }
8597
SerializeAsString() const8598 std::string EnumDescriptorProto::SerializeAsString() const {
8599 ::protozero::HeapBuffered<::protozero::Message> msg;
8600 Serialize(msg.get());
8601 return msg.SerializeAsString();
8602 }
8603
SerializeAsArray() const8604 std::vector<uint8_t> EnumDescriptorProto::SerializeAsArray() const {
8605 ::protozero::HeapBuffered<::protozero::Message> msg;
8606 Serialize(msg.get());
8607 return msg.SerializeAsArray();
8608 }
8609
Serialize(::protozero::Message * msg) const8610 void EnumDescriptorProto::Serialize(::protozero::Message* msg) const {
8611 // Field 1: name
8612 if (_has_field_[1]) {
8613 msg->AppendString(1, name_);
8614 }
8615
8616 // Field 2: value
8617 for (auto& it : value_) {
8618 it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
8619 }
8620
8621 // Field 5: reserved_name
8622 for (auto& it : reserved_name_) {
8623 msg->AppendString(5, it);
8624 }
8625
8626 msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
8627 }
8628
8629
8630 OneofDescriptorProto::OneofDescriptorProto() = default;
8631 OneofDescriptorProto::~OneofDescriptorProto() = default;
8632 OneofDescriptorProto::OneofDescriptorProto(const OneofDescriptorProto&) = default;
8633 OneofDescriptorProto& OneofDescriptorProto::operator=(const OneofDescriptorProto&) = default;
8634 OneofDescriptorProto::OneofDescriptorProto(OneofDescriptorProto&&) noexcept = default;
8635 OneofDescriptorProto& OneofDescriptorProto::operator=(OneofDescriptorProto&&) = default;
8636
operator ==(const OneofDescriptorProto & other) const8637 bool OneofDescriptorProto::operator==(const OneofDescriptorProto& other) const {
8638 return unknown_fields_ == other.unknown_fields_
8639 && name_ == other.name_
8640 && options_ == other.options_;
8641 }
8642
ParseFromArray(const void * raw,size_t size)8643 bool OneofDescriptorProto::ParseFromArray(const void* raw, size_t size) {
8644 unknown_fields_.clear();
8645 bool packed_error = false;
8646
8647 ::protozero::ProtoDecoder dec(raw, size);
8648 for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
8649 if (field.id() < _has_field_.size()) {
8650 _has_field_.set(field.id());
8651 }
8652 switch (field.id()) {
8653 case 1 /* name */:
8654 field.get(&name_);
8655 break;
8656 case 2 /* options */:
8657 (*options_).ParseFromString(field.as_std_string());
8658 break;
8659 default:
8660 field.SerializeAndAppendTo(&unknown_fields_);
8661 break;
8662 }
8663 }
8664 return !packed_error && !dec.bytes_left();
8665 }
8666
SerializeAsString() const8667 std::string OneofDescriptorProto::SerializeAsString() const {
8668 ::protozero::HeapBuffered<::protozero::Message> msg;
8669 Serialize(msg.get());
8670 return msg.SerializeAsString();
8671 }
8672
SerializeAsArray() const8673 std::vector<uint8_t> OneofDescriptorProto::SerializeAsArray() const {
8674 ::protozero::HeapBuffered<::protozero::Message> msg;
8675 Serialize(msg.get());
8676 return msg.SerializeAsArray();
8677 }
8678
Serialize(::protozero::Message * msg) const8679 void OneofDescriptorProto::Serialize(::protozero::Message* msg) const {
8680 // Field 1: name
8681 if (_has_field_[1]) {
8682 msg->AppendString(1, name_);
8683 }
8684
8685 // Field 2: options
8686 if (_has_field_[2]) {
8687 (*options_).Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
8688 }
8689
8690 msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
8691 }
8692
8693
8694 FieldDescriptorProto::FieldDescriptorProto() = default;
8695 FieldDescriptorProto::~FieldDescriptorProto() = default;
8696 FieldDescriptorProto::FieldDescriptorProto(const FieldDescriptorProto&) = default;
8697 FieldDescriptorProto& FieldDescriptorProto::operator=(const FieldDescriptorProto&) = default;
8698 FieldDescriptorProto::FieldDescriptorProto(FieldDescriptorProto&&) noexcept = default;
8699 FieldDescriptorProto& FieldDescriptorProto::operator=(FieldDescriptorProto&&) = default;
8700
operator ==(const FieldDescriptorProto & other) const8701 bool FieldDescriptorProto::operator==(const FieldDescriptorProto& other) const {
8702 return unknown_fields_ == other.unknown_fields_
8703 && name_ == other.name_
8704 && number_ == other.number_
8705 && label_ == other.label_
8706 && type_ == other.type_
8707 && type_name_ == other.type_name_
8708 && extendee_ == other.extendee_
8709 && default_value_ == other.default_value_
8710 && oneof_index_ == other.oneof_index_;
8711 }
8712
ParseFromArray(const void * raw,size_t size)8713 bool FieldDescriptorProto::ParseFromArray(const void* raw, size_t size) {
8714 unknown_fields_.clear();
8715 bool packed_error = false;
8716
8717 ::protozero::ProtoDecoder dec(raw, size);
8718 for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
8719 if (field.id() < _has_field_.size()) {
8720 _has_field_.set(field.id());
8721 }
8722 switch (field.id()) {
8723 case 1 /* name */:
8724 field.get(&name_);
8725 break;
8726 case 3 /* number */:
8727 field.get(&number_);
8728 break;
8729 case 4 /* label */:
8730 field.get(&label_);
8731 break;
8732 case 5 /* type */:
8733 field.get(&type_);
8734 break;
8735 case 6 /* type_name */:
8736 field.get(&type_name_);
8737 break;
8738 case 2 /* extendee */:
8739 field.get(&extendee_);
8740 break;
8741 case 7 /* default_value */:
8742 field.get(&default_value_);
8743 break;
8744 case 9 /* oneof_index */:
8745 field.get(&oneof_index_);
8746 break;
8747 default:
8748 field.SerializeAndAppendTo(&unknown_fields_);
8749 break;
8750 }
8751 }
8752 return !packed_error && !dec.bytes_left();
8753 }
8754
SerializeAsString() const8755 std::string FieldDescriptorProto::SerializeAsString() const {
8756 ::protozero::HeapBuffered<::protozero::Message> msg;
8757 Serialize(msg.get());
8758 return msg.SerializeAsString();
8759 }
8760
SerializeAsArray() const8761 std::vector<uint8_t> FieldDescriptorProto::SerializeAsArray() const {
8762 ::protozero::HeapBuffered<::protozero::Message> msg;
8763 Serialize(msg.get());
8764 return msg.SerializeAsArray();
8765 }
8766
Serialize(::protozero::Message * msg) const8767 void FieldDescriptorProto::Serialize(::protozero::Message* msg) const {
8768 // Field 1: name
8769 if (_has_field_[1]) {
8770 msg->AppendString(1, name_);
8771 }
8772
8773 // Field 3: number
8774 if (_has_field_[3]) {
8775 msg->AppendVarInt(3, number_);
8776 }
8777
8778 // Field 4: label
8779 if (_has_field_[4]) {
8780 msg->AppendVarInt(4, label_);
8781 }
8782
8783 // Field 5: type
8784 if (_has_field_[5]) {
8785 msg->AppendVarInt(5, type_);
8786 }
8787
8788 // Field 6: type_name
8789 if (_has_field_[6]) {
8790 msg->AppendString(6, type_name_);
8791 }
8792
8793 // Field 2: extendee
8794 if (_has_field_[2]) {
8795 msg->AppendString(2, extendee_);
8796 }
8797
8798 // Field 7: default_value
8799 if (_has_field_[7]) {
8800 msg->AppendString(7, default_value_);
8801 }
8802
8803 // Field 9: oneof_index
8804 if (_has_field_[9]) {
8805 msg->AppendVarInt(9, oneof_index_);
8806 }
8807
8808 msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
8809 }
8810
8811
8812 DescriptorProto::DescriptorProto() = default;
8813 DescriptorProto::~DescriptorProto() = default;
8814 DescriptorProto::DescriptorProto(const DescriptorProto&) = default;
8815 DescriptorProto& DescriptorProto::operator=(const DescriptorProto&) = default;
8816 DescriptorProto::DescriptorProto(DescriptorProto&&) noexcept = default;
8817 DescriptorProto& DescriptorProto::operator=(DescriptorProto&&) = default;
8818
operator ==(const DescriptorProto & other) const8819 bool DescriptorProto::operator==(const DescriptorProto& other) const {
8820 return unknown_fields_ == other.unknown_fields_
8821 && name_ == other.name_
8822 && field_ == other.field_
8823 && extension_ == other.extension_
8824 && nested_type_ == other.nested_type_
8825 && enum_type_ == other.enum_type_
8826 && oneof_decl_ == other.oneof_decl_
8827 && reserved_range_ == other.reserved_range_
8828 && reserved_name_ == other.reserved_name_;
8829 }
8830
ParseFromArray(const void * raw,size_t size)8831 bool DescriptorProto::ParseFromArray(const void* raw, size_t size) {
8832 field_.clear();
8833 extension_.clear();
8834 nested_type_.clear();
8835 enum_type_.clear();
8836 oneof_decl_.clear();
8837 reserved_range_.clear();
8838 reserved_name_.clear();
8839 unknown_fields_.clear();
8840 bool packed_error = false;
8841
8842 ::protozero::ProtoDecoder dec(raw, size);
8843 for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
8844 if (field.id() < _has_field_.size()) {
8845 _has_field_.set(field.id());
8846 }
8847 switch (field.id()) {
8848 case 1 /* name */:
8849 field.get(&name_);
8850 break;
8851 case 2 /* field */:
8852 field_.emplace_back();
8853 field_.back().ParseFromString(field.as_std_string());
8854 break;
8855 case 6 /* extension */:
8856 extension_.emplace_back();
8857 extension_.back().ParseFromString(field.as_std_string());
8858 break;
8859 case 3 /* nested_type */:
8860 nested_type_.emplace_back();
8861 nested_type_.back().ParseFromString(field.as_std_string());
8862 break;
8863 case 4 /* enum_type */:
8864 enum_type_.emplace_back();
8865 enum_type_.back().ParseFromString(field.as_std_string());
8866 break;
8867 case 8 /* oneof_decl */:
8868 oneof_decl_.emplace_back();
8869 oneof_decl_.back().ParseFromString(field.as_std_string());
8870 break;
8871 case 9 /* reserved_range */:
8872 reserved_range_.emplace_back();
8873 reserved_range_.back().ParseFromString(field.as_std_string());
8874 break;
8875 case 10 /* reserved_name */:
8876 reserved_name_.emplace_back();
8877 field.get(&reserved_name_.back());
8878 break;
8879 default:
8880 field.SerializeAndAppendTo(&unknown_fields_);
8881 break;
8882 }
8883 }
8884 return !packed_error && !dec.bytes_left();
8885 }
8886
SerializeAsString() const8887 std::string DescriptorProto::SerializeAsString() const {
8888 ::protozero::HeapBuffered<::protozero::Message> msg;
8889 Serialize(msg.get());
8890 return msg.SerializeAsString();
8891 }
8892
SerializeAsArray() const8893 std::vector<uint8_t> DescriptorProto::SerializeAsArray() const {
8894 ::protozero::HeapBuffered<::protozero::Message> msg;
8895 Serialize(msg.get());
8896 return msg.SerializeAsArray();
8897 }
8898
Serialize(::protozero::Message * msg) const8899 void DescriptorProto::Serialize(::protozero::Message* msg) const {
8900 // Field 1: name
8901 if (_has_field_[1]) {
8902 msg->AppendString(1, name_);
8903 }
8904
8905 // Field 2: field
8906 for (auto& it : field_) {
8907 it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
8908 }
8909
8910 // Field 6: extension
8911 for (auto& it : extension_) {
8912 it.Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
8913 }
8914
8915 // Field 3: nested_type
8916 for (auto& it : nested_type_) {
8917 it.Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
8918 }
8919
8920 // Field 4: enum_type
8921 for (auto& it : enum_type_) {
8922 it.Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
8923 }
8924
8925 // Field 8: oneof_decl
8926 for (auto& it : oneof_decl_) {
8927 it.Serialize(msg->BeginNestedMessage<::protozero::Message>(8));
8928 }
8929
8930 // Field 9: reserved_range
8931 for (auto& it : reserved_range_) {
8932 it.Serialize(msg->BeginNestedMessage<::protozero::Message>(9));
8933 }
8934
8935 // Field 10: reserved_name
8936 for (auto& it : reserved_name_) {
8937 msg->AppendString(10, it);
8938 }
8939
8940 msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
8941 }
8942
8943
8944 DescriptorProto_ReservedRange::DescriptorProto_ReservedRange() = default;
8945 DescriptorProto_ReservedRange::~DescriptorProto_ReservedRange() = default;
8946 DescriptorProto_ReservedRange::DescriptorProto_ReservedRange(const DescriptorProto_ReservedRange&) = default;
8947 DescriptorProto_ReservedRange& DescriptorProto_ReservedRange::operator=(const DescriptorProto_ReservedRange&) = default;
8948 DescriptorProto_ReservedRange::DescriptorProto_ReservedRange(DescriptorProto_ReservedRange&&) noexcept = default;
8949 DescriptorProto_ReservedRange& DescriptorProto_ReservedRange::operator=(DescriptorProto_ReservedRange&&) = default;
8950
operator ==(const DescriptorProto_ReservedRange & other) const8951 bool DescriptorProto_ReservedRange::operator==(const DescriptorProto_ReservedRange& other) const {
8952 return unknown_fields_ == other.unknown_fields_
8953 && start_ == other.start_
8954 && end_ == other.end_;
8955 }
8956
ParseFromArray(const void * raw,size_t size)8957 bool DescriptorProto_ReservedRange::ParseFromArray(const void* raw, size_t size) {
8958 unknown_fields_.clear();
8959 bool packed_error = false;
8960
8961 ::protozero::ProtoDecoder dec(raw, size);
8962 for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
8963 if (field.id() < _has_field_.size()) {
8964 _has_field_.set(field.id());
8965 }
8966 switch (field.id()) {
8967 case 1 /* start */:
8968 field.get(&start_);
8969 break;
8970 case 2 /* end */:
8971 field.get(&end_);
8972 break;
8973 default:
8974 field.SerializeAndAppendTo(&unknown_fields_);
8975 break;
8976 }
8977 }
8978 return !packed_error && !dec.bytes_left();
8979 }
8980
SerializeAsString() const8981 std::string DescriptorProto_ReservedRange::SerializeAsString() const {
8982 ::protozero::HeapBuffered<::protozero::Message> msg;
8983 Serialize(msg.get());
8984 return msg.SerializeAsString();
8985 }
8986
SerializeAsArray() const8987 std::vector<uint8_t> DescriptorProto_ReservedRange::SerializeAsArray() const {
8988 ::protozero::HeapBuffered<::protozero::Message> msg;
8989 Serialize(msg.get());
8990 return msg.SerializeAsArray();
8991 }
8992
Serialize(::protozero::Message * msg) const8993 void DescriptorProto_ReservedRange::Serialize(::protozero::Message* msg) const {
8994 // Field 1: start
8995 if (_has_field_[1]) {
8996 msg->AppendVarInt(1, start_);
8997 }
8998
8999 // Field 2: end
9000 if (_has_field_[2]) {
9001 msg->AppendVarInt(2, end_);
9002 }
9003
9004 msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
9005 }
9006
9007
9008 FileDescriptorProto::FileDescriptorProto() = default;
9009 FileDescriptorProto::~FileDescriptorProto() = default;
9010 FileDescriptorProto::FileDescriptorProto(const FileDescriptorProto&) = default;
9011 FileDescriptorProto& FileDescriptorProto::operator=(const FileDescriptorProto&) = default;
9012 FileDescriptorProto::FileDescriptorProto(FileDescriptorProto&&) noexcept = default;
9013 FileDescriptorProto& FileDescriptorProto::operator=(FileDescriptorProto&&) = default;
9014
operator ==(const FileDescriptorProto & other) const9015 bool FileDescriptorProto::operator==(const FileDescriptorProto& other) const {
9016 return unknown_fields_ == other.unknown_fields_
9017 && name_ == other.name_
9018 && package_ == other.package_
9019 && dependency_ == other.dependency_
9020 && public_dependency_ == other.public_dependency_
9021 && weak_dependency_ == other.weak_dependency_
9022 && message_type_ == other.message_type_
9023 && enum_type_ == other.enum_type_
9024 && extension_ == other.extension_;
9025 }
9026
ParseFromArray(const void * raw,size_t size)9027 bool FileDescriptorProto::ParseFromArray(const void* raw, size_t size) {
9028 dependency_.clear();
9029 public_dependency_.clear();
9030 weak_dependency_.clear();
9031 message_type_.clear();
9032 enum_type_.clear();
9033 extension_.clear();
9034 unknown_fields_.clear();
9035 bool packed_error = false;
9036
9037 ::protozero::ProtoDecoder dec(raw, size);
9038 for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
9039 if (field.id() < _has_field_.size()) {
9040 _has_field_.set(field.id());
9041 }
9042 switch (field.id()) {
9043 case 1 /* name */:
9044 field.get(&name_);
9045 break;
9046 case 2 /* package */:
9047 field.get(&package_);
9048 break;
9049 case 3 /* dependency */:
9050 dependency_.emplace_back();
9051 field.get(&dependency_.back());
9052 break;
9053 case 10 /* public_dependency */:
9054 public_dependency_.emplace_back();
9055 field.get(&public_dependency_.back());
9056 break;
9057 case 11 /* weak_dependency */:
9058 weak_dependency_.emplace_back();
9059 field.get(&weak_dependency_.back());
9060 break;
9061 case 4 /* message_type */:
9062 message_type_.emplace_back();
9063 message_type_.back().ParseFromString(field.as_std_string());
9064 break;
9065 case 5 /* enum_type */:
9066 enum_type_.emplace_back();
9067 enum_type_.back().ParseFromString(field.as_std_string());
9068 break;
9069 case 7 /* extension */:
9070 extension_.emplace_back();
9071 extension_.back().ParseFromString(field.as_std_string());
9072 break;
9073 default:
9074 field.SerializeAndAppendTo(&unknown_fields_);
9075 break;
9076 }
9077 }
9078 return !packed_error && !dec.bytes_left();
9079 }
9080
SerializeAsString() const9081 std::string FileDescriptorProto::SerializeAsString() const {
9082 ::protozero::HeapBuffered<::protozero::Message> msg;
9083 Serialize(msg.get());
9084 return msg.SerializeAsString();
9085 }
9086
SerializeAsArray() const9087 std::vector<uint8_t> FileDescriptorProto::SerializeAsArray() const {
9088 ::protozero::HeapBuffered<::protozero::Message> msg;
9089 Serialize(msg.get());
9090 return msg.SerializeAsArray();
9091 }
9092
Serialize(::protozero::Message * msg) const9093 void FileDescriptorProto::Serialize(::protozero::Message* msg) const {
9094 // Field 1: name
9095 if (_has_field_[1]) {
9096 msg->AppendString(1, name_);
9097 }
9098
9099 // Field 2: package
9100 if (_has_field_[2]) {
9101 msg->AppendString(2, package_);
9102 }
9103
9104 // Field 3: dependency
9105 for (auto& it : dependency_) {
9106 msg->AppendString(3, it);
9107 }
9108
9109 // Field 10: public_dependency
9110 for (auto& it : public_dependency_) {
9111 msg->AppendVarInt(10, it);
9112 }
9113
9114 // Field 11: weak_dependency
9115 for (auto& it : weak_dependency_) {
9116 msg->AppendVarInt(11, it);
9117 }
9118
9119 // Field 4: message_type
9120 for (auto& it : message_type_) {
9121 it.Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
9122 }
9123
9124 // Field 5: enum_type
9125 for (auto& it : enum_type_) {
9126 it.Serialize(msg->BeginNestedMessage<::protozero::Message>(5));
9127 }
9128
9129 // Field 7: extension
9130 for (auto& it : extension_) {
9131 it.Serialize(msg->BeginNestedMessage<::protozero::Message>(7));
9132 }
9133
9134 msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
9135 }
9136
9137
9138 FileDescriptorSet::FileDescriptorSet() = default;
9139 FileDescriptorSet::~FileDescriptorSet() = default;
9140 FileDescriptorSet::FileDescriptorSet(const FileDescriptorSet&) = default;
9141 FileDescriptorSet& FileDescriptorSet::operator=(const FileDescriptorSet&) = default;
9142 FileDescriptorSet::FileDescriptorSet(FileDescriptorSet&&) noexcept = default;
9143 FileDescriptorSet& FileDescriptorSet::operator=(FileDescriptorSet&&) = default;
9144
operator ==(const FileDescriptorSet & other) const9145 bool FileDescriptorSet::operator==(const FileDescriptorSet& other) const {
9146 return unknown_fields_ == other.unknown_fields_
9147 && file_ == other.file_;
9148 }
9149
ParseFromArray(const void * raw,size_t size)9150 bool FileDescriptorSet::ParseFromArray(const void* raw, size_t size) {
9151 file_.clear();
9152 unknown_fields_.clear();
9153 bool packed_error = false;
9154
9155 ::protozero::ProtoDecoder dec(raw, size);
9156 for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
9157 if (field.id() < _has_field_.size()) {
9158 _has_field_.set(field.id());
9159 }
9160 switch (field.id()) {
9161 case 1 /* file */:
9162 file_.emplace_back();
9163 file_.back().ParseFromString(field.as_std_string());
9164 break;
9165 default:
9166 field.SerializeAndAppendTo(&unknown_fields_);
9167 break;
9168 }
9169 }
9170 return !packed_error && !dec.bytes_left();
9171 }
9172
SerializeAsString() const9173 std::string FileDescriptorSet::SerializeAsString() const {
9174 ::protozero::HeapBuffered<::protozero::Message> msg;
9175 Serialize(msg.get());
9176 return msg.SerializeAsString();
9177 }
9178
SerializeAsArray() const9179 std::vector<uint8_t> FileDescriptorSet::SerializeAsArray() const {
9180 ::protozero::HeapBuffered<::protozero::Message> msg;
9181 Serialize(msg.get());
9182 return msg.SerializeAsArray();
9183 }
9184
Serialize(::protozero::Message * msg) const9185 void FileDescriptorSet::Serialize(::protozero::Message* msg) const {
9186 // Field 1: file
9187 for (auto& it : file_) {
9188 it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
9189 }
9190
9191 msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
9192 }
9193
9194 } // namespace perfetto
9195 } // namespace protos
9196 } // namespace gen
9197 #pragma GCC diagnostic pop
9198 // gen_amalgamated begin source: gen/protos/perfetto/common/gpu_counter_descriptor.gen.cc
9199 // gen_amalgamated begin header: gen/protos/perfetto/common/gpu_counter_descriptor.gen.h
9200 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
9201 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_GPU_COUNTER_DESCRIPTOR_PROTO_CPP_H_
9202 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_GPU_COUNTER_DESCRIPTOR_PROTO_CPP_H_
9203
9204 #include <stdint.h>
9205 #include <bitset>
9206 #include <vector>
9207 #include <string>
9208 #include <type_traits>
9209
9210 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
9211 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
9212 // gen_amalgamated expanded: #include "perfetto/base/export.h"
9213
9214 namespace perfetto {
9215 namespace protos {
9216 namespace gen {
9217 class GpuCounterDescriptor;
9218 class GpuCounterDescriptor_GpuCounterBlock;
9219 class GpuCounterDescriptor_GpuCounterSpec;
9220 enum GpuCounterDescriptor_GpuCounterGroup : int;
9221 enum GpuCounterDescriptor_MeasureUnit : int;
9222 } // namespace perfetto
9223 } // namespace protos
9224 } // namespace gen
9225
9226 namespace protozero {
9227 class Message;
9228 } // namespace protozero
9229
9230 namespace perfetto {
9231 namespace protos {
9232 namespace gen {
9233 enum GpuCounterDescriptor_GpuCounterGroup : int {
9234 GpuCounterDescriptor_GpuCounterGroup_UNCLASSIFIED = 0,
9235 GpuCounterDescriptor_GpuCounterGroup_SYSTEM = 1,
9236 GpuCounterDescriptor_GpuCounterGroup_VERTICES = 2,
9237 GpuCounterDescriptor_GpuCounterGroup_FRAGMENTS = 3,
9238 GpuCounterDescriptor_GpuCounterGroup_PRIMITIVES = 4,
9239 GpuCounterDescriptor_GpuCounterGroup_MEMORY = 5,
9240 GpuCounterDescriptor_GpuCounterGroup_COMPUTE = 6,
9241 };
9242 enum GpuCounterDescriptor_MeasureUnit : int {
9243 GpuCounterDescriptor_MeasureUnit_NONE = 0,
9244 GpuCounterDescriptor_MeasureUnit_BIT = 1,
9245 GpuCounterDescriptor_MeasureUnit_KILOBIT = 2,
9246 GpuCounterDescriptor_MeasureUnit_MEGABIT = 3,
9247 GpuCounterDescriptor_MeasureUnit_GIGABIT = 4,
9248 GpuCounterDescriptor_MeasureUnit_TERABIT = 5,
9249 GpuCounterDescriptor_MeasureUnit_PETABIT = 6,
9250 GpuCounterDescriptor_MeasureUnit_BYTE = 7,
9251 GpuCounterDescriptor_MeasureUnit_KILOBYTE = 8,
9252 GpuCounterDescriptor_MeasureUnit_MEGABYTE = 9,
9253 GpuCounterDescriptor_MeasureUnit_GIGABYTE = 10,
9254 GpuCounterDescriptor_MeasureUnit_TERABYTE = 11,
9255 GpuCounterDescriptor_MeasureUnit_PETABYTE = 12,
9256 GpuCounterDescriptor_MeasureUnit_HERTZ = 13,
9257 GpuCounterDescriptor_MeasureUnit_KILOHERTZ = 14,
9258 GpuCounterDescriptor_MeasureUnit_MEGAHERTZ = 15,
9259 GpuCounterDescriptor_MeasureUnit_GIGAHERTZ = 16,
9260 GpuCounterDescriptor_MeasureUnit_TERAHERTZ = 17,
9261 GpuCounterDescriptor_MeasureUnit_PETAHERTZ = 18,
9262 GpuCounterDescriptor_MeasureUnit_NANOSECOND = 19,
9263 GpuCounterDescriptor_MeasureUnit_MICROSECOND = 20,
9264 GpuCounterDescriptor_MeasureUnit_MILLISECOND = 21,
9265 GpuCounterDescriptor_MeasureUnit_SECOND = 22,
9266 GpuCounterDescriptor_MeasureUnit_MINUTE = 23,
9267 GpuCounterDescriptor_MeasureUnit_HOUR = 24,
9268 GpuCounterDescriptor_MeasureUnit_VERTEX = 25,
9269 GpuCounterDescriptor_MeasureUnit_PIXEL = 26,
9270 GpuCounterDescriptor_MeasureUnit_TRIANGLE = 27,
9271 GpuCounterDescriptor_MeasureUnit_PRIMITIVE = 38,
9272 GpuCounterDescriptor_MeasureUnit_FRAGMENT = 39,
9273 GpuCounterDescriptor_MeasureUnit_MILLIWATT = 28,
9274 GpuCounterDescriptor_MeasureUnit_WATT = 29,
9275 GpuCounterDescriptor_MeasureUnit_KILOWATT = 30,
9276 GpuCounterDescriptor_MeasureUnit_JOULE = 31,
9277 GpuCounterDescriptor_MeasureUnit_VOLT = 32,
9278 GpuCounterDescriptor_MeasureUnit_AMPERE = 33,
9279 GpuCounterDescriptor_MeasureUnit_CELSIUS = 34,
9280 GpuCounterDescriptor_MeasureUnit_FAHRENHEIT = 35,
9281 GpuCounterDescriptor_MeasureUnit_KELVIN = 36,
9282 GpuCounterDescriptor_MeasureUnit_PERCENT = 37,
9283 GpuCounterDescriptor_MeasureUnit_INSTRUCTION = 40,
9284 };
9285
9286 class PERFETTO_EXPORT GpuCounterDescriptor : public ::protozero::CppMessageObj {
9287 public:
9288 using GpuCounterSpec = GpuCounterDescriptor_GpuCounterSpec;
9289 using GpuCounterBlock = GpuCounterDescriptor_GpuCounterBlock;
9290 using GpuCounterGroup = GpuCounterDescriptor_GpuCounterGroup;
9291 static constexpr auto UNCLASSIFIED = GpuCounterDescriptor_GpuCounterGroup_UNCLASSIFIED;
9292 static constexpr auto SYSTEM = GpuCounterDescriptor_GpuCounterGroup_SYSTEM;
9293 static constexpr auto VERTICES = GpuCounterDescriptor_GpuCounterGroup_VERTICES;
9294 static constexpr auto FRAGMENTS = GpuCounterDescriptor_GpuCounterGroup_FRAGMENTS;
9295 static constexpr auto PRIMITIVES = GpuCounterDescriptor_GpuCounterGroup_PRIMITIVES;
9296 static constexpr auto MEMORY = GpuCounterDescriptor_GpuCounterGroup_MEMORY;
9297 static constexpr auto COMPUTE = GpuCounterDescriptor_GpuCounterGroup_COMPUTE;
9298 static constexpr auto GpuCounterGroup_MIN = GpuCounterDescriptor_GpuCounterGroup_UNCLASSIFIED;
9299 static constexpr auto GpuCounterGroup_MAX = GpuCounterDescriptor_GpuCounterGroup_COMPUTE;
9300 using MeasureUnit = GpuCounterDescriptor_MeasureUnit;
9301 static constexpr auto NONE = GpuCounterDescriptor_MeasureUnit_NONE;
9302 static constexpr auto BIT = GpuCounterDescriptor_MeasureUnit_BIT;
9303 static constexpr auto KILOBIT = GpuCounterDescriptor_MeasureUnit_KILOBIT;
9304 static constexpr auto MEGABIT = GpuCounterDescriptor_MeasureUnit_MEGABIT;
9305 static constexpr auto GIGABIT = GpuCounterDescriptor_MeasureUnit_GIGABIT;
9306 static constexpr auto TERABIT = GpuCounterDescriptor_MeasureUnit_TERABIT;
9307 static constexpr auto PETABIT = GpuCounterDescriptor_MeasureUnit_PETABIT;
9308 static constexpr auto BYTE = GpuCounterDescriptor_MeasureUnit_BYTE;
9309 static constexpr auto KILOBYTE = GpuCounterDescriptor_MeasureUnit_KILOBYTE;
9310 static constexpr auto MEGABYTE = GpuCounterDescriptor_MeasureUnit_MEGABYTE;
9311 static constexpr auto GIGABYTE = GpuCounterDescriptor_MeasureUnit_GIGABYTE;
9312 static constexpr auto TERABYTE = GpuCounterDescriptor_MeasureUnit_TERABYTE;
9313 static constexpr auto PETABYTE = GpuCounterDescriptor_MeasureUnit_PETABYTE;
9314 static constexpr auto HERTZ = GpuCounterDescriptor_MeasureUnit_HERTZ;
9315 static constexpr auto KILOHERTZ = GpuCounterDescriptor_MeasureUnit_KILOHERTZ;
9316 static constexpr auto MEGAHERTZ = GpuCounterDescriptor_MeasureUnit_MEGAHERTZ;
9317 static constexpr auto GIGAHERTZ = GpuCounterDescriptor_MeasureUnit_GIGAHERTZ;
9318 static constexpr auto TERAHERTZ = GpuCounterDescriptor_MeasureUnit_TERAHERTZ;
9319 static constexpr auto PETAHERTZ = GpuCounterDescriptor_MeasureUnit_PETAHERTZ;
9320 static constexpr auto NANOSECOND = GpuCounterDescriptor_MeasureUnit_NANOSECOND;
9321 static constexpr auto MICROSECOND = GpuCounterDescriptor_MeasureUnit_MICROSECOND;
9322 static constexpr auto MILLISECOND = GpuCounterDescriptor_MeasureUnit_MILLISECOND;
9323 static constexpr auto SECOND = GpuCounterDescriptor_MeasureUnit_SECOND;
9324 static constexpr auto MINUTE = GpuCounterDescriptor_MeasureUnit_MINUTE;
9325 static constexpr auto HOUR = GpuCounterDescriptor_MeasureUnit_HOUR;
9326 static constexpr auto VERTEX = GpuCounterDescriptor_MeasureUnit_VERTEX;
9327 static constexpr auto PIXEL = GpuCounterDescriptor_MeasureUnit_PIXEL;
9328 static constexpr auto TRIANGLE = GpuCounterDescriptor_MeasureUnit_TRIANGLE;
9329 static constexpr auto PRIMITIVE = GpuCounterDescriptor_MeasureUnit_PRIMITIVE;
9330 static constexpr auto FRAGMENT = GpuCounterDescriptor_MeasureUnit_FRAGMENT;
9331 static constexpr auto MILLIWATT = GpuCounterDescriptor_MeasureUnit_MILLIWATT;
9332 static constexpr auto WATT = GpuCounterDescriptor_MeasureUnit_WATT;
9333 static constexpr auto KILOWATT = GpuCounterDescriptor_MeasureUnit_KILOWATT;
9334 static constexpr auto JOULE = GpuCounterDescriptor_MeasureUnit_JOULE;
9335 static constexpr auto VOLT = GpuCounterDescriptor_MeasureUnit_VOLT;
9336 static constexpr auto AMPERE = GpuCounterDescriptor_MeasureUnit_AMPERE;
9337 static constexpr auto CELSIUS = GpuCounterDescriptor_MeasureUnit_CELSIUS;
9338 static constexpr auto FAHRENHEIT = GpuCounterDescriptor_MeasureUnit_FAHRENHEIT;
9339 static constexpr auto KELVIN = GpuCounterDescriptor_MeasureUnit_KELVIN;
9340 static constexpr auto PERCENT = GpuCounterDescriptor_MeasureUnit_PERCENT;
9341 static constexpr auto INSTRUCTION = GpuCounterDescriptor_MeasureUnit_INSTRUCTION;
9342 static constexpr auto MeasureUnit_MIN = GpuCounterDescriptor_MeasureUnit_NONE;
9343 static constexpr auto MeasureUnit_MAX = GpuCounterDescriptor_MeasureUnit_INSTRUCTION;
9344 enum FieldNumbers {
9345 kSpecsFieldNumber = 1,
9346 kBlocksFieldNumber = 2,
9347 kMinSamplingPeriodNsFieldNumber = 3,
9348 kMaxSamplingPeriodNsFieldNumber = 4,
9349 kSupportsInstrumentedSamplingFieldNumber = 5,
9350 };
9351
9352 GpuCounterDescriptor();
9353 ~GpuCounterDescriptor() override;
9354 GpuCounterDescriptor(GpuCounterDescriptor&&) noexcept;
9355 GpuCounterDescriptor& operator=(GpuCounterDescriptor&&);
9356 GpuCounterDescriptor(const GpuCounterDescriptor&);
9357 GpuCounterDescriptor& operator=(const GpuCounterDescriptor&);
9358 bool operator==(const GpuCounterDescriptor&) const;
operator !=(const GpuCounterDescriptor & other) const9359 bool operator!=(const GpuCounterDescriptor& other) const { return !(*this == other); }
9360
9361 bool ParseFromArray(const void*, size_t) override;
9362 std::string SerializeAsString() const override;
9363 std::vector<uint8_t> SerializeAsArray() const override;
9364 void Serialize(::protozero::Message*) const;
9365
specs_size() const9366 int specs_size() const { return static_cast<int>(specs_.size()); }
specs() const9367 const std::vector<GpuCounterDescriptor_GpuCounterSpec>& specs() const { return specs_; }
mutable_specs()9368 std::vector<GpuCounterDescriptor_GpuCounterSpec>* mutable_specs() { return &specs_; }
clear_specs()9369 void clear_specs() { specs_.clear(); }
add_specs()9370 GpuCounterDescriptor_GpuCounterSpec* add_specs() { specs_.emplace_back(); return &specs_.back(); }
9371
blocks_size() const9372 int blocks_size() const { return static_cast<int>(blocks_.size()); }
blocks() const9373 const std::vector<GpuCounterDescriptor_GpuCounterBlock>& blocks() const { return blocks_; }
mutable_blocks()9374 std::vector<GpuCounterDescriptor_GpuCounterBlock>* mutable_blocks() { return &blocks_; }
clear_blocks()9375 void clear_blocks() { blocks_.clear(); }
add_blocks()9376 GpuCounterDescriptor_GpuCounterBlock* add_blocks() { blocks_.emplace_back(); return &blocks_.back(); }
9377
has_min_sampling_period_ns() const9378 bool has_min_sampling_period_ns() const { return _has_field_[3]; }
min_sampling_period_ns() const9379 uint64_t min_sampling_period_ns() const { return min_sampling_period_ns_; }
set_min_sampling_period_ns(uint64_t value)9380 void set_min_sampling_period_ns(uint64_t value) { min_sampling_period_ns_ = value; _has_field_.set(3); }
9381
has_max_sampling_period_ns() const9382 bool has_max_sampling_period_ns() const { return _has_field_[4]; }
max_sampling_period_ns() const9383 uint64_t max_sampling_period_ns() const { return max_sampling_period_ns_; }
set_max_sampling_period_ns(uint64_t value)9384 void set_max_sampling_period_ns(uint64_t value) { max_sampling_period_ns_ = value; _has_field_.set(4); }
9385
has_supports_instrumented_sampling() const9386 bool has_supports_instrumented_sampling() const { return _has_field_[5]; }
supports_instrumented_sampling() const9387 bool supports_instrumented_sampling() const { return supports_instrumented_sampling_; }
set_supports_instrumented_sampling(bool value)9388 void set_supports_instrumented_sampling(bool value) { supports_instrumented_sampling_ = value; _has_field_.set(5); }
9389
9390 private:
9391 std::vector<GpuCounterDescriptor_GpuCounterSpec> specs_;
9392 std::vector<GpuCounterDescriptor_GpuCounterBlock> blocks_;
9393 uint64_t min_sampling_period_ns_{};
9394 uint64_t max_sampling_period_ns_{};
9395 bool supports_instrumented_sampling_{};
9396
9397 // Allows to preserve unknown protobuf fields for compatibility
9398 // with future versions of .proto files.
9399 std::string unknown_fields_;
9400
9401 std::bitset<6> _has_field_{};
9402 };
9403
9404
9405 class PERFETTO_EXPORT GpuCounterDescriptor_GpuCounterBlock : public ::protozero::CppMessageObj {
9406 public:
9407 enum FieldNumbers {
9408 kBlockIdFieldNumber = 1,
9409 kBlockCapacityFieldNumber = 2,
9410 kNameFieldNumber = 3,
9411 kDescriptionFieldNumber = 4,
9412 kCounterIdsFieldNumber = 5,
9413 };
9414
9415 GpuCounterDescriptor_GpuCounterBlock();
9416 ~GpuCounterDescriptor_GpuCounterBlock() override;
9417 GpuCounterDescriptor_GpuCounterBlock(GpuCounterDescriptor_GpuCounterBlock&&) noexcept;
9418 GpuCounterDescriptor_GpuCounterBlock& operator=(GpuCounterDescriptor_GpuCounterBlock&&);
9419 GpuCounterDescriptor_GpuCounterBlock(const GpuCounterDescriptor_GpuCounterBlock&);
9420 GpuCounterDescriptor_GpuCounterBlock& operator=(const GpuCounterDescriptor_GpuCounterBlock&);
9421 bool operator==(const GpuCounterDescriptor_GpuCounterBlock&) const;
operator !=(const GpuCounterDescriptor_GpuCounterBlock & other) const9422 bool operator!=(const GpuCounterDescriptor_GpuCounterBlock& other) const { return !(*this == other); }
9423
9424 bool ParseFromArray(const void*, size_t) override;
9425 std::string SerializeAsString() const override;
9426 std::vector<uint8_t> SerializeAsArray() const override;
9427 void Serialize(::protozero::Message*) const;
9428
has_block_id() const9429 bool has_block_id() const { return _has_field_[1]; }
block_id() const9430 uint32_t block_id() const { return block_id_; }
set_block_id(uint32_t value)9431 void set_block_id(uint32_t value) { block_id_ = value; _has_field_.set(1); }
9432
has_block_capacity() const9433 bool has_block_capacity() const { return _has_field_[2]; }
block_capacity() const9434 uint32_t block_capacity() const { return block_capacity_; }
set_block_capacity(uint32_t value)9435 void set_block_capacity(uint32_t value) { block_capacity_ = value; _has_field_.set(2); }
9436
has_name() const9437 bool has_name() const { return _has_field_[3]; }
name() const9438 const std::string& name() const { return name_; }
set_name(const std::string & value)9439 void set_name(const std::string& value) { name_ = value; _has_field_.set(3); }
9440
has_description() const9441 bool has_description() const { return _has_field_[4]; }
description() const9442 const std::string& description() const { return description_; }
set_description(const std::string & value)9443 void set_description(const std::string& value) { description_ = value; _has_field_.set(4); }
9444
counter_ids_size() const9445 int counter_ids_size() const { return static_cast<int>(counter_ids_.size()); }
counter_ids() const9446 const std::vector<uint32_t>& counter_ids() const { return counter_ids_; }
mutable_counter_ids()9447 std::vector<uint32_t>* mutable_counter_ids() { return &counter_ids_; }
clear_counter_ids()9448 void clear_counter_ids() { counter_ids_.clear(); }
add_counter_ids(uint32_t value)9449 void add_counter_ids(uint32_t value) { counter_ids_.emplace_back(value); }
add_counter_ids()9450 uint32_t* add_counter_ids() { counter_ids_.emplace_back(); return &counter_ids_.back(); }
9451
9452 private:
9453 uint32_t block_id_{};
9454 uint32_t block_capacity_{};
9455 std::string name_{};
9456 std::string description_{};
9457 std::vector<uint32_t> counter_ids_;
9458
9459 // Allows to preserve unknown protobuf fields for compatibility
9460 // with future versions of .proto files.
9461 std::string unknown_fields_;
9462
9463 std::bitset<6> _has_field_{};
9464 };
9465
9466
9467 class PERFETTO_EXPORT GpuCounterDescriptor_GpuCounterSpec : public ::protozero::CppMessageObj {
9468 public:
9469 enum FieldNumbers {
9470 kCounterIdFieldNumber = 1,
9471 kNameFieldNumber = 2,
9472 kDescriptionFieldNumber = 3,
9473 kIntPeakValueFieldNumber = 5,
9474 kDoublePeakValueFieldNumber = 6,
9475 kNumeratorUnitsFieldNumber = 7,
9476 kDenominatorUnitsFieldNumber = 8,
9477 kSelectByDefaultFieldNumber = 9,
9478 kGroupsFieldNumber = 10,
9479 };
9480
9481 GpuCounterDescriptor_GpuCounterSpec();
9482 ~GpuCounterDescriptor_GpuCounterSpec() override;
9483 GpuCounterDescriptor_GpuCounterSpec(GpuCounterDescriptor_GpuCounterSpec&&) noexcept;
9484 GpuCounterDescriptor_GpuCounterSpec& operator=(GpuCounterDescriptor_GpuCounterSpec&&);
9485 GpuCounterDescriptor_GpuCounterSpec(const GpuCounterDescriptor_GpuCounterSpec&);
9486 GpuCounterDescriptor_GpuCounterSpec& operator=(const GpuCounterDescriptor_GpuCounterSpec&);
9487 bool operator==(const GpuCounterDescriptor_GpuCounterSpec&) const;
operator !=(const GpuCounterDescriptor_GpuCounterSpec & other) const9488 bool operator!=(const GpuCounterDescriptor_GpuCounterSpec& other) const { return !(*this == other); }
9489
9490 bool ParseFromArray(const void*, size_t) override;
9491 std::string SerializeAsString() const override;
9492 std::vector<uint8_t> SerializeAsArray() const override;
9493 void Serialize(::protozero::Message*) const;
9494
has_counter_id() const9495 bool has_counter_id() const { return _has_field_[1]; }
counter_id() const9496 uint32_t counter_id() const { return counter_id_; }
set_counter_id(uint32_t value)9497 void set_counter_id(uint32_t value) { counter_id_ = value; _has_field_.set(1); }
9498
has_name() const9499 bool has_name() const { return _has_field_[2]; }
name() const9500 const std::string& name() const { return name_; }
set_name(const std::string & value)9501 void set_name(const std::string& value) { name_ = value; _has_field_.set(2); }
9502
has_description() const9503 bool has_description() const { return _has_field_[3]; }
description() const9504 const std::string& description() const { return description_; }
set_description(const std::string & value)9505 void set_description(const std::string& value) { description_ = value; _has_field_.set(3); }
9506
has_int_peak_value() const9507 bool has_int_peak_value() const { return _has_field_[5]; }
int_peak_value() const9508 int64_t int_peak_value() const { return int_peak_value_; }
set_int_peak_value(int64_t value)9509 void set_int_peak_value(int64_t value) { int_peak_value_ = value; _has_field_.set(5); }
9510
has_double_peak_value() const9511 bool has_double_peak_value() const { return _has_field_[6]; }
double_peak_value() const9512 double double_peak_value() const { return double_peak_value_; }
set_double_peak_value(double value)9513 void set_double_peak_value(double value) { double_peak_value_ = value; _has_field_.set(6); }
9514
numerator_units_size() const9515 int numerator_units_size() const { return static_cast<int>(numerator_units_.size()); }
numerator_units() const9516 const std::vector<GpuCounterDescriptor_MeasureUnit>& numerator_units() const { return numerator_units_; }
mutable_numerator_units()9517 std::vector<GpuCounterDescriptor_MeasureUnit>* mutable_numerator_units() { return &numerator_units_; }
clear_numerator_units()9518 void clear_numerator_units() { numerator_units_.clear(); }
add_numerator_units(GpuCounterDescriptor_MeasureUnit value)9519 void add_numerator_units(GpuCounterDescriptor_MeasureUnit value) { numerator_units_.emplace_back(value); }
add_numerator_units()9520 GpuCounterDescriptor_MeasureUnit* add_numerator_units() { numerator_units_.emplace_back(); return &numerator_units_.back(); }
9521
denominator_units_size() const9522 int denominator_units_size() const { return static_cast<int>(denominator_units_.size()); }
denominator_units() const9523 const std::vector<GpuCounterDescriptor_MeasureUnit>& denominator_units() const { return denominator_units_; }
mutable_denominator_units()9524 std::vector<GpuCounterDescriptor_MeasureUnit>* mutable_denominator_units() { return &denominator_units_; }
clear_denominator_units()9525 void clear_denominator_units() { denominator_units_.clear(); }
add_denominator_units(GpuCounterDescriptor_MeasureUnit value)9526 void add_denominator_units(GpuCounterDescriptor_MeasureUnit value) { denominator_units_.emplace_back(value); }
add_denominator_units()9527 GpuCounterDescriptor_MeasureUnit* add_denominator_units() { denominator_units_.emplace_back(); return &denominator_units_.back(); }
9528
has_select_by_default() const9529 bool has_select_by_default() const { return _has_field_[9]; }
select_by_default() const9530 bool select_by_default() const { return select_by_default_; }
set_select_by_default(bool value)9531 void set_select_by_default(bool value) { select_by_default_ = value; _has_field_.set(9); }
9532
groups_size() const9533 int groups_size() const { return static_cast<int>(groups_.size()); }
groups() const9534 const std::vector<GpuCounterDescriptor_GpuCounterGroup>& groups() const { return groups_; }
mutable_groups()9535 std::vector<GpuCounterDescriptor_GpuCounterGroup>* mutable_groups() { return &groups_; }
clear_groups()9536 void clear_groups() { groups_.clear(); }
add_groups(GpuCounterDescriptor_GpuCounterGroup value)9537 void add_groups(GpuCounterDescriptor_GpuCounterGroup value) { groups_.emplace_back(value); }
add_groups()9538 GpuCounterDescriptor_GpuCounterGroup* add_groups() { groups_.emplace_back(); return &groups_.back(); }
9539
9540 private:
9541 uint32_t counter_id_{};
9542 std::string name_{};
9543 std::string description_{};
9544 int64_t int_peak_value_{};
9545 double double_peak_value_{};
9546 std::vector<GpuCounterDescriptor_MeasureUnit> numerator_units_;
9547 std::vector<GpuCounterDescriptor_MeasureUnit> denominator_units_;
9548 bool select_by_default_{};
9549 std::vector<GpuCounterDescriptor_GpuCounterGroup> groups_;
9550
9551 // Allows to preserve unknown protobuf fields for compatibility
9552 // with future versions of .proto files.
9553 std::string unknown_fields_;
9554
9555 std::bitset<11> _has_field_{};
9556 };
9557
9558 } // namespace perfetto
9559 } // namespace protos
9560 } // namespace gen
9561
9562 #endif // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_GPU_COUNTER_DESCRIPTOR_PROTO_CPP_H_
9563 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
9564 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
9565 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
9566 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
9567 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
9568 #pragma GCC diagnostic push
9569 #pragma GCC diagnostic ignored "-Wfloat-equal"
9570 // gen_amalgamated expanded: #include "protos/perfetto/common/gpu_counter_descriptor.gen.h"
9571
9572 namespace perfetto {
9573 namespace protos {
9574 namespace gen {
9575
9576 GpuCounterDescriptor::GpuCounterDescriptor() = default;
9577 GpuCounterDescriptor::~GpuCounterDescriptor() = default;
9578 GpuCounterDescriptor::GpuCounterDescriptor(const GpuCounterDescriptor&) = default;
9579 GpuCounterDescriptor& GpuCounterDescriptor::operator=(const GpuCounterDescriptor&) = default;
9580 GpuCounterDescriptor::GpuCounterDescriptor(GpuCounterDescriptor&&) noexcept = default;
9581 GpuCounterDescriptor& GpuCounterDescriptor::operator=(GpuCounterDescriptor&&) = default;
9582
operator ==(const GpuCounterDescriptor & other) const9583 bool GpuCounterDescriptor::operator==(const GpuCounterDescriptor& other) const {
9584 return unknown_fields_ == other.unknown_fields_
9585 && specs_ == other.specs_
9586 && blocks_ == other.blocks_
9587 && min_sampling_period_ns_ == other.min_sampling_period_ns_
9588 && max_sampling_period_ns_ == other.max_sampling_period_ns_
9589 && supports_instrumented_sampling_ == other.supports_instrumented_sampling_;
9590 }
9591
ParseFromArray(const void * raw,size_t size)9592 bool GpuCounterDescriptor::ParseFromArray(const void* raw, size_t size) {
9593 specs_.clear();
9594 blocks_.clear();
9595 unknown_fields_.clear();
9596 bool packed_error = false;
9597
9598 ::protozero::ProtoDecoder dec(raw, size);
9599 for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
9600 if (field.id() < _has_field_.size()) {
9601 _has_field_.set(field.id());
9602 }
9603 switch (field.id()) {
9604 case 1 /* specs */:
9605 specs_.emplace_back();
9606 specs_.back().ParseFromString(field.as_std_string());
9607 break;
9608 case 2 /* blocks */:
9609 blocks_.emplace_back();
9610 blocks_.back().ParseFromString(field.as_std_string());
9611 break;
9612 case 3 /* min_sampling_period_ns */:
9613 field.get(&min_sampling_period_ns_);
9614 break;
9615 case 4 /* max_sampling_period_ns */:
9616 field.get(&max_sampling_period_ns_);
9617 break;
9618 case 5 /* supports_instrumented_sampling */:
9619 field.get(&supports_instrumented_sampling_);
9620 break;
9621 default:
9622 field.SerializeAndAppendTo(&unknown_fields_);
9623 break;
9624 }
9625 }
9626 return !packed_error && !dec.bytes_left();
9627 }
9628
SerializeAsString() const9629 std::string GpuCounterDescriptor::SerializeAsString() const {
9630 ::protozero::HeapBuffered<::protozero::Message> msg;
9631 Serialize(msg.get());
9632 return msg.SerializeAsString();
9633 }
9634
SerializeAsArray() const9635 std::vector<uint8_t> GpuCounterDescriptor::SerializeAsArray() const {
9636 ::protozero::HeapBuffered<::protozero::Message> msg;
9637 Serialize(msg.get());
9638 return msg.SerializeAsArray();
9639 }
9640
Serialize(::protozero::Message * msg) const9641 void GpuCounterDescriptor::Serialize(::protozero::Message* msg) const {
9642 // Field 1: specs
9643 for (auto& it : specs_) {
9644 it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
9645 }
9646
9647 // Field 2: blocks
9648 for (auto& it : blocks_) {
9649 it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
9650 }
9651
9652 // Field 3: min_sampling_period_ns
9653 if (_has_field_[3]) {
9654 msg->AppendVarInt(3, min_sampling_period_ns_);
9655 }
9656
9657 // Field 4: max_sampling_period_ns
9658 if (_has_field_[4]) {
9659 msg->AppendVarInt(4, max_sampling_period_ns_);
9660 }
9661
9662 // Field 5: supports_instrumented_sampling
9663 if (_has_field_[5]) {
9664 msg->AppendTinyVarInt(5, supports_instrumented_sampling_);
9665 }
9666
9667 msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
9668 }
9669
9670
9671 GpuCounterDescriptor_GpuCounterBlock::GpuCounterDescriptor_GpuCounterBlock() = default;
9672 GpuCounterDescriptor_GpuCounterBlock::~GpuCounterDescriptor_GpuCounterBlock() = default;
9673 GpuCounterDescriptor_GpuCounterBlock::GpuCounterDescriptor_GpuCounterBlock(const GpuCounterDescriptor_GpuCounterBlock&) = default;
9674 GpuCounterDescriptor_GpuCounterBlock& GpuCounterDescriptor_GpuCounterBlock::operator=(const GpuCounterDescriptor_GpuCounterBlock&) = default;
9675 GpuCounterDescriptor_GpuCounterBlock::GpuCounterDescriptor_GpuCounterBlock(GpuCounterDescriptor_GpuCounterBlock&&) noexcept = default;
9676 GpuCounterDescriptor_GpuCounterBlock& GpuCounterDescriptor_GpuCounterBlock::operator=(GpuCounterDescriptor_GpuCounterBlock&&) = default;
9677
operator ==(const GpuCounterDescriptor_GpuCounterBlock & other) const9678 bool GpuCounterDescriptor_GpuCounterBlock::operator==(const GpuCounterDescriptor_GpuCounterBlock& other) const {
9679 return unknown_fields_ == other.unknown_fields_
9680 && block_id_ == other.block_id_
9681 && block_capacity_ == other.block_capacity_
9682 && name_ == other.name_
9683 && description_ == other.description_
9684 && counter_ids_ == other.counter_ids_;
9685 }
9686
ParseFromArray(const void * raw,size_t size)9687 bool GpuCounterDescriptor_GpuCounterBlock::ParseFromArray(const void* raw, size_t size) {
9688 counter_ids_.clear();
9689 unknown_fields_.clear();
9690 bool packed_error = false;
9691
9692 ::protozero::ProtoDecoder dec(raw, size);
9693 for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
9694 if (field.id() < _has_field_.size()) {
9695 _has_field_.set(field.id());
9696 }
9697 switch (field.id()) {
9698 case 1 /* block_id */:
9699 field.get(&block_id_);
9700 break;
9701 case 2 /* block_capacity */:
9702 field.get(&block_capacity_);
9703 break;
9704 case 3 /* name */:
9705 field.get(&name_);
9706 break;
9707 case 4 /* description */:
9708 field.get(&description_);
9709 break;
9710 case 5 /* counter_ids */:
9711 counter_ids_.emplace_back();
9712 field.get(&counter_ids_.back());
9713 break;
9714 default:
9715 field.SerializeAndAppendTo(&unknown_fields_);
9716 break;
9717 }
9718 }
9719 return !packed_error && !dec.bytes_left();
9720 }
9721
SerializeAsString() const9722 std::string GpuCounterDescriptor_GpuCounterBlock::SerializeAsString() const {
9723 ::protozero::HeapBuffered<::protozero::Message> msg;
9724 Serialize(msg.get());
9725 return msg.SerializeAsString();
9726 }
9727
SerializeAsArray() const9728 std::vector<uint8_t> GpuCounterDescriptor_GpuCounterBlock::SerializeAsArray() const {
9729 ::protozero::HeapBuffered<::protozero::Message> msg;
9730 Serialize(msg.get());
9731 return msg.SerializeAsArray();
9732 }
9733
Serialize(::protozero::Message * msg) const9734 void GpuCounterDescriptor_GpuCounterBlock::Serialize(::protozero::Message* msg) const {
9735 // Field 1: block_id
9736 if (_has_field_[1]) {
9737 msg->AppendVarInt(1, block_id_);
9738 }
9739
9740 // Field 2: block_capacity
9741 if (_has_field_[2]) {
9742 msg->AppendVarInt(2, block_capacity_);
9743 }
9744
9745 // Field 3: name
9746 if (_has_field_[3]) {
9747 msg->AppendString(3, name_);
9748 }
9749
9750 // Field 4: description
9751 if (_has_field_[4]) {
9752 msg->AppendString(4, description_);
9753 }
9754
9755 // Field 5: counter_ids
9756 for (auto& it : counter_ids_) {
9757 msg->AppendVarInt(5, it);
9758 }
9759
9760 msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
9761 }
9762
9763
9764 GpuCounterDescriptor_GpuCounterSpec::GpuCounterDescriptor_GpuCounterSpec() = default;
9765 GpuCounterDescriptor_GpuCounterSpec::~GpuCounterDescriptor_GpuCounterSpec() = default;
9766 GpuCounterDescriptor_GpuCounterSpec::GpuCounterDescriptor_GpuCounterSpec(const GpuCounterDescriptor_GpuCounterSpec&) = default;
9767 GpuCounterDescriptor_GpuCounterSpec& GpuCounterDescriptor_GpuCounterSpec::operator=(const GpuCounterDescriptor_GpuCounterSpec&) = default;
9768 GpuCounterDescriptor_GpuCounterSpec::GpuCounterDescriptor_GpuCounterSpec(GpuCounterDescriptor_GpuCounterSpec&&) noexcept = default;
9769 GpuCounterDescriptor_GpuCounterSpec& GpuCounterDescriptor_GpuCounterSpec::operator=(GpuCounterDescriptor_GpuCounterSpec&&) = default;
9770
operator ==(const GpuCounterDescriptor_GpuCounterSpec & other) const9771 bool GpuCounterDescriptor_GpuCounterSpec::operator==(const GpuCounterDescriptor_GpuCounterSpec& other) const {
9772 return unknown_fields_ == other.unknown_fields_
9773 && counter_id_ == other.counter_id_
9774 && name_ == other.name_
9775 && description_ == other.description_
9776 && int_peak_value_ == other.int_peak_value_
9777 && double_peak_value_ == other.double_peak_value_
9778 && numerator_units_ == other.numerator_units_
9779 && denominator_units_ == other.denominator_units_
9780 && select_by_default_ == other.select_by_default_
9781 && groups_ == other.groups_;
9782 }
9783
ParseFromArray(const void * raw,size_t size)9784 bool GpuCounterDescriptor_GpuCounterSpec::ParseFromArray(const void* raw, size_t size) {
9785 numerator_units_.clear();
9786 denominator_units_.clear();
9787 groups_.clear();
9788 unknown_fields_.clear();
9789 bool packed_error = false;
9790
9791 ::protozero::ProtoDecoder dec(raw, size);
9792 for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
9793 if (field.id() < _has_field_.size()) {
9794 _has_field_.set(field.id());
9795 }
9796 switch (field.id()) {
9797 case 1 /* counter_id */:
9798 field.get(&counter_id_);
9799 break;
9800 case 2 /* name */:
9801 field.get(&name_);
9802 break;
9803 case 3 /* description */:
9804 field.get(&description_);
9805 break;
9806 case 5 /* int_peak_value */:
9807 field.get(&int_peak_value_);
9808 break;
9809 case 6 /* double_peak_value */:
9810 field.get(&double_peak_value_);
9811 break;
9812 case 7 /* numerator_units */:
9813 numerator_units_.emplace_back();
9814 field.get(&numerator_units_.back());
9815 break;
9816 case 8 /* denominator_units */:
9817 denominator_units_.emplace_back();
9818 field.get(&denominator_units_.back());
9819 break;
9820 case 9 /* select_by_default */:
9821 field.get(&select_by_default_);
9822 break;
9823 case 10 /* groups */:
9824 groups_.emplace_back();
9825 field.get(&groups_.back());
9826 break;
9827 default:
9828 field.SerializeAndAppendTo(&unknown_fields_);
9829 break;
9830 }
9831 }
9832 return !packed_error && !dec.bytes_left();
9833 }
9834
SerializeAsString() const9835 std::string GpuCounterDescriptor_GpuCounterSpec::SerializeAsString() const {
9836 ::protozero::HeapBuffered<::protozero::Message> msg;
9837 Serialize(msg.get());
9838 return msg.SerializeAsString();
9839 }
9840
SerializeAsArray() const9841 std::vector<uint8_t> GpuCounterDescriptor_GpuCounterSpec::SerializeAsArray() const {
9842 ::protozero::HeapBuffered<::protozero::Message> msg;
9843 Serialize(msg.get());
9844 return msg.SerializeAsArray();
9845 }
9846
Serialize(::protozero::Message * msg) const9847 void GpuCounterDescriptor_GpuCounterSpec::Serialize(::protozero::Message* msg) const {
9848 // Field 1: counter_id
9849 if (_has_field_[1]) {
9850 msg->AppendVarInt(1, counter_id_);
9851 }
9852
9853 // Field 2: name
9854 if (_has_field_[2]) {
9855 msg->AppendString(2, name_);
9856 }
9857
9858 // Field 3: description
9859 if (_has_field_[3]) {
9860 msg->AppendString(3, description_);
9861 }
9862
9863 // Field 5: int_peak_value
9864 if (_has_field_[5]) {
9865 msg->AppendVarInt(5, int_peak_value_);
9866 }
9867
9868 // Field 6: double_peak_value
9869 if (_has_field_[6]) {
9870 msg->AppendFixed(6, double_peak_value_);
9871 }
9872
9873 // Field 7: numerator_units
9874 for (auto& it : numerator_units_) {
9875 msg->AppendVarInt(7, it);
9876 }
9877
9878 // Field 8: denominator_units
9879 for (auto& it : denominator_units_) {
9880 msg->AppendVarInt(8, it);
9881 }
9882
9883 // Field 9: select_by_default
9884 if (_has_field_[9]) {
9885 msg->AppendTinyVarInt(9, select_by_default_);
9886 }
9887
9888 // Field 10: groups
9889 for (auto& it : groups_) {
9890 msg->AppendVarInt(10, it);
9891 }
9892
9893 msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
9894 }
9895
9896 } // namespace perfetto
9897 } // namespace protos
9898 } // namespace gen
9899 #pragma GCC diagnostic pop
9900 // gen_amalgamated begin source: gen/protos/perfetto/common/observable_events.gen.cc
9901 // gen_amalgamated begin header: gen/protos/perfetto/common/observable_events.gen.h
9902 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
9903 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_OBSERVABLE_EVENTS_PROTO_CPP_H_
9904 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_OBSERVABLE_EVENTS_PROTO_CPP_H_
9905
9906 #include <stdint.h>
9907 #include <bitset>
9908 #include <vector>
9909 #include <string>
9910 #include <type_traits>
9911
9912 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
9913 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
9914 // gen_amalgamated expanded: #include "perfetto/base/export.h"
9915
9916 namespace perfetto {
9917 namespace protos {
9918 namespace gen {
9919 class ObservableEvents;
9920 class ObservableEvents_DataSourceInstanceStateChange;
9921 enum ObservableEvents_Type : int;
9922 enum ObservableEvents_DataSourceInstanceState : int;
9923 } // namespace perfetto
9924 } // namespace protos
9925 } // namespace gen
9926
9927 namespace protozero {
9928 class Message;
9929 } // namespace protozero
9930
9931 namespace perfetto {
9932 namespace protos {
9933 namespace gen {
9934 enum ObservableEvents_Type : int {
9935 ObservableEvents_Type_TYPE_UNSPECIFIED = 0,
9936 ObservableEvents_Type_TYPE_DATA_SOURCES_INSTANCES = 1,
9937 ObservableEvents_Type_TYPE_ALL_DATA_SOURCES_STARTED = 2,
9938 };
9939 enum ObservableEvents_DataSourceInstanceState : int {
9940 ObservableEvents_DataSourceInstanceState_DATA_SOURCE_INSTANCE_STATE_STOPPED = 1,
9941 ObservableEvents_DataSourceInstanceState_DATA_SOURCE_INSTANCE_STATE_STARTED = 2,
9942 };
9943
9944 class PERFETTO_EXPORT ObservableEvents : public ::protozero::CppMessageObj {
9945 public:
9946 using DataSourceInstanceStateChange = ObservableEvents_DataSourceInstanceStateChange;
9947 using Type = ObservableEvents_Type;
9948 static constexpr auto TYPE_UNSPECIFIED = ObservableEvents_Type_TYPE_UNSPECIFIED;
9949 static constexpr auto TYPE_DATA_SOURCES_INSTANCES = ObservableEvents_Type_TYPE_DATA_SOURCES_INSTANCES;
9950 static constexpr auto TYPE_ALL_DATA_SOURCES_STARTED = ObservableEvents_Type_TYPE_ALL_DATA_SOURCES_STARTED;
9951 static constexpr auto Type_MIN = ObservableEvents_Type_TYPE_UNSPECIFIED;
9952 static constexpr auto Type_MAX = ObservableEvents_Type_TYPE_ALL_DATA_SOURCES_STARTED;
9953 using DataSourceInstanceState = ObservableEvents_DataSourceInstanceState;
9954 static constexpr auto DATA_SOURCE_INSTANCE_STATE_STOPPED = ObservableEvents_DataSourceInstanceState_DATA_SOURCE_INSTANCE_STATE_STOPPED;
9955 static constexpr auto DATA_SOURCE_INSTANCE_STATE_STARTED = ObservableEvents_DataSourceInstanceState_DATA_SOURCE_INSTANCE_STATE_STARTED;
9956 static constexpr auto DataSourceInstanceState_MIN = ObservableEvents_DataSourceInstanceState_DATA_SOURCE_INSTANCE_STATE_STOPPED;
9957 static constexpr auto DataSourceInstanceState_MAX = ObservableEvents_DataSourceInstanceState_DATA_SOURCE_INSTANCE_STATE_STARTED;
9958 enum FieldNumbers {
9959 kInstanceStateChangesFieldNumber = 1,
9960 kAllDataSourcesStartedFieldNumber = 2,
9961 };
9962
9963 ObservableEvents();
9964 ~ObservableEvents() override;
9965 ObservableEvents(ObservableEvents&&) noexcept;
9966 ObservableEvents& operator=(ObservableEvents&&);
9967 ObservableEvents(const ObservableEvents&);
9968 ObservableEvents& operator=(const ObservableEvents&);
9969 bool operator==(const ObservableEvents&) const;
operator !=(const ObservableEvents & other) const9970 bool operator!=(const ObservableEvents& other) const { return !(*this == other); }
9971
9972 bool ParseFromArray(const void*, size_t) override;
9973 std::string SerializeAsString() const override;
9974 std::vector<uint8_t> SerializeAsArray() const override;
9975 void Serialize(::protozero::Message*) const;
9976
instance_state_changes_size() const9977 int instance_state_changes_size() const { return static_cast<int>(instance_state_changes_.size()); }
instance_state_changes() const9978 const std::vector<ObservableEvents_DataSourceInstanceStateChange>& instance_state_changes() const { return instance_state_changes_; }
mutable_instance_state_changes()9979 std::vector<ObservableEvents_DataSourceInstanceStateChange>* mutable_instance_state_changes() { return &instance_state_changes_; }
clear_instance_state_changes()9980 void clear_instance_state_changes() { instance_state_changes_.clear(); }
add_instance_state_changes()9981 ObservableEvents_DataSourceInstanceStateChange* add_instance_state_changes() { instance_state_changes_.emplace_back(); return &instance_state_changes_.back(); }
9982
has_all_data_sources_started() const9983 bool has_all_data_sources_started() const { return _has_field_[2]; }
all_data_sources_started() const9984 bool all_data_sources_started() const { return all_data_sources_started_; }
set_all_data_sources_started(bool value)9985 void set_all_data_sources_started(bool value) { all_data_sources_started_ = value; _has_field_.set(2); }
9986
9987 private:
9988 std::vector<ObservableEvents_DataSourceInstanceStateChange> instance_state_changes_;
9989 bool all_data_sources_started_{};
9990
9991 // Allows to preserve unknown protobuf fields for compatibility
9992 // with future versions of .proto files.
9993 std::string unknown_fields_;
9994
9995 std::bitset<3> _has_field_{};
9996 };
9997
9998
9999 class PERFETTO_EXPORT ObservableEvents_DataSourceInstanceStateChange : public ::protozero::CppMessageObj {
10000 public:
10001 enum FieldNumbers {
10002 kProducerNameFieldNumber = 1,
10003 kDataSourceNameFieldNumber = 2,
10004 kStateFieldNumber = 3,
10005 };
10006
10007 ObservableEvents_DataSourceInstanceStateChange();
10008 ~ObservableEvents_DataSourceInstanceStateChange() override;
10009 ObservableEvents_DataSourceInstanceStateChange(ObservableEvents_DataSourceInstanceStateChange&&) noexcept;
10010 ObservableEvents_DataSourceInstanceStateChange& operator=(ObservableEvents_DataSourceInstanceStateChange&&);
10011 ObservableEvents_DataSourceInstanceStateChange(const ObservableEvents_DataSourceInstanceStateChange&);
10012 ObservableEvents_DataSourceInstanceStateChange& operator=(const ObservableEvents_DataSourceInstanceStateChange&);
10013 bool operator==(const ObservableEvents_DataSourceInstanceStateChange&) const;
operator !=(const ObservableEvents_DataSourceInstanceStateChange & other) const10014 bool operator!=(const ObservableEvents_DataSourceInstanceStateChange& other) const { return !(*this == other); }
10015
10016 bool ParseFromArray(const void*, size_t) override;
10017 std::string SerializeAsString() const override;
10018 std::vector<uint8_t> SerializeAsArray() const override;
10019 void Serialize(::protozero::Message*) const;
10020
has_producer_name() const10021 bool has_producer_name() const { return _has_field_[1]; }
producer_name() const10022 const std::string& producer_name() const { return producer_name_; }
set_producer_name(const std::string & value)10023 void set_producer_name(const std::string& value) { producer_name_ = value; _has_field_.set(1); }
10024
has_data_source_name() const10025 bool has_data_source_name() const { return _has_field_[2]; }
data_source_name() const10026 const std::string& data_source_name() const { return data_source_name_; }
set_data_source_name(const std::string & value)10027 void set_data_source_name(const std::string& value) { data_source_name_ = value; _has_field_.set(2); }
10028
has_state() const10029 bool has_state() const { return _has_field_[3]; }
state() const10030 ObservableEvents_DataSourceInstanceState state() const { return state_; }
set_state(ObservableEvents_DataSourceInstanceState value)10031 void set_state(ObservableEvents_DataSourceInstanceState value) { state_ = value; _has_field_.set(3); }
10032
10033 private:
10034 std::string producer_name_{};
10035 std::string data_source_name_{};
10036 ObservableEvents_DataSourceInstanceState state_{};
10037
10038 // Allows to preserve unknown protobuf fields for compatibility
10039 // with future versions of .proto files.
10040 std::string unknown_fields_;
10041
10042 std::bitset<4> _has_field_{};
10043 };
10044
10045 } // namespace perfetto
10046 } // namespace protos
10047 } // namespace gen
10048
10049 #endif // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_OBSERVABLE_EVENTS_PROTO_CPP_H_
10050 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
10051 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
10052 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
10053 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
10054 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
10055 #pragma GCC diagnostic push
10056 #pragma GCC diagnostic ignored "-Wfloat-equal"
10057 // gen_amalgamated expanded: #include "protos/perfetto/common/observable_events.gen.h"
10058
10059 namespace perfetto {
10060 namespace protos {
10061 namespace gen {
10062
10063 ObservableEvents::ObservableEvents() = default;
10064 ObservableEvents::~ObservableEvents() = default;
10065 ObservableEvents::ObservableEvents(const ObservableEvents&) = default;
10066 ObservableEvents& ObservableEvents::operator=(const ObservableEvents&) = default;
10067 ObservableEvents::ObservableEvents(ObservableEvents&&) noexcept = default;
10068 ObservableEvents& ObservableEvents::operator=(ObservableEvents&&) = default;
10069
operator ==(const ObservableEvents & other) const10070 bool ObservableEvents::operator==(const ObservableEvents& other) const {
10071 return unknown_fields_ == other.unknown_fields_
10072 && instance_state_changes_ == other.instance_state_changes_
10073 && all_data_sources_started_ == other.all_data_sources_started_;
10074 }
10075
ParseFromArray(const void * raw,size_t size)10076 bool ObservableEvents::ParseFromArray(const void* raw, size_t size) {
10077 instance_state_changes_.clear();
10078 unknown_fields_.clear();
10079 bool packed_error = false;
10080
10081 ::protozero::ProtoDecoder dec(raw, size);
10082 for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
10083 if (field.id() < _has_field_.size()) {
10084 _has_field_.set(field.id());
10085 }
10086 switch (field.id()) {
10087 case 1 /* instance_state_changes */:
10088 instance_state_changes_.emplace_back();
10089 instance_state_changes_.back().ParseFromString(field.as_std_string());
10090 break;
10091 case 2 /* all_data_sources_started */:
10092 field.get(&all_data_sources_started_);
10093 break;
10094 default:
10095 field.SerializeAndAppendTo(&unknown_fields_);
10096 break;
10097 }
10098 }
10099 return !packed_error && !dec.bytes_left();
10100 }
10101
SerializeAsString() const10102 std::string ObservableEvents::SerializeAsString() const {
10103 ::protozero::HeapBuffered<::protozero::Message> msg;
10104 Serialize(msg.get());
10105 return msg.SerializeAsString();
10106 }
10107
SerializeAsArray() const10108 std::vector<uint8_t> ObservableEvents::SerializeAsArray() const {
10109 ::protozero::HeapBuffered<::protozero::Message> msg;
10110 Serialize(msg.get());
10111 return msg.SerializeAsArray();
10112 }
10113
Serialize(::protozero::Message * msg) const10114 void ObservableEvents::Serialize(::protozero::Message* msg) const {
10115 // Field 1: instance_state_changes
10116 for (auto& it : instance_state_changes_) {
10117 it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
10118 }
10119
10120 // Field 2: all_data_sources_started
10121 if (_has_field_[2]) {
10122 msg->AppendTinyVarInt(2, all_data_sources_started_);
10123 }
10124
10125 msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
10126 }
10127
10128
10129 ObservableEvents_DataSourceInstanceStateChange::ObservableEvents_DataSourceInstanceStateChange() = default;
10130 ObservableEvents_DataSourceInstanceStateChange::~ObservableEvents_DataSourceInstanceStateChange() = default;
10131 ObservableEvents_DataSourceInstanceStateChange::ObservableEvents_DataSourceInstanceStateChange(const ObservableEvents_DataSourceInstanceStateChange&) = default;
10132 ObservableEvents_DataSourceInstanceStateChange& ObservableEvents_DataSourceInstanceStateChange::operator=(const ObservableEvents_DataSourceInstanceStateChange&) = default;
10133 ObservableEvents_DataSourceInstanceStateChange::ObservableEvents_DataSourceInstanceStateChange(ObservableEvents_DataSourceInstanceStateChange&&) noexcept = default;
10134 ObservableEvents_DataSourceInstanceStateChange& ObservableEvents_DataSourceInstanceStateChange::operator=(ObservableEvents_DataSourceInstanceStateChange&&) = default;
10135
operator ==(const ObservableEvents_DataSourceInstanceStateChange & other) const10136 bool ObservableEvents_DataSourceInstanceStateChange::operator==(const ObservableEvents_DataSourceInstanceStateChange& other) const {
10137 return unknown_fields_ == other.unknown_fields_
10138 && producer_name_ == other.producer_name_
10139 && data_source_name_ == other.data_source_name_
10140 && state_ == other.state_;
10141 }
10142
ParseFromArray(const void * raw,size_t size)10143 bool ObservableEvents_DataSourceInstanceStateChange::ParseFromArray(const void* raw, size_t size) {
10144 unknown_fields_.clear();
10145 bool packed_error = false;
10146
10147 ::protozero::ProtoDecoder dec(raw, size);
10148 for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
10149 if (field.id() < _has_field_.size()) {
10150 _has_field_.set(field.id());
10151 }
10152 switch (field.id()) {
10153 case 1 /* producer_name */:
10154 field.get(&producer_name_);
10155 break;
10156 case 2 /* data_source_name */:
10157 field.get(&data_source_name_);
10158 break;
10159 case 3 /* state */:
10160 field.get(&state_);
10161 break;
10162 default:
10163 field.SerializeAndAppendTo(&unknown_fields_);
10164 break;
10165 }
10166 }
10167 return !packed_error && !dec.bytes_left();
10168 }
10169
SerializeAsString() const10170 std::string ObservableEvents_DataSourceInstanceStateChange::SerializeAsString() const {
10171 ::protozero::HeapBuffered<::protozero::Message> msg;
10172 Serialize(msg.get());
10173 return msg.SerializeAsString();
10174 }
10175
SerializeAsArray() const10176 std::vector<uint8_t> ObservableEvents_DataSourceInstanceStateChange::SerializeAsArray() const {
10177 ::protozero::HeapBuffered<::protozero::Message> msg;
10178 Serialize(msg.get());
10179 return msg.SerializeAsArray();
10180 }
10181
Serialize(::protozero::Message * msg) const10182 void ObservableEvents_DataSourceInstanceStateChange::Serialize(::protozero::Message* msg) const {
10183 // Field 1: producer_name
10184 if (_has_field_[1]) {
10185 msg->AppendString(1, producer_name_);
10186 }
10187
10188 // Field 2: data_source_name
10189 if (_has_field_[2]) {
10190 msg->AppendString(2, data_source_name_);
10191 }
10192
10193 // Field 3: state
10194 if (_has_field_[3]) {
10195 msg->AppendVarInt(3, state_);
10196 }
10197
10198 msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
10199 }
10200
10201 } // namespace perfetto
10202 } // namespace protos
10203 } // namespace gen
10204 #pragma GCC diagnostic pop
10205 // gen_amalgamated begin source: gen/protos/perfetto/common/sys_stats_counters.gen.cc
10206 // gen_amalgamated begin header: gen/protos/perfetto/common/sys_stats_counters.gen.h
10207 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
10208 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_SYS_STATS_COUNTERS_PROTO_CPP_H_
10209 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_SYS_STATS_COUNTERS_PROTO_CPP_H_
10210
10211 #include <stdint.h>
10212 #include <bitset>
10213 #include <vector>
10214 #include <string>
10215 #include <type_traits>
10216
10217 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
10218 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
10219 // gen_amalgamated expanded: #include "perfetto/base/export.h"
10220
10221 namespace perfetto {
10222 namespace protos {
10223 namespace gen {
10224 enum MeminfoCounters : int;
10225 enum VmstatCounters : int;
10226 } // namespace perfetto
10227 } // namespace protos
10228 } // namespace gen
10229
10230 namespace protozero {
10231 class Message;
10232 } // namespace protozero
10233
10234 namespace perfetto {
10235 namespace protos {
10236 namespace gen {
10237 enum MeminfoCounters : int {
10238 MEMINFO_UNSPECIFIED = 0,
10239 MEMINFO_MEM_TOTAL = 1,
10240 MEMINFO_MEM_FREE = 2,
10241 MEMINFO_MEM_AVAILABLE = 3,
10242 MEMINFO_BUFFERS = 4,
10243 MEMINFO_CACHED = 5,
10244 MEMINFO_SWAP_CACHED = 6,
10245 MEMINFO_ACTIVE = 7,
10246 MEMINFO_INACTIVE = 8,
10247 MEMINFO_ACTIVE_ANON = 9,
10248 MEMINFO_INACTIVE_ANON = 10,
10249 MEMINFO_ACTIVE_FILE = 11,
10250 MEMINFO_INACTIVE_FILE = 12,
10251 MEMINFO_UNEVICTABLE = 13,
10252 MEMINFO_MLOCKED = 14,
10253 MEMINFO_SWAP_TOTAL = 15,
10254 MEMINFO_SWAP_FREE = 16,
10255 MEMINFO_DIRTY = 17,
10256 MEMINFO_WRITEBACK = 18,
10257 MEMINFO_ANON_PAGES = 19,
10258 MEMINFO_MAPPED = 20,
10259 MEMINFO_SHMEM = 21,
10260 MEMINFO_SLAB = 22,
10261 MEMINFO_SLAB_RECLAIMABLE = 23,
10262 MEMINFO_SLAB_UNRECLAIMABLE = 24,
10263 MEMINFO_KERNEL_STACK = 25,
10264 MEMINFO_PAGE_TABLES = 26,
10265 MEMINFO_COMMIT_LIMIT = 27,
10266 MEMINFO_COMMITED_AS = 28,
10267 MEMINFO_VMALLOC_TOTAL = 29,
10268 MEMINFO_VMALLOC_USED = 30,
10269 MEMINFO_VMALLOC_CHUNK = 31,
10270 MEMINFO_CMA_TOTAL = 32,
10271 MEMINFO_CMA_FREE = 33,
10272 };
10273 enum VmstatCounters : int {
10274 VMSTAT_UNSPECIFIED = 0,
10275 VMSTAT_NR_FREE_PAGES = 1,
10276 VMSTAT_NR_ALLOC_BATCH = 2,
10277 VMSTAT_NR_INACTIVE_ANON = 3,
10278 VMSTAT_NR_ACTIVE_ANON = 4,
10279 VMSTAT_NR_INACTIVE_FILE = 5,
10280 VMSTAT_NR_ACTIVE_FILE = 6,
10281 VMSTAT_NR_UNEVICTABLE = 7,
10282 VMSTAT_NR_MLOCK = 8,
10283 VMSTAT_NR_ANON_PAGES = 9,
10284 VMSTAT_NR_MAPPED = 10,
10285 VMSTAT_NR_FILE_PAGES = 11,
10286 VMSTAT_NR_DIRTY = 12,
10287 VMSTAT_NR_WRITEBACK = 13,
10288 VMSTAT_NR_SLAB_RECLAIMABLE = 14,
10289 VMSTAT_NR_SLAB_UNRECLAIMABLE = 15,
10290 VMSTAT_NR_PAGE_TABLE_PAGES = 16,
10291 VMSTAT_NR_KERNEL_STACK = 17,
10292 VMSTAT_NR_OVERHEAD = 18,
10293 VMSTAT_NR_UNSTABLE = 19,
10294 VMSTAT_NR_BOUNCE = 20,
10295 VMSTAT_NR_VMSCAN_WRITE = 21,
10296 VMSTAT_NR_VMSCAN_IMMEDIATE_RECLAIM = 22,
10297 VMSTAT_NR_WRITEBACK_TEMP = 23,
10298 VMSTAT_NR_ISOLATED_ANON = 24,
10299 VMSTAT_NR_ISOLATED_FILE = 25,
10300 VMSTAT_NR_SHMEM = 26,
10301 VMSTAT_NR_DIRTIED = 27,
10302 VMSTAT_NR_WRITTEN = 28,
10303 VMSTAT_NR_PAGES_SCANNED = 29,
10304 VMSTAT_WORKINGSET_REFAULT = 30,
10305 VMSTAT_WORKINGSET_ACTIVATE = 31,
10306 VMSTAT_WORKINGSET_NODERECLAIM = 32,
10307 VMSTAT_NR_ANON_TRANSPARENT_HUGEPAGES = 33,
10308 VMSTAT_NR_FREE_CMA = 34,
10309 VMSTAT_NR_SWAPCACHE = 35,
10310 VMSTAT_NR_DIRTY_THRESHOLD = 36,
10311 VMSTAT_NR_DIRTY_BACKGROUND_THRESHOLD = 37,
10312 VMSTAT_PGPGIN = 38,
10313 VMSTAT_PGPGOUT = 39,
10314 VMSTAT_PGPGOUTCLEAN = 40,
10315 VMSTAT_PSWPIN = 41,
10316 VMSTAT_PSWPOUT = 42,
10317 VMSTAT_PGALLOC_DMA = 43,
10318 VMSTAT_PGALLOC_NORMAL = 44,
10319 VMSTAT_PGALLOC_MOVABLE = 45,
10320 VMSTAT_PGFREE = 46,
10321 VMSTAT_PGACTIVATE = 47,
10322 VMSTAT_PGDEACTIVATE = 48,
10323 VMSTAT_PGFAULT = 49,
10324 VMSTAT_PGMAJFAULT = 50,
10325 VMSTAT_PGREFILL_DMA = 51,
10326 VMSTAT_PGREFILL_NORMAL = 52,
10327 VMSTAT_PGREFILL_MOVABLE = 53,
10328 VMSTAT_PGSTEAL_KSWAPD_DMA = 54,
10329 VMSTAT_PGSTEAL_KSWAPD_NORMAL = 55,
10330 VMSTAT_PGSTEAL_KSWAPD_MOVABLE = 56,
10331 VMSTAT_PGSTEAL_DIRECT_DMA = 57,
10332 VMSTAT_PGSTEAL_DIRECT_NORMAL = 58,
10333 VMSTAT_PGSTEAL_DIRECT_MOVABLE = 59,
10334 VMSTAT_PGSCAN_KSWAPD_DMA = 60,
10335 VMSTAT_PGSCAN_KSWAPD_NORMAL = 61,
10336 VMSTAT_PGSCAN_KSWAPD_MOVABLE = 62,
10337 VMSTAT_PGSCAN_DIRECT_DMA = 63,
10338 VMSTAT_PGSCAN_DIRECT_NORMAL = 64,
10339 VMSTAT_PGSCAN_DIRECT_MOVABLE = 65,
10340 VMSTAT_PGSCAN_DIRECT_THROTTLE = 66,
10341 VMSTAT_PGINODESTEAL = 67,
10342 VMSTAT_SLABS_SCANNED = 68,
10343 VMSTAT_KSWAPD_INODESTEAL = 69,
10344 VMSTAT_KSWAPD_LOW_WMARK_HIT_QUICKLY = 70,
10345 VMSTAT_KSWAPD_HIGH_WMARK_HIT_QUICKLY = 71,
10346 VMSTAT_PAGEOUTRUN = 72,
10347 VMSTAT_ALLOCSTALL = 73,
10348 VMSTAT_PGROTATED = 74,
10349 VMSTAT_DROP_PAGECACHE = 75,
10350 VMSTAT_DROP_SLAB = 76,
10351 VMSTAT_PGMIGRATE_SUCCESS = 77,
10352 VMSTAT_PGMIGRATE_FAIL = 78,
10353 VMSTAT_COMPACT_MIGRATE_SCANNED = 79,
10354 VMSTAT_COMPACT_FREE_SCANNED = 80,
10355 VMSTAT_COMPACT_ISOLATED = 81,
10356 VMSTAT_COMPACT_STALL = 82,
10357 VMSTAT_COMPACT_FAIL = 83,
10358 VMSTAT_COMPACT_SUCCESS = 84,
10359 VMSTAT_COMPACT_DAEMON_WAKE = 85,
10360 VMSTAT_UNEVICTABLE_PGS_CULLED = 86,
10361 VMSTAT_UNEVICTABLE_PGS_SCANNED = 87,
10362 VMSTAT_UNEVICTABLE_PGS_RESCUED = 88,
10363 VMSTAT_UNEVICTABLE_PGS_MLOCKED = 89,
10364 VMSTAT_UNEVICTABLE_PGS_MUNLOCKED = 90,
10365 VMSTAT_UNEVICTABLE_PGS_CLEARED = 91,
10366 VMSTAT_UNEVICTABLE_PGS_STRANDED = 92,
10367 VMSTAT_NR_ZSPAGES = 93,
10368 VMSTAT_NR_ION_HEAP = 94,
10369 VMSTAT_NR_GPU_HEAP = 95,
10370 };
10371 } // namespace perfetto
10372 } // namespace protos
10373 } // namespace gen
10374
10375 #endif // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_SYS_STATS_COUNTERS_PROTO_CPP_H_
10376 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
10377 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
10378 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
10379 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
10380 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
10381 #pragma GCC diagnostic push
10382 #pragma GCC diagnostic ignored "-Wfloat-equal"
10383 // gen_amalgamated expanded: #include "protos/perfetto/common/sys_stats_counters.gen.h"
10384
10385 namespace perfetto {
10386 namespace protos {
10387 namespace gen {
10388 } // namespace perfetto
10389 } // namespace protos
10390 } // namespace gen
10391 #pragma GCC diagnostic pop
10392 // gen_amalgamated begin source: gen/protos/perfetto/common/trace_stats.gen.cc
10393 // gen_amalgamated begin header: gen/protos/perfetto/common/trace_stats.gen.h
10394 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
10395 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACE_STATS_PROTO_CPP_H_
10396 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACE_STATS_PROTO_CPP_H_
10397
10398 #include <stdint.h>
10399 #include <bitset>
10400 #include <vector>
10401 #include <string>
10402 #include <type_traits>
10403
10404 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
10405 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
10406 // gen_amalgamated expanded: #include "perfetto/base/export.h"
10407
10408 namespace perfetto {
10409 namespace protos {
10410 namespace gen {
10411 class TraceStats;
10412 class TraceStats_BufferStats;
10413 } // namespace perfetto
10414 } // namespace protos
10415 } // namespace gen
10416
10417 namespace protozero {
10418 class Message;
10419 } // namespace protozero
10420
10421 namespace perfetto {
10422 namespace protos {
10423 namespace gen {
10424
10425 class PERFETTO_EXPORT TraceStats : public ::protozero::CppMessageObj {
10426 public:
10427 using BufferStats = TraceStats_BufferStats;
10428 enum FieldNumbers {
10429 kBufferStatsFieldNumber = 1,
10430 kProducersConnectedFieldNumber = 2,
10431 kProducersSeenFieldNumber = 3,
10432 kDataSourcesRegisteredFieldNumber = 4,
10433 kDataSourcesSeenFieldNumber = 5,
10434 kTracingSessionsFieldNumber = 6,
10435 kTotalBuffersFieldNumber = 7,
10436 kChunksDiscardedFieldNumber = 8,
10437 kPatchesDiscardedFieldNumber = 9,
10438 kInvalidPacketsFieldNumber = 10,
10439 };
10440
10441 TraceStats();
10442 ~TraceStats() override;
10443 TraceStats(TraceStats&&) noexcept;
10444 TraceStats& operator=(TraceStats&&);
10445 TraceStats(const TraceStats&);
10446 TraceStats& operator=(const TraceStats&);
10447 bool operator==(const TraceStats&) const;
operator !=(const TraceStats & other) const10448 bool operator!=(const TraceStats& other) const { return !(*this == other); }
10449
10450 bool ParseFromArray(const void*, size_t) override;
10451 std::string SerializeAsString() const override;
10452 std::vector<uint8_t> SerializeAsArray() const override;
10453 void Serialize(::protozero::Message*) const;
10454
buffer_stats_size() const10455 int buffer_stats_size() const { return static_cast<int>(buffer_stats_.size()); }
buffer_stats() const10456 const std::vector<TraceStats_BufferStats>& buffer_stats() const { return buffer_stats_; }
mutable_buffer_stats()10457 std::vector<TraceStats_BufferStats>* mutable_buffer_stats() { return &buffer_stats_; }
clear_buffer_stats()10458 void clear_buffer_stats() { buffer_stats_.clear(); }
add_buffer_stats()10459 TraceStats_BufferStats* add_buffer_stats() { buffer_stats_.emplace_back(); return &buffer_stats_.back(); }
10460
has_producers_connected() const10461 bool has_producers_connected() const { return _has_field_[2]; }
producers_connected() const10462 uint32_t producers_connected() const { return producers_connected_; }
set_producers_connected(uint32_t value)10463 void set_producers_connected(uint32_t value) { producers_connected_ = value; _has_field_.set(2); }
10464
has_producers_seen() const10465 bool has_producers_seen() const { return _has_field_[3]; }
producers_seen() const10466 uint64_t producers_seen() const { return producers_seen_; }
set_producers_seen(uint64_t value)10467 void set_producers_seen(uint64_t value) { producers_seen_ = value; _has_field_.set(3); }
10468
has_data_sources_registered() const10469 bool has_data_sources_registered() const { return _has_field_[4]; }
data_sources_registered() const10470 uint32_t data_sources_registered() const { return data_sources_registered_; }
set_data_sources_registered(uint32_t value)10471 void set_data_sources_registered(uint32_t value) { data_sources_registered_ = value; _has_field_.set(4); }
10472
has_data_sources_seen() const10473 bool has_data_sources_seen() const { return _has_field_[5]; }
data_sources_seen() const10474 uint64_t data_sources_seen() const { return data_sources_seen_; }
set_data_sources_seen(uint64_t value)10475 void set_data_sources_seen(uint64_t value) { data_sources_seen_ = value; _has_field_.set(5); }
10476
has_tracing_sessions() const10477 bool has_tracing_sessions() const { return _has_field_[6]; }
tracing_sessions() const10478 uint32_t tracing_sessions() const { return tracing_sessions_; }
set_tracing_sessions(uint32_t value)10479 void set_tracing_sessions(uint32_t value) { tracing_sessions_ = value; _has_field_.set(6); }
10480
has_total_buffers() const10481 bool has_total_buffers() const { return _has_field_[7]; }
total_buffers() const10482