void CompilerPool::shutdown(bool detach_compilers) { for (int i = 0; i < m_compilers.size(); ++i) { if (auto c = m_compilers.exchange(i, nullptr)) { if (detach_compilers) { c->detach_from_process(); } delete c; } } }
TEST(AtomicVector, append) { AtomicVector<int> vec; Refcount<int> rc; const int M = 100; for (int i = 0; i < M; i++) { vec.append(i * 3 + 1); } for (int i = 0; i < M; i++) { auto val = vec.read(i); assert(val == i * 3 + 1); rc.dec(val); } }
std::pair<size_t, ExternCompiler*> CompilerPool::getCompiler() { std::unique_lock<std::mutex> l(m_compilerLock); m_compilerCv.wait(l, [&] { return m_freeCount.load(std::memory_order_relaxed) != 0; }); m_freeCount -= 1; for (size_t id = 0; id < m_compilers.size(); ++id) { auto ret = m_compilers.exchange(id, nullptr); if (ret) return std::make_pair(id, ret); } not_reached(); }
TEST(AtomicVector, mpAppend) { Refcount<int> rc; // No missed appends for (int i = 0; i < 12; i++) { // A few times ASSERT_EQ(rc.get(1, true), 0); AtomicVector<int> lval; const int M = 1000; auto numThreads = mptest([&](int idx) { for (int i = 0; i < M; i++) { lval.append(1); } }); ASSERT_EQ(lval.size(), M * numThreads); ASSERT_EQ(rc.get(1), M * numThreads); } rc.assertClear(); }
TEST(AtomicVector, mpRefcount) { Refcount<int> rc; // Test refcount reasoning. for (int i = 0; i < 12; i++) { assert(rc.get(1, true) == 0); AtomicVector<int> lval; auto numThreads = mptest([&](int idx) { lval.append(1); }); ASSERT_EQ(lval.size(), numThreads); assert(rc.get(1) == numThreads); (void) mptest([&](int idx) { lval.write(idx, idx + 1); }); for (int i = 0; i < numThreads; i++) { ASSERT_EQ(rc.get(i + 1), 1); } } rc.assertClear(); }
TEST(AtomicVector, write) { AtomicVector<int> vec; Refcount<int> rc; // Some single-threaded write tests. bool sawExc = false; try { vec.write(1, 666); // Past end of vector } catch(runtime_error& re) { sawExc = true; } ASSERT_EQ(sawExc, true); // Append a few. const int N = 17; const int M = 1000; for (int i = 1; i < M; i++) { ASSERT_EQ(rc.get(i, true), 0); } for (int i = 0; i < N; i++) { vec.append(3 * i + 1); } for (int i = 0; i < N; i++) { ASSERT_EQ(rc.get(3 * i + 1), 1); } for (int i = 0; i < M; i++) { auto idx = i % N; vec.write(idx, i + 1); } for (int i = 0; i < N; i++) { auto val = vec.read(i); rc.dec(val); ASSERT_EQ(rc.get(val), 1); } }