[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [UNIKRAFT PATCH 06/18] lib/ukalloc: Introduce `uk_alloc_pavail()`, `uk_alloc_pmaxalloc()`
This commit introduces - `uk_alloc_pavail()` as an equivalent for `uk_alloc_availmem()` for page allocators. - `uk_alloc_pmaxalloc()` as an equivalent for `uk_alloc_maxalloc()` for page allocators. Signed-off-by: Simon Kuenzer <simon.kuenzer@xxxxxxxxx> --- lib/ukalloc/include/uk/alloc.h | 21 +++++++++++++++ lib/ukalloc/include/uk/alloc_impl.h | 7 +++-- lib/ukallocbbuddy/bbuddy.c | 41 ++++++++++++++++++++++------- 3 files changed, 57 insertions(+), 12 deletions(-) diff --git a/lib/ukalloc/include/uk/alloc.h b/lib/ukalloc/include/uk/alloc.h index af5a71cd..b711b56a 100644 --- a/lib/ukalloc/include/uk/alloc.h +++ b/lib/ukalloc/include/uk/alloc.h @@ -68,6 +68,8 @@ typedef int (*uk_alloc_addmem_func_t) (struct uk_alloc *a, void *base, size_t size); typedef ssize_t (*uk_alloc_availmem_func_t) (struct uk_alloc *a); +typedef long (*uk_alloc_pavail_func_t) + (struct uk_alloc *a); struct uk_alloc { /* memory allocation */ @@ -89,6 +91,8 @@ struct uk_alloc { /* optional interfaces, but recommended */ uk_alloc_availmem_func_t maxalloc; /* biggest alloc req. (bytes) */ uk_alloc_availmem_func_t availmem; /* total memory available (bytes) */ + uk_alloc_pavail_func_t pmaxalloc; /* biggest alloc req. (pages) */ + uk_alloc_pavail_func_t pavail; /* total pages available */ /* optional interface */ uk_alloc_addmem_func_t addmem; @@ -244,6 +248,15 @@ static inline ssize_t uk_alloc_maxalloc(struct uk_alloc *a) return a->maxalloc(a); } +static inline long uk_alloc_pmaxalloc(struct uk_alloc *a) +{ + UK_ASSERT(a); + if (!a->pmaxalloc) + return (long) -ENOTSUP; + return a->pmaxalloc(a); +} + +/* total free memory of the allocator */ static inline ssize_t uk_alloc_availmem(struct uk_alloc *a) { UK_ASSERT(a); @@ -252,6 +265,14 @@ static inline ssize_t uk_alloc_availmem(struct uk_alloc *a) return a->availmem(a); } +static inline long uk_alloc_pavail(struct uk_alloc *a) +{ + UK_ASSERT(a); + if (!a->pavail) + return (long) -ENOTSUP; + return a->pavail(a); +} + #ifdef __cplusplus } #endif diff --git a/lib/ukalloc/include/uk/alloc_impl.h b/lib/ukalloc/include/uk/alloc_impl.h index beeb59f0..7e96ed94 100644 --- a/lib/ukalloc/include/uk/alloc_impl.h +++ b/lib/ukalloc/include/uk/alloc_impl.h @@ -120,9 +120,10 @@ void uk_pfree_compat(struct uk_alloc *a, void *ptr, unsigned long num_pages); #endif /* Shortcut for doing a registration of an allocator that only - * implements palloc(), pfree(), addmem() + * implements palloc(), pfree(), pavail(), addmem() */ -#define uk_alloc_init_palloc(a, palloc_func, pfree_func, addmem_func) \ +#define uk_alloc_init_palloc(a, palloc_func, pfree_func, pmaxalloc_func, \ + pavail_func, addmem_func) \ do { \ (a)->malloc = uk_malloc_ifpages; \ (a)->calloc = uk_calloc_compat; \ @@ -132,6 +133,8 @@ void uk_pfree_compat(struct uk_alloc *a, void *ptr, unsigned long num_pages); (a)->free = uk_free_ifpages; \ (a)->palloc = (palloc_func); \ (a)->pfree = (pfree_func); \ + (a)->pavail = (pavail_func); \ + (a)->pmaxalloc = (pmaxalloc_func); \ (a)->addmem = (addmem_func); \ \ uk_alloc_register((a)); \ diff --git a/lib/ukallocbbuddy/bbuddy.c b/lib/ukallocbbuddy/bbuddy.c index 3730eeb2..b63e2fd3 100644 --- a/lib/ukallocbbuddy/bbuddy.c +++ b/lib/ukallocbbuddy/bbuddy.c @@ -214,15 +214,6 @@ static void map_free(struct uk_bbpalloc *b, uintptr_t first_page, b->nr_free_pages += nr_pages; } -static ssize_t bbuddy_availmem(struct uk_alloc *a) -{ - struct uk_bbpalloc *b; - - UK_ASSERT(a != NULL); - b = (struct uk_bbpalloc *)&a->priv; - return (ssize_t) b->nr_free_pages << __PAGE_SHIFT; -} - /* return log of the next power of two of passed number */ static inline unsigned long num_pages_to_order(unsigned long num_pages) { @@ -360,6 +351,36 @@ static void bbuddy_pfree(struct uk_alloc *a, void *obj, unsigned long num_pages) b->free_head[order] = freed_ch; } +static long bbuddy_pmaxalloc(struct uk_alloc *a) +{ + struct uk_bbpalloc *b; + size_t i, order; + + UK_ASSERT(a != NULL); + b = (struct uk_bbpalloc *)&a->priv; + + /* Find biggest order that has still elements available */ + order = FREELIST_SIZE; + for (i = 0; i < FREELIST_SIZE; i++) { + if (!FREELIST_EMPTY(b->free_head[i])) + order = i; + } + if (order == FREELIST_SIZE) + return 0; /* no memory left */ + + return (long) (1 << order); +} + +static long bbuddy_pavail(struct uk_alloc *a) +{ + struct uk_bbpalloc *b; + + UK_ASSERT(a != NULL); + b = (struct uk_bbpalloc *)&a->priv; + + return (long) b->nr_free_pages; +} + static int bbuddy_addmem(struct uk_alloc *a, void *base, size_t len) { struct uk_bbpalloc *b; @@ -501,8 +522,8 @@ struct uk_alloc *uk_allocbbuddy_init(void *base, size_t len) /* initialize and register allocator interface */ uk_alloc_init_palloc(a, bbuddy_palloc, bbuddy_pfree, + bbuddy_pmaxalloc, bbuddy_pavail, bbuddy_addmem); - a->availmem = bbuddy_availmem; if (max > min + metalen) { /* add left memory - ignore return value */ -- 2.20.1
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |