00001
00002
00012
00013
00014
00015
00016
00031
00032 #include <l4/slab/slab.h>
00033 #include <l4/log/l4log.h>
00034 #include <l4/dm_mem/dm_mem.h>
00035
00036 #include <l4/dde_linux/dde.h>
00037
00038
00039 #include <linux/slab.h>
00040
00041
00042 #include "__config.h"
00043 #include "internal.h"
00044
00045 #define CACHE_NAMELEN 20
00048 struct kmem_cache_s
00049 {
00050 l4slab_cache_t *l4slab_cache;
00051
00052 spinlock_t spinlock;
00053
00054
00055 void (*ctor)(void *, kmem_cache_t *, unsigned long);
00056
00057 void (*dtor)(void *, kmem_cache_t *, unsigned long);
00058
00059 char name[CACHE_NAMELEN];
00060 };
00061
00065 static void * alloc_grow (l4slab_cache_t * cache, void **data)
00066 {
00067 void *memp;
00068 kmem_cache_t *kcache = (kmem_cache_t *)l4slab_get_data(cache);
00069
00070 LOGd_Enter(DEBUG_SLAB, "(name=%s)", kcache->name);
00071
00072 if (!(memp = l4dm_mem_allocate (cache->slab_size,
00073 L4DM_PINNED | L4RM_MAP | L4RM_LOG2_ALIGNED)))
00074 Panic("dde: kmem_caches can't grow");
00075
00076 return memp;
00077 }
00078
00079 #if 0
00080 void alloc_release(l4slab_cache_t *cache, void *page, void *data)
00081 {
00082
00083 l4dm_mem_release(page);
00084 }
00085 #endif
00086
00096 kmem_cache_t * kmem_cache_create (const char *name, size_t size,
00097 size_t offset, unsigned long flags,
00098 void (*ctor) (void *, kmem_cache_t *, unsigned long),
00099 void (*dtor) (void *, kmem_cache_t *, unsigned long))
00100 {
00101 kmem_cache_t *kcache;
00102
00103 LOGd_Enter(DEBUG_SLAB, "(name=%s)", name);
00104
00105 if (!name)
00106 {
00107 LOG_Error ("kmem_cache name required");
00108 return NULL;
00109 }
00110 if(dtor){
00111 LOG_Error("No destructors supported!");
00112 return 0;
00113 }
00114
00115 kcache = vmalloc (sizeof (kmem_cache_t));
00116 kcache->l4slab_cache = vmalloc (sizeof (l4slab_cache_t));
00117 if (l4slab_cache_init (kcache->l4slab_cache, size, 0, alloc_grow, NULL))
00118 {
00119 LOG_Error ("Couldn't get l4slab_cache");
00120 return NULL;
00121 }
00122
00123 l4slab_set_data(kcache->l4slab_cache, (void *)kcache);
00124 spin_lock_init(&kcache->spinlock);
00125 strncpy (kcache->name, name, CACHE_NAMELEN);
00126
00127 kcache->ctor = ctor;
00128 kcache->dtor = dtor;
00129
00130 return kcache;
00131 }
00132
00135 int kmem_cache_destroy (kmem_cache_t * kcache)
00136 {
00137 LOGd_Enter(DEBUG_SLAB, "(name=%s)", kcache->name);
00138
00139 l4slab_destroy (kcache->l4slab_cache);
00140 vfree (kcache->l4slab_cache);
00141 vfree (kcache);
00142
00143 return 0;
00144 }
00145
00148 void * kmem_cache_alloc (kmem_cache_t * kcache, int flags)
00149 {
00150 void *p;
00151
00152 spin_lock(&kcache->spinlock);
00153 p = l4slab_alloc (kcache->l4slab_cache);
00154 spin_unlock(&kcache->spinlock);
00155
00156 if (kcache->ctor)
00157 kcache->ctor(p, kcache, flags);
00158
00159 return p;
00160 }
00161
00164 void kmem_cache_free (kmem_cache_t * kcache, void *objp)
00165 {
00166 spin_lock(&kcache->spinlock);
00167 l4slab_free (kcache->l4slab_cache, objp);
00168 spin_unlock(&kcache->spinlock);
00169 }