Skip to content

Commit 7f490cc

Browse files
committed
Without sticky bit
1 parent 221329f commit 7f490cc

File tree

1 file changed

+28
-33
lines changed

1 file changed

+28
-33
lines changed

lib/picos_std.sync/stack.ml

Lines changed: 28 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,55 @@
11
open Picos_std_awaitable
22

33
type 'a state =
4-
| Nil of { mutable capacity : int }
5-
| Cons of { mutable capacity : int; value : 'a; rest : 'a state }
4+
| Nil of { capacity : int }
5+
| Cons of { capacity : int; value : 'a; rest : 'a state }
6+
7+
let[@inline] capacity_of = function Nil r -> r.capacity | Cons r -> r.capacity
68

79
type 'a t = 'a state Awaitable.t
810

911
exception Empty
1012

11-
let busy_bit = 0b01
12-
let one = 0b10
13-
let max_capacity = Int.max_int / one
13+
let max_capacity = Int.max_int
1414

1515
let create ?padded ?capacity () =
1616
let capacity =
1717
match capacity with
18-
| None -> max_capacity * one
18+
| None -> max_capacity
1919
| Some capacity ->
2020
if capacity < 1 || max_capacity < capacity then invalid_arg "capacity"
21-
else capacity * one
21+
else capacity
2222
in
2323
Awaitable.make ?padded (Nil { capacity })
2424

25+
let rec push_await t value backoff =
26+
let before = Awaitable.get t in
27+
let capacity = capacity_of before - 1 in
28+
if 0 <= capacity then
29+
let after = Cons { capacity; value; rest = before } in
30+
if Awaitable.compare_and_set t before after then Awaitable.signal t
31+
else push_await t value (Backoff.once backoff)
32+
else begin
33+
Awaitable.await t before;
34+
push_await t value Backoff.default
35+
end
36+
2537
let rec push t value backoff =
26-
match Awaitable.get t with
27-
| Nil r as before ->
28-
let capacity = r.capacity land lnot busy_bit in
29-
if
30-
Awaitable.compare_and_set t before
31-
(Cons { capacity = capacity - one; value; rest = Nil { capacity } })
32-
then begin
33-
if r.capacity land busy_bit <> 0 then Awaitable.broadcast t
34-
end
35-
else push t value (Backoff.once backoff)
36-
| Cons r as before ->
37-
let capacity = r.capacity in
38-
if one <= capacity then begin
39-
if
40-
not
41-
(Awaitable.compare_and_set t before
42-
(Cons { capacity = capacity - one; value; rest = before }))
43-
then push t value (Backoff.once backoff)
44-
end
45-
else begin
46-
if capacity <> capacity lor busy_bit then
47-
r.capacity <- capacity lor busy_bit;
48-
Awaitable.await t before;
49-
push t value Backoff.default
50-
end
38+
let before = Awaitable.get t in
39+
let capacity = capacity_of before - 1 in
40+
if 0 <= capacity then
41+
let after = Cons { capacity; value; rest = before } in
42+
if Awaitable.compare_and_set t before after then
43+
match before with Nil _ -> Awaitable.signal t | Cons _ -> ()
44+
else push t value (Backoff.once backoff)
45+
else push_await t value backoff
5146

5247
let rec pop_exn t backoff =
5348
match Awaitable.get t with
5449
| Nil _ -> raise_notrace Empty
5550
| Cons r as before ->
5651
if Awaitable.compare_and_set t before r.rest then begin
57-
if r.capacity land busy_bit <> 0 then Awaitable.broadcast t;
52+
if r.capacity = 0 then Awaitable.signal t;
5853
r.value
5954
end
6055
else pop_exn t (Backoff.once backoff)

0 commit comments

Comments
 (0)