Backed out changeset 7f7f0a43f051 (bug 956899) for testThreadingExclusiveData failures CLOSED TREE
authorWes Kocher <wkocher@mozilla.com>
Mon, 07 Mar 2016 14:31:24 -0800
changeset 287157 359ea99d2000b81449e660aa95f08f74f1878f80
parent 287156 63688afe0bd3d526c93c4aa0a6bf94089e58eec6
child 287158 0e4c29a5ea1568f9ddaee553ca2f45111ecb27ef
push id30065
push userkwierso@gmail.com
push dateWed, 09 Mar 2016 00:01:05 +0000
treeherdermozilla-central@886b5480b578 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs956899
milestone47.0a1
backs out7f7f0a43f051424dbdc87db33a9947f7b87e8c89
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backed out changeset 7f7f0a43f051 (bug 956899) for testThreadingExclusiveData failures CLOSED TREE MozReview-Commit-ID: BHrjbFNJxfW
js/src/jsapi-tests/moz.build
js/src/jsapi-tests/testMutex.cpp
js/src/jsapi-tests/testThreadingExclusiveData.cpp
js/src/moz.build
js/src/threading/ExclusiveData.cpp
js/src/threading/ExclusiveData.h
js/src/vm/Mutex.cpp
js/src/vm/Mutex.h
--- a/js/src/jsapi-tests/moz.build
+++ b/js/src/jsapi-tests/moz.build
@@ -54,16 +54,17 @@ UNIFIED_SOURCES += [
     'testIntString.cpp',
     'testIntTypesABI.cpp',
     'testIsInsideNursery.cpp',
     'testJSEvaluateScript.cpp',
     'testLookup.cpp',
     'testLooselyEqual.cpp',
     'testMappedArrayBuffer.cpp',
     'testMutedErrors.cpp',
+    'testMutex.cpp',
     'testNewObject.cpp',
     'testNewTargetInvokeConstructor.cpp',
     'testNullRoot.cpp',
     'testObjectEmulatingUndefined.cpp',
     'testOOM.cpp',
     'testParseJSON.cpp',
     'testPersistentRooted.cpp',
     'testPreserveJitCode.cpp',
@@ -77,17 +78,16 @@ UNIFIED_SOURCES += [
     'testScriptInfo.cpp',
     'testScriptObject.cpp',
     'testSetProperty.cpp',
     'testSetPropertyIgnoringNamedGetter.cpp',
     'testSourcePolicy.cpp',
     'testStringBuffer.cpp',
     'testStructuredClone.cpp',
     'testSymbol.cpp',
-    'testThreadingExclusiveData.cpp',
     'testToIntWidth.cpp',
     'testTypedArrays.cpp',
     'testUbiNode.cpp',
     'testUncaughtError.cpp',
     'testUTF8.cpp',
     'testWasmLEB128.cpp',
     'testWeakMap.cpp',
     'testXDR.cpp',
rename from js/src/jsapi-tests/testThreadingExclusiveData.cpp
rename to js/src/jsapi-tests/testMutex.cpp
--- a/js/src/jsapi-tests/testThreadingExclusiveData.cpp
+++ b/js/src/jsapi-tests/testMutex.cpp
@@ -2,48 +2,50 @@
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/IntegerRange.h"
 #include "js/Vector.h"
 #include "jsapi-tests/tests.h"
-#include "threading/ExclusiveData.h"
+#include "vm/Mutex.h"
 
 // One thread for each bit in our counter.
 const static uint8_t numThreads = 64;
-const static bool showDiagnostics = false;
 
 struct CounterAndBit
 {
     uint8_t bit;
-    const js::ExclusiveData<uint64_t>& counter;
+    const js::Mutex<uint64_t>& counter;
 
-    CounterAndBit(uint8_t bit, const js::ExclusiveData<uint64_t>& counter)
+    CounterAndBit(uint8_t bit, const js::Mutex<uint64_t>& counter)
       : bit(bit)
       , counter(counter)
     {
         MOZ_ASSERT(bit < numThreads);
     }
 };
 
+const static bool shouldPrint = false;
+
 void
 printDiagnosticMessage(uint64_t seen)
 {
-    if (showDiagnostics) {
-        fprintf(stderr, "Thread %p saw ", PR_GetCurrentThread());
-        for (auto i : mozilla::MakeRange(numThreads)) {
-            if (seen & (uint64_t(1) << i))
-                fprintf(stderr, "1");
-            else
-                fprintf(stderr, "0");
-        }
-        fprintf(stderr, "\n");
+    if (!shouldPrint)
+        return;
+
+    fprintf(stderr, "Thread %p saw ", PR_GetCurrentThread());
+    for (auto i : mozilla::MakeRange(numThreads)) {
+        if (seen & (uint64_t(1) << i))
+            fprintf(stderr, "1");
+        else
+            fprintf(stderr, "0");
     }
+    fprintf(stderr, "\n");
 }
 
 void
 setBitAndCheck(void* arg)
 {
     auto& counterAndBit = *static_cast<CounterAndBit*>(arg);
 
     while (true) {
@@ -62,19 +64,22 @@ setBitAndCheck(void* arg)
             if (guard == UINT64_MAX) {
                 js_delete(&counterAndBit);
                 return;
             }
         }
     }
 }
 
-BEGIN_TEST(testExclusiveData)
+BEGIN_TEST(testMutex)
 {
-    js::ExclusiveData<uint64_t> counter(0);
+    auto maybeCounter = js::Mutex<uint64_t>::Create(0);
+    CHECK(maybeCounter.isSome());
+
+    js::Mutex<uint64_t> counter(mozilla::Move(*maybeCounter));
 
     js::Vector<PRThread*> threads(cx);
     CHECK(threads.reserve(numThreads));
 
     for (auto i : mozilla::MakeRange(numThreads)) {
         auto counterAndBit = js_new<CounterAndBit>(i, counter);
         CHECK(counterAndBit);
         auto thread = PR_CreateThread(PR_USER_THREAD,
@@ -89,9 +94,9 @@ BEGIN_TEST(testExclusiveData)
     }
 
     for (auto thread : threads) {
         CHECK(PR_JoinThread(thread) == PR_SUCCESS);
     }
 
     return true;
 }
-END_TEST(testExclusiveData)
+END_TEST(testMutex)
--- a/js/src/moz.build
+++ b/js/src/moz.build
@@ -289,17 +289,16 @@ UNIFIED_SOURCES += [
     'proxy/DeadObjectProxy.cpp',
     'proxy/DirectProxyHandler.cpp',
     'proxy/OpaqueCrossCompartmentWrapper.cpp',
     'proxy/Proxy.cpp',
     'proxy/ScriptedDirectProxyHandler.cpp',
     'proxy/ScriptedIndirectProxyHandler.cpp',
     'proxy/SecurityWrapper.cpp',
     'proxy/Wrapper.cpp',
-    'threading/ExclusiveData.cpp',
     'vm/ArgumentsObject.cpp',
     'vm/ArrayBufferObject.cpp',
     'vm/CallNonGenericMethod.cpp',
     'vm/CharacterEncoding.cpp',
     'vm/CodeCoverage.cpp',
     'vm/Compression.cpp',
     'vm/DateTime.cpp',
     'vm/Debugger.cpp',
@@ -309,16 +308,17 @@ UNIFIED_SOURCES += [
     'vm/GeneratorObject.cpp',
     'vm/GlobalObject.cpp',
     'vm/HelperThreads.cpp',
     'vm/Id.cpp',
     'vm/Interpreter.cpp',
     'vm/JSONParser.cpp',
     'vm/MemoryMetrics.cpp',
     'vm/Monitor.cpp',
+    'vm/Mutex.cpp',
     'vm/NativeObject.cpp',
     'vm/ObjectGroup.cpp',
     'vm/PIC.cpp',
     'vm/Printer.cpp',
     'vm/Probes.cpp',
     'vm/ProxyObject.cpp',
     'vm/ReceiverGuard.cpp',
     'vm/RegExpObject.cpp',
rename from js/src/threading/ExclusiveData.cpp
rename to js/src/vm/Mutex.cpp
--- a/js/src/threading/ExclusiveData.cpp
+++ b/js/src/vm/Mutex.cpp
@@ -1,39 +1,39 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "threading/ExclusiveData.h"
+#include "vm/Mutex.h"
 
 namespace js {
 
-/* static */ mozilla::Maybe<detail::ExclusiveDataBase>
-detail::ExclusiveDataBase::Create()
+/* static */ mozilla::Maybe<detail::MutexBase>
+detail::MutexBase::Create()
 {
     auto lock = PR_NewLock();
     if (!lock)
         return mozilla::Nothing();
 
-    return mozilla::Some(detail::ExclusiveDataBase(lock));
+    return mozilla::Some(detail::MutexBase(lock));
 }
 
-detail::ExclusiveDataBase::~ExclusiveDataBase()
+detail::MutexBase::~MutexBase()
 {
     if (lock_)
         PR_DestroyLock(lock_);
 }
 
 void
-detail::ExclusiveDataBase::acquire() const
+detail::MutexBase::acquire() const
 {
     PR_Lock(lock_);
 }
 
 void
-detail::ExclusiveDataBase::release() const
+detail::MutexBase::release() const
 {
     MOZ_RELEASE_ASSERT(PR_Unlock(lock_) == PR_SUCCESS);
 }
 
 } // namespace js
rename from js/src/threading/ExclusiveData.h
rename to js/src/vm/Mutex.h
--- a/js/src/threading/ExclusiveData.h
+++ b/js/src/vm/Mutex.h
@@ -1,64 +1,64 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#ifndef threading_ExclusiveData_h
-#define threading_ExclusiveData_h
+#ifndef js_Mutex_h
+#define js_Mutex_h
 
 #include "mozilla/Maybe.h"
 #include "mozilla/Move.h"
 
 #include "jslock.h"
 
 namespace js {
 
 namespace detail {
 
-class ExclusiveDataBase
+class MutexBase
 {
   private:
     mutable PRLock* lock_;
 
-    ExclusiveDataBase(const ExclusiveDataBase&) = delete;
-    ExclusiveDataBase& operator=(const ExclusiveDataBase&) = delete;
+    MutexBase(const MutexBase&) = delete;
+    MutexBase& operator=(const MutexBase&) = delete;
 
   public:
     // This move constructor is only public for `mozilla::Forward`.
-    ExclusiveDataBase(ExclusiveDataBase&& rhs)
+    MutexBase(MutexBase&& rhs)
       : lock_(rhs.lock_)
     {
         MOZ_ASSERT(&rhs != this, "self-move disallowed!");
         rhs.lock_ = nullptr;
     }
 
-    ~ExclusiveDataBase();
+    ~MutexBase();
 
   protected:
-    explicit ExclusiveDataBase(PRLock* lock)
+    explicit MutexBase(PRLock* lock)
       : lock_(lock)
     {
         MOZ_ASSERT(lock_);
     }
 
-    static mozilla::Maybe<ExclusiveDataBase> Create();
+    static mozilla::Maybe<MutexBase> Create();
 
     void acquire() const;
     void release() const;
 };
 
 } // namespace detail
 
 /**
  * A mutual exclusion lock class.
  *
- * `ExclusiveData` provides an RAII guard to automatically lock and unlock when
+ * `Mutex` provides an RAII guard to automatically lock and unlock when
  * accessing the protected inner value.
  *
  * Unlike the STL's `std::mutex`, the protected value is internal to this
  * class. This is a huge win: one no longer has to rely on documentation to
  * explain the relationship between a lock and its protected data, and the type
  * system can enforce[0] it.
  *
  * For example, suppose we have a counter class:
@@ -72,111 +72,109 @@ class ExclusiveDataBase
  *     };
  *
  * If we share a counter across threads with `std::mutex`, we rely solely on
  * comments to document the relationship between the lock and its data, like
  * this:
  *
  *     class SharedCounter
  *     {
- *         // Remember to acquire `counter_lock` when accessing `counter`,
- *         // pretty please!
+ *         // Remember to acquire `counter_lock` when accessing `counter`, pretty please!
  *         Counter counter;
  *         std::mutex counter_lock;
  *
  *       public:
  *         void inc(size_t n) {
  *             // Whoops, forgot to acquire the lock! Off to the races!
  *             counter.inc(n);
  *         }
  *     };
  *
- * In contrast, `ExclusiveData` wraps the protected value, enabling the type
- * system to enforce that we acquire the lock before accessing the value:
+ * In contrast, `Mutex` wraps the protected value, enabling the type system to
+ * enforce that we acquire the lock before accessing the value:
  *
  *     class SharedCounter
  *     {
- *         ExclusiveData<Counter> counter;
+ *         Mutex<Counter> counter;
  *
  *       public:
  *         void inc(size_t n) {
  *             auto guard = counter.lock();
  *             guard->inc(n);
  *         }
  *     };
  *
  * The API design is based on Rust's `std::sync::Mutex<T>` type.
  *
  * [0]: Of course, we don't have a borrow checker in C++, so the type system
  *      cannot guarantee that you don't stash references received from
- *      `ExclusiveData<T>::Guard` somewhere such that the reference outlives the
- *      guard's lifetime and therefore becomes invalid. To help avoid this last
+ *      `Mutex<T>::Guard` somewhere such that the reference outlives the guard's
+ *      lifetime and therefore becomes invalid. To help avoid this last
  *      foot-gun, prefer using the guard directly! Do not store raw references
  *      to the protected value in other structures!
  */
 template <typename T>
-class ExclusiveData : private detail::ExclusiveDataBase
+class Mutex : private detail::MutexBase
 {
     mutable T value_;
 
-    ExclusiveData(const ExclusiveData&) = delete;
-    ExclusiveData& operator=(const ExclusiveData&) = delete;
+    Mutex(const Mutex&) = delete;
+    Mutex& operator=(const Mutex&) = delete;
 
     template <typename U>
-    explicit ExclusiveData(U&& u, ExclusiveDataBase&& base)
-      : ExclusiveDataBase(mozilla::Move(base))
+    explicit Mutex(U&& u, MutexBase&& base)
+      : MutexBase(mozilla::Move(base))
       , value_(mozilla::Forward<U>(u))
     { }
 
   public:
     /**
-     * Create a new `ExclusiveData`, with perfect forwarding of the protected
-     * value.
+     * Create a new `Mutex`, with perfect forwarding of the protected value.
      *
      * On success, `mozilla::Some` is returned. On failure, `mozilla::Nothing`
      * is returned.
      */
     template <typename U>
-    static mozilla::Maybe<ExclusiveData<T>> Create(U&& u) {
-        auto base = detail::ExclusiveDataBase::Create();
+    static mozilla::Maybe<Mutex<T>> Create(U&& u) {
+        auto base = detail::MutexBase::Create();
         if (base.isNothing())
             return mozilla::Nothing();
-        return mozilla::Some(ExclusiveData(mozilla::Forward<U>(u), mozilla::Move(*base)));
+        return mozilla::Some(Mutex(mozilla::Forward<U>(u), mozilla::Move(*base)));
     }
 
-    ExclusiveData(ExclusiveData&& rhs)
-      : ExclusiveDataBase(mozilla::Move(static_cast<ExclusiveDataBase&&>(rhs)))
+    Mutex(Mutex&& rhs)
+      : MutexBase(mozilla::Move(static_cast<MutexBase&&>(rhs)))
       , value_(mozilla::Move(rhs.value_))
     {
         MOZ_ASSERT(&rhs != this, "self-move disallowed!");
     }
 
-    ExclusiveData& operator=(ExclusiveData&& rhs) {
-        this->~ExclusiveData();
-        new (this) ExclusiveData(mozilla::Move(rhs));
+    Mutex& operator=(Mutex&& rhs) {
+        this->~Mutex();
+        new (this) Mutex(mozilla::Move(rhs));
         return *this;
     }
 
     /**
-     * An RAII class that provides exclusive access to a `ExclusiveData<T>`'s
-     * protected inner `T` value.
+     * An RAII class that provides exclusive access to a `Mutex<T>`'s protected
+     * inner `T` value.
      *
      * Note that this is intentionally marked MOZ_STACK_CLASS instead of
      * MOZ_RAII_CLASS, as the latter disallows moves and returning by value, but
      * Guard utilizes both.
      */
     class MOZ_STACK_CLASS Guard
     {
-        const ExclusiveData* parent_;
+        const Mutex* parent_;
 
         Guard(const Guard&) = delete;
         Guard& operator=(const Guard&) = delete;
 
       public:
-        explicit Guard(const ExclusiveData& parent)
+        explicit Guard(const Mutex& parent)
           : parent_(&parent)
         {
             parent_->acquire();
         }
 
         Guard(Guard&& rhs)
           : parent_(rhs.parent_)
         {
@@ -209,9 +207,9 @@ class ExclusiveData : private detail::Ex
      */
     Guard lock() const {
         return Guard(*this);
     }
 };
 
 } // namespace js
 
-#endif // threading_ExclusiveData_h
+#endif // js_Mutex_h