package containers
A modular, clean and powerful extension of the OCaml standard library
Install
Dune Dependency
Authors
Maintainers
Sources
v2.8.1.tar.gz
md5=d84e09c5d0abc501aa17cd502e31a038
sha512=8b832f4ada6035e80d81be0cfb7bdffb695ec67d465ed6097a144019e2b8a8f909095e78019c3da2d8181cc3cd730cd48f7519e87d3162442562103b7f36aabb
doc/src/containers.thread/CCSemaphore.ml.html
Source file CCSemaphore.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 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
(** {1 Semaphores} *) type t = { mutable n : int; mutex : Mutex.t; cond : Condition.t; } let create n = if n <= 0 then invalid_arg "Semaphore.create"; { n; mutex=Mutex.create(); cond=Condition.create(); } let get t = t.n (* assume [t.mutex] locked, try to acquire [t] *) let acquire_once_locked_ m t = while t.n < m do Condition.wait t.cond t.mutex; done; assert (t.n >= m); t.n <- t.n - m; Condition.broadcast t.cond; Mutex.unlock t.mutex let acquire m t = Mutex.lock t.mutex; acquire_once_locked_ m t (* assume [t.mutex] locked, try to release [t] *) let release_once_locked_ m t = t.n <- t.n + m; Condition.broadcast t.cond; Mutex.unlock t.mutex let release m t = Mutex.lock t.mutex; release_once_locked_ m t; () (*$R let s = create 1 in let r = CCLock.create false in let _ = Thread.create (fun s -> acquire 5 s; CCLock.set r true) s in Thread.yield (); assert_equal false (CCLock.get r); release 4 s; Thread.delay 0.2; assert_equal true (CCLock.get r); assert_equal 0 (get s) *) let with_acquire ~n t ~f = acquire n t; try let x = f() in release n t; x with e -> release n t; raise e (*$R let s = create 5 in let n = CCLock.create 0 in let a = Array.init 100 (fun i -> Thread.create (fun _ -> for _i = 1 to 100 do with_acquire ~n:(1 + (i mod 5)) s ~f:(fun () -> Thread.yield(); CCLock.incr n) done) ()) in Array.iter Thread.join a; assert_equal ~printer:CCInt.to_string 5 (get s); assert_equal ~printer:CCInt.to_string 10_000 (CCLock.get n) *) let wait_until_at_least ~n t ~f = Mutex.lock t.mutex; while t.n < n do Condition.wait t.cond t.mutex; done; assert (t.n >= n); Mutex.unlock t.mutex; f () (*$R let output s = () in let s = create 2 in let res = CCLock.create false in let id = Thread.create (fun () -> output "start"; wait_until_at_least ~n:5 s ~f:(fun () -> assert (get s >= 5); output "modify now"; CCLock.set res true) ) () in output "launched thread"; Thread.yield(); assert_bool "start" (not (CCLock.get res)); output "release 2"; release 2 s; Thread.yield(); assert_bool "after release 2" (not (CCLock.get res)); output "release 1"; release 1 s; (* should work now *) Thread.delay 0.2; Thread.join id; output "check"; assert_bool "after release 1" (CCLock.get res) *)
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>