Skip to content

Commit

Permalink
fix: reimplement Clone for new LockFreeFrozenVec
Browse files Browse the repository at this point in the history
  • Loading branch information
aminya committed Sep 23, 2023
1 parent a4f7b0a commit c69b5bd
Showing 1 changed file with 32 additions and 5 deletions.
37 changes: 32 additions & 5 deletions src/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -731,15 +731,42 @@ fn test_non_lockfree_unchecked() {

impl<T: Copy + Clone> Clone for LockFreeFrozenVec<T> {
fn clone(&self) -> Self {
let cap = self.cap.load(Ordering::Acquire);
let len = self.len.load(Ordering::Acquire);
// handle the empty case
if len == 0 {
return Self::default();
}

let new_vec = Self::with_capacity(cap);
for i in 0..len {
new_vec.push(self.get(i).unwrap());
// copy the data
let data = [Self::NULL; NUM_BUFFERS];
// for each buffer, copy the data
for i in 0..NUM_BUFFERS {
// get the buffer size and index
let buffer_size = buffer_size(i);
let buffer_idx = buffer_index(buffer_size - 1);
// get the buffer pointer
let buffer_ptr = self.data[buffer_idx].load(Ordering::Acquire);
if buffer_ptr.is_null() {
// no data in this buffer
break;
}
// allocate a new buffer
let layout = Self::layout(buffer_size);
let new_buffer_ptr = unsafe { std::alloc::alloc(layout).cast::<T>() };
assert!(!new_buffer_ptr.is_null());
// copy the data
unsafe {
std::ptr::copy_nonoverlapping(buffer_ptr, new_buffer_ptr, buffer_size);
}
// store the new buffer pointer
data[i].store(new_buffer_ptr, Ordering::Release);
}

new_vec
return Self {
data,
len: AtomicUsize::new(len),
locked: AtomicBool::new(false),
};
}
}

Expand Down

0 comments on commit c69b5bd

Please sign in to comment.