-
Notifications
You must be signed in to change notification settings - Fork 1
/
code_split.v
66 lines (60 loc) · 2.23 KB
/
code_split.v
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
From gpfsl.lang Require Import notation.
From gpfsl.logic Require Import new_delete.
Notation hole := 0 (only parsing).
Notation data := 1 (only parsing).
Notation NULL := 0 (only parsing).
Notation MATCHING := (-1) (only parsing).
Notation CANCELLED := (-1) (only parsing).
Notation CANCELLEDval := (-2) (only parsing).
(* Fine-grained version of exchanger in [gpfsl-examples/exchanger/code.v] that splits [exchange] function into three parts *)
Definition new_exchanger : val :=
λ: [],
let: "ex" := new [ #1] in
"ex" <- #NULL ;; (* published offer, initially Null *)
"ex".
(* Registers a new offer in the exchanger *)
Definition new_offer : val :=
λ: ["ex"; "x"],
(* prepare an offer called mine *)
let: "mine" := new [ #2] in
"mine" +ₗ #hole <- #MATCHING;; (* hole *)
"mine" +ₗ #data <- "x";; (* data *)
(* try publishing mine as the main offer *)
if: casʳᵉˡ("ex", #NULL, "mine")
then "mine" (* successfully published mine as the main offer *)
else (
delete [ #2; "mine"] ;;
#NULL
).
(* After registering an offer, check whether the offer is taken by other thread *)
Definition check_offer : val :=
λ: ["ex"; "mine"],
if: casʳˡˣ("mine" +ₗ #hole, #MATCHING, #CANCELLEDval)
then (* no matched! Failed. We can reclaim data. But what about the hole? *)
#CANCELLED
else (
(* read the matched sub offer with acquire *)
!ᵃᶜ("mine" +ₗ #hole)
).
(* Try exchanging with existing offer *)
Definition take_offer : val :=
λ: ["ex"; "x"],
let: "other" := !ᵃᶜ"ex" in
if: "other" = #NULL
then ( (* something racy is going on, failed. *)
#CANCELLED
)
else (
(* try to match the main offer (other) with my offer [x] as the sub offer *)
let: "ok" := casʳᵉˡ("other" +ₗ #hole, #MATCHING, "x") in
(* clean up regardless of the result. If we fail here nothing wrong can happen. *)
casʳˡˣ("ex", "other", #NULL) ;;
if: "ok"
(* managed to match, can read the main offer (other) *)
then !("other" +ₗ #data) (* we can safely read because we used an acq
read on `"ex"` previously. *)
else (
(* fail to match *)
#CANCELLED
)
).