@@ -481,6 +481,7 @@ struct
481
481
let g_var = AV. global g in
482
482
let get_mutex_global_g =
483
483
if Param. handle_atomic then (
484
+ (* Unprotected invariant is one big relation. *)
484
485
RD. keep_vars (getg (V. mutex atomic_mutex)) [g_var]
485
486
)
486
487
else
@@ -491,6 +492,7 @@ struct
491
492
RD. join get_mutex_global_g get_mutex_inits'
492
493
493
494
let get_mutex_global_g_with_mutex_inits_atomic ask getg =
495
+ (* Unprotected invariant is one big relation. *)
494
496
let get_mutex_global_g = getg (V. mutex atomic_mutex) in
495
497
let get_mutex_inits = getg V. mutex_inits in
496
498
RD. join get_mutex_global_g get_mutex_inits
@@ -501,9 +503,9 @@ struct
501
503
(* lock *)
502
504
let rel =
503
505
if atomic && RD. mem_var rel (AV. global g) then
504
- rel
506
+ rel (* Read previous unpublished unprotected write in current atomic section. *)
505
507
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. *)
507
509
else
508
510
RD. meet rel (get_mutex_global_g_with_mutex_inits ask getg g)
509
511
in
@@ -523,17 +525,17 @@ struct
523
525
rel_local'
524
526
)
525
527
else
526
- rel_local
528
+ rel_local (* Keep write local as if it were protected by the atomic section. *)
527
529
528
530
let write_global ?(invariant =false ) (ask : Q.ask ) getg sideg (st : relation_components_t ) g x : relation_components_t =
529
531
let atomic = Param. handle_atomic && ask.f MustBeAtomic in
530
532
let rel = st.rel in
531
533
(* lock *)
532
534
let rel =
533
535
if atomic && RD. mem_var rel (AV. global g) then
534
- rel
536
+ rel (* Read previous unpublished unprotected write in current atomic section. *)
535
537
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. *)
537
539
else
538
540
RD. meet rel (get_mutex_global_g_with_mutex_inits ask getg g)
539
541
in
@@ -546,7 +548,7 @@ struct
546
548
if not atomic then (
547
549
let rel_side = RD. keep_vars rel_local [g_var] in
548
550
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. *)
550
552
else
551
553
sideg (V. global g) rel_side;
552
554
let rel_local' =
@@ -558,7 +560,8 @@ struct
558
560
{st with rel = rel_local'}
559
561
)
560
562
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. *)
562
565
563
566
564
567
let lock ask getg (st : relation_components_t ) m =
@@ -573,6 +576,7 @@ struct
573
576
{st with rel = rel'}
574
577
)
575
578
else
579
+ (* Atomic section locking is recursive. *)
576
580
st (* sound w.r.t. recursive lock *)
577
581
578
582
let unlock ask getg sideg (st : relation_components_t ) m : relation_components_t =
@@ -585,6 +589,7 @@ struct
585
589
{st with rel = rel_local}
586
590
)
587
591
else (
592
+ (* Publish delayed unprotected write as if it were protected by the atomic section. *)
588
593
(* List.iter (fun var ->
589
594
match AV.find_metadata var with
590
595
| Some (Global g) -> sideg (V.mutex atomic_mutex) (RD.keep_vars rel [AV.global g])
@@ -596,6 +601,7 @@ struct
596
601
| _ -> false
597
602
)
598
603
in
604
+ (* Unprotected invariant is one big relation. *)
599
605
sideg (V. mutex atomic_mutex) rel_side;
600
606
let rel_local =
601
607
let newly_unprot var = match AV. find_metadata var with
@@ -958,6 +964,7 @@ struct
958
964
let get_mutex_global_g_with_mutex_inits inits ask getg g =
959
965
let get_mutex_global_g =
960
966
if Param. handle_atomic then (
967
+ (* Unprotected invariant is one big relation. *)
961
968
get_relevant_writes_nofilter ask @@ G. mutex @@ getg (V. mutex atomic_mutex)
962
969
|> Cluster. keep_global g
963
970
)
@@ -978,6 +985,7 @@ struct
978
985
r
979
986
980
987
let get_mutex_global_g_with_mutex_inits_atomic inits ask getg =
988
+ (* Unprotected invariant is one big relation. *)
981
989
let get_mutex_global_g = get_relevant_writes_nofilter ask @@ G. mutex @@ getg (V. mutex atomic_mutex) in
982
990
if not inits then
983
991
get_mutex_global_g
@@ -995,9 +1003,9 @@ struct
995
1003
(* Additionally filter get_m in case it contains variables it no longer protects. E.g. in 36/22. *)
996
1004
let rel =
997
1005
if atomic && RD. mem_var rel (AV. global g) then
998
- rel
1006
+ rel (* Read previous unpublished unprotected write in current atomic section. *)
999
1007
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. *)
1001
1009
else
1002
1010
Cluster. lock rel local_m (get_mutex_global_g_with_mutex_inits (not (LMust. mem lm lmust)) ask getg g)
1003
1011
in
@@ -1017,7 +1025,7 @@ struct
1017
1025
rel_local'
1018
1026
)
1019
1027
else
1020
- rel_local
1028
+ rel_local (* Keep write local as if it were protected by the atomic section. *)
1021
1029
1022
1030
let write_global ?(invariant =false ) (ask :Q.ask ) getg sideg (st : relation_components_t ) g x : relation_components_t =
1023
1031
let atomic = Param. handle_atomic && ask.f MustBeAtomic in
@@ -1029,9 +1037,9 @@ struct
1029
1037
(* Additionally filter get_m in case it contains variables it no longer protects. E.g. in 36/22. *)
1030
1038
let rel =
1031
1039
if atomic && RD. mem_var rel (AV. global g) then
1032
- rel
1040
+ rel (* Read previous unpublished unprotected write in current atomic section. *)
1033
1041
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. *)
1035
1043
else
1036
1044
Cluster. lock rel local_m (get_mutex_global_g_with_mutex_inits (not (LMust. mem lm lmust)) ask getg g)
1037
1045
in
@@ -1047,7 +1055,7 @@ struct
1047
1055
let digest = Digest. current ask in
1048
1056
let sidev = GMutex. singleton digest rel_side in
1049
1057
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. *)
1051
1059
else
1052
1060
sideg (V. global g) (G. create_global sidev);
1053
1061
let l' = L. add lm rel_side l in
@@ -1060,7 +1068,8 @@ struct
1060
1068
{rel = rel_local'; priv = (W. add g w,LMust. add lm lmust,l')}
1061
1069
)
1062
1070
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. *)
1064
1073
1065
1074
let lock ask getg (st : relation_components_t ) m =
1066
1075
let atomic = Param. handle_atomic && LockDomain.Addr. equal m (atomic_mutex) in
@@ -1076,6 +1085,7 @@ struct
1076
1085
{st with rel}
1077
1086
)
1078
1087
else
1088
+ (* Atomic section locking is recursive. *)
1079
1089
st (* sound w.r.t. recursive lock *)
1080
1090
1081
1091
let keep_only_globals ask m oct =
@@ -1106,6 +1116,7 @@ struct
1106
1116
{rel = rel_local; priv = (w',LMust. add lm lmust,l')}
1107
1117
)
1108
1118
else (
1119
+ (* Publish delayed unprotected write as if it were protected by the atomic section. *)
1109
1120
let rel_local = remove_globals_unprotected_after_unlock ask m rel in
1110
1121
let w' = W. filter (fun v -> not (is_unprotected_without ask v m)) w in
1111
1122
let side_needed = not (W. is_empty w) in
@@ -1116,6 +1127,7 @@ struct
1116
1127
let rel_side = Cluster. unlock w rel_side in
1117
1128
let digest = Digest. current ask in
1118
1129
let sidev = GMutex. singleton digest rel_side in
1130
+ (* Unprotected invariant is one big relation. *)
1119
1131
sideg (V. mutex atomic_mutex) (G. create_mutex sidev);
1120
1132
let (lmust', l') = W. fold (fun g (lmust , l ) ->
1121
1133
let lm = LLock. global g in
@@ -1386,9 +1398,9 @@ let priv_module: (module S) Lazy.t =
1386
1398
| "protection" -> (module ProtectionBasedPriv (struct let path_sensitive = false end ))
1387
1399
| "protection-path" -> (module ProtectionBasedPriv (struct let path_sensitive = true end ))
1388
1400
| "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 *)
1390
1402
| "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 *)
1392
1404
| "mutex-meet-tid-cluster12" -> (module PerMutexMeetPrivTID (NoAtomic ) (ThreadDigest ) (DownwardClosedCluster (Clustering12 )))
1393
1405
| "mutex-meet-tid-cluster2" -> (module PerMutexMeetPrivTID (NoAtomic ) (ThreadDigest ) (ArbitraryCluster (Clustering2 )))
1394
1406
| "mutex-meet-tid-cluster-max" -> (module PerMutexMeetPrivTID (NoAtomic ) (ThreadDigest ) (ArbitraryCluster (ClusteringMax )))
0 commit comments