36#define FALLBACK_PAGE_SIZE 4096U
44#define MAX_NUMBER_OF_BLOCKS 256U
47#define DEFAULT_BLOCK_ALIGNMENT 16U
53#define DESIRED_BLOCK_SIZE 131072
63#define SRN_BLOCK_NO_ID SIZE_MAX
70 void *(*allocate)(
size_t size,
size_t alignment);
97 "srn_block_t::base must be 16-byte aligned");
100typedef struct srn_allocation_stats_t {
101 size_t total_allocations;
102 size_t total_os_allocations;
103 size_t allocated_pages;
105} srn_allocation_stats_t;
114 srn_allocation_stats_t stats;
158[[nodiscard]] [[gnu::nonnull(1)]]
void *
160 size_t size,
size_t alignment);
163[[nodiscard]] [[gnu::nonnull(1)]]
void *
166#define srn_mm_allocate_in_block(mm, id, T) \
167 (T *)srn_mm_allocate_in_block_aligned(mm, id, sizeof(T), alignof(T))
169#define srn_mm_immortal_allocate(mm, T) \
170 (T *)srn_mm_immortal_allocate_aligned(mm, sizeof(T), alignof(T))
200[[nodiscard]] [[gnu::nonnull(1)]]
void *
210void srn_mm_print_blocks_summary(
srn_mm_t *mm);
size_t srn_block_id_t
The block id is effectively just an index in the blocks array in srn_mm_t.
void srn_mm_release_block(srn_mm_t *mm, srn_block_id_t id)
Release the given block id and free the memory for later allocations.
void * srn_mm_allocate_in_block_aligned(srn_mm_t *mm, srn_block_id_t block_id, size_t size, size_t alignment)
Allocate memory on a block with the given block_id.
void srn_lock_memory_manager(srn_mm_t *mm)
Locks the memory manager.
srn_block_t * srn_mm_get_block(srn_mm_t *mm, srn_block_id_t block_id)
Return the block object associated by the given block_id
void * srn_mm_reallocate(srn_mm_t *mm, void *ptr, size_t new_size)
void * srn_mm_immortal_allocate_aligned(srn_mm_t *mm, size_t size, size_t alignment)
Allocate memory on the importal block which will never gets freed.
void srn_mm_free(srn_mm_t *mm, void *ptr)
Release a pointer previously returned by srn_mm_allocate or srn_mm_reallocate.
srn_block_id_t srn_mm_allocate_block(srn_mm_t *mm)
Allocate a new block in the memory manager and return its ID.
void * srn_mm_allocate(srn_mm_t *mm, size_t size)
Generic allocations that do not participate in the block based pools.
size_t srn_mm_get_os_page_size(void)
Retutrns the OS page size.
srn_mm_t * srn_mm_init(void)
Initialize the memory manager, this function will panic on error.
void srn_mm_shutdown(srn_mm_t *mm)
Shut down the memory manager and release the resources.
size_t srn_mm_get_block_size(void)
Calculates and return the block size based on our desired size and the OS page size.
#define MAX_NUMBER_OF_BLOCKS
TODO(lxsameer): Since we want to move fast, at this stage a static array of blocks is enough for us,...
void srn_unlock_memory_manager(srn_mm_t *mm)
Unocks the memory manager.
uint8_t base[]
Where the data area starts.
size_t offset
Offset from the base.
srn_spinlock_t lock
This lock will protect only the block level operations and NOT the memory manager.
size_t size
This is the TOTAL size of the block, header + payloud.
struct srn_block_t * next
when the block does not have space to allocate a request, we will allocate a new block and point to i...
This interface is here to abstract over the allocator.
Main memory manager structure that will own all the allocated blocks and data.
srn_block_t * blocks[MAX_NUMBER_OF_BLOCKS]
srn_spinlock_t lock
This spinlock is here to protect the srn_mm_t when allocating/deallocating new blocks.
srn_block_t * immortal_block
Immortal block is a chain of blocks which will never die.
uint64_t block_bitmap[4]
This is a 256bit bitmap we treat it as a whole.
srn_memory_provider_t * provider
An abstraction over a memory provider like the malloc/free pair.