Library zoo_saturn.mpmc_bqueue__code
From zoo Require Import
prelude.
From zoo.language Require Import
typeclasses
notations.
From zoo_std Require Import
domain.
From zoo_saturn Require Import
mpmc_bqueue__types.
From zoo Require Import
options.
Definition mpmc_bqueue٠create : val :=
fun: "cap" ⇒
let: "front" := ‘Node{ §Null, (), 0, "cap" } in
{ "cap", "front", "front" }.
Definition mpmc_bqueue٠capacity : val :=
fun: "t" ⇒
"t".{capacity}.
Definition mpmc_bqueue٠size : val :=
rec: "size" "t" ⇒
match: "t".{front} with
| Node ≠ ≠ ≠ ≠ as "front" ⇒
let: "front_r" := "front" in
let: "proph" := Proph in
match: "t".{back} with
| Node ≠ ≠ ≠ ≠ as "back" ⇒
let: "back_r" := "back" in
match: "back_r".{next} with
| Node ≠ ≠ ≠ ≠ as "node" ⇒
CAS "t".[back] "back" "node" ;;
"size" "t"
| Null ⇒
if: Resolve "t".{front} "proph" () == "front" then (
"back_r".{index} - "front_r".{index}
) else (
"size" "t"
)
end
end
end.
Definition mpmc_bqueue٠is_empty : val :=
fun: "t" ⇒
match: "t".{front} with
| Node ≠ ≠ ≠ ≠ as "front_r" ⇒
"front_r".{next} == §Null
end.
Definition mpmc_bqueue٠fix_back : val :=
rec: "fix_back" "t" "back" "new_back" ⇒
match: "new_back" with
| Node ≠ ≠ ≠ ≠ as "new_back_r" ⇒
if:
"new_back_r".{next} == §Null
and
¬ CAS "t".[back] "back" "new_back"
then (
domain٠yield () ;;
"fix_back" "t" "t".{back} "new_back"
)
end.
#[local] Definition __zoo_recs_0 :=
( recs: "push_1" "t" "back" "cap" "new_back" ⇒
match: "back" with
| Node ≠ ≠ ≠ ≠ as "back_r" ⇒
match: "new_back" with
| Node ≠ ≠ ≠ ≠ as "new_back" ⇒
let: "new_back_r" := "new_back" in
if: "cap" == 0 then (
match: "t".{front} with
| Node ≠ ≠ ≠ ≠ as "front_r" ⇒
let: "cap" :=
"t".{capacity} - ("back_r".{index} - "front_r".{index})
in
if: "cap" == 0 then (
false
) else (
"back_r" <-{estimated_capacity} "cap" ;;
"push_1" "t" "back" "cap" "new_back"
)
end
) else (
"new_back_r" <-{index} "back_r".{index} + 1 ;;
"new_back_r" <-{estimated_capacity} "cap" - 1 ;;
if: CAS "back_r".[next] §Null "new_back" then (
mpmc_bqueue٠fix_back "t" "back" "new_back" ;;
true
) else (
match: "back_r".{next} with
| Null ⇒
Fail
| Node ≠ ≠ ≠ ≠ as "back" ⇒
"push_2" "t" "back" "new_back"
end
)
)
end
end
and: "push_2" "t" "back" "new_back" ⇒
match: "back" with
| Node ≠ ≠ ≠ ≠ as "back" ⇒
let: "back_r" := "back" in
"push_1" "t" "back" "back_r".{estimated_capacity} "new_back"
end
)%zoo_recs.
Definition mpmc_bqueue٠push_1 :=
ValRecs 0 __zoo_recs_0.
Definition mpmc_bqueue٠push_2 :=
ValRecs 1 __zoo_recs_0.
#[global] Instance :
AsValRecs' mpmc_bqueue٠push_1 0 __zoo_recs_0 [
mpmc_bqueue٠push_1 ;
mpmc_bqueue٠push_2
].
#[global] Instance :
AsValRecs' mpmc_bqueue٠push_2 1 __zoo_recs_0 [
mpmc_bqueue٠push_1 ;
mpmc_bqueue٠push_2
].
Definition mpmc_bqueue٠push : val :=
fun: "t" "v" ⇒
let: "new_back" := ‘Node{ §Null, "v", 0, 0 } in
mpmc_bqueue٠push_2 "t" "t".{back} "new_back".
Definition mpmc_bqueue٠pop : val :=
rec: "pop" "t" ⇒
match: "t".{front} with
| Node ≠ ≠ ≠ ≠ as "front" ⇒
let: "front_r" := "front" in
match: "front_r".{next} with
| Null ⇒
§None
| Node ≠ ≠ ≠ ≠ as "new_front" ⇒
let: "new_front_r" := "new_front" in
if: CAS "t".[front] "front" "new_front" then (
let: "v" := "new_front_r".{data} in
"new_front_r" <-{data} () ;;
‘Some( "v" )
) else (
domain٠yield () ;;
"pop" "t"
)
end
end.
prelude.
From zoo.language Require Import
typeclasses
notations.
From zoo_std Require Import
domain.
From zoo_saturn Require Import
mpmc_bqueue__types.
From zoo Require Import
options.
Definition mpmc_bqueue٠create : val :=
fun: "cap" ⇒
let: "front" := ‘Node{ §Null, (), 0, "cap" } in
{ "cap", "front", "front" }.
Definition mpmc_bqueue٠capacity : val :=
fun: "t" ⇒
"t".{capacity}.
Definition mpmc_bqueue٠size : val :=
rec: "size" "t" ⇒
match: "t".{front} with
| Node ≠ ≠ ≠ ≠ as "front" ⇒
let: "front_r" := "front" in
let: "proph" := Proph in
match: "t".{back} with
| Node ≠ ≠ ≠ ≠ as "back" ⇒
let: "back_r" := "back" in
match: "back_r".{next} with
| Node ≠ ≠ ≠ ≠ as "node" ⇒
CAS "t".[back] "back" "node" ;;
"size" "t"
| Null ⇒
if: Resolve "t".{front} "proph" () == "front" then (
"back_r".{index} - "front_r".{index}
) else (
"size" "t"
)
end
end
end.
Definition mpmc_bqueue٠is_empty : val :=
fun: "t" ⇒
match: "t".{front} with
| Node ≠ ≠ ≠ ≠ as "front_r" ⇒
"front_r".{next} == §Null
end.
Definition mpmc_bqueue٠fix_back : val :=
rec: "fix_back" "t" "back" "new_back" ⇒
match: "new_back" with
| Node ≠ ≠ ≠ ≠ as "new_back_r" ⇒
if:
"new_back_r".{next} == §Null
and
¬ CAS "t".[back] "back" "new_back"
then (
domain٠yield () ;;
"fix_back" "t" "t".{back} "new_back"
)
end.
#[local] Definition __zoo_recs_0 :=
( recs: "push_1" "t" "back" "cap" "new_back" ⇒
match: "back" with
| Node ≠ ≠ ≠ ≠ as "back_r" ⇒
match: "new_back" with
| Node ≠ ≠ ≠ ≠ as "new_back" ⇒
let: "new_back_r" := "new_back" in
if: "cap" == 0 then (
match: "t".{front} with
| Node ≠ ≠ ≠ ≠ as "front_r" ⇒
let: "cap" :=
"t".{capacity} - ("back_r".{index} - "front_r".{index})
in
if: "cap" == 0 then (
false
) else (
"back_r" <-{estimated_capacity} "cap" ;;
"push_1" "t" "back" "cap" "new_back"
)
end
) else (
"new_back_r" <-{index} "back_r".{index} + 1 ;;
"new_back_r" <-{estimated_capacity} "cap" - 1 ;;
if: CAS "back_r".[next] §Null "new_back" then (
mpmc_bqueue٠fix_back "t" "back" "new_back" ;;
true
) else (
match: "back_r".{next} with
| Null ⇒
Fail
| Node ≠ ≠ ≠ ≠ as "back" ⇒
"push_2" "t" "back" "new_back"
end
)
)
end
end
and: "push_2" "t" "back" "new_back" ⇒
match: "back" with
| Node ≠ ≠ ≠ ≠ as "back" ⇒
let: "back_r" := "back" in
"push_1" "t" "back" "back_r".{estimated_capacity} "new_back"
end
)%zoo_recs.
Definition mpmc_bqueue٠push_1 :=
ValRecs 0 __zoo_recs_0.
Definition mpmc_bqueue٠push_2 :=
ValRecs 1 __zoo_recs_0.
#[global] Instance :
AsValRecs' mpmc_bqueue٠push_1 0 __zoo_recs_0 [
mpmc_bqueue٠push_1 ;
mpmc_bqueue٠push_2
].
#[global] Instance :
AsValRecs' mpmc_bqueue٠push_2 1 __zoo_recs_0 [
mpmc_bqueue٠push_1 ;
mpmc_bqueue٠push_2
].
Definition mpmc_bqueue٠push : val :=
fun: "t" "v" ⇒
let: "new_back" := ‘Node{ §Null, "v", 0, 0 } in
mpmc_bqueue٠push_2 "t" "t".{back} "new_back".
Definition mpmc_bqueue٠pop : val :=
rec: "pop" "t" ⇒
match: "t".{front} with
| Node ≠ ≠ ≠ ≠ as "front" ⇒
let: "front_r" := "front" in
match: "front_r".{next} with
| Null ⇒
§None
| Node ≠ ≠ ≠ ≠ as "new_front" ⇒
let: "new_front_r" := "new_front" in
if: CAS "t".[front] "front" "new_front" then (
let: "v" := "new_front_r".{data} in
"new_front_r" <-{data} () ;;
‘Some( "v" )
) else (
domain٠yield () ;;
"pop" "t"
)
end
end.