summaryrefslogtreecommitdiff
path: root/libdde-linux26/lib/src/arch/l4/kmem_cache.c
diff options
context:
space:
mode:
Diffstat (limited to 'libdde-linux26/lib/src/arch/l4/kmem_cache.c')
-rw-r--r--libdde-linux26/lib/src/arch/l4/kmem_cache.c211
1 files changed, 211 insertions, 0 deletions
diff --git a/libdde-linux26/lib/src/arch/l4/kmem_cache.c b/libdde-linux26/lib/src/arch/l4/kmem_cache.c
new file mode 100644
index 00000000..5e44c140
--- /dev/null
+++ b/libdde-linux26/lib/src/arch/l4/kmem_cache.c
@@ -0,0 +1,211 @@
+/*
+ * \brief Kmem_cache implementation
+ * \author Christian Helmuth
+ * \date 2007-01-22
+ *
+ * In Linux 2.6 this resides in mm/slab.c.
+ *
+ * I'll disregard the following function currently...
+ *
+ * extern struct kmem_cache *kmem_find_general_cachep(size_t size, gfp_t gfpflags);
+ * extern void *kmem_cache_zalloc(struct kmem_cache *, gfp_t);
+ */
+
+/* Linux */
+#include <linux/slab.h>
+
+#include "local.h"
+
+
+/*******************
+ ** Configuration **
+ *******************/
+
+#define DEBUG_SLAB 0
+
+#if DEBUG_SLAB
+# define DEBUG_SLAB_ALLOC 1
+#else
+# define DEBUG_SLAB_ALLOC 0
+#endif
+
+/*
+ * Kmem cache structure
+ */
+struct kmem_cache
+{
+ const char *name; /**< cache name */
+ unsigned size; /**< obj size */
+
+ struct ddekit_slab *ddekit_slab_cache; /**< backing DDEKit cache */
+ ddekit_lock_t cache_lock; /**< lock */
+ void (*ctor)(void *); /**< object constructor */
+};
+
+
+/**
+ * Return size of objects in cache
+ */
+unsigned int kmem_cache_size(struct kmem_cache *cache)
+{
+ return cache->size;
+}
+
+
+/**
+ * Return name of cache
+ */
+const char *kmem_cache_name(struct kmem_cache *cache)
+{
+ return cache->name;
+}
+
+
+/**
+ * kmem_cache_shrink - Shrink a cache.
+ * @cachep: The cache to shrink.
+ *
+ * Releases as many slabs as possible for a cache.
+ * To help debugging, a zero exit status indicates all slabs were released.
+ */
+int kmem_cache_shrink(struct kmem_cache *cache)
+{
+ /* noop */
+ return 1;
+}
+
+
+/**
+ * kmem_cache_free - Deallocate an object
+ * @cachep: The cache the allocation was from.
+ * @objp: The previously allocated object.
+ *
+ * Free an object which was previously allocated from this
+ * cache.
+ */
+void kmem_cache_free(struct kmem_cache *cache, void *objp)
+{
+ ddekit_log(DEBUG_SLAB_ALLOC, "\"%s\" (%p)", cache->name, objp);
+
+ ddekit_lock_lock(&cache->cache_lock);
+ ddekit_slab_free(cache->ddekit_slab_cache, objp);
+ ddekit_lock_unlock(&cache->cache_lock);
+}
+
+
+/**
+ * kmem_cache_alloc - Allocate an object
+ * @cachep: The cache to allocate from.
+ * @flags: See kmalloc().
+ *
+ * Allocate an object from this cache. The flags are only relevant
+ * if the cache has no available objects.
+ */
+void *kmem_cache_alloc(struct kmem_cache *cache, gfp_t flags)
+{
+ void *ret;
+
+ ddekit_log(DEBUG_SLAB_ALLOC, "\"%s\" flags=%x", cache->name, flags);
+
+ ddekit_lock_lock(&cache->cache_lock);
+ ret = ddekit_slab_alloc(cache->ddekit_slab_cache);
+ ddekit_lock_unlock(&cache->cache_lock);
+
+ // XXX: is it valid to run ctor AND memset to zero?
+ if (flags & __GFP_ZERO)
+ memset(ret, 0, cache->size);
+ else if (cache->ctor)
+ cache->ctor(ret);
+
+ return ret;
+}
+
+
+/**
+ * kmem_cache_destroy - delete a cache
+ * @cachep: the cache to destroy
+ *
+ * Remove a struct kmem_cache object from the slab cache.
+ * Returns 0 on success.
+ *
+ * It is expected this function will be called by a module when it is
+ * unloaded. This will remove the cache completely, and avoid a duplicate
+ * cache being allocated each time a module is loaded and unloaded, if the
+ * module doesn't have persistent in-kernel storage across loads and unloads.
+ *
+ * The cache must be empty before calling this function.
+ *
+ * The caller must guarantee that noone will allocate memory from the cache
+ * during the kmem_cache_destroy().
+ */
+void kmem_cache_destroy(struct kmem_cache *cache)
+{
+ ddekit_log(DEBUG_SLAB, "\"%s\"", cache->name);
+
+ ddekit_slab_destroy(cache->ddekit_slab_cache);
+ ddekit_simple_free(cache);
+}
+
+
+/**
+ * kmem_cache_create - Create a cache.
+ * @name: A string which is used in /proc/slabinfo to identify this cache.
+ * @size: The size of objects to be created in this cache.
+ * @align: The required alignment for the objects.
+ * @flags: SLAB flags
+ * @ctor: A constructor for the objects.
+ *
+ * Returns a ptr to the cache on success, NULL on failure.
+ * Cannot be called within a int, but can be interrupted.
+ * The @ctor is run when new pages are allocated by the cache
+ * and the @dtor is run before the pages are handed back.
+ *
+ * @name must be valid until the cache is destroyed. This implies that
+ * the module calling this has to destroy the cache before getting unloaded.
+ *
+ * The flags are
+ *
+ * %SLAB_POISON - Poison the slab with a known test pattern (a5a5a5a5)
+ * to catch references to uninitialised memory.
+ *
+ * %SLAB_RED_ZONE - Insert `Red' zones around the allocated memory to check
+ * for buffer overruns.
+ *
+ * %SLAB_HWCACHE_ALIGN - Align the objects in this cache to a hardware
+ * cacheline. This can be beneficial if you're counting cycles as closely
+ * as davem.
+ */
+struct kmem_cache * kmem_cache_create(const char *name, size_t size, size_t align,
+ unsigned long flags,
+ void (*ctor)(void *))
+{
+ ddekit_log(DEBUG_SLAB, "\"%s\" obj_size=%d", name, size);
+
+ struct kmem_cache *cache;
+
+ if (!name) {
+ printk("kmem_cache name reqeuired\n");
+ return 0;
+ }
+
+ cache = ddekit_simple_malloc(sizeof(*cache));
+ if (!cache) {
+ printk("No memory for slab cache\n");
+ return 0;
+ }
+
+ /* Initialize a physically contiguous cache for kmem */
+ if (!(cache->ddekit_slab_cache = ddekit_slab_init(size, 1))) {
+ printk("DDEKit slab init failed\n");
+ ddekit_simple_free(cache);
+ return 0;
+ }
+
+ cache->name = name;
+ cache->size = size;
+ cache->ctor = ctor;
+
+ ddekit_lock_init_unlocked(&cache->cache_lock);
+
+ return cache;
+}