XenevaOS
Loading...
Searching...
No Matches
XenevaOS
BaseHdr
linux
list.h
Go to the documentation of this file.
1
#ifndef __LINUX_LIST_H__
2
#define __LINUX_LIST_H__
3
4
#include <
_null.h
>
5
#if !defined(__cplusplus)
6
/* Xeneva's list_add(list_t*, void*) must be declared before the list_add
7
* dispatch macro below, whichever header a file includes first. */
8
#include <
list.h
>
9
#endif
10
11
struct
list_head
{
12
struct
list_head
*
next
, *
prev
;
13
};
14
15
#define LIST_HEAD_INIT(name) { &(name), &(name) }
16
#define LIST_HEAD(name) struct list_head name = LIST_HEAD_INIT(name)
17
18
#define list_entry(ptr, type, member) \
19
container_of(ptr, type, member)
20
21
#define list_first_entry(ptr, type, member) \
22
list_entry((ptr)->next, type, member)
23
24
#define list_last_entry(ptr, type, member) \
25
list_entry((ptr)->prev, type, member)
26
27
#define list_next_entry(pos, member) \
28
list_entry((pos)->member.next, typeof(*(pos)), member)
29
30
#define list_prev_entry(pos, member) \
31
list_entry((pos)->member.prev, typeof(*(pos)), member)
32
33
/*
34
* The *_or_null accessors are mainline's guard against a list that turned
35
* out to be empty: list_first_entry() on an empty list computes a container
36
* out of the head's own address and returns it, so the caller gets a
37
* plausible-looking pointer that must not be dereferenced. These return
38
* NULL instead. READ_ONCE appears only inside macros, never inside a
39
* function body, which is why list.h does not have to include <kernel.h> to
40
* use it -- <kernel.h> includes this header at :110, long before READ_ONCE
41
* is defined at :576, and a macro is expanded where it is written, not
42
* where it is defined.
43
*/
44
#define list_entry_or_null(ptr, type, member) ({ \
45
struct list_head *head__ = (ptr); \
46
struct list_head *pos__ = READ_ONCE(head__->next); \
47
pos__ != head__ ? list_entry(pos__, type, member) : NULL; \
48
})
49
50
#define list_first_entry_or_null(ptr, type, member) \
51
list_entry_or_null(ptr, type, member)
52
53
#define list_last_entry_or_null(ptr, type, member) ({ \
54
struct list_head *head__ = (ptr); \
55
struct list_head *pos__ = READ_ONCE(head__->prev); \
56
pos__ != head__ ? list_entry(pos__, type, member) : NULL; \
57
})
58
59
#define list_for_each(pos, head) \
60
for (pos = (head)->next; pos != (head); pos = pos->next)
61
62
#define list_for_each_safe(pos, n, head) \
63
for (pos = (head)->next, n = pos->next; pos != (head); \
64
pos = n, n = pos->next)
65
66
#define list_for_each_entry(pos, head, member) \
67
for (pos = list_entry((head)->next, typeof(*pos), member); \
68
&pos->member != (head); \
69
pos = list_entry(pos->member.next, typeof(*pos), member))
70
71
#define list_for_each_entry_safe(pos, n, head, member) \
72
for (pos = list_entry((head)->next, typeof(*pos), member), \
73
n = list_entry(pos->member.next, typeof(*pos), member); \
74
&pos->member != (head); \
75
pos = n, n = list_entry(n->member.next, typeof(*pos), member))
76
77
#define list_for_each_entry_reverse(pos, head, member) \
78
for (pos = list_entry((head)->prev, typeof(*pos), member); \
79
&pos->member != (head); \
80
pos = list_entry(pos->member.prev, typeof(*pos), member))
81
82
/*
83
* list_entry_is_head() -- the loop condition shared by the four
84
* "resume from here" iterators below. They differ from
85
* list_for_each_entry() in where they start: that macro rewinds to the
86
* first element, these take `pos` as given and stop when it comes back
87
* around to the head. `pos` is therefore not assigned an initial value,
88
* and the caller must already hold a valid element.
89
*/
90
#define list_entry_is_head(pos, head, member) \
91
(&(pos)->member == (head))
92
93
#define list_for_each_entry_continue(pos, head, member) \
94
for (pos = list_next_entry(pos, member); \
95
!list_entry_is_head(pos, head, member); \
96
pos = list_next_entry(pos, member))
97
98
#define list_for_each_entry_continue_reverse(pos, head, member) \
99
for (pos = list_prev_entry(pos, member); \
100
!list_entry_is_head(pos, head, member); \
101
pos = list_prev_entry(pos, member))
102
103
#define list_for_each_entry_from(pos, head, member) \
104
for (; !list_entry_is_head(pos, head, member); \
105
pos = list_next_entry(pos, member))
106
107
#define list_for_each_entry_from_reverse(pos, head, member) \
108
for (; !list_entry_is_head(pos, head, member); \
109
pos = list_prev_entry(pos, member))
110
111
/*
112
* Mutation -- added for <linux/wait.h>, which keeps its queues in these
113
* lists. DCL had only the iteration macros, so a wait queue would have had
114
* nowhere to put an entry.
115
*
116
* LANDMINE, recorded so nobody has to rediscover it: Xeneva's own
117
* <list.h> -- a different, older API over `list_t` -- also exports a
118
* `list_add(list_t*, void*)`, and the two cannot be declared in one
119
* translation unit (they are both `list_add`, with different arguments; C
120
* has no overload). Nothing in the ported tty/serial set includes that
121
* header, so they coexist in the tree -- but a file that needs Xeneva's
122
* process/socket/network headers *and* a mainline list has to be split in
123
* two, or one of the two APIs renamed. DCL/linux_irq_shim.c takes the first
124
* route: the thread name it publishes in dcl_current() is fetched by
125
* DCL/current_ident.c, the one native-header TU, because
126
* <Hal/AA64/sched.h> (pthread merge, ad87f135) pulls <list.h> in just as
127
* <process.h> does.
128
*
129
* list_del() is deliberately idempotent: it clears the node and a second
130
* remove on an already-removed node is a no-op rather than a write through
131
* stale pointers. Mainline poisons the node instead, to catch the bug -- a
132
* reasonable trade when a mistake trips a debug kernel, but the wrong one
133
* here, where a doubly-removed wait entry would corrupt a queue that nothing
134
* else is checking, on a system with no lock protecting it either way.
135
*/
136
137
static
inline
void
__list_add(
struct
list_head
*
new
,
138
struct
list_head
*
prev
,
struct
list_head
*
next
)
139
{
140
next
->
prev
=
new
;
141
new
->
next
=
next
;
142
new
->
prev
=
prev
;
143
prev
->
next
=
new
;
144
}
145
146
static
inline
void
INIT_LIST_HEAD(
struct
list_head
*
list
)
147
{
148
list
->next =
list
;
149
list
->prev =
list
;
150
}
151
152
static
inline
void
linux_list_add(
struct
list_head
*
new
,
struct
list_head
*
head
)
153
{
154
__list_add(
new
,
head
,
head
->next);
155
}
156
157
/*
158
* Xeneva's own BaseHdr/list.h already exports list_add(list_t*, void*). Keep
159
* both APIs: dispatch on the second argument's type. Inside the macro body the
160
* name list_add is not re-expanded, so the default branch is the real function.
161
*/
162
#if !defined(__cplusplus)
163
#define list_add(new, head) \
164
_Generic((head), struct list_head*: linux_list_add, default: list_add)((new), (head))
165
#endif
166
167
static
inline
void
list_add_tail(
struct
list_head
*
new
,
struct
list_head
*
head
)
168
{
169
__list_add(
new
,
head
->prev,
head
);
170
}
171
172
static
inline
void
list_del(
struct
list_head
*
entry
)
173
{
174
if
(
entry
->next) {
175
entry
->next->prev =
entry
->prev;
176
entry
->prev->next =
entry
->next;
177
entry
->next = 0;
178
entry
->prev = 0;
179
}
180
}
181
182
static
inline
void
list_del_init(
struct
list_head
*
entry
)
183
{
184
list_del(
entry
);
185
INIT_LIST_HEAD(
entry
);
186
}
187
188
/*
189
* __list_del_entry() -- unlink without touching the entry's own pointers.
190
*
191
* Separate from list_del() because list_del() nulls entry->next and
192
* entry->prev, which is what the rest of DCL expects of a deleted node, but
193
* is not what the move/replace primitives below want: they relink the same
194
* node somewhere else and need its neighbours' addresses, not a cleared
195
* copy of them. Mainline's list_del() poisons instead of nulling and its
196
* __list_del_entry() leaves the node intact; DCL cannot poison (no
197
* LIST_POISON in a freestanding build that has no page-fault reporting to
198
* turn a stale dereference into a diagnosis), so the split between the two
199
* carries the same meaning with NULL in place of the poison values.
200
*/
201
static
inline
void
__list_del_entry(
struct
list_head
*
entry
)
202
{
203
if
(
entry
->next) {
204
entry
->next->prev =
entry
->prev;
205
entry
->prev->next =
entry
->next;
206
}
207
}
208
209
static
inline
void
list_move(
struct
list_head
*
list
,
struct
list_head
*
head
)
210
{
211
__list_del_entry(
list
);
212
list_add
(
list
,
head
);
213
}
214
215
static
inline
void
list_move_tail(
struct
list_head
*
list
,
struct
list_head
*
head
)
216
{
217
__list_del_entry(
list
);
218
list_add_tail(
list
,
head
);
219
}
220
221
static
inline
void
list_replace(
struct
list_head
* old,
struct
list_head
*
new
)
222
{
223
new
->next = old->
next
;
224
new
->
next
->
prev
=
new
;
225
new
->
prev
= old->
prev
;
226
new
->
prev
->
next
=
new
;
227
}
228
229
static
inline
int
list_empty(
const
struct
list_head
*
head
)
230
{
231
return
head
->next ==
head
;
232
}
233
234
/*
235
* list_is_first() / list_is_last() -- the two predicates the DRM bridge
236
* chain walks with. They answer "is this node the end of the chain", which
237
* is a different question from list_empty() ("is there anything here at
238
* all"); drm_bridge_get_next_bridge() needs the former because it returns
239
* NULL rather than the head's container when the walk runs off the end.
240
*
241
* The argument order is (list, head) -- the node being tested first -- which
242
* is the opposite of what the surrounding code might suggest, since
243
* list_is_head() above takes the same two arguments in the same order for
244
* the same reason: these read as "is `list` the first/last entry of `head`".
245
*/
246
static
inline
int
list_is_first(
const
struct
list_head
*
list
,
247
const
struct
list_head
*
head
)
248
{
249
return
list
->prev ==
head
;
250
}
251
252
static
inline
int
list_is_last(
const
struct
list_head
*
list
,
253
const
struct
list_head
*
head
)
254
{
255
return
list
->next ==
head
;
256
}
257
258
/*
259
* list_is_head() / list_is_singular() / __list_cut_position() /
260
* list_cut_position() -- mainline's, verbatim, for virtio_console.c:393:
261
*
262
* list_cut_position(&tmp_list, &pending_free_dma_bufs,
263
* pending_free_dma_bufs.prev);
264
*
265
* which cuts the whole pending-free list off under the lock so the buffers can
266
* be released without it held. The four travel together because
267
* list_cut_position() is the only *entry point* but cannot be written without
268
* the other three: it asks list_is_singular() whether there is exactly one
269
* entry (in which case cutting is a no-op unless entry is the head),
270
* list_is_head() whether entry names the head rather than a member, and
271
* __list_cut_position() does the relinking.
272
*
273
* The detail that makes __list_cut_position() worth copying rather than
274
* re-deriving is `new_first`: entry->next is read into a local *before*
275
* `entry->next = list` overwrites it, so head's new first element is the one
276
* that followed the cut point rather than the cut point's own list member.
277
* Getting that order wrong produces a list that is self-consistent, silent,
278
* and wrong -- the failure mode list debug code exists to catch and DCL does
279
* not have.
280
*
281
* mainline: include/linux/list.h:480-522.
282
*/
283
static
inline
int
list_is_head(
const
struct
list_head
*
list
,
284
const
struct
list_head
*
head
)
285
{
286
return
list
==
head
;
287
}
288
289
static
inline
int
list_is_singular(
const
struct
list_head
*
head
)
290
{
291
return
!list_empty(
head
) && (
head
->next ==
head
->prev);
292
}
293
294
static
inline
void
__list_cut_position(
struct
list_head
*
list
,
295
struct
list_head
*
head
,
296
struct
list_head
*
entry
)
297
{
298
struct
list_head
* new_first =
entry
->
next
;
299
300
list
->next =
head
->next;
301
list
->next->prev =
list
;
302
list
->prev =
entry
;
303
entry
->next =
list
;
304
head
->next = new_first;
305
new_first->
prev
=
head
;
306
}
307
308
static
inline
void
list_cut_position(
struct
list_head
*
list
,
309
struct
list_head
*
head
,
310
struct
list_head
*
entry
)
311
{
312
if
(list_empty(
head
))
313
return
;
314
if
(list_is_singular(
head
) && !list_is_head(
entry
,
head
) &&
315
(
entry
!=
head
->next))
316
return
;
317
if
(list_is_head(
entry
,
head
))
318
INIT_LIST_HEAD(
list
);
319
else
320
__list_cut_position(
list
,
head
,
entry
);
321
}
322
323
/*
324
* __list_splice() / list_splice() / list_splice_tail() -- move a whole list
325
* onto another head without copying any node. The helper does the
326
* relinking against explicit neighbours so the two entry points can name
327
* them: list_splice() puts the moved nodes first under `head`,
328
* list_splice_tail() last. Neither touches `list`, so the caller keeps
329
* ownership of the source head and it still describes its (now empty)
330
* original contents -- which is why drm_flip_work.c can splice the queued
331
* list out and then re-initialise it.
332
*
333
* The empty case is deliberately not guarded here: splicing an empty list
334
* would set head->next to head itself and corrupt the destination. Every
335
* call site in the vendored tree sits behind a list_empty() test; this is
336
* mainline's contract too, and inventing a silent early return would hide
337
* exactly the caller bug that test exists to catch.
338
*/
339
static
inline
void
__list_splice(
const
struct
list_head
*
list
,
340
struct
list_head
*
prev
,
341
struct
list_head
*
next
)
342
{
343
struct
list_head
* first =
list
->next;
344
struct
list_head
*
last
=
list
->prev;
345
346
first->
prev
=
prev
;
347
prev
->
next
= first;
348
349
last
->
next
=
next
;
350
next
->
prev
=
last
;
351
}
352
353
static
inline
void
list_splice(
const
struct
list_head
*
list
,
354
struct
list_head
*
head
)
355
{
356
if
(!list_empty(
list
))
357
__list_splice(
list
,
head
,
head
->next);
358
}
359
360
static
inline
void
list_splice_tail(
const
struct
list_head
*
list
,
361
struct
list_head
*
head
)
362
{
363
if
(!list_empty(
list
))
364
__list_splice(
list
,
head
->prev,
head
);
365
}
366
367
/*
368
* list_cut_before() -- the mirror of list_cut_position(), cut at the node
369
* *before* `entry` rather than after it.
370
*
371
* drm_encoder.c:208 calls it as
372
*
373
* list_cut_before(&tmplist, &encoder->bridge_chain,
374
* &encoder->bridge_chain);
375
*
376
* with `entry` naming the head, so the whole chain moves: entry == head is
377
* the branch that INIT_LIST_HEAD()s the destination and leaves the source
378
* to __list_cut_before(), which links every node over to `list`. Note the
379
* singular-list guard reads `head->next != entry && head != entry` -- with
380
* one node and entry at the head there is nothing to cut, but the node
381
* still has to be moved, so the guard must not reject that case.
382
*/
383
static
inline
void
__list_cut_before(
struct
list_head
*
list
,
384
struct
list_head
*
head
,
385
struct
list_head
*
entry
)
386
{
387
struct
list_head
* new_first =
entry
->
prev
;
388
389
list
->next =
head
->next;
390
list
->next->prev =
list
;
391
list
->prev = new_first;
392
new_first->
next
=
list
;
393
head
->next =
entry
;
394
entry
->prev =
head
;
395
}
396
397
static
inline
void
list_cut_before(
struct
list_head
*
list
,
398
struct
list_head
*
head
,
399
struct
list_head
*
entry
)
400
{
401
if
(list_empty(
head
))
402
return
;
403
if
(list_is_singular(
head
) &&
404
(
head
->next !=
entry
&&
head
!=
entry
))
405
return
;
406
if
(
entry
==
head
)
407
INIT_LIST_HEAD(
list
);
408
else
409
__list_cut_before(
list
,
head
,
entry
);
410
}
411
412
/*
413
* list_count_nodes() -- length of a list, O(n) and allocation-free.
414
*
415
* vkms_config.c counts configured CRTCs and planes this way, so it is the
416
* one consumer that cannot afford to track a counter alongside the list:
417
* the list is built by configfs and read back by paths that never see the
418
* writes. Written as a walk rather than an accumulator in the list itself
419
* because mainline's does not carry a length, and DCL keeping one would
420
* mean list_add() and friends had to maintain it -- a cost on every insert
421
* in the tree to serve two call sites in one driver.
422
*/
423
static
inline
size_t
list_count_nodes(
const
struct
list_head
*
head
)
424
{
425
const
struct
list_head
* pos;
426
size_t
count = 0;
427
428
list_for_each
(pos,
head
)
429
count++;
430
431
return
count;
432
}
433
434
#endif
list_for_each
#define list_for_each(pos, head)
Definition
list.h:59
list_add
#define list_add(new, head)
Definition
list.h:163
list.h
list
XEProcessList * list
Definition
main.cpp:27
_null.h
head
int const struct list_head const struct list_head struct list_head * head
Definition
list_sort.h:13
entry
void(* entry)(void *)
Definition
process.h:101
__tty__::next
struct __tty__ * next
Definition
tty.h:68
list_head
Definition
list.h:11
list_head::next
struct list_head * next
Definition
list.h:12
list_head::prev
struct list_head * prev
Definition
list.h:12
last
TTY * last
Definition
tty.cpp:48
Generated by
1.9.8