Skip to content

Commit 6a2d078

Browse files
committed
Comment atomic privatizations
1 parent ae5c42e commit 6a2d078

File tree

3 files changed

+35
-23
lines changed

3 files changed

+35
-23
lines changed

src/analyses/apron/relationPriv.apron.ml

+28-16
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,7 @@ struct
481481
let g_var = AV.global g in
482482
let get_mutex_global_g =
483483
if Param.handle_atomic then (
484+
(* Unprotected invariant is one big relation. *)
484485
RD.keep_vars (getg (V.mutex atomic_mutex)) [g_var]
485486
)
486487
else
@@ -491,6 +492,7 @@ struct
491492
RD.join get_mutex_global_g get_mutex_inits'
492493

493494
let get_mutex_global_g_with_mutex_inits_atomic ask getg =
495+
(* Unprotected invariant is one big relation. *)
494496
let get_mutex_global_g = getg (V.mutex atomic_mutex) in
495497
let get_mutex_inits = getg V.mutex_inits in
496498
RD.join get_mutex_global_g get_mutex_inits
@@ -501,9 +503,9 @@ struct
501503
(* lock *)
502504
let rel =
503505
if atomic && RD.mem_var rel (AV.global g) then
504-
rel
506+
rel (* Read previous unpublished unprotected write in current atomic section. *)
505507
else if atomic then
506-
RD.meet rel (get_mutex_global_g_with_mutex_inits_atomic ask getg)
508+
RD.meet rel (get_mutex_global_g_with_mutex_inits_atomic ask getg) (* Read unprotected invariant as full relation. *)
507509
else
508510
RD.meet rel (get_mutex_global_g_with_mutex_inits ask getg g)
509511
in
@@ -523,17 +525,17 @@ struct
523525
rel_local'
524526
)
525527
else
526-
rel_local
528+
rel_local (* Keep write local as if it were protected by the atomic section. *)
527529

528530
let write_global ?(invariant=false) (ask: Q.ask) getg sideg (st: relation_components_t) g x: relation_components_t =
529531
let atomic = Param.handle_atomic && ask.f MustBeAtomic in
530532
let rel = st.rel in
531533
(* lock *)
532534
let rel =
533535
if atomic && RD.mem_var rel (AV.global g) then
534-
rel
536+
rel (* Read previous unpublished unprotected write in current atomic section. *)
535537
else if atomic then
536-
RD.meet rel (get_mutex_global_g_with_mutex_inits_atomic ask getg)
538+
RD.meet rel (get_mutex_global_g_with_mutex_inits_atomic ask getg) (* Read unprotected invariant as full relation. *)
537539
else
538540
RD.meet rel (get_mutex_global_g_with_mutex_inits ask getg g)
539541
in
@@ -546,7 +548,7 @@ struct
546548
if not atomic then (
547549
let rel_side = RD.keep_vars rel_local [g_var] in
548550
if Param.handle_atomic then
549-
sideg (V.mutex atomic_mutex) rel_side
551+
sideg (V.mutex atomic_mutex) rel_side (* Unprotected invariant is one big relation. *)
550552
else
551553
sideg (V.global g) rel_side;
552554
let rel_local' =
@@ -558,7 +560,8 @@ struct
558560
{st with rel = rel_local'}
559561
)
560562
else
561-
{st with rel = rel_local}
563+
(* Delay publishing unprotected write in the atomic section. *)
564+
{st with rel = rel_local} (* Keep write local as if it were protected by the atomic section. *)
562565

563566

564567
let lock ask getg (st: relation_components_t) m =
@@ -573,6 +576,7 @@ struct
573576
{st with rel = rel'}
574577
)
575578
else
579+
(* Atomic section locking is recursive. *)
576580
st (* sound w.r.t. recursive lock *)
577581

578582
let unlock ask getg sideg (st: relation_components_t) m: relation_components_t =
@@ -585,6 +589,7 @@ struct
585589
{st with rel = rel_local}
586590
)
587591
else (
592+
(* Publish delayed unprotected write as if it were protected by the atomic section. *)
588593
(* List.iter (fun var ->
589594
match AV.find_metadata var with
590595
| Some (Global g) -> sideg (V.mutex atomic_mutex) (RD.keep_vars rel [AV.global g])
@@ -596,6 +601,7 @@ struct
596601
| _ -> false
597602
)
598603
in
604+
(* Unprotected invariant is one big relation. *)
599605
sideg (V.mutex atomic_mutex) rel_side;
600606
let rel_local =
601607
let newly_unprot var = match AV.find_metadata var with
@@ -958,6 +964,7 @@ struct
958964
let get_mutex_global_g_with_mutex_inits inits ask getg g =
959965
let get_mutex_global_g =
960966
if Param.handle_atomic then (
967+
(* Unprotected invariant is one big relation. *)
961968
get_relevant_writes_nofilter ask @@ G.mutex @@ getg (V.mutex atomic_mutex)
962969
|> Cluster.keep_global g
963970
)
@@ -978,6 +985,7 @@ struct
978985
r
979986

980987
let get_mutex_global_g_with_mutex_inits_atomic inits ask getg =
988+
(* Unprotected invariant is one big relation. *)
981989
let get_mutex_global_g = get_relevant_writes_nofilter ask @@ G.mutex @@ getg (V.mutex atomic_mutex) in
982990
if not inits then
983991
get_mutex_global_g
@@ -995,9 +1003,9 @@ struct
9951003
(* Additionally filter get_m in case it contains variables it no longer protects. E.g. in 36/22. *)
9961004
let rel =
9971005
if atomic && RD.mem_var rel (AV.global g) then
998-
rel
1006+
rel (* Read previous unpublished unprotected write in current atomic section. *)
9991007
else if atomic then
1000-
Cluster.lock rel local_m (get_mutex_global_g_with_mutex_inits_atomic (not (LMust.mem lm lmust)) ask getg)
1008+
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. *)
10011009
else
10021010
Cluster.lock rel local_m (get_mutex_global_g_with_mutex_inits (not (LMust.mem lm lmust)) ask getg g)
10031011
in
@@ -1017,7 +1025,7 @@ struct
10171025
rel_local'
10181026
)
10191027
else
1020-
rel_local
1028+
rel_local (* Keep write local as if it were protected by the atomic section. *)
10211029

