I think your design is correct except for the type of int* refcount;
and the incorrect use of pointers. Right now you have nothing for it to point at, so you'll be invoking undefined behavior by passing the (indeterminate) pointer value to the atomic operations. I don't understand why you're using a pointer at all. The type should be:
int refcount;
and the code should be:
void value_retain(value v) {
atomic_fetch_add(&v.refcount, 1);
}
void value_release(value v) {
if(atomic_fetch_sub(&v.refcount, 1) == 1) {
// free memory, depending on type...
}
}
As for the order/barrier semantics, retain should be an acquire operation and release should be a release operation, but using full barriers for both is also ok.