Skip to content

Commit 73e82a9

Browse files
committed
Simplify promise-first code
- Apply code reviews Apply code reviews
1 parent 6df8afa commit 73e82a9

File tree

5 files changed

+108
-345
lines changed

5 files changed

+108
-345
lines changed

ArchSem/GenPromising.v

Lines changed: 27 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,7 @@ Module GenPromising (IWA : InterfaceWithArch) (TM : TermModelsT IWA).
375375
promise ← mchoosel (enum bool);
376376
if (promise : bool) then cpromise_tid fuel tid else run_tid isem prom tid.
377377

378-
(** Computational evaluate all the possible allowed final states according
378+
(** Computationally evaluate all the possible allowed final states according
379379
to the promising model prom starting from st *)
380380
Fixpoint run (fuel : nat) : Exec.t t string final :=
381381
st ← mGet;
@@ -386,54 +386,41 @@ Module GenPromising (IWA : InterfaceWithArch) (TM : TermModelsT IWA).
386386
run fuel
387387
else mthrow "Could not finish running within the size of the fuel".
388388

389-
(** Explore all possible promise-based executions across all threads. *)
390-
Fixpoint prune_promises_and_states (fuel_per_tid fuel : nat)
391-
(finals : list final) : Exec.t t string (list final) :=
389+
(** Computationally evaluate all the possible allowed final states according
390+
to the promising model prom starting from st with promise-first optimization.
391+
The size of fuel should be at least (# of promises) + max(# of instructions) + 1 *)
392+
Fixpoint run_promise_first (fuel : nat) : Exec.t t string final :=
392393
if fuel is S fuel then
393394
st ← mGet;
394395
(* Find out next possible promises or terminating states at the current thread *)
395396
executions ←
396-
for (tid : fin n) in enum (fin n) do
397+
vmapM (λ '(tid, ts),
397398
'(promises_per_tid, tstates_per_tid) ←
398399
mlift $ prom.(enumerate_promises_and_terminal_states)
399-
fuel_per_tid tid (term tid) (initmem st) (tstate tid st) (events st);
400-
mret (map (λ ev, (ev, tid)) promises_per_tid, tstates_per_tid)
401-
end;
402-
403-
(* Compute cartesian products of the possible thread states *)
404-
let tstates_sys :=
405-
fold_left (λ partial_sts tstates_tid,
406-
List.flat_map (λ tstate,
407-
if is_emptyb partial_sts then [[tstate]]
408-
else map (λ partial_st, partial_st ++ [tstate]) partial_sts
409-
) tstates_tid
410-
) (map snd executions) [] in
411-
let new_finals :=
412-
omap (λ tstates,
413-
if (list_to_vec_n n tstates) is Some tstates_vec then
414-
let st := Make tstates_vec st.(PState.initmem) st.(PState.events) in
415-
if decide $ terminated prom term st is left pt
416-
then Some (make_final st pt)
417-
else None
418-
else None
419-
) tstates_sys in
400+
fuel (fin_to_nat tid) (term tid) (initmem st) ts (events st);
401+
mret (map (.,tid) promises_per_tid, tstates_per_tid)
402+
) (venumerate (tstates st));
420403

421-
(* Non-deterministically choose the next promise and the tid for pruning *)
422-
let promises_all := List.concat (map fst executions) in
423-
if is_emptyb promises_all then
424-
mret (new_finals ++ finals)
425-
else
404+
promise ← mchoosel (enum bool);
405+
if (promise : bool) then
406+
(* Non-deterministically choose the next promise and the tid for pruning *)
407+
let promises_all := List.concat (vmap fst executions) in
426408
'(next_ev, tid) ← mchoosel promises_all;
427409
mSet (λ st, promise_tid prom st tid next_ev);;
428-
prune_promises_and_states fuel_per_tid fuel (new_finals ++ finals)
429-
else mret finals.
430-
431-
(** Computational evaluate all the possible allowed final states according
432-
to the promising model prom starting from st
433-
with promise-first optimization *)
434-
Definition run_promise_first (fuel : nat) : Exec.t t string final :=
435-
finals ← prune_promises_and_states fuel fuel [];
436-
mchoosel finals.
410+
run_promise_first fuel
411+
else
412+
(* Compute cartesian products of the possible thread states *)
413+
let tstates_all := cprodn (vmap snd executions) in
414+
let new_finals :=
415+
omap (λ tstates,
416+
let st := Make tstates st.(PState.initmem) st.(PState.events) in
417+
if decide $ terminated prom term st is left pt
418+
then Some (make_final st pt)
419+
else None
420+
) tstates_all in
421+
mchoosel new_finals
422+
else
423+
mthrow "Could not finish running within the size of the fuel".
437424

438425
End CPS.
439426
Arguments to_final_archState {_ _ _}.
@@ -442,25 +429,12 @@ Module GenPromising (IWA : InterfaceWithArch) (TM : TermModelsT IWA).
442429
(** Create a computational model from an ISA model and promising model *)
443430
Definition Promising_to_Modelc (isem : iMon ()) (prom : BasicExecutablePM)
444431
(fuel : nat) : archModel.c ∅ :=
445-
λ n term (initMs : archState n),
446-
PState.from_archState prom initMs |>
447-
archModel.Res.from_exec
448-
$ CPState.to_final_archState
449-
<$> CPState.run isem prom term fuel.
450-
451-
(** Create a computational model from an ISA model and promising model
452-
with promise-free optimization *)
453-
Definition Promising_to_Modelc_pf (isem : iMon ()) (prom : BasicExecutablePM)
454-
(fuel : nat) : archModel.c ∅ :=
455432
λ n term (initMs : archState n),
456433
PState.from_archState prom initMs |>
457434
archModel.Res.from_exec
458435
$ CPState.to_final_archState
459436
<$> CPState.run_promise_first prom term fuel.
460437

461-
(* TODO state some soundness lemma between Promising_to_Modelnc and
462-
Promising_Modelc *)
463-
464438
End GenPromising.
465439

466440
Module Type GenPromisingT (IWA : InterfaceWithArch) (TM : TermModelsT IWA).

ArchSemArm/UMPromising.v

Lines changed: 35 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -452,18 +452,16 @@ Definition read_mem4 (addr : address) (macc : mem_acc) (init : Memory.initial) :
452452
This may mutate memory if no existing promise can be fullfilled *)
453453
Definition write_mem (tid : nat) (loc : Loc.t) (vdata : view)
454454
(macc : mem_acc) (mem : Memory.t)
455-
(data : val) (mem_update : bool) :
455+
(data : val) :
456456
Exec.t TState.t string (Memory.t * view * option view):=
457457
let msg := Msg.make tid loc data in
458458
let is_release := is_rel_acq macc in
459459
ts ← mGet;
460-
'(time, mem, new_promise)
460+
let '(time, mem, new_promise) :=
461461
match Memory.fulfill msg (TState.prom ts) mem with
462-
| Some t => mret (t, mem, false)
463-
| None =>
464-
if mem_update then mret (Memory.promise msg mem, true)
465-
else mdiscard
466-
end;
462+
| Some t => (t, mem, false)
463+
| None => (Memory.promise msg mem, true)
464+
end in
467465
let vbob :=
468466
ts.(TState.vdmbst) ⊔ ts.(TState.vdmb) ⊔ ts.(TState.visb) ⊔ ts.(TState.vacq)
469467
⊔ view_if is_release (ts.(TState.vrd) ⊔ ts.(TState.vwr)) in
@@ -473,10 +471,8 @@ Definition write_mem (tid : nat) (loc : Loc.t) (vdata : view)
473471
mSet $ TState.update_coh loc time;;
474472
mSet $ TState.update TState.vwr time;;
475473
mSet $ TState.update TState.vrel (view_if is_release time);;
476-
mret $ match new_promise with
477-
| true => (mem, time, Some vpre)
478-
| false => (mem, time, None)
479-
end.
474+
mret (mem, time, (if new_promise then Some vpre else None)).
475+
480476

481477
(** Tries to perform a memory write.
482478
@@ -487,12 +483,12 @@ Definition write_mem (tid : nat) (loc : Loc.t) (vdata : view)
487483
return value indicate the success (true for success, false for error) *)
488484
Definition write_mem_xcl (tid : nat) (loc : Loc.t)
489485
(vdata : view) (macc : mem_acc)
490-
(mem : Memory.t) (data : val) (mem_update : bool)
486+
(mem : Memory.t) (data : val)
491487
: Exec.t TState.t string (Memory.t * option view) :=
492488
guard_or "Atomic RMW unsupported" (¬ (is_atomic_rmw macc));;
493489
let xcl := is_exclusive macc in
494490
if xcl then
495-
'(mem, time, vpre_opt) ← write_mem tid loc vdata macc mem data mem_update;
491+
'(mem, time, vpre_opt) ← write_mem tid loc vdata macc mem data;
496492
ts ← mGet;
497493
match TState.xclb ts with
498494
| None => mdiscard
@@ -503,7 +499,7 @@ Definition write_mem_xcl (tid : nat) (loc : Loc.t)
503499
mSet TState.clear_xclb;;
504500
mret (mem, vpre_opt)
505501
else
506-
'(mem, time, vpre_opt) ← write_mem tid loc vdata macc mem data mem_update;
502+
'(mem, time, vpre_opt) ← write_mem tid loc vdata macc mem data;
507503
mSet $ TState.set_fwdb loc (FwdItem.make time vdata false);;
508504
mret (mem, vpre_opt).
509505

@@ -533,9 +529,9 @@ End IIS.
533529
Section RunOutcome.
534530
Context (tid : nat) (initmem : memoryMap).
535531

536-
Equations run_outcome (out : outcome) (mem_update : bool) :
532+
Equations run_outcome (out : outcome) :
537533
Exec.t (PPState.t TState.t Msg.t IIS.t) string (eff_ret out * option view) :=
538-
| RegWrite reg racc val, mem_update =>
534+
| RegWrite reg racc val =>
539535
guard_or "Non trivial reg access types unsupported" (racc = None);;
540536
vreg ← mget (IIS.strict ∘ PPState.iis);
541537
vreg' ←
@@ -549,14 +545,14 @@ Section RunOutcome.
549545
TState.set_reg reg (val, vreg') ts;
550546
msetv PPState.state nts;;
551547
mret ((), None)
552-
| RegRead reg racc, mem_update =>
548+
| RegRead reg racc =>
553549
guard_or "Non trivial reg access types unsupported" (racc = None);;
554550
ts ← mget PPState.state;
555551
'(val, view) ← othrow "Register isn't mapped can't read" $
556552
dmap_lookup reg ts.(TState.regs);
557553
mset PPState.iis $ IIS.add view;;
558554
mret (val, None)
559-
| MemRead (MemReq.make macc addr addr_space 8 0), mem_update =>
555+
| MemRead (MemReq.make macc addr addr_space 8 0) =>
560556
guard_or "Access outside Non-Secure" (addr_space = PAS_NonSecure);;
561557
loc ← othrow "PA not supported" $ Loc.from_addr addr;
562558
if is_ifetch macc then
@@ -570,28 +566,28 @@ Section RunOutcome.
570566
mset PPState.iis $ IIS.add view;;
571567
mret (Ok (val, bv_0 0), None)
572568
else mthrow "Read is not explicit or ifetch"
573-
| MemRead (MemReq.make macc addr addr_space 4 0), mem_update => (* ifetch *)
569+
| MemRead (MemReq.make macc addr addr_space 4 0) => (* ifetch *)
574570
guard_or "Access outside Non-Secure" (addr_space = PAS_NonSecure);;
575571
let initmem := Memory.initial_from_memMap initmem in
576572
opcode ← Exec.liftSt PPState.mem $ read_mem4 addr macc initmem;
577573
mret (Ok (opcode, 0%bv), None)
578-
| MemRead _, mem_update => mthrow "Memory read of size other than 8 and 4"
579-
| MemWriteAddrAnnounce _, mem_update =>
574+
| MemRead _ => mthrow "Memory read of size other than 8 and 4"
575+
| MemWriteAddrAnnounce _ =>
580576
vaddr ← mget (IIS.strict ∘ PPState.iis);
581577
mset PPState.state $ TState.update TState.vcap vaddr;;
582578
mret ((), None)
583-
| MemWrite (MemReq.make macc addr addr_space 8 0) val tags, mem_update =>
579+
| MemWrite (MemReq.make macc addr addr_space 8 0) val tags =>
584580
guard_or "Access outside Non-Secure" (addr_space = PAS_NonSecure);;
585581
addr ← othrow "PA not supported" $ Loc.from_addr addr;
586582
if is_explicit macc then
587583
mem ← mget PPState.mem;
588584
vdata ← mget (IIS.strict ∘ PPState.iis);
589585
'(mem, vpre_opt) ← Exec.liftSt PPState.state
590-
$ write_mem_xcl tid addr vdata macc mem val mem_update;
586+
$ write_mem_xcl tid addr vdata macc mem val;
591587
msetv PPState.mem mem;;
592588
mret (Ok (), vpre_opt)
593589
else mthrow "Unsupported non-explicit write"
594-
| Barrier (Barrier_DMB dmb), mem_update => (* dmb *)
590+
| Barrier (Barrier_DMB dmb) => (* dmb *)
595591
ts ← mget PPState.state;
596592
match dmb.(DxB_types) with
597593
| MBReqTypes_All (* dmb sy *) =>
@@ -602,16 +598,17 @@ Section RunOutcome.
602598
mset PPState.state $ TState.update TState.vdmbst ts.(TState.vwr)
603599
end;;
604600
mret ((), None)
605-
| Barrier (Barrier_ISB ()), mem_update => (* isb *)
601+
| Barrier (Barrier_ISB ()) => (* isb *)
606602
ts ← mget PPState.state;
607603
mset PPState.state $ TState.update TState.visb (TState.vcap ts);;
608604
mret ((), None)
609-
| GenericFail s, mem_update => mthrow ("Instruction failure: " ++ s)%string
610-
| _, _ => mthrow "Unsupported outcome".
605+
| GenericFail s => mthrow ("Instruction failure: " ++ s)%string
606+
| _ => mthrow "Unsupported outcome".
611607

612608
Definition run_outcome' (out : outcome) :
613609
Exec.t (PPState.t TState.t Msg.t IIS.t) string (eff_ret out) :=
614-
run_outcome out true |$> fst.
610+
run_outcome out |$> fst.
611+
615612
End RunOutcome.
616613

617614
Module CProm.
@@ -650,14 +647,17 @@ Section ComputeProm.
650647
(base : view)
651648
(out : outcome) :
652649
Exec.t (CProm.t * PPState.t TState.t Msg.t IIS.t) string (eff_ret out) :=
653-
'(res, vpre_opt) ← Exec.liftSt snd $ run_outcome tid initmem out true;
650+
'(res, vpre_opt) ← Exec.liftSt snd $ run_outcome tid initmem out;
654651
if vpre_opt is Some vpre then
655652
mem ← mget (PPState.mem ∘ snd);
656653
mset fst (CProm.add_if mem vpre base);;
657654
mret res
658655
else
659656
mret res.
660657

658+
(* Run the thread state until termination, collecting certified promises.
659+
Returns true if termination occurs within the given fuel,
660+
false otherwise. *)
661661
Fixpoint run_to_termination_promise
662662
(isem : iMon ())
663663
(fuel : nat)
@@ -677,43 +677,7 @@ Section ComputeProm.
677677
run_to_termination_promise isem fuel base
678678
end.
679679

680-
Definition run_to_termination (isem : iMon ())
681-
(fuel : nat)
682-
(ts : TState.t)
683-
(mem : Memory.t) :
684-
result string (list Msg.t * list TState.t) :=
685-
let base := List.length mem in
686-
let res := Exec.results $
687-
run_to_termination_promise isem fuel base (CProm.init, PPState.Make ts mem IIS.init) in
688-
guard_or ("Could not finish promises within the size of the fuel")%string
689-
(∀ r ∈ res, r.2 = true);;
690-
mret $ (CProm.proms (union_list res.*1.*1), []).
691-
692-
Definition run_outcome_with_no_promise
693-
(out : outcome) :
694-
Exec.t (PPState.t TState.t Msg.t IIS.t) string (eff_ret out) :=
695-
'(res, _) ← run_outcome tid initmem out false;
696-
mret res.
697-
698-
Fixpoint run_to_termination_no_promise
699-
(isem : iMon ())
700-
(fuel : nat) :
701-
Exec.t (PPState.t TState.t Msg.t IIS.t) string bool :=
702-
match fuel with
703-
| 0%nat =>
704-
ts ← mget PPState.state;
705-
mret (term (TState.reg_map ts))
706-
| S fuel =>
707-
let handler := run_outcome_with_no_promise in
708-
cinterp handler isem;;
709-
ts ← mget PPState.state;
710-
if term (TState.reg_map ts) then
711-
mret true
712-
else
713-
run_to_termination_no_promise isem fuel
714-
end.
715-
716-
Definition run_to_termination_pf (isem : iMon ())
680+
Definition run_to_termination (isem : iMon ())
717681
(fuel : nat)
718682
(ts : TState.t)
719683
(mem : Memory.t)
@@ -724,11 +688,11 @@ Section ComputeProm.
724688
guard_or ("Could not finish promises within the size of the fuel")%string
725689
(∀ r ∈ res_proms, r.2 = true);;
726690
let promises := res_proms.*1.*1 |> CProm.proms ∘ union_list in
727-
let res := Exec.results $
728-
run_to_termination_no_promise isem fuel (PPState.Make ts mem IIS.init) in
729-
guard_or ("Could not finish the remaining states within the size of the fuel")%string
730-
(∀ r ∈ res, r.2 = true);;
731-
let tstates := map PPState.state res.*1 in
691+
let tstates :=
692+
res_proms
693+
|> omap (λ '((cp, st), _),
694+
if is_emptyb (CProm.proms cp) then Some (PPState.state st)
695+
else None) in
732696
mret (promises, tstates).
733697

734698
End ComputeProm.
@@ -814,20 +778,5 @@ Next Obligation. Admitted.
814778
Next Obligation. Admitted.
815779
Next Obligation. Admitted.
816780

817-
Program Definition UMPromising_exe_pf' (isem : iMon ())
818-
: BasicExecutablePM :=
819-
{|pModel := UMPromising_cert' isem;
820-
enumerate_promises_and_terminal_states :=
821-
λ fuel tid term initmem ts mem,
822-
run_to_termination_pf tid initmem term isem fuel ts mem
823-
|}.
824-
Next Obligation. Admitted.
825-
Next Obligation. Admitted.
826-
Next Obligation. Admitted.
827-
Next Obligation. Admitted.
828-
829781
Definition UMPromising_cert_c isem fuel :=
830782
Promising_to_Modelc isem (UMPromising_exe' isem) fuel.
831-
832-
Definition UMPromising_cert_c_pf isem fuel :=
833-
Promising_to_Modelc_pf isem (UMPromising_exe_pf' isem) fuel.

0 commit comments

Comments
 (0)