File: fault.ml

package info (click to toggle)
herdtools7 7.58-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 19,732 kB
  • sloc: ml: 128,583; ansic: 3,827; makefile: 670; python: 407; sh: 212; awk: 14
file content (216 lines) | stat: -rw-r--r-- 6,380 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
(****************************************************************************)
(*                           the diy toolsuite                              *)
(*                                                                          *)
(* Jade Alglave, University College London, UK.                             *)
(* Luc Maranget, INRIA Paris-Rocquencourt, France.                          *)
(*                                                                          *)
(* Copyright 2019-present Institut National de Recherche en Informatique et *)
(* en Automatique, ARM Ltd and the authors. All rights reserved.            *)
(*                                                                          *)
(* This software is governed by the CeCILL-B license under French law and   *)
(* abiding by the rules of distribution of free software. You can use,      *)
(* modify and/ or redistribute the software under the terms of the CeCILL-B *)
(* license as circulated by CEA, CNRS and INRIA at the following URL        *)
(* "http://www.cecill.info". We also give a copy in LICENSE.txt.            *)
(****************************************************************************)

(** External view of faults, which are part of final state *)
open Printf

module type I = sig
  type arch_global
  val pp_global : arch_global -> string
  val global_compare : arch_global -> arch_global -> int
  val same_id_fault : arch_global -> arch_global -> bool

  type fault_type
  val pp_fault_type : fault_type -> string
  val fault_type_compare : fault_type -> fault_type -> int
end

type ('loc, 'ftype) atom =
  (Proc.t * Label.t option) * 'loc option * 'ftype option

let pp_gen f pp_lbl pp_loc pp_ft (lbl,x,ft) =
  let x = Misc.pp_opt_arg pp_loc x
  and ft = Misc.pp_opt_arg pp_ft ft in
  sprintf "%s(%s%s%s)" f (pp_lbl lbl) x ft

let pp_fatom pp_loc =
  pp_gen "fault"
    (fun (p,lbl) -> match lbl with
    | None -> Proc.pp p
    | Some lbl -> sprintf "%s:%s" (Proc.pp p) (Label.pp lbl))
    pp_loc

let atom_compare v_compare ft_compare ((p1,lbl1),v1,ft1) ((p2,lbl2),v2,ft2) = match Proc.compare p1 p2 with
| 0 ->
    begin match Misc.opt_compare String.compare lbl1 lbl2 with
    | 0 ->
       begin match Misc.opt_compare v_compare v1 v2 with
       | 0 -> Misc.opt_compare ft_compare ft1 ft2
       | r -> r
       end
    | r -> r
    end
| r -> r

let map_value f (p,v,ft) = (p,Misc.map_opt f v,ft)

module type S = sig

  type loc_global
  type fault_type

  type fault =
    (Proc.t * Label.Set.t) * loc_global option *
    fault_type option * string option

  val pp_fault : fault -> string
  module FaultSet : MySet.S with type elt = fault

  type fatom = (loc_global,fault_type) atom

  val pp_fatom : fatom -> string
  val check_one_fatom : fault -> fatom -> bool
  val check_fatom : FaultSet.t -> fatom -> bool
  module FaultAtomSet : MySet.S with type elt = fatom
end

module Make(A:I) =
  struct

    type loc_global = A.arch_global
    type fault_type = A.fault_type
    type fault =
      (Proc.t * Label.Set.t) * loc_global option
      * fault_type option * string option

    let pp_lbl (p,lbl) = match Label.Set.as_small 1 lbl with
    | Some [] ->  Proc.pp p
    | Some [lbl] -> sprintf "%s:%s" (Proc.pp p) (Label.pp lbl)
    | _ ->
        sprintf "%s:{%s}" (Proc.pp p)
          (Label.Set.pp_str "," Label.pp lbl)


    let pp_fault (lbl,x,ftype,msg) =
      let x = Misc.pp_opt_arg A.pp_global x
      and ftype = Misc.pp_opt_arg A.pp_fault_type ftype
      and msg = Misc.pp_opt_arg Misc.identity msg in
      sprintf "Fault(%s%s%s%s)" (pp_lbl lbl) x ftype msg

    let compare_lbl (p1,lbl1) (p2,lbl2) = match Proc.compare p1 p2 with
    | 0 -> Label.Set.compare lbl1 lbl2
    | r -> r

    let compare (lbl1,x1,ftype1,msg1) (lbl2,x2,ftype2,msg2) =
      match compare_lbl lbl1 lbl2 with
      | 0 ->
         begin match Misc.opt_compare A.global_compare x1 x2 with
         | 0 ->
            begin match Misc.opt_compare A.fault_type_compare ftype1 ftype2 with
            | 0 -> Misc.opt_compare String.compare msg1 msg2
            | r -> r
            end
         | r -> r
         end
      | r -> r

    module FaultSet =
      MySet.Make
        (struct
          type t = fault
          let compare = compare
        end)

    type fatom = (loc_global,fault_type) atom

    let pp_fatom = pp_fatom A.pp_global A.pp_fault_type

    let check_one_fatom ((p0,lbls0),x0,ftype0,_)  ((p,lblo),x,ftype) =
      Proc.compare p p0 = 0 &&
      begin match lblo with
      | None -> true
      | Some lbl -> Label.Set.mem lbl lbls0
      end &&
      begin match ftype0, ftype with
      | _, None -> true
      | Some ft0, Some ft when ft0 = ft -> true
      | _, _ -> false
      end &&
      begin match x0,x with
      | _,None -> true
      | Some x0, Some x ->  A.same_id_fault x x0
      | None,_ -> false (* or assert false ? *)
      end

    let check_fatom flts a =
      FaultSet.exists
        (fun flt -> check_one_fatom flt a)
        flts

    module FaultAtomSet =
      MySet.Make
        (struct
          type t = fatom
          let compare ((p0,lbl0),x0,ft0)  ((p1,lbl1),x1,ft1) =
            match Proc.compare p0 p1 with
            | 0 ->
                begin match Misc.opt_compare Label.compare lbl0 lbl1 with
                | 0 ->
                   begin
                     match Misc.opt_compare A.global_compare x0 x1 with
                     | 0 -> Misc.opt_compare A.fault_type_compare ft0 ft1
                     | r -> r
                   end
                | r -> r
                end
            | r -> r
        end)
  end

module Handling : sig
  type t =
    | Handled
    | Fatal
    | Skip

  val default : t
  val tags : string list
  val parse : string -> t option
  val pp : t -> string

  val is_fatal : t -> bool
  val is_skip : t -> bool
end
=
struct
  type t =
    | Handled
    | Fatal
    | Skip

  let default = Fatal

  let tags =  ["handled"; "fatal"; "faultToNext"; ]

  let parse = function
    | "imprecise"|"handled" -> Some Handled
    | "precise"|"fatal" -> Some Fatal
    | "faulttonext"|"skip" -> Some Skip
    | _ -> None

  let pp = function
    | Handled -> "handled"
    | Fatal -> "fatal"
    | Skip -> "faulToNext"

  let is_fatal = function
    | Fatal -> true
    | Handled | Skip -> false

  let is_skip = function
    | Skip -> true
    | Fatal | Handled -> false
end