@@ -956,6 +956,12 @@ struct
956
956
(* weak: G -> (2^M -> D) *)
957
957
(* sync: M -> (2^M -> (G -> D)) *)
958
958
include AbstractLockCenteredBase (VD ) (CPA )
959
+
960
+ module W =
961
+ struct
962
+ include MapDomain. MapBot (LockDomain. MustLock ) (MayVars )
963
+ let name () = " W"
964
+ end
959
965
end
960
966
961
967
module MinePrivBase =
@@ -1130,14 +1136,9 @@ struct
1130
1136
include LockCenteredBase
1131
1137
open Locksets
1132
1138
1133
- module W =
1134
- struct
1135
- include SetDomain. ToppedSet (Basetype. Variables ) (struct let topname = " All variables" end )
1136
- let name () = " W"
1137
- end
1138
- module D = MapDomain. MapBot (MustLockset ) (W )
1139
+ module D = W
1139
1140
1140
- let startstate () = D . empty ()
1141
+ let startstate () = W . empty ()
1141
1142
1142
1143
let read_global ask getg (st : BaseComponents (D).t ) x =
1143
1144
let s = current_lockset ask in
@@ -1153,8 +1154,11 @@ struct
1153
1154
let cpa' = CPA. add x v st.cpa in
1154
1155
if not invariant && not (! earlyglobs && is_excluded_from_earlyglobs x) then
1155
1156
sideg (V. global x) (G. create_weak (GWeak. singleton s v));
1156
- let w' = if not invariant then
1157
- D. join st.priv (D. singleton s (W. singleton x))
1157
+ let w' = if not invariant then (
1158
+ MustLockset. fold (fun m acc ->
1159
+ W. join acc (W. singleton m (MayVars. singleton x))
1160
+ ) s st.priv
1161
+ )
1158
1162
else
1159
1163
st.priv (* No need to add invariant to W because it doesn't matter for reads after invariant, only unlocks. *)
1160
1164
in
@@ -1169,18 +1173,13 @@ struct
1169
1173
acc
1170
1174
) (G. sync (getg (V. mutex m))) st.cpa
1171
1175
in
1176
+ (* Could set W m to empty here (like Lock-Centered) but Miné doesn't and mentions this over-approximation. *)
1172
1177
{st with cpa = cpa'}
1173
1178
1174
1179
let unlock ask getg sideg (st : BaseComponents (D).t ) m =
1175
1180
let s = MustLockset. remove m (current_lockset ask) in
1176
- let w = D. fold (fun s' w acc ->
1177
- if MustLockset. mem m s' then
1178
- W. join w acc
1179
- else
1180
- acc
1181
- ) st.priv (W. empty () )
1182
- in
1183
- let is_in_W x _ = W. mem x w in
1181
+ let w = W. find m st.priv in
1182
+ let is_in_W x _ = MayVars. mem x w in
1184
1183
let side_cpa = CPA. filter is_in_W st.cpa in
1185
1184
sideg (V. mutex m) (G. create_sync (GSync. singleton s side_cpa));
1186
1185
st
@@ -1201,7 +1200,7 @@ struct
1201
1200
CPA. fold (fun x v (st : BaseComponents (D).t ) ->
1202
1201
if is_global ask x then (
1203
1202
sideg (V. global x) (G. create_weak (GWeak. singleton (MustLockset. empty () ) v));
1204
- {st with priv = D. join st.priv ( D. singleton ( MustLockset. empty () ) ( W. singleton x))} (* TODO: is this add necessary? *)
1203
+ st
1205
1204
)
1206
1205
else
1207
1206
st
@@ -1227,12 +1226,6 @@ struct
1227
1226
let name () = " V"
1228
1227
end
1229
1228
1230
- module DV2 =
1231
- struct
1232
- include MapDomain. MapBot_LiftTop (LockDomain. MustLock ) (MayVars )
1233
- let name () = " V2"
1234
- end
1235
-
1236
1229
module L =
1237
1230
struct
1238
1231
include MapDomain. MapBot_LiftTop (LockDomain. MustLock ) (MinLocksets )
@@ -1248,7 +1241,7 @@ struct
1248
1241
open Locksets
1249
1242
1250
1243
open LockCenteredD
1251
- module D = Lattice. Prod3 (DV ) (DV2 ) (L )
1244
+ module D = Lattice. Prod3 (DV ) (W ) (L )
1252
1245
1253
1246
module Wrapper = Wrapper (G )
1254
1247
module UnwrappedG = G
@@ -1257,7 +1250,7 @@ struct
1257
1250
let invariant_global ask getg = invariant_global ask (Wrapper. getg ask getg)
1258
1251
let invariant_vars ask getg = invariant_vars ask (Wrapper. getg ask getg)
1259
1252
1260
- let startstate () = (DV. bot () , DV2 . bot () , L. bot () )
1253
+ let startstate () = (DV. bot () , W . bot () , L. bot () )
1261
1254
1262
1255
let lockset_init = MustLockset. all ()
1263
1256
@@ -1271,7 +1264,7 @@ struct
1271
1264
let read_global ask getg (st : BaseComponents (D).t ) x =
1272
1265
let getg = Wrapper. getg ask getg in
1273
1266
let s = current_lockset ask in
1274
- let (vv, vv2 , l) = st.priv in
1267
+ let (vv, _ , l) = st.priv in
1275
1268
let d_cpa = CPA. find x st.cpa in
1276
1269
let d_sync = L. fold (fun m bs acc ->
1277
1270
if not (MustVars. mem x (DV. find m vv)) then
@@ -1315,34 +1308,35 @@ struct
1315
1308
let sideg = Wrapper. sideg ask sideg in
1316
1309
let getg = Wrapper. getg ask getg in
1317
1310
let s = current_lockset ask in
1318
- let (vv, vv2 , l) = st.priv in
1319
- let (v', v2 ') = L. fold (fun m _ (acc1 , acc2 ) ->
1311
+ let (vv, w , l) = st.priv in
1312
+ let (v', w ') = L. fold (fun m _ (acc1 , acc2 ) ->
1320
1313
DV. add m (MustVars. add x (DV. find m acc1)) acc1,
1321
- DV2 . add m (MayVars. add x (DV2 . find m acc2)) acc2
1322
- ) l (vv, vv2 )
1314
+ W . add m (MayVars. add x (W . find m acc2)) acc2
1315
+ ) l (vv, w )
1323
1316
in
1324
1317
let cpa' = CPA. add x v st.cpa in
1325
1318
if not invariant && not (! earlyglobs && is_excluded_from_earlyglobs x) then (
1326
1319
let v = distr_init getg x v in
1327
1320
sideg (V. global x) (UnwrappedG. create_weak (GWeak. singleton s v))
1328
1321
(* Unlock after invariant will still side effect refined value from CPA, because cannot distinguish from non-invariant write. *)
1329
1322
);
1330
- {st with cpa = cpa'; priv = (v', v2 ', l)}
1323
+ {st with cpa = cpa'; priv = (v', w ', l)}
1331
1324
1332
1325
let lock ask getg (st : BaseComponents (D).t ) m =
1333
1326
let s = current_lockset ask in
1334
- let (v, v2 , l) = st.priv in
1327
+ let (v, w , l) = st.priv in
1335
1328
let v' = DV. add m (MustVars. empty () ) v in
1336
- let v2 ' = DV2 . add m (MayVars. empty () ) v2 in
1329
+ let w ' = W . add m (MayVars. empty () ) w in
1337
1330
let l' = L. add m (MinLocksets. singleton s) l in
1338
- {st with priv = (v', v2 ', l')}
1331
+ {st with priv = (v', w ', l')}
1339
1332
1340
1333
let unlock ask getg sideg (st : BaseComponents (D).t ) m =
1341
1334
let sideg = Wrapper. sideg ask sideg in
1342
1335
let getg = Wrapper. getg ask getg in
1343
1336
let s = MustLockset. remove m (current_lockset ask) in
1344
- let (_, v2, _) = st.priv in
1345
- let is_in_G x _ = is_global ask x && MayVars. mem x (DV2. find m v2) in
1337
+ let (_, w, _) = st.priv in
1338
+ let w = W. find m w in
1339
+ let is_in_G x _ = is_global ask x && MayVars. mem x w in (* TODO: is_global check unnecessary? *)
1346
1340
let side_cpa = CPA. filter is_in_G st.cpa in
1347
1341
let side_cpa = CPA. mapi (fun x v ->
1348
1342
let v = distr_init getg x v in
0 commit comments