1*1c27b644SPaul E. McKenney// SPDX-License-Identifier: GPL-2.0+ 2*1c27b644SPaul E. McKenney(* 3*1c27b644SPaul E. McKenney * Copyright (C) 2016 Luc Maranget <luc.maranget@inria.fr> for Inria 4*1c27b644SPaul E. McKenney * Copyright (C) 2017 Alan Stern <stern@rowland.harvard.edu> 5*1c27b644SPaul E. McKenney *) 6*1c27b644SPaul E. McKenney 7*1c27b644SPaul E. McKenney(* Generate coherence orders and handle lock operations *) 8*1c27b644SPaul E. McKenney 9*1c27b644SPaul E. McKenneyinclude "cross.cat" 10*1c27b644SPaul E. McKenney 11*1c27b644SPaul E. McKenney(* From lock reads to their partner lock writes *) 12*1c27b644SPaul E. McKenneylet lk-rmw = ([LKR] ; po-loc ; [LKW]) \ (po ; po) 13*1c27b644SPaul E. McKenneylet rmw = rmw | lk-rmw 14*1c27b644SPaul E. McKenney 15*1c27b644SPaul E. McKenney(* 16*1c27b644SPaul E. McKenney * A paired LKR must always see an unlocked value; spin_lock() calls nested 17*1c27b644SPaul E. McKenney * inside a critical section (for the same lock) always deadlock. 18*1c27b644SPaul E. McKenney *) 19*1c27b644SPaul E. McKenneyempty ([LKW] ; po-loc ; [domain(lk-rmw)]) \ (po-loc ; [UL] ; po-loc) 20*1c27b644SPaul E. McKenney as lock-nest 21*1c27b644SPaul E. McKenney 22*1c27b644SPaul E. McKenney(* The litmus test is invalid if an LKW event is not part of an RMW pair *) 23*1c27b644SPaul E. McKenneyflag ~empty LKW \ range(lk-rmw) as unpaired-LKW 24*1c27b644SPaul E. McKenney 25*1c27b644SPaul E. McKenney(* This will be allowed if we implement spin_is_locked() *) 26*1c27b644SPaul E. McKenneyflag ~empty LKR \ domain(lk-rmw) as unpaired-LKR 27*1c27b644SPaul E. McKenney 28*1c27b644SPaul E. McKenney(* There should be no R or W accesses to spinlocks *) 29*1c27b644SPaul E. McKenneylet ALL-LOCKS = LKR | LKW | UL | LF 30*1c27b644SPaul E. McKenneyflag ~empty [M \ IW] ; loc ; [ALL-LOCKS] as mixed-lock-accesses 31*1c27b644SPaul E. McKenney 32*1c27b644SPaul E. McKenney(* The final value of a spinlock should not be tested *) 33*1c27b644SPaul E. McKenneyflag ~empty [FW] ; loc ; [ALL-LOCKS] as lock-final 34*1c27b644SPaul E. McKenney 35*1c27b644SPaul E. McKenney 36*1c27b644SPaul E. McKenney(* 37*1c27b644SPaul E. McKenney * Put lock operations in their appropriate classes, but leave UL out of W 38*1c27b644SPaul E. McKenney * until after the co relation has been generated. 39*1c27b644SPaul E. McKenney *) 40*1c27b644SPaul E. McKenneylet R = R | LKR | LF 41*1c27b644SPaul E. McKenneylet W = W | LKW 42*1c27b644SPaul E. McKenney 43*1c27b644SPaul E. McKenneylet Release = Release | UL 44*1c27b644SPaul E. McKenneylet Acquire = Acquire | LKR 45*1c27b644SPaul E. McKenney 46*1c27b644SPaul E. McKenney 47*1c27b644SPaul E. McKenney(* Match LKW events to their corresponding UL events *) 48*1c27b644SPaul E. McKenneylet critical = ([LKW] ; po-loc ; [UL]) \ (po-loc ; [LKW | UL] ; po-loc) 49*1c27b644SPaul E. McKenney 50*1c27b644SPaul E. McKenneyflag ~empty UL \ range(critical) as unmatched-unlock 51*1c27b644SPaul E. McKenney 52*1c27b644SPaul E. McKenney(* Allow up to one unmatched LKW per location; more must deadlock *) 53*1c27b644SPaul E. McKenneylet UNMATCHED-LKW = LKW \ domain(critical) 54*1c27b644SPaul E. McKenneyempty ([UNMATCHED-LKW] ; loc ; [UNMATCHED-LKW]) \ id as unmatched-locks 55*1c27b644SPaul E. McKenney 56*1c27b644SPaul E. McKenney 57*1c27b644SPaul E. McKenney(* rfi for LF events: link each LKW to the LF events in its critical section *) 58*1c27b644SPaul E. McKenneylet rfi-lf = ([LKW] ; po-loc ; [LF]) \ ([LKW] ; po-loc ; [UL] ; po-loc) 59*1c27b644SPaul E. McKenney 60*1c27b644SPaul E. McKenney(* rfe for LF events *) 61*1c27b644SPaul E. McKenneylet all-possible-rfe-lf = 62*1c27b644SPaul E. McKenney (* 63*1c27b644SPaul E. McKenney * Given an LF event r, compute the possible rfe edges for that event 64*1c27b644SPaul E. McKenney * (all those starting from LKW events in other threads), 65*1c27b644SPaul E. McKenney * and then convert that relation to a set of single-edge relations. 66*1c27b644SPaul E. McKenney *) 67*1c27b644SPaul E. McKenney let possible-rfe-lf r = 68*1c27b644SPaul E. McKenney let pair-to-relation p = p ++ 0 69*1c27b644SPaul E. McKenney in map pair-to-relation ((LKW * {r}) & loc & ext) 70*1c27b644SPaul E. McKenney (* Do this for each LF event r that isn't in rfi-lf *) 71*1c27b644SPaul E. McKenney in map possible-rfe-lf (LF \ range(rfi-lf)) 72*1c27b644SPaul E. McKenney 73*1c27b644SPaul E. McKenney(* Generate all rf relations for LF events *) 74*1c27b644SPaul E. McKenneywith rfe-lf from cross(all-possible-rfe-lf) 75*1c27b644SPaul E. McKenneylet rf = rf | rfi-lf | rfe-lf 76*1c27b644SPaul E. McKenney 77*1c27b644SPaul E. McKenney 78*1c27b644SPaul E. McKenney(* Generate all co relations, including LKW events but not UL *) 79*1c27b644SPaul E. McKenneylet co0 = co0 | ([IW] ; loc ; [LKW]) | 80*1c27b644SPaul E. McKenney (([LKW] ; loc ; [UNMATCHED-LKW]) \ [UNMATCHED-LKW]) 81*1c27b644SPaul E. McKenneyinclude "cos-opt.cat" 82*1c27b644SPaul E. McKenneylet W = W | UL 83*1c27b644SPaul E. McKenneylet M = R | W 84*1c27b644SPaul E. McKenney 85*1c27b644SPaul E. McKenney(* Merge UL events into co *) 86*1c27b644SPaul E. McKenneylet co = (co | critical | (critical^-1 ; co))+ 87*1c27b644SPaul E. McKenneylet coe = co & ext 88*1c27b644SPaul E. McKenneylet coi = co & int 89*1c27b644SPaul E. McKenney 90*1c27b644SPaul E. McKenney(* Merge LKR events into rf *) 91*1c27b644SPaul E. McKenneylet rf = rf | ([IW | UL] ; singlestep(co) ; lk-rmw^-1) 92*1c27b644SPaul E. McKenneylet rfe = rf & ext 93*1c27b644SPaul E. McKenneylet rfi = rf & int 94*1c27b644SPaul E. McKenney 95*1c27b644SPaul E. McKenneylet fr = rf^-1 ; co 96*1c27b644SPaul E. McKenneylet fre = fr & ext 97*1c27b644SPaul E. McKenneylet fri = fr & int 98*1c27b644SPaul E. McKenney 99*1c27b644SPaul E. McKenneyshow co,rf,fr 100