github.com/aclements/go-misc@v0.0.0-20240129233631-2f6ede80790c/memmodel/sc.go (about)

     1  // Copyright 2016 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package main
     6  
     7  // SCModel models all loads and stores as sequentially consistent.
     8  // That is, there is a total order over all loads and stores. It
     9  // implements sequential consistency using a direct operational
    10  // semantics.
    11  type SCModel struct{}
    12  
    13  func (SCModel) String() string {
    14  	return "SC"
    15  }
    16  
    17  func (SCModel) Eval(p *Prog, outcomes *OutcomeSet) {
    18  	// Run the program in all possible ways, gather the results of
    19  	// each load instruction, and at the end of each execution
    20  	// record the outcome.
    21  	outcomes.Reset(p)
    22  	(&scGlobal{p, outcomes}).rec(scState{})
    23  }
    24  
    25  // scGlobal stores state that is global to an SC evaluation.
    26  type scGlobal struct {
    27  	p        *Prog
    28  	outcomes *OutcomeSet
    29  }
    30  
    31  // scState stores the state of a program at a single point during
    32  // execution.
    33  type scState struct {
    34  	mem     MemState
    35  	pcs     [MaxThreads]int
    36  	outcome Outcome
    37  }
    38  
    39  func (g *scGlobal) rec(s scState) {
    40  	var opres int
    41  	// Pick an op to execute next.
    42  	any := false
    43  	for tid := range g.p.Threads {
    44  		op := g.p.Threads[tid].Ops[s.pcs[tid]]
    45  		if op.Type != OpExit {
    46  			any = true
    47  			ns := s
    48  			ns.mem, opres = op.Exec(ns.mem)
    49  			if op.Type == OpLoad {
    50  				ns.outcome |= Outcome(opres) << op.ID
    51  			}
    52  			ns.pcs[tid]++
    53  			g.rec(ns)
    54  		}
    55  	}
    56  	if !any {
    57  		// This execution is done.
    58  		g.outcomes.Add(s.outcome)
    59  	}
    60  }