mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-10-09 14:55:06 +02:00
97 lines
2.6 KiB
Rust
97 lines
2.6 KiB
Rust
//! Test using `Bytes` with an allocator that hands out "odd" pointers for
|
|
//! vectors (pointers where the LSB is set).
|
|
|
|
#![cfg(not(miri))] // Miri does not support custom allocators (also, Miri is "odd" by default with 50% chance)
|
|
|
|
use std::alloc::{GlobalAlloc, Layout, System};
|
|
use std::ptr;
|
|
|
|
use bytes::Bytes;
|
|
|
|
#[global_allocator]
|
|
static ODD: Odd = Odd;
|
|
|
|
struct Odd;
|
|
|
|
unsafe impl GlobalAlloc for Odd {
|
|
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
|
|
if layout.align() == 1 && layout.size() > 0 {
|
|
// Allocate slightly bigger so that we can offset the pointer by 1
|
|
let size = layout.size() + 1;
|
|
let new_layout = match Layout::from_size_align(size, 1) {
|
|
Ok(layout) => layout,
|
|
Err(_err) => return ptr::null_mut(),
|
|
};
|
|
let ptr = System.alloc(new_layout);
|
|
if !ptr.is_null() {
|
|
ptr.offset(1)
|
|
} else {
|
|
ptr
|
|
}
|
|
} else {
|
|
System.alloc(layout)
|
|
}
|
|
}
|
|
|
|
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
|
|
if layout.align() == 1 && layout.size() > 0 {
|
|
let size = layout.size() + 1;
|
|
let new_layout = match Layout::from_size_align(size, 1) {
|
|
Ok(layout) => layout,
|
|
Err(_err) => std::process::abort(),
|
|
};
|
|
System.dealloc(ptr.offset(-1), new_layout);
|
|
} else {
|
|
System.dealloc(ptr, layout);
|
|
}
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn sanity_check_odd_allocator() {
|
|
let vec = vec![33u8; 1024];
|
|
let p = vec.as_ptr() as usize;
|
|
assert!(p & 0x1 == 0x1, "{:#b}", p);
|
|
}
|
|
|
|
#[test]
|
|
fn test_bytes_from_vec_drop() {
|
|
let vec = vec![33u8; 1024];
|
|
let _b = Bytes::from(vec);
|
|
}
|
|
|
|
#[test]
|
|
fn test_bytes_clone_drop() {
|
|
let vec = vec![33u8; 1024];
|
|
let b1 = Bytes::from(vec);
|
|
let _b2 = b1.clone();
|
|
}
|
|
|
|
#[test]
|
|
fn test_bytes_into_vec() {
|
|
let vec = vec![33u8; 1024];
|
|
|
|
// Test cases where kind == KIND_VEC
|
|
let b1 = Bytes::from(vec.clone());
|
|
assert_eq!(Vec::from(b1), vec);
|
|
|
|
// Test cases where kind == KIND_ARC, ref_cnt == 1
|
|
let b1 = Bytes::from(vec.clone());
|
|
drop(b1.clone());
|
|
assert_eq!(Vec::from(b1), vec);
|
|
|
|
// Test cases where kind == KIND_ARC, ref_cnt == 2
|
|
let b1 = Bytes::from(vec.clone());
|
|
let b2 = b1.clone();
|
|
assert_eq!(Vec::from(b1), vec);
|
|
|
|
// Test cases where vtable = SHARED_VTABLE, kind == KIND_ARC, ref_cnt == 1
|
|
assert_eq!(Vec::from(b2), vec);
|
|
|
|
// Test cases where offset != 0
|
|
let mut b1 = Bytes::from(vec.clone());
|
|
let b2 = b1.split_off(20);
|
|
|
|
assert_eq!(Vec::from(b2), vec[20..]);
|
|
assert_eq!(Vec::from(b1), vec[..20]);
|
|
}
|