1
0
Fork 0
mirror of https://github.com/tailix/libkernaux.git synced 2024-10-30 11:54:01 -04:00

Allocate and free multiple pages in PFA

This commit is contained in:
Alex Kotov 2021-12-14 05:39:54 +05:00
parent 42f13090c7
commit 98c7db3f13
Signed by: kotovalexarian
GPG key ID: 553C0EBBEB5D5F08
3 changed files with 77 additions and 8 deletions

View file

@ -32,9 +32,15 @@ __attribute__((nonnull));
size_t KernAux_PFA_alloc_page(KernAux_PFA pfa) size_t KernAux_PFA_alloc_page(KernAux_PFA pfa)
__attribute__((nonnull)); __attribute__((nonnull));
size_t KernAux_PFA_alloc_pages(KernAux_PFA pfa, size_t mem_size)
__attribute__((nonnull));
void KernAux_PFA_free_page(KernAux_PFA pfa, size_t page_addr) void KernAux_PFA_free_page(KernAux_PFA pfa, size_t page_addr)
__attribute__((nonnull)); __attribute__((nonnull));
void KernAux_PFA_free_pages(KernAux_PFA pfa, size_t page_addr, size_t mem_size)
__attribute__((nonnull));
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View file

@ -71,8 +71,7 @@ void KernAux_PFA_mark(
size_t KernAux_PFA_alloc_page(const KernAux_PFA pfa) size_t KernAux_PFA_alloc_page(const KernAux_PFA pfa)
{ {
// We start from 1 because 0 indicates failure. // We start from 1 because 0 indicates failure.
// It is not very usefull to alloc page at address 0; // It is not very useful to alloc page at address 0;
//
for (size_t index = 1; index < KERNAUX_PFA_PAGES_COUNT_MAX; ++index) { for (size_t index = 1; index < KERNAUX_PFA_PAGES_COUNT_MAX; ++index) {
if (pfa->pages[index]) { if (pfa->pages[index]) {
pfa->pages[index] = false; pfa->pages[index] = false;
@ -83,9 +82,51 @@ size_t KernAux_PFA_alloc_page(const KernAux_PFA pfa)
return 0; return 0;
} }
size_t KernAux_PFA_alloc_pages(const KernAux_PFA pfa, const size_t mem_size)
{
if (mem_size % KERNAUX_PFA_PAGE_SIZE != 0) return 0;
const size_t pages_count = mem_size / KERNAUX_PFA_PAGE_SIZE;
// We start from 1 because 0 indicates failure.
// It is not very useful to alloc page at address 0;
for (size_t start = 1; start < KERNAUX_PFA_PAGES_COUNT_MAX;) {
size_t end = start;
for (; end < start + pages_count; ++end) {
if (!pfa->pages[end]) break;
}
if (end >= KERNAUX_PFA_PAGES_COUNT_MAX) return 0;
if (end == start + pages_count - 1) {
for (size_t index = start; index <= end; ++index) {
pfa->pages[index] = false;
}
return start * KERNAUX_PFA_PAGE_SIZE;
}
start = end + 1;
}
return 0;
}
void KernAux_PFA_free_page(const KernAux_PFA pfa, size_t page_addr) void KernAux_PFA_free_page(const KernAux_PFA pfa, size_t page_addr)
{ {
if (page_addr % KERNAUX_PFA_PAGE_SIZE != 0) return; if (page_addr % KERNAUX_PFA_PAGE_SIZE != 0) return;
pfa->pages[page_addr / KERNAUX_PFA_PAGE_SIZE] = true; pfa->pages[page_addr / KERNAUX_PFA_PAGE_SIZE] = true;
} }
void KernAux_PFA_free_pages(
const KernAux_PFA pfa,
const size_t page_addr,
const size_t mem_size
) {
if (page_addr % KERNAUX_PFA_PAGE_SIZE != 0) return;
if (mem_size % KERNAUX_PFA_PAGE_SIZE != 0) return;
const size_t start_index = page_addr / KERNAUX_PFA_PAGE_SIZE;
const size_t pages_count = mem_size / KERNAUX_PFA_PAGE_SIZE;
for (size_t index = 0; index < pages_count; ++index) {
pfa->pages[start_index + index] = true;
}
}

View file

@ -44,6 +44,7 @@ int main()
assert(!KernAux_PFA_is_available(&pfa, index * KERNAUX_PFA_PAGE_SIZE)); assert(!KernAux_PFA_is_available(&pfa, index * KERNAUX_PFA_PAGE_SIZE));
} }
{
const size_t page_addr = KernAux_PFA_alloc_page(&pfa); const size_t page_addr = KernAux_PFA_alloc_page(&pfa);
assert(page_addr != 0); assert(page_addr != 0);
@ -53,6 +54,27 @@ int main()
KernAux_PFA_free_page(&pfa, page_addr); KernAux_PFA_free_page(&pfa, page_addr);
assert(KernAux_PFA_is_available(&pfa, page_addr)); assert(KernAux_PFA_is_available(&pfa, page_addr));
}
{
const size_t page_addr =
KernAux_PFA_alloc_pages(&pfa, 10 * KERNAUX_PFA_PAGE_SIZE);
assert(page_addr != 0);
assert(page_addr % KERNAUX_PFA_PAGE_SIZE == 0);
for (size_t index = 0, addr = page_addr; index < 10; ++index) {
assert(!KernAux_PFA_is_available(&pfa, addr));
addr += KERNAUX_PFA_PAGE_SIZE;
}
KernAux_PFA_free_pages(&pfa, page_addr, 10 * KERNAUX_PFA_PAGE_SIZE);
for (size_t index = 0, addr = page_addr; index < 10; ++index) {
assert(KernAux_PFA_is_available(&pfa, addr));
addr += KERNAUX_PFA_PAGE_SIZE;
}
}
for (size_t index = 0; index < KERNAUX_PFA_PAGES_COUNT_MAX; ++index) { for (size_t index = 0; index < KERNAUX_PFA_PAGES_COUNT_MAX; ++index) {
if (KernAux_PFA_is_available(&pfa, index * KERNAUX_PFA_PAGE_SIZE)) { if (KernAux_PFA_is_available(&pfa, index * KERNAUX_PFA_PAGE_SIZE)) {