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

Use an integer has an identifier for fiber instead of == #115

Open
dinosaure opened this issue Apr 25, 2024 · 3 comments
Open

Use an integer has an identifier for fiber instead of == #115

dinosaure opened this issue Apr 25, 2024 · 3 comments

Comments

@dinosaure
Copy link

Concerning some parts of Picos, it's required to know which is our current fiber to compare with some others (like for mutex and condition). It requires that Fiber must be used to be able to use Lazy, Mutex or Condition. However, only a comparison is needed. To give an opportunity for someone else to implement its own fiber but be able to use these modules, it can be interesting to define an effect such as type _ Effect.t += Current : int Effect.t which returns an unique identifier of the current fiber. By this way, the scheduler implementor just need to provide such unique identifier instead of a Fiber.t.

@polytypic
Copy link
Collaborator

polytypic commented Apr 25, 2024

Would the use of FLS be sufficient?

module Picos_fiber_id : sig
  val fiber_id : unit -> int
  (** [fiber_id ()] returns a unique integer id for the current fiber. *)
end = struct
  let fiber_id_key =
    let next = Atomic.make 0 in
    Fiber.FLS.new_key
    @@ Computed (fun () ->
        Atomic.fetch_and_add next 1)

  let fiber_id () =
    Fiber.FLS.get (Fiber.current ()) fiber_id_key
end

We could put this into a library for Picos.

@dinosaure
Copy link
Author

dinosaure commented Apr 26, 2024

Would the use of FLS be sufficient?

My idea is precisely to have an independent Current effect of the Fiber.t type. As it happens, as far as Miou is concerned, I define my own Current effect and, from what I've been able to see in picos.sync, the interest of the Current effect lies solely in its ability to discriminate the given fiber from others and modify the forbid value.

This could be broken down into:

  1. an effect that gives a unique identifier that picos or another scheduler can transmit (@fabbing's idea of using the unique identifier of fibers present in the stack is a good idea)
  2. an effect to modify the forbid of the fiber

This would allow picos.sync to depend on certain elements of Fiber.t but to leave it to the discretion of the implementer to propose his own Fiber.t (as Miou does) while offering a certain compatibility with picos.sync.

In this case, I'd like picos.sync to be able to work with Miou without depending on Fiber.t.

@polytypic
Copy link
Collaborator

polytypic commented Apr 26, 2024

If I understand correctly what you are after then this is something I also thought about a lot while designing the Fiber concept. Yes, I agree, it would be nice to be able to leave the representation of the "per fiber state" abstract. I recall talking about this in some meetings. Unfortunately I am sceptical that any of the ways to do that (e.g. objects, modules, ... effects) would be better (faster, taking less memory, simpler, easier, ...) in practice than the current design (I suspect most other ways will be the opposite: slower, take more memory, more complicated, more difficult to work with or more difficult for a scheduler to provide).

The idea with the current design is to define a "fiber" concept that should not be too costly for a scheduler to maintain as part of their per fiber state.

Nothing prevents a scheduler from having more per fiber state. For example, Picos_threaded has this record type for per fiber state:

type t = { fiber : Fiber.t; mutex : Mutex.t; condition : Condition.t }

and the current operation returns the fiber field from the per fiber state record:

and current t =
(* The current handler must never propagate cancelation, but it would be
possible to yield here to run some other fiber before resuming the current
fiber. *)
t.fiber

Would this not work in your case (i.e. define your own per fiber state record with Picos.Fiber.t as one element of it)?

Note that a Picos compatible scheduler should not only allow one to perform Current to get the Fiber.t, but the scheduler should also respect whatever state changes are then then done through the Fiber.t object.

An advantage of having a concrete Fiber.t type is that it can be manipulated efficiently once obtained. Another advantage is that Current is just one effect rather than multiple effects Forbid, Get_computation, ...

Integer ids are problematic. For example, I would much rather have Thread.TLS than Thread.id (I'm referring to the systhreads of OCaml), because I could easily and efficiently implement Thread.id with Thread.TLS, but implementing Thread.TLS with Thread.id is far more involved. You need some sort of mapping from ids to state. That will likely mean one or two orders of magnitude slower accesses to such state. And then you will need to manage such mappings (create entries, remove entries). I would rather avoid that and do not wish that upon anyone.

Note that Picos_sync is just one tiny library implemented in Picos. I'm currently working on finishing #49 where the Bundle concept will need to manipulate both the forbid flag and the computations associated with a fiber. Note that PR #49 also makes it possible to change the computation associated with a fiber (i.e Fiber.set_computation).

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

No branches or pull requests

2 participants