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:
parent
42f13090c7
commit
98c7db3f13
3 changed files with 77 additions and 8 deletions
|
@ -32,9 +32,15 @@ __attribute__((nonnull));
|
|||
size_t KernAux_PFA_alloc_page(KernAux_PFA pfa)
|
||||
__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)
|
||||
__attribute__((nonnull));
|
||||
|
||||
void KernAux_PFA_free_pages(KernAux_PFA pfa, size_t page_addr, size_t mem_size)
|
||||
__attribute__((nonnull));
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
45
src/pfa.c
45
src/pfa.c
|
@ -71,8 +71,7 @@ void KernAux_PFA_mark(
|
|||
size_t KernAux_PFA_alloc_page(const KernAux_PFA pfa)
|
||||
{
|
||||
// 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) {
|
||||
if (pfa->pages[index]) {
|
||||
pfa->pages[index] = false;
|
||||
|
@ -83,9 +82,51 @@ size_t KernAux_PFA_alloc_page(const KernAux_PFA pfa)
|
|||
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)
|
||||
{
|
||||
if (page_addr % KERNAUX_PFA_PAGE_SIZE != 0) return;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,15 +44,37 @@ int main()
|
|||
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 % KERNAUX_PFA_PAGE_SIZE == 0);
|
||||
assert(!KernAux_PFA_is_available(&pfa, page_addr));
|
||||
assert(page_addr != 0);
|
||||
assert(page_addr % KERNAUX_PFA_PAGE_SIZE == 0);
|
||||
assert(!KernAux_PFA_is_available(&pfa, page_addr));
|
||||
|
||||
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) {
|
||||
if (KernAux_PFA_is_available(&pfa, index * KERNAUX_PFA_PAGE_SIZE)) {
|
||||
|
|
Loading…
Reference in a new issue