// SPDX-License-Identifier: GPL-2.0
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <pthread.h>
#include <unistd.h>
#include <assert.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 test_verbose;

struct kmem_cache {
	pthread_mutex_t lock;
	unsigned int size;
	unsigned int align;
	int nr_objs;
	void *objs;
	void (*ctor)(void *);
	unsigned int non_kernel;
	unsigned long nr_allocated;
	unsigned long nr_tallocated;
};

void kmem_cache_set_non_kernel(struct kmem_cache *cachep, unsigned int val)
{
	cachep->non_kernel = val;
}

unsigned long kmem_cache_get_alloc(struct kmem_cache *cachep)
{
	return cachep->size * cachep->nr_allocated;
}

unsigned long kmem_cache_nr_allocated(struct kmem_cache *cachep)
{
	return cachep->nr_allocated;
}

unsigned long kmem_cache_nr_tallocated(struct kmem_cache *cachep)
{
	return cachep->nr_tallocated;
}

void kmem_cache_zero_nr_tallocated(struct kmem_cache *cachep)
{
	cachep->nr_tallocated = 0;
}

void *kmem_cache_alloc_lru(struct kmem_cache *cachep, struct list_lru *lru,
		int gfp)
{
	void *p;

	if (!(gfp & __GFP_DIRECT_RECLAIM)) {
		if (!cachep->non_kernel)
			return NULL;

		cachep->non_kernel--;
	}

	pthread_mutex_lock(&cachep->lock);
	if (cachep->nr_objs) {
		struct radix_tree_node *node = cachep->objs;
		cachep->nr_objs--;
		cachep->objs = node->parent;
		pthread_mutex_unlock(&cachep->lock);
		node->parent = NULL;
		p = node;
	} else {
		pthread_mutex_unlock(&cachep->lock);
		if (cachep->align)
			posix_memalign(&p, cachep->align, cachep->size);
		else
			p = malloc(cachep->size);
		if (cachep->ctor)
			cachep->ctor(p);
		else if (gfp & __GFP_ZERO)
			memset(p, 0, cachep->size);
	}

	uatomic_inc(&cachep->nr_allocated);
	uatomic_inc(&nr_allocated);
	uatomic_inc(&cachep->nr_tallocated);
	if (kmalloc_verbose)
		printf("Allocating %p from slab\n", p);
	return p;
}

void kmem_cache_free_locked(struct kmem_cache *cachep, void *objp)
{
	assert(objp);
	uatomic_dec(&nr_allocated);
	uatomic_dec(&cachep->nr_allocated);
	if (kmalloc_verbose)
		printf("Freeing %p to slab\n", objp);
	if (cachep->nr_objs > 10 || cachep->align) {
		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;
	}
}

void kmem_cache_free(struct kmem_cache *cachep, void *objp)
{
	pthread_mutex_lock(&cachep->lock);
	kmem_cache_free_locked(cachep, objp);
	pthread_mutex_unlock(&cachep->lock);
}

void kmem_cache_free_bulk(struct kmem_cache *cachep, size_t size, void **list)
{
	if (kmalloc_verbose)
		pr_debug("Bulk free %p[0-%lu]\n", list, size - 1);

	pthread_mutex_lock(&cachep->lock);
	for (int i = 0; i < size; i++)
		kmem_cache_free_locked(cachep, list[i]);
	pthread_mutex_unlock(&cachep->lock);
}

void kmem_cache_shrink(struct kmem_cache *cachep)
{
}

int kmem_cache_alloc_bulk(struct kmem_cache *cachep, gfp_t gfp, size_t size,
			  void **p)
{
	size_t i;

	if (kmalloc_verbose)
		pr_debug("Bulk alloc %lu\n", size);

	if (!(gfp & __GFP_DIRECT_RECLAIM)) {
		if (cachep->non_kernel < size)
			return 0;

		cachep->non_kernel -= size;
	}

	pthread_mutex_lock(&cachep->lock);
	if (cachep->nr_objs >= size) {
		struct radix_tree_node *node;

		for (i = 0; i < size; i++) {
			node = cachep->objs;
			cachep->nr_objs--;
			cachep->objs = node->parent;
			p[i] = node;
			node->parent = NULL;
		}
		pthread_mutex_unlock(&cachep->lock);
	} else {
		pthread_mutex_unlock(&cachep->lock);
		for (i = 0; i < size; i++) {
			if (cachep->align) {
				posix_memalign(&p[i], cachep->align,
					       cachep->size);
			} else {
				p[i] = malloc(cachep->size);
			}
			if (cachep->ctor)
				cachep->ctor(p[i]);
			else if (gfp & __GFP_ZERO)
				memset(p[i], 0, cachep->size);
		}
	}

	for (i = 0; i < size; i++) {
		uatomic_inc(&nr_allocated);
		uatomic_inc(&cachep->nr_allocated);
		uatomic_inc(&cachep->nr_tallocated);
		if (kmalloc_verbose)
			printf("Allocating %p from slab\n", p[i]);
	}

	return size;
}

struct kmem_cache *
kmem_cache_create(const char *name, unsigned int size, unsigned int align,
		unsigned int flags, void (*ctor)(void *))
{
	struct kmem_cache *ret = malloc(sizeof(*ret));

	pthread_mutex_init(&ret->lock, NULL);
	ret->size = size;
	ret->align = align;
	ret->nr_objs = 0;
	ret->nr_allocated = 0;
	ret->nr_tallocated = 0;
	ret->objs = NULL;
	ret->ctor = ctor;
	ret->non_kernel = 0;
	return ret;
}

/*
 * Test the test infrastructure for kem_cache_alloc/free and bulk counterparts.
 */
void test_kmem_cache_bulk(void)
{
	int i;
	void *list[12];
	static struct kmem_cache *test_cache, *test_cache2;

	/*
	 * Testing the bulk allocators without aligned kmem_cache to force the
	 * bulk alloc/free to reuse
	 */
	test_cache = kmem_cache_create("test_cache", 256, 0, SLAB_PANIC, NULL);

	for (i = 0; i < 5; i++)
		list[i] = kmem_cache_alloc(test_cache, __GFP_DIRECT_RECLAIM);

	for (i = 0; i < 5; i++)
		kmem_cache_free(test_cache, list[i]);
	assert(test_cache->nr_objs == 5);

	kmem_cache_alloc_bulk(test_cache, __GFP_DIRECT_RECLAIM, 5, list);
	kmem_cache_free_bulk(test_cache, 5, list);

	for (i = 0; i < 12 ; i++)
		list[i] = kmem_cache_alloc(test_cache, __GFP_DIRECT_RECLAIM);

	for (i = 0; i < 12; i++)
		kmem_cache_free(test_cache, list[i]);

	/* The last free will not be kept around */
	assert(test_cache->nr_objs == 11);

	/* Aligned caches will immediately free */
	test_cache2 = kmem_cache_create("test_cache2", 128, 128, SLAB_PANIC, NULL);

	kmem_cache_alloc_bulk(test_cache2, __GFP_DIRECT_RECLAIM, 10, list);
	kmem_cache_free_bulk(test_cache2, 10, list);
	assert(!test_cache2->nr_objs);


}
