From 2d8c689ac1f417abd963444e443ec0a64ed18967 Mon Sep 17 00:00:00 2001 From: Alex Kotov Date: Tue, 1 Dec 2020 04:38:55 +0500 Subject: [PATCH] Alloc and free pages in PFA --- include/kernaux/pfa.h | 10 +++++++--- src/pfa.c | 24 ++++++++++++++++++++++++ tests/test_pfa.c | 10 ++++++++++ 3 files changed, 41 insertions(+), 3 deletions(-) diff --git a/include/kernaux/pfa.h b/include/kernaux/pfa.h index b80e355..2a63f6d 100644 --- a/include/kernaux/pfa.h +++ b/include/kernaux/pfa.h @@ -14,9 +14,7 @@ struct KernAux_PFA { kernaux_bool pages[KERNAUX_PFA_PAGES_COUNT_MAX]; }; -void KernAux_PFA_initialize( - struct KernAux_PFA *pfa -) +void KernAux_PFA_initialize(struct KernAux_PFA *pfa) __attribute__((nonnull)); void KernAux_PFA_mark_available( @@ -26,6 +24,12 @@ void KernAux_PFA_mark_available( ) __attribute__((nonnull)); +unsigned int KernAux_PFA_alloc_page(struct KernAux_PFA *pfa) +__attribute__((nonnull)); + +void KernAux_PFA_free_page(struct KernAux_PFA *pfa, unsigned int page_addr) +__attribute__((nonnull)); + #ifdef __cplusplus } #endif diff --git a/src/pfa.c b/src/pfa.c index 3a5b46e..360a1da 100644 --- a/src/pfa.c +++ b/src/pfa.c @@ -35,3 +35,27 @@ void KernAux_PFA_mark_available( pfa->pages[index] = KERNAUX_TRUE; } } + +unsigned int KernAux_PFA_alloc_page(struct KernAux_PFA *pfa) +{ + // We start from 1 because 0 indicates failure. + // It is not very usefull to alloc page at address 0; + // + for (unsigned int index = 1; index < KERNAUX_PFA_PAGES_COUNT_MAX; ++index) { + if (pfa->pages[index]) { + pfa->pages[index] = KERNAUX_FALSE; + return index * KERNAUX_PFA_PAGE_SIZE; + } + } + + return 0; +} + +void KernAux_PFA_free_page(struct KernAux_PFA *pfa, unsigned int page_addr) +{ + if (page_addr % KERNAUX_PFA_PAGE_SIZE != 0) { + return; + } + + pfa->pages[page_addr / KERNAUX_PFA_PAGE_SIZE] = KERNAUX_TRUE; +} diff --git a/tests/test_pfa.c b/tests/test_pfa.c index bd07e25..96811a3 100644 --- a/tests/test_pfa.c +++ b/tests/test_pfa.c @@ -35,5 +35,15 @@ int main() assert(pfa.pages[index] == KERNAUX_FALSE); } + unsigned int page_addr = KernAux_PFA_alloc_page(&pfa); + + assert(page_addr != 0); + assert(page_addr % KERNAUX_PFA_PAGE_SIZE == 0); + assert(!pfa.pages[page_addr / KERNAUX_PFA_PAGE_SIZE]); + + KernAux_PFA_free_page(&pfa, page_addr); + + assert(pfa.pages[page_addr / KERNAUX_PFA_PAGE_SIZE]); + return 0; }