Skip to content
DenseChip
Learn
PracticeCode labInterview

DenseChip

Navigate

Menu

LearnPracticeCode labInterview

Tools

All toolsSV editorCode repoResume
DenseChip

Practice, courses, and chip-design tools in one focused workspace.

LearnPracticeCode labInterviewToolsLearning paths

© 2026 DenseChip

AboutContactPrivacyTerms
Skip to lesson

Course contents

  • How to Use This Course
  • Reading Path
  • Cache Coherency Glossary
  • The Shared Course Model
  • Cache Coherency Revision Sheet
  • Why Coherence Exists8
  • States and Protocols12
  • Transactions12
  • Races and Controller Design8
    • Transient States and Races
      • Why Transient States Exist
      • Simultaneous Upgrades
      • Racing Requests at the Home
      • Eviction Versus Intervention
    • Controller Resources
  • Progress and the Fabric16
  • Ordering and Synchronization12
  • Performance and Scalability12
  • Real Protocols12
  • SoC Integration12
  • Power, Clocking and Reliability12
  • Verification12
  • Debug and Bring-up12
  • Interview and Design Review17
  • Capstone: A Coherent Model Lab5
Loading lesson

‹Transient States and Races
  1. Topics
  2. Cache Coherency
  3. Races and Controller Design
  4. Transient States and Races
  5. Racing Requests at the Home

Part 4 · Races and Controller Design · All levels

Racing Requests at the Home

Order a cold reader before a queued writer, deliver grants before revoking them, and handle an Inv or Fwd that overtakes its Data.

