Update Marl to bf3e23083

bf3e23083 pool.h: Don't over-qualify Loan type parameters
dc76e9653 CMake: Fix configuration file installation path
fca4771b4 Scheduler: Increase max number of threads from 64 to 256.
1b3fd77b2 debug: Add MARL_WARN for printing warnings
3928f44d6 [Grammar] Fix passive tense.
a2918916e CMake: Add install target (#21)
1ec7c36cf examples/primes.cpp: Add missing header including
ed21a07a1 Minor cleanup

Commands:
git subtree pull --prefix third_party/marl https://github.com/google/marl bf3e23083979c3bd3de1c77346b655eec423b3bc --squash

Bug: b/141003126
Change-Id: I5e9afad957d52919c48a60d8db49c04e43102870
diff --git a/third_party/marl/CMakeLists.txt b/third_party/marl/CMakeLists.txt
index f3ab6d9..7885494 100644
--- a/third_party/marl/CMakeLists.txt
+++ b/third_party/marl/CMakeLists.txt
@@ -26,6 +26,7 @@
 option(MARL_BUILD_TESTS "Build tests" OFF)
 option(MARL_ASAN "Build marl with address sanitizer" OFF)
 option(MARL_TSAN "Build marl with thread sanitizer" OFF)
+option(MARL_INSTALL "Create marl install target" OFF)
 
 if(MARL_ASAN AND MARL_TSAN)
     message(FATAL_ERROR "MARL_ASAN and MARL_TSAN are mutually exclusive")
@@ -53,7 +54,7 @@
 ###########################################################
 # File lists
 ###########################################################
-file(GLOB MARL_LIST
+set(MARL_LIST
     ${MARL_SRC_DIR}/debug.cpp
     ${MARL_SRC_DIR}/scheduler.cpp
     ${MARL_SRC_DIR}/thread.cpp
@@ -74,20 +75,6 @@
     )
 endif(NOT MSVC)
 
-file(GLOB MARL_TEST_LIST
-    ${MARL_SRC_DIR}/blockingcall_test.cpp
-    ${MARL_SRC_DIR}/conditionvariable_test.cpp
-    ${MARL_SRC_DIR}/containers_test.cpp
-    ${MARL_SRC_DIR}/defer_test.cpp
-    ${MARL_SRC_DIR}/marl_test.cpp
-    ${MARL_SRC_DIR}/marl_test.h
-    ${MARL_SRC_DIR}/osfiber_test.cpp
-    ${MARL_SRC_DIR}/pool_test.cpp
-    ${MARL_SRC_DIR}/scheduler_test.cpp
-    ${MARL_SRC_DIR}/ticket_test.cpp
-    ${MARL_SRC_DIR}/waitgroup_test.cpp
-)
-
 ###########################################################
 # OS libraries
 ###########################################################
@@ -148,10 +135,44 @@
 
 target_link_libraries(marl "${MARL_OS_LIBS}")
 
+# install
+if(MARL_INSTALL)
+    include(GNUInstallDirs)
+
+    install(DIRECTORY ${MARL_INCLUDE_DIR}/marl
+        DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
+        USE_SOURCE_PERMISSIONS
+    )
+
+    install(TARGETS marl
+        EXPORT marl-targets
+        ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+        LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+        RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+        INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
+    )
+
+    install(EXPORT marl-targets
+        FILE marl-config.cmake
+        NAMESPACE marl::
+        DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/marl
+    )
+endif(MARL_INSTALL)
+
 # tests
 if(MARL_BUILD_TESTS)
-    file(GLOB MARL_TEST_LIST
-        ${MARL_SRC_DIR}/*_test.cpp
+    set(MARL_TEST_LIST
+        ${MARL_SRC_DIR}/blockingcall_test.cpp
+        ${MARL_SRC_DIR}/conditionvariable_test.cpp
+        ${MARL_SRC_DIR}/containers_test.cpp
+        ${MARL_SRC_DIR}/defer_test.cpp
+        ${MARL_SRC_DIR}/marl_test.cpp
+        ${MARL_SRC_DIR}/marl_test.h
+        ${MARL_SRC_DIR}/osfiber_test.cpp
+        ${MARL_SRC_DIR}/pool_test.cpp
+        ${MARL_SRC_DIR}/scheduler_test.cpp
+        ${MARL_SRC_DIR}/ticket_test.cpp
+        ${MARL_SRC_DIR}/waitgroup_test.cpp
         ${GOOGLETEST_DIR}/googletest/src/gtest-all.cc
     )
 
diff --git a/third_party/marl/README.md b/third_party/marl/README.md
index 3641f79..7c3ed94 100644
--- a/third_party/marl/README.md
+++ b/third_party/marl/README.md
@@ -45,7 +45,7 @@
 
 ### Windows
 
-Marl can be build using [Visual Studio 2019's CMake integration](https://docs.microsoft.com/en-us/cpp/build/cmake-projects-in-visual-studio?view=vs-2019).
+Marl can be built using [Visual Studio 2019's CMake integration](https://docs.microsoft.com/en-us/cpp/build/cmake-projects-in-visual-studio?view=vs-2019).
 
 ### Using Marl in your CMake project
 
diff --git a/third_party/marl/examples/fractal.cpp b/third_party/marl/examples/fractal.cpp
index bf74f27..0993341 100644
--- a/third_party/marl/examples/fractal.cpp
+++ b/third_party/marl/examples/fractal.cpp
@@ -175,17 +175,20 @@
       for (uint32_t x = 0; x < imageWidth; x++) {
         // Calculate the fractal pixel color.
         Color<float> color = {};
+        // Take a number of sub-pixel samples.
         for (int sy = 0; sy < samplesPerPixelH; sy++) {
           auto fy = float(y) + (sy / float(samplesPerPixelH));
+          auto dy = float(fy) / float(imageHeight);
           for (int sx = 0; sx < samplesPerPixelW; sx++) {
             auto fx = float(x) + (sx / float(samplesPerPixelW));
             auto dx = float(fx) / float(imageWidth);
-            auto dy = float(fy) / float(imageHeight);
             color += julia(lerp(dx, windowMinX, windowMaxX),
                            lerp(dy, windowMinY, windowMaxY), cx, cy);
           }
         }
+        // Average the color.
         color /= samplesPerPixelW * samplesPerPixelH;
+        // Write the pixel out to the image buffer.
         pixels[x + y * imageWidth] = {static_cast<uint8_t>(color.r * 255),
                                       static_cast<uint8_t>(color.g * 255),
                                       static_cast<uint8_t>(color.b * 255)};
diff --git a/third_party/marl/examples/primes.cpp b/third_party/marl/examples/primes.cpp
index 9f77631..a6dea8ef 100644
--- a/third_party/marl/examples/primes.cpp
+++ b/third_party/marl/examples/primes.cpp
@@ -20,6 +20,8 @@
 #include "marl/thread.h"
 #include "marl/ticket.h"
 
+#include <math.h>
+
 // searchMax defines the upper limit on primes to find.
 constexpr int searchMax = 10000000;
 
diff --git a/third_party/marl/include/marl/debug.h b/third_party/marl/include/marl/debug.h
index 4eea139..ce4612a 100644
--- a/third_party/marl/include/marl/debug.h
+++ b/third_party/marl/include/marl/debug.h
@@ -26,6 +26,7 @@
 namespace marl {
 
 void fatal(const char* msg, ...);
+void warn(const char* msg, ...);
 void assert_has_bound_scheduler(const char* feature);
 
 #if MARL_DEBUG_ENABLED
@@ -39,11 +40,13 @@
 #define MARL_ASSERT_HAS_BOUND_SCHEDULER(feature) \
   assert_has_bound_scheduler(feature);
 #define MARL_UNREACHABLE() MARL_FATAL("UNREACHABLE");
+#define MARL_WARN(msg, ...) marl::warn("WARNING: " msg "\n", ##__VA_ARGS__);
 #else
 #define MARL_FATAL(msg, ...)
 #define MARL_ASSERT(cond, msg, ...)
 #define MARL_ASSERT_HAS_BOUND_SCHEDULER(feature)
 #define MARL_UNREACHABLE()
+#define MARL_WARN(msg, ...)
 #endif
 
 }  // namespace marl
diff --git a/third_party/marl/include/marl/pool.h b/third_party/marl/include/marl/pool.h
index 7fd50fe..69beaef 100644
--- a/third_party/marl/include/marl/pool.h
+++ b/third_party/marl/include/marl/pool.h
@@ -161,7 +161,7 @@
 }
 
 template <typename T>
-typename Pool<T>::Loan& Pool<T>::Loan::operator=(const Pool<T>::Loan& rhs) {
+typename Pool<T>::Loan& Pool<T>::Loan::operator=(const Loan& rhs) {
   reset();
   if (rhs.item != nullptr) {
     item = rhs.item;
@@ -172,7 +172,7 @@
 }
 
 template <typename T>
-typename Pool<T>::Loan& Pool<T>::Loan::operator=(Pool<T>::Loan&& rhs) {
+typename Pool<T>::Loan& Pool<T>::Loan::operator=(Loan&& rhs) {
   reset();
   std::swap(item, rhs.item);
   std::swap(storage, rhs.storage);
diff --git a/third_party/marl/include/marl/scheduler.h b/third_party/marl/include/marl/scheduler.h
index bb1b0af..7a04f49 100644
--- a/third_party/marl/include/marl/scheduler.h
+++ b/third_party/marl/include/marl/scheduler.h
@@ -137,7 +137,7 @@
   static constexpr size_t FiberStackSize = 1024 * 1024;
 
   // Maximum number of worker threads.
-  static constexpr size_t MaxWorkerThreads = 64;
+  static constexpr size_t MaxWorkerThreads = 256;
 
   // TODO: Implement a queue that recycles elements to reduce number of
   // heap allocations.
diff --git a/third_party/marl/src/debug.cpp b/third_party/marl/src/debug.cpp
index 4b9964a..8c8b7e4 100644
--- a/third_party/marl/src/debug.cpp
+++ b/third_party/marl/src/debug.cpp
@@ -32,6 +32,13 @@
   abort();
 }
 
+void warn(const char* msg, ...) {
+  va_list vararg;
+  va_start(vararg, msg);
+  vfprintf(stdout, msg, vararg);
+  va_end(vararg);
+}
+
 void assert_has_bound_scheduler(const char* feature) {
   MARL_ASSERT(Scheduler::get() != nullptr,
               "%s requires a marl::Scheduler to be bound", feature);
diff --git a/third_party/marl/src/scheduler.cpp b/third_party/marl/src/scheduler.cpp
index ca21cdd..09771ac 100644
--- a/third_party/marl/src/scheduler.cpp
+++ b/third_party/marl/src/scheduler.cpp
@@ -122,6 +122,14 @@
 
 void Scheduler::setWorkerThreadCount(int newCount) {
   MARL_ASSERT(newCount >= 0, "count must be positive");
+  if (newCount > int(MaxWorkerThreads)) {
+    MARL_WARN(
+        "marl::Scheduler::setWorkerThreadCount() called with a count of %d, "
+        "which exceeds the maximum of %d. Limiting the number of threads to "
+        "%d.",
+        newCount, int(MaxWorkerThreads), int(MaxWorkerThreads));
+    newCount = MaxWorkerThreads;
+  }
   auto oldCount = numWorkerThreads;
   for (int idx = oldCount - 1; idx >= newCount; idx--) {
     workerThreads[idx]->stop();