10221030
let write_global ?(invariant=false) (ask:Q.ask) getg sideg (st: relation_components_t) g x: relation_components_t =
10231031
let atomic = Param.handle_atomic && ask.f MustBeAtomic in
@@ -1029,9 +1037,9 @@ struct
10291037
(* Additionally filter get_m in case it contains variables it no longer protects. E.g. in 36/22. *)
10301038
let rel =
10311039
if atomic && RD.mem_var rel (AV.global g) then
1032-
rel
1040+
rel (* Read previous unpublished unprotected write in current atomic section. *)
10331041
else if atomic then
1034-
Cluster.lock rel local_m (get_mutex_global_g_with_mutex_inits_atomic (not (LMust.mem lm lmust)) ask getg)
1042+
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. *)
10351043
else
10361044
Cluster.lock rel local_m (get_mutex_global_g_with_mutex_inits (not (LMust.mem lm lmust)) ask getg g)
10371045
in
@@ -1047,7 +1055,7 @@ struct
10471055
let digest = Digest.current ask in
10481056
let sidev = GMutex.singleton digest rel_side in
10491057
if Param.handle_atomic then
1050-
sideg (V.mutex atomic_mutex) (G.create_global sidev)
1058+
sideg (V.mutex atomic_mutex) (G.create_global sidev) (* Unprotected invariant is one big relation. *)
10511059
else
10521060
sideg (V.global g) (G.create_global sidev);
10531061
let l' = L.add lm rel_side l in
@@ -1060,7 +1068,8 @@ struct
10601068
{rel = rel_local'; priv = (W.add g w,LMust.add lm lmust,l')}
10611069
)
10621070
else
1063-
{rel = rel_local; priv = (W.add g w,lmust,l)}
1071+
(* Delay publishing unprotected write in the atomic section. *)
1072+
{rel = rel_local; priv = (W.add g w,lmust,l)} (* Keep write local as if it were protected by the atomic section. *)
10641073

10651074
let lock ask getg (st: relation_components_t) m =
10661075
let atomic = Param.handle_atomic && LockDomain.Addr.equal m (atomic_mutex) in
@@ -1076,6 +1085,7 @@ struct
10761085
{st with rel}
10771086
)
10781087
else
1088+
(* Atomic section locking is recursive. *)
10791089
st (* sound w.r.t. recursive lock *)
10801090

