A store request is an intention, not permission. A read epoch allows read-only copies and has no active writer. A write epoch gives one cache exclusive permission; it may contain many local loads and stores without any new coherence transaction. Idle time with readers remains a read epoch. There need not be a writer somewhere in the machine at every instant.
The value entering a new epoch must carry forward the result of the preceding write epoch, or the initial value if no write has occurred. Equal permissions alone cannot ensure this. The Primer, second edition, Chapter 2 develops the SWMR and data-value invariants using epochs. We apply that reasoning to one location, X; it does not establish ordering between different addresses or language-level synchronization.
For this independent warm example choose MSI: C0 and C1 start S / 0, H is S{C0,C1}, and memory = 0. This is a reachable read-epoch snapshot of the initially uncached X = 0. No earlier writer is assumed. C0 already has the correct data, so the final Data is permission-only: it authorises M while keeping the cached value 0. H serializes conflicts for X, records this upgrade as pending at step 1, and collects C1's Inv-Ack at step 3 before sending the step-4 grant: four serial legs.
Step | C0 state / value | C1 state / value | H directory | Memory | Newest data |
|---|---|---|---|---|---|
0. Read epoch | S / 0 | S / 0 | S{C0,C1} | 0 | C0, C1 and memory: 0 |
1. GetM at H | SM^D / 0 | S / 0 | S{C0,C1}, pend GetM C0, acks 0/1 | 0 | C0, C1 and memory: 0 |
2. Inv at C1 | SM^D / 0 | I / - | S{C0,C1}, pend GetM C0, acks 0/1 | 0 | C0 and memory: 0 |
3. Inv-Ack at H | SM^D / 0 | I / - | S{C0}, pend GetM C0, acks 1/1 | 0 | C0 and memory: 0 |
4. Data at C0 | M / 0 | I / - | S{C0}, pend GetM C0, acks 1/1 | 0 | C0 and memory: 0, Data carried no value |
(assumed) grant delivered | M / 0 | I / - | exclusive(C0) | 0 | C0 and memory: 0 |
L. Local store | M / 1 | I / - | exclusive(C0) | 0 | C0: 1 |
In SM^D C0 keeps its S copy: loads hit, stores stall. M / 0 at step 4 is deliberately conservative: the cache has write permission and takes dirty responsibility even before the pending store executes. At step 2 the directory still lists C1 until H processes its acknowledgement, although C1 has already invalidated. Pending metadata records outstanding obligations rather than a perfect instantaneous inventory. Likewise H keeps the pending upgrade in the step-4 row and records exclusive(C0) only in the '(assumed) grant delivered' row.
H chooses this upgrade before any conflicting transaction for X, then holds later work until it completes. The choice and the usable write grant are different events: selecting C0 does not revoke C1's permission. C1 loses its readable copy at step 2; H learns that at step 3; C0 can use exclusive permission at step 4. Those causal dependencies, not any assumed message order, make the boundary safe.
Not yet in this teaching trace. H has completed its acknowledgement wait, but C0 is still in SM^D until the permission-only Data arrives at step 4. The exclusive grant begins the usable write epoch; L changes the value within it.