Changeset b60615b in mainline


Ignore:
Timestamp:
2018-11-13T16:48:08Z (5 years ago)
Author:
Jiří Zárevúcky <zarevucky.jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
71fb5ac
Parents:
159c1525
git-author:
Jiří Zárevúcky <zarevucky.jiri@…> (2018-11-11 17:03:50)
git-committer:
Jiří Zárevúcky <zarevucky.jiri@…> (2018-11-13 16:48:08)
Message:

Modify kernel malloc()

This new implementation places the allocation size in front of the allocated
object, instead of relying on the slab allocator being able to determine source
slab cache for an object. This should improve scalability and help reduce
complexity of the memory management subsystem (further changes coming).

The drawback is more memory consumed by small malloc() allocations, however that
can be mitigated by switching to an API where the user provides known object
size to deallocation (most users know it either statically or from length they
necessarily remember).

Location:
kernel
Files:
1 added
6 edited

Legend:

Unmodified
Added
Removed
  • kernel/Makefile

    r159c1525 rb60615b  
    9494        -fdebug-prefix-map=$(realpath $(ROOT_PATH))=.
    9595
    96 GCC_CFLAGS = -std=gnu99 -Wall -Wextra -Wno-unused-parameter \
     96GCC_CFLAGS = -std=gnu11 -Wall -Wextra -Wno-unused-parameter \
    9797        -Wmissing-prototypes -Werror-implicit-function-declaration \
    9898        -Wwrite-strings -pipe -Wno-cast-function-type
    9999
    100 CLANG_CFLAGS = -std=gnu99 -Wall -Wextra -Wno-unused-parameter \
     100CLANG_CFLAGS = -std=gnu11 -Wall -Wextra -Wno-unused-parameter \
    101101        -Wno-missing-field-initializers -Wno-unused-command-line-argument \
    102102        -Wmissing-prototypes -Werror-implicit-function-declaration \
     
    197197        generic/src/mm/tlb.c \
    198198        generic/src/mm/as.c \
     199        generic/src/mm/malloc.c \
    199200        generic/src/mm/backend_anon.c \
    200201        generic/src/mm/backend_elf.c \
  • kernel/generic/include/bitops.h

    r159c1525 rb60615b  
    3636#define KERN_BITOPS_H_
    3737
     38#include <stdint.h>
    3839#include <trace.h>
    3940
  • kernel/generic/include/main/main.h

    r159c1525 rb60615b  
    4848extern void main_ap(void);
    4949
     50extern void malloc_init(void);
     51
    5052#endif
    5153
  • kernel/generic/include/mm/slab.h

    r159c1525 rb60615b  
    4040#include <atomic.h>
    4141#include <mm/frame.h>
    42 
    43 /** Minimum size to be allocated by malloc */
    44 #define SLAB_MIN_MALLOC_W  4
    45 
    46 /** Maximum size to be allocated by malloc */
    47 #define SLAB_MAX_MALLOC_W  22
    4842
    4943/** Initial Magazine size (TODO: dynamically growing magazines) */
  • kernel/generic/src/main/main.c

    r159c1525 rb60615b  
    246246        frame_init();
    247247        slab_cache_init();
     248        malloc_init();
    248249        ra_init();
    249250        sysinfo_init();
  • kernel/generic/src/mm/slab.c

    r159c1525 rb60615b  
    138138static slab_cache_t *slab_extern_cache;
    139139
    140 /** Caches for malloc */
    141 static slab_cache_t *malloc_caches[SLAB_MAX_MALLOC_W - SLAB_MIN_MALLOC_W + 1];
    142 
    143 static const char *malloc_names[] =  {
    144         "malloc-16",
    145         "malloc-32",
    146         "malloc-64",
    147         "malloc-128",
    148         "malloc-256",
    149         "malloc-512",
    150         "malloc-1K",
    151         "malloc-2K",
    152         "malloc-4K",
    153         "malloc-8K",
    154         "malloc-16K",
    155         "malloc-32K",
    156         "malloc-64K",
    157         "malloc-128K",
    158         "malloc-256K",
    159         "malloc-512K",
    160         "malloc-1M",
    161         "malloc-2M",
    162         "malloc-4M"
    163 };
    164 
    165140/** Slab descriptor */
    166141typedef struct {
     
    775750                panic("Destroying cache that is not empty.");
    776751
    777         if (!(cache->flags & SLAB_CACHE_NOMAGAZINE)) {
    778                 slab_t *mag_slab = obj2slab(cache->mag_cache);
    779                 _slab_free(mag_slab->cache, cache->mag_cache, mag_slab);
     752        if (!(cache->flags & SLAB_CACHE_NOMAGAZINE) && cache->mag_cache) {
     753                slab_free(&slab_mag_cache, cache->mag_cache);
    780754        }
    781755
     
    914888            NULL, NULL, SLAB_CACHE_SLINSIDE | SLAB_CACHE_MAGDEFERRED);
    915889
    916         /* Initialize structures for malloc */
    917         size_t i;
    918         size_t size;
    919 
    920         for (i = 0, size = (1 << SLAB_MIN_MALLOC_W);
    921             i < (SLAB_MAX_MALLOC_W - SLAB_MIN_MALLOC_W + 1);
    922             i++, size <<= 1) {
    923                 malloc_caches[i] = slab_cache_create(malloc_names[i], size, 0,
    924                     NULL, NULL, SLAB_CACHE_MAGDEFERRED);
    925         }
    926 
    927890#ifdef CONFIG_DEBUG
    928891        _slab_initialized = 1;
     
    961924}
    962925
    963 void *malloc(size_t size)
    964 {
    965         assert(_slab_initialized);
    966         assert(size <= (1 << SLAB_MAX_MALLOC_W));
    967 
    968         if (size < (1 << SLAB_MIN_MALLOC_W))
    969                 size = (1 << SLAB_MIN_MALLOC_W);
    970 
    971         uint8_t idx = fnzb(size - 1) - SLAB_MIN_MALLOC_W + 1;
    972 
    973         return slab_alloc(malloc_caches[idx], FRAME_ATOMIC);
    974 }
    975 
    976 void *realloc(void *ptr, size_t size)
    977 {
    978         assert(_slab_initialized);
    979         assert(size <= (1 << SLAB_MAX_MALLOC_W));
    980 
    981         void *new_ptr;
    982 
    983         if (size > 0) {
    984                 if (size < (1 << SLAB_MIN_MALLOC_W))
    985                         size = (1 << SLAB_MIN_MALLOC_W);
    986                 uint8_t idx = fnzb(size - 1) - SLAB_MIN_MALLOC_W + 1;
    987 
    988                 new_ptr = slab_alloc(malloc_caches[idx], FRAME_ATOMIC);
    989         } else
    990                 new_ptr = NULL;
    991 
    992         if ((new_ptr != NULL) && (ptr != NULL)) {
    993                 slab_t *slab = obj2slab(ptr);
    994                 memcpy(new_ptr, ptr, min(size, slab->cache->size));
    995         }
    996 
    997         if (ptr != NULL)
    998                 free(ptr);
    999 
    1000         return new_ptr;
    1001 }
    1002 
    1003 void free(void *ptr)
    1004 {
    1005         if (!ptr)
    1006                 return;
    1007 
    1008         slab_t *slab = obj2slab(ptr);
    1009         _slab_free(slab->cache, ptr, slab);
    1010 }
    1011 
    1012926/** @}
    1013927 */
Note: See TracChangeset for help on using the changeset viewer.