mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-11-01 03:57:30 +09:00
89 lines
2.4 KiB
C++
89 lines
2.4 KiB
C++
/* -*- 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 "mozilla/IntegerRange.h"
|
|
#include "js/Vector.h"
|
|
#include "jsapi-tests/tests.h"
|
|
#include "threading/ExclusiveData.h"
|
|
#include "threading/Thread.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;
|
|
|
|
CounterAndBit(uint8_t bit, const js::ExclusiveData<uint64_t>& counter)
|
|
: bit(bit)
|
|
, counter(counter)
|
|
{
|
|
MOZ_ASSERT(bit < NumThreads);
|
|
}
|
|
};
|
|
|
|
void
|
|
printDiagnosticMessage(uint8_t bit, uint64_t seen)
|
|
{
|
|
if (!ShowDiagnostics)
|
|
return;
|
|
|
|
fprintf(stderr, "Thread %d saw ", bit);
|
|
for (auto i : mozilla::MakeRange(NumThreads)) {
|
|
if (seen & (uint64_t(1) << i))
|
|
fprintf(stderr, "1");
|
|
else
|
|
fprintf(stderr, "0");
|
|
}
|
|
fprintf(stderr, "\n");
|
|
}
|
|
|
|
void
|
|
setBitAndCheck(CounterAndBit* counterAndBit)
|
|
{
|
|
while (true) {
|
|
{
|
|
// Set our bit. Repeatedly setting it is idempotent.
|
|
auto guard = counterAndBit->counter.lock();
|
|
printDiagnosticMessage(counterAndBit->bit, guard);
|
|
guard |= (uint64_t(1) << counterAndBit->bit);
|
|
}
|
|
|
|
{
|
|
// Check to see if we have observed all the other threads setting
|
|
// their bit as well.
|
|
auto guard = counterAndBit->counter.lock();
|
|
printDiagnosticMessage(counterAndBit->bit, guard);
|
|
if (guard == UINT64_MAX) {
|
|
js_delete(counterAndBit);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
BEGIN_TEST(testExclusiveData)
|
|
{
|
|
js::ExclusiveData<uint64_t> counter(js::mutexid::TestMutex, 0);
|
|
|
|
js::Vector<js::Thread> threads(cx);
|
|
CHECK(threads.reserve(NumThreads));
|
|
|
|
for (auto i : mozilla::MakeRange(NumThreads)) {
|
|
auto counterAndBit = js_new<CounterAndBit>(i, counter);
|
|
CHECK(counterAndBit);
|
|
CHECK(threads.emplaceBack());
|
|
CHECK(threads.back().init(setBitAndCheck, counterAndBit));
|
|
}
|
|
|
|
for (auto& thread : threads)
|
|
thread.join();
|
|
|
|
return true;
|
|
}
|
|
END_TEST(testExclusiveData)
|