[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [UNIKRAFT/LIBTINYALLOC PATCH] Initial port of tinyalloc to Unikraft



Hi Razvan,

Agree, also tinyalloc should not be autoselected. I will provide a v2.

Thanks for the review!

Hugo

On Fri, Sep 18, 2020 at 11:51:07AM +0300, Razvan Deaconescu wrote:
> Hi, Hugo.
> 
> I tested tinyalloc on linuxu and KVM, it works.
> 
> Why did you name the structure "struct tinyalloc", without the uk_
> prefix as is the case with the other allocators (i.e. "struct
> uk_bbpalloc" and "struct uk_allocregion").
> 
> When selecting tinyalloc in the configuration screen, the malloc
> compatibility interface should also be automatically selected. It's not
> obvious it has to be selected and one may miss it.
> 
> There's another comment inline.
> 
> Razvan
> 
> Hugo Lefeuvre <hugo.lefeuvre@xxxxxxxxx> writes:
> > Signed-off-by: Hugo Lefeuvre <hugo.lefeuvre@xxxxxxxxx>
> > ---
> >  Config.uk                                          |  32 +++
> >  Makefile.uk                                        |  73 +++++
> >  glue.c                                             | 101 +++++++
> >  include/uk/tinyalloc.h                             |  48 ++++
> >  main-tree.patch                                    |  45 +++
> >  .../0001-do-not-store-heap-info-statically.patch   | 312 
> > +++++++++++++++++++++
> >  6 files changed, 611 insertions(+)
> >  create mode 100644 Config.uk
> >  create mode 100644 Makefile.uk
> >  create mode 100644 glue.c
> >  create mode 100644 include/uk/tinyalloc.h
> >  create mode 100644 main-tree.patch
> >  create mode 100644 patches/0001-do-not-store-heap-info-statically.patch
> >
> > diff --git a/Config.uk b/Config.uk
> > new file mode 100644
> > index 0000000..4b9d127
> > --- /dev/null
> > +++ b/Config.uk
> > @@ -0,0 +1,32 @@
> > +menuconfig LIBTINYALLOC
> > +      bool "tinyalloc - sequential fit, linked list based tiny allocator"
> > +      default y
> > +
> > +if LIBTINYALLOC
> > +   config LIBTINYALLOC_DISABLE_SPLIT
> > +           bool "Disable block splitting"
> > +           default n
> > +           help
> > +                   If splitting is enabled, split blocks according to split
> > +                   threshold.
> > +
> > +   config LIBTINYALLOC_DISABLE_COMPACT
> > +           bool "Disable block compaction"
> > +           default n
> > +           help
> > +                   If compaction is enabled, sort blocks into the free
> > +                   list, merge if appropriate. Otherwise blocks are just
> > +                   added as new head of the free list.
> > +
> > +   config LIBTINYALLOC_HEAP_BLOCKS
> > +           int "Number of available heap blocks"
> > +           default 2048
> > +
> > +   config LIBTINYALLOC_SPLIT_THRESH
> > +           int "Split threshold, in bytes"
> > +           default 16
> > +
> > +   config LIBTINYALLOC_ALIGNMENT
> > +           int "Standard allocation alignment, in bytes"
> > +           default 8
> > +endif
> > diff --git a/Makefile.uk b/Makefile.uk
> > new file mode 100644
> > index 0000000..21aa8fe
> > --- /dev/null
> > +++ b/Makefile.uk
> > @@ -0,0 +1,73 @@
> > +#  libtinyalloc Makefile.uc
> > +#
> > +#  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.
> > +
> > +################################################################################
> > +# Library registration
> > +################################################################################
> > +$(eval $(call addlib_s,libtinyalloc,$(CONFIG_LIBTINYALLOC)))
> > +
> > +################################################################################
> > +# Sources
> > +################################################################################
> > +LIBTINYALLOC_VERSION=96450f32d80fe7d23f6aa5426046143e57801bc4
> > +LIBTINYALLOC_URL=https://github.com/thi-ng/tinyalloc/archive/$(LIBTINYALLOC_VERSION).zip
> > +LIBTINYALLOC_DIR=tinyalloc-$(LIBTINYALLOC_VERSION)
> > +
> > +LIBTINYALLOC_PATCHDIR=$(LIBTINYALLOC_BASE)/patches
> > +$(eval $(call 
> > fetch,libtinyalloc,$(LIBTINYALLOC_URL),$(LIBTINYALLOC_VERSION).zip))
> > +$(eval $(call 
> > patch,libtinyalloc,$(LIBTINYALLOC_PATCHDIR),$(LIBTINYALLOC_DIR)))
> > +
> > +################################################################################
> > +# Helpers
> > +################################################################################
> > +LIBTINYALLOC=$(LIBTINYALLOC_ORIGIN)/$(LIBTINYALLOC_DIR)
> > +
> > +################################################################################
> > +# Library includes
> > +################################################################################
> > +CINCLUDES-$(CONFIG_LIBTINYALLOC) += -I$(LIBTINYALLOC_BASE)     \
> > +                                    -I$(LIBTINYALLOC_BASE)/include \
> > +                               -I$(LIBTINYALLOC)
> > +
> > +################################################################################
> > +# Global flags
> > +################################################################################
> > +#LIBTINYALLOC_CFLAGS-y += -D_POSIX_SOURCE -D_GNU_SOURCE -D__GNU__
> > +
> > +################################################################################
> > +# Glue code
> > +################################################################################
> > +LIBTINYALLOC_SRCS-y += $(LIBTINYALLOC_BASE)/glue.c
> > +
> > +################################################################################
> > +# Sources
> > +################################################################################
> > +LIBTINYALLOC_SRCS-y += $(LIBTINYALLOC)/tinyalloc.c
> > diff --git a/glue.c b/glue.c
> > new file mode 100644
> > index 0000000..9266e92
> > --- /dev/null
> > +++ b/glue.c
> > @@ -0,0 +1,101 @@
> > +/* 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.
> > + */
> > +
> > +#include <uk/tinyalloc.h>
> > +#include <uk/alloc_impl.h>
> > +#include <string.h> /* for memset */
> > +#include <tinyalloc.h>
> > +
> > +static void *uk_tinyalloc_malloc(struct uk_alloc *a, size_t size)
> > +{
> > +   struct tinyalloc *b;
> > +
> > +   b = (struct tinyalloc *)&a->priv;
> > +   return ta_alloc(b, size);
> > +}
> > +
> > +static void uk_tinyalloc_free(struct uk_alloc *a, void *ptr)
> > +{
> > +   struct tinyalloc *b;
> > +
> > +   b = (struct tinyalloc *)&a->priv;
> > +   ta_free(b, ptr);
> > +}
> > +
> > +/* initialization */
> > +
> > +struct uk_alloc *uk_tinyalloc_init(void *base, size_t len)
> > +{
> > +   struct uk_alloc *a;
> > +   struct tinyalloc *b;
> > +   size_t metalen;
> > +
> > +   /* TODO: This port 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;
> > +
> > +   /* Allocate space for allocator descriptor */
> > +   metalen = sizeof(*a) + sizeof(*b);
> > +
> > +   /* 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 tinyalloc *)&a->priv;
> > +   memset(a, 0, metalen);
> > +
> > +   uk_pr_info("Initialize tinyalloc allocator @ 0x%" __PRIuptr ", len %"
> > +                   __PRIsz"\n", (uintptr_t)a, len);
> > +
> > +   ta_init(b, base + metalen, base + len, CONFIG_LIBTINYALLOC_HEAP_BLOCKS,
> > +           CONFIG_LIBTINYALLOC_SPLIT_THRESH,
> > +           CONFIG_LIBTINYALLOC_ALIGNMENT);
> > +
> > +   if (!a) {
> > +           uk_pr_err("Failed to allocate memory for uk_alloc 
> > structure!\n");
> > +           return NULL;
> > +   }
> 
> Shouldn't this be if (!b)?
> 
> > +   uk_alloc_init_malloc_ifmalloc(a, uk_tinyalloc_malloc,
> > +                                    uk_tinyalloc_free, NULL);
> > +
> > +   return a;
> > +}
> > diff --git a/include/uk/tinyalloc.h b/include/uk/tinyalloc.h
> > new file mode 100644
> > index 0000000..87290ed
> > --- /dev/null
> > +++ b/include/uk/tinyalloc.h
> > @@ -0,0 +1,48 @@
> > +/* 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 __LIBTINYALLOC_H__
> > +#define __LIBTINYALLOC_H__
> > +
> > +#include <uk/alloc.h>
> > +
> > +#ifdef __cplusplus
> > +extern "C" {
> > +#endif
> > +
> > +struct uk_alloc *uk_tinyalloc_init(void *base, size_t len);
> > +
> > +#ifdef __cplusplus
> > +}
> > +#endif
> > +
> > +#endif /* __LIBTINYALLOC_H__ */
> > diff --git a/main-tree.patch b/main-tree.patch
> > new file mode 100644
> > index 0000000..40bb096
> > --- /dev/null
> > +++ b/main-tree.patch
> > @@ -0,0 +1,45 @@
> > +From: Hugo Lefeuvre <hugo.lefeuvre@xxxxxxxxx>
> > +Subject: Add tinyalloc entry to the menuconfig and initialize it
> > +diff --git a/lib/ukboot/Config.uk b/lib/ukboot/Config.uk
> > +index a888bc1c..694762fa 100644
> > +--- a/lib/ukboot/Config.uk
> > ++++ b/lib/ukboot/Config.uk
> > +@@ -32,6 +32,16 @@ if LIBUKBOOT
> > +             Satisfy allocation as fast as possible. No support for free().
> > +             Refer to help in ukallocregion for more information.
> > + 
> > ++          config LIBUKBOOT_INITTINYALLOC
> > ++          bool "tinyalloc"
> > ++          select LIBTINYALLOC
> > ++          help
> > ++            Minimalist allocator implementation, meant for use in systems
> > ++            with unmanaged linear memory such as WebAssembly or embedded
> > ++            systems. tinyalloc is highly configurable and offers high
> > ++            performance and reasonable memory usage when used and
> > ++            configured appropriately.
> > ++
> > +           config LIBUKBOOT_NOALLOC
> > +           bool "No memory allocator"
> > + 
> > +diff --git a/lib/ukboot/boot.c b/lib/ukboot/boot.c
> > +index 4e749aa5..b8bf0a20 100644
> > +--- a/lib/ukboot/boot.c
> > ++++ b/lib/ukboot/boot.c
> > +@@ -45,6 +45,8 @@
> > + #include <uk/allocbbuddy.h>
> > + #elif CONFIG_LIBUKBOOT_INITREGION
> > + #include <uk/allocregion.h>
> > ++#elif CONFIG_LIBUKBOOT_INITTINYALLOC
> > ++#include <uk/tinyalloc.h>
> > + #endif
> > + #if CONFIG_LIBUKSCHED
> > + #include <uk/sched.h>
> > +@@ -233,6 +235,8 @@ void ukplat_entry(int argc, char *argv[])
> > +                   a = uk_allocbbuddy_init(md.base, md.len);
> > + #elif CONFIG_LIBUKBOOT_INITREGION
> > +                   a = uk_allocregion_init(md.base, md.len);
> > ++#elif CONFIG_LIBUKBOOT_INITTINYALLOC
> > ++                  a = uk_tinyalloc_init(md.base, md.len);
> > + #endif
> > +           } else {
> > +                   uk_alloc_addmem(a, md.base, md.len);
> > diff --git a/patches/0001-do-not-store-heap-info-statically.patch 
> > b/patches/0001-do-not-store-heap-info-statically.patch
> > new file mode 100644
> > index 0000000..fd7b953
> > --- /dev/null
> > +++ b/patches/0001-do-not-store-heap-info-statically.patch
> > @@ -0,0 +1,312 @@
> > +From: Hugo Lefeuvre <hugo.lefeuvre@xxxxxxxxx>
> > +Subject: Adapt tinyalloc interface to Unikraft
> > + - avoid statics: create a struct tinyalloc to store allocator metadata
> > + - pass struct metadata as argument to allocation functions
> > +diff -urNp tinyalloc-orig/tinyalloc.c tinyalloc-patched/tinyalloc.c
> > +--- tinyalloc-orig/tinyalloc.c     2019-08-17 23:56:45.000000000 +0200
> > ++++ tinyalloc-patched/tinyalloc.c  2020-06-30 10:34:24.945558078 +0200
> > +@@ -9,36 +9,16 @@ extern void print_i(size_t);
> > + #define print_i(X)
> > + #endif
> > + 
> > +-typedef struct Block Block;
> > +-
> > +-struct Block {
> > +-    void *addr;
> > +-    Block *next;
> > +-    size_t size;
> > +-};
> > +-
> > +-typedef struct {
> > +-    Block *free;   // first free block
> > +-    Block *used;   // first used block
> > +-    Block *fresh;  // first available blank block
> > +-    size_t top;    // top free addr
> > +-    Block *blocks;
> > +-} Heap;
> > +-
> > +-static Heap *heap = NULL;
> > +-static void *heap_limit = NULL;
> > +-static size_t heap_split_thresh;
> > +-static size_t heap_alignment;
> > +-static size_t heap_max_blocks;
> > +-
> > + /**
> > +  * If compaction is enabled, inserts block
> > +  * into free list, sorted by addr.
> > +  * If disabled, add block has new head of
> > +  * the free list.
> > +  */
> > +-static void insert_block(Block *block) {
> > +-#ifndef TA_DISABLE_COMPACT
> > ++static void insert_block(struct tinyalloc *a, Block *block) {
> > ++    Heap *heap = a->heap;
> > ++
> > ++#ifndef CONFIG_LIBTINYALLOC_DISABLE_COMPACT
> > +     Block *ptr  = heap->free;
> > +     Block *prev = NULL;
> > +     while (ptr != NULL) {
> > +@@ -66,8 +46,10 @@ static void insert_block(Block *block) {
> > + #endif
> > + }
> > + 
> > +-#ifndef TA_DISABLE_COMPACT
> > +-static void release_blocks(Block *scan, Block *to) {
> > ++#ifndef CONFIG_LIBTINYALLOC_DISABLE_COMPACT
> > ++static void release_blocks(struct tinyalloc *a, Block *scan, Block *to) {
> > ++    Heap *heap = a->heap;
> > ++
> > +     Block *scan_next;
> > +     while (scan != to) {
> > +         print_s("release");
> > +@@ -81,7 +63,9 @@ static void release_blocks(Block *scan,
> > +     }
> > + }
> > + 
> > +-static void compact() {
> > ++static void compact(struct tinyalloc *a) {
> > ++    Heap *heap = a->heap;
> > ++
> > +     Block *ptr = heap->free;
> > +     Block *prev;
> > +     Block *scan;
> > +@@ -103,7 +87,7 @@ static void compact() {
> > +             ptr->size   = new_size;
> > +             Block *next = prev->next;
> > +             // make merged blocks available
> > +-            release_blocks(ptr->next, prev->next);
> > ++            release_blocks(a, ptr->next, prev->next);
> > +             // relink
> > +             ptr->next = next;
> > +         }
> > +@@ -112,30 +96,36 @@ static void compact() {
> > + }
> > + #endif
> > + 
> > +-bool ta_init(const void *base, const void *limit, const size_t 
> > heap_blocks, const size_t split_thresh, const size_t alignment) {
> > +-    heap = (Heap *)base;
> > +-    heap_limit = limit;
> > +-    heap_split_thresh = split_thresh;
> > +-    heap_alignment = alignment;
> > +-    heap_max_blocks = heap_blocks;
> > ++void ta_init(struct tinyalloc *a, const void *base, const void *limit,
> > ++             const size_t heap_blocks, const size_t split_thresh,
> > ++             const size_t alignment) {
> > ++    Heap *heap;
> > ++
> > ++    a->heap = (Heap *)base;
> > ++    a->heap_limit = limit;
> > ++    a->heap_split_thresh = split_thresh;
> > ++    a->heap_alignment = alignment;
> > ++    a->heap_max_blocks = heap_blocks;
> > + 
> > ++    heap = a->heap;
> > +     heap->free   = NULL;
> > +     heap->used   = NULL;
> > ++    heap->blocks = (Block*) ((size_t)base + sizeof(Heap));
> > +     heap->fresh  = heap->blocks;
> > +     heap->top    = (size_t)base + sizeof(Heap) + heap_blocks * 
> > sizeof(Block);
> > +-    heap->blocks = base + sizeof(Heap);
> > + 
> > +     Block *block = heap->blocks;
> > +-    size_t i     = heap_max_blocks - 1;
> > ++    size_t i     = a->heap_max_blocks - 1;
> > +     while (i--) {
> > +         block->next = block + 1;
> > +         block++;
> > +     }
> > +     block->next = NULL;
> > +-    return true;
> > + }
> > + 
> > +-bool ta_free(void *free) {
> > ++void ta_free(struct tinyalloc *a, void *free) {
> > ++    Heap *heap = a->heap;
> > ++
> > +     Block *block = heap->used;
> > +     Block *prev  = NULL;
> > +     while (block != NULL) {
> > +@@ -145,25 +135,28 @@ bool ta_free(void *free) {
> > +             } else {
> > +                 heap->used = block->next;
> > +             }
> > +-            insert_block(block);
> > +-#ifndef TA_DISABLE_COMPACT
> > +-            compact();
> > ++            insert_block(a, block);
> > ++#ifndef CONFIG_LIBTINYALLOC_DISABLE_COMPACT
> > ++            compact(a);
> > + #endif
> > +-            return true;
> > ++            return;
> > +         }
> > +         prev  = block;
> > +         block = block->next;
> > +     }
> > +-    return false;
> > ++    return;
> > + }
> > + 
> > +-static Block *alloc_block(size_t num) {
> > ++static Block *alloc_block(struct tinyalloc *a, size_t num) {
> > ++    Heap *heap = a->heap;
> > ++
> > +     Block *ptr  = heap->free;
> > +     Block *prev = NULL;
> > +     size_t top  = heap->top;
> > +-    num         = (num + heap_alignment - 1) & -heap_alignment;
> > ++    num         = (num + a->heap_alignment - 1) & - a->heap_alignment;
> > +     while (ptr != NULL) {
> > +-        const int is_top = ((size_t)ptr->addr + ptr->size >= top) && 
> > ((size_t)ptr->addr + num <= heap_limit);
> > ++        const int is_top = ((size_t)ptr->addr + ptr->size >= top)
> > ++                  && ((size_t)ptr->addr + num <= a->heap_limit);
> > +         if (is_top || ptr->size >= num) {
> > +             if (prev != NULL) {
> > +                 prev->next = ptr->next;
> > +@@ -176,10 +169,10 @@ static Block *alloc_block(size_t num) {
> > +                 print_s("resize top block");
> > +                 ptr->size = num;
> > +                 heap->top = (size_t)ptr->addr + num;
> > +-#ifndef TA_DISABLE_SPLIT
> > ++#ifndef CONFIG_LIBTINYALLOC_DISABLE_SPLIT
> > +             } else if (heap->fresh != NULL) {
> > +                 size_t excess = ptr->size - num;
> > +-                if (excess >= heap_split_thresh) {
> > ++                if (excess >= a->heap_split_thresh) {
> > +                     ptr->size    = num;
> > +                     Block *split = heap->fresh;
> > +                     heap->fresh  = split->next;
> > +@@ -187,9 +180,9 @@ static Block *alloc_block(size_t num) {
> > +                     print_s("split");
> > +                     print_i((size_t)split->addr);
> > +                     split->size = excess;
> > +-                    insert_block(split);
> > +-#ifndef TA_DISABLE_COMPACT
> > +-                    compact();
> > ++                    insert_block(a, split);
> > ++#ifndef CONFIG_LIBTINYALLOC_DISABLE_COMPACT
> > ++                    compact(a);
> > + #endif
> > +                 }
> > + #endif
> > +@@ -199,10 +192,11 @@ static Block *alloc_block(size_t num) {
> > +         prev = ptr;
> > +         ptr  = ptr->next;
> > +     }
> > ++
> > +     // no matching free blocks
> > +     // see if any other blocks available
> > +     size_t new_top = top + num;
> > +-    if (heap->fresh != NULL && new_top <= heap_limit) {
> > ++    if (heap->fresh != NULL && new_top <= (size_t)a->heap_limit) {
> > +         ptr         = heap->fresh;
> > +         heap->fresh = ptr->next;
> > +         ptr->addr   = (void *)top;
> > +@@ -212,11 +206,12 @@ static Block *alloc_block(size_t num) {
> > +         heap->top   = new_top;
> > +         return ptr;
> > +     }
> > ++
> > +     return NULL;
> > + }
> > + 
> > +-void *ta_alloc(size_t num) {
> > +-    Block *block = alloc_block(num);
> > ++void *ta_alloc(struct tinyalloc *a, size_t num) {
> > ++    Block *block = alloc_block(a, num);
> > +     if (block != NULL) {
> > +         return block->addr;
> > +     }
> > +@@ -236,9 +231,9 @@ static void memclear(void *ptr, size_t n
> > +     }
> > + }
> > + 
> > +-void *ta_calloc(size_t num, size_t size) {
> > ++void *ta_calloc(struct tinyalloc *a, size_t num, size_t size) {
> > +     num *= size;
> > +-    Block *block = alloc_block(num);
> > ++    Block *block = alloc_block(a, num);
> > +     if (block != NULL) {
> > +         memclear(block->addr, num);
> > +         return block->addr;
> > +@@ -255,18 +250,21 @@ static size_t count_blocks(Block *ptr) {
> > +     return num;
> > + }
> > + 
> > +-size_t ta_num_free() {
> > ++size_t ta_num_free(struct tinyalloc *a) {
> > ++    Heap *heap = a->heap;
> > +     return count_blocks(heap->free);
> > + }
> > + 
> > +-size_t ta_num_used() {
> > ++size_t ta_num_used(struct tinyalloc *a) {
> > ++    Heap *heap = a->heap;
> > +     return count_blocks(heap->used);
> > + }
> > + 
> > +-size_t ta_num_fresh() {
> > ++size_t ta_num_fresh(struct tinyalloc *a) {
> > ++    Heap *heap = a->heap;
> > +     return count_blocks(heap->fresh);
> > + }
> > + 
> > +-bool ta_check() {
> > +-    return heap_max_blocks == ta_num_free() + ta_num_used() + 
> > ta_num_fresh();
> > ++bool ta_check(struct tinyalloc *a) {
> > ++    return a->heap_max_blocks == ta_num_free(a) + ta_num_used(a) + 
> > ta_num_fresh(a);
> > + }
> > +diff -urNp tinyalloc-orig/tinyalloc.h tinyalloc-patched/tinyalloc.h
> > +--- tinyalloc-orig/tinyalloc.h     2019-08-17 23:56:45.000000000 +0200
> > ++++ tinyalloc-patched/tinyalloc.h  2020-06-30 10:38:59.734724059 +0200
> > +@@ -1,12 +1,41 @@
> > + #include <stdbool.h>
> > + #include <stddef.h>
> > + 
> > +-bool ta_init(const void *base, const void *limit, const size_t 
> > heap_blocks, const size_t split_thresh, const size_t alignment);
> > +-void *ta_alloc(size_t num);
> > +-void *ta_calloc(size_t num, size_t size);
> > +-bool ta_free(void *ptr);
> > +-
> > +-size_t ta_num_free();
> > +-size_t ta_num_used();
> > +-size_t ta_num_fresh();
> > +-bool ta_check();
> > ++typedef struct Block Block;
> > ++
> > ++struct Block {
> > ++    void *addr;
> > ++    Block *next;
> > ++    size_t size;
> > ++};
> > ++
> > ++typedef struct {
> > ++    Block *free;   // first free block
> > ++    Block *used;   // first used block
> > ++    Block *fresh;  // first available blank block
> > ++    size_t top;    // top free addr
> > ++    Block *blocks;
> > ++} Heap;
> > ++
> > ++struct tinyalloc {
> > ++    Heap *heap;
> > ++    void *heap_limit;
> > ++    size_t heap_split_thresh;
> > ++    size_t heap_alignment;
> > ++    size_t heap_max_blocks;
> > ++};
> > ++
> > ++void ta_init(struct tinyalloc *a, const void *base, const void *limit,
> > ++             const size_t heap_blocks, const size_t split_thresh,
> > ++             const size_t alignment);
> > ++
> > ++void *ta_alloc(struct tinyalloc *a, size_t num);
> > ++void *ta_calloc(struct tinyalloc *a, size_t num, size_t size);
> > ++void  ta_free(struct tinyalloc *a, void *ptr);
> > ++int   ta_posix_memalign(struct tinyalloc *a, void **memptr, size_t align,
> > ++                  size_t size);
> > ++
> > ++size_t ta_num_free(struct tinyalloc *a);
> > ++size_t ta_num_used(struct tinyalloc *a);
> > ++size_t ta_num_fresh(struct tinyalloc *a);
> > ++bool   ta_check(struct tinyalloc *a);
> 

-- 
                Hugo Lefeuvre (hle)    |    www.owl.eu.com
RSA4096_ 360B 03B3 BF27 4F4D 7A3F D5E8 14AA 1EB8 A247 3DFD
ed25519_ 37B2 6D38 0B25 B8A2 6B9F 3A65 A36F 5357 5F2D DC4C

Attachment: signature.asc
Description: PGP signature


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.