124 lines
4.7 KiB
C
124 lines
4.7 KiB
C
/// @file buddysystem.h
|
|
/// @brief Buddy System.
|
|
/// @copyright (c) 2014-2022 This file is distributed under the MIT License.
|
|
/// See LICENSE.md for details.
|
|
|
|
#pragma once
|
|
|
|
#include "klib/list_head.h"
|
|
#include "klib/stdatomic.h"
|
|
#include "stdint.h"
|
|
|
|
/// @brief Max gfp pages order of buddysystem blocks.
|
|
#define MAX_BUDDYSYSTEM_GFP_ORDER 14
|
|
|
|
/// @brief Provide the offset of the element inside the given type of page.
|
|
#define BBSTRUCT_OFFSET(page, element) \
|
|
((uint32_t) & (((page *)NULL)->element))
|
|
|
|
/// @brief Returns the address of the given element of a given type of page,
|
|
/// based on the provided bbstruct.
|
|
#define PG_FROM_BBSTRUCT(bbstruct, page, element) \
|
|
((page *)(((uint32_t)(bbstruct)) - BBSTRUCT_OFFSET(page, element)))
|
|
|
|
/// The base structure representing a bb page
|
|
typedef struct bb_page_t {
|
|
/// The flags of the page.
|
|
volatile unsigned long flags;
|
|
/// The current page order.
|
|
uint32_t order;
|
|
/// Keep track of where the page is located.
|
|
union {
|
|
/// The page siblings when not allocated.
|
|
list_head siblings;
|
|
/// The cache list pointer when allocated but on cache.
|
|
list_head cache;
|
|
} location;
|
|
} bb_page_t;
|
|
|
|
/// @brief Buddy system descriptor: collection of free page blocks.
|
|
/// Each block represents 2^k free contiguous page.
|
|
typedef struct bb_free_area_t {
|
|
/// free_list collectes the first page descriptors of a blocks of 2^k frames
|
|
list_head free_list;
|
|
/// nr_free specifies the number of blocks of free pages.
|
|
int nr_free;
|
|
} bb_free_area_t;
|
|
|
|
/// @brief Buddy system instance,
|
|
/// that represents a memory area managed by the buddy system
|
|
typedef struct bb_instance_t {
|
|
/// Name of this bb instance
|
|
const char *name;
|
|
/// List of buddy system pages grouped by level.
|
|
bb_free_area_t free_area[MAX_BUDDYSYSTEM_GFP_ORDER];
|
|
/// Pointer to start of free pages cache
|
|
list_head free_pages_cache_list;
|
|
/// Size of the current cache
|
|
unsigned long free_pages_cache_size;
|
|
/// Buddysystem instance size in number of pages.
|
|
unsigned long size;
|
|
/// Address of the first managed page
|
|
bb_page_t *base_page;
|
|
/// Size of the (padded) wrapper page structure
|
|
unsigned long pgs_size;
|
|
/// Offset of the bb_page_t struct from the start of the whole structure
|
|
unsigned long bbpg_offset;
|
|
} bb_instance_t;
|
|
|
|
/// @brief Allocate a block of page frames of size 2^order.
|
|
/// @param instance A buddy system instance.
|
|
/// @param order The logarithm of the size of the block.
|
|
/// @return The address of the first page descriptor of the block, or NULL.
|
|
bb_page_t *bb_alloc_pages(bb_instance_t *instance, unsigned int order);
|
|
|
|
/// @brief Free a block of page frames of size 2^order.
|
|
/// @param instance A buddy system instance.
|
|
/// @param page The address of the first page descriptor of the block.
|
|
void bb_free_pages(bb_instance_t *instance, bb_page_t *page);
|
|
|
|
/// @brief Alloc a page using bb cache.
|
|
/// @param instance Buddy system instance.
|
|
/// @return An allocated page.
|
|
bb_page_t *bb_alloc_page_cached(bb_instance_t *instance);
|
|
|
|
/// @brief Free a page allocated with bb_alloc_page_cached.
|
|
/// @param instance Buddy system instance.
|
|
/// @param page The address of the first page descriptor of the block.
|
|
void bb_free_page_cached(bb_instance_t *instance, bb_page_t *page);
|
|
|
|
/// @brief Initialize Buddy System.
|
|
/// @param instance A buddysystem instance.
|
|
/// @param name The name of the current instance (for debug purposes)
|
|
/// @param pages_start The start address of the page structures
|
|
/// @param bbpage_offset The offset from the start of the whole page of the
|
|
/// bb_page_t struct.
|
|
/// @param pages_stride The (padded) size of the whole page structure
|
|
/// @param pages_count The number of pages in this region
|
|
void buddy_system_init(
|
|
bb_instance_t *instance,
|
|
const char *name,
|
|
void *pages_start,
|
|
uint32_t bbpage_offset,
|
|
uint32_t pages_stride,
|
|
uint32_t pages_count);
|
|
|
|
/// @brief Print the size of free_list of each free_area.
|
|
/// @param instance A buddy system instance.
|
|
void buddy_system_dump(bb_instance_t *instance);
|
|
|
|
/// @brief Returns the total space for the given instance.
|
|
/// @param instance A buddy system instance.
|
|
/// @return The requested total sapce.
|
|
unsigned long buddy_system_get_total_space(bb_instance_t *instance);
|
|
|
|
/// @brief Returns the free space for the given instance.
|
|
/// @param instance A buddy system instance.
|
|
/// @return The requested total sapce.
|
|
unsigned long buddy_system_get_free_space(bb_instance_t *instance);
|
|
|
|
/// @brief Returns the cached space for the given instance.
|
|
/// @param instance A buddy system instance.
|
|
/// @return The requested total sapce.
|
|
unsigned long buddy_system_get_cached_space(bb_instance_t *instance);
|