]> git.saurik.com Git - apple/libdispatch.git/blob - private/voucher_activity_private.h
libdispatch-442.1.4.tar.gz
[apple/libdispatch.git] / private / voucher_activity_private.h
1 /*
2 * Copyright (c) 2013-2014 Apple Inc. All rights reserved.
3 *
4 * @APPLE_APACHE_LICENSE_HEADER_START@
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 * @APPLE_APACHE_LICENSE_HEADER_END@
19 */
20
21 #ifndef __OS_VOUCHER_ACTIVITY_PRIVATE__
22 #define __OS_VOUCHER_ACTIVITY_PRIVATE__
23
24 #include <os/base.h>
25 #include <os/object.h>
26 #if !defined(__DISPATCH_BUILDING_DISPATCH__)
27 #include <os/voucher_private.h>
28 #endif
29
30 #define OS_VOUCHER_ACTIVITY_SPI_VERSION 20140708
31
32 #if OS_VOUCHER_WEAK_IMPORT
33 #define OS_VOUCHER_EXPORT OS_EXPORT OS_WEAK_IMPORT
34 #else
35 #define OS_VOUCHER_EXPORT OS_EXPORT
36 #endif
37
38 __BEGIN_DECLS
39
40 #if OS_VOUCHER_ACTIVITY_SPI
41
42 /*!
43 * @group Voucher Activity SPI
44 * SPI intended for libtrace only
45 */
46
47 /*!
48 * @typedef voucher_activity_id_t
49 *
50 * @abstract
51 * Opaque activity identifier.
52 *
53 * @discussion
54 * Scalar value type, not reference counted.
55 */
56 typedef uint64_t voucher_activity_id_t;
57
58 /*!
59 * @enum voucher_activity_tracepoint_type_t
60 *
61 * @abstract
62 * Types of tracepoints.
63 */
64 OS_ENUM(voucher_activity_tracepoint_type, uint8_t,
65 voucher_activity_tracepoint_type_release = (1u << 0),
66 voucher_activity_tracepoint_type_debug = (1u << 1),
67 voucher_activity_tracepoint_type_error = (1u << 6) | (1u << 0),
68 voucher_activity_tracepoint_type_fault = (1u << 7) | (1u << 6) | (1u << 0),
69 );
70
71 /*!
72 * @enum voucher_activity_flag_t
73 *
74 * @abstract
75 * Flags to pass to voucher_activity_start/voucher_activity_start_with_location
76 */
77 OS_ENUM(voucher_activity_flag, unsigned long,
78 voucher_activity_flag_default = 0,
79 voucher_activity_flag_force = 0x1,
80 );
81
82 /*!
83 * @typedef voucher_activity_trace_id_t
84 *
85 * @abstract
86 * Opaque tracepoint identifier.
87 */
88 typedef uint64_t voucher_activity_trace_id_t;
89 static const uint8_t _voucher_activity_trace_id_type_shift = 40;
90 static const uint8_t _voucher_activity_trace_id_code_namespace_shift = 32;
91
92 /*!
93 * @function voucher_activity_trace_id
94 *
95 * @abstract
96 * Return tracepoint identifier for specified arguments.
97 *
98 * @param type
99 * Tracepoint type from voucher_activity_tracepoint_type_t.
100 *
101 * @param code_namespace
102 * Namespace of 'code' argument.
103 *
104 * @param code
105 * Tracepoint code.
106 *
107 * @result
108 * Tracepoint identifier.
109 */
110 __OSX_AVAILABLE_STARTING(__MAC_10_10,__IPHONE_8_0)
111 OS_INLINE OS_ALWAYS_INLINE
112 voucher_activity_trace_id_t
113 voucher_activity_trace_id(uint8_t type, uint8_t code_namespace, uint32_t code)
114 {
115 return ((voucher_activity_trace_id_t)type <<
116 _voucher_activity_trace_id_type_shift) |
117 ((voucher_activity_trace_id_t)code_namespace <<
118 _voucher_activity_trace_id_code_namespace_shift) |
119 (voucher_activity_trace_id_t)code;
120 }
121
122 /*!
123 * @function voucher_activity_start
124 *
125 * @abstract
126 * Creates a new activity identifier and marks the current thread as
127 * participating in the activity.
128 *
129 * @discussion
130 * As part of voucher transport, activities are automatically propagated by the
131 * system to other threads and processes (across IPC).
132 *
133 * Activities persist as long as any threads in any process are marked as
134 * participating. There may be many calls to voucher_activity_end()
135 * corresponding to one call to voucher_activity_start().
136 *
137 * @param trace_id
138 * Tracepoint identifier returned by voucher_activity_trace_id(), intended for
139 * identification of the automatic tracepoint generated as part of creating the
140 * new activity.
141 *
142 * @param flags
143 * Pass voucher_activity_flag_force to indicate that existing activities
144 * on the current thread should not be inherited and that a new toplevel
145 * activity should be created.
146 *
147 * @result
148 * A new activity identifier.
149 */
150 __OSX_AVAILABLE_STARTING(__MAC_10_10,__IPHONE_8_0)
151 OS_VOUCHER_EXPORT OS_WARN_RESULT OS_NOTHROW
152 voucher_activity_id_t
153 voucher_activity_start(voucher_activity_trace_id_t trace_id,
154 voucher_activity_flag_t flags);
155
156 /*!
157 * @function voucher_activity_start_with_location
158 *
159 * @abstract
160 * Creates a new activity identifier and marks the current thread as
161 * participating in the activity.
162 *
163 * @discussion
164 * As part of voucher transport, activities are automatically propagated by the
165 * system to other threads and processes (across IPC).
166 *
167 * Activities persist as long as any threads in any process are marked as
168 * participating. There may be many calls to voucher_activity_end()
169 * corresponding to one call to voucher_activity_start_with_location().
170 *
171 * @param trace_id
172 * Tracepoint identifier returned by voucher_activity_trace_id(), intended for
173 * identification of the automatic tracepoint generated as part of creating the
174 * new activity.
175 *
176 * @param location
177 * Location identifier for the automatic tracepoint generated as part of
178 * creating the new activity.
179 *
180 * @param flags
181 * Pass voucher_activity_flag_force to indicate that existing activities
182 * on the current thread should not be inherited and that a new toplevel
183 * activity should be created.
184 *
185 * @result
186 * A new activity identifier.
187 */
188 __OSX_AVAILABLE_STARTING(__MAC_10_10,__IPHONE_8_0)
189 OS_VOUCHER_EXPORT OS_WARN_RESULT OS_NOTHROW
190 voucher_activity_id_t
191 voucher_activity_start_with_location(voucher_activity_trace_id_t trace_id,
192 uint64_t location, voucher_activity_flag_t flags);
193
194 /*!
195 * @function voucher_activity_end
196 *
197 * @abstract
198 * Unmarks the current thread if it is marked as particpating in the activity
199 * with the specified identifier.
200 *
201 * @discussion
202 * Activities persist as long as any threads in any process are marked as
203 * participating. There may be many calls to voucher_activity_end()
204 * corresponding to one call to voucher_activity_start() or
205 * voucher_activity_start_with_location().
206 */
207 __OSX_AVAILABLE_STARTING(__MAC_10_10,__IPHONE_8_0)
208 OS_VOUCHER_EXPORT OS_NOTHROW
209 void
210 voucher_activity_end(voucher_activity_id_t activity_id);
211
212 /*!
213 * @function voucher_get_activities
214 *
215 * @abstract
216 * Returns the list of activity identifiers that the current thread is marked
217 * with.
218 *
219 * @param entries
220 * Pointer to an array of activity identifiers to be filled in.
221 *
222 * @param count
223 * Pointer to the requested number of activity identifiers.
224 * On output will be filled with the number of activities that are available.
225 *
226 * @result
227 * Number of activity identifiers written to 'entries'
228 */
229 __OSX_AVAILABLE_STARTING(__MAC_10_10,__IPHONE_8_0)
230 OS_VOUCHER_EXPORT OS_NOTHROW
231 unsigned int
232 voucher_get_activities(voucher_activity_id_t *entries, unsigned int *count);
233
234 /*!
235 * @group Voucher Activity Trace SPI
236 * SPI intended for libtrace only
237 */
238
239 /*!
240 * @function voucher_activity_get_namespace
241 *
242 * @abstract
243 * Returns the namespace of the current activity.
244 *
245 * @result
246 * The namespace of the current activity (if any).
247 */
248 __OSX_AVAILABLE_STARTING(__MAC_10_10,__IPHONE_8_0)
249 OS_VOUCHER_EXPORT OS_NOTHROW
250 uint8_t
251 voucher_activity_get_namespace(void);
252
253 /*!
254 * @function voucher_activity_trace
255 *
256 * @abstract
257 * Add a tracepoint to trace buffer of the current activity.
258 *
259 * @param trace_id
260 * Tracepoint identifier returned by voucher_activity_trace_id()
261 *
262 * @param location
263 * Tracepoint location.
264 *
265 * @param buffer
266 * Pointer to packed buffer of tracepoint data.
267 *
268 * @param length
269 * Length of data at 'buffer'.
270 *
271 * @result
272 * Timestamp recorded in tracepoint or 0 if no tracepoint was recorded.
273 */
274 __OSX_AVAILABLE_STARTING(__MAC_10_10,__IPHONE_8_0)
275 OS_VOUCHER_EXPORT OS_NOTHROW
276 uint64_t
277 voucher_activity_trace(voucher_activity_trace_id_t trace_id, uint64_t location,
278 void *buffer, size_t length);
279
280 /*!
281 * @function voucher_activity_trace_args
282 *
283 * @abstract
284 * Add a tracepoint to trace buffer of the current activity, recording
285 * specified arguments passed in registers.
286 *
287 * @param trace_id
288 * Tracepoint identifier returned by voucher_activity_trace_id()
289 *
290 * @param location
291 * Tracepoint location.
292 *
293 * @param arg1
294 * Argument to be recorded in tracepoint data.
295 *
296 * @param arg2
297 * Argument to be recorded in tracepoint data.
298 *
299 * @param arg3
300 * Argument to be recorded in tracepoint data.
301 *
302 * @param arg4
303 * Argument to be recorded in tracepoint data.
304 *
305 * @result
306 * Timestamp recorded in tracepoint or 0 if no tracepoint was recorded.
307 */
308 __OSX_AVAILABLE_STARTING(__MAC_10_10,__IPHONE_8_0)
309 OS_VOUCHER_EXPORT OS_NOTHROW
310 uint64_t
311 voucher_activity_trace_args(voucher_activity_trace_id_t trace_id,
312 uint64_t location, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3,
313 uintptr_t arg4);
314
315 /*!
316 * @group Voucher Activity Mode SPI
317 * SPI intended for libtrace only
318 */
319
320 /*!
321 * @enum voucher_activity_mode_t
322 *
323 * @abstract
324 * Voucher activity mode.
325 *
326 * @discussion
327 * Configure at process start by setting the OS_ACTIVITY_MODE environment
328 * variable.
329 */
330 OS_ENUM(voucher_activity_mode, unsigned long,
331 voucher_activity_mode_disable = 0,
332 voucher_activity_mode_release = (1u << 0),
333 voucher_activity_mode_debug = (1u << 1),
334 voucher_activity_mode_stream = (1u << 2),
335 );
336
337 /*!
338 * @function voucher_activity_get_mode
339 *
340 * @abstract
341 * Return current mode of voucher activity subsystem.
342 *
343 * @result
344 * Value from voucher_activity_mode_t enum.
345 */
346 __OSX_AVAILABLE_STARTING(__MAC_10_10,__IPHONE_8_0)
347 OS_VOUCHER_EXPORT OS_WARN_RESULT OS_NOTHROW
348 voucher_activity_mode_t
349 voucher_activity_get_mode(void);
350
351 /*!
352 * @function voucher_activity_set_mode_4libtrace(void)
353 *
354 * @abstract
355 * Set the current mode of voucher activity subsystem.
356 *
357 * @param mode
358 * The new mode.
359 *
360 * Note that the new mode will take effect soon, but not immediately.
361 */
362 __OSX_AVAILABLE_STARTING(__MAC_10_10,__IPHONE_8_0)
363 OS_VOUCHER_EXPORT OS_NOTHROW
364 void
365 voucher_activity_set_mode_4libtrace(voucher_activity_mode_t mode);
366
367 /*!
368 * @group Voucher Activity Metadata SPI
369 * SPI intended for libtrace only
370 */
371
372 /*!
373 * @function voucher_activity_get_metadata_buffer
374 *
375 * @abstract
376 * Return address and length of buffer in the process trace memory area
377 * reserved for libtrace metadata.
378 *
379 * @param length
380 * Pointer to size_t variable, filled with length of metadata buffer.
381 *
382 * @result
383 * Address of metadata buffer.
384 */
385 __OSX_AVAILABLE_STARTING(__MAC_10_10,__IPHONE_8_0)
386 OS_VOUCHER_EXPORT OS_WARN_RESULT OS_NOTHROW OS_NONNULL_ALL
387 void*
388 voucher_activity_get_metadata_buffer(size_t *length);
389
390 #endif // OS_VOUCHER_ACTIVITY_SPI
391
392 #if OS_VOUCHER_ACTIVITY_BUFFER_SPI
393
394 /*!
395 * @group Voucher Activity Tracepoint SPI
396 * SPI intended for diagnosticd only
397 */
398
399 OS_ENUM(_voucher_activity_tracepoint_flag, uint16_t,
400 _voucher_activity_trace_flag_buffer_empty = 0,
401 _voucher_activity_trace_flag_tracepoint = (1u << 0),
402 _voucher_activity_trace_flag_tracepoint_args = (1u << 1),
403 _voucher_activity_trace_flag_wide_first = (1u << 6),
404 _voucher_activity_trace_flag_wide_second = (1u << 6) | (1u << 7),
405 _voucher_activity_trace_flag_start = (1u << 8),
406 _voucher_activity_trace_flag_end = (1u << 8) | (1u << 9),
407 _voucher_activity_trace_flag_libdispatch = (1u << 13),
408 _voucher_activity_trace_flag_activity = (1u << 14),
409 _voucher_activity_trace_flag_buffer_header = (1u << 15),
410 );
411
412 // for tracepoints with _voucher_activity_trace_flag_libdispatch
413 OS_ENUM(_voucher_activity_tracepoint_namespace, uint8_t,
414 _voucher_activity_tracepoint_namespace_ipc = 0x1
415 );
416 OS_ENUM(_voucher_activity_tracepoint_code, uint32_t,
417 _voucher_activity_tracepoint_namespace_ipc_send = 0x1,
418 _voucher_activity_tracepoint_namespace_ipc_receive = 0x2,
419 );
420
421 typedef struct _voucher_activity_tracepoint_s {
422 uint16_t vat_flags; // voucher_activity_tracepoint_flag_t
423 uint8_t vat_type; // voucher_activity_tracepoint_type_t
424 uint8_t vat_namespace; // namespace for tracepoint code
425 uint32_t vat_code; // tracepoint code
426 uint64_t vat_thread; // pthread_t
427 uint64_t vat_timestamp; // absolute time
428 uint64_t vat_location; // tracepoint PC
429 uint64_t vat_data[4]; // trace data
430 } *_voucher_activity_tracepoint_t;
431
432 /*!
433 * @group Voucher Activity Buffer Internals
434 * SPI intended for diagnosticd only
435 * Layout of structs is subject to change without notice
436 */
437
438 #include <sys/queue.h>
439 #include <atm/atm_types.h>
440 #include <os/lock_private.h>
441
442 static const atm_subaid32_t _voucher_default_activity_subid =
443 ATM_SUBAID32_MAX-1;
444
445 static const size_t _voucher_activity_buffer_size = 4096;
446 static const size_t _voucher_activity_tracepoints_per_buffer =
447 _voucher_activity_buffer_size /
448 sizeof(struct _voucher_activity_tracepoint_s);
449 typedef uint8_t _voucher_activity_buffer_t[_voucher_activity_buffer_size];
450
451 struct _voucher_activity_self_metadata_s {
452 struct _voucher_activity_metadata_opaque_s *vasm_baseaddr;
453 };
454 typedef struct _voucher_activity_metadata_opaque_s {
455 _voucher_activity_buffer_t vam_kernel_metadata;
456 _voucher_activity_buffer_t vam_client_metadata;
457 union {
458 struct _voucher_activity_self_metadata_s vam_self_metadata;
459 _voucher_activity_buffer_t vam_self_metadata_opaque;
460 };
461 } *_voucher_activity_metadata_opaque_t;
462
463 typedef os_lock_handoff_s _voucher_activity_lock_s;
464
465 typedef struct _voucher_atm_s {
466 int32_t volatile vatm_refcnt;
467 mach_voucher_t vatm_kvoucher;
468 atm_aid_t vatm_id;
469 atm_mailbox_offset_t vatm_mailbox_offset;
470 TAILQ_ENTRY(_voucher_atm_s) vatm_list;
471 #if __LP64__
472 uintptr_t vatm_pad[3];
473 // cacheline
474 #endif
475 _voucher_activity_lock_s vatm_activities_lock;
476 TAILQ_HEAD(_voucher_atm_activities_s, _voucher_activity_s) vatm_activities;
477 TAILQ_HEAD(, _voucher_activity_s) vatm_used_activities;
478 } *_voucher_atm_t;
479
480 // must match layout of _voucher_activity_tracepoint_s
481 typedef struct _voucher_activity_buffer_header_s {
482 uint16_t vabh_flags; // _voucher_activity_trace_flag_buffer_header
483 uint8_t vabh_unused[6];
484 uint64_t vabh_thread;
485 uint64_t vabh_timestamp;
486 uint32_t volatile vabh_next_tracepoint_idx;
487 uint32_t vabh_sequence_no;
488 voucher_activity_id_t vabh_activity_id;
489 uint64_t vabh_reserved;
490 TAILQ_ENTRY(_voucher_activity_buffer_header_s) vabh_list;
491 } *_voucher_activity_buffer_header_t;
492
493 // must match layout of _voucher_activity_buffer_header_s
494 typedef struct _voucher_activity_s {
495 // first tracepoint entry
496 // must match layout of _voucher_activity_tracepoint_s
497 uint16_t va_flags; // _voucher_activity_trace_flag_buffer_header |
498 // _voucher_activity_trace_flag_activity |
499 // _voucher_activity_trace_flag_start |
500 // _voucher_activity_trace_flag_wide_first
501 uint8_t va_type;
502 uint8_t va_namespace;
503 uint32_t va_code;
504 uint64_t va_thread;
505 uint64_t va_timestamp;
506 uint32_t volatile vabh_next_tracepoint_idx;
507 uint32_t volatile va_max_sequence_no;
508 voucher_activity_id_t va_id;
509 int32_t volatile va_use_count;
510 uint32_t va_buffer_limit;
511 TAILQ_HEAD(_voucher_activity_buffer_list_s,
512 _voucher_activity_buffer_header_s) va_buffers;
513 #if !__LP64__
514 uint64_t va_pad;
515 #endif
516
517 // second tracepoint entry
518 // must match layout of _voucher_activity_tracepoint_s
519 uint16_t va_flags2;
520 uint8_t va_unused2[2];
521 int32_t volatile va_refcnt;
522 uint64_t va_location;
523 _voucher_activity_buffer_header_t volatile va_current_buffer;
524 _voucher_atm_t va_atm;
525 _voucher_activity_lock_s va_buffers_lock;
526 uintptr_t va_pad2[2];
527
528 #if __LP64__
529 // third tracepoint entry
530 // must match layout of _voucher_activity_tracepoint_s
531 uint16_t va_flags3;
532 uint8_t va_unused3[6];
533 uintptr_t va_pad3;
534 #endif
535 TAILQ_ENTRY(_voucher_activity_s) va_list;
536 TAILQ_ENTRY(_voucher_activity_s) va_atm_list;
537 TAILQ_ENTRY(_voucher_activity_s) va_atm_used_list;
538 } *_voucher_activity_t;
539
540 #endif // OS_VOUCHER_ACTIVITY_BUFFER_SPI
541
542 __END_DECLS
543
544 #endif // __OS_VOUCHER_ACTIVITY_PRIVATE__