Skip to main content

storage_device/
buffer.rs

1// Copyright 2021 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use crate::buffer_allocator::BufferAllocator as PoolBufferAllocator;
6use std::borrow::Borrow;
7use std::marker::PhantomData;
8use std::ops::{Bound, Range, RangeBounds};
9use std::slice::SliceIndex;
10use storage_ptr_slice::{MutPtrByteSlice, PtrByteSlice};
11
12pub use crate::buffer_allocator::BufferFuture;
13
14/// An entity capable of reclaiming a memory buffer range when dropped.
15pub trait BufferAllocator: Send + Sync + std::fmt::Debug + 'static {
16    /// Frees or reclaims the specified memory range.
17    fn free_buffer(&self, range: Range<usize>);
18}
19
20pub(super) fn round_down<T>(value: T, granularity: T) -> T
21where
22    T: num::Num + Copy,
23{
24    value - value % granularity
25}
26
27pub(super) fn round_up<T>(value: T, granularity: T) -> T
28where
29    T: num::Num + Copy,
30{
31    round_down(value + granularity - T::one(), granularity)
32}
33
34// Returns a range within a range.
35// For example, subrange(100..200, 20..30) = 120..130.
36fn subrange<R: RangeBounds<usize>>(source: &Range<usize>, bounds: &R) -> Range<usize> {
37    let subrange = (match bounds.start_bound() {
38        Bound::Included(&s) => source.start + s,
39        Bound::Excluded(&s) => source.start + s + 1,
40        Bound::Unbounded => source.start,
41    })..(match bounds.end_bound() {
42        Bound::Included(&e) => source.start + e + 1,
43        Bound::Excluded(&e) => source.start + e,
44        Bound::Unbounded => source.end,
45    });
46    assert!(subrange.end <= source.end);
47    subrange
48}
49
50fn split_range(range: &Range<usize>, mid: usize) -> (Range<usize>, Range<usize>) {
51    let l = range.end - range.start;
52    let base = range.start;
53    (base..base + mid, base + mid..base + l)
54}
55/// Buffer is a read-write buffer that can be used for I/O with the block device. They are created
56/// by a BufferAllocator, and automatically deallocate themselves when they go out of scope.
57///
58/// Most usage will be on the unowned BufferRef and MutableBufferRef types, since these types are
59/// used for Device::read and Device::write.
60///
61/// Buffers are always block-aligned (both in offset and length), but unaligned slices can be made
62/// with the reference types. That said, the Device trait requires aligned BufferRef and
63/// MutableBufferRef objects, so alignment must be restored by the time a device read/write is
64/// requested.
65///
66/// For example, when writing an unaligned amount of data to the device, generally two Buffers
67/// would need to be involved; the input Buffer could be used to write everything up to the last
68/// block, and a second single-block alignment Buffer would be used to read-modify-update the last
69/// block.
70use std::sync::Arc;
71
72#[derive(Debug)]
73pub struct BufferImpl<'a, H: Borrow<A>, A: ?Sized + BufferAllocator> {
74    slice: MutPtrByteSlice<'a>,
75    range: Range<usize>,
76    allocator: H,
77    _phantom: PhantomData<fn() -> &'a A>,
78}
79
80pub type Buffer<'a> = BufferImpl<'a, &'a PoolBufferAllocator, PoolBufferAllocator>;
81pub type OwnedBuffer = BufferImpl<'static, Arc<dyn BufferAllocator>, dyn BufferAllocator>;
82
83// Alias for the traits which need to be satisfied for `subslice` and friends.
84// This trait is automatically satisfied for most typical uses (a..b, a.., ..b, ..).
85pub trait SliceRange: Clone + RangeBounds<usize> + SliceIndex<[u8], Output = [u8]> {}
86impl<T> SliceRange for T where T: Clone + RangeBounds<usize> + SliceIndex<[u8], Output = [u8]> {}
87
88impl<'a, H: Borrow<A>, A: ?Sized + BufferAllocator> BufferImpl<'a, H, A> {
89    pub(super) fn new(slice: MutPtrByteSlice<'a>, range: Range<usize>, allocator: H) -> Self {
90        assert_eq!(slice.len(), range.end - range.start);
91        Self { slice, range, allocator, _phantom: PhantomData }
92    }
93
94    /// Takes a read-only reference to this buffer.
95    pub fn as_ref(&self) -> BufferRef<'_> {
96        self.subslice(..)
97    }
98
99    /// Takes a read-only reference to this buffer over `range` (which must be within the size of
100    /// the buffer).
101    pub fn subslice<R: SliceRange>(&self, range: R) -> BufferRef<'_> {
102        let new_range = subrange(&self.range, &range);
103        let relative_range =
104            (new_range.start - self.range.start)..(new_range.end - self.range.start);
105        let slice = self.slice.as_ptr_slice().subslice(relative_range);
106        BufferRef { slice, start: new_range.start, end: new_range.end }
107    }
108
109    /// Takes a read-write reference to this buffer.
110    pub fn as_mut(&mut self) -> MutableBufferRef<'_> {
111        self.subslice_mut(..)
112    }
113
114    /// Takes a read-write reference to this buffer over `range` (which must be within the size of
115    /// the buffer).
116    pub fn subslice_mut<R: SliceRange>(&mut self, range: R) -> MutableBufferRef<'_> {
117        let new_range = subrange(&self.range, &range);
118        let relative_range =
119            (new_range.start - self.range.start)..(new_range.end - self.range.start);
120        let slice = self.slice.reborrow().subslice_mut(relative_range);
121        MutableBufferRef { slice, range: new_range }
122    }
123
124    /// Returns the buffer's capacity.
125    pub fn len(&self) -> usize {
126        self.range.end - self.range.start
127    }
128
129    /// Returns a slice of the buffer's contents.
130    pub fn as_slice(&self) -> &[u8] {
131        // SAFETY: `self.slice` points to a valid memory range of `self.len()` bytes.
132        unsafe { std::slice::from_raw_parts(self.slice.as_ptr(), self.len()) }
133    }
134
135    /// Returns a mutable slice of the buffer's contents.
136    pub fn as_mut_slice(&mut self) -> &mut [u8] {
137        // SAFETY: `&mut self` guarantees exclusive mutable access to this range of `self.len()`
138        // bytes.
139        unsafe { std::slice::from_raw_parts_mut(self.slice.as_mut_ptr(), self.len()) }
140    }
141
142    /// Copies the contents of this buffer into `dest`.
143    ///
144    /// # Panics
145    ///
146    /// Panics if `dest.len() != self.len()`.
147    pub fn copy_to_slice(&self, dest: &mut [u8]) {
148        self.slice.as_ptr_slice().copy_to_slice(dest);
149    }
150
151    /// Copies the contents of `src` into this buffer.
152    ///
153    /// # Panics
154    ///
155    /// Panics if `src.len() != self.len()`.
156    pub fn copy_from_slice(&mut self, src: &[u8]) {
157        self.as_mut_slice().copy_from_slice(src);
158    }
159
160    /// Fills the buffer with `val`.
161    pub fn fill(&mut self, val: u8) {
162        self.slice.fill(val);
163    }
164
165    /// Returns the range in the underlying BufferSource that this buffer covers.
166    pub fn range(&self) -> Range<usize> {
167        self.range.clone()
168    }
169
170    /// Returns a reference to the allocator.
171    pub fn allocator(&self) -> &A {
172        self.allocator.borrow()
173    }
174
175    /// Returns the buffer's contents as a Vec.
176    pub fn to_vec(&self) -> Vec<u8> {
177        self.as_ref().to_vec()
178    }
179
180    /// Appends the buffer's contents to `vec`.
181    pub fn append_to(&self, vec: &mut Vec<u8>) {
182        self.as_ref().append_to(vec)
183    }
184
185    /// Returns a raw pointer to the buffer's contents.
186    pub fn as_ptr(&self) -> *const u8 {
187        self.slice.as_ptr()
188    }
189
190    /// Returns a mutable raw pointer to the buffer's contents.
191    pub fn as_mut_ptr(&mut self) -> *mut u8 {
192        self.slice.as_mut_ptr()
193    }
194
195    /// Returns a read-only pointer slice over the buffer.
196    pub fn as_ptr_slice(&self) -> PtrByteSlice<'_> {
197        self.slice.as_ptr_slice()
198    }
199
200    /// Returns a mutable pointer slice over the buffer.
201    pub fn as_mut_ptr_slice(&mut self) -> MutPtrByteSlice<'_> {
202        self.slice.reborrow()
203    }
204}
205
206impl<'a, H: Borrow<A>, A: ?Sized + BufferAllocator> Drop for BufferImpl<'a, H, A> {
207    fn drop(&mut self) {
208        self.allocator.borrow().free_buffer(self.range.clone());
209    }
210}
211
212/// BufferRef is an unowned, read-only view over a Buffer.
213#[derive(Clone, Copy, Debug)]
214pub struct BufferRef<'a> {
215    slice: PtrByteSlice<'a>,
216    start: usize, // Not range so that we get Copy.
217    end: usize,
218}
219
220impl<'a> BufferRef<'a> {
221    /// Returns the buffer's capacity.
222    pub fn len(&self) -> usize {
223        self.end - self.start
224    }
225
226    pub fn is_empty(&self) -> bool {
227        self.end == self.start
228    }
229
230    /// Returns a slice of the buffer's contents.
231    pub fn as_slice(&self) -> &[u8] {
232        // SAFETY: The caller must ensure safety if the buffer is shared. This is a temporary
233        // compatibility shim during the soft-transition.
234        unsafe { std::slice::from_raw_parts(self.slice.as_ptr(), self.len()) }
235    }
236
237    /// Slices and consumes this reference. See Buffer::subslice.
238    pub fn subslice<R: SliceRange>(&self, range: R) -> BufferRef<'_> {
239        let new_range = subrange(&self.range(), &range);
240        let relative_range = (new_range.start - self.start)..(new_range.end - self.start);
241        let slice = self.slice.subslice(relative_range);
242        BufferRef { slice, start: new_range.start, end: new_range.end }
243    }
244
245    /// Splits at `mid` (included in the right child), yielding two BufferRefs.
246    pub fn split_at(&self, mid: usize) -> (BufferRef<'_>, BufferRef<'_>) {
247        let ranges = split_range(&self.range(), mid);
248        let (left_slice, right_slice) = self.slice.split_at(mid);
249        (
250            BufferRef { slice: left_slice, start: ranges.0.start, end: ranges.0.end },
251            BufferRef { slice: right_slice, start: ranges.1.start, end: ranges.1.end },
252        )
253    }
254
255    /// Returns the range in the underlying BufferSource that this BufferRef covers.
256    pub fn range(&self) -> Range<usize> {
257        self.start..self.end
258    }
259
260    /// Copies the contents of this buffer into `dest`.
261    ///
262    /// # Panics
263    ///
264    /// Panics if `dest.len() != self.len()`.
265    pub fn copy_to_slice(&self, dest: &mut [u8]) {
266        self.slice.copy_to_slice(dest);
267    }
268
269    /// Returns the buffer's contents as a Vec.
270    pub fn to_vec(&self) -> Vec<u8> {
271        self.slice.to_vec()
272    }
273
274    /// Appends the buffer's contents to `vec`.
275    pub fn append_to(&self, vec: &mut Vec<u8>) {
276        self.slice.append_to(vec);
277    }
278
279    /// Returns a raw pointer to the buffer's contents.
280    pub fn as_ptr(&self) -> *const u8 {
281        self.slice.as_ptr()
282    }
283
284    /// Returns a read-only pointer slice over the buffer.
285    pub fn as_ptr_slice(&self) -> PtrByteSlice<'a> {
286        self.slice
287    }
288}
289
290/// MutableBufferRef is an unowned, read-write view of a Buffer.
291#[derive(Debug)]
292pub struct MutableBufferRef<'a> {
293    slice: MutPtrByteSlice<'a>,
294    range: Range<usize>,
295}
296
297impl<'a> MutableBufferRef<'a> {
298    /// Returns the buffer's capacity.
299    pub fn len(&self) -> usize {
300        self.range.end - self.range.start
301    }
302
303    pub fn is_empty(&self) -> bool {
304        self.range.end == self.range.start
305    }
306
307    /// Returns a read-only view of the buffer.
308    pub fn as_ref(&self) -> BufferRef<'_> {
309        BufferRef { slice: self.slice.as_ptr_slice(), start: self.range.start, end: self.range.end }
310    }
311
312    /// Consumes this reference and returns a read-only view.
313    pub fn into_ref(self) -> BufferRef<'a> {
314        BufferRef { slice: self.slice.into(), start: self.range.start, end: self.range.end }
315    }
316
317    /// Returns a slice of the buffer's contents.
318    pub fn as_slice(&self) -> &[u8] {
319        // SAFETY: The caller must ensure safety if the buffer is shared. This is a temporary
320        // compatibility shim during the soft-transition.
321        unsafe { std::slice::from_raw_parts(self.slice.as_ptr(), self.len()) }
322    }
323
324    /// Returns a mutable slice of the buffer's contents.
325    pub fn as_mut_slice(&mut self) -> &mut [u8] {
326        // SAFETY: The caller must ensure safety if the buffer is shared. This is a temporary
327        // compatibility shim during the soft-transition.
328        unsafe { std::slice::from_raw_parts_mut(self.slice.as_mut_ptr(), self.len()) }
329    }
330
331    /// Reborrows this reference with a lesser lifetime. This mirrors the usual borrowing semantics
332    /// (i.e. the borrow ends when the new reference goes out of scope), and exists so that a
333    /// MutableBufferRef can be subsliced without consuming it.
334    ///
335    /// For example:
336    ///    let mut buf: MutableBufferRef<'_> = ...;
337    ///    {
338    ///        let sub = buf.reborrow().subslice_mut(a..b);
339    ///    }
340    pub fn reborrow(&mut self) -> MutableBufferRef<'_> {
341        MutableBufferRef { slice: self.slice.reborrow(), range: self.range.clone() }
342    }
343
344    /// Slices this reference. See Buffer::subslice.
345    pub fn subslice<R: SliceRange>(&self, range: R) -> BufferRef<'_> {
346        let new_range = subrange(&self.range, &range);
347        let relative_range =
348            (new_range.start - self.range.start)..(new_range.end - self.range.start);
349        let slice = self.slice.as_ptr_slice().subslice(relative_range);
350        BufferRef { slice, start: new_range.start, end: new_range.end }
351    }
352
353    /// Slices and consumes this reference. See Buffer::subslice_mut.
354    pub fn subslice_mut<R: SliceRange>(mut self, range: R) -> MutableBufferRef<'a> {
355        let new_range = subrange(&self.range, &range);
356        let relative_range =
357            (new_range.start - self.range.start)..(new_range.end - self.range.start);
358        self.slice = self.slice.subslice_mut(relative_range);
359        self.range = new_range;
360        self
361    }
362
363    /// Splits at `mid` (included in the right child), yielding two BufferRefs.
364    pub fn split_at(&self, mid: usize) -> (BufferRef<'_>, BufferRef<'_>) {
365        let ranges = split_range(&self.range, mid);
366        let (left_slice, right_slice) = self.slice.as_ptr_slice().split_at(mid);
367        (
368            BufferRef { slice: left_slice, start: ranges.0.start, end: ranges.0.end },
369            BufferRef { slice: right_slice, start: ranges.1.start, end: ranges.1.end },
370        )
371    }
372
373    /// Consumes the reference and splits it at `mid` (included in the right child), yielding two
374    /// MutableBufferRefs.
375    pub fn split_at_mut(self, mid: usize) -> (MutableBufferRef<'a>, MutableBufferRef<'a>) {
376        let ranges = split_range(&self.range, mid);
377        let (left_slice, right_slice) = self.slice.split_at_mut(mid);
378        (
379            MutableBufferRef { slice: left_slice, range: ranges.0 },
380            MutableBufferRef { slice: right_slice, range: ranges.1 },
381        )
382    }
383
384    /// Returns the range in the underlying BufferSource that this MutableBufferRef covers.
385    pub fn range(&self) -> Range<usize> {
386        self.range.clone()
387    }
388
389    /// Copies the contents of this buffer into `dest`.
390    ///
391    /// # Panics
392    ///
393    /// Panics if `dest.len() != self.len()`.
394    pub fn copy_to_slice(&self, dest: &mut [u8]) {
395        self.slice.copy_to_slice(dest);
396    }
397
398    /// Copies the contents of `src` into this buffer.
399    ///
400    /// # Panics
401    ///
402    /// Panics if `src.len() != self.len()`.
403    pub fn copy_from_slice(&mut self, src: &[u8]) {
404        self.slice.copy_from_ptr_slice(src.into());
405    }
406
407    /// Fills the buffer with `val`.
408    pub fn fill(&mut self, val: u8) {
409        self.slice.fill(val);
410    }
411
412    /// Returns the buffer's contents as a Vec.
413    pub fn to_vec(&self) -> Vec<u8> {
414        self.slice.to_vec()
415    }
416
417    /// Appends the buffer's contents to `vec`.
418    pub fn append_to(&self, vec: &mut Vec<u8>) {
419        self.slice.append_to(vec);
420    }
421
422    /// Returns a raw pointer to the buffer's contents.
423    pub fn as_ptr(&self) -> *const u8 {
424        self.slice.as_ptr()
425    }
426
427    /// Returns a mutable raw pointer to the buffer's contents.
428    pub fn as_mut_ptr(&mut self) -> *mut u8 {
429        self.slice.as_mut_ptr()
430    }
431
432    /// Returns a read-only pointer slice over the buffer.
433    pub fn as_ptr_slice(&self) -> PtrByteSlice<'_> {
434        self.slice.as_ptr_slice()
435    }
436
437    /// Returns a mutable pointer slice over the buffer.
438    pub fn as_mut_ptr_slice(&mut self) -> MutPtrByteSlice<'_> {
439        self.slice.reborrow()
440    }
441
442    /// Consumes this reference and returns a mutable pointer slice.
443    pub fn into_mut_ptr_slice(self) -> MutPtrByteSlice<'a> {
444        self.slice
445    }
446}
447
448// SAFETY: BufferRef is a read-only view over allocator-managed memory. It does not allow
449// mutation and behaves like `&[u8]`, which is Send and Sync.
450unsafe impl Send for BufferRef<'_> {}
451// SAFETY: See Send impl above.
452unsafe impl Sync for BufferRef<'_> {}
453
454// SAFETY: MutableBufferRef behaves like `&mut [u8]`. It enforces exclusivity (no overlapping
455// views) and does not have interior mutability, making it safe to Send and Sync.
456unsafe impl Send for MutableBufferRef<'_> {}
457// SAFETY: See Send impl above.
458unsafe impl Sync for MutableBufferRef<'_> {}