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. Simultaneous Upgrades

Part 4 · Races and Controller Design · All levels

Simultaneous Upgrades

Serialize two GetM requests and turn the losing upgrade into a data acquisition after its shared copy is invalidated.

On this page

    What if both readers ask to write?

    Both requests can be in flight without both permissions being granted. Begin after completed reads from reset X = 0: C0 S / 0, C1 S / 0, H S{C0,C1}, memory = 0. Select MSI. H accepts A from C0 first and queues B from C1, rather than rejecting B. C0 writes first; C1 waits and writes next.

    Both cores enter SM^D for their local store requests. The losing C1 must still process Inv while its own GetM is queued. It loses its S bytes, acknowledges and becomes IM^D with a pending store. H must then supply a current value for B, not a permission-only upgrade. C0 performs its store of 1 before it answers the Fwd-GetM for B, by the policy below. In the table, queued GetM C1 means B waits in H's queue for X.

    C0 wins exclusive permission after C1 acknowledges invalidation, writes one, then relinquishes it so queued C1 receives one and writes two.
    Two queued upgrades: A completes first, B receives data because its original S copy was revoked.

    Step

    C0 state / value

    C1 state / value

    H directory

    Memory

    Newest data

    Initial

    S / 0

    S / 0

    S{C0,C1}

    0

    C0, C1 and memory: 0

    1. GetM A at H

    SM^D / 0

    S / 0

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

    0

    C0, C1 and memory: 0

    2. GetM B at H

    SM^D / 0

    SM^D / 0

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

    0

    C0, C1 and memory: 0

    3. Inv at C1

    SM^D / 0

    IM^D / -

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

    0

    C0 and memory: 0

    4. Inv-Ack at H

    SM^D / 0

    IM^D / -

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

    0

    C0 and memory: 0

    5. Data at C0

    M / 0

    IM^D / -

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

    0

    C0 and memory: 0

    (assumed) grant delivered

    M / 0

    IM^D / -

    exclusive(C0), queued GetM C1

    0

    C0 and memory: 0

    L. Local store

    M / 1

    IM^D / -

    exclusive(C0), queued GetM C1

    0

    C0: 1

    6. Fwd-GetM at C0

    I / -

    IM^D / -

    exclusive(C0), pend GetM C1

    0

    Data(1) in flight to H

    7. Data at H

    I / -

    IM^D / -

    exclusive(C0), pend GetM C1

    0

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

    8. 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

    H knows C1's copy is gone through the matching Inv-Ack, not through B's arrival or C1's intention to write. H starts B only after A's grant has been delivered (the grant-delivery rule). Data(1) carries the value from step 6 to step 7, and H's buffer holds it until step 8. Memory stays stale legally because the final holder is dirty and exclusive.

    Note

    Policy: a cache that receives its M grant performs at least the stalled store before it processes a Fwd or Inv for X. Without this, C0 and C1 can pass M back and forth while neither store completes (livelock).

    A waiting local request cannot block required protocol work

    If C1 refused Inv until B completed, A would wait for C1 while B waited behind A: a protocol dependency cycle. The chosen policy lets the Inv change C1's pending state without cancelling the processor store. This example uses a queue at H, not a NACK.

    Common pitfall

    Returning permission-only Data to B because its request began as an upgrade. C1 became I at step 3 and no longer has the bytes. Its final response must include the current value 1.

    Interview

    Name the winner, queue policy, losing cache's response to Inv, and how B's data requirement changes. Then state the store-before-Fwd policy and the livelock it prevents.

    Check yourself Could C1 keep S / 0 readable at step 3 simply because B is already queued?

    No. A is selected first and needs its old reader revoked. C1 acknowledges after losing that permission, retains its store intent, and later acquires a fresh current value for B.

    Related topics

    • Shared course model

    • Prerequisite: non-racing upgrade

    Previous

    39 / 167

    Next: Racing Requests at the Home

    Up next

    Up nextRacing Requests at the Home

    Sign in to save progress

    Practice this lessonReport an error

    See also

    • Eviction Versus Intervention