1818
1919(* Michael-Scott queue *)
2020
21- type 'a node = Nil | Next of 'a * 'a node Atomic .t
22- type 'a t = { head : 'a node Atomic .t ; tail : 'a node Atomic .t Atomic .t }
21+ type 'a node = 'a * [ `Nil | `Node of 'a node ] Atomic .t
22+
23+ type 'a t = {
24+ head : [ `Node of 'a node ] Atomic .t ;
25+ tail : [ `Nil | `Node of 'a node ] Atomic .t Atomic .t ;
26+ }
2327
2428let create () =
25- let tail = Atomic. make Nil in
26- let head = Next (Obj. magic () , tail) in
29+ let tail = Atomic. make ` Nil in
30+ let head = `Node (Obj. magic () , tail) in
2731 { head = Atomic. make head; tail = Atomic. make tail }
2832
29- let is_empty q =
30- match Atomic. get q.head with
31- | Nil -> failwith " MSQueue.is_empty: impossible"
32- | Next (_ , x ) -> ( match Atomic. get x with Nil -> true | _ -> false )
33+ let is_empty { head; _ } =
34+ let (`Node (_, x)) = Atomic. get head in
35+ Atomic. get x == `Nil
3336
34- let pop q =
37+ let pop { head; _ } =
3538 let b = Backoff. create () in
3639 let rec loop () =
37- let s = Atomic. get q.head in
38- let nhead =
39- match s with
40- | Nil -> failwith " MSQueue.pop: impossible"
41- | Next (_ , x ) -> Atomic. get x
42- in
43- match nhead with
44- | Nil -> None
45- | Next (v, x) when Atomic. compare_and_set q.head s (Next (Obj. magic () , x))
46- ->
40+ let (`Node (_, x) as old_head ) = Atomic. get head in
41+ match Atomic. get x with
42+ | `Nil -> None
43+ | `Node (v, x)
44+ when Atomic. compare_and_set head old_head (`Node (Obj. magic () , x)) ->
4745 Some v
4846 | _ ->
4947 Backoff. once b;
5048 loop ()
5149 in
5250 loop ()
5351
54- let push q v =
52+ let push { tail; _ } v =
5553 let rec find_tail_and_enq curr_end node =
56- if Atomic. compare_and_set curr_end Nil node then ()
54+ if Atomic. compare_and_set curr_end ` Nil node then ()
5755 else
5856 match Atomic. get curr_end with
59- | Nil -> find_tail_and_enq curr_end node
60- | Next (_ , n ) -> find_tail_and_enq n node
57+ | ` Nil -> find_tail_and_enq curr_end node
58+ | `Node (_ , n ) -> find_tail_and_enq n node
6159 in
62- let new_tail = Atomic. make Nil in
63- let newnode = Next (v, new_tail) in
64- let old_tail = Atomic. get q. tail in
60+ let new_tail = Atomic. make ` Nil in
61+ let newnode = `Node (v, new_tail) in
62+ let old_tail = Atomic. get tail in
6563 find_tail_and_enq old_tail newnode;
66- ignore (Atomic. compare_and_set q. tail old_tail new_tail)
64+ ignore (Atomic. compare_and_set tail old_tail new_tail)
6765
68- let clean_until q f =
66+ let clean_until { head; _ } f =
6967 let b = Backoff. create () in
7068 let rec loop () =
71- let s = Atomic. get q.head in
72- let nhead =
73- match s with
74- | Nil -> failwith " MSQueue.pop: impossible"
75- | Next (_ , x ) -> Atomic. get x
76- in
77- match nhead with
78- | Nil -> ()
79- | Next (v , x ) ->
69+ let (`Node (_, x) as old_head ) = Atomic. get head in
70+ match Atomic. get x with
71+ | `Nil -> ()
72+ | `Node (v , x ) ->
8073 if not (f v) then
81- if Atomic. compare_and_set q. head s ( Next (Obj. magic () , x)) then (
74+ if Atomic. compare_and_set head old_head ( `Node (Obj. magic () , x)) then (
8275 Backoff. reset b;
8376 loop () )
8477 else (
@@ -88,11 +81,10 @@ let clean_until q f =
8881 in
8982 loop ()
9083
91- type 'a cursor = 'a node
84+ type 'a cursor = [ `Nil | `Node of 'a node ]
9285
93- let snapshot q =
94- match Atomic. get q.head with
95- | Nil -> failwith " MSQueue.snapshot: impossible"
96- | Next (_ , n ) -> Atomic. get n
86+ let snapshot { head; _ } =
87+ let (`Node (_, n)) = Atomic. get head in
88+ Atomic. get n
9789
98- let next c = match c with Nil -> None | Next (a , n ) -> Some (a, Atomic. get n)
90+ let next = function ` Nil -> None | `Node (a , n ) -> Some (a, Atomic. get n)
0 commit comments