10811091
let keep_only_globals ask m oct =
@@ -1106,6 +1116,7 @@ struct
11061116
{rel = rel_local; priv = (w',LMust.add lm lmust,l')}
11071117
)
11081118
else (
1119+
(* Publish delayed unprotected write as if it were protected by the atomic section. *)
11091120
let rel_local = remove_globals_unprotected_after_unlock ask m rel in
11101121
let w' = W.filter (fun v -> not (is_unprotected_without ask v m)) w in
11111122
let side_needed = not (W.is_empty w) in
@@ -1116,6 +1127,7 @@ struct
11161127
let rel_side = Cluster.unlock w rel_side in
11171128
let digest = Digest.current ask in
11181129
let sidev = GMutex.singleton digest rel_side in
1130+
(* Unprotected invariant is one big relation. *)
11191131
sideg (V.mutex atomic_mutex) (G.create_mutex sidev);
11201132
let (lmust', l') = W.fold (fun g (lmust, l) ->
11211133
let lm = LLock.global g in
@@ -1386,9 +1398,9 @@ let priv_module: (module S) Lazy.t =
13861398
| "protection" -> (module ProtectionBasedPriv (struct let path_sensitive = false end))
13871399
| "protection-path" -> (module ProtectionBasedPriv (struct let path_sensitive = true end))
13881400
| "mutex-meet" -> (module PerMutexMeetPriv (NoAtomic))
1389-
| "mutex-meet-atomic" -> (module PerMutexMeetPriv (struct let handle_atomic = true end))
1401+
| "mutex-meet-atomic" -> (module PerMutexMeetPriv (struct let handle_atomic = true end)) (* experimental *)
13901402
| "mutex-meet-tid" -> (module PerMutexMeetPrivTID (NoAtomic) (ThreadDigest) (NoCluster))
1391-
| "mutex-meet-tid-atomic" -> (module PerMutexMeetPrivTID (struct let handle_atomic = true end) (ThreadDigest) (NoCluster))
1403+
| "mutex-meet-tid-atomic" -> (module PerMutexMeetPrivTID (struct let handle_atomic = true end) (ThreadDigest) (NoCluster)) (* experimental *)
13921404
| "mutex-meet-tid-cluster12" -> (module PerMutexMeetPrivTID (NoAtomic) (ThreadDigest) (DownwardClosedCluster (Clustering12)))
13931405
| "mutex-meet-tid-cluster2" -> (module PerMutexMeetPrivTID (NoAtomic) (ThreadDigest) (ArbitraryCluster (Clustering2)))
13941406
| "mutex-meet-tid-cluster-max" -> (module PerMutexMeetPrivTID (NoAtomic) (ThreadDigest) (ArbitraryCluster (ClusteringMax)))

src/analyses/basePriv.ml

+6-6
Original file line numberDiff line numberDiff line change
@@ -677,7 +677,7 @@ struct
677677
if P.mem x st.priv then
678678
CPA.find x st.cpa
679679
else if Param.handle_atomic && ask.f MustBeAtomic then
680-
VD.join (CPA.find x st.cpa) (getg (V.unprotected x))
680+
VD.join (CPA.find x st.cpa) (getg (V.unprotected x)) (* Account for previous unpublished unprotected writes in current atomic section. *)
681681
else if is_unprotected ask x then
682682
getg (V.unprotected x) (* CPA unnecessary because all values in GUnprot anyway *)
683683
else
@@ -686,13 +686,13 @@ struct
686686
let write_global ?(invariant=false) (ask: Queries.ask) getg sideg (st: BaseComponents (D).t) x v =
687687
if not invariant then (
688688
if not (Param.handle_atomic && ask.f MustBeAtomic) then
689-
sideg (V.unprotected x) v;
689+
sideg (V.unprotected x) v; (* Delay publishing unprotected write in the atomic section. *)
690690
if !earlyglobs then (* earlyglobs workaround for 13/60 *)
691691
sideg (V.protected x) v
692692
(* Unlock after invariant will still side effect refined value (if protected) from CPA, because cannot distinguish from non-invariant write since W is implicit. *)
693693
);
694694
if Param.handle_atomic && ask.f MustBeAtomic then
695-
{st with cpa = CPA.add x v st.cpa; priv = P.add x st.priv}
695+
{st with cpa = CPA.add x v st.cpa; priv = P.add x st.priv} (* Keep write local as if it were protected by the atomic section. *)
696696
else if is_unprotected ask x then
697697
st
698698
else
@@ -711,7 +711,7 @@ struct
711711
if not Param.check_read_unprotected || is_unprotected_without ask ~write:false x m then
712712
sideg (V.protected x) v;
713713
if atomic then
714-
sideg (V.unprotected x) v;
714+
sideg (V.unprotected x) v; (* Publish delayed unprotected write as if it were protected by the atomic section. *)
715715

716716
if is_unprotected_without ask x m then (* is_in_V' *)
717717
{st with cpa = CPA.remove x st.cpa; priv = P.remove x st.priv}
@@ -1790,9 +1790,9 @@ let priv_module: (module S) Lazy.t =
17901790
| "mutex-meet" -> (module PerMutexMeetPriv)
17911791
| "mutex-meet-tid" -> (module PerMutexMeetTIDPriv (ThreadDigest))
17921792
| "protection" -> (module ProtectionBasedPriv (struct let check_read_unprotected = false let handle_atomic = false end))
1793-
| "protection-atomic" -> (module ProtectionBasedPriv (struct let check_read_unprotected = false let handle_atomic = true end))
1793+
| "protection-atomic" -> (module ProtectionBasedPriv (struct let check_read_unprotected = false let handle_atomic = true end)) (* experimental *)
17941794
| "protection-read" -> (module ProtectionBasedPriv (struct let check_read_unprotected = true let handle_atomic = false end))
1795-
| "protection-read-atomic" -> (module ProtectionBasedPriv (struct let check_read_unprotected = true let handle_atomic = true end))
1795+
| "protection-read-atomic" -> (module ProtectionBasedPriv (struct let check_read_unprotected = true let handle_atomic = true end)) (* experimental *)
17961796
| "mine" -> (module MinePriv)
17971797
| "mine-nothread" -> (module MineNoThreadPriv)
17981798
| "mine-W" -> (module MineWPriv (struct let side_effect_global_init = true end))

src/analyses/commonPriv.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ module VD = BaseDomain.VD
1212
module type AtomicParam =
1313
sig
1414
val handle_atomic: bool
15-
(** Whether to handle SV-COMP atomic blocks. *)
15+
(** Whether to handle SV-COMP atomic blocks (experimental). *)
1616
end
1717

1818
module NoAtomic: AtomicParam =

0 commit comments

Comments
 (0)