summaryrefslogtreecommitdiff
path: root/sos-code-article6.5/sos/kmalloc.c
diff options
context:
space:
mode:
authorAlex AUVOLAT <alex.auvolat@ens.fr>2014-03-28 17:09:15 +0100
committerAlex AUVOLAT <alex.auvolat@ens.fr>2014-03-28 17:09:15 +0100
commita8968330aff45e0b8cf278f49fa337d5fcb9bfd8 (patch)
treededf697b1a5c3c96e77f77e551e9e6af8785a51c /sos-code-article6.5/sos/kmalloc.c
parent8d9e22df8afa4c3339e52c7b3b77388ca0e69fac (diff)
downloadSOS-a8968330aff45e0b8cf278f49fa337d5fcb9bfd8.tar.gz
SOS-a8968330aff45e0b8cf278f49fa337d5fcb9bfd8.zip
Import and compile code for article 6.5
Diffstat (limited to 'sos-code-article6.5/sos/kmalloc.c')
-rw-r--r--sos-code-article6.5/sos/kmalloc.c113
1 files changed, 113 insertions, 0 deletions
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 <sos/assert.h>
+#include <sos/macros.h>
+
+#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);
+}
+
+