root/tools/testing/radix-tree/linux.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. kmem_cache_alloc
  2. kmem_cache_free
  3. kmalloc
  4. kfree
  5. kmem_cache_create

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

/* [<][>][^][v][top][bottom][index][help] */