Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hash table from picos #154

Open
wants to merge 16 commits into
base: main
Choose a base branch
from
Open

Hash table from picos #154

wants to merge 16 commits into from

Conversation

lyrm
Copy link
Collaborator

@lyrm lyrm commented Sep 25, 2024

Import Picos hash table in Saturn. Some changes:

  • using the size module
  • a safe and an unsafe version. Issue : the size module uses Obj.magic

TODO :

  • Dscheck tests are taking too long
  • the safe and the unsafe implementation are the same except for the use of Transparent_atomic and Multicore_magic.Atomic_array. Could we avoid duplicating the code somehow ?

@lyrm lyrm marked this pull request as draft September 25, 2024 21:42
@lyrm lyrm marked this pull request as ready for review October 3, 2024 13:35
@lyrm lyrm requested a review from polytypic October 3, 2024 13:41
bench/bench_htbl.ml Outdated Show resolved Hide resolved
bench/bench_htbl.ml Outdated Show resolved Hide resolved
src_lockfree/htbl/htbl.ml Outdated Show resolved Hide resolved
test/htbl/stm_htbl.ml Outdated Show resolved Hide resolved
test/htbl/dscheck_htbl.ml Outdated Show resolved Hide resolved
bench/bench_htbl.ml Outdated Show resolved Hide resolved
src_lockfree/htbl/dune Outdated Show resolved Hide resolved
src_lockfree/htbl/dune Outdated Show resolved Hide resolved
bench/bench_htbl.ml Outdated Show resolved Hide resolved
@polytypic
Copy link
Contributor

polytypic commented Oct 18, 2024

BTW, I'm adding a couple of operations to the Picos Htbl:

val try_set : ('k, 'v) t -> 'k -> 'v -> bool
(** [try_set htbl key value] tries to update an existing binding of [key] to
    [value].  Returns [true] on success and [false] in case the hash table did
    not contain a binding for [key]. *)

val try_compare_and_set : ('k, 'v) t -> 'k -> 'v -> 'v -> bool
(** [try_compare_and_set htbl key before after] tries to update an existing
    binding of [key] from the [before] value to the [after] value.  The values
    are compared using physical equality, i.e. the [==] operator.  Returns
    [true] on success and [false] in case the hash table did not contain a
    binding of [key] to the [before] value. *)

val try_compare_and_remove : ('k, 'v) t -> 'k -> 'v -> bool
(** [try_compare_and_remove htbl key before] tries to remove a binding of [key]
    to the [before] value.  Values are compared using physical equality,
    i.e. the [==] operator.  Returns [true] on success and [false] in case the
    hash table did not contain a binding of [key] to the [before] value. *)

These are currently in a draft PR, Add Awaitable atomic locations, but I will likely move the Htbl changes to a separate PR soon.

There is a reason for adding operations with the above kind of semantics. The reason being that those operations allow consensus among arbitrarily many processes. In practical terms, it means that you can create new non-blocking operations using those operations as building blocks. If you look at the Stdlib Hashtbl, then many of the operations it provides, such as

val add : ('a, 'b) t -> 'a -> 'b -> unit
val remove : ('a, 'b) t -> 'a -> unit
val replace : ('a, 'b) t -> 'a -> 'b -> unit

do not, by themselves, allow consensus among arbitrarily many processes and are therefore limited in their use as building blocks of new non-blocking operations.

For example, in the PR, there is an (internal) lock-free operation

let rec add_awaiter t (one : Awaiters.is1) =
  match Htbl.find_exn awaiters (Packed t) with
  | before ->
      let many = Awaiters.snoc before one in
      if not (Htbl.try_compare_and_set awaiters (Packed t) before (Min1 many))
      then add_awaiter t one
  | exception Not_found ->
      if not (Htbl.try_add awaiters (Packed t) (Min1 one)) then
        add_awaiter t one

that adds an awaiter (one is a node for single awaiter) to a queue in the awaiters hash table. Notice how the operations provided by the Htbl allow one to write that using a very familiar lock-free retry pattern.

@lyrm lyrm force-pushed the picos_htbl branch 4 times, most recently from 1103194 to 0bb3771 Compare October 29, 2024 19:20
@lyrm
Copy link
Collaborator Author

lyrm commented Oct 30, 2024

This PR is ready. I have began squashing the commits to make it more readable if additional people want to have a look before it is merged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants