hi 能解释一下Address 里面的version ABA, version +1, version +2, version -1 的场景和为什么,设计原理?,这确实没看懂 尤其 if (nref > 1), if ((ver2 & 1)) if (ver1 == ver2 || ver1 + 1 == ver2) ) 能讲解一下每个if分支 的作用
Socket::Address
Socket::Address(SocketId id, SocketUniquePtr* ptr) {
const base::ResourceId<Socket> slot = SlotOfSocketId(id);
Socket* const m = address_resource(slot);
if (__builtin_expect(m != NULL, 1)) {
// acquire fence makes sure this thread sees latest changes before
// Dereference() or Revive().
const uint64_t vref1 = m->_versioned_ref.fetch_add(
1, boost::memory_order_acquire);
const uint32_t ver1 = VersionOfVRef(vref1);
if (ver1 == VersionOfSocketId(id)) {
ptr->reset(m);
return 0;
}
const uint64_t vref2 = m->_versioned_ref.fetch_sub(
1, boost::memory_order_release);
const int32_t nref = NRefOfVRef(vref2);
if (nref > 1) {
return -1;
} else if (__builtin_expect(nref == 1, 1)) {
const uint32_t ver2 = VersionOfVRef(vref2);
if ((ver2 & 1)) {
if (ver1 == ver2 || ver1 + 1 == ver2) {
uint64_t expected_vref = vref2 - 1;
if (m->_versioned_ref.compare_exchange_strong(
expected_vref, MakeVRef(ver2 + 1, 0),
boost::memory_order_acquire,
boost::memory_order_relaxed)) {
m->OnRecycle();
return_resource(slot);
}
} else {
CHECK(false) << "ref-version=" << ver1
<< " unref-version=" << ver2;
}
} else {
CHECK_EQ(ver1, ver2);
// Addressed a free slot.
}
} else {
CHECK(false) << "Over dereferenced SocketId=" << id;
}
}
return -1;
}
hi 能解释一下Address 里面的version ABA, version +1, version +2, version -1 的场景和为什么,设计原理?,这确实没看懂 尤其 if (nref > 1), if ((ver2 & 1)) if (ver1 == ver2 || ver1 + 1 == ver2) ) 能讲解一下每个if分支 的作用
Socket::Address