radix tree test suite: Dial down verbosity with -v
[linux-block.git] / tools / testing / radix-tree / linux.c
1 #include <stdlib.h>
2 #include <string.h>
3 #include <malloc.h>
4 #include <pthread.h>
5 #include <unistd.h>
6 #include <assert.h>
7
8 #include <linux/gfp.h>
9 #include <linux/poison.h>
10 #include <linux/slab.h>
11 #include <linux/radix-tree.h>
12 #include <urcu/uatomic.h>
13
14 int nr_allocated;
15 int preempt_count;
16 int kmalloc_verbose;
17 int test_verbose;
18
19 struct kmem_cache {
20         pthread_mutex_t lock;
21         int size;
22         int nr_objs;
23         void *objs;
24         void (*ctor)(void *);
25 };
26
27 void *kmem_cache_alloc(struct kmem_cache *cachep, int flags)
28 {
29         struct radix_tree_node *node;
30
31         if (flags & __GFP_NOWARN)
32                 return NULL;
33
34         pthread_mutex_lock(&cachep->lock);
35         if (cachep->nr_objs) {
36                 cachep->nr_objs--;
37                 node = cachep->objs;
38                 cachep->objs = node->private_data;
39                 pthread_mutex_unlock(&cachep->lock);
40                 node->private_data = NULL;
41         } else {
42                 pthread_mutex_unlock(&cachep->lock);
43                 node = malloc(cachep->size);
44                 if (cachep->ctor)
45                         cachep->ctor(node);
46         }
47
48         uatomic_inc(&nr_allocated);
49         if (kmalloc_verbose)
50                 printf("Allocating %p from slab\n", node);
51         return node;
52 }
53
54 void kmem_cache_free(struct kmem_cache *cachep, void *objp)
55 {
56         assert(objp);
57         uatomic_dec(&nr_allocated);
58         if (kmalloc_verbose)
59                 printf("Freeing %p to slab\n", objp);
60         pthread_mutex_lock(&cachep->lock);
61         if (cachep->nr_objs > 10) {
62                 memset(objp, POISON_FREE, cachep->size);
63                 free(objp);
64         } else {
65                 struct radix_tree_node *node = objp;
66                 cachep->nr_objs++;
67                 node->private_data = cachep->objs;
68                 cachep->objs = node;
69         }
70         pthread_mutex_unlock(&cachep->lock);
71 }
72
73 void *kmalloc(size_t size, gfp_t gfp)
74 {
75         void *ret = malloc(size);
76         uatomic_inc(&nr_allocated);
77         if (kmalloc_verbose)
78                 printf("Allocating %p from malloc\n", ret);
79         return ret;
80 }
81
82 void kfree(void *p)
83 {
84         if (!p)
85                 return;
86         uatomic_dec(&nr_allocated);
87         if (kmalloc_verbose)
88                 printf("Freeing %p to malloc\n", p);
89         free(p);
90 }
91
92 struct kmem_cache *
93 kmem_cache_create(const char *name, size_t size, size_t offset,
94         unsigned long flags, void (*ctor)(void *))
95 {
96         struct kmem_cache *ret = malloc(sizeof(*ret));
97
98         pthread_mutex_init(&ret->lock, NULL);
99         ret->size = size;
100         ret->nr_objs = 0;
101         ret->objs = NULL;
102         ret->ctor = ctor;
103         return ret;
104 }