chore: checkpoint before Python removal

This commit is contained in:
2026-03-26 22:33:59 +00:00
parent 683cec9307
commit e568ddf82a
29972 changed files with 11269302 additions and 2 deletions

171
vendor/seize/benches/single_thread.rs vendored Normal file
View File

@@ -0,0 +1,171 @@
use criterion::{criterion_group, criterion_main, Criterion};
// this benchmark mainly compares uncontended enter/leave overhead
fn single_thread(c: &mut Criterion) {
c.bench_function("single_thread-seize", |b| {
let mut stack = seize_stack::Stack::new();
b.iter(|| {
for i in 0..1000 {
stack.push(i);
assert!(stack.pop().is_some());
}
for i in 0..1000 {
stack.push(i);
assert!(stack.pop().is_some());
}
assert!(stack.pop().is_none());
assert!(stack.is_empty());
});
drop(stack);
});
c.bench_function("single_thread-crossbeam", |b| {
let mut stack = crossbeam_stack::Stack::new();
b.iter(|| {
for i in 0..1000 {
stack.push(i);
assert!(stack.pop().is_some());
}
for i in 0..1000 {
stack.push(i);
assert!(stack.pop().is_some());
}
assert!(stack.pop().is_none());
assert!(stack.is_empty());
})
});
}
criterion_group!(benches, single_thread);
criterion_main!(benches);
mod seize_stack {
use criterion::black_box;
use seize::{Collector, Link, Linked};
use std::ptr;
pub struct Stack {
head: *mut Linked<Node>,
collector: Collector,
alloc: *mut Linked<Node>,
}
struct Node {
data: Option<usize>,
next: *mut Linked<Node>,
}
impl Stack {
pub fn new() -> Stack {
let collector = Collector::new().epoch_frequency(None);
Stack {
head: ptr::null_mut(),
alloc: collector.link_boxed(Node {
data: Some(1),
next: ptr::null_mut(),
}),
collector,
}
}
pub fn push(&mut self, _value: usize) {
let guard = black_box(self.collector.enter());
self.head = self.alloc;
drop(guard);
}
pub fn pop(&mut self) -> Option<usize> {
let guard = black_box(self.collector.enter());
unsafe {
let head = self.head;
if head.is_null() {
return None;
}
self.head = (*head).next;
guard.defer_retire(head, |link| {
let head: *mut Linked<Node> = Link::cast(link);
assert!(!head.is_null());
assert!((*head).data == Some(1));
});
(*head).data
}
}
pub fn is_empty(&self) -> bool {
let _guard = black_box(crossbeam_epoch::pin());
self.head.is_null()
}
}
}
mod crossbeam_stack {
use criterion::black_box;
use std::ptr;
pub struct Stack {
head: *mut Node,
alloc: *mut Node,
}
struct Node {
data: Option<usize>,
next: *mut Node,
}
impl Stack {
pub fn new() -> Stack {
Stack {
head: ptr::null_mut(),
alloc: Box::into_raw(Box::new(Node {
data: Some(1),
next: ptr::null_mut(),
})),
}
}
pub fn push(&mut self, _value: usize) {
let guard = black_box(crossbeam_epoch::pin());
self.head = self.alloc;
drop(guard);
}
pub fn pop(&mut self) -> Option<usize> {
let guard = black_box(crossbeam_epoch::pin());
unsafe {
let head = self.head;
if head.is_null() {
return None;
}
self.head = (*head).next;
guard.defer_unchecked(move || {
assert!(!head.is_null());
assert!((*head).data == Some(1));
});
(*head).data
}
}
pub fn is_empty(&self) -> bool {
let _guard = black_box(crossbeam_epoch::pin());
self.head.is_null()
}
}
}

244
vendor/seize/benches/stack.rs vendored Normal file
View File

