From 8701c9b47319202e845fb12b3e7f7bc829b4c144 Mon Sep 17 00:00:00 2001 From: Kimplul Date: Wed, 26 Jul 2023 19:23:33 +0300 Subject: allow tail call optimizations to happen easier --- common/pmem.c | 47 +++++++++++++++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 16 deletions(-) (limited to 'common') diff --git a/common/pmem.c b/common/pmem.c index 8169b88..02c5146 100644 --- a/common/pmem.c +++ b/common/pmem.c @@ -177,12 +177,11 @@ static void __mark_free(struct mm_branch *branch, pm_t page, return; } + /* freeing a page results in always clearing a full bit */ + bitmap_clear(branch->used, idx); if(cur_order != tree_order) __mark_free(sub_branch(branch, idx), page, req_order, cur_order - 1, tree_order); - - /* freeing a page results in always clearing a full bit */ - bitmap_clear(branch->used, idx); } /** @@ -319,32 +318,48 @@ static pm_t __branch_find_first_unset(struct mm_branch *branch) } /** - * Search for unused pages in tree. + * Main worker for searching a free page. + * Passing the address worked up so far allows the compiler to performa + * tail call optimization, speeding things up a little. * * @param branch Current branch. * @param cur_order Current order of branch. * @param req_order Requested page order. - * @return \c -1 if there are no free pages, otherwise the address of the lower - * order page found. + * @param addr Address built up so far. + * @return Final address of found free page if found, -1 otherwise. */ -static pm_t __search_tree(struct mm_branch *branch, - enum mm_order cur_order, - enum mm_order req_order) +static pm_t __search_branch(struct mm_branch *branch, + enum mm_order cur_order, + enum mm_order req_order, + pm_t addr) { pm_t page = __branch_find_first_unset(branch); if (page == (pm_t)(-1)) return -1; if (cur_order == req_order) - return page << order_shift(cur_order); + return addr | page << order_shift(cur_order); - pm_t r = __search_tree(sub_branch(branch, page), - cur_order - 1, req_order); - - if (r == (pm_t)(-1)) - return -1; + return __search_branch(sub_branch(branch, page), + cur_order - 1, req_order, + addr | page << order_shift(cur_order)); +} - return (page << order_shift(cur_order)) + r; +/** + * Search for unused pages in tree. + * Easy wrapper for __search_branch. + * + * @param branch Current branch. + * @param cur_order Current order of branch. + * @param req_order Requested page order. + * @return \c -1 if there are no free pages, otherwise the address of the lower + * order page found. + */ +static pm_t __search_tree(struct mm_branch *branch, + enum mm_order cur_order, + enum mm_order req_order) +{ + return __search_branch(branch, cur_order, req_order, 0); } pm_t alloc_page(enum mm_order order) -- cgit v1.3