Merge changes Ia7ee9d37,Ia3214243

* changes:
  Update Marl to 5f31df137
  Squashed 'third_party/marl/' changes from bf3e23083..5f31df137
diff --git a/third_party/marl/.gitignore b/third_party/marl/.gitignore
index c99ccc1..0c63853 100644
--- a/third_party/marl/.gitignore
+++ b/third_party/marl/.gitignore
@@ -1,2 +1,3 @@
 /.vscode/
-/build/
\ No newline at end of file
+/build/
+bazel-*
diff --git a/third_party/marl/BUILD.bazel b/third_party/marl/BUILD.bazel
new file mode 100644
index 0000000..bcb5643
--- /dev/null
+++ b/third_party/marl/BUILD.bazel
@@ -0,0 +1,54 @@
+# Copyright 2019 The Marl Authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+cc_library(
+    name = "marl",
+    srcs = glob(
+        [
+            "src/**/*.cpp",
+            "src/**/*.c",
+            "src/**/*.h",
+        ],
+        exclude = glob([
+            "src/**/*_test.cpp",
+        ]),
+    ) + select({
+        "@bazel_tools//src/conditions:windows": [],
+        "//conditions:default": glob(["src/**/*.S"]),
+    }),
+    hdrs = glob([
+        "include/marl/**/*.h",
+    ]),
+    includes = [
+        "include",
+    ],
+    linkopts = select({
+        "@bazel_tools//src/conditions:linux_x86_64": ["-pthread"],
+        "//conditions:default": [],
+    }),
+    visibility = [
+        "//visibility:public",
+    ],
+)
+
+cc_test(
+    name = "tests",
+    srcs = glob([
+        "src/**/*_test.cpp",
+    ]),
+    deps = [
+        "//:marl",
+        "@googletest//:gtest",
+    ],
+)
diff --git a/third_party/marl/WORKSPACE b/third_party/marl/WORKSPACE
new file mode 100644
index 0000000..60425d6
--- /dev/null
+++ b/third_party/marl/WORKSPACE
@@ -0,0 +1,18 @@
+# Copyright 2019 The Marl Authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+local_repository(
+  name = "googletest",
+  path = "./third_party/googletest",
+)
diff --git a/third_party/marl/examples/BUILD.bazel b/third_party/marl/examples/BUILD.bazel
new file mode 100644
index 0000000..5d68d73
--- /dev/null
+++ b/third_party/marl/examples/BUILD.bazel
@@ -0,0 +1,33 @@
+# Copyright 2019 The Marl Authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+cc_binary(
+  name = "fractal",
+  srcs = [
+    "fractal.cpp",
+  ],
+  deps = [
+    "//:marl",
+  ],
+)
+
+cc_binary(
+  name = "primes",
+  srcs = [
+    "primes.cpp",
+  ],
+  deps = [
+    "//:marl",
+  ],
+)
diff --git a/third_party/marl/kokoro/linux/presubmit.cfg b/third_party/marl/kokoro/linux/bazel/presubmit.cfg
similarity index 73%
rename from third_party/marl/kokoro/linux/presubmit.cfg
rename to third_party/marl/kokoro/linux/bazel/presubmit.cfg
index 131a77f..6568287 100644
--- a/third_party/marl/kokoro/linux/presubmit.cfg
+++ b/third_party/marl/kokoro/linux/bazel/presubmit.cfg
@@ -2,3 +2,8 @@
 
 # Location of the continuous bash script in Git.
 build_file: "marl/kokoro/linux/presubmit.sh"
