Skip to content

Commit b3cbdc7

Browse files
committed
Resolve haunted list being evicted prematurely
1 parent 75d3d97 commit b3cbdc7

4 files changed

Lines changed: 354 additions & 94 deletions

File tree

src/arcache/ll.rs

Lines changed: 69 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,12 @@ fn alloc_nid() -> usize {
2222
{
2323
LL_ALLOC_LIST.with(|llist| llist.lock().unwrap().insert(nid));
2424
}
25-
eprintln!("Allocate -> {:?}", nid);
25+
// eprintln!("LL Allocate -> {:?}", nid);
2626
nid
2727
}
2828

29-
#[cfg(all(test, not(miri)))]
29+
#[cfg(all(test, not(miri), not(feature = "dhat-heap")))]
3030
fn release_nid(nid: usize) {
31-
println!("Release -> {:?}", nid);
32-
#[cfg(not(feature = "dhat-heap"))]
3331
{
3432
let r = LL_ALLOC_LIST.with(|llist| llist.lock().unwrap().remove(&nid));
3533
assert!(r);
@@ -223,7 +221,7 @@ where
223221
self.append_n(n)
224222
}
225223

226-
// Append an arbitrary node into this set.
224+
// Append an arbitrary node into this set, at the tail end.
227225
pub(crate) fn append_n(&mut self, owned: LLNodeOwned<K>) -> LLNodeRef<K> {
228226
// Who is to the left of tail?
229227
let n = owned.into_inner();
@@ -270,8 +268,14 @@ where
270268
if n.inner == unsafe { (*self.tail).prev } {
271269
// Done, no-op
272270
} else {
271+
let previous_size = self.size;
272+
273273
let owned = self.extract(n);
274274
self.append_n(owned);
275+
276+
let after_size = self.size;
277+
278+
assert_eq!(previous_size, after_size);
275279
}
276280
}
277281

@@ -302,8 +306,8 @@ where
302306

303307
// Cut a node out from this list from any location.
304308
pub(crate) fn extract(&mut self, n: LLNodeRef<K>) -> LLNodeOwned<K> {
305-
assert!(self.size > 0);
306309
assert!(!n.is_null());
310+
assert!(self.size > 0);
307311
unsafe {
308312
// We should have a prev and next
309313
debug_assert!(!(*n.inner).prev.is_null());
@@ -354,7 +358,7 @@ where
354358
}
355359

356360
pub(crate) fn drop_head(&mut self) {
357-
while let Some(owned) = self.pop() {
361+
if let Some(owned) = self.pop() {
358362
let n = owned.into_inner();
359363
LLNode::free(n);
360364
}
@@ -388,6 +392,62 @@ where
388392
Some(l)
389393
}
390394
}
395+
396+
#[cfg(test)]
397+
pub(crate) fn verify(&self) {
398+
// Walk the list to ensure it's sane.
399+
400+
let head = self.head;
401+
let tail = self.tail;
402+
403+
let expect_size = self.size;
404+
let mut size = 0;
405+
406+
// Establish that the sentinel nodes exist, and that they
407+
// have the correct out bound null/non-null pointers.
408+
assert_ne!(head, tail);
409+
410+
unsafe {
411+
assert!((*head).prev.is_null());
412+
assert!(!(*head).next.is_null());
413+
414+
assert!((*tail).next.is_null());
415+
assert!(!(*tail).prev.is_null());
416+
}
417+
418+
// Now we walk each item to assert that they have the correct structure.
419+
let mut n = unsafe { (*head).next };
420+
// We have to manually check head here.
421+
unsafe {
422+
assert_eq!((*n).prev, head);
423+
}
424+
425+
while n != tail {
426+
unsafe {
427+
// Setup the pointer for the next iteration.
428+
let next = (*n).next;
429+
430+
// Add the size.
431+
size += (*(*n).k.as_ptr()).ll_weight();
432+
433+
// assert we have outbound pointers.
434+
assert!(!(*n).prev.is_null());
435+
assert!(!(*n).next.is_null());
436+
437+
// Assert that the previous node points to us.
438+
assert!(!(*(*n).prev).next.is_null());
439+
assert!((*(*n).prev).next == n);
440+
// Assert that the next node points back to us.
441+
// NOTE: This accounts for tail pointing back to us.
442+
assert!(!(*(*n).next).prev.is_null());
443+
assert!((*(*n).next).prev == n);
444+
445+
n = next;
446+
}
447+
}
448+
449+
assert_eq!(expect_size, size);
450+
}
391451
}
392452

393453
impl<K> Drop for LL<K>
@@ -477,7 +537,7 @@ where
477537
debug_assert!(!v.is_null());
478538
let llnode = unsafe { Box::from_raw(v) };
479539
let k = unsafe { llnode.k.assume_init() };
480-
#[cfg(all(test, not(miri)))]
540+
#[cfg(all(test, not(miri), not(feature = "dhat-heap")))]
481541
release_nid(llnode.nid);
482542

483543
k
@@ -494,7 +554,7 @@ where
494554
debug_assert!(!v.is_null());
495555
let _llnode = unsafe { Box::from_raw(v) };
496556
// Markers never have a k to drop.
497-
#[cfg(all(test, not(miri)))]
557+
#[cfg(all(test, not(miri), not(feature = "dhat-heap")))]
498558
release_nid(_llnode.nid)
499559
}
500560
}

0 commit comments

Comments
 (0)