1 // SPDX-License-Identifier: GPL-2.0+ 1 // SPDX-License-Identifier: GPL-2.0+ 2 (* 2 (* 3 * Copyright (C) 2016 Luc Maranget <luc.marange 3 * Copyright (C) 2016 Luc Maranget <luc.maranget@inria.fr> for Inria 4 * Copyright (C) 2017 Alan Stern <stern@rowland 4 * Copyright (C) 2017 Alan Stern <stern@rowland.harvard.edu> 5 *) 5 *) 6 6 7 (* 7 (* 8 * Generate coherence orders and handle lock o 8 * Generate coherence orders and handle lock operations 9 *) 9 *) 10 10 11 include "cross.cat" 11 include "cross.cat" 12 12 13 (* 13 (* 14 * The lock-related events generated by herd7 !! 14 * The lock-related events generated by herd are as follows: 15 * 15 * 16 * LKR Lock-Read: the read part of a 16 * LKR Lock-Read: the read part of a spin_lock() or successful 17 * spin_trylock() read-mo 17 * spin_trylock() read-modify-write event pair 18 * LKW Lock-Write: the write part of 18 * LKW Lock-Write: the write part of a spin_lock() or successful 19 * spin_trylock() RMW eve 19 * spin_trylock() RMW event pair 20 * UL Unlock: a spin_unlock() event 20 * UL Unlock: a spin_unlock() event 21 * LF Lock-Fail: a failed spin_trylo 21 * LF Lock-Fail: a failed spin_trylock() event 22 * RL Read-Locked: a spin_is_locked( 22 * RL Read-Locked: a spin_is_locked() event which returns True 23 * RU Read-Unlocked: a spin_is_locke 23 * RU Read-Unlocked: a spin_is_locked() event which returns False 24 * 24 * 25 * LKR and LKW events always come paired, like 25 * LKR and LKW events always come paired, like all RMW event sequences. 26 * 26 * 27 * LKR, LF, RL, and RU are read events; LKR ha 27 * LKR, LF, RL, and RU are read events; LKR has Acquire ordering. 28 * LKW and UL are write events; UL has Release 28 * LKW and UL are write events; UL has Release ordering. 29 * LKW, LF, RL, and RU have no ordering proper 29 * LKW, LF, RL, and RU have no ordering properties. 30 *) 30 *) 31 31 32 (* Backward compatibility *) 32 (* Backward compatibility *) 33 let RL = try RL with emptyset 33 let RL = try RL with emptyset 34 let RU = try RU with emptyset 34 let RU = try RU with emptyset 35 35 36 (* Treat RL as a kind of LF: a read with no or 36 (* Treat RL as a kind of LF: a read with no ordering properties *) 37 let LF = LF | RL 37 let LF = LF | RL 38 38 39 (* There should be no ordinary R or W accesses !! 39 (* There should be no ordinary R or W accesses to spinlocks *) 40 let ALL-LOCKS = LKR | LKW | UL | LF | RU | Src !! 40 let ALL-LOCKS = LKR | LKW | UL | LF | RU 41 flag ~empty [M \ IW \ ALL-LOCKS] ; loc ; [ALL- !! 41 flag ~empty [M \ IW] ; loc ; [ALL-LOCKS] as mixed-lock-accesses 42 42 43 (* Link Lock-Reads to their RMW-partner Lock-W 43 (* Link Lock-Reads to their RMW-partner Lock-Writes *) 44 let lk-rmw = ([LKR] ; po-loc ; [LKW]) \ (po ; 44 let lk-rmw = ([LKR] ; po-loc ; [LKW]) \ (po ; po) 45 let rmw = rmw | lk-rmw 45 let rmw = rmw | lk-rmw 46 46 47 (* The litmus test is invalid if an LKR/LKW ev 47 (* The litmus test is invalid if an LKR/LKW event is not part of an RMW pair *) 48 flag ~empty LKW \ range(lk-rmw) as unpaired-LK 48 flag ~empty LKW \ range(lk-rmw) as unpaired-LKW 49 flag ~empty LKR \ domain(lk-rmw) as unpaired-L 49 flag ~empty LKR \ domain(lk-rmw) as unpaired-LKR 50 50 51 (* 51 (* 52 * An LKR must always see an unlocked value; s 52 * An LKR must always see an unlocked value; spin_lock() calls nested 53 * inside a critical section (for the same loc 53 * inside a critical section (for the same lock) always deadlock. 54 *) 54 *) 55 empty ([LKW] ; po-loc ; [LKR]) \ (po-loc ; [UL 55 empty ([LKW] ; po-loc ; [LKR]) \ (po-loc ; [UL] ; po-loc) as lock-nest 56 56 57 (* << 58 * In the same way, spin_is_locked() inside a << 59 * return True (no RU events can be in a criti << 60 *) << 61 empty ([LKW] ; po-loc ; [RU]) \ (po-loc ; [UL] << 62 << 63 (* The final value of a spinlock should not be 57 (* The final value of a spinlock should not be tested *) 64 flag ~empty [FW] ; loc ; [ALL-LOCKS] as lock-f 58 flag ~empty [FW] ; loc ; [ALL-LOCKS] as lock-final 65 59 66 (* 60 (* 67 * Put lock operations in their appropriate cl 61 * Put lock operations in their appropriate classes, but leave UL out of W 68 * until after the co relation has been genera 62 * until after the co relation has been generated. 69 *) 63 *) 70 let R = R | LKR | LF | RU 64 let R = R | LKR | LF | RU 71 let W = W | LKW 65 let W = W | LKW 72 66 73 let Release = Release | UL 67 let Release = Release | UL 74 let Acquire = Acquire | LKR 68 let Acquire = Acquire | LKR 75 69 76 (* Match LKW events to their corresponding UL 70 (* Match LKW events to their corresponding UL events *) 77 let critical = ([LKW] ; po-loc ; [UL]) \ (po-l 71 let critical = ([LKW] ; po-loc ; [UL]) \ (po-loc ; [LKW | UL] ; po-loc) 78 72 79 flag ~empty UL \ range(critical) as unmatched- 73 flag ~empty UL \ range(critical) as unmatched-unlock 80 74 81 (* Allow up to one unmatched LKW per location; 75 (* Allow up to one unmatched LKW per location; more must deadlock *) 82 let UNMATCHED-LKW = LKW \ domain(critical) 76 let UNMATCHED-LKW = LKW \ domain(critical) 83 empty ([UNMATCHED-LKW] ; loc ; [UNMATCHED-LKW] 77 empty ([UNMATCHED-LKW] ; loc ; [UNMATCHED-LKW]) \ id as unmatched-locks 84 78 85 (* rfi for LF events: link each LKW to the LF 79 (* rfi for LF events: link each LKW to the LF events in its critical section *) 86 let rfi-lf = ([LKW] ; po-loc ; [LF]) \ ([LKW] 80 let rfi-lf = ([LKW] ; po-loc ; [LF]) \ ([LKW] ; po-loc ; [UL] ; po-loc) 87 81 88 (* Utility macro to convert a single pair to a !! 82 (* rfe for LF events *) 89 let pair-to-relation p = p ++ 0 << 90 << 91 (* << 92 * If a given LF event e is outside a critical << 93 * internally but it may read from an LKW even << 94 * Compute the relation containing these possi << 95 *) << 96 let possible-rfe-noncrit-lf e = (LKW * {e}) & << 97 << 98 (* Compute set of sets of possible rfe edges f << 99 let all-possible-rfe-lf = 83 let all-possible-rfe-lf = 100 (* 84 (* 101 * Convert the possible-rfe-noncrit-lf !! 85 * Given an LF event r, compute the possible rfe edges for that event 102 * to a set of single edges !! 86 * (all those starting from LKW events in other threads), >> 87 * and then convert that relation to a set of single-edge relations. 103 *) 88 *) 104 let set-of-singleton-rfe-lf e = !! 89 let possible-rfe-lf r = 105 map pair-to-relation ( !! 90 let pair-to-relation p = p ++ 0 106 (* Do this for each LF event e that is !! 91 in map pair-to-relation ((LKW * {r}) & loc & ext) 107 in map set-of-singleton-rfe-lf (LF \ r !! 92 (* Do this for each LF event r that isn't in rfi-lf *) >> 93 in map possible-rfe-lf (LF \ range(rfi-lf)) 108 94 109 (* Generate all rf relations for LF events *) 95 (* Generate all rf relations for LF events *) 110 with rfe-lf from cross(all-possible-rfe-lf) 96 with rfe-lf from cross(all-possible-rfe-lf) 111 let rf-lf = rfe-lf | rfi-lf 97 let rf-lf = rfe-lf | rfi-lf 112 98 113 (* 99 (* 114 * A given RU event e may read internally from !! 100 * RU, i.e., spin_is_locked() returning False, is slightly different. 115 * or it may read from a UL event in another t !! 101 * We rely on the memory model to rule out cases where spin_is_locked() 116 * Compute the relation containing these possi !! 102 * within one of the lock's critical sections returns False. 117 *) 103 *) 118 let possible-rf-ru e = (((UL * {e}) & po-loc) !! 104 119 ([UL] ; po-loc ; [UL] !! 105 (* rfi for RU events: an RU may read from the last po-previous UL *) 120 (((UL | IW) * {e}) & loc & ext !! 106 let rfi-ru = ([UL] ; po-loc ; [RU]) \ ([UL] ; po-loc ; [LKW] ; po-loc) 121 !! 107 122 (* Compute set of sets of possible rf edges fo !! 108 (* rfe for RU events: an RU may read from an external UL or the initial write *) 123 let all-possible-rf-ru = !! 109 let all-possible-rfe-ru = 124 (* Convert the possible-rf-ru relation !! 110 let possible-rfe-ru r = 125 let set-of-singleton-rf-ru e = !! 111 let pair-to-relation p = p ++ 0 126 map pair-to-relation (possible !! 112 in map pair-to-relation (((UL | IW) * {r}) & loc & ext) 127 (* Do this for each RU event e *) !! 113 in map possible-rfe-ru RU 128 in map set-of-singleton-rf-ru RU << 129 114 130 (* Generate all rf relations for RU events *) 115 (* Generate all rf relations for RU events *) 131 with rf-ru from cross(all-possible-rf-ru) !! 116 with rfe-ru from cross(all-possible-rfe-ru) >> 117 let rf-ru = rfe-ru | rfi-ru 132 118 133 (* Final rf relation *) 119 (* Final rf relation *) 134 let rf = rf | rf-lf | rf-ru 120 let rf = rf | rf-lf | rf-ru 135 121 136 (* Generate all co relations, including LKW ev 122 (* Generate all co relations, including LKW events but not UL *) 137 let co0 = co0 | ([IW] ; loc ; [LKW]) | 123 let co0 = co0 | ([IW] ; loc ; [LKW]) | 138 (([LKW] ; loc ; [UNMATCHED-LKW]) \ [UN 124 (([LKW] ; loc ; [UNMATCHED-LKW]) \ [UNMATCHED-LKW]) 139 include "cos-opt.cat" 125 include "cos-opt.cat" 140 let W = W | UL 126 let W = W | UL 141 let M = R | W 127 let M = R | W 142 128 143 (* Merge UL events into co *) 129 (* Merge UL events into co *) 144 let co = (co | critical | (critical^-1 ; co))+ 130 let co = (co | critical | (critical^-1 ; co))+ 145 let coe = co & ext 131 let coe = co & ext 146 let coi = co & int 132 let coi = co & int 147 133 148 (* Merge LKR events into rf *) 134 (* Merge LKR events into rf *) 149 let rf = rf | ([IW | UL] ; singlestep(co) ; lk 135 let rf = rf | ([IW | UL] ; singlestep(co) ; lk-rmw^-1) 150 let rfe = rf & ext 136 let rfe = rf & ext 151 let rfi = rf & int 137 let rfi = rf & int 152 138 153 let fr = rf^-1 ; co 139 let fr = rf^-1 ; co 154 let fre = fr & ext 140 let fre = fr & ext 155 let fri = fr & int 141 let fri = fr & int 156 142 157 show co,rf,fr 143 show co,rf,fr
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.