+
+env_vars {
+  key: "BUILD_SYSTEM"
+  value: "bazel"
+}
diff --git a/third_party/marl/kokoro/linux/presubmit.cfg b/third_party/marl/kokoro/linux/cmake/presubmit.cfg
similarity index 73%
copy from third_party/marl/kokoro/linux/presubmit.cfg
copy to third_party/marl/kokoro/linux/cmake/presubmit.cfg
index 131a77f..f377ee0 100644
--- a/third_party/marl/kokoro/linux/presubmit.cfg
+++ b/third_party/marl/kokoro/linux/cmake/presubmit.cfg
@@ -2,3 +2,8 @@
 
 # Location of the continuous bash script in Git.
 build_file: "marl/kokoro/linux/presubmit.sh"
+
+env_vars {
+  key: "BUILD_SYSTEM"
+  value: "cmake"
+}
diff --git a/third_party/marl/kokoro/linux/presubmit.sh b/third_party/marl/kokoro/linux/presubmit.sh
index ae166f4..60bddbe 100755
--- a/third_party/marl/kokoro/linux/presubmit.sh
+++ b/third_party/marl/kokoro/linux/presubmit.sh
@@ -3,21 +3,39 @@
 set -e # Fail on any error.
 set -x # Display commands being run.
 
+BUILD_ROOT=$PWD
+
 cd github/marl
 
 git submodule update --init
 
-mkdir build
-cd build
+if [ "$BUILD_SYSTEM" == "cmake" ]; then
+    mkdir build
+    cd build
 
-build_and_run() {
-    cmake .. -DMARL_BUILD_EXAMPLES=1 -DMARL_BUILD_TESTS=1 -DMARL_WARNINGS_AS_ERRORS=1 $1
-    make --jobs=$(nproc)
+    build_and_run() {
+        cmake .. -DMARL_BUILD_EXAMPLES=1 -DMARL_BUILD_TESTS=1 -DMARL_WARNINGS_AS_ERRORS=1 $1
+        make --jobs=$(nproc)
 
-    ./marl-unittests
-    ./fractal
-}
+        ./marl-unittests
+        ./fractal
+        ./primes > /dev/null
+    }
 
-build_and_run ""
-build_and_run "-DMARL_ASAN=1"
-build_and_run "-DMARL_MSAN=1"
\ No newline at end of file
+    build_and_run ""
+    build_and_run "-DMARL_ASAN=1"
+    build_and_run "-DMARL_MSAN=1"
+elif [ "$BUILD_SYSTEM" == "bazel" ]; then
+    # Get bazel
+    curl -L -k -O -s https://github.com/bazelbuild/bazel/releases/download/0.29.1/bazel-0.29.1-installer-linux-x86_64.sh
+    mkdir $BUILD_ROOT/bazel
+    bash bazel-0.29.1-installer-linux-x86_64.sh --prefix=$BUILD_ROOT/bazel
+    rm bazel-0.29.1-installer-linux-x86_64.sh
+    # Build and run
+    $BUILD_ROOT/bazel/bin/bazel test //:tests
+    $BUILD_ROOT/bazel/bin/bazel run //examples:fractal
+    $BUILD_ROOT/bazel/bin/bazel run //examples:primes > /dev/null
+else
+    echo "Unknown build system: $BUILD_SYSTEM"
+    exit 1
+fi
\ No newline at end of file
diff --git a/third_party/marl/kokoro/macos/presubmit.cfg b/third_party/marl/kokoro/macos/bazel/presubmit.cfg
similarity index 73%
rename from third_party/marl/kokoro/macos/presubmit.cfg
rename to third_party/marl/kokoro/macos/bazel/presubmit.cfg
index 009e936..c897fb3 100644
--- a/third_party/marl/kokoro/macos/presubmit.cfg
+++ b/third_party/marl/kokoro/macos/bazel/presubmit.cfg
@@ -2,3 +2,8 @@
 
 # Location of the continuous bash script in Git.
 build_file: "marl/kokoro/macos/presubmit.sh"
