perfetto: Support building on Fuchsia for Chrome

Adds build support for Fuchsia for bundled builds.
Unittests are passing.

Change-Id: I4b4599ba3ca12453998cb02536bb93dfc4443161
diff --git a/gn/standalone/BUILDCONFIG.gn b/gn/standalone/BUILDCONFIG.gn
index 773f87d..cc2f1b8 100644
--- a/gn/standalone/BUILDCONFIG.gn
+++ b/gn/standalone/BUILDCONFIG.gn
@@ -40,9 +40,10 @@
 is_linux_host = host_os == "linux"
 is_mac = current_os == "mac"
 
-# Building with Windows is currently only supported in the Chromium tree so
-# always set this to false.
+# Building with Windows/Fuchsia is currently only supported in the Chromium
+# tree so always set this to false.
 is_win = false
+is_fuchsia = false
 
 if (target_cpu == "") {
   target_cpu = host_cpu
diff --git a/include/perfetto/base/build_config.h b/include/perfetto/base/build_config.h
index ef00b16..f0be366 100644
--- a/include/perfetto/base/build_config.h
+++ b/include/perfetto/base/build_config.h
@@ -30,30 +30,42 @@
 #define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_LINUX() 0
 #define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_WIN() 0
 #define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_WASM() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_FUCHSIA() 0
 #elif defined(__APPLE__)
 #define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_ANDROID() 0
 #define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_MACOSX() 1
 #define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_LINUX() 0
 #define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_WIN() 0
 #define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_WASM() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_FUCHSIA() 0
 #elif defined(__linux__)
 #define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_ANDROID() 0
 #define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_MACOSX() 0
 #define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_LINUX() 1
 #define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_WIN() 0
 #define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_WASM() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_FUCHSIA() 0
 #elif defined(_WIN32)
 #define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_ANDROID() 0
 #define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_MACOSX() 0
 #define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_LINUX() 0
 #define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_WIN() 1
 #define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_WASM() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_FUCHSIA() 0
 #elif defined(__EMSCRIPTEN__)
 #define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_ANDROID() 0
 #define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_MACOSX() 0
 #define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_LINUX() 0
 #define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_WIN() 0
 #define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_WASM() 1
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_FUCHSIA() 0
+#elif defined(__Fuchsia__)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_ANDROID() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_MACOSX() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_LINUX() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_WIN() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_WASM() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_FUCHSIA() 1
 #else
 #error OS not supported (see build_config.h)
 #endif
diff --git a/include/perfetto/base/thread_utils.h b/include/perfetto/base/thread_utils.h
index 15bc1ae..38a9694 100644
--- a/include/perfetto/base/thread_utils.h
+++ b/include/perfetto/base/thread_utils.h
@@ -23,6 +23,9 @@
 
 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
 #include <processthreadsapi.h>
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
+#include <zircon/process.h>
+#include <zircon/types.h>
 #else
 #include <pthread.h>
 #include <sys/syscall.h>
@@ -41,6 +44,10 @@
 inline pid_t GetThreadId() {
   return static_cast<pid_t>(syscall(__NR_gettid));
 }
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
+inline zx_handle_t GetThreadId() {
+  return static_cast<pid_t>(zx_thread_self());
+}
 #elif PERFETTO_BUILDFLAG(PERFETTO_OS_MACOSX)
 inline uint64_t GetThreadId() {
   uint64_t tid;
diff --git a/src/base/paged_memory_unittest.cc b/src/base/paged_memory_unittest.cc
index 6c2f4e8..5e1521a 100644
--- a/src/base/paged_memory_unittest.cc
+++ b/src/base/paged_memory_unittest.cc
@@ -23,7 +23,8 @@
 #include "src/base/test/vm_test_utils.h"
 
 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_MACOSX) && \
-    !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+    !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) &&    \
+    !PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
 #include <sys/resource.h>
 #endif
 
@@ -43,7 +44,9 @@
     for (size_t i = 0; i < kSize / sizeof(uint64_t); i++)
       ASSERT_EQ(0u, *(reinterpret_cast<uint64_t*>(mem.Get()) + i));
 
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
     ASSERT_TRUE(vm_test_utils::IsMapped(ptr_raw, kSize));
+#endif
 
 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
@@ -54,8 +57,10 @@
 #endif
   }
 
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
   // Freed memory is necessarily not mapped in to the process.
   ASSERT_FALSE(vm_test_utils::IsMapped(ptr_raw, kSize));
+#endif
 }
 
 TEST(PagedMemoryTest, Uncommitted) {
@@ -87,8 +92,11 @@
          i < kSize / sizeof(uint64_t); i++) {
       ASSERT_EQ(0u, *(reinterpret_cast<uint64_t*>(mem.Get()) + i));
     }
