Closed NickBarnes closed 2 weeks ago
(I had some questions/discussions in my comment and my expectation would be that maybe @NickBarnes has an opinion on them, which I would be curious to hear -- maybe he decides to update the PR as a result -- before we decide to merge.)
There are some calls to
caml_atomic_store_release(&num_domain_to_*
that could be turned intocaml_atomic_refcount_init
calls
Updating these.
and it may also make sense to define a helper function to encapsulate the
caml_atomic_load_acquire(&foo) == 0
logic, which is frequent in major_gc.c, and where the acquire ordering might be important for performance.
As I understand it, atomic_load(p)
is the same as atomic_load_explicit(p, memory_order_seq_cst)
which is the same as atomic_load_explicit(p, memory_order_acquire)
which is the same as atomic_load_acquire(p)
. I assume the reason we have atomic_load_acquire()
at all is to explicitly document the memory order for the programmer. I'm replacing all accesses to these atomic counters with calls to the appropriate inline caml_atomic_counter_
functions.
My impression is that this PR leaves the code slightly inconsistent in that some of the
num_domains_to_*
variables use some counter operations and also some plain loads and stores.
Fixing these up for consistency. Thank you.
Updated to reflect review comments: all access to atomic counters is now through caml_atomic_counter_...
inline functions.
As an experiment, I also made this branch which uses the singleton-struct hack to force all users to use this camlatomic.h
API. That found an instance in otherlibs/unix/mmap_ba.c
which was just using --
, which I have here replaced with the appropriate function call. Atomic types in C are defined such that --
and ++
decrement and increment operators on them do the right thing; this whole PR is based on the assumption that we avoid using those to emphasize the atomic nature - and cost - of the operations to the programmer.
This small PR unifies two separate implementations of atomic counters in the runtime. There are functions for
atomic_uintnat
counters inatomic_refcount.h
, used inbigarray.c
, and we use similar counters inmajor_gc.c
, with one inline functionatomic_fetch_add_verify_ge0
inplatform.h
which is only used for decrement but has an assertion to guard against underflow. I unify the two into inline functions incamlatomic.h
(which seems like the natural home for them). Incidentally, the increment/decrement functions now return the value after the update—obviously more intuitive than the previousatomic_refcount
semantics—which means a1
inbigarray.c
has become a0
. There's also a tiny tweak inmisc.h
to avoid the circular header dependency which otherwise arises.