On this page

    Does arrival order automatically finish the first transaction?

    No. Selecting a request starts obligations; it does not make the intended cache state real. Reset MSI: C0 and C1 I, H U, memory = 0. C0 sends GetS A and C1 sends GetM B. In this example A reaches H first; H queues B and completes A before starting B's invalidation.

    C0 wins a read grant, not permanent priority. C1 waits until A's Data is delivered, then H invalidates C0, collects its acknowledgement, reads memory for B and grants C1 write permission. This first trace uses the grant-delivery rule of Parts 1 to 3. The section 'When the grant-delivery rule is dropped' below shows what a real protocol does instead.

    Two requests arrive at H, which completes C0's read before invalidating it and granting queued C1 the value zero with M permission.
    A read wins first; B waits through A's delivery, then revokes that reader before becoming writable.

    Step

    C0 state / value

    C1 state / value

    H directory

    Memory

    Newest data

    Initial

    I / -

    I / -

    U

    0

    memory: 0

    1. GetS A at H

    IS^D / -

    I / -

    U, pend GetS C0

    0

    memory: 0

    2. GetM B at H

    IS^D / -

    IM^D / -

    U, pend GetS C0, queued GetM C1

    0

    memory: 0

    H reads memory

    IS^D / -

    IM^D / -

    U, pend GetS C0, queued GetM C1

    0

    memory: 0, Data(0) in flight to C0

    3. Data at C0

    S / 0

    IM^D / -

    U, pend GetS C0, queued GetM C1

    0

    C0 and memory: 0

    (assumed) grant delivered

    S / 0

    IM^D / -

    S{C0}, queued GetM C1

    0

    C0 and memory: 0

    L. Load

    S / 0

    IM^D / -

    S{C0}, queued GetM C1

    0

    C0 and memory: 0

    4. Inv at C0

    I / -

    IM^D / -

    S{C0}, pend GetM C1, acks 0/1

    0

    memory: 0

    5. Inv-Ack at H

    I / -

    IM^D / -

    U, pend GetM C1, acks 1/1

    0

    memory: 0

    H reads memory for B

    I / -

    IM^D / -

    U, pend GetM C1, acks 1/1

    0

    memory: 0, Data(0) in flight to C1

    6. Data at C1

    I / -

    M / 0

    U, pend GetM C1, acks 1/1

    0

    C1 and memory: 0

    (assumed) grant delivered

    I / -

    M / 0

    exclusive(C1)

    0

    C1 and memory: 0

    L. Local store

    I / -

    M / 1

    exclusive(C1)

    0

    C1: 1

    memory = 0 is current throughout because no store happens before C1's L. If B reached H first, H would serve B first and A would wait: the order in which the cores sent their requests does not decide the order at H.

    Why not send both A's Data and B's Inv immediately?

    With no FIFO order between messages, Inv could reach C0 before its older granting Data. A naive cache in IS^D might acknowledge the Inv as if it held nothing, then install the late S grant after C1 has become writable: C0 would read a stale copy for ever. The grant-delivery rule avoids this by waiting. Real protocols do not assume H can see delivery, so they use one of the remedies below.

    When the grant-delivery rule is dropped

    The course model promised that Part 4 shows what real protocols do instead of the grant-delivery rule. There are two choices: the requester handles an Inv or Fwd that arrives before its Data (traces a and b), or the requester sends H a completion message so H knows the grant was delivered (trace c). In traces a and b H sends A's Data and starts B at once. Each numbered arrow is a delivered message, so an arrow's number is when it arrives, not when it was sent.

    a. An Inv overtakes Data: IS^D_I

    IS^D_I is the Primer's name for a cache that was in IS^D and has received an Inv. It remembers the Inv, uses the Data for the one pending load when it arrives, and then drops the copy and becomes I. C0 handles the Inv at once: it sends Inv-Ack without waiting for Data. That is safe because C0 has no readable copy, and the late Data is used once and never installed. The pending load is ordered before B's store, since it returns the value B replaces.

    C0 receives B's Inv while still in IS^D, acknowledges it and moves to IS^D_I. A's Data then serves the pending load and C0 ends invalid while C1 is granted M.
    An Inv that arrives before Data is acknowledged at once. The late Data serves one load and is dropped.

    Step

    C0 state / value

    C1 state / value

    H directory

    Memory

    Newest data

    Initial

    I / -

    I / -

    U

    0

    memory: 0

    1. GetS A at H

    IS^D / -

    I / -

    U, pend GetS C0

    0

    memory: 0

    2. GetM B at H

    IS^D / -

    IM^D / -

    U, pend GetS C0, queued GetM C1

    0

    memory: 0

    H reads memory

    IS^D / -

    IM^D / -

    U, pend GetS C0, queued GetM C1

    0

    memory: 0, Data(0) in flight to C0

    H starts B

    IS^D / -

    IM^D / -

    S{C0}, pend GetM C1, acks 0/1

    0

    memory: 0, Data(0) in flight to C0

    3. Inv at C0 (handled: Inv-Ack sent)

    IS^D_I / -

    IM^D / -

    S{C0}, pend GetM C1, acks 0/1

    0

    memory: 0, Data(0) in flight to C0

    4. Inv-Ack at H

    IS^D_I / -

    IM^D / -

    U, pend GetM C1, acks 1/1

    0

    memory: 0, Data(0) in flight to C0

    5. Data at C0, L. pending load returns 0

    I / -

    IM^D / -

    U, pend GetM C1, acks 1/1

    0

    memory: 0

    H reads memory for B

    I / -

    IM^D / -

    U, pend GetM C1, acks 1/1

    0

    memory: 0, Data(0) in flight to C1

    6. Data at C1

    I / -

    M / 0

    U, pend GetM C1, acks 1/1

    0

    C1 and memory: 0

    (assumed) grant delivered

    I / -

    M / 0

    exclusive(C1)

    0

    C1 and memory: 0

    L. Local store

    I / -

    M / 1

    exclusive(C1)

    0

    C1: 1

    H may also deliver step 6 before step 5. The result is the same: C1 may store 1 before C0's load returns 0, and that load is still ordered before the store.

    b. A Fwd-GetM overtakes Data: hold it in IM^D

    Now both requests are writes. C0 sends GetM A from I, C1 sends GetM B. H sends A's Data and at once forwards B to C0, its new exclusive holder. Fwd-GetM reaches C0 while it is still in IM^D. C0 cannot answer: it has neither the data nor the permission. It stalls the Fwd (holds it in its incoming queue) until Data arrives, performs its store, then answers. The stall cannot deadlock, because the Data it waits for is already in flight and depends on nothing C0 must do, provided the held Fwd does not block the queue that delivers Data.

    C0 receives B's forward while still in IM^D, holds it, receives its own Data, stores one, then sends one to H, which grants C1 M.
    A Fwd-GetM that arrives before Data waits at C0 until C0 has its grant and has done its store.

    Step

    C0 state / value

    C1 state / value

    H directory

    Memory

    Newest data

    Initial

    I / -

    I / -

    U

    0

    memory: 0

    1. GetM A at H

    IM^D / -

    I / -

    U, pend GetM C0

    0

    memory: 0

    2. GetM B at H

    IM^D / -

    IM^D / -

    U, pend GetM C0, queued GetM C1

    0

    memory: 0

    H reads memory

    IM^D / -

    IM^D / -

    U, pend GetM C0, queued GetM C1

    0

    memory: 0, Data(0) in flight to C0

    H starts B

    IM^D / -

    IM^D / -

    exclusive(C0), pend GetM C1

    0

    memory: 0, Data(0) in flight to C0

    3. Fwd-GetM at C0 (stalled)

    IM^D / -

    IM^D / -

    exclusive(C0), pend GetM C1

    0

    memory: 0, Data(0) in flight to C0

    4. Data at C0 (Fwd still stalled)

    M / 0

    IM^D / -

    exclusive(C0), pend GetM C1

    0

    C0 and memory: 0

    L. Local store

    M / 1

    IM^D / -

    exclusive(C0), pend GetM C1

    0

    C0: 1

    C0 handles the Fwd

    I / -

    IM^D / -

    exclusive(C0), pend GetM C1

    0

    Data(1) in flight to H

    5. Data at H

    I / -

    IM^D / -

    exclusive(C0), pend GetM C1

    0

    H buffer: 1, Data(1) in flight to C1

    6. Data at C1

    I / -

    M / 1

    exclusive(C0), pend GetM C1

    0

    C1: 1

    (assumed) grant delivered

    I / -

    M / 1

    exclusive(C1)

    0

    C1: 1

    L. Local store

    I / -

    M / 2

    exclusive(C1)

    0

    C1: 2

    The store before the answer is the policy from Simultaneous Upgrades: a cache that receives its M grant performs at least the stalled store before it processes a Fwd or Inv for X.

    c. The alternative: a completion message

    Instead of handling early Inv and Fwd, the requester tells H when its grant has arrived. It sends a completion message (called Complete here; real protocols use names such as Unblock or CompAck) after it installs the Data. H keeps the next transaction for X waiting until the completion arrives. The core uses its data at once, so the completion is off the requester's critical path. The cost is one extra message per transaction and a line that stays busy at H one leg longer.

    C0 receives its Data, uses it, and sends Complete to H. Only then does H invalidate C0 and grant C1 M.
    A completion message tells H that A's grant arrived, so H can safely start B.

    Step

    C0 state / value

    C1 state / value

    H directory

    Memory

    Newest data

    Initial

    I / -

    I / -

    U

    0

    memory: 0

    1. GetS A at H

    IS^D / -

    I / -

    U, pend GetS C0

    0

    memory: 0

    2. GetM B at H

    IS^D / -

    IM^D / -

    U, pend GetS C0, queued GetM C1

    0

    memory: 0

    H reads memory

    IS^D / -

    IM^D / -

    U, pend GetS C0, queued GetM C1

    0

    memory: 0, Data(0) in flight to C0

    3. Data at C0

    S / 0

    IM^D / -

    U, pend GetS C0, queued GetM C1

    0

    C0 and memory: 0

    L. Load

    S / 0

    IM^D / -

    U, pend GetS C0, queued GetM C1

    0

    C0 and memory: 0

    4. Complete at H

    S / 0

    IM^D / -

    S{C0}, pend GetM C1, acks 0/1

    0

    C0 and memory: 0

    5. Inv at C0

    I / -

    IM^D / -

    S{C0}, pend GetM C1, acks 0/1

    0

    memory: 0

    6. Inv-Ack at H

    I / -

    IM^D / -

    U, pend GetM C1, acks 1/1

    0

    memory: 0

    H reads memory for B

    I / -

    IM^D / -

    U, pend GetM C1, acks 1/1

    0

    memory: 0, Data(0) in flight to C1

    7. Data at C1

    I / -

    M / 0

    U, pend GetM C1, acks 1/1

    0

    C1 and memory: 0

    (assumed) grant delivered

    I / -

    M / 0

    exclusive(C1)

    0

    C1 and memory: 0

    L. Local store

    I / -

    M / 1

    exclusive(C1)

    0

    C1: 1

    What a waiting cache does with each event

    Stall means the event waits in the cache's incoming queue until the state changes. Rows are the requester's transient states in this course (acks collected at H).

    State

    Load

    Store

    Inv

    Fwd-GetS / Fwd-GetM

    Data

    IS^D

    Stall

    Stall

    Cannot occur under the grant-delivery rule, see the early-Inv section. Without it: send Inv-Ack, go to IS^D_I (trace a).

    Cannot occur under the grant-delivery rule, see the early-Inv section. Without it, only after an E grant (MESI, MOESI): stall until Data.

    Pending load returns the value, go to S.

    IM^D

    Stall

    Stall

    Cannot occur: an IM^D cache is not on H's sharer list, so H forwards to it rather than invalidating it.

    Cannot occur under the grant-delivery rule, see the early-Inv section. Without it: stall until Data, perform the store, then answer (trace b).

    Go to M, perform the stalled store first.

    SM^D

    Hit

    Stall

    Send Inv-Ack, go to IM^D (store intent kept).

    Cannot occur: H forwards only to an exclusive holder.

    Go to M, perform the stalled store first.

    IS^D_I

    Stall

    Stall

    Cannot occur: the Inv was already acknowledged.

    Cannot occur.

    Pending load returns the value, drop the copy, go to I.

    Common pitfall

    Changing H's stable entry to S{C0} at selection time and treating it as evidence that C0 has installed Data. Pending metadata must distinguish the intended holder from actual delivered permission.

    Interview

    Show the home choice and the completion dependency separately. Then give both real-protocol remedies: handle the early Inv or Fwd at the requester (IS^D_I, stall in IM^D), or send a completion message to H.

    Check yourself What does C0 acknowledge at step 5 of the first trace that it could not safely acknowledge before step 3?

    At step 5 it has received the read grant and has now revoked that installed permission. It could not safely acknowledge before step 3 without a transient state that remembers the Inv and drops the copy after one use: otherwise the late Data could install a stale readable copy.

    Related topics

    • Shared course model

    • Compare: two writers competing

    Previous

    40 / 167

    Next: Eviction Versus Intervention

    Up next

    Up nextEviction Versus Intervention

    Sign in to save progress

    Practice this lessonReport an error

    See also

    • Why Transient States Exist