Define and enforce atomicity as an explicit contract: if correctness depends on thread/writer invariants, encode it in the API name/docs and validate it at usage sites; if a value can be concurrently updated, read/write it exclusively via atomic operations (no non-atomic peeking into parts of an atomic container).

Practical rules: 1) Single-writer “atomic” helpers

2) Packed atomic bitfields

3) Document IO-thread vs main-thread invariants

Example (atomic-packed refcount access):

#define OBJ_REFCOUNT_MASK ((1U << OBJ_REFCOUNT_BITS) - 1)
#define OBJ_EXPIRABLE_BIT 30
#define OBJ_ISKVOBJ_BIT 31

static inline unsigned robj_refcount(const robj *o) {
    uint32_t v;
    atomicGet(o->atomic_flags_refcount, v); // must be atomic
    return v & OBJ_REFCOUNT_MASK;
}

static inline unsigned robj_expirable(const robj *o) {
    uint32_t v;
    atomicGet(o->atomic_flags_refcount, v); // must be atomic
    return (v >> OBJ_EXPIRABLE_BIT) & 1;
}

If you can’t clearly state the invariants and make every concurrent access atomic-safe, redesign the ownership model or synchronization rather than relying on “it never races” assumptions.