60 lines
3.7 KiB
C
60 lines
3.7 KiB
C
// SPDX-License-Identifier: MPL-2.0
|
|
// This is the implementation for the slab allocator for sh_radix_NODE
|
|
#ifndef SH_LIB_SLAB_RADIX_NODE_H
|
|
#define SH_LIB_SLAB_RADIX_NODE_H
|
|
#include "memory/page.h"
|
|
#include "std/status.h"
|
|
#include "std/type.h"
|
|
#include "memory/pez/radix.h"
|
|
#include "memory/pba.h"
|
|
#define SH_SLAB_RADIX_NODE_SLAB_DATA_PAGES (sh_uint64)32
|
|
#define SH_SLAB_RADIX_NODE_SLAB_DATA_SIZE_BYTES (sh_uint64)(SH_SLAB_RADIX_NODE_SLAB_DATA_PAGES*4096)
|
|
#define SH_SLAB_RADIX_NODE_OBJECT_SIZE_BYTES (sh_uint64)128
|
|
#define SH_SLAB_RADIX_NODE_OBJECTS_PER_SLAB (sh_uint64)1024
|
|
#define SH_SLAB_RADIX_NODE_ACTUAL_OBJECTS_PER_SLAB (sh_uint64)1006
|
|
#define SH_SLAB_RADIX_NODE_SLAB_BITMAP_SIZE_BYTES (sh_uint64)(SH_SLAB_RADIX_NODE_OBJECTS_PER_SLAB/8)
|
|
#define SH_SLAB_RADIX_NODE_NULL_REF (sh_uint64)0
|
|
#define SH_SLAB_RADIX_NODE_SLAB_SIG {'S','h','S','l','R','a','N','o'}
|
|
#define SH_SLAB_RADIX_NODE_MAGIC 0x6F4E61526C536853ULL // little endian
|
|
// Radix node slab structure
|
|
#pragma pack(1)
|
|
typedef struct sh_slab_radix_node_SLAB {
|
|
sh_uint8 sig[8];
|
|
sh_uint16 used_count;
|
|
sh_uint64 slab_index;
|
|
struct sh_slab_radix_node_SLAB* next_slab;
|
|
struct sh_slab_radix_node_SLAB* prev_slab;
|
|
struct sh_slab_radix_node_SLAB* next_partial;
|
|
struct sh_slab_radix_node_SLAB* prev_partial;
|
|
sh_uint8 padding[78];
|
|
sh_uint64 free_bitmap[16]; // First 18 objects will be mark as unavailable due to being replaced by the header and bitmap
|
|
sh_uint16 node_bitmap[1024];
|
|
sh_radix_NODE nodes[SH_SLAB_RADIX_NODE_ACTUAL_OBJECTS_PER_SLAB];
|
|
} sh_slab_radix_node_SLAB;
|
|
#pragma pack()
|
|
// Radix node slab allocator structure
|
|
struct sh_slab_radix_node_SLAB_ALLOCATOR {
|
|
sh_slab_radix_node_SLAB* first_slab;
|
|
sh_slab_radix_node_SLAB* partial_head;
|
|
sh_uint64 slab_count;
|
|
sh_pba_PAGE_BLOCK_ALLOCATOR* pba;
|
|
};
|
|
typedef sh_uint16 sh_slab_radix_node_NODE_INDEX_IN_SLAB;
|
|
// Initialize slab allocator structure. Does not allocate any slab
|
|
SH_STATUS sh_slab_radix_node_alloc_init(struct sh_slab_radix_node_SLAB_ALLOCATOR* slab_alloc,sh_pba_PAGE_BLOCK_ALLOCATOR *pba);
|
|
// Allocate a new slab, initialize it and put it into the allocator. If new slab isn't the first to be allocated, push it on the partial slab list
|
|
SH_STATUS sh_slab_radix_node_add_slab(struct sh_slab_radix_node_SLAB_ALLOCATOR* alloc,sh_page_PAGE_TABLE_POOL *ptp,sh_slab_radix_node_SLAB** out_slab);
|
|
// Obtain a pointer to the first partial slab. Does not scan the slabs. Allocate a new slab if necessary
|
|
SH_STATUS sh_slab_radix_node_get_partial_slab(struct sh_slab_radix_node_SLAB_ALLOCATOR* alloc,sh_page_PAGE_TABLE_POOL* ptp,sh_slab_radix_node_SLAB** found_slab);
|
|
// Rescan all the slabs to set all metadatas in case of doubt. Does not modify alloc->slab_count or <any slab>->nodes
|
|
SH_STATUS sh_slab_radix_node_scan_slabs(struct sh_slab_radix_node_SLAB_ALLOCATOR* alloc);
|
|
// Return a valid pointer to an empty object slot as well as the object index in the corresponding index. Slabs allocation is automated by sh_slab_radix_node_get_partial_slab
|
|
SH_STATUS sh_slab_radix_node_find_free_object(struct sh_slab_radix_node_SLAB_ALLOCATOR* alloc,sh_page_PAGE_TABLE_POOL *ptp,sh_radix_NODE** out,sh_slab_radix_node_NODE_INDEX_IN_SLAB* index_in_slab);
|
|
// Allocate one new radix node object. Return a pointer to the struct of the new object. Since it call sh_slab_reg_phys_find_free_object, it can allocate new slab
|
|
SH_STATUS sh_slab_radix_node_alloc(struct sh_slab_radix_node_SLAB_ALLOCATOR* alloc,sh_page_PAGE_TABLE_POOL *ptp,sh_radix_NODE** out_obj);
|
|
// Dellocate one radix node object provided as pointer.
|
|
SH_STATUS sh_slab_radix_node_dealloc(struct sh_slab_radix_node_SLAB_ALLOCATOR* alloc,sh_radix_NODE *object_ptr);
|
|
// Return a pointer to the bitmap of a node
|
|
sh_uint16 *sh_slab_radix_node_get_node_bitmap(struct sh_slab_radix_node_SLAB_ALLOCATOR* alloc,sh_radix_NODE *object_ptr);
|
|
#endif
|