{
  "schema": "auturnal.deep-research-review.v2",
  "slug": "weak-memory-contracts",
  "title": "Concurrent Programs Across Memory Models: From Litmus Tests to Contracts",
  "category": "Languages and verification",
  "dek": "The order visible in source code is only one layer of a concurrent program's semantics.",
  "abstract": "Concurrent software is governed by both a programming-language memory model and the target machine's permitted behavior. Treating either layer as simple interleaving can hide errors, while using an observed hardware outcome to justify a racy source program can be equally unsound. This review connects the x86-TSO model, the foundations of the C++ concurrency model, and its formalization through a store-buffering litmus test. A finite operational model enumerates sequentially consistent and buffered executions, demonstrating why two reads of zero are excluded in one model and permitted in the other. We distinguish atomicity, ordering, visibility, and progress, and show how release/acquire reasoning depends on the value actually observed. The figures expose allowed outcomes and combinatorial schedule growth without claiming hardware occurrence probabilities.",
  "english": "Concurrent software is governed by both a programming-language memory model and the target machine's permitted behavior. Treating either layer as simple interleaving can hide errors, while using an observed hardware outcome to justify a racy source program can be equally unsound. This review connects the x86-TSO model, the foundations of the C++ concurrency model, and its formalization through a store-buffering litmus test. A finite operational model enumerates sequentially consistent and buffered executions, demonstrating why two reads of zero are excluded in one model and permitted in the other. We distinguish atomicity, ordering, visibility, and progress, and show how release/acquire reasoning depends on the value actually observed. The figures expose allowed outcomes and combinatorial schedule growth without claiming hardware occurrence probabilities.",
  "refs": [
    "cs-06-1",
    "cs-06-2",
    "cs-06-3"
  ],
  "sections": [
    [
      "Two models lie between the programmer and the result",
      "A programmer writes source operations, a compiler transforms them, and a processor executes machine instructions under an architectural memory model. The source language and the machine need not expose identical behaviors. Correct compilation must preserve the language's contract while using the target's available ordering mechanisms.\nThis layered view matters because a hardware experiment cannot legalize a source-language data race. A program may appear reliable on one processor and still have undefined behavior at the language level. Conversely, an atomic source program can legitimately expose outcomes that surprise someone expecting every operation to participate in one global sequential order. A rigorous explanation must identify the language version, operation types, ordering annotations, compiler mapping, and machine model before interpreting a result.",
      [
        "cs-06-1",
        "cs-06-2",
        "cs-06-3"
      ]
    ],
    [
      "What the foundational papers establish",
      "Sewell and colleagues give a precise x86-TSO model with an intuitive store-buffer account and machine-checked foundations. Boehm and Adve explain key decisions behind the C++ concurrency model, including the treatment of data races and the goal of useful guarantees for race-free programs. Batty and colleagues formalize C++ concurrency and analyze the relationship between language semantics and implementation.\nThese papers motivate precise reasoning rather than a claim that one historical model is a complete current specification. Our executable example is a deliberately restricted operational model of two stores, two loads, and FIFO store-buffer flushes. It excludes read-modify-write instructions, mixed-size accesses, device memory, and the full details of language-level undefined behavior. Its results belong to that model, not to every processor carrying a familiar architecture label.",
      [
        "cs-06-1",
        "cs-06-2",
        "cs-06-3"
      ]
    ],
    [
      "The store-buffering litmus test",
      "Initialize x and y to zero. Thread A stores one to x and then reads y into r_A. Thread B stores one to y and then reads x into r_B. Under sequential consistency, all four operations must have a total order consistent with each thread's program order. If r_A is zero, A's read precedes B's store. If r_B is zero, B's read precedes A's store. Combining those constraints with the two program orders creates an impossible cycle.\nThus both reads cannot be zero in the sequentially consistent model. The argument is a proof about an order relation, not a statement that writes propagate instantaneously in physical hardware. The appendix enumerates the six interleavings that preserve each thread's two-operation order and confirms the exclusion. The enumeration provides a concrete companion to the cycle argument.",
      []
    ],
    [
      "Buffers produce a different allowed execution",
      "In the buffered model, a store first enters its issuing thread's queue and becomes visible to the other thread when it flushes to shared memory. A load of an unrelated address may execute while the earlier store remains buffered. Both stores can therefore enter their queues, both loads can read the initial shared zeros, and both queues can flush later.\nThis witness does not require a processor to execute arbitrary instructions out of order at the source level. It arises from the distinction between issuing a store and making it visible. The finite checker adds one flush event per thread, constrains each flush to follow its store, and explores all legal event orders. It confirms four reachable read-result pairs in this restricted model, compared with three under sequential consistency. It does not assign physical frequencies to those outcomes.",
      []
    ],
    [
      "Atomicity and order answer different questions",
      "An atomic variable provides rules that prevent an access from behaving like a torn ordinary read or write within the language's specified setting. Ordering controls which relationships between accesses must hold. Atomic operations with weak ordering can therefore avoid a data race without making every cross-thread observation sequentially consistent.\nA useful review separates several claims: the value is not torn; updates to one object have a coherent modification order; a reader observes particular preceding writes; and some operation eventually completes. None is a synonym for the others. A lock-free algorithm may satisfy a system-wide progress property while allowing one thread to starve. A memory-order annotation may establish visibility without imposing fairness on scheduling. Performance comparisons must preserve the same correctness and progress contracts before their costs can be meaningfully compared.",
      []
    ],
    [
      "Release and acquire need a connecting observation",
      "A common publication pattern writes a payload and then publishes a flag with release semantics. A reader loads the flag with acquire semantics and, if it observes the corresponding publication as defined by the language, can use the resulting synchronization relationship to reason about the payload. The words release and acquire alone do not create a relationship between arbitrary operations.\nIf the reader observes an earlier flag value or accesses the payload before the relevant synchronization, the intended argument may fail. Reusing a flag across multiple object lifetimes introduces additional questions about which publication was observed. In a review, draw the actual reads-from and ordering relationships and state the lifetime assumptions. This is more reliable than placing strong-looking annotations around code and assuming the intended dependency follows.",
      [
        "cs-06-2",
        "cs-06-3"
      ]
    ],
    [
      "A fence must close the relevant path",
      "A fence has meaning within a specific memory model and in relation to surrounding operations. It is not a universal command to make every earlier write visible everywhere. In the toy store-buffer model, requiring each thread's store to flush before its subsequent load removes the both-zero witness. That is an explicit model transformation whose effect can be enumerated.\nMapping such a condition to real source code requires the language's rules and the compiler's target mapping. Replacing a missing synchronization relation with a hardware-specific instruction inside otherwise racy code may not restore a valid language-level argument. The correct unit of analysis is the full path from source semantics through generated code to allowed hardware execution. A litmus test is valuable precisely because it keeps that path small enough to inspect.",
      []
    ],
    [
      "Why schedule counts are not probabilities",
      "The first figure counts allowed read-result pairs under three declared variants: sequential consistency, the buffered model, and the buffered model with store-before-load flushing. These counts show a semantic difference. They are not estimates of how often a CPU will exhibit each outcome. A real processor's scheduling, cache state, contention, and compiler output determine an empirical distribution.\nThe second figure shows the number of interleavings of two threads with m ordered operations each, equal to the central binomial coefficient. At m equal to ten there are 184,756 such interleavings before additional memory events are introduced. Dynamic partial-order reduction and symbolic methods can avoid examining every equivalent schedule. The curve explains the pressure for those methods; it is not a measured runtime curve for a checker.",
      []
    ],
    [
      "Testing should preserve the observation boundary",
      "A hardware litmus harness needs to prevent the compiler from removing or transforming the experiment in ways inconsistent with the intended source semantics. It should record the exact generated code, compiler version and flags, processor model, operating conditions, repetition count, and all observed outcomes. Absence of an outcome in a finite run is not proof that the architecture forbids it.\nFor application code, tests should also cover object lifetime, reclamation, cancellation, and exceptional control flow. These often invalidate an otherwise correct publication argument. A useful negative control deliberately removes the synchronization relation in a model where the resulting witness is known. The test then demonstrates sensitivity to the property under investigation rather than merely exercising a high-volume loop that always appears to succeed.",
      []
    ],
    [
      "Conclusion: specify the allowed executions",
      "The productive question in concurrent programming is not whether the code usually runs in order, but which executions the language and target permit and which of those the algorithm can tolerate. The store-buffering example makes this difference visible with four operations and two additional flush events.\nPrecise memory models allow performance-oriented implementations without relying on folklore. Their benefit is lost when atomicity, ordering, visibility, and progress are merged into one vague notion of thread safety. A defensible argument names each required relation, checks the compiler and hardware boundary, and uses tests as observations of that contract rather than as substitutes for it.",
      []
    ]
  ],
  "section_kinds": [
    "source_based_review",
    "source_based_review",
    "author_analysis_or_verification_proposal",
    "author_analysis_or_verification_proposal",
    "author_analysis_or_verification_proposal",
    "source_based_review",
    "author_analysis_or_verification_proposal",
    "author_analysis_or_verification_proposal",
    "author_analysis_or_verification_proposal",
    "author_analysis_or_verification_proposal"
  ],
  "equations": [
    {
      "tex": "W_x \\prec R_y \\prec W_y \\prec R_x \\prec W_x",
      "explanation": "The cycle that would be required for both reads to return zero under sequential consistency; no strict total order can contain it."
    },
    {
      "tex": "W_x^{\\mathrm{buf}},W_y^{\\mathrm{buf}},R_y(0),R_x(0),F_x,F_y",
      "explanation": "One allowed witness in the declared store-buffer model; F denotes a flush to shared memory."
    },
    {
      "tex": "N_{\\mathrm{interleavings}}(m)=\\binom{2m}{m}",
      "explanation": "Two threads each perform m internally ordered events; this counts syntactic interleavings before equivalence reduction."
    },
    {
      "tex": "\\mathcal O_{\\mathrm{SC}}=\\{(0,1),(1,0),(1,1)\\},\\quad \\mathcal O_{\\mathrm{buf}}=\\mathcal O_{\\mathrm{SC}}\\cup\\{(0,0)\\}",
      "explanation": "Read-result sets for the specific two-thread litmus test and restricted operational models used here."
    }
  ],
  "table": {
    "headers": [
      "Question",
      "Relevant contract",
      "Common mistaken inference"
    ],
    "rows": [
      [
        "Is an access atomic?",
        "Language/architecture access semantics",
        "All accesses are globally ordered"
      ],
      [
        "Is data published?",
        "A justified synchronization relation",
        "Any acquire observes any release"
      ],
      [
        "Is an outcome possible?",
        "Formal allowed-execution model",
        "An unobserved outcome is forbidden"
      ],
      [
        "Does an operation finish?",
        "Progress and scheduling assumptions",
        "Memory ordering guarantees fairness"
      ]
    ]
  },
  "protocol": [
    "State the exact source and target models before running a litmus test.",
    "Enumerate the sequentially consistent store-buffering histories as a control.",
    "Add explicit store and flush events and retain the both-zero witness.",
    "Add the declared flush-before-load condition and verify that the witness disappears.",
    "For hardware experiments, preserve generated code and environment metadata.",
    "Review lifetime, reclamation, and progress properties separately from visibility."
  ],
  "limitations": [
    "The local model is a restricted operational abstraction, not the complete x86-TSO or C++ standard.",
    "No hardware litmus test or compiler conformance suite was executed.",
    "Allowed-outcome counts have no implied probability measure.",
    "The source papers are foundational historical results, not an exhaustive account of current architectures."
  ],
  "evidence": [
    {
      "source": "cs-06-1",
      "result": "A precise x86-TSO model supports reasoning beyond ambiguous informal processor descriptions.",
      "boundary": "Its full model contains more detail than the small buffer example here.",
      "locator": "Abstract and abstract-machine section."
    },
    {
      "source": "cs-06-2",
      "result": "The C++ concurrency design ties useful guarantees to language-level race and ordering rules.",
      "boundary": "Observed hardware behavior cannot justify undefined source behavior.",
      "locator": "Abstract and memory-model design discussion."
    },
    {
      "source": "cs-06-3",
      "result": "A formal account of C++ concurrency makes candidate executions and compilation questions explicit.",
      "boundary": "The paper concerns the modeled language design and its stated scope.",
      "locator": "Abstract and formal execution relations."
    }
  ],
  "research_questions": [
    "Does the actual reader observe the publication needed for the intended happens-before argument?",
    "Which compiler transformation or lifetime assumption could invalidate the algorithm?",
    "What progress guarantee is required beyond memory-order correctness?"
  ],
  "kind": "ai_assisted_research_guide",
  "author": "Codex (AI)",
  "original_language": "en",
  "created_date": "2026-10-22",
  "published_date": null,
  "publication_status": "local_draft_pending_owner_upload",
  "version": 1,
  "previous_version": null,
  "analytic": "weak-memory-contracts",
  "peer_reviewed": false,
  "journal_publication": false,
  "disclosure": {
    "authorship": "Written and technically self-reviewed by Codex (AI). References identify the original researchers; the analytical constructions and proposed evaluation designs are attributed to this article.",
    "figures": "Covers are conceptual ImageGen illustrations. Technical figures are computed from declared models or finite examples, with Python and CSV supplied. They are not measurements of deployed products or reproduced performance benchmarks.",
    "review": "This local draft has no independent peer-review or journal-acceptance record. Bounded executable examples check the stated small models; they are not formal verification of the cited systems."
  },
  "review_scope": "A focused analytical review of three selected foundational primary sources, with original worked examples. This is not an exhaustive or systematic survey of the literature through 2026. Source access and version notes are recorded with the bibliography.",
  "revision_note": "Initial local English manuscript; no server upload or publication action."
}
