package picos
Pico scheduler framework
Install
Dune Dependency
Authors
Maintainers
Sources
picos-0.3.0.tbz
sha256=544804c0bde4b29764f82f04e7defed7c06bc43e5a6ce3f7fdc326cb54a7f066
sha512=4c93427e477fb52374a554a8b9c4c92836a9b5899161275d1473269ab526a1f59177209140631ed763a55be375855dea12f076e18bf4124522414986c0e257be
doc/src/picos.threaded/picos_threaded.ml.html
Source file picos_threaded.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
open Picos type t = { fiber : Fiber.t; mutex : Mutex.t; condition : Condition.t } let create_packed ~forbid packed = let fiber = Fiber.create_packed ~forbid packed in let mutex = Mutex.create () in let condition = Condition.create () in { fiber; mutex; condition } let rec block trigger t = if not (Trigger.is_signaled trigger) then begin (* We block fibers (or threads) on a per thread mutex and condition. *) Mutex.lock t.mutex; match if not (Trigger.is_signaled trigger) then (* We assume that there is no poll point after the above [Mutex.lock] and before the below [Condition.wait] is ready to be woken up by a [Condition.broadcast]. *) Condition.wait t.condition t.mutex with | () -> Mutex.unlock t.mutex; block trigger t | exception exn -> (* Condition.wait may be interrupted by asynchronous exceptions and we must make sure to unlock even in that case. *) Mutex.unlock t.mutex; raise exn end let resume trigger t _ = let _is_canceled : bool = Fiber.unsuspend t.fiber trigger in (* This will be called when the trigger is signaled. We simply broadcast on the per thread condition variable. *) begin match Mutex.lock t.mutex with | () -> Mutex.unlock t.mutex | exception Sys_error _ -> (* This should mean that [resume] was called from a signal handler running on the scheduler thread. If the assumption about not having poll points holds, the [Condition.broadcast] should now be able to wake up the [Condition.wait] in the scheduler. *) () end; Condition.broadcast t.condition let[@alert "-handler"] rec await t trigger = if Fiber.try_suspend t.fiber trigger t t resume then block trigger t; Fiber.canceled t.fiber 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 and yield t = (* In other handlers we need to account for cancelation. *) Fiber.check t.fiber; Thread.yield () and cancel_after : type a. _ -> a Computation.t -> _ = (* We need an explicit type signature to allow OCaml to generalize the tyoe as all of the handlers are in a single recursive definition. *) fun t computation ~seconds exn_bt -> Fiber.check t.fiber; Select.cancel_after computation ~seconds exn_bt and spawn : type a. _ -> forbid:bool -> a Computation.t -> _ = fun t ~forbid computation mains -> Fiber.check t.fiber; let packed = Computation.Packed computation in mains |> List.iter @@ fun main -> Thread.create (fun () -> (* We need to (recursively) install the handler on each new thread that we create. *) Handler.using handler (create_packed ~forbid packed) main) () |> ignore and handler = Handler.{ current; spawn; yield; cancel_after; await } let run ~forbid main = Select.check_configured (); let packed = Computation.Packed (Computation.create ()) in Handler.using handler (create_packed ~forbid packed) main
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>