1/*
2 * Copyright (c) 2021 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28
29#ifndef _KERN_SMR_TYPES_H_
30#define _KERN_SMR_TYPES_H_
31
32#include <sys/cdefs.h>
33#include <stdbool.h>
34#include <stdint.h>
35#include <os/base.h>
36
37__BEGIN_DECLS
38
39/*!
40 * @typedef smr_seq_t
41 *
42 * @brief
43 * Represents an opaque SMR sequence number.
44 */
45typedef unsigned long smr_seq_t;
46
47/*!
48 * @typedef smr_t
49 *
50 * @brief
51 * Type for an SMR domain.
52 */
53typedef struct smr *smr_t;
54
55
56/*!
57 * @typedef smr_node_t
58 *
59 * @brief
60 * Intrusive data structure used with @c ssmr_call() to defer callbacks
61 * to a safe time.
62 */
63typedef struct smr_node *smr_node_t;
64
65/*!
66 * @typedef smr_cb_t
67 *
68 * @brief
69 * A callback acting on an @c smr_node_t to destroy it.
70 */
71typedef void (*smr_cb_t)(smr_node_t);
72
73struct smr_node {
74 struct smr_node *smrn_next;
75 smr_cb_t XNU_PTRAUTH_SIGNED_FUNCTION_PTR("ssmr_cb_t") smrn_cb;
76};
77
78/*!
79 * @macro SMR_POINTER_DECL
80 *
81 * @brief
82 * Macro to declare a pointer type that uses SMR for access.
83 */
84#define SMR_POINTER_DECL(name, type_t) \
85 struct name { type_t volatile __smr_ptr; }
86
87/*!
88 * @macro SMR_POINTER
89 *
90 * @brief
91 * Macro to declare a pointer that uses SMR for access.
92 */
93#define SMR_POINTER(type_t) \
94 SMR_POINTER_DECL(, type_t)
95
96
97/* internal types that clients should not use directly */
98typedef SMR_POINTER(struct smrq_slink *) __smrq_slink_t;
99typedef SMR_POINTER(struct smrq_link *) __smrq_link_t;
100
101
102/*!
103 * @struct smrq_slink
104 *
105 * @brief
106 * Type used to represent a linkage in an SMR queue
107 * (single form, with O(n) deletion).
108 */
109struct smrq_slink {
110 __smrq_slink_t next;
111};
112
113/*!
114 * @struct smrq_link
115 *
116 * @brief
117 * Type used to represent a linkage in an SMR queue
118 * (double form, with O(1) deletion).
119 */
120struct smrq_link {
121 __smrq_link_t next;
122 __smrq_link_t *prev;
123};
124
125
126/*!
127 * @struct smrq_slist_head
128 *
129 * @brief
130 * Type used to represent the head of a singly linked list.
131 *
132 * @discussion
133 * This must be used with @c smrq_slink linkages.
134 *
135 * This type supports:
136 * - insertion at the head,
137 * - O(n) removal / replacement.
138 */
139struct smrq_slist_head {
140 __smrq_slink_t first;
141};
142
143#define SMRQ_SLIST_INITIALIZER(name) \
144 { .first = { NULL } }
145
146/*!
147 * @struct smrq_list_head
148 *
149 * @brief
150 * Type used to represent the head of a doubly linked list.
151 *
152 * @discussion
153 * This must be used with @c smrq_link linkages.
154 *
155 * This type supports:
156 * - insertion at the head,
157 * - O(1) removal / replacement.
158 */
159struct smrq_list_head {
160 __smrq_link_t first;
161};
162
163#define SMRQ_LIST_INITIALIZER(name) \
164 { .first = { NULL } }
165
166/*!
167 * @struct smrq_stailq_head
168 *
169 * @brief
170 * Type used to represent the head of a singly linked tail-queue.
171 *
172 * @discussion
173 * This must be used with @c smrq_slink linkages.
174 *
175 * This type supports:
176 * - insertion at the head,
177 * - insertion at the tail,
178 * - O(n) removal / replacement.
179 */
180struct smrq_stailq_head {
181 __smrq_slink_t first;
182 __smrq_slink_t *last;
183};
184
185#define SMRQ_STAILQ_INITIALIZER(name) \
186 { .first = { NULL }, .last = &(name).first }
187
188/*!
189 * @struct smrq_tailq_head
190 *
191 * @brief
192 * Type used to represent the head of a doubly linked tail-queue.
193 *
194 * @discussion
195 * This must be used with @c smrq_link linkages.
196 *
197 * This type supports:
198 * - insertion at the head,
199 * - insertion at the tail,
200 * - O(1) removal / replacement.
201 */
202struct smrq_tailq_head {
203 __smrq_link_t first;
204 __smrq_link_t *last;
205};
206
207#define SMRQ_TAILQ_INITIALIZER(name) \
208 { .first = { NULL }, .last = &(name).first }
209
210__END_DECLS
211
212#endif /* _KERN_SMR_TYPES_H_ */
213