summaryrefslogtreecommitdiffstats
path: root/tools/testing/radix-tree/linux.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/testing/radix-tree/linux.c')
-rw-r--r--tools/testing/radix-tree/linux.c90
1 files changed, 67 insertions, 23 deletions
diff --git a/tools/testing/radix-tree/linux.c b/tools/testing/radix-tree/linux.c
index 154823737b20..cf48c8473f48 100644
--- a/tools/testing/radix-tree/linux.c
+++ b/tools/testing/radix-tree/linux.c
@@ -1,51 +1,92 @@
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
+#include <pthread.h>
#include <unistd.h>
#include <assert.h>
-#include <linux/mempool.h>
+#include <linux/gfp.h>
+#include <linux/poison.h>
#include <linux/slab.h>
+#include <linux/radix-tree.h>
#include <urcu/uatomic.h>
int nr_allocated;
+int preempt_count;
+int kmalloc_verbose;
+int test_verbose;
-void *mempool_alloc(mempool_t *pool, int gfp_mask)
-{
- return pool->alloc(gfp_mask, pool->data);
-}
+struct kmem_cache {
+ pthread_mutex_t lock;
+ int size;
+ int nr_objs;
+ void *objs;
+ void (*ctor)(void *);
+};
-void mempool_free(void *element, mempool_t *pool)
+void *kmem_cache_alloc(struct kmem_cache *cachep, int flags)
{
- pool->free(element, pool->data);
+ struct radix_tree_node *node;
+
+ if (flags & __GFP_NOWARN)
+ return NULL;
+
+ pthread_mutex_lock(&cachep->lock);
+ if (cachep->nr_objs) {
+ cachep->nr_objs--;
+ node = cachep->objs;
+ cachep->objs = node->parent;
+ pthread_mutex_unlock(&cachep->lock);
+ node->parent = NULL;
+ } else {
+ pthread_mutex_unlock(&cachep->lock);
+ node = malloc(cachep->size);
+ if (cachep->ctor)
+ cachep->ctor(node);
+ }
+
+ uatomic_inc(&nr_allocated);
+ if (kmalloc_verbose)
+ printf("Allocating %p from slab\n", node);
+ return node;
}
-mempool_t *mempool_create(int min_nr, mempool_alloc_t *alloc_fn,
- mempool_free_t *free_fn, void *pool_data)
+void kmem_cache_free(struct kmem_cache *cachep, void *objp)
{
- mempool_t *ret = malloc(sizeof(*ret));
-
- ret->alloc = alloc_fn;
- ret->free = free_fn;
- ret->data = pool_data;
- return ret;
+ assert(objp);
+ uatomic_dec(&nr_allocated);
+ if (kmalloc_verbose)
+ printf("Freeing %p to slab\n", objp);
+ pthread_mutex_lock(&cachep->lock);
+ if (cachep->nr_objs > 10) {
+ memset(objp, POISON_FREE, cachep->size);
+ free(objp);
+ } else {
+ struct radix_tree_node *node = objp;
+ cachep->nr_objs++;
+ node->parent = cachep->objs;
+ cachep->objs = node;
+ }
+ pthread_mutex_unlock(&cachep->lock);
}
-void *kmem_cache_alloc(struct kmem_cache *cachep, int flags)
+void *kmalloc(size_t size, gfp_t gfp)
{
- void *ret = malloc(cachep->size);
- if (cachep->ctor)
- cachep->ctor(ret);
+ void *ret = malloc(size);
uatomic_inc(&nr_allocated);
+ if (kmalloc_verbose)
+ printf("Allocating %p from malloc\n", ret);
return ret;
}
-void kmem_cache_free(struct kmem_cache *cachep, void *objp)
+void kfree(void *p)
{
- assert(objp);
+ if (!p)
+ return;
uatomic_dec(&nr_allocated);
- memset(objp, 0, cachep->size);
- free(objp);
+ if (kmalloc_verbose)
+ printf("Freeing %p to malloc\n", p);
+ free(p);
}
struct kmem_cache *
@@ -54,7 +95,10 @@ kmem_cache_create(const char *name, size_t size, size_t offset,
{
struct kmem_cache *ret = malloc(sizeof(*ret));
+ pthread_mutex_init(&ret->lock, NULL);
ret->size = size;
+ ret->nr_objs = 0;
+ ret->objs = NULL;
ret->ctor = ctor;
return ret;
}
OpenPOWER on IntegriCloud