package picos_std
Sample libraries for Picos
Install
Dune Dependency
Authors
Maintainers
Sources
picos-0.5.0.tbz
sha256=862d61383e2df93a876bedcffb1fd1ddc0f96c50b0e9c07943a2aee1f0e182be
sha512=87805379017ef4a7f2c11b954625a3757a0f1431bb9ba59132202de278b3e41adbe0cdc20e3ab23b7c9a8c5a15faeb7ec79348e7d80f2b14274b00df0893b8c0
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)"
>