Optimise gatomicrefcount operations
Looking through the gatomicrefcount
code, I noticed that g_atomic_ref_count_inc()
does three atomic operations (when compiled without G_DISABLE_CHECKS
):
- one
get
for the precondition check - one
get
for the overflow check - the
inc
While I don’t want to get rid of the validation/checking, we should be able to get this down to 1 atomic operation on Linux. It should probably be possible on other platforms too, but I haven’t investigated that too closely. While I haven’t done any profiling on gatomicrefcount
, it would be good to make the One True Refcounting Implementation as good as possible; and multiple individual atomic operations make a non-atomic whole.
Sketch improved implementation:
#if defined(G_ATOMIC_LOCK_FREE) && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)
gint old_value;
g_return_if_fail (arc != NULL);
old_value = __sync_fetch_and_add (arc, 1);
g_return_if_fail (old_value > 0);
/* While we now critical() after the increment, that doesn’t matter since all bets are now off anyway */
if (old_value == G_MAXINT)
g_critical ("Reference count has reached saturation");
#else
/* … old implementation … */
#endif
Similar improvements could be made to some of the other gatomicrefcount
methods, though none of them are as atomic-operation-heavy as inc
.
We may want to add a new variant of g_atomic_int_inc()
which exposes this neatness to everyone else, too. I would settle for it just landing in gatomicrefcount
though.