iceoryx2_bb_memory/
heap_allocator.rs

1// Copyright (c) 2023 Contributors to the Eclipse Foundation
2//
3// See the NOTICE file(s) distributed with this work for additional
4// information regarding copyright ownership.
5//
6// This program and the accompanying materials are made available under the
7// terms of the Apache Software License 2.0 which is available at
8// https://www.apache.org/licenses/LICENSE-2.0, or the MIT license
9// which is available at https://opensource.org/licenses/MIT.
10//
11// SPDX-License-Identifier: Apache-2.0 OR MIT
12
13//! A **threadsafe** and **lock-free** [`Allocator`] which acquires the memory from the heap.
14
15use core::{alloc::Layout, ptr::NonNull};
16
17use iceoryx2_bb_elementary_traits::allocator::{AllocationGrowError, AllocationShrinkError};
18use iceoryx2_bb_posix::memory::heap;
19use iceoryx2_log::fail;
20
21pub use iceoryx2_bb_elementary_traits::allocator::{AllocationError, Allocator, BaseAllocator};
22
23#[derive(Debug)]
24pub struct HeapAllocator {}
25
26impl Default for HeapAllocator {
27    fn default() -> Self {
28        Self::new()
29    }
30}
31
32impl HeapAllocator {
33    pub const fn new() -> HeapAllocator {
34        HeapAllocator {}
35    }
36
37    pub fn global() -> &'static HeapAllocator {
38        static ALLOCATOR: HeapAllocator = HeapAllocator {};
39        &ALLOCATOR
40    }
41}
42
43impl BaseAllocator for HeapAllocator {
44    fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocationError> {
45        Ok(fail!(from self, when heap::allocate(layout),
46                "Failed to allocate {} bytes with an alignment of {}.", layout.size(), layout.align()))
47    }
48
49    unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
50        heap::deallocate(ptr, layout);
51    }
52}
53
54impl Allocator for HeapAllocator {
55    unsafe fn grow(
56        &self,
57        ptr: NonNull<u8>,
58        old_layout: Layout,
59        new_layout: Layout,
60    ) -> Result<NonNull<[u8]>, AllocationGrowError> {
61        if old_layout.size() >= new_layout.size() {
62            fail!(from self, with AllocationGrowError::GrowWouldShrink,
63                "Failed to grow memory from (size: {}, align: {}) to (size: {}, align: {}).", old_layout.size(),old_layout.align(), new_layout.size(), new_layout.align());
64        }
65        Ok(
66            fail!(from self, when heap::resize(ptr, old_layout, new_layout),
67                "Failed to grow memory from (size: {}, align: {}) to (size: {}, align: {}).", old_layout.size(),old_layout.align(), new_layout.size(), new_layout.align()),
68        )
69    }
70
71    unsafe fn shrink(
72        &self,
73        ptr: NonNull<u8>,
74        old_layout: Layout,
75        new_layout: Layout,
76    ) -> Result<NonNull<[u8]>, AllocationShrinkError> {
77        if old_layout.size() <= new_layout.size() {
78            fail!(from self, with AllocationShrinkError::ShrinkWouldGrow,
79                "Failed to shrink memory from (size: {}, align: {}) to (size: {}, align: {}).", old_layout.size(),old_layout.align(), new_layout.size(), new_layout.align());
80        }
81        Ok(
82            fail!(from self, when heap::resize(ptr, old_layout, new_layout),
83                "Failed to shrink memory from (size: {}, align: {}) to (size: {}, align: {}).", old_layout.size(),old_layout.align(), new_layout.size(), new_layout.align()),
84        )
85    }
86}