Skip to content

Commit d659a5c

Browse files
authored
Merge pull request herd#1175 from relokin/cas-fix
[herd] Consolidate alternative executions of a failed CAS
2 parents 83bb909 + 254ee8d commit d659a5c

28 files changed

Lines changed: 128 additions & 229 deletions

herd/AArch64Sem.ml

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1989,7 +1989,9 @@ module Make
19891989
let read_mem a =
19901990
if noret then do_read_mem_ret sz Annot.NoRet aexp ac a ii
19911991
else do_read_mem_ret sz an aexp ac a ii in
1992-
M.aarch64_cas_no (Access.is_physical ac) ma read_rs write_rs read_mem branch M.neqT
1992+
let noact _ _ = M.mk_singleton_es Act.NoAction ii in
1993+
M.aarch64_cas_no (Access.is_physical ac) ma read_rs write_rs read_mem
1994+
noact branch M.neqT
19931995
in
19941996
let mop_fail_with_wb ac ma _ =
19951997
(* CAS fails, there is an Explicit Write Effect writing back *)
@@ -1998,8 +2000,8 @@ module Make
19982000
if noret then do_read_mem_ret sz Annot.NoRet aexp ac a ii
19992001
else rmw_amo_read sz rmw ac a ii
20002002
and write_mem a v = rmw_amo_write sz rmw ac a v ii in
2001-
M.aarch64_cas_no_with_writeback (Access.is_physical ac) ma read_rs write_rs
2002-
read_mem write_mem branch M.neqT
2003+
M.aarch64_cas_no (Access.is_physical ac) ma read_rs write_rs
2004+
read_mem write_mem branch M.neqT
20032005
in
20042006
let mop_success ac ma mv =
20052007
(* CAS succeeds, there is an Explicit Write Effect *)
@@ -2058,22 +2060,23 @@ module Make
20582060
(* CASP fails, there are no Explicit Write Effects *)
20592061
let read_mem a = do_read_mem_ret sz an aexp ac a ii
20602062
>>| (add_size a sz
2061-
>>= fun a -> do_read_mem_ret sz an aexp ac a ii) in
2063+
>>= fun a -> do_read_mem_ret sz an aexp ac a ii) in
2064+
let noact _ _ = M.mk_singleton_es Act.NoAction ii in
20622065
M.aarch64_cas_no (Access.is_physical ac) ma read_rs
2063-
write_rs read_mem branch neqp
2066+
write_rs read_mem noact branch neqp
20642067
in
20652068
let mop_fail_with_wb ac ma _ =
20662069
(* CASP fails, there are Explicit Write Effects writing back *)
20672070
(* the value that is already in memory *)
2068-
let read_mem a = do_read_mem_ret sz an aexp ac a ii
2071+
let read_mem a = rmw_amo_read sz rmw ac a ii
20692072
>>| (add_size a sz
2070-
>>= fun a -> do_read_mem_ret sz an aexp ac a ii)
2073+
>>= fun a -> rmw_amo_read sz rmw ac a ii)
20712074
and write_mem a (v1,v2) =
20722075
rmw_amo_write sz rmw ac a v1 ii
20732076
>>| (add_size a sz >>= fun a2 ->
20742077
rmw_amo_write sz rmw ac a2 v2 ii)
20752078
>>= fun _ -> M.unitT () in
2076-
M.aarch64_cas_no_with_writeback (Access.is_physical ac) ma read_rs
2079+
M.aarch64_cas_no (Access.is_physical ac) ma read_rs
20772080
write_rs read_mem write_mem branch neqp
20782081
in
20792082
let mop_success ac ma _ =

herd/ASLAction.ml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,10 @@ module Make (C: Config) (A : S) = struct
265265
| Branching _ -> true
266266
| Access _|Barrier _|CutOff _|NoAction -> false
267267

268+
let is_no_action = function
269+
| NoAction -> true
270+
| _ -> false
271+
268272
(* Unrolling control *)
269273
let cutoff msg = CutOff msg
270274
let is_cutoff = function

herd/BellAction.ml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,8 @@ end = struct
200200

201201
let is_commit = is_bcc
202202

203+
let is_no_action _ = false
204+
203205
(* Unroll control *)
204206
let cutoff msg = CutOff msg
205207
let is_cutoff = function

