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;
@@ -54,40 +52,35 @@ let pop q =
5452let rec fix_tail tail old_tail new_tail =
5553 if Atomic. compare_and_set tail old_tail new_tail then
5654 match Atomic. get new_tail with
57- | Nil -> ()
58- | Next (_ , new_new_tail ) -> fix_tail tail new_tail new_new_tail
55+ | ` Nil -> ()
56+ | `Node (_ , new_new_tail ) -> fix_tail tail new_tail new_new_tail
5957
60- let push q v =
58+ let push { tail; _ } v =
6159 let rec find_tail_and_enq curr_end node =
62- if Atomic. compare_and_set curr_end Nil node then ()
60+ if Atomic. compare_and_set curr_end ` Nil node then ()
6361 else
6462 match Atomic. get curr_end with
65- | Nil -> find_tail_and_enq curr_end node
66- | Next (_ , n ) -> find_tail_and_enq n node
63+ | ` Nil -> find_tail_and_enq curr_end node
64+ | `Node (_ , n ) -> find_tail_and_enq n node
6765 in
68- let new_tail = Atomic. make Nil in
69- let newnode = Next (v, new_tail) in
70- let old_tail = Atomic. get q. tail in
66+ let new_tail = Atomic. make ` Nil in
67+ let newnode = `Node (v, new_tail) in
68+ let old_tail = Atomic. get tail in
7169 find_tail_and_enq old_tail newnode;
72- if Atomic. compare_and_set q. tail old_tail new_tail then
70+ if Atomic. compare_and_set tail old_tail new_tail then
7371 match Atomic. get new_tail with
74- | Nil -> ()
75- | Next (_ , new_new_tail ) -> fix_tail q. tail new_tail new_new_tail
72+ | ` Nil -> ()
73+ | `Node (_ , new_new_tail ) -> fix_tail tail new_tail new_new_tail
7674
77- let clean_until q f =
75+ let clean_until { head; _ } f =
7876 let b = Backoff. create () in
7977 let rec loop () =
80- let s = Atomic. get q.head in
81- let nhead =
82- match s with
83- | Nil -> failwith " MSQueue.pop: impossible"
84- | Next (_ , x ) -> Atomic. get x
85- in
86- match nhead with
87- | Nil -> ()
88- | Next (v , x ) ->
78+ let (`Node (_, x) as old_head ) = Atomic. get head in
79+ match Atomic. get x with
80+ | `Nil -> ()
81+ | `Node (v , x ) ->
8982 if not (f v) then
90- if Atomic. compare_and_set q. head s ( Next (Obj. magic () , x)) then (
83+ if Atomic. compare_and_set head old_head ( `Node (Obj. magic () , x)) then (
9184 Backoff. reset b;
9285 loop () )
9386 else (
@@ -97,11 +90,10 @@ let clean_until q f =
9790 in
9891 loop ()
9992
100- type 'a cursor = 'a node
93+ type 'a cursor = [ `Nil | `Node of 'a node ]
10194
102- let snapshot q =
103- match Atomic. get q.head with
104- | Nil -> failwith " MSQueue.snapshot: impossible"
105- | Next (_ , n ) -> Atomic. get n
95+ let snapshot { head; _ } =
96+ let (`Node (_, n)) = Atomic. get head in
97+ Atomic. get n
10698
107- let next c = match c with Nil -> None | Next (a , n ) -> Some (a, Atomic. get n)
99+ let next = function ` Nil -> None | `Node (a , n ) -> Some (a, Atomic. get n)
0 commit comments