Skip to content

Commit

Permalink
fn DisjointMutArcSlice::new_zeroed_slice: Add constructor that uses…
Browse files Browse the repository at this point in the history
… zeroed allocations to optimize out initialization, and use this on `f.mvs`.
  • Loading branch information
kkysen committed Sep 23, 2024
1 parent 7d72409 commit b42479b
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 9 deletions.
1 change: 1 addition & 0 deletions lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
any(target_arch = "riscv32", target_arch = "riscv64"),
feature(stdarch_riscv_feature_detection)
)]
#![feature(new_uninit)]
#![deny(unsafe_op_in_unsafe_fn)]
#![allow(clippy::all)]
#![deny(clippy::undocumented_unsafe_blocks)]
Expand Down
9 changes: 4 additions & 5 deletions src/decode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ use crate::src::cdf::CdfThreadContext;
use crate::src::ctx::CaseSet;
use crate::src::dequant_tables::dav1d_dq_tbl;
use crate::src::disjoint_mut::DisjointMut;
use crate::src::disjoint_mut::DisjointMutArcSlice;
use crate::src::disjoint_mut::DisjointMutSlice;
use crate::src::enum_map::enum_map;
use crate::src::enum_map::enum_map_ty;
Expand Down Expand Up @@ -5220,11 +5221,9 @@ pub fn rav1d_submit_frame(c: &Rav1dContext, state: &mut Rav1dState) -> Rav1dResu
// ref_mvs
if frame_hdr.frame_type.is_inter_or_switch() || frame_hdr.allow_intrabc {
// TODO fallible allocation
f.mvs = Some(
(0..f.sb128h as usize * 16 * (f.b4_stride >> 1) as usize)
.map(|_| Default::default())
.collect(),
);
f.mvs = Some(DisjointMutArcSlice::new_zeroed_slice(
f.sb128h as usize * 16 * (f.b4_stride >> 1) as usize,
));
if !frame_hdr.allow_intrabc {
for i in 0..7 {
f.refpoc[i] = f.refp[i].p.frame_hdr.as_ref().unwrap().frame_offset as c_uint;
Expand Down
39 changes: 36 additions & 3 deletions src/disjoint_mut.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use std::fmt::Formatter;
use std::marker::PhantomData;
use std::mem;
use std::mem::ManuallyDrop;
use std::mem::MaybeUninit;
use std::ops::Deref;
use std::ops::DerefMut;
use std::ops::Index;
Expand All @@ -27,6 +28,7 @@ use std::ptr::addr_of_mut;
use std::sync::Arc;
use zerocopy::AsBytes;
use zerocopy::FromBytes;
use zerocopy::FromZeroes;

/// Wraps an indexable collection to allow unchecked concurrent mutable borrows.
///
Expand Down Expand Up @@ -1185,14 +1187,14 @@ impl<T> FromIterator<T> for DisjointMutArcSlice<T> {
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
#[cfg(debug_assertions)]
let inner = {
let box_slice = iter.into_iter().collect::<Box<[_]>>();
let box_slice = iter.into_iter().collect::<Box<[T]>>();
Arc::new(DisjointMut::new(box_slice))
};
#[cfg(not(debug_assertions))]
let inner = {
use std::mem;

let arc_slice = iter.into_iter().collect::<Arc<[_]>>();
let arc_slice = iter.into_iter().collect::<Arc<[T]>>();

// Do our best to check that `DisjointMut` is in fact `#[repr(transparent)]`.
type A = Vec<u8>; // Some concrete sized type.
Expand All @@ -1201,7 +1203,7 @@ impl<T> FromIterator<T> for DisjointMutArcSlice<T> {

// SAFETY: When `#[cfg(not(debug_assertions))]`, `DisjointMut` is `#[repr(transparent)]`,
// containing only an `UnsafeCell`, which is also `#[repr(transparent)]`.
unsafe { mem::transmute::<Arc<[_]>, Arc<DisjointMut<[_]>>>(arc_slice) }
unsafe { mem::transmute::<Arc<[T]>, Arc<DisjointMut<[T]>>>(arc_slice) }
};
Self { inner }
}
Expand All @@ -1212,3 +1214,34 @@ impl<T> Default for DisjointMutArcSlice<T> {
[].into_iter().collect()
}
}

impl<T: FromZeroes> DisjointMutArcSlice<T> {
pub fn new_zeroed_slice(len: usize) -> Self {
#[cfg(debug_assertions)]
let inner = {
let box_slice = Box::new_zeroed_slice(len);
Arc::new(DisjointMut::new(box_slice))
};
#[cfg(not(debug_assertions))]
let inner = {
use std::mem;

let arc_slice = Arc::new_zeroed_slice(len);

// Do our best to check that `DisjointMut` is in fact `#[repr(transparent)]`.
type A = Vec<u8>; // Some concrete sized type.
const _: () = assert!(mem::size_of::<DisjointMut<A>>() == mem::size_of::<A>());
const _: () = assert!(mem::align_of::<DisjointMut<A>>() == mem::align_of::<A>());

// SAFETY: When `#[cfg(not(debug_assertions))]`, `DisjointMut` is `#[repr(transparent)]`,
// containing only an `UnsafeCell`, which is also `#[repr(transparent)]`.
unsafe { mem::transmute::<Arc<[T]>, Arc<DisjointMut<[T]>>>(arc_slice) }
};
// SAFETY: `T: FromZeroes`, and the `MaybeUninit<T>` is all zeros,
// since it is allocated with `new_zeroed_slice`.
let inner = unsafe {
mem::transmute::<Arc<DisjointMutSlice<MaybeUninit<T>>>, Arc<DisjointMutSlice<T>>>(inner)
};
Self { inner }
}
}
2 changes: 1 addition & 1 deletion src/refmvs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ use std::ptr;
use std::slice;
use zerocopy::FromZeroes;

#[derive(Clone, Copy, Default, PartialEq, Eq)]
#[derive(Clone, Copy, Default, PartialEq, Eq, FromZeroes)]
#[repr(C, packed)]
pub struct RefMvsTemporalBlock {
pub mv: Mv,
Expand Down

0 comments on commit b42479b

Please sign in to comment.