@@ -125,64 +125,76 @@ module M : S = struct
125
125
let a = Atomic. get q.tab in
126
126
let size = b - t in
127
127
let a =
128
- if size = CArray. size a then (
128
+ if size = CArray. size a then begin
129
129
grow q t b;
130
- Atomic. get q.tab)
130
+ Atomic. get q.tab
131
+ end
131
132
else a
132
133
in
133
134
CArray. put a b v';
134
135
Atomic. set q.bottom (b + 1 )
135
136
136
- let [@ inline] release ptr =
137
+ type ('a, _) poly = Option : ('a , 'a option ) poly | Value : ('a , 'a ) poly
138
+
139
+ let [@ inline] release : type a r. a ref -> (a, r) poly -> r =
140
+ fun ptr poly ->
137
141
let res = ! ptr in
138
142
(* we know this ptr will never be dereferenced, but want to
139
143
break the reference to ensure that the contents of the
140
144
deque array get garbage collected *)
141
145
ptr := Obj. magic () ;
142
- res
146
+ match poly with Option -> Some res | Value -> res
143
147
144
- let pop q =
145
- if size q = 0 then raise Exit
148
+ let pop_as : type a r. a t -> (a, r) poly -> r =
149
+ fun q poly ->
150
+ if size q = 0 then match poly with Option -> None | Value -> raise Exit
146
151
else
147
152
let b = Atomic. get q.bottom - 1 in
148
153
Atomic. set q.bottom b;
149
154
let t = Atomic. get q.top in
150
155
let a = Atomic. get q.tab in
151
156
let size = b - t in
152
- if size < 0 then (
157
+ if size < 0 then begin
153
158
(* empty queue *)
154
159
Atomic. set q.bottom (b + 1 );
155
- raise Exit )
160
+ match poly with Option -> None | Value -> raise Exit
161
+ end
156
162
else
157
163
let out = CArray. get a b in
158
164
if b = t then
159
165
(* single last element *)
160
- if Atomic. compare_and_set q.top t (t + 1 ) then (
166
+ if Atomic. compare_and_set q.top t (t + 1 ) then begin
161
167
Atomic. set q.bottom (b + 1 );
162
- release out)
163
- else (
168
+ release out poly
169
+ end
170
+ else begin
164
171
Atomic. set q.bottom (b + 1 );
165
- raise Exit )
166
- else (
172
+ match poly with Option -> None | Value -> raise Exit
173
+ end
174
+ else begin
167
175
(* non-empty queue *)
168
- if q.next_shrink > size then (
176
+ if q.next_shrink > size then begin
169
177
Atomic. set q.tab (CArray. shrink a t b);
170
- set_next_shrink q);
171
- release out)
178
+ set_next_shrink q
179
+ end ;
180
+ release out poly
181
+ end
172
182
173
- let pop_opt q = try Some (pop q) with Exit -> None
183
+ let pop q = pop_as q Value
184
+ let pop_opt q = pop_as q Option
174
185
175
- let rec steal backoff q =
186
+ let rec steal_as : type a r. a t -> Backoff.t -> (a, r) poly -> r =
187
+ fun q backoff poly ->
176
188
let t = Atomic. get q.top in
177
189
let b = Atomic. get q.bottom in
178
190
let size = b - t in
179
- if size < = 0 then raise Exit
191
+ if size < = 0 then match poly with Option -> None | Value -> raise Exit
180
192
else
181
193
let a = Atomic. get q.tab in
182
194
let out = CArray. get a t in
183
- if Atomic. compare_and_set q.top t (t + 1 ) then release out
184
- else steal (Backoff. once backoff) q
195
+ if Atomic. compare_and_set q.top t (t + 1 ) then release out poly
196
+ else steal_as q (Backoff. once backoff) poly
185
197
186
- let steal q = steal Backoff. default q
187
- let steal_opt q = try Some (steal q) with Exit -> None
198
+ let steal q = steal_as q Backoff. default Value
199
+ let steal_opt q = steal_as q Backoff. default Option
188
200
end
0 commit comments