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
type t = {
mutable n : int;
m : Mutex.t;
c : Condition.t;
}
let create n =
if n <= 0 then
invalid_arg (Printf.sprintf
"Semaphore value must be positive, got %d" n);
let m = Mutex.create ()
and c = Condition.create () in
{ n; m; c; }
exception Inconsistent_state of string
let inconsistent_state fmt = Printf.kprintf (fun msg ->
raise (Inconsistent_state msg)) fmt
let acquire s k =
if k <= 0 then
invalid_arg (Printf.sprintf
"Semaphore acquisition requires a positive value, got %d" k);
Mutex.lock s.m;
while s.n < k do
Condition.wait s.c s.m;
done;
if not (s.n >= k) then
inconsistent_state "Semaphore value cannot be smaller than %d, got %d" k s.n;
s.n <- s.n - k;
Condition.signal s.c;
Mutex.unlock s.m
let release s k =
if k <= 0 then
invalid_arg (Printf.sprintf
"Semaphore release requires a positive value, got %d" k);
Mutex.lock s.m;
s.n <- s.n + k;
Condition.signal s.c;
Mutex.unlock s.m
let execute_with_weight s k f =
acquire s k;
Xapi_stdext_pervasives.Pervasiveext.finally f
(fun () -> release s k)
let execute s f =
execute_with_weight s 1 f