Commit 7a366031 authored by Joe Ratterman's avatar Joe Ratterman Committed by Pavan Balaji
Browse files

When decrementing a ref-count to 0, do not bother with atomics.



  If the ref-count is 1, we *should* be the only thread holding a
  reference.  It is therefore legal to skip atomics.  If that is
  insufficient justificaion, consider that there are only three things
  a concurrent thread should be doing:

    1) Reading: Not a problem, since the store is atomic.
    2) Decrementing: Illegal; it would go negative using pure atomics.
    3) Incrementing: Illegal; we are about to destroy the object.

Add #ifdef guard for use of 'aggressive counter optimizations'

(ibm) 20a558c3802fb3e138eb6b3c786a434538efffdd
Signed-off-by: default avatarJoe Ratterman <jratt@us.ibm.com>
Signed-off-by: default avatarMichael Blocksome <blocksom@us.ibm.com>

Updated by Pavan Balaji to use an OPA atomic load instead of a simple
load operation.

Fixes #1835
Signed-off-by: Pavan Balaji's avatarPavan Balaji <balaji@anl.gov>
Signed-off-by: default avatarWilliam Gropp <wgropp@illinois.edu>
parent 835ab3bc
......@@ -300,10 +300,25 @@ typedef OPA_int_t MPIU_Handle_ref_count;
MPIU_HANDLE_LOG_REFCOUNT_CHANGE(objptr_, "incr"); \
MPIU_HANDLE_CHECK_REFCOUNT(objptr_,"incr"); \
} while (0)
/* Special optimization: when the reference count touches one, we are
* about to free the object. In this case, it is illegal for another
* thread to either increment the reference (i.e., create a new object
* that depends on this object) or decrement the references (i.e.,
* free the object simultaneously). We, however, have to ensure that
* our load is atomic. OPA does this for us, while optimizing it to a
* simple load for cases where the architecture already provides us
* with load atomicity and no need for load memory barriers. */
#define MPIU_Object_release_ref_always(objptr_,inuse_ptr) \
do { \
int got_zero_ = OPA_decr_and_test_int(&((objptr_)->ref_count)); \
*(inuse_ptr) = got_zero_ ? 0 : 1; \
if (likely(OPA_load_int((objptr_)->ref_count.v) == 1)) { \
(objptr_)->ref_count.v = 0; \
*(inuse_ptr) = 0; \
} \
else { \
int got_zero_ = OPA_decr_and_test_int(&((objptr_)->ref_count)); \
*(inuse_ptr) = got_zero_ ? 0 : 1; \
} \
MPIU_HANDLE_LOG_REFCOUNT_CHANGE(objptr_, "decr"); \
MPIU_HANDLE_CHECK_REFCOUNT(objptr_,"decr"); \
} while (0)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment