Skip to content

Commit

Permalink
Use more efficient ref implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
kayceesrk committed Dec 8, 2016
1 parent d9b28e4 commit 94ff96f
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 22 deletions.
5 changes: 5 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
all:
ocaml pkg/pkg.ml build --pinned false

clean:
rm -rf clean
2 changes: 1 addition & 1 deletion opam
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ depends: [
"ocamlfind" {build}
"ocamlbuild" {build}
"topkg" {build}
"kcas" {>= "0.1.2"}
"kcas" {>= "0.1.3"}
]
depopts: []
build: [
Expand Down
44 changes: 23 additions & 21 deletions src/lf_msqueue.ml
Original file line number Diff line number Diff line change
Expand Up @@ -36,67 +36,69 @@ end

module M : S = struct

module Cas = Kcas.W1

type 'a node =
| Nil
| Next of 'a * 'a node Kcas.ref
| Next of 'a * 'a node Cas.ref

type 'a t =
{ head : 'a node Kcas.ref ;
tail : 'a node Kcas.ref }
{ head : 'a node Cas.ref ;
tail : 'a node Cas.ref }

let create () =
let head = (Next (Obj.magic (), Kcas.ref Nil)) in
{ head = Kcas.ref head ; tail = Kcas.ref head }
let head = (Next (Obj.magic (), Cas.ref Nil)) in
{ head = Cas.ref head ; tail = Cas.ref head }

let is_empty q =
match Kcas.get q.head with
match Cas.get q.head with
| Nil -> failwith "MSQueue.is_empty: impossible"
| Next (_,x) ->
( match Kcas.get x with
( match Cas.get x with
| Nil -> true
| _ -> false )

let pop q =
let b = Kcas.Backoff.create () in
let rec loop () =
let s = Kcas.get q.head in
let s = Cas.get q.head in
let nhead = match s with
| Nil -> failwith "MSQueue.pop: impossible"
| Next (_, x) -> Kcas.get x
| Next (_, x) -> Cas.get x
in match nhead with
| Nil -> None
| Next (v, _) when Kcas.cas q.head s nhead -> Some v
| Next (v, _) when Cas.cas q.head s nhead -> Some v
| _ -> ( Kcas.Backoff.once b ; loop () )
in loop ()

let push q v =
let rec find_tail_and_enq curr_end node =
if Kcas.cas curr_end Nil node then ()
else match Kcas.get curr_end with
if Cas.cas curr_end Nil node then ()
else match Cas.get curr_end with
| Nil -> find_tail_and_enq curr_end node
| Next (_, n) -> find_tail_and_enq n node
in
let newnode = Next (v, Kcas.ref Nil) in
let tail = Kcas.get q.tail in
let newnode = Next (v, Cas.ref Nil) in
let tail = Cas.get q.tail in
match tail with
| Nil -> failwith "HW_MSQueue.push: impossible"
| Next (_, n) -> begin
find_tail_and_enq n newnode;
ignore (Kcas.cas q.tail tail newnode)
ignore (Cas.cas q.tail tail newnode)
end

let rec clean_until q f =
let b = Kcas.Backoff.create () in
let rec loop () =
let s = Kcas.get q.head in
let s = Cas.get q.head in
let nhead = match s with
| Nil -> failwith "MSQueue.pop: impossible"
| Next (_, x) -> Kcas.get x
| Next (_, x) -> Cas.get x
in match nhead with
| Nil -> ()
| Next (v, _) ->
if not (f v) then
if Kcas.cas q.head s nhead
if Cas.cas q.head s nhead
then (Kcas.Backoff.reset b; loop ())
else (Kcas.Backoff.once b; loop ())
else ()
Expand All @@ -105,13 +107,13 @@ module M : S = struct
type 'a cursor = 'a node

let snapshot q =
match Kcas.get q.head with
match Cas.get q.head with
| Nil -> failwith "MSQueue.snapshot: impossible"
| Next (_, n) -> Kcas.get n
| Next (_, n) -> Cas.get n

let next c =
match c with
| Nil -> None
| Next (a, n) -> Some (a, Kcas.get n)
| Next (a, n) -> Some (a, Cas.get n)

end

0 comments on commit 94ff96f

Please sign in to comment.