Skip to content

Commit

Permalink
Replace AlignedBoxedSlice with aligned_vec::ABox
Browse files Browse the repository at this point in the history
  • Loading branch information
FreezyLemon authored and barrbrain committed Apr 2, 2024
1 parent f3dd049 commit 732162e
Show file tree
Hide file tree
Showing 4 changed files with 12 additions and 106 deletions.
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ profiling = { version = "1" }
tracing-subscriber = { version = "0.3.18", optional = true }
tracing-chrome = { version = "0.7.1", optional = true }
tracing = { version = "0.1.40", optional = true }
aligned-vec = "0.5.0"

[dependencies.image]
version = "0.24.8"
Expand Down
6 changes: 4 additions & 2 deletions src/predict.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ cfg_if::cfg_if! {
}
}

use aligned_vec::{avec, ABox};

use crate::context::{TileBlockOffset, MAX_SB_SIZE_LOG2, MAX_TX_SIZE};
use crate::cpu_features::CpuFeatureLevel;
use crate::encoder::FrameInvariants;
Expand Down Expand Up @@ -423,7 +425,7 @@ impl PredictionMode {
/// compound inter prediction.
#[derive(Debug)]
pub struct InterCompoundBuffers {
data: AlignedBoxedSlice<i16>,
data: ABox<[i16]>,
}

impl InterCompoundBuffers {
Expand Down Expand Up @@ -452,7 +454,7 @@ impl InterCompoundBuffers {

impl Default for InterCompoundBuffers {
fn default() -> Self {
Self { data: AlignedBoxedSlice::new(2 * Self::BUFFER_SIZE, 0) }
Self { data: avec![0; 2 * Self::BUFFER_SIZE].into_boxed_slice() }
}
}

Expand Down
104 changes: 0 additions & 104 deletions src/util/align.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,7 @@
// Media Patent License 1.0 was not distributed with this source code in the
// PATENTS file, you can obtain it at www.aomedia.org/license/patent.

use std::alloc::{alloc, dealloc, Layout};
use std::mem::MaybeUninit;
use std::ptr;
use std::{fmt, mem};

#[repr(align(64))]
pub struct Align64;
Expand Down Expand Up @@ -64,101 +61,6 @@ impl<T> Aligned<T> {
}
}

/// An analog to a Box<[T]> where the underlying slice is aligned.
/// Alignment is according to the architecture-specific SIMD constraints.
pub struct AlignedBoxedSlice<T> {
ptr: std::ptr::NonNull<T>,
len: usize,
}

impl<T> AlignedBoxedSlice<T> {
// Data alignment in bytes.
cfg_if::cfg_if! {
if #[cfg(target_arch = "wasm32")] {
// FIXME: wasm32 allocator fails for alignment larger than 3
const DATA_ALIGNMENT_LOG2: usize = 3;
} else {
const DATA_ALIGNMENT_LOG2: usize = 6;
}
}

const fn layout(len: usize) -> Layout {
// SAFETY: We are ensuring that `align` is non-zero and is a multiple of 2.
unsafe {
Layout::from_size_align_unchecked(
len * mem::size_of::<T>(),
1 << Self::DATA_ALIGNMENT_LOG2,
)
}
}

fn alloc(len: usize) -> std::ptr::NonNull<T> {
// SAFETY: We are not calling this with a null pointer, so it's safe.
unsafe { ptr::NonNull::new_unchecked(alloc(Self::layout(len)) as *mut T) }
}

/// Creates a [`AlignedBoxedSlice`] with a slice of length [`len`] filled with
/// [`val`].
pub fn new(len: usize, val: T) -> Self
where
T: Clone,
{
let mut output = Self { ptr: Self::alloc(len), len };

for a in output.iter_mut() {
*a = val.clone();
}

output
}
}

impl<T: fmt::Debug> fmt::Debug for AlignedBoxedSlice<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(&**self, f)
}
}

impl<T> std::ops::Deref for AlignedBoxedSlice<T> {
type Target = [T];

fn deref(&self) -> &[T] {
// SAFETY: We know that `self.ptr` is not null, and we know its length.
unsafe {
let p = self.ptr.as_ptr();

std::slice::from_raw_parts(p, self.len)
}
}
}

impl<T> std::ops::DerefMut for AlignedBoxedSlice<T> {
fn deref_mut(&mut self) -> &mut [T] {
// SAFETY: We know that `self.ptr` is not null, and we know its length.
unsafe {
let p = self.ptr.as_ptr();

std::slice::from_raw_parts_mut(p, self.len)
}
}
}

impl<T> std::ops::Drop for AlignedBoxedSlice<T> {
fn drop(&mut self) {
// SAFETY: We know that the contents of this struct are aligned and valid to drop.
unsafe {
for a in self.iter_mut() {
ptr::drop_in_place(a)
}

dealloc(self.ptr.as_ptr() as *mut u8, Self::layout(self.len));
}
}
}

unsafe impl<T> Send for AlignedBoxedSlice<T> where T: Send {}
unsafe impl<T> Sync for AlignedBoxedSlice<T> where T: Sync {}

#[cfg(test)]
mod test {
use super::*;
Expand All @@ -172,10 +74,4 @@ mod test {
let a: Aligned<_> = Aligned::new([0u8; 3]);
assert!(is_aligned(a.data.as_ptr(), 4));
}

#[test]
fn sanity_heap() {
let a: AlignedBoxedSlice<_> = AlignedBoxedSlice::new(3, 0u8);
assert!(is_aligned(a.as_ptr(), 4));
}
}

0 comments on commit 732162e

Please sign in to comment.