linux/tools/testing/radix-tree/linux.c
<<
>>
Prefs
   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
  15int nr_allocated;
  16int preempt_count;
  17int kmalloc_verbose;
  18int test_verbose;
  19
  20struct kmem_cache {
  21        pthread_mutex_t lock;
  22        int size;
  23        int nr_objs;
  24        void *objs;
  25        void (*ctor)(void *);
  26};
  27
  28void *kmem_cache_alloc(struct kmem_cache *cachep, int flags)
  29{
  30        struct radix_tree_node *node;
  31
  32        if (flags & __GFP_NOWARN)
  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
  55void 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
  74void *kmalloc(size_t size, gfp_t gfp)
  75{
  76        void *ret = malloc(size);
  77        uatomic_inc(&nr_allocated);
  78        if (kmalloc_verbose)
  79                printf("Allocating %p from malloc\n", ret);
  80        return ret;
  81}
  82
  83void kfree(void *p)
  84{
  85        if (!p)
  86                return;
  87        uatomic_dec(&nr_allocated);
  88        if (kmalloc_verbose)
  89                printf("Freeing %p to malloc\n", p);
  90        free(p);
  91}
  92
  93struct kmem_cache *
  94kmem_cache_create(const char *name, size_t size, size_t offset,
  95        unsigned long flags, void (*ctor)(void *))
  96{
  97        struct kmem_cache *ret = malloc(sizeof(*ret));
  98
  99        pthread_mutex_init(&ret->lock, NULL);
 100        ret->size = size;
 101        ret->nr_objs = 0;
 102        ret->objs = NULL;
 103        ret->ctor = ctor;
 104        return ret;
 105}
 106