@@ -0,0 +1,244 @@
use std::sync::Arc;
use std::thread;
use criterion::{criterion_group, criterion_main, Criterion};
fn treiber_stack(c: &mut Criterion) {
c.bench_function("trieber_stack-haphazard", |b| {
b.iter(|| {
let stack = Arc::new(haphazard_stack::TreiberStack::new());
let handles = (0..66)
.map(|_| {
let stack = stack.clone();
thread::spawn(move || {
for i in 0..1000 {
stack.push(i);
assert!(stack.pop().is_some());
}
})
})
.collect::<Vec<_>>();
for i in 0..1000 {
stack.push(i);
assert!(stack.pop().is_some());
}
for handle in handles {
handle.join().unwrap();
}
assert!(stack.pop().is_none());
assert!(stack.is_empty());
})
});
c.bench_function("trieber_stack-seize", |b| {
b.iter(|| {
let stack = Arc::new(seize_stack::TreiberStack::new());
let handles = (0..66)
.map(|_| {
let stack = stack.clone();
thread::spawn(move || {
for i in 0..1000 {
stack.push(i);
assert!(stack.pop().is_some());
}
})
})
.collect::<Vec<_>>();
for i in 0..1000 {
stack.push(i);
assert!(stack.pop().is_some());
}
for handle in handles {
handle.join().unwrap();
}
assert!(stack.pop().is_none());
assert!(stack.is_empty());
})
});
}
criterion_group!(benches, treiber_stack);
criterion_main!(benches);
mod seize_stack {
use seize::{reclaim, Collector, Linked};
use std::mem::ManuallyDrop;
use std::ptr;
use std::sync::atomic::{AtomicPtr, Ordering};
#[derive(Debug)]
pub struct TreiberStack<T> {
head: AtomicPtr<Linked<Node<T>>>,
collector: Collector,
}
#[derive(Debug)]
struct Node<T> {
data: ManuallyDrop<T>,
next: *mut Linked<Node<T>>,
}
impl<T> TreiberStack<T> {
pub fn new() -> TreiberStack<T> {
TreiberStack {
head: AtomicPtr::new(ptr::null_mut()),
collector: Collector::new().epoch_frequency(None),
}
}
pub fn push(&self, value: T) {
let node = self.collector.link_boxed(Node {
data: ManuallyDrop::new(value),
next: ptr::null_mut(),
});
let guard = self.collector.enter();
loop {
let head = guard.protect(&self.head, Ordering::Acquire);
unsafe { (*node).next = head }
if self
.head
.compare_exchange(head, node, Ordering::AcqRel, Ordering::Relaxed)
.is_ok()
{
break;
}
}
}
pub fn pop(&self) -> Option<T> {
let guard = self.collector.enter();
loop {
let head = guard.protect(&self.head, Ordering::Acquire);
if head.is_null() {
return None;
}
let next = unsafe { (*head).next };
if self
.head
.compare_exchange(head, next, Ordering::Release, Ordering::Relaxed)
.is_ok()
{
unsafe {
let data = ptr::read(&(*head).data);
self.collector
.retire(head, reclaim::boxed::<Linked<Node<T>>>);
return Some(ManuallyDrop::into_inner(data));
}
}
}
}
pub fn is_empty(&self) -> bool {
let guard = self.collector.enter();
guard.protect(&self.head, Ordering::Relaxed).is_null()
}
}
impl<T> Drop for TreiberStack<T> {
fn drop(&mut self) {
while self.pop().is_some() {}
}
}
}
mod haphazard_stack {
use haphazard::{Domain, HazardPointer};
use std::mem::ManuallyDrop;
use std::ptr;
use std::sync::atomic::{AtomicPtr, Ordering};
#[derive(Debug)]
pub struct TreiberStack<T: 'static> {
head: AtomicPtr<Node<T>>,
}
#[derive(Debug)]
struct Node<T> {
data: ManuallyDrop<T>,
next: *mut Node<T>,
}
unsafe impl<T> Send for Node<T> {}
unsafe impl<T> Sync for Node<T> {}
impl<T> TreiberStack<T> {
pub fn new() -> TreiberStack<T> {
TreiberStack {
head: AtomicPtr::default(),
}
}
pub fn push(&self, value: T) {
let node = Box::into_raw(Box::new(Node {
data: ManuallyDrop::new(value),
next: ptr::null_mut(),
}));
let mut h = HazardPointer::new();
loop {
let head = match h.protect_ptr(&self.head) {
Some((ptr, _)) => ptr.as_ptr(),
None => ptr::null_mut(),
};
unsafe { (*node).next = head }
if self
.head
.compare_exchange(head, node, Ordering::Release, Ordering::Relaxed)
.is_ok()
{
break;
}
}
}
pub fn pop(&self) -> Option<T> {
let mut h = HazardPointer::new();
loop {
let (head, _) = h.protect_ptr(&self.head)?;
let next = unsafe { head.as_ref().next };
if self
.head
.compare_exchange(head.as_ptr(), next, Ordering::Release, Ordering::Relaxed)
.is_ok()
{
unsafe {
let data = ptr::read(&head.as_ref().data);
Domain::global().retire_ptr::<_, Box<Node<T>>>(head.as_ptr());
return Some(ManuallyDrop::into_inner(data));
}
}
}
}
pub fn is_empty(&self) -> bool {
let mut h = HazardPointer::new();
unsafe { h.protect(&self.head) }.is_none()
}
}
impl<T> Drop for TreiberStack<T> {
fn drop(&mut self) {
while self.pop().is_some() {}
}
}
}