From: Lunaixsky Date: Sat, 8 Feb 2025 05:14:38 +0000 (+0000) Subject: reduce the size of ppage by 8 bytes using signly linked list X-Git-Url: https://scm.lunaixsky.com/lunaix-os.git/commitdiff_plain/104ad9766838ec1c572102d6fe0dd689b016b830?hp=669e8fc63dd1aa7fe4c830b1d40371a1ab47fc4f reduce the size of ppage by 8 bytes using signly linked list --- diff --git a/lunaix-os/includes/lunaix/ds/list.h b/lunaix-os/includes/lunaix/ds/list.h index 288ee66..e4ab344 100644 --- a/lunaix-os/includes/lunaix/ds/list.h +++ b/lunaix-os/includes/lunaix/ds/list.h @@ -33,7 +33,7 @@ list_head_init(struct list_head *list) static inline void list_node_init(struct list_node *node) { - node->next = node; + node->next = NULL; } #define slist_entry(ptr, type, member) \ @@ -58,10 +58,31 @@ __llist_add_batch(struct list_node *new_first, return new_last->next == NULL; } +static inline bool +list_empty(struct list_head* head) +{ + return !head->first; +} + static inline void list_add(struct list_head* head, struct list_node* node) { __llist_add_batch(node, node, head); } +static inline struct list_node* +list_pop_head(struct list_head* head) { + struct list_node* node; + + if (list_empty(head)) { + return NULL; + } + + node = head->first; + head->first = node->next; + + list_node_init(node); + return node; +} + #endif /* __LUNAIX_LIST_H */ diff --git a/lunaix-os/includes/lunaix/mm/physical.h b/lunaix-os/includes/lunaix/mm/physical.h index e1710bf..bb15e6c 100644 --- a/lunaix-os/includes/lunaix/mm/physical.h +++ b/lunaix-os/includes/lunaix/mm/physical.h @@ -3,6 +3,7 @@ #include #include +#include /** * @brief 长久页:不会被缓存,但允许释放 @@ -45,7 +46,7 @@ struct ppage }; unsigned short companion; - struct llist_header sibs; + struct list_node sibs; struct ppage_arch arch; } align(16); diff --git a/lunaix-os/includes/lunaix/mm/pmm.h b/lunaix-os/includes/lunaix/mm/pmm.h index bd55eb1..c0e08b2 100644 --- a/lunaix-os/includes/lunaix/mm/pmm.h +++ b/lunaix-os/includes/lunaix/mm/pmm.h @@ -36,7 +36,7 @@ struct pmem_pool #elif defined(CONFIG_PMALLOC_METHOD_SIMPLE) - struct llist_header idle_order[MAX_PAGE_ORDERS]; + struct list_head idle_order[MAX_PAGE_ORDERS]; int count[MAX_PAGE_ORDERS]; #endif diff --git a/lunaix-os/kernel/mm/pmalloc_simple.c b/lunaix-os/kernel/mm/pmalloc_simple.c index 93fae04..2cfcde3 100644 --- a/lunaix-os/kernel/mm/pmalloc_simple.c +++ b/lunaix-os/kernel/mm/pmalloc_simple.c @@ -27,13 +27,13 @@ __uninitialized_page(struct ppage* page) } static inline void -__set_page_initialized(struct ppage* page) +__init_page(struct ppage* page) { page->flags |= INIT_FLAG; } static inline void -__set_pages_uninitialized(struct ppage* lead) +__deinit_page(struct ppage* lead) { for (size_t i = 0; i < (1UL << lead->order); i++) { @@ -51,7 +51,7 @@ void pmm_allocator_init_pool(struct pmem_pool* pool) { for (int i = 0; i < MAX_PAGE_ORDERS; i++) { - llist_init_head(&pool->idle_order[i]); + list_head_init(&pool->idle_order[i]); pool->count[i] = 0; } @@ -78,15 +78,15 @@ pmm_free_one(struct ppage* page, int type_mask) assert(order <= MAX_PAGE_ORDERS); struct pmem_pool* pool = pmm_pool_lookup(page); - struct llist_header* bucket = &pool->idle_order[order]; + struct list_head* bucket = &pool->idle_order[order]; if (pool->count[order] < po_limit[order]) { - llist_append(bucket, &page->sibs); - pool->count[order]++; + list_add(bucket, &page->sibs); + pool->count[order] += 1; return; } - __set_pages_uninitialized(page); + __deinit_page(page); } static pfn_t index = 0; @@ -128,28 +128,42 @@ pmm_looknext(struct pmem_pool* pool, size_t order) page->companion = i; page->pool = pool->type; page->refs = 0; - llist_init_head(&page->sibs); - __set_page_initialized(page); + list_node_init(&page->sibs); + __init_page(page); } return lead; } +static struct ppage* +__select_free_page_from(struct list_head* bucket) +{ + struct list_node* sib; + struct ppage* page; + + do { + sib = list_pop_head(bucket); + page = sib ? slist_entry(sib, struct ppage, sibs) : NULL; + } while (page && __uninitialized_page(page)); + + return page; +} + struct ppage* pmm_alloc_napot_type(int pool, size_t order, ppage_type_t type) { assert(order <= MAX_PAGE_ORDERS); struct pmem_pool* _pool = pmm_pool_get(pool); - struct llist_header* bucket = &_pool->idle_order[order]; - + struct list_head* bucket = &_pool->idle_order[order]; struct ppage* good_page = NULL; - if (!llist_empty(bucket)) { - (_pool->count[order])--; - good_page = list_entry(bucket->next, struct ppage, sibs); - llist_delete(&good_page->sibs); + + if (!list_empty(bucket)) { + _pool->count[order] -= 1; + good_page = __select_free_page_from(bucket); } - else { + + if (!good_page) { good_page = pmm_looknext(_pool, order); } @@ -169,14 +183,10 @@ pmm_allocator_trymark_onhold(struct pmem_pool* pool, while (start <= end) { if (__uninitialized_page(start)) { set_reserved(start); - __set_page_initialized(start); + __init_page(start); } else if (!start->refs) { - struct ppage* lead = leading_page(start); - llist_delete(&lead->sibs); - - __set_pages_uninitialized(lead); - + __deinit_page(leading_page(start)); continue; } else if (!reserved_page(start)) { @@ -195,7 +205,7 @@ pmm_allocator_trymark_unhold(struct pmem_pool* pool, { while (start <= end) { if (!__uninitialized_page(start) && reserved_page(start)) { - __set_pages_uninitialized(start); + __deinit_page(start); } start++;