Skip to content

Commit e00bfb0

Browse files
committed
Distinguish Read from ReadWrite in mutex analysis (closes #1712)
1 parent 1fed2e7 commit e00bfb0

File tree

2 files changed

+33
-24
lines changed

2 files changed

+33
-24
lines changed

src/analyses/mutexAnalysis.ml

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ open Analyses
1313

1414
module VarSet = SetDomain.Make (Basetype.Variables)
1515

16+
type access_kind = Read | Write
17+
1618
module Spec =
1719
struct
1820
module Arg =
@@ -72,23 +74,22 @@ struct
7274
(** Collects information about which variables are protected by which mutexes *)
7375
module GProtecting: sig
7476
include Lattice.S
75-
val make: kind:Queries.ProtectionKind.t -> recovered:bool -> MustLockset.t -> t
77+
val make: kind:access_kind -> recovered:bool -> MustLockset.t -> t
7678
val get: kind:Queries.ProtectionKind.t -> Queries.Protection.t -> t -> MustLockset.t
7779
end = struct
7880
include MakeP (MustLockset)
7981

80-
let make ~kind ~recovered locks =
81-
(* If the access is not a write, set to T so intersection with current write-protecting is identity *)
82-
let wlocks =
82+
let make ~(kind: access_kind) ~recovered locks =
83+
let locks =
8384
match kind with
84-
| Queries.ProtectionKind.Write -> locks
85-
| ReadWrite -> MustLockset.all ()
85+
| Write -> (locks, locks)
86+
| Read -> (locks, MustLockset.all ()) (* If the access is not a write, set to T so intersection with current write-protecting is identity *)
8687
in
8788
if recovered then
8889
(* If we are in single-threaded mode again, this does not need to be added to set of mutexes protecting in mt-mode only *)
89-
((locks, wlocks), (MustLockset.all (), MustLockset.all ()))
90+
(locks, (MustLockset.all (), MustLockset.all ()))
9091
else
91-
((locks, wlocks), (locks, wlocks))
92+
(locks, locks)
9293
end
9394

9495

@@ -299,24 +300,33 @@ struct
299300
if not (MustLocksetRW.is_all (fst oman.local)) then
300301
let locks = MustLocksetRW.to_must_lockset (MustLocksetRW.filter snd (fst oman.local)) in
301302
let kind = match kind with
302-
| Write | Free -> Queries.ProtectionKind.Write
303-
| Read -> ReadWrite
303+
| Write | Free -> Write
304+
| Read -> Read
304305
| Call
305-
| Spawn -> ReadWrite (* TODO: nonsense? *)
306+
| Spawn -> Read (* TODO: nonsense? *)
306307
in
307308
let s = GProtecting.make ~kind ~recovered:is_recovered_to_st locks in
308309
man.sideg (V.protecting v) (G.create_protecting s);
309310

310311
if !AnalysisState.postsolving then (
311-
let protecting mode = GProtecting.get ~kind mode (G.protecting (man.global (V.protecting v))) in
312-
let held_strong = protecting Strong in
313-
let held_weak = protecting Weak in
314-
let vs = VarSet.singleton v in
315-
let protected = G.create_protected @@ GProtected.make ~kind vs in
316-
MustLockset.iter (fun ml -> man.sideg (V.protected ml) protected) held_strong;
317-
(* If the mutex set here is top, it is actually not accessed *)
318-
if is_recovered_to_st && not @@ MustLockset.is_all held_weak then
319-
MustLockset.iter (fun ml -> man.sideg (V.protected ml) protected) held_weak;
312+
let side_protected kind mode =
313+
let protecting = GProtecting.get ~kind mode (G.protecting (man.global (V.protecting v))) in
314+
(* If the mutex set here is top, it is actually not accessed *)
315+
if not @@ MustLockset.is_all protecting then (
316+
let vs = VarSet.singleton v in
317+
let protected = G.create_protected @@ GProtected.make ~kind vs in
318+
MustLockset.iter (fun ml -> man.sideg (V.protected ml) protected) protecting
319+
)
320+
in
321+
let side_protected kind =
322+
side_protected kind Strong;
323+
if is_recovered_to_st then
324+
side_protected kind Weak
325+
in
326+
side_protected Queries.ProtectionKind.ReadWrite;
327+
match kind with
328+
| Write -> side_protected Queries.ProtectionKind.Write
329+
| Read -> ()
320330
)
321331
| None -> M.info ~category:Unsound "Write to unknown address: privatization is unsound."
322332
in

tests/regression/46-apron2/98-issue-1511b.t

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,9 @@
4444

4545

4646
# Issue #1712
47-
TODO: Mutex f should read-write protect j as well.
4847

4948
$ goblint --enable warn.deterministic --enable dbg.print_protection --disable ana.dead-code.lines 98-issue-1511b.c
50-
[Info][Race] Mutex f read-write protects 1 variable(s): {nothing2}
49+
[Info][Race] Mutex f read-write protects 2 variable(s): {j, nothing2}
5150
[Info][Race] Variable j read-write protected by 1 mutex(es): {f}
5251
[Info][Race] Variable nothing2 read-write protected by 1 mutex(es): {f}
5352
[Info][Race] Memory locations race summary:
@@ -57,5 +56,5 @@ TODO: Mutex f should read-write protect j as well.
5756
total memory locations: 1
5857
[Info][Race] Mutex read-write protection summary:
5958
Number of mutexes: 1
60-
Max number variables of protected by a mutex: 1
61-
Total number of protected variables (including duplicates): 1
59+
Max number variables of protected by a mutex: 2
60+
Total number of protected variables (including duplicates): 2

0 commit comments

Comments
 (0)