-
-    ASSERT_TRUE(vm_test_utils::IsMapped(ptr_raw, kSize));
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
+    // Fuchsia doesn't yet support paging. So this should be a no-op.
+    mem.EnsureCommitted(kSize);
+    for (size_t i = 0; i < kSize / sizeof(uint64_t); i++)
+      ASSERT_EQ(0u, *(reinterpret_cast<uint64_t*>(mem.Get()) + i));
 #else
     // Linux only maps on access.
     ASSERT_FALSE(vm_test_utils::IsMapped(ptr_raw, kSize));
@@ -103,8 +111,10 @@
 #endif
   }
 
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
   // Freed memory is necessarily not mapped in to the process.
   ASSERT_FALSE(vm_test_utils::IsMapped(ptr_raw, kSize));
+#endif
 }
 
 #if defined(ADDRESS_SANITIZER)
@@ -137,10 +147,12 @@
 
 // Disable this on:
 // MacOS: because it doesn't seem to have an equivalent rlimit to bound mmap().
+// Fuchsia: doesn't support rlimit.
 // Sanitizers: they seem to try to shadow mmaped memory and fail due to OOMs.
-#if !PERFETTO_BUILDFLAG(PERFETTO_OS_MACOSX) &&                             \
-    !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) && !defined(ADDRESS_SANITIZER) && \
-    !defined(LEAK_SANITIZER) && !defined(THREAD_SANITIZER) &&              \
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_MACOSX) &&                                 \
+    !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) &&                                    \
+    !PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA) && !defined(ADDRESS_SANITIZER) && \
+    !defined(LEAK_SANITIZER) && !defined(THREAD_SANITIZER) &&                  \
     !defined(MEMORY_SANITIZER)
 // Glibc headers hit this on RLIMIT_ macros.
 #pragma GCC diagnostic push
diff --git a/src/base/test/utils.cc b/src/base/test/utils.cc
index 18cdaf9..9e2ff4c 100644
--- a/src/base/test/utils.cc
+++ b/src/base/test/utils.cc
@@ -23,7 +23,8 @@
 
 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
-    PERFETTO_BUILDFLAG(PERFETTO_OS_MACOSX)
+    PERFETTO_BUILDFLAG(PERFETTO_OS_MACOSX) ||  \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
 #include <limits.h>
 #include <unistd.h>
 #endif
@@ -37,8 +38,9 @@
     return std::string(test_data_root) + path;
   }
 
-#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
-    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
   char buf[PATH_MAX];
   ssize_t bytes = readlink("/proc/self/exe", buf, sizeof(buf));
   PERFETTO_CHECK(bytes != -1);
diff --git a/src/base/test/vm_test_utils.cc b/src/base/test/vm_test_utils.cc
index ddbad2e..619fcbf 100644
--- a/src/base/test/vm_test_utils.cc
+++ b/src/base/test/vm_test_utils.cc
@@ -93,6 +93,9 @@
   if (pages_found * kPageSize == size)
     return true;
   return false;
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
+  // Fuchsia doesn't yet support paging (b/119503290).
+  return true;
 #else
 #if PERFETTO_BUILDFLAG(PERFETTO_OS_MACOSX)
   using PageState = char;
diff --git a/src/base/utils_unittest.cc b/src/base/utils_unittest.cc
index 4fb35bf..1d0f834 100644
--- a/src/base/utils_unittest.cc
+++ b/src/base/utils_unittest.cc
@@ -59,6 +59,9 @@
   EXPECT_EQ(4u, ArraySize(bar_4));
 }
 
+// Fuchsia doesn't currently support sigaction(), see
+// fuchsia.atlassian.net/browse/ZX-560.
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
 TEST(UtilsTest, EintrWrapper) {
   Pipe pipe = Pipe::Create();
 
@@ -99,6 +102,7 @@
   // Restore the old handler.
   sigaction(SIGUSR2, &old_sa, nullptr);
 }
+#endif  // !PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
 
 TEST(UtilsTest, Align) {
   EXPECT_EQ(0u, AlignUp<4>(0));
diff --git a/src/tracing/core/service_impl_unittest.cc b/src/tracing/core/service_impl_unittest.cc
index cbf2da6..0184d53 100644
--- a/src/tracing/core/service_impl_unittest.cc
+++ b/src/tracing/core/service_impl_unittest.cc
@@ -378,6 +378,13 @@
   producer->WaitForDataSourceStop("data_source");
   consumer->WaitForTracingDisabled();
 
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
+  // On Fuchsia, writing to the file seems to happen concurrently to the read
+  // below, which can cause flakiness. Flush forcefully to ensure all data was
+  // written.
+  fsync(*tmp_file);
+#endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
+
   // Verify the contents of the file.
   std::string trace_raw;
   ASSERT_TRUE(base::ReadFile(tmp_file.path().c_str(), &trace_raw));