This repository has been archived by the owner on Nov 8, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
dispatch.ml
213 lines (132 loc) · 3.87 KB
/
dispatch.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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
open Core.Std
open Ctypes
open Signed
open Unsigned
open Foreign
type never_returns = unit
module Primitive = struct
module Runtime = struct
let class_ = ptr void
let lookup_class =
foreign "objc_lookUpClass" (string @-> returning class_)
let class_name =
foreign "class_getName" (class_ @-> returning string)
end
module Object = struct
type t = unit ptr
let t : t typ = ptr void
let retain =
foreign "dispatch_retain" (t @-> returning void)
let release =
foreign "dispatch_release" (t @-> returning void)
end
module Time = struct
type t = uint64
let t = uint64_t
let now = UInt64.of_int 0
let create =
foreign "dispatch_time" (t @-> int64_t @-> returning t)
end
module Function = struct
type t = (unit ptr -> unit)
let t : t typ = funptr (ptr void @-> returning void)
(*let of_f (f:(unit -> unit)) = (fun (_:unit ptr) -> f ())*)
let of_f f = f
end
module Queue = struct
module Priority = struct
type t = long
let t : t typ = long
let high = Long.of_int 2
let default = Long.of_int 0
let low = Long.of_int (-2)
let background = Long.of_int 0x8000 (* int16 min *)
end
module Attr = struct
end
module Qos = struct
end
module Once = struct
type t = long
let t : t typ = long
end
type t = unit ptr
let t : t typ = ptr void
let current_queue =
foreign "dispatch_get_current_queue" (void @-> returning t)
let global_queue =
foreign "dispatch_get_global_queue" (long @-> ulong @-> returning t)
let create =
foreign "dispatch_queue_create" (string @-> ptr void @-> returning t)
let label =
foreign "dispatch_queue_get_label" (t @-> returning string)
let async_f =
foreign "dispatch_async_f" (t @-> ptr void @-> Function.t @-> returning void)
let sync_f =
foreign "dispatch_sync_f" (t @-> ptr void @-> Function.t @-> returning void)
let after_f =
foreign "dispatch_after_f"
(Time.t @-> t @-> ptr void @-> Function.t @-> returning void)
let once_f =
foreign "dispatch_once_f"
(Once.t @-> ptr void @-> Function.t @-> returning void)
let main =
foreign "dispatch_main" (void @-> returning void)
end
end
module Time = struct
module P = Primitive.Time
type t = P.t
let now = P.now
let create when_ delta =
P.create when_ delta
let of_int = UInt64.of_int
let to_int = UInt64.to_int
let of_int64 = UInt64.of_int64
let to_int64 = UInt64.to_int64
end
module Queue = struct
module P = Primitive.Queue
module F = Primitive.Function
type t = P.t
type work = (unit ptr -> unit)
let current () = P.current_queue ()
let global () = P.global_queue P.Priority.high ULong.zero
let create label = P.create label null
let label queue = P.label queue
let async queue ~f = P.async_f queue null @@ F.of_f f
let sync queue ~f = P.sync_f queue null @@ F.of_f f
let after queue ~f ~time = P.after_f time queue null @@ F.of_f f
let once queue ~f = P.once_f queue null @@ F.of_f f
let forever () = P.main ()
end
let test_f _ =
()
let rec fib n =
if n < 2 then n else fib (n - 2) + fib (n - 1)
let () =
let label = Queue.label @@ Queue.global () in
Printf.printf "queue label = %s\n" label;
Printf.printf "begin create queue\n";
flush_all ();
let workers = ref [] in
for i = 0 to 20 do
Printf.printf "create queue %d\n" i;
flush_all ();
let queue = Queue.create "test" in
workers := queue :: !workers
done;
Printf.printf "ready queue\n";
flush_all ();
for i = 0 to 10000 do
List.iter !workers
~f:(fun worker ->
Queue.async worker ~f:(fun _ -> ignore @@ fib 38);
ignore @@ Unix.nanosleep 0.01;
);
done;
flush_all ();
Printf.printf "begin loop\n";
flush_all ();
Queue.forever ();
()