aboutsummaryrefslogtreecommitdiffstats
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.c48
1 files changed, 41 insertions, 7 deletions
diff --git a/tools/testing/radix-tree/linux.c b/tools/testing/radix-tree/linux.c
index ff0452e8a0c4..d31ea7c9abec 100644
--- a/tools/testing/radix-tree/linux.c
+++ b/tools/testing/radix-tree/linux.c
@@ -1,16 +1,27 @@
1#include <stdlib.h> 1#include <stdlib.h>
2#include <string.h> 2#include <string.h>
3#include <malloc.h> 3#include <malloc.h>
4#include <pthread.h>
4#include <unistd.h> 5#include <unistd.h>
5#include <assert.h> 6#include <assert.h>
6 7
7#include <linux/mempool.h> 8#include <linux/mempool.h>
9#include <linux/poison.h>
8#include <linux/slab.h> 10#include <linux/slab.h>
11#include <linux/radix-tree.h>
9#include <urcu/uatomic.h> 12#include <urcu/uatomic.h>
10 13
11int nr_allocated; 14int nr_allocated;
12int preempt_count; 15int preempt_count;
13 16
17struct kmem_cache {
18 pthread_mutex_t lock;
19 int size;
20 int nr_objs;
21 void *objs;
22 void (*ctor)(void *);
23};
24
14void *mempool_alloc(mempool_t *pool, int gfp_mask) 25void *mempool_alloc(mempool_t *pool, int gfp_mask)
15{ 26{
16 return pool->alloc(gfp_mask, pool->data); 27 return pool->alloc(gfp_mask, pool->data);
@@ -34,24 +45,44 @@ mempool_t *mempool_create(int min_nr, mempool_alloc_t *alloc_fn,
34 45
35void *kmem_cache_alloc(struct kmem_cache *cachep, int flags) 46void *kmem_cache_alloc(struct kmem_cache *cachep, int flags)
36{ 47{
37 void *ret; 48 struct radix_tree_node *node;
38 49
39 if (flags & __GFP_NOWARN) 50 if (flags & __GFP_NOWARN)
40 return NULL; 51 return NULL;
41 52
42 ret = malloc(cachep->size); 53 pthread_mutex_lock(&cachep->lock);
43 if (cachep->ctor) 54 if (cachep->nr_objs) {
44 cachep->ctor(ret); 55 cachep->nr_objs--;
56 node = cachep->objs;
57 cachep->objs = node->private_data;
58 pthread_mutex_unlock(&cachep->lock);
59 node->private_data = NULL;
60 } else {
61 pthread_mutex_unlock(&cachep->lock);
62 node = malloc(cachep->size);
63 if (cachep->ctor)
64 cachep->ctor(node);
65 }
66
45 uatomic_inc(&nr_allocated); 67 uatomic_inc(&nr_allocated);
46 return ret; 68 return node;
47} 69}
48 70
49void kmem_cache_free(struct kmem_cache *cachep, void *objp) 71void kmem_cache_free(struct kmem_cache *cachep, void *objp)
50{ 72{
51 assert(objp); 73 assert(objp);
52 uatomic_dec(&nr_allocated); 74 uatomic_dec(&nr_allocated);
53 memset(objp, 0, cachep->size); 75 pthread_mutex_lock(&cachep->lock);
54 free(objp); 76 if (cachep->nr_objs > 10) {
77 memset(objp, POISON_FREE, cachep->size);
78 free(objp);
79 } else {
80 struct radix_tree_node *node = objp;
81 cachep->nr_objs++;
82 node->private_data = cachep->objs;
83 cachep->objs = node;
84 }
85 pthread_mutex_unlock(&cachep->lock);
55} 86}
56 87
57void *kmalloc(size_t size, gfp_t gfp) 88void *kmalloc(size_t size, gfp_t gfp)
@@ -75,7 +106,10 @@ kmem_cache_create(const char *name, size_t size, size_t offset,
75{ 106{
76 struct kmem_cache *ret = malloc(sizeof(*ret)); 107 struct kmem_cache *ret = malloc(sizeof(*ret));
77 108
109 pthread_mutex_init(&ret->lock, NULL);
78 ret->size = size; 110 ret->size = size;
111 ret->nr_objs = 0;
112 ret->objs = NULL;
79 ret->ctor = ctor; 113 ret->ctor = ctor;
80 return ret; 114 return ret;
81} 115}