From ae39c7330e621253767a95fbe2f90b1a2ce4fe5f Mon Sep 17 00:00:00 2001 From: bsimmers Date: Tue, 23 Jul 2013 00:59:09 -0700 Subject: [PATCH] Fix AtomicVector::ensureSize I should've used unique_ptr::release() instead of unique_ptr::reset(), but I decided to stop using unique_ptr altogether since gcc generated nicer code without it. I also eliminated a redundant load of m_next. --- hphp/runtime/vm/func.cpp | 4 ++-- hphp/util/atomic_vector.h | 16 +++++++++------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/hphp/runtime/vm/func.cpp b/hphp/runtime/vm/func.cpp index 7c29fc3a2..15f6fe975 100644 --- a/hphp/runtime/vm/func.cpp +++ b/hphp/runtime/vm/func.cpp @@ -87,10 +87,10 @@ void Func::parametersCompat(const PreClass* preClass, const Func* imeth) const { static std::atomic s_nextFuncId(0); -// This size hint will create a ~8MB vector and is rarely hit in +// This size hint will create a ~6MB vector and is rarely hit in // practice. Note that this is just a hint and exceeding it won't // affect correctness. -constexpr size_t kFuncVecSizeHint = 1000000; +constexpr size_t kFuncVecSizeHint = 750000; static AtomicVector s_funcVec(kFuncVecSizeHint, nullptr); void Func::setNewFuncId() { diff --git a/hphp/util/atomic_vector.h b/hphp/util/atomic_vector.h index bd2951ede..9623b32bd 100644 --- a/hphp/util/atomic_vector.h +++ b/hphp/util/atomic_vector.h @@ -58,7 +58,7 @@ class AtomicVector { private: static std::string typeName(); - size_t m_size; + const size_t m_size; std::atomic m_next; const Value m_default; std::unique_ptr[]> m_vals; @@ -101,20 +101,22 @@ void AtomicVector::ensureSize(size_t size) { typeName(), size, m_size); if (m_size >= size) return; - if (!m_next.load(std::memory_order_acquire)) { - auto next = folly::make_unique(m_size * 2, m_default); + auto next = m_next.load(std::memory_order_acquire); + if (!next) { + next = new AtomicVector(m_size * 2, m_default); AtomicVector* expected = nullptr; - FTRACE(2, "Attempting to use {}...", next.get()); - if (!m_next.compare_exchange_strong(expected, next.get(), + FTRACE(2, "Attempting to use {}...", next); + if (!m_next.compare_exchange_strong(expected, next, std::memory_order_acq_rel)) { FTRACE(2, "lost race to {}\n", expected); + delete next; + next = expected; } else { FTRACE(2, "success\n"); - next.reset(); } } - m_next.load(std::memory_order_acquire)->ensureSize(size - m_size); + next->ensureSize(size - m_size); } template