From 50ad329b6e4e19942e30c78cf709b24cd3ad08b7 Mon Sep 17 00:00:00 2001 From: Enrico Fraccaroli Date: Tue, 19 Oct 2021 14:32:08 +0200 Subject: [PATCH] Improve buddysystem comments. --- mentos/src/mem/buddysystem.c | 88 ++++++++++++++++++++++-------------- 1 file changed, 53 insertions(+), 35 deletions(-) diff --git a/mentos/src/mem/buddysystem.c b/mentos/src/mem/buddysystem.c index d1cd2b1..410521d 100644 --- a/mentos/src/mem/buddysystem.c +++ b/mentos/src/mem/buddysystem.c @@ -6,6 +6,7 @@ /// Change the header. #define __DEBUG_HEADER__ "[BUDDY ]" +#define __DEBUG_LEVEL__ 100 #include "mem/buddysystem.h" #include "mem/paging.h" @@ -71,16 +72,16 @@ static inline bb_page_t *__get_page_at_index(bb_instance_t *instance, unsigned i } /// @brief Computes the number of pages separating the two pages (begin, end). -/// @param instance The buddy system instance we are working with. -/// @param begin The first page. -/// @param end The second page. +/// @param instance the buddy system instance we are working with. +/// @param begin the first page. +/// @param end the second page. /// @return The number of pages between begin and end. static inline unsigned int __get_page_range(bb_instance_t *instance, bb_page_t *begin, bb_page_t *end) { return (((uintptr_t)end) - ((uintptr_t)begin)) / instance->pgs_size; } -/// @brief Get the buddy index of a page. +/// @brief Get the buddy index of a page. /// @details /// ----------------------- xor ----------------------- /// | page_idx ^ (1UL << order) = buddy_idx | @@ -90,14 +91,28 @@ static inline unsigned int __get_page_range(bb_instance_t *instance, bb_page_t * /// If the bit of page_idx that corresponds to the block /// size, is 1, then we have to take the block on the /// left (0), otherwise we have to take the block on the right (1). -/// @param page_idx A page index. -/// @param order The logarithm of the size of the block. -/// @return The page index of the buddy of page. +/// @param page_idx the page index. +/// @param order the logarithm of the size of the block. +/// @return the page index of the buddy of page. static inline unsigned long __get_buddy_at_index(unsigned long page_idx, unsigned int order) { return (page_idx ^ (1UL << order)); } +/// @brief Returns the pointer to the free-area manager for the given order. +/// +/// @param instance the buddysystem instance. +/// @param order the desired order. +/// @return pointer to the free-area manager. +static inline bb_free_area_t *__get_area_of_order(bb_instance_t *instance, unsigned int order) +{ + return instance->free_area + order; +} + +/// @brief Checks if the page is FREE and has the same order. +/// @param page the page to check. +/// @param order the oder to check. +/// @return true if the page is buddy, false otherwise. static inline bool_t __page_is_buddy(bb_page_t *page, unsigned int order) { return __bb_test_flag(page, FREE_PAGE) && (page->order == order); @@ -236,7 +251,7 @@ void bb_free_pages(bb_instance_t *instance, bb_page_t *page) // Get the page that gets forgotten, it's always the one on the right (the greatest) bb_page_t *forgot_page = buddy > page ? buddy : page; - + // Clear the root flag from the forgotten page. /* ... */; @@ -254,14 +269,14 @@ void bb_free_pages(bb_instance_t *instance, bb_page_t *page) // Update the order of the coalesced page. /* ... */; - + // Set it to be a root page and a free page /* ... */; /* ... */; // Insert coalesced as first element in the free list. list_head_add(&/* ... */, &/* ... */); - + // Increase the number of free block of the free_area_t. /* ... */; @@ -277,29 +292,34 @@ void buddy_system_init(bb_instance_t *instance, uint32_t pages_stride, uint32_t pages_count) { - // Compute the base bb page of the struct + // Compute the base base page of the buddysystem instance. instance->base_page = ((bb_page_t *)(((uint32_t)pages_start) + bbpage_offset)); - - // Save all needed page info + // Save all needed page info. instance->bbpg_offset = bbpage_offset; instance->pgs_size = pages_stride; instance->size = pages_count; instance->name = name; - // Initialize all pages - for (uint32_t i = 0; i < pages_count; i++) { - bb_page_t *page = __get_page_at_index(instance, i); - page->flags = 0; - // Mark page as free + // Initialize all pages. + for (uint32_t index = 0; index < pages_count; ++index) { + // Get the page at the given index. + bb_page_t *page = __get_page_at_index(instance, index); + // Initialize the flags of the page. + page->flags = 0; + // Mark page as free. __bb_set_flag(page, FREE_PAGE); - // Initialize siblings list + // Initialize siblings list. list_head_init(&(page->location.siblings)); + // N.B.: The order is initialized afterwards. } // Initialize the free_lists of each area of the zone. for (unsigned int order = 0; order < MAX_BUDDYSYSTEM_GFP_ORDER; order++) { - bb_free_area_t *area = instance->free_area + order; - area->nr_free = 0; + // Get the area that manages the given order. + bb_free_area_t *area = __get_area_of_order(instance, order); + // Initialize the number of free pages. + area->nr_free = 0; + // Initialize linked list of free pages. list_head_init(&area->free_list); } @@ -307,29 +327,27 @@ void buddy_system_init(bb_instance_t *instance, bb_page_t *page = instance->base_page; // Address of the last page descriptor of the zone. bb_page_t *last_page = __get_page_from_base(instance, page, instance->size); - + // Initially, all the memory is divided into blocks of the higher order. + const unsigned int max_order = MAX_BUDDYSYSTEM_GFP_ORDER - 1; // Get the free area collecting the larges block of page frames. - const unsigned int order = MAX_BUDDYSYSTEM_GFP_ORDER - 1; - bb_free_area_t *area = instance->free_area + order; - + bb_free_area_t *area = __get_area_of_order(instance, max_order); + // Compute the block size. + uint32_t block_size = 1UL << max_order; // Add all zone's pages to the largest free area block. - uint32_t block_size = 1UL << order; while ((page + block_size) <= last_page) { // Save the order of the page. - page->order = order; - // Set the page as root + page->order = max_order; + // Set the page as root. __bb_set_flag(page, ROOT_PAGE); - - // Insert page as first element in the list. + // Insert the page inside the list of free pages of the area. list_head_add_tail(&page->location.siblings, &area->free_list); - // Increase the number of free block of the free_area_t. + // Increase the number of free block of the area. area->nr_free++; - + // Move to the next page. page = __get_page_from_base(instance, page, block_size); } - - assert(page == last_page && - "Memory size is not aligned to MAX_ORDER size!"); + // Check that the page we have reached with the iteration is the last page. + assert(page == last_page && "Memory size is not aligned to MAX_ORDER size!"); } void buddy_system_dump(bb_instance_t *instance)