+
+env_vars {
+  key: "BUILD_SYSTEM"
+  value: "bazel"
+}
diff --git a/third_party/marl/kokoro/macos/presubmit.cfg b/third_party/marl/kokoro/macos/cmake/presubmit.cfg
similarity index 73%
copy from third_party/marl/kokoro/macos/presubmit.cfg
copy to third_party/marl/kokoro/macos/cmake/presubmit.cfg
index 009e936..aa023a9 100644
--- a/third_party/marl/kokoro/macos/presubmit.cfg
+++ b/third_party/marl/kokoro/macos/cmake/presubmit.cfg
@@ -2,3 +2,8 @@
 
 # Location of the continuous bash script in Git.
 build_file: "marl/kokoro/macos/presubmit.sh"
+
+env_vars {
+  key: "BUILD_SYSTEM"
+  value: "cmake"
+}
diff --git a/third_party/marl/kokoro/macos/presubmit.sh b/third_party/marl/kokoro/macos/presubmit.sh
index 3d1b775..ea97913 100755
--- a/third_party/marl/kokoro/macos/presubmit.sh
+++ b/third_party/marl/kokoro/macos/presubmit.sh
@@ -3,15 +3,34 @@
 set -e # Fail on any error.
 set -x # Display commands being run.
 
+BUILD_ROOT=$PWD
+
 cd github/marl
 
 git submodule update --init
 
-mkdir build
-cd build
-cmake .. -DMARL_BUILD_EXAMPLES=1 -DMARL_BUILD_TESTS=1 -DMARL_WARNINGS_AS_ERRORS=1
-make -j$(sysctl -n hw.logicalcpu)
+if [ "$BUILD_SYSTEM" == "cmake" ]; then
+    mkdir build
+    cd build
 
-./marl-unittests
+    cmake .. -DMARL_BUILD_EXAMPLES=1 -DMARL_BUILD_TESTS=1 -DMARL_WARNINGS_AS_ERRORS=1
+    make -j$(sysctl -n hw.logicalcpu)
 
-./fractal
+    ./marl-unittests
+
+    ./fractal
+    ./primes > /dev/null
+elif [ "$BUILD_SYSTEM" == "bazel" ]; then
+    # Get bazel
+    curl -L -k -O -s https://github.com/bazelbuild/bazel/releases/download/0.29.1/bazel-0.29.1-installer-darwin-x86_64.sh
+    mkdir $BUILD_ROOT/bazel
+    sh bazel-0.29.1-installer-darwin-x86_64.sh --prefix=$BUILD_ROOT/bazel
+    rm bazel-0.29.1-installer-darwin-x86_64.sh
+    # Build and run
+    $BUILD_ROOT/bazel/bin/bazel test //:tests
+    $BUILD_ROOT/bazel/bin/bazel run //examples:fractal
+    $BUILD_ROOT/bazel/bin/bazel run //examples:primes > /dev/null
+else
+    echo "Unknown build system: $BUILD_SYSTEM"
+    exit 1
+fi
\ No newline at end of file
diff --git a/third_party/marl/kokoro/windows/presubmit.cfg b/third_party/marl/kokoro/windows/bazel/presubmit.cfg
similarity index 73%
rename from third_party/marl/kokoro/windows/presubmit.cfg
rename to third_party/marl/kokoro/windows/bazel/presubmit.cfg
index d580a41..ef6acd8 100644
--- a/third_party/marl/kokoro/windows/presubmit.cfg
+++ b/third_party/marl/kokoro/windows/bazel/presubmit.cfg
@@ -2,3 +2,8 @@
 
 # Location of the continuous bash script in Git.
 build_file: "marl/kokoro/windows/presubmit.bat"
+
+env_vars {
+  key: "BUILD_SYSTEM"
+  value: "bazel"
+}
diff --git a/third_party/marl/kokoro/windows/presubmit.cfg b/third_party/marl/kokoro/windows/cmake/presubmit.cfg
similarity index 73%
copy from third_party/marl/kokoro/windows/presubmit.cfg
copy to third_party/marl/kokoro/windows/cmake/presubmit.cfg
index d580a41..72d1734 100644
--- a/third_party/marl/kokoro/windows/presubmit.cfg
+++ b/third_party/marl/kokoro/windows/cmake/presubmit.cfg
@@ -2,3 +2,8 @@
 
 # Location of the continuous bash script in Git.
 build_file: "marl/kokoro/windows/presubmit.bat"
