fix(util/rc): reference counter memory_order flags
See discussion at http://www.chaoticmind.net/~hcb/projects/boost.atomic/doc/atomic/usage_examples.html#boost_atomic.usage_examples.example_reference_counters http://stackoverflow.com/questions/10268737/c11-atomics-and-intrusive-shared-pointer-reference-count Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
parent
c0f862d88a
commit
de657e8df0
3 changed files with 23 additions and 4 deletions
|
@ -336,13 +336,15 @@ struct import_modules_fn {
|
|||
}
|
||||
obj_counter++;
|
||||
}
|
||||
if (atomic_fetch_sub_explicit(&m_import_counter, 1u, memory_order_relaxed) == 1u) {
|
||||
if (atomic_fetch_sub_explicit(&m_import_counter, 1u, memory_order_release) == 1u) {
|
||||
atomic_thread_fence(memory_order_acquire);
|
||||
m_all_modules_imported = true;
|
||||
m_asynch_cv.notify_all();
|
||||
}
|
||||
// Module was successfully imported, we should notify descendents.
|
||||
for (module_info_ptr const & d : r->m_dependents) {
|
||||
if (atomic_fetch_sub_explicit(&(d->m_counter), 1u, memory_order_relaxed) == 1u) {
|
||||
if (atomic_fetch_sub_explicit(&(d->m_counter), 1u, memory_order_release) == 1u) {
|
||||
atomic_thread_fence(memory_order_acquire);
|
||||
// all d's dependencies have been processed
|
||||
add_import_module_task(d);
|
||||
}
|
||||
|
|
|
@ -16,8 +16,16 @@ atomic<unsigned> m_rc; \
|
|||
public: \
|
||||
unsigned get_rc() const { return atomic_load(&m_rc); } \
|
||||
void inc_ref() { atomic_fetch_add_explicit(&m_rc, 1u, memory_order_relaxed); } \
|
||||
bool dec_ref_core() { lean_assert(get_rc() > 0); return atomic_fetch_sub_explicit(&m_rc, 1u, memory_order_relaxed) == 1u; } \
|
||||
void dec_ref() { if (dec_ref_core()) dealloc(); }
|
||||
bool dec_ref_core() { \
|
||||
lean_assert(get_rc() > 0); \
|
||||
if (atomic_fetch_sub_explicit(&m_rc, 1u, memory_order_release) == 1u) { \
|
||||
atomic_thread_fence(memory_order_acquire); \
|
||||
return true; \
|
||||
} else { \
|
||||
return false; \
|
||||
} \
|
||||
} \
|
||||
void dec_ref() { if (dec_ref_core()) { dealloc(); } }
|
||||
|
||||
#define LEAN_COPY_REF(Arg) \
|
||||
if (Arg.m_ptr) \
|
||||
|
|
|
@ -31,6 +31,9 @@ using std::atomic_load;
|
|||
using std::atomic_fetch_add_explicit;
|
||||
using std::atomic_fetch_sub_explicit;
|
||||
using std::memory_order_relaxed;
|
||||
using std::memory_order_release;
|
||||
using std::memory_order_acquire;
|
||||
using std::atomic_thread_fence;
|
||||
namespace chrono = std::chrono;
|
||||
namespace this_thread = std::this_thread;
|
||||
}
|
||||
|
@ -46,9 +49,12 @@ using boost::mutex;
|
|||
using boost::recursive_mutex;
|
||||
using boost::atomic;
|
||||
using boost::memory_order_relaxed;
|
||||
using boost::memory_order_acquire;
|
||||
using boost::memory_order_release;
|
||||
using boost::condition_variable;
|
||||
using boost::unique_lock;
|
||||
using boost::lock_guard;
|
||||
using boost::atomic_thread_fence;
|
||||
namespace chrono = boost::chrono;
|
||||
namespace this_thread = boost::this_thread;
|
||||
typedef atomic<bool> atomic_bool;
|
||||
|
@ -71,6 +77,9 @@ namespace chrono {
|
|||
typedef unsigned milliseconds;
|
||||
}
|
||||
constexpr int memory_order_relaxed = 0;
|
||||
constexpr int memory_order_release = 0;
|
||||
constexpr int memory_order_acquire = 0;
|
||||
inline void atomic_thread_fence(int ) {}
|
||||
template<typename T>
|
||||
class atomic {
|
||||
T m_value;
|
||||
|
|
Loading…
Reference in a new issue