(struct uk_alloc *a, void *base, size_t size);
typedef ssize_t (*uk_alloc_getsize_func_t)
(struct uk_alloc *a);
+typedef long (*uk_alloc_getpsize_func_t)
+ (struct uk_alloc *a);
struct uk_alloc {
/* memory allocation */
/* optional interfaces, but recommended */
uk_alloc_getsize_func_t maxalloc; /* biggest alloc req. (bytes) */
uk_alloc_getsize_func_t availmem; /* total memory available (bytes) */
+ uk_alloc_getpsize_func_t pmaxalloc; /* biggest alloc req. (pages) */
+ uk_alloc_getpsize_func_t pavailmem; /* total pages available */
/* optional interface */
uk_alloc_addmem_func_t addmem;
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);
return a->availmem(a);
}
+static inline long uk_alloc_pavailmem(struct uk_alloc *a)
+{
+ UK_ASSERT(a);
+ if (!a->pavailmem)
+ return (long) -ENOTSUP;
+ return a->pavailmem(a);
+}
+
#ifdef __cplusplus
}
#endif
#endif
/* Shortcut for doing a registration of an allocator that only
- * implements palloc(), pfree(), addmem()
+ * implements palloc(), pfree(), pmaxalloc(), pavailmem(), 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, \
+ pavailmem_func, addmem_func) \
do { \
(a)->malloc = uk_malloc_ifpages; \
(a)->calloc = uk_calloc_compat; \
(a)->free = uk_free_ifpages; \
(a)->palloc = (palloc_func); \
(a)->pfree = (pfree_func); \
+ (a)->pavailmem = (pavailmem_func); \
+ (a)->pmaxalloc = (pmaxalloc_func); \
(a)->addmem = (addmem_func); \
\
uk_alloc_register((a)); \
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)
{
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_pavailmem(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;
/* initialize and register allocator interface */
uk_alloc_init_palloc(a, bbuddy_palloc, bbuddy_pfree,
+ bbuddy_pmaxalloc, bbuddy_pavailmem,
bbuddy_addmem);
- a->availmem = bbuddy_availmem;
if (max > min + metalen) {
/* add left memory - ignore return value */