ftrace: add PagePool for ftrace reader

Adds a page pool allocator + reader/writer queue.
This is tested but not used by this CL. Upcoming CLs will
use this.
PagePool is tailored around the needs of the upcoming ftrace CpuReader.
It has two responsibilities:
1) A cheap bump-pointer page allocator for the writing side of CpuReader.
2) A thread-safe producer/consumer queue to synchronize the read/write
   threads of CpuReader.
For context, CpuReader (and hence this class) is used on two threads:
(1) A worker thread that writes into the buffer and (2) the main thread which
reads all the content in big batches and turn them into protos.
There is At most one thread writing and At most one thread reading. In rare
circumstances they can be active At the same time.
This class is optimized for the following use case:
- Most of the times CpuReader wants to write 4096 bytes. In some rare cases
  (read() during flush) it wants to write < 4096 bytes.
- Even when it writes < 4096 bytes, CpuReader can figure out the size of the
  payload from the ftrace header. We don't need extra tracking to tell how
  much of each page is used.
- Doing a syscall for each page write is overkill. In most occasions
  CpuReader writes bursts of several pages in one go.
- We can't really predict upfront how big the write bursts will be, hence we
  cannot predict the size of the pool, unless we accept a very high bound.
  In extreme, yet rare, conditions, CpuReader will read the whole per-cpu
  ftrace buffer, while the reader is still reading the previous batch.
- Write burst should not be too frequent, so once they are over it's worth
  spending some extra cycles to release the memory.
- The reader side always wants to read *all* the written pages in one batch.
  While this happens though, the write might want to write more.
The architecture of this class is as follows. Pages are organized in
PageBlock(s). A PageBlock is simply an array of pages and is the elementary
unit of memory allocation and frees. Pages within one block are cheaply
allocated with a simple bump-pointer allocator.
     [      Writer (thread worker)    ] | [    Reader (main thread)   ]
                                 ~~~~~~~~~~~~~~~~~~~~~
     +---> write queue ------------> ready queue --+
     |                                             |
     +------------------------------- freelist <---+
                                 ~~~~~~~~~~~~~~~~~~~~~
                                 ~  mutex protected  ~
                                 ~~~~~~~~~~~~~~~~~~~~~

Bug: 73886018
Test: perfetto_unittests --gtest_filter=PagePoolTest.*
Change-Id: Id0fa389cc3d6c9347b2a25c8b49d8ff901fed7c9
diff --git a/Android.bp b/Android.bp
index 6e4f684..f265d74 100644
--- a/Android.bp
+++ b/Android.bp
@@ -236,6 +236,7 @@
     "src/traced/probes/ftrace/ftrace_metadata.cc",
     "src/traced/probes/ftrace/ftrace_procfs.cc",
     "src/traced/probes/ftrace/ftrace_stats.cc",
+    "src/traced/probes/ftrace/page_pool.cc",
     "src/traced/probes/ftrace/proto_translation_table.cc",
     "src/traced/probes/probes.cc",
     "src/traced/probes/probes_data_source.cc",
@@ -520,6 +521,7 @@
     "src/traced/probes/ftrace/ftrace_procfs.cc",
     "src/traced/probes/ftrace/ftrace_procfs_integrationtest.cc",
     "src/traced/probes/ftrace/ftrace_stats.cc",
+    "src/traced/probes/ftrace/page_pool.cc",
     "src/traced/probes/ftrace/proto_translation_table.cc",
     "src/traced/probes/ftrace/test/cpu_reader_support.cc",
     "src/traced/probes/probes_data_source.cc",
@@ -2353,6 +2355,8 @@
     "src/traced/probes/ftrace/ftrace_procfs.cc",
     "src/traced/probes/ftrace/ftrace_procfs_unittest.cc",
     "src/traced/probes/ftrace/ftrace_stats.cc",
+    "src/traced/probes/ftrace/page_pool.cc",
+    "src/traced/probes/ftrace/page_pool_unittest.cc",
     "src/traced/probes/ftrace/proto_translation_table.cc",
     "src/traced/probes/ftrace/proto_translation_table_unittest.cc",
     "src/traced/probes/ftrace/test/cpu_reader_support.cc",