lock.cat 2.9 KB

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