1// dispatch/base.h
2pub const function_t = *const fn (?*anyopaque) callconv(.c) void;
3
4// dispatch/object.h
5pub const object_t = *_os_object_s;
6pub const retain = dispatch_retain;
7pub const release = dispatch_release;
8pub const get_context = dispatch_get_context;
9pub const set_context = dispatch_set_context;
10pub const set_finalizer_f = dispatch_set_finalizer_f;
11pub const activate = dispatch_activate;
12pub const @"suspend" = dispatch_suspend;
13pub const @"resume" = dispatch_resume;
14
15const _os_object_s = opaque {
16 pub const retain = dispatch_retain;
17 pub const release = dispatch_release;
18 pub const get_context = dispatch_get_context;
19 pub const set_context = dispatch_set_context;
20 pub const set_finalizer = dispatch_set_finalizer_f;
21 pub const activate = dispatch_activate;
22 pub const @"suspend" = dispatch_suspend;
23 pub const @"resume" = dispatch_resume;
24 pub const set_target_queue = dispatch_set_target_queue;
25};
26extern "c" fn dispatch_retain(object: object_t) void;
27extern "c" fn dispatch_release(object: object_t) void;
28extern "c" fn dispatch_get_context(object: object_t) ?*anyopaque;
29extern "c" fn dispatch_set_context(object: object_t, context: ?*anyopaque) void;
30extern "c" fn dispatch_set_finalizer_f(object: object_t, finalizer: ?function_t) void;
31extern "c" fn dispatch_activate(object: object_t) void;
32extern "c" fn dispatch_suspend(object: object_t) void;
33extern "c" fn dispatch_resume(object: object_t) void;
34
35// dispatch/once.h
36pub const once_t = enum(isize) {
37 init = 0,
38 done = -1,
39 _,
40
41 pub inline fn once(predicate: *once_t, context: ?*anyopaque, function: function_t) void {
42 if (predicate.* != .done) {
43 @branchHint(.unlikely);
44 once_f(predicate, context, function);
45 } else asm volatile ("" ::: .{ .memory = true });
46 switch (builtin.mode) {
47 .debug, .safe => {},
48 .fast, .small => if (predicate.* != .done) unreachable,
49 }
50 }
51};
52pub const once_f = dispatch_once_f;
53
54extern "c" fn dispatch_once_f(predicate: *once_t, context: ?*anyopaque, function: function_t) void;
55
56// dispatch/queue.h
57pub const queue_t = *queue_s;
58pub const queue_global_t = queue_t;
59pub const queue_serial_executor_t = queue_t;
60pub const queue_serial_t = queue_t;
61pub const queue_main_t = queue_serial_t;
62pub const queue_concurrent_t = queue_t;
63pub const async_f = dispatch_async_f;
64pub const sync_f = dispatch_sync_f;
65pub const async_and_wait_f = dispatch_async_and_wait_f;
66pub const apply_f = dispatch_apply_f;
67pub const get_current_queue = dispatch_get_current_queue;
68pub inline fn get_main_queue() queue_main_t {
69 return &_dispatch_main_q;
70}
71pub const queue_priority_t = enum(c_long) {
72 HIGH = 2,
73 DEFAULT = 0,
74 LOW = -1,
75 BACKGROUND = std.math.minInt(i16),
76 _,
77};
78pub const get_global_queue = dispatch_get_global_queue;
79pub const queue_attr_t = ?*queue_attr_s;
80pub inline fn QUEUE_SERIAL() queue_attr_t {
81 return null;
82}
83pub inline fn QUEUE_INACTIVE() queue_attr_t {
84 return queue_attr_make_initially_inactive(QUEUE_SERIAL());
85}
86pub inline fn QUEUE_CONCURRENT() queue_attr_t {
87 return &_dispatch_queue_attr_concurrent;
88}
89pub inline fn QUEUE_CONCURRENT_INACTIVE() queue_attr_t {
90 return queue_attr_make_initially_inactive(QUEUE_CONCURRENT());
91}
92pub const queue_attr_make_initially_inactive = dispatch_queue_attr_make_initially_inactive;
93pub const TARGET_QUEUE_DEFAULT: ?queue_t = null;
94pub const queue_create_with_target = dispatch_queue_create_with_target;
95pub const queue_create = dispatch_queue_create;
96pub const CURRENT_QUEUE_LABEL: ?[*:0]const u8 = null;
97pub const queue_get_label = dispatch_queue_get_label;
98pub const main = dispatch_main;
99pub const after_f = dispatch_after_f;
100
101const queue_s = opaque {
102 pub inline fn as_object(queue: queue_t) object_t {
103 return @ptrCast(queue);
104 }
105 pub const async = async_f;
106 pub const sync = sync_f;
107 pub const async_and_wait = async_and_wait_f;
108 pub const apply = apply_f;
109 pub const get_current = get_current_queue;
110 pub const get_main = get_main_queue;
111 pub const get_global = get_global_queue;
112 pub const TARGET_DEFAULT = TARGET_QUEUE_DEFAULT;
113 pub const create_with_target = queue_create_with_target;
114 pub const create = queue_create;
115 pub const get_label = queue_get_label;
116};
117extern "c" fn dispatch_async_f(queue: queue_t, context: ?*anyopaque, work: function_t) void;
118extern "c" fn dispatch_sync_f(queue: queue_t, context: ?*anyopaque, work: function_t) void;
119extern "c" fn dispatch_async_and_wait_f(queue: queue_t, context: ?*anyopaque, work: function_t) void;
120extern "c" fn dispatch_apply_f(iterations: usize, queue: ?queue_t, context: ?*anyopaque, work: *const fn (context: ?*anyopaque, iteration: usize) callconv(.c) void) void;
121extern "c" fn dispatch_get_current_queue() queue_t;
122extern "c" var _dispatch_main_q: queue_s;
123extern "c" fn dispatch_get_global_queue(identifier: isize, flags: usize) queue_global_t;
124const queue_attr_s = opaque {
125 pub inline fn as_object(queue_attr: queue_attr_t) object_t {
126 return @ptrCast(queue_attr);
127 }
128 pub const SERIAL = QUEUE_SERIAL;
129 pub const INACTIVE = QUEUE_INACTIVE;
130 pub const CONCURRENT = QUEUE_CONCURRENT;
131 pub const CONCURRENT_INACTIVE = QUEUE_CONCURRENT_INACTIVE;
132};
133extern "c" var _dispatch_queue_attr_concurrent: queue_attr_s;
134extern "c" fn dispatch_queue_attr_make_initially_inactive(attr: queue_attr_t) queue_attr_t;
135extern "c" fn dispatch_queue_create_with_target(label: ?[*:0]const u8, attr: queue_attr_t, target: ?queue_t) ?queue_t;
136extern "c" fn dispatch_queue_create(label: ?[*:0]const u8, attr: queue_attr_t) ?queue_t;
137extern "c" fn dispatch_queue_get_label(queue: ?queue_t) [*:0]const u8;
138extern "c" fn dispatch_set_target_queue(object: object_t, queue: ?queue_t) void;
139extern "c" fn dispatch_main() noreturn;
140extern "c" fn dispatch_after_f(when: time_t, queue: queue_t, context: ?*anyopaque, work: function_t) void;
141
142// dispatch/semaphore.h
143pub const semaphore_t = *semaphore_s;
144pub const semaphore_create = dispatch_semaphore_create;
145pub const semaphore_wait = dispatch_semaphore_wait;
146pub const semaphore_signal = dispatch_semaphore_signal;
147
148const semaphore_s = opaque {
149 pub inline fn as_object(semaphore: semaphore_t) object_t {
150 return @ptrCast(semaphore);
151 }
152 pub const create = semaphore_create;
153 pub const wait = semaphore_wait;
154 pub const signal = semaphore_signal;
155};
156extern "c" fn dispatch_semaphore_create(value: isize) ?semaphore_t;
157extern "c" fn dispatch_semaphore_wait(dsema: semaphore_t, timeout: time_t) isize;
158extern "c" fn dispatch_semaphore_signal(dsema: semaphore_t) isize;
159
160// dispatch/source.h
161pub const source_t = *source_s;
162pub const source_type_t = *const source_type_s;
163pub const SOURCE_TYPE_DATA_ADD = &_dispatch_source_type_data_add;
164pub const SOURCE_TYPE_DATA_OR = &_dispatch_source_type_data_or;
165pub const SOURCE_TYPE_DATA_REPLACE = &_dispatch_source_type_data_replace;
166pub const SOURCE_TYPE_MACH_SEND = &_dispatch_source_type_mach_send;
167pub const SOURCE_TYPE_MACH_RECV = &_dispatch_source_type_mach_recv;
168pub const SOURCE_TYPE_MEMORYPRESSURE = &_dispatch_source_type_memorypressure;
169pub const SOURCE_TYPE_PROC = &_dispatch_source_type_proc;
170pub const SOURCE_TYPE_READ = &_dispatch_source_type_read;
171pub const SOURCE_TYPE_SIGNAL = &_dispatch_source_type_signal;
172pub const SOURCE_TYPE_TIMER = &_dispatch_source_type_timer;
173pub const SOURCE_TYPE_VNODE = &_dispatch_source_type_vnode;
174pub const SOURCE_TYPE_WRITE = &_dispatch_source_type_write;
175pub const source_mach_send_flags_t = packed struct(usize) {
176 DEAD: bool = false,
177 unused1: @Int(.unsigned, @bitSizeOf(usize) - 1) = 0,
178};
179pub const source_mach_recv_flags_t = packed struct(usize) {
180 unused0: @Int(.unsigned, @bitSizeOf(usize) - 0) = 0,
181};
182pub const source_memorypressure_flags_t = packed struct(usize) {
183 NORMAL: bool = false,
184 WARN: bool = false,
185 CRITICAL: bool = false,
186 unused3: @Int(.unsigned, @bitSizeOf(usize) - 3) = 0,
187};
188pub const source_proc_flags_t = packed struct(usize) {
189 unused0: u27 = 0,
190 SIGNAL: bool = false,
191 unused28: u1 = 0,
192 EXEC: bool = false,
193 FORK: bool = false,
194 EXIT: bool = false,
195 unused32: @Int(.unsigned, @bitSizeOf(usize) - 32) = 0,
196};
197pub const source_vnode_flags_t = packed struct(usize) {
198 DELETE: bool = false,
199 WRITE: bool = false,
200 EXTEND: bool = false,
201 ATTRIB: bool = false,
202 LINK: bool = false,
203 RENAME: bool = false,
204 REVOKE: bool = false,
205 unused7: u1 = 0,
206 FUNLOCK: bool = false,
207 unused9: @Int(.unsigned, @bitSizeOf(usize) - 9) = 0,
208};
209pub const source_timer_flags_t = packed struct(usize) {
210 STRICT: bool = false,
211 unused1: @Int(.unsigned, @bitSizeOf(usize) - 1) = 0,
212};
213pub const source_flags_t = packed union(usize) {
214 raw: usize,
215 MACH_SEND: source_mach_send_flags_t,
216 MACH_RECV: source_mach_recv_flags_t,
217 MEMORYPRESSURE: source_memorypressure_flags_t,
218 PROC: source_proc_flags_t,
219 VNODE: source_vnode_flags_t,
220 pub const none: source_flags_t = .{ .raw = 0 };
221};
222pub const source_create = dispatch_source_create;
223pub const source_set_event_handler_f = dispatch_source_set_event_handler_f;
224pub const source_set_cancel_handler_f = dispatch_source_set_cancel_handler_f;
225pub const source_cancel = dispatch_source_cancel;
226pub const source_testcancel = dispatch_source_testcancel;
227pub const source_get_handle = dispatch_source_get_handle;
228pub const source_get_mask = dispatch_source_get_mask;
229pub const source_get_data = dispatch_source_get_data;
230pub const source_merge_data = dispatch_source_merge_data;
231pub const source_set_timer = dispatch_source_set_timer;
232pub const source_set_registration_handler_f = dispatch_source_set_registration_handler_f;
233
234const source_s = opaque {
235 pub inline fn as_object(source: source_t) object_t {
236 return @ptrCast(source);
237 }
238 pub const set_event_handler = source_set_event_handler_f;
239 pub const set_cancel_handler = source_set_cancel_handler_f;
240 pub const cancel = source_cancel;
241 pub const testcancel = source_testcancel;
242 pub const get_handle = source_get_handle;
243 pub const get_mask = source_get_mask;
244 pub const get_data = source_get_data;
245 pub const merge_data = source_merge_data;
246 pub const set_timer = source_set_timer;
247 pub const set_registration_handler = source_set_registration_handler_f;
248};
249const source_type_s = opaque {
250 pub const DATA_ADD = SOURCE_TYPE_DATA_ADD;
251 pub const DATA_OR = SOURCE_TYPE_DATA_OR;
252 pub const DATA_REPLACE = SOURCE_TYPE_DATA_REPLACE;
253 pub const MACH_SEND = SOURCE_TYPE_MACH_SEND;
254 pub const MACH_RECV = SOURCE_TYPE_MACH_RECV;
255 pub const MEMORYPRESSURE = SOURCE_TYPE_MEMORYPRESSURE;
256 pub const PROC = SOURCE_TYPE_PROC;
257 pub const READ = SOURCE_TYPE_READ;
258 pub const SIGNAL = SOURCE_TYPE_SIGNAL;
259 pub const TIMER = SOURCE_TYPE_TIMER;
260 pub const VNODE = SOURCE_TYPE_VNODE;
261 pub const WRITE = SOURCE_TYPE_WRITE;
262};
263extern "c" const _dispatch_source_type_data_add: source_type_s;
264extern "c" const _dispatch_source_type_data_or: source_type_s;
265extern "c" const _dispatch_source_type_data_replace: source_type_s;
266extern "c" const _dispatch_source_type_mach_send: source_type_s;
267extern "c" const _dispatch_source_type_mach_recv: source_type_s;
268extern "c" const _dispatch_source_type_memorypressure: source_type_s;
269extern "c" const _dispatch_source_type_proc: source_type_s;
270extern "c" const _dispatch_source_type_read: source_type_s;
271extern "c" const _dispatch_source_type_signal: source_type_s;
272extern "c" const _dispatch_source_type_timer: source_type_s;
273extern "c" const _dispatch_source_type_vnode: source_type_s;
274extern "c" const _dispatch_source_type_write: source_type_s;
275extern "c" fn dispatch_source_create(type: source_type_t, handle: usize, mask: source_flags_t, queue: ?queue_t) ?source_t;
276extern "c" fn dispatch_source_set_event_handler_f(source: source_t, handler: ?function_t) void;
277extern "c" fn dispatch_source_set_cancel_handler_f(source: source_t, handler: ?function_t) void;
278extern "c" fn dispatch_source_cancel(source: source_t) void;
279extern "c" fn dispatch_source_testcancel(source: source_t) isize;
280extern "c" fn dispatch_source_get_handle(source: source_t) usize;
281extern "c" fn dispatch_source_get_mask(source: source_t) source_flags_t;
282extern "c" fn dispatch_source_get_data(source: source_t) usize;
283extern "c" fn dispatch_source_merge_data(source: source_t, value: usize) void;
284extern "c" fn dispatch_source_set_timer(source: source_t, start: time_t, interval: u64, leeway: u64) void;
285extern "c" fn dispatch_source_set_registration_handler_f(source: source_t, handler: ?function_t) void;
286
287// dispatch/time.h
288pub const time_t = enum(u64) {
289 WALL_NOW = WALLTIME_NOW,
290 NOW = TIME_NOW,
291 FOREVER = TIME_FOREVER,
292 _,
293
294 pub const time = dispatch_time;
295 pub const walltime = dispatch_walltime;
296 pub const after = dispatch_after_f;
297};
298pub const WALLTIME_NOW = ~@as(u64, 1);
299pub const TIME_NOW: u64 = 0;
300pub const TIME_FOREVER = ~@as(u64, 0);
301pub const time = dispatch_time;
302pub const walltime = dispatch_walltime;
303
304extern "c" fn dispatch_time(when: time_t, delta: i64) time_t;
305extern "c" fn dispatch_walltime(when: ?*const std.c.timespec, delta: i64) time_t;
306
307const builtin = @import("builtin");
308const std = @import("std");