Skip to content

Commit

Permalink
Add useful warnings. (#170)
Browse files Browse the repository at this point in the history
Add missing and useful warnings in documentation.
  • Loading branch information
lyrm authored Dec 2, 2024
1 parent 2bb4d4b commit 3b74e90
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 19 deletions.
17 changes: 14 additions & 3 deletions src/bounded_queue/bounded_queue_intf.mli
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ module type BOUNDED_QUEUE = sig
(** [of_list_exn ~capacity list] creates a new queue from a list.
@raises Full if the length of [list] is greater than [capacity].
🐌 This is a linear-time operation.
{[
# open Saturn.Bounded_queue
Expand Down Expand Up @@ -107,7 +109,9 @@ module type BOUNDED_QUEUE = sig
queue is full. *)
end

(** {1 Examples}
(** {1 Examples} *)

(** {2 Sequential example}
An example top-level session:
{[
# open Saturn.Bounded_queue
Expand Down Expand Up @@ -135,9 +139,16 @@ end
- : int option = None
# pop_exn t
Exception: Saturn__Bounded_queue.Empty.]}
*)

(** {2 Multicore example}
Note: The barrier is used in this example solely to make the results more
interesting by increasing the likelihood of parallelism. Spawning a domain is
a costly operation, especially compared to the relatively small amount of work
being performed here. In practice, using a barrier in this manner is unnecessary.
A multicore example:
{@ocaml non-deterministic[
{@ocaml non-deterministic=command[
# open Saturn.Bounded_queue
# let t :int t = create ~capacity:4 ()
val t : int t = <abstr>
Expand Down
42 changes: 32 additions & 10 deletions src/bounded_stack.mli
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ val of_list_exn : ?capacity:int -> 'a list -> 'a t
@raises Full if the [list] is longer than the capacity of the stack.
🐌 This is a linear-time operation.
{[
# open Saturn.Bounded_stack
# let t : int t = of_list_exn [1;2;3;4]
Expand Down Expand Up @@ -106,18 +107,23 @@ val push_exn : 'a t -> 'a -> unit
val try_push : 'a t -> 'a -> bool
(** [try_push stack element] tries to add [element] to the top of the [stack].
Returns [true] if the element was successfully added, or [false] if the
stack is full. *)
stack is full.
*)

val push_all_exn : 'a t -> 'a list -> unit
(** [push_all_exn stack elements] adds all [elements] to the top of the [stack].
@raises Full if the [stack] is full. *)
@raises Full if the [stack] is full.
🐌 This is a linear-time operation on the size of [elements]. *)

val try_push_all : 'a t -> 'a list -> bool
(** [try_push_all stack elements] tries to add all [elements] to the top of the
[stack]. Returns [true] if the elements were successfully added, or [false] if
the stack is full.
🐌 This is a linear-time operation on the size of [elements].
{[
# let t : int t = create ()
val t : int t = <abstr>
Expand All @@ -142,21 +148,29 @@ bottom.
val of_seq : ?capacity:int -> 'a Seq.t -> 'a t
(** [of_seq seq] creates a stack from a [seq]. It must be finite.
@raises Full if the [list] is longer than the capacity of the stack.
@raises Full if the [seq] is longer than the capacity of the stack.
🐌 This is a linear-time operation.
*)

val add_seq_exn : 'a t -> 'a Seq.t -> unit
(** [add_seq_exn stack seq] adds all elements of [seq] to the top of the
[stack]. [seq] must be finite.
@raises Full if the [seq] is too long to fit in the stack. *)
@raises Full if the [seq] is too long to fit in the stack.
🐌 This is a linear-time operation on the size of [seq]. *)

val try_add_seq : 'a t -> 'a Seq.t -> bool
(** [try_add_seq stack seq] tries to add all elements of [seq] to the top of the
[stack]. Returns [true] if the elements were successfully added, or [false] if
the [seq] is too long to fit in the stack. *)
the [seq] is too long to fit in the stack.
🐌 This is a linear-time operation. *)

(** {1 Examples} *)

(** {1 Examples}
(** {2 Sequential example}
An example top-level session:
{[
# open Saturn.Bounded_stack
Expand All @@ -176,27 +190,36 @@ the [seq] is too long to fit in the stack. *)
- : int option = None
# pop_exn t
Exception: Saturn__Bounded_stack.Empty.]}
*)

(** {2 Multicore example}
Note: The barrier is used in this example solely to make the results more
interesting by increasing the likelihood of parallelism. Spawning a domain is
a costly operation, especially compared to the relatively small amount of work
being performed here. In practice, using a barrier in this manner is unnecessary.
A multicore example:
{@ocaml non-deterministic[
{@ocaml non-deterministic=command[
# open Saturn.Bounded_stack
# let t :int t = create ()
val t : int t = <abstr>
# let barrier = Atomic.make 2
val barrier : int Atomic.t = <abstr>
# let pusher () =
Atomic.decr barrier;
while Atomic.get barrier != 0 do Domain.cpu_relax () done;
try_push_all t [1;2;3] |> ignore;
push_exn t 42;
push_exn t 12
val pusher : unit -> unit = <fun>
# let popper () =
Atomic.decr barrier;
while Atomic.get barrier != 0 do Domain.cpu_relax () done;
List.init 6 (fun i -> Domain.cpu_relax (); pop_opt t)
val popper : unit -> int option list = <fun>
# let domain_pusher = Domain.spawn pusher
val domain_pusher : unit Domain.t = <abstr>
# let domain_popper = Domain.spawn popper
Expand All @@ -206,5 +229,4 @@ the [seq] is too long to fit in the stack. *)
# Domain.join domain_popper
- : int option list = [Some 42; Some 3; Some 2; Some 1; None; Some 12]
]}
*)
28 changes: 22 additions & 6 deletions src/treiber_stack.mli
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ val push : 'a t -> 'a -> unit
val push_all : 'a t -> 'a list -> unit
(** [push_all stack elements] adds all [elements] to the top of the [stack].
🐌 This is a linear-time operation on the size of [elements].
{[
# let t : int t = create ()
val t : int t = <abstr>
Expand All @@ -96,13 +98,19 @@ bottom.
🐌 This is a linear time operation. *)

val of_seq : 'a Seq.t -> 'a t
(** [of_seq seq] creates a stack from a [seq]. It must be finite. *)
(** [of_seq seq] creates a stack from a [seq]. It must be finite.
🐌 This is a linear-time operation. *)

val add_seq : 'a t -> 'a Seq.t -> unit
(** [add_seq stack seq] adds all elements of [seq] to the top of the
[stack]. [seq] must be finite. *)
[stack]. [seq] must be finite.
🐌 This is a linear-time operation on the size of [elements]. *)

(** {1 Examples}
(** {1 Examples} *)

(** {2 Sequential example}
An example top-level session:
{[
# open Saturn.Stack
Expand All @@ -120,26 +128,35 @@ val add_seq : 'a t -> 'a Seq.t -> unit
- : int list = [2; 1; 42]
# pop_exn t
Exception: Saturn__Treiber_stack.Empty.]}
*)

A multicore example:
{@ocaml non-deterministic[
(** {2 Multicore example}
Note: The barrier is used in this example solely to make the results more
interesting by increasing the likelihood of parallelism. Spawning a domain is
a costly operation, especially compared to the relatively small amount of work
being performed here. In practice, using a barrier in this manner is unnecessary.
{@ocaml non-deterministic=command[
# open Saturn.Stack
# let t : int t = create ()
val t : int t = <abstr>
# let barrier = Atomic.make 2
val barrier : int Atomic.t = <abstr>
# let pusher () =
Atomic.decr barrier;
while Atomic.get barrier != 0 do Domain.cpu_relax () done;
push_all t [1;2;3] |> ignore;
push t 42;
push t 12
val pusher : unit -> unit = <fun>
# let popper () =
Atomic.decr barrier;
while Atomic.get barrier != 0 do Domain.cpu_relax () done;
List.init 6 (fun i -> Domain.cpu_relax (); pop_opt t)
val popper : unit -> int option list = <fun>
# let domain_pusher = Domain.spawn pusher
val domain_pusher : unit Domain.t = <abstr>
# let domain_popper = Domain.spawn popper
Expand All @@ -149,5 +166,4 @@ val add_seq : 'a t -> 'a Seq.t -> unit
# Domain.join domain_popper
- : int option list = [Some 42; Some 3; Some 2; Some 1; None; Some 12]
]}
*)

0 comments on commit 3b74e90

Please sign in to comment.