Skip to content

Commit 7b8f578

Browse files
committed
Complete redesign of the kcas library API
1 parent 3290886 commit 7b8f578

19 files changed

+884
-341
lines changed

CHANGES.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
All notable changes to this project will be documented in this file.
44

5+
## 0.2.0
6+
7+
* Complete redesign adding a new transaction API (@polytypic, review: @bartoszmodelski)
8+
59
## 0.1.8
610

711
* Fix a bug in GKMZ implementation (@polytypic, review: @bartoszmodelski)

LICENSE.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
Copyright (c) 2016, KC Sivaramakrishnan <kc@kcsrk.info>
22
Copyright (c) 2017, Nicolas ASSOUAD <nicolas.assouad@ens.fr>
33
Copyright (c) 2018, Sadiq Jaffer
4+
Copyright (c) 2023, Vesa Karvonen <vesa.a.j.k@gmail.com>
45

56
Permission to use, copy, modify, and/or distribute this software for any
67
purpose with or without fee is hereby granted, provided that the above

src/backoff.ml

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
* Copyright (c) 2015, Théo Laurent <theo.laurent@ens.fr>
33
* Copyright (c) 2015, KC Sivaramakrishnan <sk826@cl.cam.ac.uk>
44
* Copyright (c) 2021, Sudha Parimala <sudharg247@gmail.com>
5+
* Copyright (c) 2023, Vesa Karvonen <vesa.a.j.k@gmail.com>
56
*
67
* Permission to use, copy, modify, and/or distribute this software for any
78
* purpose with or without fee is hereby granted, provided that the above
@@ -16,28 +17,37 @@
1617
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1718
*)
1819

19-
module type S = sig
20-
type t
20+
type t = int
2121

22-
val create : ?max:int -> unit -> t
23-
val once : t -> unit
24-
val reset : t -> unit
25-
end
22+
let bits = 5
23+
let max_wait_log = 30 (* [Random.bits] returns 30 random bits. *)
24+
let mask = (1 lsl bits) - 1
2625

27-
module M : S = struct
28-
type t = int * int ref
26+
let create ?(lower_wait_log = 4) ?(upper_wait_log = 17) () =
27+
assert (
28+
0 <= lower_wait_log
29+
&& lower_wait_log <= upper_wait_log
30+
&& upper_wait_log <= max_wait_log);
31+
(upper_wait_log lsl (bits * 2))
32+
lor (lower_wait_log lsl bits) lor lower_wait_log
2933

30-
let _ = Random.self_init ()
31-
let create ?(max = 32) () = (max, ref 1)
34+
let get_upper_wait_log backoff = backoff lsr (bits * 2)
35+
let get_lower_wait_log backoff = (backoff lsr bits) land mask
36+
let get_wait_log backoff = backoff land mask
3237

33-
let once (maxv, r) =
34-
let t = Random.int !r in
35-
r := min (2 * !r) maxv;
36-
if t = 0 then ()
37-
else
38-
for _ = 1 to 2048 * t do
39-
Domain.cpu_relax ()
40-
done
38+
let reset backoff =
39+
let lower_wait_log = get_lower_wait_log backoff in
40+
backoff land lnot mask lor lower_wait_log
4141

42-
let reset (_, r) = r := 1
43-
end
42+
let once backoff =
43+
let wait_log = get_wait_log backoff in
44+
let wait_mask = (1 lsl wait_log) - 1 in
45+
let t = Random.bits () land wait_mask in
46+
for _ = 0 to t do
47+
Domain.cpu_relax ()
48+
done;
49+
let upper_wait_log = get_upper_wait_log backoff in
50+
let next_wait_log = Int.min upper_wait_log (wait_log + 1) in
51+
backoff lxor wait_log lor next_wait_log
52+
53+
let default = create ()

src/backoff.mli

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
(*
22
* Copyright (c) 2015, Théo Laurent <theo.laurent@ens.fr>
33
* Copyright (c) 2015, KC Sivaramakrishnan <sk826@cl.cam.ac.uk>
4+
* Copyright (c) 2023, Vesa Karvonen <vesa.a.j.k@gmail.com>
45
*
56
* Permission to use, copy, modify, and/or distribute this software for any
67
* purpose with or without fee is hereby granted, provided that the above
@@ -15,12 +16,31 @@
1516
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1617
*)
1718

18-
module type S = sig
19-
type t
19+
type t
20+
(** Type of backoff values. *)
2021

21-
val create : ?max:int -> unit -> t
22-
val once : t -> unit
23-
val reset : t -> unit
24-
end
22+
val max_wait_log : int
23+
(** Logarithm of the maximum allowed value for wait. *)
2524

26-
module M : S
25+
val create : ?lower_wait_log:int -> ?upper_wait_log:int -> unit -> t
26+
(** [create] creates a backoff value. [upper_wait_log], [lower_wait_log]
27+
override the logarithmic upper and lower bound on the number of spins
28+
executed by {!once}. *)
29+
30+
val default : t
31+
(** [default] is equivalent to [create ()]. *)
32+
33+
val once : t -> t
34+
(** [once b] executes one random wait and returns a new backoff with logarithm
35+
of the current maximum value incremented unless it is already at
36+
[upper_wait_log] of [b].
37+
38+
Note that this uses the default Stdlib [Random] per-domain generator. *)
39+
40+
val reset : t -> t
41+
(** [reset b] returns a backoff equivalent to [b] except with current value set
42+
to the [lower_wait_log] of [b]. *)
43+
44+
val get_wait_log : t -> int
45+
(** [get_wait_log b] returns logarithm of the maximum value of wait for next
46+
{!once}. *)

0 commit comments

Comments
 (0)