@@ -761,11 +761,15 @@ module type ClusterArg = functor (RD: RelationDomain.RD) ->
761
761
sig
762
762
module LRD : Lattice .S
763
763
764
+ module Cluster : Printable .S
765
+
764
766
val keep_only_protected_globals : Q .ask -> LockDomain.MustLock .t -> LRD .t -> LRD .t
765
767
val keep_global : varinfo -> LRD .t -> LRD .t
766
768
767
769
val lock : RD .t -> LRD .t -> LRD .t -> RD .t
768
- val unlock : W .t -> RD .t -> LRD .t
770
+ val unlock : W .t -> RD .t -> LRD .t * (Cluster .t list )
771
+
772
+ val filter_clusters : (Cluster .t -> bool ) -> LRD .t -> LRD .t
769
773
770
774
val name : unit -> string
771
775
end
@@ -775,6 +779,7 @@ module NoCluster:ClusterArg = functor (RD: RelationDomain.RD) ->
775
779
struct
776
780
open CommonPerMutex (RD)
777
781
module LRD = RD
782
+ module Cluster = Printable. Unit
778
783
779
784
let keep_only_protected_globals = keep_only_protected_globals
780
785
@@ -786,7 +791,13 @@ struct
786
791
RD. meet oct (RD. join local_m get_m)
787
792
788
793
let unlock w oct_side =
789
- oct_side
794
+ oct_side, [() ]
795
+
796
+ let filter_clusters f oct =
797
+ if f () then
798
+ oct
799
+ else
800
+ RD. bot ()
790
801
791
802
let name () = " no-clusters"
792
803
end
@@ -860,6 +871,8 @@ struct
860
871
module VS = SetDomain. Make (CilType. Varinfo )
861
872
module LRD = MapDomain. MapBot (VS ) (RD )
862
873
874
+ module Cluster = VS
875
+
863
876
let keep_only_protected_globals ask m octs =
864
877
(* normal (strong) mapping: contains only still fully protected *)
865
878
(* must filter by protection to avoid later meeting with non-protecting *)
@@ -909,7 +922,10 @@ struct
909
922
let oct_side_cluster gs =
910
923
RD. keep_vars oct_side (gs |> VS. elements |> List. map V. global)
911
924
in
912
- LRD. add_list_fun clusters oct_side_cluster (LRD. empty () )
925
+ (LRD. add_list_fun clusters oct_side_cluster (LRD. empty () ), clusters)
926
+
927
+ let filter_clusters f oct =
928
+ LRD. filter (fun gs _ -> f gs) oct
913
929
914
930
let name = ClusteringArg. name
915
931
end
@@ -925,6 +941,8 @@ struct
925
941
module LRD1 = DCCluster. LRD
926
942
module LRD = Lattice. Prod (LRD1 ) (LRD1 ) (* second component is only used between keep_* and lock for additional weak mapping *)
927
943
944
+ module Cluster = DCCluster. Cluster
945
+
928
946
let name = ClusteringArg. name
929
947
930
948
let filter_map' f m =
@@ -986,7 +1004,11 @@ struct
986
1004
r
987
1005
988
1006
let unlock w oct_side =
989
- (DCCluster. unlock w oct_side, LRD1. bot () )
1007
+ let lad, clusters = DCCluster. unlock w oct_side in
1008
+ ((lad, LRD1. bot () ), clusters)
1009
+
1010
+ let filter_clusters f (lad ,lad' ) =
1011
+ (LRD1. filter (fun gs _ -> f gs) lad, LRD1. filter (fun gs _ -> f gs) lad')
990
1012
end
991
1013
992
1014
(* * Per-mutex meet with TIDs. *)
@@ -1000,7 +1022,7 @@ struct
1000
1022
module Cluster = NC
1001
1023
module LRD = NC. LRD
1002
1024
1003
- include PerMutexTidCommon (Digest ) (LRD )
1025
+ include PerMutexTidCommon (Digest ) (LRD ) ( NC. Cluster )
1004
1026
1005
1027
module AV = RD. V
1006
1028
module P = UnitP
@@ -1022,13 +1044,11 @@ struct
1022
1044
let get_m = get_relevant_writes ask m (G. mutex @@ getg (V. mutex m)) in
1023
1045
if M. tracing then M. traceli " relationpriv" " get_m_with_mutex_inits %a\n get=%a" LockDomain.MustLock. pretty m LRD. pretty get_m;
1024
1046
let r =
1025
- if not inits then
1026
- get_m
1027
- else
1028
- let get_mutex_inits = merge_all @@ G. mutex @@ getg V. mutex_inits in
1029
- let get_mutex_inits' = Cluster. keep_only_protected_globals ask m get_mutex_inits in
1030
- if M. tracing then M. trace " relationpriv" " inits=%a\n inits'=%a" LRD. pretty get_mutex_inits LRD. pretty get_mutex_inits';
1031
- LRD. join get_m get_mutex_inits'
1047
+ let get_mutex_inits = merge_all @@ G. mutex @@ getg V. mutex_inits in
1048
+ let get_mutex_inits' = Cluster. keep_only_protected_globals ask m get_mutex_inits in
1049
+ let get_mutex_inits' = Cluster. filter_clusters inits get_mutex_inits' in
1050
+ if M. tracing then M. trace " relationpriv" " inits=%a\n inits'=%a" LRD. pretty get_mutex_inits LRD. pretty get_mutex_inits';
1051
+ LRD. join get_m get_mutex_inits'
1032
1052
in
1033
1053
if M. tracing then M. traceu " relationpriv" " -> %a" LRD. pretty r;
1034
1054
r
@@ -1047,25 +1067,21 @@ struct
1047
1067
in
1048
1068
if M. tracing then M. traceli " relationpriv" " get_mutex_global_g_with_mutex_inits %a\n get=%a" CilType.Varinfo. pretty g LRD. pretty get_mutex_global_g;
1049
1069
let r =
1050
- if not inits then
1051
- get_mutex_global_g
1052
- else
1053
- let get_mutex_inits = merge_all @@ G. mutex @@ getg V. mutex_inits in
1054
- let get_mutex_inits' = Cluster. keep_global g get_mutex_inits in
1055
- if M. tracing then M. trace " relationpriv" " inits=%a\n inits'=%a" LRD. pretty get_mutex_inits LRD. pretty get_mutex_inits';
1056
- LRD. join get_mutex_global_g get_mutex_inits'
1070
+ let get_mutex_inits = merge_all @@ G. mutex @@ getg V. mutex_inits in
1071
+ let get_mutex_inits' = Cluster. keep_global g get_mutex_inits in
1072
+ let get_mutex_inits' = Cluster. filter_clusters inits get_mutex_inits' in
1073
+ if M. tracing then M. trace " relationpriv" " inits=%a\n inits'=%a" LRD. pretty get_mutex_inits LRD. pretty get_mutex_inits';
1074
+ LRD. join get_mutex_global_g get_mutex_inits'
1057
1075
in
1058
1076
if M. tracing then M. traceu " relationpriv" " -> %a" LRD. pretty r;
1059
1077
r
1060
1078
1061
1079
let get_mutex_global_g_with_mutex_inits_atomic inits ask getg =
1062
1080
(* Unprotected invariant is one big relation. *)
1063
1081
let get_mutex_global_g = get_relevant_writes_nofilter ask @@ G. mutex @@ getg (V. mutex atomic_mutex) in
1064
- if not inits then
1065
- get_mutex_global_g
1066
- else
1067
- let get_mutex_inits = merge_all @@ G. mutex @@ getg V. mutex_inits in
1068
- LRD. join get_mutex_global_g get_mutex_inits
1082
+ let get_mutex_inits = merge_all @@ G. mutex @@ getg V. mutex_inits in
1083
+ let get_mutex_inits' = Cluster. filter_clusters inits get_mutex_inits in
1084
+ LRD. join get_mutex_global_g get_mutex_inits'
1069
1085
1070
1086
let read_global (ask : Q.ask ) getg (st : relation_components_t ) g x : RD.t =
1071
1087
let atomic = Param. handle_atomic && ask.f MustBeAtomic in
@@ -1079,9 +1095,9 @@ struct
1079
1095
if atomic && RD. mem_var rel (AV. global g) then
1080
1096
rel (* Read previous unpublished unprotected write in current atomic section. *)
1081
1097
else if atomic then
1082
- Cluster. lock rel local_m (get_mutex_global_g_with_mutex_inits_atomic (not (LMust. mem lm lmust)) ask getg) (* Read unprotected invariant as full relation. *)
1098
+ Cluster. lock rel local_m (get_mutex_global_g_with_mutex_inits_atomic (fun c -> ( not (LMust. mem (lm,c) lmust) )) ask getg) (* Read unprotected invariant as full relation. *)
1083
1099
else
1084
- Cluster. lock rel local_m (get_mutex_global_g_with_mutex_inits (not (LMust. mem lm lmust)) ask getg g)
1100
+ Cluster. lock rel local_m (get_mutex_global_g_with_mutex_inits (fun c -> ( not (LMust. mem (lm,c) lmust) )) ask getg g)
1085
1101
in
1086
1102
(* read *)
1087
1103
let g_var = AV. global g in
@@ -1113,9 +1129,9 @@ struct
1113
1129
if atomic && RD. mem_var rel (AV. global g) then
1114
1130
rel (* Read previous unpublished unprotected write in current atomic section. *)
1115
1131
else if atomic then
1116
- Cluster. lock rel local_m (get_mutex_global_g_with_mutex_inits_atomic (not (LMust. mem lm lmust)) ask getg) (* Read unprotected invariant as full relation. *)
1132
+ Cluster. lock rel local_m (get_mutex_global_g_with_mutex_inits_atomic (fun c -> ( not (LMust. mem (lm,c) lmust) )) ask getg) (* Read unprotected invariant as full relation. *)
1117
1133
else
1118
- Cluster. lock rel local_m (get_mutex_global_g_with_mutex_inits (not (LMust. mem lm lmust)) ask getg g)
1134
+ Cluster. lock rel local_m (get_mutex_global_g_with_mutex_inits (fun c -> ( not (LMust. mem (lm,c) lmust) )) ask getg g)
1119
1135
in
1120
1136
(* write *)
1121
1137
let g_var = AV. global g in
@@ -1125,7 +1141,7 @@ struct
1125
1141
(* unlock *)
1126
1142
if not atomic then (
1127
1143
let rel_side = RD. keep_vars rel_local [g_var] in
1128
- let rel_side = Cluster. unlock (W. singleton g) rel_side in
1144
+ let rel_side, clusters = Cluster. unlock (W. singleton g) rel_side in
1129
1145
let digest = Digest. current ask in
1130
1146
let sidev = GMutex. singleton digest rel_side in
1131
1147
if Param. handle_atomic then
@@ -1139,7 +1155,8 @@ struct
1139
1155
else
1140
1156
rel_local
1141
1157
in
1142
- {rel = rel_local'; priv = (W. add g w,LMust. add lm lmust,l')}
1158
+ let lmust' = List. fold (fun a c -> LMust. add (lm,c) a) lmust clusters in
1159
+ {rel = rel_local'; priv = (W. add g w,lmust',l')}
1143
1160
)
1144
1161
else
1145
1162
(* Delay publishing unprotected write in the atomic section. *)
@@ -1151,7 +1168,7 @@ struct
1151
1168
let rel = st.rel in
1152
1169
let _,lmust,l = st.priv in
1153
1170
let lm = LLock. mutex m in
1154
- let get_m = get_m_with_mutex_inits (not (LMust. mem lm lmust)) ask getg m in
1171
+ let get_m = get_m_with_mutex_inits (fun c -> ( not (LMust. mem (lm,c) lmust) )) ask getg m in
1155
1172
let local_m = BatOption. default (LRD. bot () ) (L. find_opt lm l) in
1156
1173
(* Additionally filter get_m in case it contains variables it no longer protects. E.g. in 36/22. *)
1157
1174
let local_m = Cluster. keep_only_protected_globals ask m local_m in
@@ -1181,13 +1198,14 @@ struct
1181
1198
{rel = rel_local; priv = (w',lmust,l)}
1182
1199
else
1183
1200
let rel_side = keep_only_protected_globals ask m rel in
1184
- let rel_side = Cluster. unlock w rel_side in
1201
+ let rel_side, clusters = Cluster. unlock w rel_side in
1185
1202
let digest = Digest. current ask in
1186
1203
let sidev = GMutex. singleton digest rel_side in
1187
1204
sideg (V. mutex m) (G. create_mutex sidev);
1188
1205
let lm = LLock. mutex m in
1189
1206
let l' = L. add lm rel_side l in
1190
- {rel = rel_local; priv = (w',LMust. add lm lmust,l')}
1207
+ let lmust' = List. fold (fun a c -> LMust. add (lm,c) a) lmust clusters in
1208
+ {rel = rel_local; priv = (w',lmust',l')}
1191
1209
)
1192
1210
else (
1193
1211
(* Publish delayed unprotected write as if it were protected by the atomic section. *)
@@ -1198,14 +1216,15 @@ struct
1198
1216
{rel = rel_local; priv = (w',lmust,l)}
1199
1217
else
1200
1218
let rel_side = keep_only_globals ask m rel in
1201
- let rel_side = Cluster. unlock w rel_side in
1219
+ let rel_side, clusters = Cluster. unlock w rel_side in
1202
1220
let digest = Digest. current ask in
1203
1221
let sidev = GMutex. singleton digest rel_side in
1204
1222
(* Unprotected invariant is one big relation. *)
1205
1223
sideg (V. mutex atomic_mutex) (G. create_mutex sidev);
1206
1224
let (lmust', l') = W. fold (fun g (lmust , l ) ->
1207
1225
let lm = LLock. global g in
1208
- (LMust. add lm lmust, L. add lm rel_side l)
1226
+ let lmust'' = List. fold (fun a c -> LMust. add (lm,c) a) lmust clusters in
1227
+ (lmust'', L. add lm rel_side l)
1209
1228
) w (lmust, l)
1210
1229
in
1211
1230
{rel = rel_local; priv = (w',lmust',l')}
@@ -1295,7 +1314,7 @@ struct
1295
1314
) (RD. vars rel)
1296
1315
in
1297
1316
let rel_side = RD. keep_vars rel g_vars in
1298
- let rel_side = Cluster. unlock (W. top () ) rel_side in (* top W to avoid any filtering *)
1317
+ let rel_side, clusters = Cluster. unlock (W. top () ) rel_side in (* top W to avoid any filtering *)
1299
1318
let digest = Digest. current ask in
1300
1319
let sidev = GMutex. singleton digest rel_side in
1301
1320
sideg V. mutex_inits (G. create_mutex sidev);
0 commit comments