herd/CAction.ml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,8 @@ end = struct
262262
let is_pred ?cond:_ _ = false
263263
let is_commit _ = false
264264

265+
let is_no_action _ = false
266+
265267
(* Unrolling control *)
266268
let cutoff msg = CutOff msg
267269
let is_cutoff = function

herd/JavaAction.ml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,8 @@ end = struct
200200
let is_pred ?cond:_ _ = false
201201
let is_commit _ = false
202202

203+
let is_no_action _ = false
204+
203205
include Explicit.NoAction
204206

205207
let annot_in_list _ _ = false

herd/action.mli

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ module type S = sig
9797
val is_pred : ?cond:string option -> action -> bool
9898
val is_commit : action -> bool
9999

100+
val is_no_action : action -> bool
101+
100102
(* Unrolling control *)
101103
val cutoff : string -> action
102104
val is_cutoff : action -> bool

herd/event.ml

Lines changed: 35 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -468,14 +468,9 @@ val same_instance : event -> event -> bool
468468
event_structure -> event_structure -> event_structure ->
469469
event_structure
470470

471-
val aarch64_cas_no :
472-
bool -> (* Physical memory access *)
473-
bool -> (* Add an iico_ctrl between the Branch and the Register Write *)
474-
event_structure -> event_structure -> event_structure ->
475-
event_structure -> event_structure -> event_structure
476-
477-
val aarch64_cas_ok :
478-
bool (* Physical memory access *) -> [`DataFromRRs | `DataFromRx] ->
471+
val aarch64_cas :
472+
bool (* Physical memory access *) ->
473+
[< `DataFromRRs | `DataFromRx | `No] ->
479474
event_structure -> event_structure -> event_structure ->
480475
event_structure -> event_structure -> event_structure ->
481476
event_structure -> event_structure
@@ -2327,79 +2322,8 @@ module Make (C:Config) (AI:Arch_herd.S) (Act:Action.S with module A = AI) :
23272322
resa.aligned @ data.aligned @ addr.aligned
23282323
@ wres.aligned @ wresult.aligned @ wmem.aligned ;}
23292324

2330-
(* AArch64 CAS, failure *)
2331-
let aarch64_cas_no is_phy add_ctrl rn rs wrs rm br =
2332-
let input_wrs = minimals wrs
2333-
and input_rm = minimals rm
2334-
and input_br = minimals br in
2335-
{ procs = [] ;
2336-
events =
2337-
EventSet.union5
2338-
rn.events rs.events wrs.events rm.events br.events;
2339-
speculated =
2340-
if do_deps then
2341-
EventSet.union5
2342-
rn.speculated rs.speculated wrs.speculated rm.speculated br.speculated
2343-
else rn.speculated;
2344-
po = po_union5 rn rs wrs rm br;
2345-
partial_po = partial_po_union5 rn rs wrs rm br;
2346-
intra_causality_data =
2347-
EventRel.union
2348-
(EventRel.union5
2349-
rn.intra_causality_data
2350-
rs.intra_causality_data
2351-
wrs.intra_causality_data
2352-
rm.intra_causality_data
2353-
br.intra_causality_data)
2354-
(EventRel.union4
2355-
(EventRel.cartesian (get_output rn) input_rm) (* D1 *)
2356-
(EventRel.cartesian (get_output rm) input_wrs) (* Df1 *)
2357-
(EventRel.cartesian (get_output rm) input_br)
2358-
(EventRel.cartesian (get_output rs) input_br)
2359-
);
2360-
intra_causality_control =
2361-
(if is_branching && is_phy then
2362-
EventRel.union
2363-
(EventRel.cartesian (get_ctrl_output_commits rn) input_rm)
2364-
else Misc.identity)
2365-
((if add_ctrl then
2366-
EventRel.union
2367-
(EventRel.cartesian (get_output br) input_wrs)
2368-
else Misc.identity)
2369-
(EventRel.union5
2370-
rn.intra_causality_control rs.intra_causality_control
2371-
wrs.intra_causality_control rm.intra_causality_control
2372-
br.intra_causality_control)) ;
2373-
intra_causality_order =
2374-
EventRel.union5
2375-
rn.intra_causality_order rs.intra_causality_order
2376-
wrs.intra_causality_order rm.intra_causality_order
2377-
br.intra_causality_order;
2378-
control =
2379-
EventRel.union5 rn.control rs.control rm.control wrs.control br.control;
2380-
data_ports =
2381-
EventSet.union5
2382-
rn.data_ports rs.data_ports
2383-
wrs.data_ports rm.data_ports br.data_ports;
2384-
success_ports =
2385-
EventSet.union5
2386-
rn.success_ports rs.success_ports
2387-
wrs.success_ports rm.success_ports br.success_ports;
2388-
sca =
2389-
EventSetSet.union5
2390-
rn.sca rs.sca wrs.sca rm.sca br.sca;
2391-
mem_accesses =
2392-
EventSet.union5
2393-
rn.mem_accesses rs.mem_accesses
2394-
wrs.mem_accesses rm.mem_accesses br.mem_accesses;
2395-
input=None; data_input=None;
2396-
output = Some (maximals wrs);
2397-
ctrl_output = None ;
2398-
aligned = rn.aligned @ rs.aligned @ wrs.aligned @ rm.aligned @ br.aligned;
2399-
}
2400-
2401-
(* AArch64 CAS, success *)
2402-
let aarch64_cas_ok is_phy prov_data rn rs rt wrs rm wm br =
2325+
(* AArch64 CAS *)
2326+
let aarch64_cas is_phy mode rn rs rt wrs rm wm br =
24032327
let input_wrs = minimals wrs
24042328
and input_rm = minimals rm
24052329
and input_wm = minimals wm
@@ -2428,18 +2352,34 @@ module Make (C:Config) (AI:Arch_herd.S) (Act:Action.S with module A = AI) :
24282352
rm.intra_causality_data;
24292353
br.intra_causality_data;
24302354
wm.intra_causality_data])
2431-
(let output_rn = get_output rn
2432-
and output_prov_data = match prov_data with
2433-
| `DataFromRRs -> get_output rs
2434-
| `DataFromRx -> get_output rm
2435-
in
2436-
EventRel.unions
2437-
[(EventRel.cartesian output_rn input_rm); (* D1 *)
2438-
(EventRel.cartesian output_rn input_wm); (* Ds2 *)
2439-
(EventRel.cartesian (get_output rt) input_wm); (* Ds3 *)
2440-
(EventRel.cartesian output_prov_data input_wrs);
2355+
(let output_rn = get_output rn in
2356+
(* Data for the Register Write Effect of Ws *)
2357+
let wrs_data = match mode with
2358+
| `DataFromRRs ->
2359+
[EventRel.cartesian (get_output rs) input_wrs; ]
2360+
| `DataFromRx | `No ->
2361+
[EventRel.cartesian (get_output rm) input_wrs; ] in
2362+
(* Address for the Write Memory Effect *)
2363+
let wm_addr = [EventRel.cartesian output_rn input_wm; ]
2364+
(* Data for the Write Memory Effect *)
2365+
and wm_data = match mode with
2366+
| `DataFromRRs | `DataFromRx ->
2367+
[EventRel.cartesian (get_output rt) input_wm; ]
2368+
| `No ->
2369+
[EventRel.cartesian (get_output rm) input_wm; ] in
2370+
(* Handle the case where wm is NoAction *)
2371+
let wm_rels = match EventSet.elements wm.events with
2372+
| [evt] when Act.is_no_action evt.action ->
2373+
[]
2374+
| evts when List.for_all is_mem_store evts ->
2375+
wm_data @ wm_addr
2376+
| _ -> assert false in
2377+
let rels =
2378+
wrs_data @ wm_rels @
2379+
[(EventRel.cartesian output_rn input_rm);
24412380
(EventRel.cartesian (get_output rs) input_br);
2442-
(EventRel.cartesian (get_output rm) input_br);]
2381+
(EventRel.cartesian (get_output rm) input_br);] in
2382+
EventRel.unions rels
24432383
);
24442384
intra_causality_control =
24452385
EventRel.union
@@ -2457,9 +2397,10 @@ module Make (C:Config) (AI:Arch_herd.S) (Act:Action.S with module A = AI) :
24572397
EventRel.cartesian (get_ctrl_output_commits rn)
24582398
(EventSet.union input_rm input_wm)
24592399
else EventRel.empty)
2460-
(match prov_data with
2400+
(match mode with
24612401
| `DataFromRRs -> EventRel.cartesian output_br input_wrs
2462-
| `DataFromRx -> EventRel.empty)
2402+
| `DataFromRx
2403+
| `No -> EventRel.empty)
24632404
(EventRel.cartesian output_br input_wm) (* Cs1 *)
24642405
(EventRel.cartesian output_br input_wm)); (* Cs2 *)
24652406
intra_causality_order =

herd/eventsMonad.ml

Lines changed: 29 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -577,75 +577,6 @@ Monad type:
577577
read_addr (eiid,Evt.empty) in
578578
eiid,(acts,None)
579579

580-
(* AArch64 failed cas *)
581-
let do_aarch64_cas_no
582-
(is_physical:bool)
583-
(add_ctrl:bool)
584-
(read_rn:'loc t) (read_rs:'v t)
585-
(write_rs:'v-> unit t)
586-
(read_mem: 'loc -> 'v t)
587-
(branch: 'loc -> unit t)
588-
(rne: 'v -> 'v -> unit t)
589-
eiid =
590-
let eiid,read_rn = read_rn eiid in
591-
let eiid,read_rs = read_rs eiid in
592-
let cv,cl_cv,es_rs = Evt.as_singleton_nospecul read_rs in
593-
let acts_rn,spec = read_rn in
594-
assert (Misc.is_none spec) ;
595-
let eiid,acts =
596-
Evt.fold
597-
(fun (a,cl_a,es_rn) (eiid,acts) ->
598-
let eiid,read_mem = read_mem a eiid in
599-
let ov,cl_rm,es_rm = Evt.as_singleton_nospecul read_mem in
600-
let eiid,write_rs = write_rs ov eiid in
601-
let (),cl_wrs,es_wrs = Evt.as_singleton_nospecul write_rs in
602-
let eiid,branch = branch a eiid in
603-
let (),cl_br,es_br = Evt.as_singleton_nospecul branch in
604-
let eiid,nem = rne ov cv eiid in
605-
let (),cl_ne,eseq = Evt.as_singleton_nospecul nem in
606-
assert (E.is_empty_event_structure eseq) ;
607-
let es =
608-
E.aarch64_cas_no is_physical add_ctrl es_rn es_rs es_wrs es_rm es_br in
609-
let cls = cl_a@cl_cv@cl_rm@cl_wrs@cl_ne@cl_br in
610-
eiid,Evt.add ((),cls,es) acts)
611-
acts_rn (eiid,Evt.empty) in
612-
eiid,(acts, None)
613-
614-
(* AArch64 failed cas that writes into memory nevertheless *)
615-
let do_aarch64_cas_no_with_writeback
616-
(is_physical:bool)
617-
(read_rn:'loc t) (read_rs:'v t)
618-
(write_rs:'v-> unit t)
619-
(read_mem: 'loc -> 'v t) (write_mem: 'loc -> 'v -> unit t)
620-
(branch: 'loc -> unit t)
621-
(rne: 'v -> 'v -> unit t)
622-
eiid =
623-
let eiid,read_rn = read_rn eiid in
624-
let eiid,read_rs = read_rs eiid in
625-
let cv,cl_cv,es_rs = Evt.as_singleton_nospecul read_rs in
626-
let acts_rn,spec = read_rn in
627-
assert (Misc.is_none spec) ;
628-
let eiid,acts =
629-
Evt.fold
630-
(fun (a,cl_a,es_rn) (eiid,acts) ->
631-
let eiid,read_mem = read_mem a eiid in
632-
let ov,cl_rm,es_rm = Evt.as_singleton_nospecul read_mem in
633-
let eiid,write_mem = write_mem a ov eiid in
634-
let (),cl_wm,es_wm= Evt.as_singleton_nospecul write_mem in
635-
let eiid,write_rs = write_rs ov eiid in
636-
let (),cl_wrs,es_wrs = Evt.as_singleton_nospecul write_rs in
637-
let eiid,branch = branch a eiid in
638-
let (),cl_br,es_br = Evt.as_singleton_nospecul branch in
639-
let eiid,nem = rne ov cv eiid in
640-
let (),cl_ne,eseq = Evt.as_singleton_nospecul nem in
641-
assert (E.is_empty_event_structure eseq) ;
642-
let es =
643-
E.aarch64_cas_ok is_physical `DataFromRx es_rn es_rs E.empty_event_structure es_wrs es_rm es_wm es_br in
644-
let cls = cl_a@cl_cv@cl_rm@cl_wm@cl_wrs@cl_br@cl_ne in
645-
eiid,Evt.add ((),cls,es) acts)
646-
acts_rn (eiid,Evt.empty) in
647-
eiid,(acts, None)
648-
649580
(* AArch64 successful cas *)
650581
let do_aarch64_cas_ok
651582
(is_physical:bool) (prov_data: [`DataFromRRs | `DataFromRx])
@@ -677,7 +608,7 @@ Monad type:
677608
let (),cl_eq,eseq = Evt.as_singleton_nospecul eqm in
678609
assert (E.is_empty_event_structure eseq) ;
679610
let es =
680-
E.aarch64_cas_ok is_physical prov_data es_rn es_rs es_rt es_wrs es_rm es_wm es_br in
611+
E.aarch64_cas is_physical prov_data es_rn es_rs es_rt es_wrs es_rm es_wm es_br in
681612
let cls = cl_a@cl_cv@cl_nv@cl_rm@cl_wm@cl_wrs@cl_br@cl_eq in
682613
eiid,Evt.add ((),cls,es) acts)
683614
acts_rn (eiid,Evt.empty) in
@@ -737,20 +668,35 @@ Monad type:
737668
in
738669
altT (do_ `DataFromRRs) (do_ `DataFromRx)
739670

