]> git.saurik.com Git - apple/libdispatch.git/blame - os/firehose_buffer_private.h
libdispatch-913.30.4.tar.gz
[apple/libdispatch.git] / os / firehose_buffer_private.h
CommitLineData
beb15981
A
1/*
2 * Copyright (c) 2015 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 __FIREHOSE_BUFFER_PRIVATE__
22#define __FIREHOSE_BUFFER_PRIVATE__
23
24#if OS_FIREHOSE_SPI
25#ifdef KERNEL
26#include <stdint.h>
27#else
28#include <os/base.h>
6b746eb4 29#include <os/availability.h>
beb15981
A
30#include <os/base_private.h>
31#include <dispatch/dispatch.h>
32#endif
33
6b746eb4 34#define OS_FIREHOSE_SPI_VERSION 20170222
beb15981
A
35
36/*!
37 * @group Firehose SPI
38 * SPI intended for logd only
39 * Layout of structs is subject to change without notice
40 */
41
beb15981
A
42#define FIREHOSE_BUFFER_LIBTRACE_HEADER_SIZE 2048ul
43#define FIREHOSE_BUFFER_KERNEL_CHUNK_COUNT 16
44
beb15981
A
45typedef struct firehose_buffer_range_s {
46 uint16_t fbr_offset; // offset from the start of the buffer
47 uint16_t fbr_length;
48} *firehose_buffer_range_t;
49
50#ifdef KERNEL
51
fa22f35b
A
52typedef struct firehose_chunk_s *firehose_chunk_t;
53
beb15981
A
54// implemented by the kernel
55extern void __firehose_buffer_push_to_logd(firehose_buffer_t fb, bool for_io);
56extern void __firehose_critical_region_enter(void);
57extern void __firehose_critical_region_leave(void);
58extern void __firehose_allocate(vm_offset_t *addr, vm_size_t size);
59
60// exported for the kernel
61firehose_tracepoint_t
62__firehose_buffer_tracepoint_reserve(uint64_t stamp, firehose_stream_t stream,
63 uint16_t pubsize, uint16_t privsize, uint8_t **privptr);
64
beb15981
A
65void
66__firehose_buffer_tracepoint_flush(firehose_tracepoint_t vat,
67 firehose_tracepoint_id_u vatid);
68
beb15981
A
69firehose_buffer_t
70__firehose_buffer_create(size_t *size);
71
72void
73__firehose_merge_updates(firehose_push_reply_t update);
74
75#else
76
77#define __firehose_critical_region_enter()
78#define __firehose_critical_region_leave()
79
80OS_EXPORT
81const uint32_t _firehose_spi_version;
82
83OS_ALWAYS_INLINE
84static inline const uint8_t *
fa22f35b 85_firehose_tracepoint_reader_init(firehose_chunk_t fc, const uint8_t **endptr)
beb15981 86{
fa22f35b
A
87 const uint8_t *start = fc->fc_data;
88 const uint8_t *end = fc->fc_start + fc->fc_pos.fcp_next_entry_offs;
beb15981 89
fa22f35b 90 if (end > fc->fc_start + FIREHOSE_CHUNK_SIZE) {
beb15981
A
91 end = start;
92 }
93 *endptr = end;
94 return start;
95}
96
97OS_ALWAYS_INLINE
98static inline firehose_tracepoint_t
99_firehose_tracepoint_reader_next(const uint8_t **ptr, const uint8_t *end)
100{
101 const uint16_t ft_size = offsetof(struct firehose_tracepoint_s, ft_data);
fa22f35b
A
102 struct ft_unaligned_s {
103 struct firehose_tracepoint_s ft;
104 } __attribute__((packed, aligned(1))) *uft;
beb15981
A
105
106 do {
fa22f35b
A
107 uft = (struct ft_unaligned_s *)*ptr;
108 if (uft->ft.ft_data >= end) {
beb15981
A
109 // reached the end
110 return NULL;
111 }
fa22f35b 112 if (!uft->ft.ft_length) {
beb15981
A
113 // tracepoint write didn't even start
114 return NULL;
115 }
fa22f35b 116 if (uft->ft.ft_length > end - uft->ft.ft_data) {
beb15981
A
117 // invalid length
118 return NULL;
119 }
fa22f35b 120 *ptr += roundup(ft_size + uft->ft.ft_length, 8);
beb15981 121 // test whether write of the tracepoint was finished
fa22f35b 122 } while (os_unlikely(uft->ft.ft_id.ftid_value == 0));
beb15981 123
fa22f35b 124 return (firehose_tracepoint_t)uft;
beb15981
A
125}
126
127#define firehose_tracepoint_foreach(ft, fbc) \
128 for (const uint8_t *end, *p = _firehose_tracepoint_reader_init(fbc, &end); \
129 ((ft) = _firehose_tracepoint_reader_next(&p, end)); )
130
131OS_ALWAYS_INLINE
132static inline bool
fa22f35b
A
133firehose_buffer_range_validate(firehose_chunk_t fc, firehose_tracepoint_t ft,
134 firehose_buffer_range_t range)
beb15981 135{
fa22f35b 136 if (range->fbr_offset + range->fbr_length > FIREHOSE_CHUNK_SIZE) {
beb15981
A
137 return false;
138 }
fa22f35b 139 if (fc->fc_start + range->fbr_offset < ft->ft_data + ft->ft_length) {
beb15981
A
140 return false;
141 }
142 return true;
143}
144
145#endif // !KERNEL
146
147#endif // OS_FIREHOSE_SPI
148
149#endif // __FIREHOSE_BUFFER_PRIVATE__