+
+env_vars {
+  key: "BUILD_SYSTEM"
+  value: "cmake"
+}
diff --git a/third_party/marl/kokoro/windows/presubmit.bat b/third_party/marl/kokoro/windows/presubmit.bat
index 504ad8c..9c15406 100644
--- a/third_party/marl/kokoro/windows/presubmit.bat
+++ b/third_party/marl/kokoro/windows/presubmit.bat
@@ -2,30 +2,62 @@
 
 SETLOCAL ENABLEDELAYEDEXPANSION
 
+SET BUILD_ROOT=%cd%
 SET PATH=C:\python36;C:\Program Files\cmake\bin;%PATH%
-set SRC=%cd%\github\marl
+SET SRC=%cd%\github\marl
 
 cd %SRC%
-if !ERRORLEVEL! neq 0 exit /b !ERRORLEVEL!
+if !ERRORLEVEL! neq 0 exit !ERRORLEVEL!
 
 git submodule update --init
-if !ERRORLEVEL! neq 0 exit /b !ERRORLEVEL!
+if !ERRORLEVEL! neq 0 exit !ERRORLEVEL!
 
 SET MSBUILD="C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\MSBuild\15.0\Bin\MSBuild"
 SET CONFIG=Release
 
 mkdir %SRC%\build
 cd %SRC%\build
-if !ERRORLEVEL! neq 0 exit /b !ERRORLEVEL!
+if !ERRORLEVEL! neq 0 exit !ERRORLEVEL!
 
