From a8968330aff45e0b8cf278f49fa337d5fcb9bfd8 Mon Sep 17 00:00:00 2001 From: Alex AUVOLAT Date: Fri, 28 Mar 2014 17:09:15 +0100 Subject: Import and compile code for article 6.5 --- sos-code-article6.5/sos/kmalloc.c | 113 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 sos-code-article6.5/sos/kmalloc.c (limited to 'sos-code-article6.5/sos/kmalloc.c') diff --git a/sos-code-article6.5/sos/kmalloc.c b/sos-code-article6.5/sos/kmalloc.c new file mode 100644 index 0000000..62d948d --- /dev/null +++ b/sos-code-article6.5/sos/kmalloc.c @@ -0,0 +1,113 @@ +/* Copyright (C) 2004 David Decotigny + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + USA. +*/ + +#include +#include + +#include "physmem.h" +#include "kmem_vmm.h" +#include "kmem_slab.h" + +#include "kmalloc.h" + +/* The cache structures for these caches, the object size, their + names, and some number of pages that contain them. They might not + necessarily be powers of 2s. */ +static struct { + const char *name; + sos_size_t object_size; + sos_count_t pages_per_slab; + struct sos_kslab_cache *cache; +} kmalloc_cache[] = + { + { "kmalloc 8B objects", 8, 1 }, + { "kmalloc 16B objects", 16, 1 }, + { "kmalloc 32B objects", 32, 1 }, + { "kmalloc 64B objects", 64, 1 }, + { "kmalloc 128B objects", 128, 1 }, + { "kmalloc 256B objects", 256, 2 }, + { "kmalloc 1024B objects", 1024, 2 }, + { "kmalloc 2048B objects", 2048, 3 }, + { "kmalloc 4096B objects", 4096, 4 }, + { "kmalloc 8192B objects", 8192, 8 }, + { "kmalloc 16384B objects", 16384, 12 }, + { NULL, 0, 0, NULL } + }; + + +sos_ret_t sos_kmalloc_subsystem_setup() +{ + int i; + for (i = 0 ; kmalloc_cache[i].object_size != 0 ; i ++) + { + struct sos_kslab_cache *new_cache; + new_cache = sos_kmem_cache_create(kmalloc_cache[i].name, + kmalloc_cache[i].object_size, + kmalloc_cache[i].pages_per_slab, + 0, + SOS_KSLAB_CREATE_MAP + ); + SOS_ASSERT_FATAL(new_cache != NULL); + kmalloc_cache[i].cache = new_cache; + } + return SOS_OK; +} + + +sos_vaddr_t sos_kmalloc(sos_size_t size, sos_ui32_t flags) +{ + /* Look for a suitable pre-allocated kmalloc cache */ + int i; + for (i = 0 ; kmalloc_cache[i].object_size != 0 ; i ++) + { + if (kmalloc_cache[i].object_size >= size) + return sos_kmem_cache_alloc(kmalloc_cache[i].cache, + (flags + & SOS_KMALLOC_ATOMIC)? + SOS_KSLAB_ALLOC_ATOMIC:0); + } + + /* none found yet => we directly use the kmem_vmm subsystem to + allocate whole pages */ + return sos_kmem_vmm_alloc(SOS_PAGE_ALIGN_SUP(size) / SOS_PAGE_SIZE, + ( (flags + & SOS_KMALLOC_ATOMIC)? + SOS_KMEM_VMM_ATOMIC:0) + | SOS_KMEM_VMM_MAP + ); +} + + +sos_ret_t sos_kfree(sos_vaddr_t vaddr) +{ + /* The trouble here is that we aren't sure whether this object is a + slab object in a pre-allocated kmalloc cache, or an object + directly allocated as a kmem_vmm region. */ + + /* We first pretend this object is allocated in a pre-allocated + kmalloc cache */ + if (! sos_kmem_cache_free(vaddr)) + return SOS_OK; /* Great ! We guessed right ! */ + + /* Here we're wrong: it appears not to be an object in a + pre-allocated kmalloc cache. So we try to pretend this is a + kmem_vmm area */ + return sos_kmem_vmm_free(vaddr); +} + + -- cgit v1.2.3