2 * Copyright (c) 2013-2014 Apple Inc. All rights reserved.
4 * @APPLE_APACHE_LICENSE_HEADER_START@
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 * @APPLE_APACHE_LICENSE_HEADER_END@
21 #ifndef __OS_VOUCHER_ACTIVITY_PRIVATE__
22 #define __OS_VOUCHER_ACTIVITY_PRIVATE__
25 #include <os/object.h>
26 #if !defined(__DISPATCH_BUILDING_DISPATCH__)
27 #include <os/voucher_private.h>
30 #define OS_VOUCHER_ACTIVITY_SPI_VERSION 20150318
32 #if OS_VOUCHER_WEAK_IMPORT
33 #define OS_VOUCHER_EXPORT OS_EXPORT OS_WEAK_IMPORT
35 #define OS_VOUCHER_EXPORT OS_EXPORT
40 #if OS_VOUCHER_ACTIVITY_SPI
43 * @group Voucher Activity SPI
44 * SPI intended for libtrace only
48 * @typedef voucher_activity_id_t
51 * Opaque activity identifier.
54 * Scalar value type, not reference counted.
56 typedef uint64_t voucher_activity_id_t
;
59 * @enum voucher_activity_tracepoint_type_t
62 * Types of tracepoints.
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),
72 * @enum voucher_activity_flag_t
75 * Flags to pass to voucher_activity_start/voucher_activity_start_with_location
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,
86 * @typedef voucher_activity_trace_id_t
89 * Opaque tracepoint identifier.
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;
96 * @function voucher_activity_trace_id
99 * Return tracepoint identifier for specified arguments.
102 * Tracepoint type from voucher_activity_tracepoint_type_t.
104 * @param code_namespace
105 * Namespace of 'code' argument.
111 * Tracepoint identifier.
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
)
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
;
126 * @function voucher_activity_start
129 * Creates a new activity identifier and marks the current thread as
130 * participating in the activity.
133 * As part of voucher transport, activities are automatically propagated by the
134 * system to other threads and processes (across IPC).
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().
141 * Tracepoint identifier returned by voucher_activity_trace_id(), intended for
142 * identification of the automatic tracepoint generated as part of creating the
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.
151 * A new activity identifier.
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
);
160 * @function voucher_activity_start_with_location
163 * Creates a new activity identifier and marks the current thread as
164 * participating in the activity.
167 * As part of voucher transport, activities are automatically propagated by the
168 * system to other threads and processes (across IPC).
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().
175 * Tracepoint identifier returned by voucher_activity_trace_id(), intended for
176 * identification of the automatic tracepoint generated as part of creating the
180 * Location identifier for the automatic tracepoint generated as part of
181 * creating the new activity.
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.
189 * A new activity identifier.
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
);
198 * @function voucher_activity_end
201 * Unmarks the current thread if it is marked as particpating in the activity
202 * with the specified identifier.
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().
210 __OSX_AVAILABLE_STARTING(__MAC_10_10
,__IPHONE_8_0
)
211 OS_VOUCHER_EXPORT OS_NOTHROW
213 voucher_activity_end(voucher_activity_id_t activity_id
);
216 * @function voucher_get_activities
219 * Returns the list of activity identifiers that the current thread is marked
223 * Pointer to an array of activity identifiers to be filled in.
226 * Pointer to the requested number of activity identifiers.
227 * On output will be filled with the number of activities that are available.
230 * Number of activity identifiers written to 'entries'
232 __OSX_AVAILABLE_STARTING(__MAC_10_10
,__IPHONE_8_0
)
233 OS_VOUCHER_EXPORT OS_NOTHROW
235 voucher_get_activities(voucher_activity_id_t
*entries
, unsigned int *count
);
238 * @group Voucher Activity Trace SPI
239 * SPI intended for libtrace only
243 * @function voucher_activity_get_namespace
246 * Returns the namespace of the current activity.
249 * The namespace of the current activity (if any).
251 __OSX_AVAILABLE_STARTING(__MAC_10_10
,__IPHONE_8_0
)
252 OS_VOUCHER_EXPORT OS_NOTHROW
254 voucher_activity_get_namespace(void);
257 * @function voucher_activity_trace
260 * Add a tracepoint to trace buffer of the current activity.
263 * Tracepoint identifier returned by voucher_activity_trace_id()
266 * Tracepoint location.
269 * Pointer to packed buffer of tracepoint data.
272 * Length of data at 'buffer'.
275 * Timestamp recorded in tracepoint or 0 if no tracepoint was recorded.
277 __OSX_AVAILABLE_STARTING(__MAC_10_10
,__IPHONE_8_0
)
278 OS_VOUCHER_EXPORT OS_NOTHROW
280 voucher_activity_trace(voucher_activity_trace_id_t trace_id
, uint64_t location
,
281 void *buffer
, size_t length
);
284 * @function voucher_activity_trace_strings
287 * Add a tracepoint with strings data to trace buffer of the current activity.
290 * Tracepoint identifier returned by voucher_activity_trace_id()
293 * Tracepoint location.
296 * Pointer to packed buffer of tracepoint data.
299 * Length of data at 'buffer'.
302 * NULL-terminated array of strings data.
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]).
310 * @param total_strings_size
311 * Total size of all strings data to be copied from strings array (including
312 * all NUL-terminators).
315 * Timestamp recorded in tracepoint or 0 if no tracepoint was recorded.
317 __OSX_AVAILABLE_STARTING(__MAC_10_11
,__IPHONE_9_0
)
318 OS_VOUCHER_EXPORT OS_NOTHROW
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
);
325 * @function voucher_activity_trace_args
328 * Add a tracepoint to trace buffer of the current activity, recording
329 * specified arguments passed in registers.
332 * Tracepoint identifier returned by voucher_activity_trace_id()
335 * Tracepoint location.
338 * Argument to be recorded in tracepoint data.
341 * Argument to be recorded in tracepoint data.
344 * Argument to be recorded in tracepoint data.
347 * Argument to be recorded in tracepoint data.
350 * Timestamp recorded in tracepoint or 0 if no tracepoint was recorded.
352 __OSX_AVAILABLE_STARTING(__MAC_10_10
,__IPHONE_8_0
)
353 OS_VOUCHER_EXPORT OS_NOTHROW
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
,
360 * @group Voucher Activity Mode SPI
361 * SPI intended for libtrace only
365 * @enum voucher_activity_mode_t
368 * Voucher activity mode.
371 * Configure at process start by setting the OS_ACTIVITY_MODE environment
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),
382 * @function voucher_activity_get_mode
385 * Return current mode of voucher activity subsystem.
388 * Value from voucher_activity_mode_t enum.
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);
396 * @function voucher_activity_set_mode_4libtrace
399 * Set the current mode of voucher activity subsystem.
404 * Note that the new mode will take effect soon, but not immediately.
406 __OSX_AVAILABLE_STARTING(__MAC_10_10
,__IPHONE_8_0
)
407 OS_VOUCHER_EXPORT OS_NOTHROW
409 voucher_activity_set_mode_4libtrace(voucher_activity_mode_t mode
);
412 * @group Voucher Activity Metadata SPI
413 * SPI intended for libtrace only
417 * @function voucher_activity_get_metadata_buffer
420 * Return address and length of buffer in the process trace memory area
421 * reserved for libtrace metadata.
424 * Pointer to size_t variable, filled with length of metadata buffer.
427 * Address of metadata buffer.
429 __OSX_AVAILABLE_STARTING(__MAC_10_10
,__IPHONE_8_0
)
430 OS_VOUCHER_EXPORT OS_WARN_RESULT OS_NOTHROW OS_NONNULL_ALL
432 voucher_activity_get_metadata_buffer(size_t *length
);
434 #endif // OS_VOUCHER_ACTIVITY_SPI
436 #if OS_VOUCHER_ACTIVITY_BUFFER_SPI
439 * @group Voucher Activity Tracepoint SPI
440 * SPI intended for diagnosticd only
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),
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
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,
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
475 uint64_t vat_data
[4]; // trace data
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
481 } *_voucher_activity_tracepoint_t
;
484 * @group Voucher Activity Buffer Internals
485 * SPI intended for diagnosticd only
486 * Layout of structs is subject to change without notice
489 #include <sys/queue.h>
490 #include <atm/atm_types.h>
491 #include <os/lock_private.h>
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
501 typedef uint8_t _voucher_activity_buffer_t
[_voucher_activity_buffer_size
];
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)));
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
;
519 typedef struct _voucher_activity_metadata_opaque_s
{
520 _voucher_activity_buffer_t vam_client_metadata
;
522 struct _voucher_activity_self_metadata_s vam_self_metadata
;
523 _voucher_activity_buffer_t vam_self_metadata_opaque
;
525 } *_voucher_activity_metadata_opaque_t
;
527 typedef os_lock_handoff_s _voucher_activity_lock_s
;
529 OS_ENUM(_voucher_activity_buffer_atomic_flags
, uint8_t,
530 _voucher_activity_buffer_full
= (1u << 0),
531 _voucher_activity_buffer_pushing
= (1u << 1),
535 uint64_t vabp_atomic_pos
;
537 uint16_t vabp_refcnt
;
540 uint16_t vabp_next_tracepoint_idx
;
541 uint16_t vabp_string_offset
; // offset from the _end_ of the buffer
543 } _voucher_activity_buffer_position_u
;
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
549 uint8_t vat_namespace
;
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
;
560 * @enum _voucher_activity_buffer_hook_reason
562 * @constant _voucher_activity_buffer_hook_reason_full
563 * Specified activity buffer is full.
564 * Will be reported reused or freed later.
566 * @constant _voucher_activity_buffer_hook_reason_reuse
567 * Specified activity buffer is about to be reused.
568 * Was previously reported as full.
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.
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
;
581 * @typedef _voucher_activity_buffer_hook_t
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.
590 * Reason for callback.
593 * Pointer to activity buffer.
595 typedef void (*_voucher_activity_buffer_hook_t
)(
596 _voucher_activity_buffer_hook_reason reason
,
597 _voucher_activity_buffer_header_t buffer
);
600 * @function voucher_activity_buffer_hook_install_4libtrace
603 * Install activity buffer hook callback function.
604 * Must be called from the libtrace initializer, and at most once.
607 * Hook function to install.
609 __OSX_AVAILABLE_STARTING(__MAC_10_11
,__IPHONE_9_0
)
610 OS_VOUCHER_EXPORT OS_NOTHROW
612 voucher_activity_buffer_hook_install_4libtrace(
613 _voucher_activity_buffer_hook_t hook
);
615 #endif // OS_VOUCHER_ACTIVITY_BUFFER_SPI
619 #endif // __OS_VOUCHER_ACTIVITY_PRIVATE__