• No results found

Concolic Snippets and Programming with transit

Figure 4.2 shows the ingredients of a concolic snippet expressed in the transit lan- guage. We compare the elements in Figure 4.2 with the notation for a transition t ,

hl,m,guard,updates,l0iwhich we set up in Section 2.2. For clarity, a “Transition” — note themono-spacedfont — refers to the identically named construct in thetransitlanguage, whereas a “transition” — note the serif-ed font — refers to the notion of a transition formalized in Section 2.2.CurrentStaterepresents the initial location for the transition,lin our notation.

A Transition intransit groups togetheralltransitions which begin from a given initial location CurrentLocation ∈ L, i.e., a Transition in the transit language represents all

transitions of the formt,hCurrentState,m,guard,updates,l0i, which begin atCurrentState. Within eachTransition, we have multipleguard blocks, one for each transition which begins at locationCurrentState. TheInputEventdescribes the input messagem(or) which triggers

the transition. Within each guard block, the guard is optional. If left unspecified, it will be synthesized bytransit. Each guard block specifies aNextState, which isl0in our notation,

as well as an optional output messageOutMsg. transitallows the programmer tofuse a

transition involving the receipt of a message with a transition involving transmitting an output message,i.e., an input or internal transition, followed immediately by an output transition.

C1 C2 Dir EXCLUSIVE Owner=C1 Sharers=∅ READ Sender = C2 BUSY_SHARED Owner=C2 Sharers={C1} RepMsg IntMsg

Figure 4.3: An error trace generated by the model checker in response to an incorrect completion for the SGI-Origin protocol synthesized bytransit. Here, “C1” and “C2” represent two cache

esms and “Dir” represents the directoryesm. Time progresses downward along the dotted arrows (lanes) and the state of eachesmafter each transition is annotated along the lanes. Message exchanges and their contents are described using annotated arrows across lanes. Within each guard block,transitallows multiplePre-Postblocks. The semantics of each such

block of the formPrei⇒Posti1;Posti2; . . .Postim;, wherePreiis a Boolean valued expression

on the state variables and incoming message fields,V∪{mp}, andPostijconstrains the value of exactlyonestate variable or a field of the output messagemp, are that ifPreiholds at the

beginning of the transition, thenPostij,j∈[1,m]must hold after the transition has executed.

4.2.1

Using Snippets in

transit

To illustrate the use of snippets in transit, we use an anecdote from our case study of implementing the SGI-Origin cache coherence protocol [LL97] from published informal textual rules. A directory-based cache coherence protocol, such as the SGI-Origin protocol, ensures that the copies of data maintained in the private caches of a multi-processor system are kept consistent. The protocol has a distinguished “Directory” process, which maintains the global view of the processors in the system which currently have a copy of the data in the cache. The “Cache” processes coordinate with the Directory process via exchange of messages whenever they need to perform read or write operations on a block of data. The cache and the directory processes are typically modeled asesms, and we refer to them as processes or

esms interchangeably. In the SGI-Origin protocol, the directoryesmhas the variableSharers, whose type is a finite set of cache process (oresm) identifiers, and a variableOwner, whose type is a cache process identifier. TheSharers variable maintains the set of caches which

have a read-only copy of the data, whereas the value of theOwnervariable, if defined, is the identity of the sole cacheesmin the system which has a read-write copy of the data. The safety property that every cache coherence protocol needs to satisfy is thecoherence property,

which states that the valuereadby an cacheesmis the same as the value written by themost recentwrite operation by any cacheesmin the system.

One of the textual rules from the paper [LL97], describing the behavior of the directory

esmin the SGI-Origin protocol, on receiving a read request from a cacheesmreads:

If directory state is Exclusive with another owner, transitions to Busy-shared with requester as owner and send out an intervention shared request to the previous owner and a speculative reply to the requester. Go to 5b.

Note that this description does not specify how theSharersvariable needs to be updated. The programmer indicates that the new value of theSharersvariable needs to containat leastthe sender of the message received, in addition to the old contents of theSharersvariable. This is codified intransitusing the followingconcolic snippet:

Transition(EXCLUSIVE, ReqNet Msg) {

[] => (BUSY_SHARED, RepNet RepMsg, IntNet IntMsg) { (Msg.Type = READ & Msg.Sender != Owner) ==> {

SubsetOf(SetUnion(Sharers, {Msg.Sender}), Sharers’);

. . .

}}}

Note that this snippet isactiveonly when the current location of the directoryesmisEXCLUSIVE

and a request message is received. It also specifies that the location to transition to is BUSY_SHARED, and that the a reply message as well as an intervention message is to be trans- mitted, as required by the textual rule. TheReqNet,RepNetandIntNetdeclarations indicate the specific channels these messages are sent out over. This is a technicality required by the

transit language is not particularly relevant to the ideas we describe, so we ignore it in the rest of the manuscript. To be consistent with this snippet,transit needs to generate code for the update of the state variable Sharers such that the new value of the variable (denoted by the primed variableSharers’) is the super-set of union of the old value of the variable and the sender of the message. Based on the snippet provided by the user, suppose that transitgenerated the following code for the update of theSharers variable for the transition in question:

Sharers := Sharers ∪ {Msg.Sender}

An attempt to verify the protocol instantiated with this update, results in a violation of the coherence invariant. A visual representation of a simplified version of the error trace is shown in Figure 4.3. Observe that the transition shown on the directory esmin Figure 4.3 is a concrete instance of the concolic snippet that we have described, with the cacheesmC2being Msg.Senderand theOwnervariable of the directoryesmDir initially set toC1. Upon inspecting the error trace, the programmer recognized that in this particular case, the new value of theSharersvariable needed to include the previous value of theOwnervariable as well. The programmer codifies this using the followingconcrete snippet:

Transition(EXCLUSIVE, ReqNet Msg) {

[] => (BUSY_SHARED, RepNet RepMsg, IntNet IntMsg) {

(Msg.Type = READ & Msg.Sender = C2 & Owner = C1) ==> { Sharers’ = {C1, C2};

. . .

}}}

Observe that this snippet is only applicable in the specific case when the directory receives aREADrequest from cacheC2, and the owner is cacheC1. The programmer has not applied any global reasoning to come up with this snippet. With this additional snippet,transit

generated a new implementation with the correct update for theSharersvariable as: Sharers := Sharers ∪ {Msg.Sender,Owner}

To sum up,transitallows a snippet to be (1) completely symbolic, in which case the constraints on each lvalue are simple equalities, andtransitdoes not attempt to synthesize code for such snippets, instead treating them as the implementation itself, or (2) concolic, in which case, each of the constraintsPostijhas no restriction on its form, but only constrainsone lvalue, or (3) concrete, in which case, it still constrainsonelvalue, but concrete values are used

in both the pre- and the post-conditions in the constraints.