Why this makes it correct
release covers the writer: ready never becomes visible before data (steps 2 and 4). acquire covers the reader: after it sees ready, queued invalidations are processed first, so the later load of data can't return the old value (step 6). Each covers one side and both are needed: with release only, core 1 can still read 0 from a stale line; with acquire only, ready may become visible before data.