lib/ovs-atomic.h
/* Decrements 'refcount' and returns the previous reference count.  To
 * be used only when a memory barrier is already provided for the
 * protected object independently.
 *
 * For example:
 *
 * if (ovs_refcount_unref_relaxed(&object->ref_cnt) == 1) {
 *     ovsrcu_postpone(destructor_function, object);
 * }
 *
 * Here RCU quiescing already provides a full memory barrier.  No additional
 * barriers are needed here.
 *
 * Or:
 *
 * if (stp && ovs_refcount_unref_relaxed(&stp->ref_cnt) == 1) {
 *     ovs_mutex_lock(&mutex);
 *     ovs_list_remove(&stp->node);
 *     ovs_mutex_unlock(&mutex);
 *     free(stp->name);
 *     free(stp);
 * }
 *
 * Here a mutex is used to guard access to all of 'stp' apart from
 * 'ref_cnt'.  Hence all changes to 'stp' by other threads must be
 * visible when we get the mutex, and no access after the unlock can
 * be reordered to happen prior the lock operation.  No additional
 * barriers are needed here.
 */
Decrements 'refcount' and returns the previous reference count.  To
be used only when a memory barrier is already provided for the
protected object independently.

For example.



Here RCU quiescing already provides a full memory barrier.  No additional
barriers are needed here.





Here a mutex is used to guard access to all of 'stp' apart from
'ref_cnt'.  Hence all changes to 'stp' by other threads must be
visible when we get the mutex, and no access after the unlock can
be reordered to happen prior the lock operation.  No additional
barriers are needed here.
Decrements ' refcount ' and returns the previous reference count . To be used only when a memory barrier is already provided for the protected object independently . For example . Here RCU quiescing already provides a full memory barrier . No additional barriers are needed here . Here a mutex is used to guard access to all of ' stp ' apart from ' ref_cnt ' . Hence all changes to ' stp ' by other threads must be visible when we get the mutex and no access after the unlock can be reordered to happen prior the lock operation . No additional barriers are needed here .
static inline unsigned int
ovs_refcount_unref_relaxed(struct ovs_refcount *refcount)
{
    unsigned int old_refcount;
    atomic_sub_explicit(&refcount->count, 1u, &old_refcount,
                        memory_order_relaxed);
    ovs_assert(old_refcount > 0);
    return old_refcount;
}
static inline unsigned int ovs_refcount_unref_relaxed ( struct ovs_refcount * refcount ) { unsigned int old_refcount ; atomic_sub_explicit ( & refcount -> count , 1u , & old_refcount , memory_order_relaxed ) ; ovs_assert ( old_refcount > 0 ) ; return old_refcount ; }
Decrements 'refcount' and returns the previous reference count.
Decrements ' refcount ' and returns the previous reference count .