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; } } }
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(); }