740-
let aarch64_cas_no (is_physical:bool) (read_rn:'loc t) (read_rs:'v t)
741-
(write_rs:'v-> unit t) (read_mem: 'loc -> 'v t) (branch: 'loc -> unit t)
742-
(rne: 'v -> 'v -> unit t) =
743-
let do_ add_ctrl =
744-
do_aarch64_cas_no is_physical add_ctrl read_rn read_rs write_rs
745-
read_mem branch rne
746-
in
747-
altT (do_ true) (do_ false)
748-
749-
let aarch64_cas_no_with_writeback (is_physical: bool) (read_rn: 'loc t)
671+
let aarch64_cas_no (is_physical: bool) (read_rn: 'loc t)
750672
(read_rs: 'v t) (write_rs: 'v -> unit t) (read_mem: 'loc -> 'v t)
751-
(write_mem: 'loc -> 'v -> unit t) (branch: 'loc -> unit t) (rne: 'v -> 'v -> unit t) =
752-
do_aarch64_cas_no_with_writeback is_physical read_rn read_rs
753-
write_rs read_mem write_mem branch rne
673+
(write_mem: 'loc -> 'v -> unit t) (branch: 'loc -> unit t) (rne: 'v -> 'v -> unit t)
674+
eiid =
675+
let eiid,read_rn = read_rn eiid in
676+
let eiid,read_rs = read_rs eiid in
677+
let cv,cl_cv,es_rs = Evt.as_singleton_nospecul read_rs in
678+
let acts_rn,spec = read_rn in
679+
assert (Misc.is_none spec) ;
680+
let eiid,acts =
681+
Evt.fold
682+
(fun (a,cl_a,es_rn) (eiid,acts) ->
683+
let eiid,read_mem = read_mem a eiid in
684+
let ov,cl_rm,es_rm = Evt.as_singleton_nospecul read_mem in
685+
let eiid,write_mem = write_mem a ov eiid in
686+
let (),cl_wm,es_wm= Evt.as_singleton_nospecul write_mem in
687+
let eiid,write_rs = write_rs ov eiid in
688+
let (),cl_wrs,es_wrs = Evt.as_singleton_nospecul write_rs in
689+
let eiid,branch = branch a eiid in
690+
let (),cl_br,es_br = Evt.as_singleton_nospecul branch in
691+
let eiid,nem = rne ov cv eiid in
692+
let (),cl_ne,eseq = Evt.as_singleton_nospecul nem in
693+
assert (E.is_empty_event_structure eseq) ;
694+
let es =
695+
E.aarch64_cas is_physical `No es_rn es_rs E.empty_event_structure es_wrs es_rm es_wm es_br in
696+
let cls = cl_a@cl_cv@cl_rm@cl_wm@cl_wrs@cl_br@cl_ne in
697+
eiid,Evt.add ((),cls,es) acts)
698+
acts_rn (eiid,Evt.empty) in
699+
eiid,(acts, None)
754700

755701
(* RISCV store conditional may always succeed? *)
756702
let riscv_store_conditional = aarch64_or_riscv_store_conditional false

0 commit comments

Comments
 (0)