tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

testThreadingExclusiveData.cpp (2315B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
      2 * vim: set ts=8 sts=2 et sw=2 tw=80:
      3 * This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #include "mozilla/IntegerRange.h"
      8 #include "js/Vector.h"
      9 #include "jsapi-tests/tests.h"
     10 #include "threading/ExclusiveData.h"
     11 #include "threading/Thread.h"
     12 
     13 // One thread for each bit in our counter.
     14 const static uint8_t NumThreads = 64;
     15 const static bool ShowDiagnostics = false;
     16 
     17 struct CounterAndBit {
     18  uint8_t bit;
     19  const js::ExclusiveData<uint64_t>& counter;
     20 
     21  CounterAndBit(uint8_t bit, const js::ExclusiveData<uint64_t>& counter)
     22      : bit(bit), counter(counter) {
     23    MOZ_ASSERT(bit < NumThreads);
     24  }
     25 };
     26 
     27 void printDiagnosticMessage(uint8_t bit, uint64_t seen) {
     28  if (!ShowDiagnostics) {
     29    return;
     30  }
     31 
     32  fprintf(stderr, "Thread %d saw ", bit);
     33  for (auto i : mozilla::IntegerRange(NumThreads)) {
     34    if (seen & (uint64_t(1) << i)) {
     35      fprintf(stderr, "1");
     36    } else {
     37      fprintf(stderr, "0");
     38    }
     39  }
     40  fprintf(stderr, "\n");
     41 }
     42 
     43 void setBitAndCheck(CounterAndBit* counterAndBit) {
     44  while (true) {
     45    {
     46      // Set our bit. Repeatedly setting it is idempotent.
     47      auto guard = counterAndBit->counter.lock();
     48      printDiagnosticMessage(counterAndBit->bit, guard);
     49      guard |= (uint64_t(1) << counterAndBit->bit);
     50    }
     51 
     52    {
     53      // Check to see if we have observed all the other threads setting
     54      // their bit as well.
     55      auto guard = counterAndBit->counter.lock();
     56      printDiagnosticMessage(counterAndBit->bit, guard);
     57      if (guard == UINT64_MAX) {
     58        js_delete(counterAndBit);
     59        return;
     60      }
     61    }
     62  }
     63 }
     64 
     65 BEGIN_TEST(testExclusiveData) {
     66  js::ExclusiveData<uint64_t> counter(js::mutexid::TestMutex, 0);
     67 
     68  js::Vector<js::Thread> threads(cx);
     69  CHECK(threads.reserve(NumThreads));
     70 
     71  for (auto i : mozilla::IntegerRange(NumThreads)) {
     72    auto counterAndBit = js_new<CounterAndBit>(i, counter);
     73    CHECK(counterAndBit);
     74    CHECK(threads.emplaceBack());
     75    CHECK(threads.back().init(setBitAndCheck, counterAndBit));
     76  }
     77 
     78  for (auto& thread : threads) {
     79    thread.join();
     80  }
     81 
     82  return true;
     83 }
     84 END_TEST(testExclusiveData)