]> git.saurik.com Git - apple/libdispatch.git/blob - private/voucher_activity_private.h
libdispatch-501.40.12.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 20150318
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 voucher_activity_flag_debug = 0x2,
81 voucher_activity_flag_persist = 0x4,
82 voucher_activity_flag_stream = 0x8,
83 );
84
85 /*!
86 * @typedef voucher_activity_trace_id_t
87 *
88 * @abstract
89 * Opaque tracepoint identifier.
90 */
91 typedef uint64_t voucher_activity_trace_id_t;
92 static const uint8_t _voucher_activity_trace_id_type_shift = 40;
93 static const uint8_t _voucher_activity_trace_id_code_namespace_shift = 32;
94
95 /*!
96 * @function voucher_activity_trace_id
97 *
98 * @abstract
99 * Return tracepoint identifier for specified arguments.
100 *
101 * @param type
102 * Tracepoint type from voucher_activity_tracepoint_type_t.
103 *
104 * @param code_namespace
105 * Namespace of 'code' argument.
106 *
107 * @param code
108 * Tracepoint code.
109 *
110 * @result
111 * Tracepoint identifier.
112 */
113 __OSX_AVAILABLE_STARTING(__MAC_10_10,__IPHONE_8_0)
114 OS_INLINE OS_ALWAYS_INLINE
115 voucher_activity_trace_id_t
116 voucher_activity_trace_id(uint8_t type, uint8_t code_namespace, uint32_t code)
117 {
118 return ((voucher_activity_trace_id_t)type <<
119 _voucher_activity_trace_id_type_shift) |
120 ((voucher_activity_trace_id_t)code_namespace <<
121 _voucher_activity_trace_id_code_namespace_shift) |
122 (voucher_activity_trace_id_t)code;
123 }
124
125 /*!
126 * @function voucher_activity_start
127 *
128 * @abstract
129 * Creates a new activity identifier and marks the current thread as
130 * participating in the activity.
131 *
132 * @discussion
133 * As part of voucher transport, activities are automatically propagated by the
134 * system to other threads and processes (across IPC).
135 *
136 * Activities persist as long as any threads in any process are marked as
137 * participating. There may be many calls to voucher_activity_end()
138 * corresponding to one call to voucher_activity_start().
139 *
140 * @param trace_id
141 * Tracepoint identifier returned by voucher_activity_trace_id(), intended for
142 * identification of the automatic tracepoint generated as part of creating the
143 * new activity.
144 *
145 * @param flags
146 * Pass voucher_activity_flag_force to indicate that existing activities
147 * on the current thread should not be inherited and that a new toplevel
148 * activity should be created.
149 *
150 * @result
151 * A new activity identifier.
152 */
153 __OSX_AVAILABLE_STARTING(__MAC_10_10,__IPHONE_8_0)
154 OS_VOUCHER_EXPORT OS_WARN_RESULT OS_NOTHROW
155 voucher_activity_id_t
156 voucher_activity_start(voucher_activity_trace_id_t trace_id,
157 voucher_activity_flag_t flags);
158
159 /*!
160 * @function voucher_activity_start_with_location
161 *
162 * @abstract
163 * Creates a new activity identifier and marks the current thread as
164 * participating in the activity.
165 *
166 * @discussion
167 * As part of voucher transport, activities are automatically propagated by the
168 * system to other threads and processes (across IPC).
169 *
170 * Activities persist as long as any threads in any process are marked as
171 * participating. There may be many calls to voucher_activity_end()
172 * corresponding to one call to voucher_activity_start_with_location().
173 *
174 * @param trace_id
175 * Tracepoint identifier returned by voucher_activity_trace_id(), intended for
176 * identification of the automatic tracepoint generated as part of creating the
177 * new activity.
178 *
179 * @param location
180 * Location identifier for the automatic tracepoint generated as part of
181 * creating the new activity.
182 *
183 * @param flags
184 * Pass voucher_activity_flag_force to indicate that existing activities
185 * on the current thread should not be inherited and that a new toplevel
186 * activity should be created.
187 *
188 * @result
189 * A new activity identifier.
190 */
191 __OSX_AVAILABLE_STARTING(__MAC_10_10,__IPHONE_8_0)
192 OS_VOUCHER_EXPORT OS_WARN_RESULT OS_NOTHROW
193 voucher_activity_id_t
194 voucher_activity_start_with_location(voucher_activity_trace_id_t trace_id,
195 uint64_t location, voucher_activity_flag_t flags);
196
197 /*!
198 * @function voucher_activity_end
199 *
200 * @abstract
201 * Unmarks the current thread if it is marked as particpating in the activity
202 * with the specified identifier.
203 *
204 * @discussion
205 * Activities persist as long as any threads in any process are marked as
206 * participating. There may be many calls to voucher_activity_end()
207 * corresponding to one call to voucher_activity_start() or
208 * voucher_activity_start_with_location().
209 */
210 __OSX_AVAILABLE_STARTING(__MAC_10_10,__IPHONE_8_0)
211 OS_VOUCHER_EXPORT OS_NOTHROW
212 void
213 voucher_activity_end(voucher_activity_id_t activity_id);
214
215 /*!
216 * @function voucher_get_activities
217 *
218 * @abstract
219 * Returns the list of activity identifiers that the current thread is marked
220 * with.
221 *
222 * @param entries
223 * Pointer to an array of activity identifiers to be filled in.
224 *
225 * @param count
226 * Pointer to the requested number of activity identifiers.
227 * On output will be filled with the number of activities that are available.
228 *
229 * @result
230 * Number of activity identifiers written to 'entries'
231 */
232 __OSX_AVAILABLE_STARTING(__MAC_10_10,__IPHONE_8_0)
233 OS_VOUCHER_EXPORT OS_NOTHROW
234 unsigned int
235 voucher_get_activities(voucher_activity_id_t *entries, unsigned int *count);
236
237 /*!
238 * @group Voucher Activity Trace SPI
239 * SPI intended for libtrace only
240 */
241
242 /*!
243 * @function voucher_activity_get_namespace
244 *
245 * @abstract
246 * Returns the namespace of the current activity.
247 *
248 * @result
249 * The namespace of the current activity (if any).
250 */
251 __OSX_AVAILABLE_STARTING(__MAC_10_10,__IPHONE_8_0)
252 OS_VOUCHER_EXPORT OS_NOTHROW
253 uint8_t
254 voucher_activity_get_namespace(void);
255
256 /*!
257 * @function voucher_activity_trace
258 *
259 * @abstract
260 * Add a tracepoint to trace buffer of the current activity.
261 *
262 * @param trace_id
263 * Tracepoint identifier returned by voucher_activity_trace_id()
264 *
265 * @param location
266 * Tracepoint location.
267 *
268 * @param buffer
269 * Pointer to packed buffer of tracepoint data.
270 *
271 * @param length
272 * Length of data at 'buffer'.
273 *
274 * @result
275 * Timestamp recorded in tracepoint or 0 if no tracepoint was recorded.
276 */
277 __OSX_AVAILABLE_STARTING(__MAC_10_10,__IPHONE_8_0)
278 OS_VOUCHER_EXPORT OS_NOTHROW
279 uint64_t
280 voucher_activity_trace(voucher_activity_trace_id_t trace_id, uint64_t location,
281 void *buffer, size_t length);
282
283 /*!
284 * @function voucher_activity_trace_strings
285 *
286 * @abstract
287 * Add a tracepoint with strings data to trace buffer of the current activity.
288 *
289 * @param trace_id
290 * Tracepoint identifier returned by voucher_activity_trace_id()
291 *
292 * @param location
293 * Tracepoint location.
294 *
295 * @param buffer
296 * Pointer to packed buffer of tracepoint data.
297 *
298 * @param length
299 * Length of data at 'buffer'.
300 *
301 * @param strings
302 * NULL-terminated array of strings data.
303 *
304 * @param string_lengths
305 * Array of string lengths (required to have the same number of elements as the
306 * 'strings' array): string_lengths[i] is the maximum number of characters to
307 * copy from strings[i], excluding the NUL-terminator (may be smaller than the
308 * length of the string present in strings[i]).
309 *
310 * @param total_strings_size
311 * Total size of all strings data to be copied from strings array (including
312 * all NUL-terminators).
313 *
314 * @result
315 * Timestamp recorded in tracepoint or 0 if no tracepoint was recorded.
316 */
317 __OSX_AVAILABLE_STARTING(__MAC_10_11,__IPHONE_9_0)
318 OS_VOUCHER_EXPORT OS_NOTHROW
319 uint64_t
320 voucher_activity_trace_strings(voucher_activity_trace_id_t trace_id,
321 uint64_t location, void *buffer, size_t length, const char *strings[],
322 size_t string_lengths[], size_t total_strings_size);
323
324 /*!
325 * @function voucher_activity_trace_args
326 *
327 * @abstract
328 * Add a tracepoint to trace buffer of the current activity, recording
329 * specified arguments passed in registers.
330 *
331 * @param trace_id
332 * Tracepoint identifier returned by voucher_activity_trace_id()
333 *
334 * @param location
335 * Tracepoint location.
336 *
337 * @param arg1
338 * Argument to be recorded in tracepoint data.
339 *
340 * @param arg2
341 * Argument to be recorded in tracepoint data.
342 *
343 * @param arg3
344 * Argument to be recorded in tracepoint data.
345 *
346 * @param arg4
347 * Argument to be recorded in tracepoint data.
348 *
349 * @result
350 * Timestamp recorded in tracepoint or 0 if no tracepoint was recorded.
351 */
352 __OSX_AVAILABLE_STARTING(__MAC_10_10,__IPHONE_8_0)
353 OS_VOUCHER_EXPORT OS_NOTHROW
354 uint64_t
355 voucher_activity_trace_args(voucher_activity_trace_id_t trace_id,
356 uint64_t location, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3,
357 uintptr_t arg4);
358
359 /*!
360 * @group Voucher Activity Mode SPI
361 * SPI intended for libtrace only
362 */
363
364 /*!
365 * @enum voucher_activity_mode_t
366 *
367 * @abstract
368 * Voucher activity mode.
369 *
370 * @discussion
371 * Configure at process start by setting the OS_ACTIVITY_MODE environment
372 * variable.
373 */
374 OS_ENUM(voucher_activity_mode, unsigned long,
375 voucher_activity_mode_disable = 0,
376 voucher_activity_mode_release = (1u << 0),
377 voucher_activity_mode_debug = (1u << 1),
378 voucher_activity_mode_stream = (1u << 2),
379 );
380
381 /*!
382 * @function voucher_activity_get_mode
383 *
384 * @abstract
385 * Return current mode of voucher activity subsystem.
386 *
387 * @result
388 * Value from voucher_activity_mode_t enum.
389 */
390 __OSX_AVAILABLE_STARTING(__MAC_10_10,__IPHONE_8_0)
391 OS_VOUCHER_EXPORT OS_WARN_RESULT OS_NOTHROW
392 voucher_activity_mode_t
393 voucher_activity_get_mode(void);
394
395 /*!
396 * @function voucher_activity_set_mode_4libtrace
397 *
398 * @abstract
399 * Set the current mode of voucher activity subsystem.
400 *
401 * @param mode
402 * The new mode.
403 *
404 * Note that the new mode will take effect soon, but not immediately.
405 */
406 __OSX_AVAILABLE_STARTING(__MAC_10_10,__IPHONE_8_0)
407 OS_VOUCHER_EXPORT OS_NOTHROW
408 void
409 voucher_activity_set_mode_4libtrace(voucher_activity_mode_t mode);
410
411 /*!
412 * @group Voucher Activity Metadata SPI
413 * SPI intended for libtrace only
414 */
415
416 /*!
417 * @function voucher_activity_get_metadata_buffer
418 *
419 * @abstract
420 * Return address and length of buffer in the process trace memory area
421 * reserved for libtrace metadata.
422 *
423 * @param length
424 * Pointer to size_t variable, filled with length of metadata buffer.
425 *
426 * @result
427 * Address of metadata buffer.
428 */
429 __OSX_AVAILABLE_STARTING(__MAC_10_10,__IPHONE_8_0)
430 OS_VOUCHER_EXPORT OS_WARN_RESULT OS_NOTHROW OS_NONNULL_ALL
431 void*
432 voucher_activity_get_metadata_buffer(size_t *length);
433
434 #endif // OS_VOUCHER_ACTIVITY_SPI
435
436 #if OS_VOUCHER_ACTIVITY_BUFFER_SPI
437
438 /*!
439 * @group Voucher Activity Tracepoint SPI
440 * SPI intended for diagnosticd only
441 */
442
443 OS_ENUM(_voucher_activity_tracepoint_flag, uint16_t,
444 _voucher_activity_trace_flag_buffer_empty = 0,
445 _voucher_activity_trace_flag_tracepoint = (1u << 0),
446 _voucher_activity_trace_flag_tracepoint_args = (1u << 1),
447 _voucher_activity_trace_flag_tracepoint_strings = (1u << 2),
448 _voucher_activity_trace_flag_wide_first = (1u << 6),
449 _voucher_activity_trace_flag_wide_second = (1u << 6) | (1u << 7),
450 _voucher_activity_trace_flag_start = (1u << 8),
451 _voucher_activity_trace_flag_end = (1u << 8) | (1u << 9),
452 _voucher_activity_trace_flag_libdispatch = (1u << 13),
453 _voucher_activity_trace_flag_activity = (1u << 14),
454 _voucher_activity_trace_flag_buffer_header = (1u << 15),
455 );
456
457 // for tracepoints with _voucher_activity_trace_flag_libdispatch
458 OS_ENUM(_voucher_activity_tracepoint_namespace, uint8_t,
459 _voucher_activity_tracepoint_namespace_ipc = 0x1
460 );
461 OS_ENUM(_voucher_activity_tracepoint_code, uint32_t,
462 _voucher_activity_tracepoint_namespace_ipc_send = 0x1,
463 _voucher_activity_tracepoint_namespace_ipc_receive = 0x2,
464 );
465
466 typedef struct _voucher_activity_tracepoint_s {
467 uint16_t vat_flags; // voucher_activity_tracepoint_flag_t
468 uint8_t vat_type; // voucher_activity_tracepoint_type_t
469 uint8_t vat_namespace; // namespace for tracepoint code
470 uint32_t vat_code; // tracepoint code
471 uint64_t vat_thread; // pthread_t
472 uint64_t vat_timestamp; // absolute time
473 uint64_t vat_location; // tracepoint PC
474 union {
475 uint64_t vat_data[4]; // trace data
476 struct {
477 uint16_t vats_offset; // offset to string data (from buffer end)
478 uint8_t vats_data[30]; // trace data
479 } vat_stroff; // iff _vat_flag_tracepoint_strings present
480 };
481 } *_voucher_activity_tracepoint_t;
482
483 /*!
484 * @group Voucher Activity Buffer Internals
485 * SPI intended for diagnosticd only
486 * Layout of structs is subject to change without notice
487 */
488
489 #include <sys/queue.h>
490 #include <atm/atm_types.h>
491 #include <os/lock_private.h>
492
493 static const size_t _voucher_activity_buffer_size = 4096;
494 static const size_t _voucher_activity_tracepoints_per_buffer =
495 _voucher_activity_buffer_size /
496 sizeof(struct _voucher_activity_tracepoint_s);
497 static const size_t _voucher_activity_buffer_header_size =
498 sizeof(struct _voucher_activity_tracepoint_s);
499 static const size_t _voucher_activity_strings_header_size = 0; // TODO
500
501 typedef uint8_t _voucher_activity_buffer_t[_voucher_activity_buffer_size];
502
503 static const size_t _voucher_activity_buffers_per_heap = 512;
504 typedef unsigned long _voucher_activity_bitmap_base_t;
505 static const size_t _voucher_activity_bits_per_bitmap_base_t =
506 8 * sizeof(_voucher_activity_bitmap_base_t);
507 static const size_t _voucher_activity_bitmaps_per_heap =
508 _voucher_activity_buffers_per_heap /
509 _voucher_activity_bits_per_bitmap_base_t;
510 typedef _voucher_activity_bitmap_base_t
511 _voucher_activity_bitmap_t[_voucher_activity_bitmaps_per_heap]
512 __attribute__((__aligned__(64)));
513
514 struct _voucher_activity_self_metadata_s {
515 struct _voucher_activity_metadata_opaque_s *vasm_baseaddr;
516 _voucher_activity_bitmap_t volatile vam_buffer_bitmap;
517 };
518
519 typedef struct _voucher_activity_metadata_opaque_s {
520 _voucher_activity_buffer_t vam_client_metadata;
521 union {
522 struct _voucher_activity_self_metadata_s vam_self_metadata;
523 _voucher_activity_buffer_t vam_self_metadata_opaque;
524 };
525 } *_voucher_activity_metadata_opaque_t;
526
527 typedef os_lock_handoff_s _voucher_activity_lock_s;
528
529 OS_ENUM(_voucher_activity_buffer_atomic_flags, uint8_t,
530 _voucher_activity_buffer_full = (1u << 0),
531 _voucher_activity_buffer_pushing = (1u << 1),
532 );
533
534 typedef union {
535 uint64_t vabp_atomic_pos;
536 struct {
537 uint16_t vabp_refcnt;
538 uint8_t vabp_flags;
539 uint8_t vabp_unused;
540 uint16_t vabp_next_tracepoint_idx;
541 uint16_t vabp_string_offset; // offset from the _end_ of the buffer
542 } vabp_pos;
543 } _voucher_activity_buffer_position_u;
544
545 // must match layout of _voucher_activity_tracepoint_s
546 typedef struct _voucher_activity_buffer_header_s {
547 uint16_t vabh_flags; // _voucher_activity_trace_flag_buffer_header
548 uint8_t vat_type;
549 uint8_t vat_namespace;
550 uint32_t vat_code;
551 uint64_t vat_thread;
552 uint64_t vat_timestamp;
553 uint64_t vat_location;
554 voucher_activity_id_t vabh_activity_id;
555 _voucher_activity_buffer_position_u volatile vabh_pos;
556 TAILQ_ENTRY(_voucher_activity_buffer_header_s) vabh_list;
557 } *_voucher_activity_buffer_header_t;
558
559 /*!
560 * @enum _voucher_activity_buffer_hook_reason
561 *
562 * @constant _voucher_activity_buffer_hook_reason_full
563 * Specified activity buffer is full.
564 * Will be reported reused or freed later.
565 *
566 * @constant _voucher_activity_buffer_hook_reason_reuse
567 * Specified activity buffer is about to be reused.
568 * Was previously reported as full.
569 *
570 * @constant _voucher_activity_buffer_hook_reason_free
571 * Specified activity buffer is about to be freed.
572 * May have been previously reported as full or may be only partially filled.
573 */
574 typedef enum _voucher_activity_buffer_hook_reason {
575 _voucher_activity_buffer_hook_reason_full = 0x1,
576 _voucher_activity_buffer_hook_reason_reuse = 0x2,
577 _voucher_activity_buffer_hook_reason_free = 0x4,
578 } _voucher_activity_buffer_hook_reason;
579
580 /*!
581 * @typedef _voucher_activity_buffer_hook_t
582 *
583 * @abstract
584 * A function pointer called when an activity buffer is full or being freed.
585 * NOTE: callbacks occur under an activity-wide handoff lock and work done
586 * inside the callback function must not block or otherwise cause that lock to
587 * be held for a extended period of time.
588 *
589 * @param reason
590 * Reason for callback.
591 *
592 * @param buffer
593 * Pointer to activity buffer.
594 */
595 typedef void (*_voucher_activity_buffer_hook_t)(
596 _voucher_activity_buffer_hook_reason reason,
597 _voucher_activity_buffer_header_t buffer);
598
599 /*!
600 * @function voucher_activity_buffer_hook_install_4libtrace
601 *
602 * @abstract
603 * Install activity buffer hook callback function.
604 * Must be called from the libtrace initializer, and at most once.
605 *
606 * @param hook
607 * Hook function to install.
608 */
609 __OSX_AVAILABLE_STARTING(__MAC_10_11,__IPHONE_9_0)
610 OS_VOUCHER_EXPORT OS_NOTHROW
611 void
612 voucher_activity_buffer_hook_install_4libtrace(
613 _voucher_activity_buffer_hook_t hook);
614
615 #endif // OS_VOUCHER_ACTIVITY_BUFFER_SPI
616
617 __END_DECLS
618
619 #endif // __OS_VOUCHER_ACTIVITY_PRIVATE__