-cmake .. -G "Visual Studio 15 2017 Win64" -Thost=x64 "-DMARL_BUILD_TESTS=1" "-DMARL_BUILD_EXAMPLES=1" "-DMARL_WARNINGS_AS_ERRORS=1"
-if !ERRORLEVEL! neq 0 exit /b !ERRORLEVEL!
+IF /I "%BUILD_SYSTEM%"=="cmake" (
+    cmake .. -G "Visual Studio 15 2017 Win64" -Thost=x64 "-DMARL_BUILD_TESTS=1" "-DMARL_BUILD_EXAMPLES=1" "-DMARL_WARNINGS_AS_ERRORS=1"
+    if !ERRORLEVEL! neq 0 exit !ERRORLEVEL!
+    %MSBUILD% /p:Configuration=%CONFIG% Marl.sln
+    if !ERRORLEVEL! neq 0 exit !ERRORLEVEL!
+    Release\marl-unittests.exe
+    if !ERRORLEVEL! neq 0 exit !ERRORLEVEL!
+    Release\fractal.exe
+    if !ERRORLEVEL! neq 0 exit !ERRORLEVEL!
+    Release\primes.exe > nul
+    if !ERRORLEVEL! neq 0 exit !ERRORLEVEL!
+) ELSE IF /I "%BUILD_SYSTEM%"=="bazel" (
+    REM Fix up the MSYS environment.
+    wget -q http://repo.msys2.org/mingw/x86_64/mingw-w64-x86_64-gcc-7.3.0-2-any.pkg.tar.xz
+    wget -q http://repo.msys2.org/mingw/x86_64/mingw-w64-x86_64-gcc-libs-7.3.0-2-any.pkg.tar.xz
+    c:\tools\msys64\usr\bin\bash --login -c "pacman -R --noconfirm catgets libcatgets"
+    c:\tools\msys64\usr\bin\bash --login -c "pacman -Syu --noconfirm"
+    c:\tools\msys64\usr\bin\bash --login -c "pacman -Sy --noconfirm mingw-w64-x86_64-crt-git patch"
+    c:\tools\msys64\usr\bin\bash --login -c "pacman -U --noconfirm mingw-w64-x86_64-gcc*-7.3.0-2-any.pkg.tar.xz"
+    set PATH=C:\tools\msys64\mingw64\bin;c:\tools\msys64\usr\bin;!PATH!
+    set BAZEL_SH=C:\tools\msys64\usr\bin\bash.exe
 
-%MSBUILD% /p:Configuration=%CONFIG% Marl.sln
-if !ERRORLEVEL! neq 0 exit /b !ERRORLEVEL!
+    REM Install Bazel
+    SET BAZEL_DIR=!BUILD_ROOT!\bazel
+    mkdir !BAZEL_DIR!
+    if !ERRORLEVEL! neq 0 exit !ERRORLEVEL!
+    wget -q https://github.com/bazelbuild/bazel/releases/download/0.29.1/bazel-0.29.1-windows-x86_64.zip
+    if !ERRORLEVEL! neq 0 exit !ERRORLEVEL!
+    unzip -q bazel-0.29.1-windows-x86_64.zip -d !BAZEL_DIR!
+    if !ERRORLEVEL! neq 0 exit !ERRORLEVEL!
 
-Release\marl-unittests.exe
-if !ERRORLEVEL! neq 0 exit /b !ERRORLEVEL!
-
-Release\fractal.exe
-if !ERRORLEVEL! neq 0 exit /b !ERRORLEVEL!
+    REM Build and run
+    !BAZEL_DIR!\bazel test //:tests --test_output=all
+    if !ERRORLEVEL! neq 0 exit !ERRORLEVEL!
+    !BAZEL_DIR!\bazel run //examples:fractal
+    if !ERRORLEVEL! neq 0 exit !ERRORLEVEL!
+    !BAZEL_DIR!\bazel run //examples:primes > nul
+    if !ERRORLEVEL! neq 0 exit !ERRORLEVEL!
+) ELSE (
+    echo "Unknown build system: %BUILD_SYSTEM%"
+    exit /b 1
+)
diff --git a/third_party/marl/src/osfiber_asm_aarch64.S b/third_party/marl/src/osfiber_asm_aarch64.S
index 1fa08d9..04db6de 100644
--- a/third_party/marl/src/osfiber_asm_aarch64.S
+++ b/third_party/marl/src/osfiber_asm_aarch64.S
@@ -44,6 +44,7 @@
     str x26, [x0, #MARL_REG_r26]
     str x27, [x0, #MARL_REG_r27]
     str x28, [x0, #MARL_REG_r28]
+    str x29, [x0, #MARL_REG_r29]
 
     str d8,  [x0, #MARL_REG_v8]
     str d9,  [x0, #MARL_REG_v9]
@@ -78,6 +79,7 @@
     ldr x26, [x7, #MARL_REG_r26]
     ldr x27, [x7, #MARL_REG_r27]
     ldr x28, [x7, #MARL_REG_r28]
+    ldr x29, [x7, #MARL_REG_r29]
 
     ldr d8,  [x7, #MARL_REG_v8]
     ldr d9,  [x7, #MARL_REG_v9]
diff --git a/third_party/marl/src/osfiber_asm_aarch64.h b/third_party/marl/src/osfiber_asm_aarch64.h
index ccd19ef..c50d742 100644
--- a/third_party/marl/src/osfiber_asm_aarch64.h
+++ b/third_party/marl/src/osfiber_asm_aarch64.h
@@ -27,16 +27,17 @@
 #define MARL_REG_r26 0x60
 #define MARL_REG_r27 0x68
 #define MARL_REG_r28 0x70
-#define MARL_REG_v8 0x78
-#define MARL_REG_v9 0x80
-#define MARL_REG_v10 0x88
-#define MARL_REG_v11 0x90
-#define MARL_REG_v12 0x98
-#define MARL_REG_v13 0xa0
-#define MARL_REG_v14 0xa8
-#define MARL_REG_v15 0xb0
-#define MARL_REG_SP 0xb8
-#define MARL_REG_LR 0xc0
+#define MARL_REG_r29 0x78
+#define MARL_REG_v8 0x80
+#define MARL_REG_v9 0x88
+#define MARL_REG_v10 0x90
+#define MARL_REG_v11 0x98
+#define MARL_REG_v12 0xa0
+#define MARL_REG_v13 0xa8
+#define MARL_REG_v14 0xb0
+#define MARL_REG_v15 0xb8
+#define MARL_REG_SP 0xc0
+#define MARL_REG_LR 0xc8
 
 #if defined(__APPLE__)
 #define MARL_ASM_SYMBOL(x) _##x
@@ -71,6 +72,7 @@
   uintptr_t r26;
   uintptr_t r27;
   uintptr_t r28;
+  uintptr_t r29;
 
   uintptr_t v8;
   uintptr_t v9;
@@ -117,6 +119,8 @@
               "Bad register offset");
 static_assert(offsetof(marl_fiber_context, r28) == MARL_REG_r28,
               "Bad register offset");
+static_assert(offsetof(marl_fiber_context, r29) == MARL_REG_r29,
+              "Bad register offset");
 static_assert(offsetof(marl_fiber_context, v8) == MARL_REG_v8,
               "Bad register offset");
 static_assert(offsetof(marl_fiber_context, v9) == MARL_REG_v9,
diff --git a/third_party/marl/src/scheduler.cpp b/third_party/marl/src/scheduler.cpp
index 09771ac..1a08d8f 100644
--- a/third_party/marl/src/scheduler.cpp
+++ b/third_party/marl/src/scheduler.cpp
@@ -408,7 +408,7 @@
     std::unique_lock<std::mutex>& lock) {
   MARL_ASSERT(work.num == work.fibers.size() + work.tasks.size(),
               "work.num out of sync");
-  if (work.num == 0) {
+  if (work.num == 0 && mode == Mode::MultiThreaded) {
     scheduler->onBeginSpinning(id);
     lock.unlock();
     spinForWork();
diff --git a/third_party/marl/src/scheduler_test.cpp b/third_party/marl/src/scheduler_test.cpp
index c0c5055..1f0562a 100644
--- a/third_party/marl/src/scheduler_test.cpp
+++ b/third_party/marl/src/scheduler_test.cpp
@@ -14,8 +14,11 @@
 
 #include "marl_test.h"
 
+#include "marl/defer.h"
 #include "marl/waitgroup.h"
 
+#include <unordered_set>
+
 TEST(WithoutBoundScheduler, SchedulerConstructAndDestruct) {
   auto scheduler = new marl::Scheduler();
   delete scheduler;
@@ -102,4 +105,27 @@
   for (auto& thread : threads) {
     thread.join();
   }
+}
+
+TEST(WithoutBoundScheduler, TasksOnlyScheduledOnWorkerThreads) {
+  auto scheduler = std::unique_ptr<marl::Scheduler>(new marl::Scheduler());
+  scheduler->bind();
+  scheduler->setWorkerThreadCount(8);
+  std::mutex mutex;
+  std::unordered_set<std::thread::id> threads;
+  marl::WaitGroup wg;
+  for (int i = 0; i < 10000; i++) {
+    wg.add(1);
+    marl::schedule([&mutex, &threads, wg] {
+      defer(wg.done());
+      std::unique_lock<std::mutex> lock(mutex);
+      threads.emplace(std::this_thread::get_id());
+    });
+  }
+  wg.wait();
+
+  ASSERT_EQ(threads.size(), 8U);
+  ASSERT_EQ(threads.count(std::this_thread::get_id()), 0U);
+
+  scheduler->unbind();
 }
\ No newline at end of file