[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [UNIKRAFT PATCH 1/2] lib/ukallocregion: add region-based allocator
Hi Simon, it looks like region.c is missing an #include (inline). We might want to fix this with a v2 after your review (or while upstreaming). regards, Hugo On Mon, 2020-06-22 at 16:23 +0200, Hugo Lefeuvre wrote: > Add ukallocregion, a minimalist region-based allocator. > > Note that deallocation is not supported. This makes sense because > regions > only allow for deallocation at region-granularity. In our case, this > would > imply the freeing of the entire heap, which is generally not > possible. > > Obviously, the lack of deallocation support makes ukallocregion a > fairly > bad general-purpose allocator. This allocator is interesting in that > it > offers maximum speed allocation and deallocation (bounded O(1), no > bookkeeping). It can be used as a baseline for measurements (e.g., > boot > time) or as a first-level allocator in a nested context. > > Refer to Gay & Aiken, `Memory management with explicit regions' > (PLDI'98) > for an introduction to region-based memory management. > > Signed-off-by: Hugo Lefeuvre <hugo.lefeuvre@xxxxxxxxx> > --- > lib/Makefile.uk | 1 + > lib/ukallocregion/Config.uk | 13 +++ > lib/ukallocregion/Makefile.uk | 6 + > lib/ukallocregion/exportsyms.uk | 1 + > lib/ukallocregion/include/uk/allocregion.h | 49 +++++++++ > lib/ukallocregion/region.c | 169 > +++++++++++++++++++++++++++++ > 6 files changed, 239 insertions(+) > create mode 100644 lib/ukallocregion/Config.uk > create mode 100644 lib/ukallocregion/Makefile.uk > create mode 100644 lib/ukallocregion/exportsyms.uk > create mode 100644 lib/ukallocregion/include/uk/allocregion.h > create mode 100644 lib/ukallocregion/region.c > > diff --git a/lib/Makefile.uk b/lib/Makefile.uk > index aa7e730..1f223d2 100644 > --- a/lib/Makefile.uk > +++ b/lib/Makefile.uk > @@ -14,6 +14,7 @@ $(eval $(call > _import_lib,$(CONFIG_UK_BASE)/lib/uktimeconv)) > $(eval $(call _import_lib,$(CONFIG_UK_BASE)/lib/nolibc)) > $(eval $(call _import_lib,$(CONFIG_UK_BASE)/lib/ukalloc)) > $(eval $(call _import_lib,$(CONFIG_UK_BASE)/lib/ukallocbbuddy)) > +$(eval $(call _import_lib,$(CONFIG_UK_BASE)/lib/ukallocregion)) > $(eval $(call _import_lib,$(CONFIG_UK_BASE)/lib/uksched)) > $(eval $(call _import_lib,$(CONFIG_UK_BASE)/lib/ukschedcoop)) > $(eval $(call _import_lib,$(CONFIG_UK_BASE)/lib/fdt)) > diff --git a/lib/ukallocregion/Config.uk > b/lib/ukallocregion/Config.uk > new file mode 100644 > index 0000000..0bbc69f > --- /dev/null > +++ b/lib/ukallocregion/Config.uk > @@ -0,0 +1,13 @@ > +config LIBUKALLOCREGION > + bool "ukallocregion - Region-based allocator" > + default n > + select LIBNOLIBC if !HAVE_LIBC > + select LIBUKDEBUG > + select LIBUKALLOC > + help > + Satisfy allocations as fast as possible, without > bookkeeping. No > + support for free(): when the end of the allocation pool is > reached, > + the allocator runs out-of-memory. This allocator is useful > for > + experimentation, as baseline, or as first-level allocator > in a nested > + context. Note that this allocator does not provide optimal > locality of > + reference. > diff --git a/lib/ukallocregion/Makefile.uk > b/lib/ukallocregion/Makefile.uk > new file mode 100644 > index 0000000..05a3d67 > --- /dev/null > +++ b/lib/ukallocregion/Makefile.uk > @@ -0,0 +1,6 @@ > +$(eval $(call addlib_s,libukallocregion,$(CONFIG_LIBUKALLOCREGION))) > + > +CINCLUDES-$(CONFIG_LIBUKALLOCREGION) += > -I$(LIBUKALLOCREGION_BASE)/include > +CXXINCLUDES-$(CONFIG_LIBUKALLOCREGION) += > -I$(LIBUKALLOCREGION_BASE)/include > + > +LIBUKALLOCREGION_SRCS-y += $(LIBUKALLOCREGION_BASE)/region.c > diff --git a/lib/ukallocregion/exportsyms.uk > b/lib/ukallocregion/exportsyms.uk > new file mode 100644 > index 0000000..481bc10 > --- /dev/null > +++ b/lib/ukallocregion/exportsyms.uk > @@ -0,0 +1 @@ > +uk_allocregion_init > diff --git a/lib/ukallocregion/include/uk/allocregion.h > b/lib/ukallocregion/include/uk/allocregion.h > new file mode 100644 > index 0000000..1fc12db > --- /dev/null > +++ b/lib/ukallocregion/include/uk/allocregion.h > @@ -0,0 +1,49 @@ > +/* SPDX-License-Identifier: BSD-3-Clause */ > +/* > + * Authors: Hugo Lefeuvre <hugo.lefeuvre@xxxxxxxxx> > + * > + * Copyright (c) 2020, NEC Europe Ltd., NEC Corporation. All rights > reserved. > + * > + * Redistribution and use in source and binary forms, with or > without > + * modification, are permitted provided that the following > conditions > + * are met: > + * > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above > copyright > + * notice, this list of conditions and the following disclaimer > in the > + * documentation and/or other materials provided with the > distribution. > + * 3. Neither the name of the copyright holder nor the names of its > + * contributors may be used to endorse or promote products > derived from > + * this software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND > CONTRIBUTORS "AS IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED > TO, THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A > PARTICULAR PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR > CONTRIBUTORS BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, > OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT > OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR > BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, > WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR > OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF > ADVISED OF THE > + * POSSIBILITY OF SUCH DAMAGE. > + */ > + > +#ifndef __LIBUKALLOCREGION_H__ > +#define __LIBUKALLOCREGION_H__ > + > +#include <uk/alloc.h> > + > +#ifdef __cplusplus > +extern "C" { > +#endif > + > +/* allocator initialization */ > +struct uk_alloc *uk_allocregion_init(void *base, size_t len); > + > +#ifdef __cplusplus > +} > +#endif > + > +#endif /* __LIBUKALLOCREGION_H__ */ > diff --git a/lib/ukallocregion/region.c b/lib/ukallocregion/region.c > new file mode 100644 > index 0000000..6760b4c > --- /dev/null > +++ b/lib/ukallocregion/region.c > @@ -0,0 +1,169 @@ > +/* SPDX-License-Identifier: BSD-3-Clause */ > +/* > + * Authors: Hugo Lefeuvre <hugo.lefeuvre@xxxxxxxxx> > + * > + * Copyright (c) 2020, NEC Europe Ltd., NEC Corporation. All rights > reserved. > + * > + * Redistribution and use in source and binary forms, with or > without > + * modification, are permitted provided that the following > conditions > + * are met: > + * > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above > copyright > + * notice, this list of conditions and the following disclaimer > in the > + * documentation and/or other materials provided with the > distribution. > + * 3. Neither the name of the copyright holder nor the names of its > + * contributors may be used to endorse or promote products > derived from > + * this software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND > CONTRIBUTORS "AS IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED > TO, THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A > PARTICULAR PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR > CONTRIBUTORS BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, > OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT > OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR > BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, > WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR > OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF > ADVISED OF THE > + * POSSIBILITY OF SUCH DAMAGE. > + */ > + > +/* ukallocregion is a minimalist region implementation. > + * > + * Note that deallocation is not supported. This makes sense because > regions > + * only allow for deallocation at region-granularity. In our case, > this would > + * imply the freeing of the entire heap, which is generally not > possible. > + * > + * Obviously, the lack of deallocation support makes ukallocregion a > fairly bad > + * general-purpose allocator. This allocator is interesting in that > it offers > + * maximum speed allocation and deallocation (no bookkeeping). It > can be used as > + * a baseline for measurements (e.g., boot time) or as a first-level > allocator > + * in a nested context. > + * > + * Refer to Gay & Aiken, `Memory management with explicit regions' > (PLDI'98) for > + * an introduction to region-based memory management. > + */ > + > +#include <uk/allocregion.h> > +#include <uk/alloc_impl.h> > +#include <uk/page.h> // round_pgup() #include <limits.h> is needed for __PAGE_SIZE. > + > +struct uk_allocregion { > + void *heap_top; > + void *heap_base; > +}; > + > +void *uk_allocregion_malloc(struct uk_alloc *a, size_t size) > +{ > + struct uk_allocregion *b; > + void *newbase, *prevbase; > + > + UK_ASSERT(a != NULL); > + > + b = (struct uk_allocregion *)&a->priv; > + > + /* return aligned pointers: this is a requirement for some > + * embedded systems archs, and more generally good for > performance > + */ > + newbase = (void *) ALIGN_UP(((uintptr_t) b->heap_base + > size), > + (uintptr_t) sizeof(void *)); > + prevbase = b->heap_base; > + > + UK_ASSERT(newbase >= b->heap_base); > + UK_ASSERT(newbase <= b->heap_top); > + > + b->heap_base = newbase; > + > + return prevbase; > +} > + > +int uk_allocregion_posix_memalign(struct uk_alloc *a, void **memptr, > + size_t align, size_t size) > +{ > + struct uk_allocregion *b; > + uintptr_t intptr; > + > + UK_ASSERT(a != NULL); > + > + b = (struct uk_allocregion *)&a->priv; > + > + /* align must be a power of two */ > + UK_ASSERT(((align - 1) & align) == 0); > + > + /* align must be larger than pointer size */ > + UK_ASSERT((align % sizeof(void *)) == 0); > + > + if (!size) { > + *memptr = NULL; > + return EINVAL; > + } > + > + intptr = ALIGN_UP((uintptr_t) b->heap_base, (uintptr_t) > align); > + > + if (intptr > (uintptr_t) b->heap_top) > + return ENOMEM; /* out-of-memory */ > + > + *memptr = (void *)intptr; > + b->heap_base = (void *)(intptr + size); > + > + return 0; > +} > + > +void uk_allocregion_free(struct uk_alloc *a __unused, void *ptr > __unused) > +{ > + uk_pr_debug("%p: Releasing of memory is not supported by " > + "ukallocregion\n", a); > +} > + > +int uk_allocregion_addmem(struct uk_alloc *a __unused, void *base > __unused, > + size_t size __unused) > +{ > + /* TODO: support multiple regions */ > + uk_pr_debug("%p: ukallocregion does not support multiple > memory " > + "regions\n", a); > + return 0; > +} > + > +struct uk_alloc *uk_allocregion_init(void *base, size_t len) > +{ > + struct uk_alloc *a; > + struct uk_allocregion *b; > + size_t metalen = sizeof(*a) + sizeof(*b); > + > + /* TODO: ukallocregion does not support multiple memory > regions yet. > + * Because of the multiboot layout, the first region might > be a single > + * page, so we simply ignore it. > + */ > + if (len <= __PAGE_SIZE) > + return NULL; > + > + /* enough space for allocator available? */ > + if (metalen > len) { > + uk_pr_err("Not enough space for allocator: %"__PRIsz > + " B required but only %"__PRIuptr" B > usable\n", > + metalen, len); > + return NULL; > + } > + > + /* store allocator metadata on the heap, just before the > memory pool */ > + a = (struct uk_alloc *)base; > + b = (struct uk_allocregion *)&a->priv; > + > + uk_pr_info("Initialize allocregion allocator @ 0x%" > + __PRIuptr ", len %"__PRIsz"\n", (uintptr_t)a, > len); > + > + b->heap_top = (void *)((uintptr_t) base + len); > + b->heap_base = (void *)((uintptr_t) base + metalen); > + > + /* use exclusively "compat" wrappers for calloc, realloc, > memalign, > + * palloc and pfree as those do not add additional metadata. > + */ > + uk_alloc_init_malloc(a, uk_allocregion_malloc, > uk_calloc_compat, > + uk_realloc_compat, > uk_allocregion_free, > + uk_allocregion_posix_memalign, > + uk_memalign_compat, NULL); > + > + return a; > +}
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |