6
6
7
7
use crate :: init:: PinInit ;
8
8
use crate :: types:: Opaque ;
9
+ use core:: marker:: PhantomData ;
9
10
use core:: ptr;
10
11
11
12
mod impl_list_item_mod;
@@ -14,7 +15,42 @@ pub use self::impl_list_item_mod::{impl_has_list_links, impl_list_item, HasListL
14
15
mod arc;
15
16
pub use self :: arc:: { impl_list_arc_safe, AtomicTracker , ListArc , ListArcSafe , TryNewListArc } ;
16
17
17
- /// Implemented by types where a [`ListArc<Self>`] can be inserted into a `List`.
18
+ /// A linked list.
19
+ ///
20
+ /// All elements in this linked list will be [`ListArc`] references to the value. Since a value can
21
+ /// only have one `ListArc` (for each pair of prev/next pointers), this ensures that the same
22
+ /// prev/next pointers are not used for several linked lists.
23
+ ///
24
+ /// # Invariants
25
+ ///
26
+ /// * If the list is empty, then `first` is null. Otherwise, `first` points at the `ListLinks`
27
+ /// field of the first element in the list.
28
+ /// * All prev/next pointers in `ListLinks` fields of items in the list are valid and form a cycle.
29
+ /// * For every item in the list, the list owns the associated [`ListArc`] reference and has
30
+ /// exclusive access to the `ListLinks` field.
31
+ pub struct List < T : ?Sized + ListItem < ID > , const ID : u64 = 0 > {
32
+ first : * mut ListLinksFields ,
33
+ _ty : PhantomData < ListArc < T , ID > > ,
34
+ }
35
+
36
+ // SAFETY: This is a container of `ListArc<T, ID>`, and access to the container allows the same
37
+ // type of access to the `ListArc<T, ID>` elements.
38
+ unsafe impl < T , const ID : u64 > Send for List < T , ID >
39
+ where
40
+ ListArc < T , ID > : Send ,
41
+ T : ?Sized + ListItem < ID > ,
42
+ {
43
+ }
44
+ // SAFETY: This is a container of `ListArc<T, ID>`, and access to the container allows the same
45
+ // type of access to the `ListArc<T, ID>` elements.
46
+ unsafe impl < T , const ID : u64 > Sync for List < T , ID >
47
+ where
48
+ ListArc < T , ID > : Sync ,
49
+ T : ?Sized + ListItem < ID > ,
50
+ {
51
+ }
52
+
53
+ /// Implemented by types where a [`ListArc<Self>`] can be inserted into a [`List`].
18
54
///
19
55
/// # Safety
20
56
///
@@ -56,7 +92,7 @@ pub unsafe trait ListItem<const ID: u64 = 0>: ListArcSafe<ID> {
56
92
/// been called.
57
93
unsafe fn view_value ( me : * mut ListLinks < ID > ) -> * const Self ;
58
94
59
- /// This is called when an item is inserted into a `List`.
95
+ /// This is called when an item is inserted into a [ `List`] .
60
96
///
61
97
/// # Guarantees
62
98
///
@@ -103,7 +139,6 @@ struct ListLinksFields {
103
139
pub struct ListLinks < const ID : u64 = 0 > {
104
140
// This type is `!Unpin` for aliasing reasons as the pointers are part of an intrusive linked
105
141
// list.
106
- #[ allow( dead_code) ]
107
142
inner : Opaque < ListLinksFields > ,
108
143
}
109
144
@@ -127,4 +162,293 @@ impl<const ID: u64> ListLinks<ID> {
127
162
} ) ,
128
163
}
129
164
}
165
+
166
+ /// # Safety
167
+ ///
168
+ /// `me` must be dereferenceable.
169
+ #[ inline]
170
+ unsafe fn fields ( me : * mut Self ) -> * mut ListLinksFields {
171
+ // SAFETY: The caller promises that the pointer is valid.
172
+ unsafe { Opaque :: raw_get ( ptr:: addr_of!( ( * me) . inner) ) }
173
+ }
174
+
175
+ /// # Safety
176
+ ///
177
+ /// `me` must be dereferenceable.
178
+ #[ inline]
179
+ unsafe fn from_fields ( me : * mut ListLinksFields ) -> * mut Self {
180
+ me. cast ( )
181
+ }
182
+ }
183
+
184
+ impl < T : ?Sized + ListItem < ID > , const ID : u64 > List < T , ID > {
185
+ /// Creates a new empty list.
186
+ pub const fn new ( ) -> Self {
187
+ Self {
188
+ first : ptr:: null_mut ( ) ,
189
+ _ty : PhantomData ,
190
+ }
191
+ }
192
+
193
+ /// Returns whether this list is empty.
194
+ pub fn is_empty ( & self ) -> bool {
195
+ self . first . is_null ( )
196
+ }
197
+
198
+ /// Add the provided item to the back of the list.
199
+ pub fn push_back ( & mut self , item : ListArc < T , ID > ) {
200
+ let raw_item = ListArc :: into_raw ( item) ;
201
+ // SAFETY:
202
+ // * We just got `raw_item` from a `ListArc`, so it's in an `Arc`.
203
+ // * Since we have ownership of the `ListArc`, `post_remove` must have been called after
204
+ // the most recent call to `prepare_to_insert`, if any.
205
+ // * We own the `ListArc`.
206
+ // * Removing items from this list is always done using `remove_internal_inner`, which
207
+ // calls `post_remove` before giving up ownership.
208
+ let list_links = unsafe { T :: prepare_to_insert ( raw_item) } ;
209
+ // SAFETY: We have not yet called `post_remove`, so `list_links` is still valid.
210
+ let item = unsafe { ListLinks :: fields ( list_links) } ;
211
+
212
+ if self . first . is_null ( ) {
213
+ self . first = item;
214
+ // SAFETY: The caller just gave us ownership of these fields.
215
+ // INVARIANT: A linked list with one item should be cyclic.
216
+ unsafe {
217
+ ( * item) . next = item;
218
+ ( * item) . prev = item;
219
+ }
220
+ } else {
221
+ let next = self . first ;
222
+ // SAFETY: By the type invariant, this pointer is valid or null. We just checked that
223
+ // it's not null, so it must be valid.
224
+ let prev = unsafe { ( * next) . prev } ;
225
+ // SAFETY: Pointers in a linked list are never dangling, and the caller just gave us
226
+ // ownership of the fields on `item`.
227
+ // INVARIANT: This correctly inserts `item` between `prev` and `next`.
228
+ unsafe {
229
+ ( * item) . next = next;
230
+ ( * item) . prev = prev;
231
+ ( * prev) . next = item;
232
+ ( * next) . prev = item;
233
+ }
234
+ }
235
+ }
236
+
237
+ /// Add the provided item to the front of the list.
238
+ pub fn push_front ( & mut self , item : ListArc < T , ID > ) {
239
+ let raw_item = ListArc :: into_raw ( item) ;
240
+ // SAFETY:
241
+ // * We just got `raw_item` from a `ListArc`, so it's in an `Arc`.
242
+ // * If this requirement is violated, then the previous caller of `prepare_to_insert`
243
+ // violated the safety requirement that they can't give up ownership of the `ListArc`
244
+ // until they call `post_remove`.
245
+ // * We own the `ListArc`.
246
+ // * Removing items] from this list is always done using `remove_internal_inner`, which
247
+ // calls `post_remove` before giving up ownership.
248
+ let list_links = unsafe { T :: prepare_to_insert ( raw_item) } ;
249
+ // SAFETY: We have not yet called `post_remove`, so `list_links` is still valid.
250
+ let item = unsafe { ListLinks :: fields ( list_links) } ;
251
+
252
+ if self . first . is_null ( ) {
253
+ // SAFETY: The caller just gave us ownership of these fields.
254
+ // INVARIANT: A linked list with one item should be cyclic.
255
+ unsafe {
256
+ ( * item) . next = item;
257
+ ( * item) . prev = item;
258
+ }
259
+ } else {
260
+ let next = self . first ;
261
+ // SAFETY: We just checked that `next` is non-null.
262
+ let prev = unsafe { ( * next) . prev } ;
263
+ // SAFETY: Pointers in a linked list are never dangling, and the caller just gave us
264
+ // ownership of the fields on `item`.
265
+ // INVARIANT: This correctly inserts `item` between `prev` and `next`.
266
+ unsafe {
267
+ ( * item) . next = next;
268
+ ( * item) . prev = prev;
269
+ ( * prev) . next = item;
270
+ ( * next) . prev = item;
271
+ }
272
+ }
273
+ self . first = item;
274
+ }
275
+
276
+ /// Removes the last item from this list.
277
+ pub fn pop_back ( & mut self ) -> Option < ListArc < T , ID > > {
278
+ if self . first . is_null ( ) {
279
+ return None ;
280
+ }
281
+
282
+ // SAFETY: We just checked that the list is not empty.
283
+ let last = unsafe { ( * self . first ) . prev } ;
284
+ // SAFETY: The last item of this list is in this list.
285
+ Some ( unsafe { self . remove_internal ( last) } )
286
+ }
287
+
288
+ /// Removes the first item from this list.
289
+ pub fn pop_front ( & mut self ) -> Option < ListArc < T , ID > > {
290
+ if self . first . is_null ( ) {
291
+ return None ;
292
+ }
293
+
294
+ // SAFETY: The first item of this list is in this list.
295
+ Some ( unsafe { self . remove_internal ( self . first ) } )
296
+ }
297
+
298
+ /// Removes the provided item from this list and returns it.
299
+ ///
300
+ /// This returns `None` if the item is not in the list. (Note that by the safety requirements,
301
+ /// this means that the item is not in any list.)
302
+ ///
303
+ /// # Safety
304
+ ///
305
+ /// `item` must not be in a different linked list (with the same id).
306
+ pub unsafe fn remove ( & mut self , item : & T ) -> Option < ListArc < T , ID > > {
307
+ let mut item = unsafe { ListLinks :: fields ( T :: view_links ( item) ) } ;
308
+ // SAFETY: The user provided a reference, and reference are never dangling.
309
+ //
310
+ // As for why this is not a data race, there are two cases:
311
+ //
312
+ // * If `item` is not in any list, then these fields are read-only and null.
313
+ // * If `item` is in this list, then we have exclusive access to these fields since we
314
+ // have a mutable reference to the list.
315
+ //
316
+ // In either case, there's no race.
317
+ let ListLinksFields { next, prev } = unsafe { * item } ;
318
+
319
+ debug_assert_eq ! ( next. is_null( ) , prev. is_null( ) ) ;
320
+ if !next. is_null ( ) {
321
+ // This is really a no-op, but this ensures that `item` is a raw pointer that was
322
+ // obtained without going through a pointer->reference->pointer conversion roundtrip.
323
+ // This ensures that the list is valid under the more restrictive strict provenance
324
+ // ruleset.
325
+ //
326
+ // SAFETY: We just checked that `next` is not null, and it's not dangling by the
327
+ // list invariants.
328
+ unsafe {
329
+ debug_assert_eq ! ( item, ( * next) . prev) ;
330
+ item = ( * next) . prev ;
331
+ }
332
+
333
+ // SAFETY: We just checked that `item` is in a list, so the caller guarantees that it
334
+ // is in this list. The pointers are in the right order.
335
+ Some ( unsafe { self . remove_internal_inner ( item, next, prev) } )
336
+ } else {
337
+ None
338
+ }
339
+ }
340
+
341
+ /// Removes the provided item from the list.
342
+ ///
343
+ /// # Safety
344
+ ///
345
+ /// `item` must point at an item in this list.
346
+ unsafe fn remove_internal ( & mut self , item : * mut ListLinksFields ) -> ListArc < T , ID > {
347
+ // SAFETY: The caller promises that this pointer is not dangling, and there's no data race
348
+ // since we have a mutable reference to the list containing `item`.
349
+ let ListLinksFields { next, prev } = unsafe { * item } ;
350
+ // SAFETY: The pointers are ok and in the right order.
351
+ unsafe { self . remove_internal_inner ( item, next, prev) }
352
+ }
353
+
354
+ /// Removes the provided item from the list.
355
+ ///
356
+ /// # Safety
357
+ ///
358
+ /// The `item` pointer must point at an item in this list, and we must have `(*item).next ==
359
+ /// next` and `(*item).prev == prev`.
360
+ unsafe fn remove_internal_inner (
361
+ & mut self ,
362
+ item : * mut ListLinksFields ,
363
+ next : * mut ListLinksFields ,
364
+ prev : * mut ListLinksFields ,
365
+ ) -> ListArc < T , ID > {
366
+ // SAFETY: We have exclusive access to the pointers of items in the list, and the prev/next
367
+ // pointers are always valid for items in a list.
368
+ //
369
+ // INVARIANT: There are three cases:
370
+ // * If the list has at least three items, then after removing the item, `prev` and `next`
371
+ // will be next to each other.
372
+ // * If the list has two items, then the remaining item will point at itself.
373
+ // * If the list has one item, then `next == prev == item`, so these writes have no
374
+ // effect. The list remains unchanged and `item` is still in the list for now.
375
+ unsafe {
376
+ ( * next) . prev = prev;
377
+ ( * prev) . next = next;
378
+ }
379
+ // SAFETY: We have exclusive access to items in the list.
380
+ // INVARIANT: `item` is being removed, so the pointers should be null.
381
+ unsafe {
382
+ ( * item) . prev = ptr:: null_mut ( ) ;
383
+ ( * item) . next = ptr:: null_mut ( ) ;
384
+ }
385
+ // INVARIANT: There are three cases:
386
+ // * If `item` was not the first item, then `self.first` should remain unchanged.
387
+ // * If `item` was the first item and there is another item, then we just updated
388
+ // `prev->next` to `next`, which is the new first item, and setting `item->next` to null
389
+ // did not modify `prev->next`.
390
+ // * If `item` was the only item in the list, then `prev == item`, and we just set
391
+ // `item->next` to null, so this correctly sets `first` to null now that the list is
392
+ // empty.
393
+ if self . first == item {
394
+ // SAFETY: The `prev` pointer is the value that `item->prev` had when it was in this
395
+ // list, so it must be valid. There is no race since `prev` is still in the list and we
396
+ // still have exclusive access to the list.
397
+ self . first = unsafe { ( * prev) . next } ;
398
+ }
399
+
400
+ // SAFETY: `item` used to be in the list, so it is dereferenceable by the type invariants
401
+ // of `List`.
402
+ let list_links = unsafe { ListLinks :: from_fields ( item) } ;
403
+ // SAFETY: Any pointer in the list originates from a `prepare_to_insert` call.
404
+ let raw_item = unsafe { T :: post_remove ( list_links) } ;
405
+ // SAFETY: The above call to `post_remove` guarantees that we can recreate the `ListArc`.
406
+ unsafe { ListArc :: from_raw ( raw_item) }
407
+ }
408
+
409
+ /// Moves all items from `other` into `self`.
410
+ ///
411
+ /// The items of `other` are added to the back of `self`, so the last item of `other` becomes
412
+ /// the last item of `self`.
413
+ pub fn push_all_back ( & mut self , other : & mut List < T , ID > ) {
414
+ // First, we insert the elements into `self`. At the end, we make `other` empty.
415
+ if self . is_empty ( ) {
416
+ // INVARIANT: All of the elements in `other` become elements of `self`.
417
+ self . first = other. first ;
418
+ } else if !other. is_empty ( ) {
419
+ let other_first = other. first ;
420
+ // SAFETY: The other list is not empty, so this pointer is valid.
421
+ let other_last = unsafe { ( * other_first) . prev } ;
422
+ let self_first = self . first ;
423
+ // SAFETY: The self list is not empty, so this pointer is valid.
424
+ let self_last = unsafe { ( * self_first) . prev } ;
425
+
426
+ // SAFETY: We have exclusive access to both lists, so we can update the pointers.
427
+ // INVARIANT: This correctly sets the pointers to merge both lists. We do not need to
428
+ // update `self.first` because the first element of `self` does not change.
429
+ unsafe {
430
+ ( * self_first) . prev = other_last;
431
+ ( * other_last) . next = self_first;
432
+ ( * self_last) . next = other_first;
433
+ ( * other_first) . prev = self_last;
434
+ }
435
+ }
436
+
437
+ // INVARIANT: The other list is now empty, so update its pointer.
438
+ other. first = ptr:: null_mut ( ) ;
439
+ }
440
+ }
441
+
442
+ impl < T : ?Sized + ListItem < ID > , const ID : u64 > Default for List < T , ID > {
443
+ fn default ( ) -> Self {
444
+ List :: new ( )
445
+ }
446
+ }
447
+
448
+ impl < T : ?Sized + ListItem < ID > , const ID : u64 > Drop for List < T , ID > {
449
+ fn drop ( & mut self ) {
450
+ while let Some ( item) = self . pop_front ( ) {
451
+ drop ( item) ;
452
+ }
453
+ }
130
454
}
0 commit comments