package picos_std
Sample libraries for Picos
Install
Dune Dependency
Authors
Maintainers
Sources
picos-0.6.0.tbz
sha256=3f5a08199cf65c2dae2f7d68f3877178f1da8eabf5376e15114e5a8958087dfa
sha512=ad24910c47ce614268c4268874bb918da7f8b5f03b3ad706bbf30323635262e94ddab6be24eaebbca706bfa82c0a517d4272b396459e020c185942125c9bdb7b
doc/src/picos_std.sync/condition.ml.html
Source file condition.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
open Picos type t = Trigger.t Q.t Atomic.t let create ?padded () = Multicore_magic.copy_as ?padded @@ Atomic.make (Q.T Zero) let broadcast (t : t) = if Atomic.get t != T Zero then match Atomic.exchange t (T Zero) with | T Zero -> () | T (One _ as q) -> Q.iter q Trigger.signal (* We try to avoid starvation of signal by making it so that when, at the start of signal or wait, the head is empty, the tail is reversed into the head. This way both signal and wait attempt O(1) and O(n) operations at the same time. *) let rec signal (t : t) backoff = match Atomic.get t with | T Zero -> () | T (One _ as q) as before -> let after = Q.tail q in if Atomic.compare_and_set t before after then let trigger = Q.head q in Trigger.signal trigger else signal t (Backoff.once backoff) let rec cleanup backoff trigger (t : t) = (* We have been canceled. If we can't drop our trigger from the variable, we signal the next trigger in queue to make sure each signal wakes up at least one non-canceled waiter if possible. *) match Atomic.get t with | T Zero -> () | T (One _ as q) as before -> let after = Q.remove q trigger in if before == after then signal t Backoff.default else if not (Atomic.compare_and_set t before after) then cleanup (Backoff.once backoff) trigger t let rec wait (t : t) mutex trigger fiber backoff = let before = Atomic.get t in let after = Q.add before trigger in if Atomic.compare_and_set t before after then begin Mutex.unlock_as (Fiber.Maybe.of_fiber fiber) mutex Backoff.default; let result = Trigger.await trigger in let forbid = Fiber.exchange fiber ~forbid:true in Mutex.lock_as (Fiber.Maybe.of_fiber fiber) mutex Nothing Backoff.default; Fiber.set fiber ~forbid; match result with | None -> () | Some (exn, bt) -> cleanup Backoff.default trigger t; Printexc.raise_with_backtrace exn bt end else wait t mutex trigger fiber (Backoff.once backoff) let wait t mutex = let fiber = Fiber.current () in let trigger = Trigger.create () in wait t mutex trigger fiber Backoff.default let[@inline] signal t = signal t Backoff.default
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>