Click here to load reader

Automatically Verifying Concurrent Queue Algorithms

  • View
    30

  • Download
    0

Embed Size (px)

DESCRIPTION

Automatically Verifying Concurrent Queue Algorithms. Eran Yahav Mooly Sagiv School of Computer Science Tel-Aviv University {yahave,msagiv}@post.tau.ac.il http://www.cs.tau.ac.il/~yahave. Automatically Verifying Partial Correctness of Software using Abstract Interpretation. - PowerPoint PPT Presentation

Text of Automatically Verifying Concurrent Queue Algorithms

  • Automatically Verifying Concurrent Queue AlgorithmsEran Yahav Mooly SagivSchool of Computer ScienceTel-Aviv University

    {yahave,msagiv}@post.tau.ac.ilhttp://www.cs.tau.ac.il/~yahave

  • Automatically Verifying Partial Correctness of Softwareusing Abstract InterpretationOperates on the program sourceFully automaticConservative resultsNo errors are reported partial correctness is guaranteed But may produce false alarmsMakes the results non-usefulThe Challenge avoid false alarms

  • Concurrent Queues

    A common component of concurrent systemsOperating systemsA large number of suggested algorithmsHard to get right[Stone90] races + items may be lost[Valois94] items may be lost Mostly given without formal proof of correctness

  • Automatically Verifying Concurrent Queue Algorithms?Support the followingConcurrencyDynamic allocation/deallocation of objectsDestructive updatesHeap referencesUnbounded storage (heap)Dynamic allocation/deallocation of threadsHandling references with sufficient precision for establishing correctness propertiesPreceding pointer-analysis phase usually insufficient

  • Example [Michael&Scott PODC96]public void enqueue(Object value) { e_1 node = new QueueItem() // allocate queue nodee_2 node.val = value // copy enqueued value into nodee_3 node.next.ref = NULL e_4 while(true) { // Keep trying until done e_5 tail = this.Tail // get Tail.ptr and Tail.count e_6 next = tail.ref.next // get next ptr and count e_7 if (tail == this.Tail) { // are tails consistent?e_8 if (next.ref == NULL) { // was tail pointing to last node?e_9 if CAS(tail.ref.next, next, ) { // try connecte_10 break // Enqueue is done. Exit loop e_11 }e_12 } else { // tail wasnt pointing to last nodee_13 CAS(this.Tail, tail,) // try advance taile_14 } e_15 } e_16 } e_17 CAS(this.Tail, tail, ) //enqueue done. try swing tail e_18 }

  • Correctness P1 The linked list is always connectedP2 Nodes are only inserted after the last node of the linked listP3 Nodes are only deleted from the beginning of the linked listP4 Head always points to the first node in the linked listP5 Tail always points to a node in the linked list

  • Rich Problem Expressive FormalismWe use first-order logic with transitive closureNaturally define behavior of heap-manipulating programsHeap referencesHeap Reachability Threads as heap-allocated objects (and scheduling)Can also model integers

  • PlanVanilla verification attemptProgram configurationsExpressing safety propertiesAbstraction Refining the vanilla solutionInstrumentation predicatesPrototype implementation (TVLA/3VMC)

  • ConfigurationsA program configuration encodesglobal storeprogram-location of every threadstatus of locks and threadsFirst-order logical structures used to represent program configurations

  • Configurations as First-order Logical StructuresFirst-order structureObjects - Individuals properties of objects unary predicatesrelationship between objects binary predicatesAdditional integrity constraints FO formulas ObjectType unary predicatesReferences between objects binary predicatesThreadProgram location unary predicatesIntegers Distinguished zero individual unary predicateSuccessor relationship binary predicateWith integrity constraints corresponding to Peano axioms

  • Concrete Configurationat[e_2]at[e_2]zerosuccsuccsuccrv[node]rv[node]rv[this]rv[this]rv[Head]rv[next]rv[next]rv[next]rv[Tail]iv[Tail]iv[Head]iv[next]iv[next]iv[next]rv[value]rv[value]

  • ConfigurationsPredicates model properties of interesteq(v1,v2)is_T(v){ at[lab](t) : lab Labels }{ rv[fld](o1,o2) : fld Fields }{ iv[fld](o1,o2) : fld Fields }heldBy(l,t), blocked(t,l), waiting(t,l)zero(v), succ(v1,v2)Can use the framework with different predicates

  • Safety Properties

    PropertyProperty FormulaP1Tail reachable from Headq:nbq,vt. rv[Tail](q,vt) vh. rv[Head](q,vh) rv[next]*(vh, vt)P2Insert after lastq:nbq,ti:thread,vi,vt. at[e_18](ti) rv[node](ti,vi) rv[tail](ti,vt) rv[this](ti,q) rv[next](vt,vi) rv[Tail](q,vi)P3Delete firstq:nbq,td:thread,vd,vh. at[d_19](td) rv[head](td,vd) rv[this](td,q) rv[Head](q,vh) rv[next](vd,vh)P4Head firstq:nbq,v,u. rv[Head](q,v) rv[next](u,v)P5Tail existsq:nbq. v. rv[Tail](q,v)

  • Tail Reachable from Headat[e_2]at[e_2]zerosuccsuccsuccrv[node]rv[node]rv[this]rv[this]rv[Head]rv[next]rv[next]rv[next]rv[Tail]iv[Tail]iv[Head]iv[next]iv[next]iv[next]VhVtq:nbq,vt. rv[Tail](q,vt) vh. rv[Head](q,vh) rv[next]*(vh, vt)rv[value]rv[value]

  • Abstract Program ModelConservative representation of the concrete modelUse 3-valued logical structures to conservatively represent multiple 2-valued structures1 = true0 = false1/2 = unknownA join semi-lattice, 0 1 = 1/2Conservatively apply actions on abstract configurations

  • Concrete Configurationat[e_2]at[e_2]zerosuccsuccsuccrv[node]rv[node]rv[this]rv[this]rv[Head]rv[next]rv[next]rv[next]rv[Tail]iv[Tail]iv[Head]iv[next]iv[next]iv[next]rv[value]rv[value]

  • Abstract Configurationzerosuccrv[Head]iv[Tail]iv[Head]at[e_2]rv[this]iv[next]rv[node]rv[this]rv[next]succrv[Tail]rv[value]

  • canonical AbstractionMerge all nodes with the same unary predicate values into a single summary node Join predicate valuesConverts a configuration of infinite size into a 3-valued abstract configuration of bounded size

  • Concrete Bad Configurationat[e_2]at[e_2]zerosuccsuccsuccrv[node]rv[node]rv[this]rv[this]rv[Head]rv[next]rv[next]rv[Tail]iv[Tail]iv[Head]iv[next]iv[next]q:nbq,vt. rv[Tail](q,vt) vh. rv[Head](q,vh) rv[next]*(vh, vt)rv[value]rv[value]

  • Abstract Configurationat[e_2]zerosuccrv[Head]iv[Tail]iv[Head]at[e_2]rv[this]iv[next]rv[this]rv[next]succrv[Tail]q:nbq,vt. rv[Tail](q,vt) vh. rv[Head](q,vh) rv[next]*(vh, vt)rv[node]rv[value]

  • InstrumentationRefine the abstraction by recording additional informationNatural idea record which property-formulae hold via nullary predicatesCorresponds to predicate abstractionMore generally record subformulae that hold for an individual via unary predicatesObtain (some) useful results without changing set of predicates per program/property

  • Instrumentation Predicates

  • Instrumented Concrete Configurationr_by[node]rt[node,n]is[this]r_by[this]rt[this,n]r_by[node]rt[node,n]r_by[head]rt[head,n]r_by[next]rt[Head,n]r_by[next]rt[Head,n]r_by[next]r_by[Tail]rt[Head,n]rt[Tail,n]at[e_2]at[e_2]zeroi_by[]succsuccsuccrv[node]rv[node]rv[this]rv[this]rv[Head]rv[next]rv[next]rv[next]rv[Tail]iv[Tail]iv[Head]iv[next]iv[next]iv[next]r_by[value]rt[value,n]r_by[value]rt[value,n]rv[value]rv[value]

  • Instrumented Abstract Configurationr_by[node]rt[node,n]is[this]r_by[this]rt[this,n]r_by[Head]rt[Head,n]r_by[next]rt[Head,n]r_by[next]r_by[Tail]rt[Head,n]rt[Tail,n]at[e_2]rv[node]rv[this]rv[Head]rv[next]rv[next]rv[Tail]iv[Tail]iv[Head]iv[next]iv[next]rv[next]succsucczeroi_by[]q:nbq,vt. rv[Tail](q,vt) vh. rv[Head](q,vh) rv[next]*(vh, vt)q:nbq,v. rv[Tail](q,v) rt[Head,n](v)r_by[value]rt[value,n]rv[value]

  • InstrumentationBad newsCurrently instrumentation predicates are not automatically derivedSome experience in deriving predicates [PLDI02]No refinement yetGood newsUnary instrumentation predicates more powerful than nullary (predicate abstraction)Standard instrumentation predicates work for wide range of programs (e.g., apprentice challenge)Update formulae for instrumentation predicates are automatically derived via finite differencing [ESOP03]Encouraging results with derived formulae

  • Best Conservative InterpretationConcrete RepresentationConcrete Representation

  • Abstract Interpretation - Concretizationr_by[node]rt[node,n]is[this]r_by[this]rt[this,n]r_by[Head]rt[Head,n]r_by[next]rt[Head,n]r_by[next]r_by[Tail]rt[Head,n]rt[Tail,n]at[e_2]rv[node]rv[this]rv[Head]rv[next]rv[next]rv[Tail]iv[Tail]iv[Head]iv[next]iv[next]rv[next]succsucczeroi_by[]r_by[value]rt[value,n]rv[value]e_2 node.val = value

  • Abstract Interpretation - Concretizationr_by[node]rt[node,n]at[e_2]rv[node]r_by[value]rt[value,n]rv[value]e_2 node.val = value

  • Abstract Interpretation - updater_by[node]rt[node,n]exists[val]at[e_3]rv[node]r_by[value]rt[value,n]r_by[val]rt[val,n]rv[value]rv[val]rv[value]rv[value]e_2 node.val = value

  • Abstract Interpretation - abstractionr_by[node]rt[node,n]at[e_2]rv[node]r_by[value]rt[value,n]rv[value]at[e_3]rv[value]rv[val]rv[node]r_by[value]rt[value,n]r_by[val]rt[val,n]r_by[node]rt[node,n]exists[val]at[e_3]rv[value]rv[val]rv[node]r_by[value]rt[value,n]r_by[val]rt[val,n]r_by[node]rt[node,n]exists[val]r_by[node]rt[node,n]at[e_2]rv[node]r_by[value]rt[value,n]rv[value]at[e_3]rv[value]rv[val]rv[node]r_by[value]rt[value,n]r_by[val]rt[val,n]r_by[node]rt[node,n]exists[val]

  • Prototype ImplementationTVLA/3VMCfocuscoerceLimitationsonly intraproceduralno optimizations usedNo partial-order reduction

  • Experimental Results

    ProgramConfigsSpace (MB)Time (Sec)Nbq_enqueue183314.2727Nbq_dequeue10985.3309Nbq_err1360.111Nbq_uni170.13Tlq_enqueue982106162Tlq_dequeue2254.1304Twolockqn9757.5577Twolockq_err1240.130

  • ConclusionsCommon challenges of model checking and abstract interpretationFalse alarmsCostScalabilitySizeLanguage features

  • Conclusions

    Sheet1

    Traditional MCOur Approach

    concrete configurationpropositionalFOTC

    abstractionmodel extraction*abstract interpretation

    control flowinternally representedinternally represented

    materialization?basic feature

    object numbera priori boundedunbounded

    thread numberfixed or a prio