Squashed 'third_party/marl/' changes from f1c446ccd..3285a2dfb

3285a2dfb Workaround MSAN false-positive
6bf128cab Assert that threads are joined before destruction
06b72af16 Scheduler: Add a couple of asserts

git-subtree-dir: third_party/marl
git-subtree-split: 3285a2dfb966fda7639391c43ec823fa88d70267
diff --git a/src/scheduler.cpp b/src/scheduler.cpp
index be20ed1..027565d 100644
--- a/src/scheduler.cpp
+++ b/src/scheduler.cpp
@@ -17,6 +17,7 @@
 #include "marl/scheduler.h"
 
 #include "marl/debug.h"
+#include "marl/sanitizers.h"
 #include "marl/thread.h"
 #include "marl/trace.h"
 
@@ -91,7 +92,13 @@
 }
 
 void Scheduler::bind() {
+#if !MEMORY_SANITIZER_ENABLED
+  // thread_local variables in shared libraries are initialized at load-time,
+  // but this is not observed by MemorySanitizer if the loader itself was not
+  // instrumented, leading to false-positive unitialized variable errors.
+  // See https://github.com/google/marl/issues/184
   MARL_ASSERT(bound == nullptr, "Scheduler already bound");
+#endif
   bound = this;
   {
     marl::lock lock(singleThreadedWorkers.mutex);
@@ -237,10 +244,16 @@
 }
 
 void Scheduler::Fiber::wait(marl::lock& lock, const Predicate& pred) {
+  MARL_ASSERT(worker == Worker::getCurrent(),
+              "Scheduler::Fiber::wait() must only be called on the currently "
+              "executing fiber");
   worker->wait(lock, nullptr, pred);
 }
 
 void Scheduler::Fiber::switchTo(Fiber* to) {
+  MARL_ASSERT(worker == Worker::getCurrent(),
+              "Scheduler::Fiber::switchTo() must only be called on the "
+              "currently executing fiber");
   if (to != this) {
     impl->switchTo(to->impl.get());
   }
diff --git a/src/thread.cpp b/src/thread.cpp
index 3febe62..d0750fa 100644
--- a/src/thread.cpp
+++ b/src/thread.cpp
@@ -402,11 +402,13 @@
     : impl(new Thread::Impl(std::move(affinity), std::move(func))) {}
 
 Thread::~Thread() {
-  delete impl;
+  MARL_ASSERT(!impl, "Thread::join() was not called before destruction");
 }
 
 void Thread::join() {
   impl->thread.join();
+  delete impl;
+  impl = nullptr;
 }
 
 void Thread::setName(const char* fmt, ...) {