1717
1818(* Michael-Scott queue *)
1919
20- type 'a node = Nil | Next of 'a * 'a node Atomic .t
21- type 'a t = { head : 'a node Atomic .t ; tail : 'a node Atomic .t Atomic .t }
20+ type 'a node = 'a * [ `Nil | `Node of 'a node ] Atomic .t
21+
22+ type 'a t = {
23+ head : [ `Node of 'a node ] Atomic .t ;
24+ tail : [ `Nil | `Node of 'a node ] Atomic .t Atomic .t ;
25+ }
2226
2327let create () =
24- let tail = Atomic. make Nil in
25- let head = Next (Obj. magic () , tail) in
28+ let tail = Atomic. make ` Nil in
29+ let head = `Node (Obj. magic () , tail) in
2630 { head = Atomic. make head; tail = Atomic. make tail }
2731
28- let is_empty q =
29- match Atomic. get q.head with
30- | Nil -> failwith " MSQueue.is_empty: impossible"
31- | Next (_ , x ) -> ( match Atomic. get x with Nil -> true | _ -> false )
32+ let is_empty { head; _ } =
33+ let (`Node (_, x)) = Atomic. get head in
34+ Atomic. get x == `Nil
3235
33- let pop q =
36+ let pop { head; _ } =
3437 let b = Backoff. create () in
3538 let rec loop () =
36- let s = Atomic. get q.head in
37- let nhead =
38- match s with
39- | Nil -> failwith " MSQueue.pop: impossible"
40- | Next (_ , x ) -> Atomic. get x
41- in
42- match nhead with
43- | Nil -> None
44- | Next (v, x) when Atomic. compare_and_set q.head s (Next (Obj. magic () , x))
45- ->
39+ let (`Node (_, x) as old_head ) = Atomic. get head in
40+ match Atomic. get x with
41+ | `Nil -> None
42+ | `Node (v, x)
43+ when Atomic. compare_and_set head old_head (`Node (Obj. magic () , x)) ->
4644 Some v
4745 | _ ->
4846 Backoff. once b;
4947 loop ()
5048 in
5149 loop ()
5250
53- let push q v =
51+ let push { tail; _ } v =
5452 let rec find_tail_and_enq curr_end node =
55- if Atomic. compare_and_set curr_end Nil node then ()
53+ if Atomic. compare_and_set curr_end ` Nil node then ()
5654 else
5755 match Atomic. get curr_end with
58- | Nil -> find_tail_and_enq curr_end node
59- | Next (_ , n ) -> find_tail_and_enq n node
56+ | ` Nil -> find_tail_and_enq curr_end node
57+ | `Node (_ , n ) -> find_tail_and_enq n node
6058 in
61- let new_tail = Atomic. make Nil in
62- let newnode = Next (v, new_tail) in
63- let old_tail = Atomic. get q. tail in
59+ let new_tail = Atomic. make ` Nil in
60+ let newnode = `Node (v, new_tail) in
61+ let old_tail = Atomic. get tail in
6462 find_tail_and_enq old_tail newnode;
65- ignore (Atomic. compare_and_set q. tail old_tail new_tail)
63+ ignore (Atomic. compare_and_set tail old_tail new_tail)
6664
67- let clean_until q f =
65+ let clean_until { head; _ } f =
6866 let b = Backoff. create () in
6967 let rec loop () =
70- let s = Atomic. get q.head in
71- let nhead =
72- match s with
73- | Nil -> failwith " MSQueue.pop: impossible"
74- | Next (_ , x ) -> Atomic. get x
75- in
76- match nhead with
77- | Nil -> ()
78- | Next (v , x ) ->
68+ let (`Node (_, x) as old_head ) = Atomic. get head in
69+ match Atomic. get x with
70+ | `Nil -> ()
71+ | `Node (v , x ) ->
7972 if not (f v) then
80- if Atomic. compare_and_set q. head s ( Next (Obj. magic () , x)) then (
73+ if Atomic. compare_and_set head old_head ( `Node (Obj. magic () , x)) then (
8174 Backoff. reset b;
8275 loop () )
8376 else (
@@ -87,11 +80,10 @@ let clean_until q f =
8780 in
8881 loop ()
8982
90- type 'a cursor = 'a node
83+ type 'a cursor = [ `Nil | `Node of 'a node ]
9184
92- let snapshot q =
93- match Atomic. get q.head with
94- | Nil -> failwith " MSQueue.snapshot: impossible"
95- | Next (_ , n ) -> Atomic. get n
85+ let snapshot { head; _ } =
86+ let (`Node (_, n)) = Atomic. get head in
87+ Atomic. get n
9688
97- let next c = match c with Nil -> None | Next (a , n ) -> Some (a, Atomic. get n)
89+ let next = function ` Nil -> None | `Node (a , n ) -> Some (a, Atomic. get n)
0 commit comments