drivers/android/binder/range_alloc/array.rs

Source file repositories/reference/linux-study-clean/drivers/android/binder/range_alloc/array.rs

File Facts

System
Linux kernel
Corpus path
drivers/android/binder/range_alloc/array.rs
Extension
.rs
Size
9592 bytes
Lines
282
Domain
Driver Families
Bucket
drivers/android
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct FindEmptyRes {
    /// Which index in `ranges` should we insert the new range at?
    ///
    /// Inserting the new range at this index keeps `ranges` sorted.
    insert_at_idx: usize,
    /// Which offset should we insert the new range at?
    insert_at_offset: usize,
}

impl<T> ArrayRangeAllocator<T> {
    pub(crate) fn new(size: usize, alloc: EmptyArrayAlloc<T>) -> Self {
        Self {
            ranges: alloc.ranges,
            size,
            free_oneway_space: size / 2,
        }
    }

    pub(crate) fn free_oneway_space(&self) -> usize {
        self.free_oneway_space
    }

    pub(crate) fn count_buffers(&self) -> usize {
        self.ranges.len()
    }

    pub(crate) fn total_size(&self) -> usize {
        self.size
    }

    pub(crate) fn is_full(&self) -> bool {
        self.ranges.len() == self.ranges.capacity()
    }

    pub(crate) fn debug_print(&self, m: &SeqFile) -> Result<()> {
        for range in &self.ranges {
            seq_print!(
                m,
                "  buffer {}: {} size {} pid {} oneway {}",
                0,
                range.offset,
                range.size,
                range.state.pid(),
                range.state.is_oneway(),
            );
            if let DescriptorState::Reserved(_) = range.state {
                seq_print!(m, " reserved\n");
            } else {
                seq_print!(m, " allocated\n");
            }
        }
        Ok(())
    }

    /// Find somewhere to put a new range.
    ///
    /// Unlike the tree implementation, we do not bother to find the smallest gap. The idea is that
    /// fragmentation isn't a big issue when we don't have many ranges.
    ///
    /// Returns the index that the new range should have in `self.ranges` after insertion.
    fn find_empty_range(&self, size: usize) -> Option<FindEmptyRes> {
        let after_last_range = self.ranges.last().map(Range::endpoint).unwrap_or(0);

        if size <= self.total_size() - after_last_range {
            // We can put the range at the end, so just do that.
            Some(FindEmptyRes {
                insert_at_idx: self.ranges.len(),
                insert_at_offset: after_last_range,
            })
        } else {
            let mut end_of_prev = 0;
            for (i, range) in self.ranges.iter().enumerate() {
                // Does it fit before the i'th range?
                if size <= range.offset - end_of_prev {
                    return Some(FindEmptyRes {
                        insert_at_idx: i,
                        insert_at_offset: end_of_prev,
                    });
                }
                end_of_prev = range.endpoint();
            }
            None
        }
    }

    pub(crate) fn reserve_new(
        &mut self,
        debug_id: usize,
        size: usize,
        is_oneway: bool,

Annotation

Implementation Notes