/*
 * Copyright (c) 2019 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */
#include <zephyr/sys/sys_heap.h>
#include <zephyr/sys/util.h>
#include <zephyr/kernel.h>
#include "heap.h"

/* White-box sys_heap validation code.  Uses internal data structures.
 * Not expected to be useful in production apps.  This checks every
 * header field of every chunk and returns true if the totality of the
 * data structure is a valid heap.  It doesn't necessarily tell you
 * that it is the CORRECT heap given the history of alloc/free calls
 * that it can't inspect.  In a pathological case, you can imagine
 * something scribbling a copy of a previously-valid heap on top of a
 * running one and corrupting it. YMMV.
 */

#define VALIDATE(cond) do { if (!(cond)) { return false; } } while (0)

static bool in_bounds(struct z_heap *h, chunkid_t c)
{
	VALIDATE(c >= right_chunk(h, 0));
	VALIDATE(c < h->end_chunk);
	VALIDATE(chunk_size(h, c) < h->end_chunk);
	return true;
}

static bool valid_chunk(struct z_heap *h, chunkid_t c)
{
	VALIDATE(chunk_size(h, c) > 0);
	VALIDATE(c + chunk_size(h, c) <= h->end_chunk);
	VALIDATE(in_bounds(h, c));
	VALIDATE(right_chunk(h, left_chunk(h, c)) == c);
	VALIDATE(left_chunk(h, right_chunk(h, c)) == c);
	if (chunk_used(h, c)) {
		VALIDATE(!solo_free_header(h, c));
	} else {
		VALIDATE(chunk_used(h, left_chunk(h, c)));
		VALIDATE(chunk_used(h, right_chunk(h, c)));
		if (!solo_free_header(h, c)) {
			VALIDATE(in_bounds(h, prev_free_chunk(h, c)));
			VALIDATE(in_bounds(h, next_free_chunk(h, c)));
		}
	}
	return true;
}

/* Validate multiple state dimensions for the bucket "next" pointer
 * and see that they match.  Probably should unify the design a
 * bit...
 */
static inline void check_nexts(struct z_heap *h, int bidx)
{
	struct z_heap_bucket *b = &h->buckets[bidx];

	bool emptybit = (h->avail_buckets & BIT(bidx)) == 0;
	bool emptylist = b->next == 0;
	bool empties_match = emptybit == emptylist;

	(void)empties_match;
	CHECK(empties_match);

	if (b->next != 0) {
		CHECK(valid_chunk(h, b->next));
	}
}

static void get_alloc_info(struct z_heap *h, size_t *alloc_bytes,
			   size_t *free_bytes)
{
	chunkid_t c;

	*alloc_bytes = 0;
	*free_bytes = 0;

	for (c = right_chunk(h, 0); c < h->end_chunk; c = right_chunk(h, c)) {
		if (chunk_used(h, c)) {
			*alloc_bytes += chunksz_to_bytes(h, chunk_size(h, c));
		} else if (!solo_free_header(h, c)) {
			*free_bytes += chunksz_to_bytes(h, chunk_size(h, c));
		}
	}
}

bool sys_heap_validate(struct sys_heap *heap)
{
	struct z_heap *h = heap->heap;
	chunkid_t c;

	/*
	 * Walk through the chunks linearly, verifying sizes and end pointer.
	 */
	for (c = right_chunk(h, 0); c < h->end_chunk; c = right_chunk(h, c)) {
		if (!valid_chunk(h, c)) {
			return false;
		}
	}
	if (c != h->end_chunk) {
		return false;  /* Should have exactly consumed the buffer */
	}

#ifdef CONFIG_SYS_HEAP_RUNTIME_STATS
	/*
	 * Validate sys_heap_runtime_stats_get API.
	 * Iterate all chunks in sys_heap to get total allocated bytes and
	 * free bytes, then compare with the results of
	 * sys_heap_runtime_stats_get function.
	 */
	size_t allocated_bytes, free_bytes;
	struct sys_memory_stats stat;

	get_alloc_info(h, &allocated_bytes, &free_bytes);
	sys_heap_runtime_stats_get(heap, &stat);
	if ((stat.allocated_bytes != allocated_bytes) ||
	    (stat.free_bytes != free_bytes)) {
		return false;
	}
#endif

	/* Check the free lists: entry count should match, empty bit
	 * should be correct, and all chunk entries should point into
	 * valid unused chunks.  Mark those chunks USED, temporarily.
	 */
	for (int b = 0; b <= bucket_idx(h, h->end_chunk); b++) {
		chunkid_t c0 = h->buckets[b].next;
		uint32_t n = 0;

		check_nexts(h, b);

		for (c = c0; c != 0 && (n == 0 || c != c0);
		     n++, c = next_free_chunk(h, c)) {
			if (!valid_chunk(h, c)) {
				return false;
			}
			set_chunk_used(h, c, true);
		}

		bool empty = (h->avail_buckets & BIT(b)) == 0;
		bool zero = n == 0;

		if (empty != zero) {
			return false;
		}

		if (empty && h->buckets[b].next != 0) {
			return false;
		}
	}

	/*
	 * Walk through the chunks linearly again, verifying that all chunks
	 * but solo headers are now USED (i.e. all free blocks were found
	 * during enumeration).  Mark all such blocks UNUSED and solo headers
	 * USED.
	 */
	chunkid_t prev_chunk = 0;
	for (c = right_chunk(h, 0); c < h->end_chunk; c = right_chunk(h, c)) {
		if (!chunk_used(h, c) && !solo_free_header(h, c)) {
			return false;
		}
		if (left_chunk(h, c) != prev_chunk) {
			return false;
		}
		prev_chunk = c;

		set_chunk_used(h, c, solo_free_header(h, c));
	}
	if (c != h->end_chunk) {
		return false;  /* Should have exactly consumed the buffer */
	}

	/* Go through the free lists again checking that the linear
	 * pass caught all the blocks and that they now show UNUSED.
	 * Mark them USED.
	 */
	for (int b = 0; b <= bucket_idx(h, h->end_chunk); b++) {
		chunkid_t c0 = h->buckets[b].next;
		int n = 0;

		if (c0 == 0) {
			continue;
		}

		for (c = c0; n == 0 || c != c0; n++, c = next_free_chunk(h, c)) {
			if (chunk_used(h, c)) {
				return false;
			}
			set_chunk_used(h, c, true);
		}
	}

	/* Now we are valid, but have managed to invert all the in-use
	 * fields.  One more linear pass to fix them up
	 */
	for (c = right_chunk(h, 0); c < h->end_chunk; c = right_chunk(h, c)) {
		set_chunk_used(h, c, !chunk_used(h, c));
	}
	return true;
}

struct z_heap_stress_rec {
	void *(*alloc_fn)(void *arg, size_t bytes);
	void (*free_fn)(void *arg, void *p);
	void *arg;
	size_t total_bytes;
	struct z_heap_stress_block *blocks;
	size_t nblocks;
	size_t blocks_alloced;
	size_t bytes_alloced;
	uint32_t target_percent;
};

struct z_heap_stress_block {
	void *ptr;
	size_t sz;
};

/* Very simple LCRNG (from https://nuclear.llnl.gov/CNP/rng/rngman/node4.html)
 *
 * Here to guarantee cross-platform test repeatability.
 */
static uint32_t rand32(void)
{
	static uint64_t state = 123456789; /* seed */

	state = state * 2862933555777941757UL + 3037000493UL;

	return (uint32_t)(state >> 32);
}

static bool rand_alloc_choice(struct z_heap_stress_rec *sr)
{
	/* Edge cases: no blocks allocated, and no space for a new one */
	if (sr->blocks_alloced == 0) {
		return true;
	} else if (sr->blocks_alloced >= sr->nblocks) {
		return false;
	} else {

		/* The way this works is to scale the chance of choosing to
		 * allocate vs. free such that it's even odds when the heap is
		 * at the target percent, with linear tapering on the low
		 * slope (i.e. we choose to always allocate with an empty
		 * heap, allocate 50% of the time when the heap is exactly at
		 * the target, and always free when above the target).  In
		 * practice, the operations aren't quite symmetric (you can
		 * always free, but your allocation might fail), and the units
		 * aren't matched (we're doing math based on bytes allocated
		 * and ignoring the overhead) but this is close enough.  And
		 * yes, the math here is coarse (in units of percent), but
		 * that's good enough and fits well inside 32 bit quantities.
		 * (Note precision issue when heap size is above 40MB
		 * though!).
		 */
		__ASSERT(sr->total_bytes < 0xffffffffU / 100, "too big for u32!");
		uint32_t full_pct = (100 * sr->bytes_alloced) / sr->total_bytes;
		uint32_t target = sr->target_percent ? sr->target_percent : 1;
		uint32_t free_chance = 0xffffffffU;

		if (full_pct < sr->target_percent) {
			free_chance = full_pct * (0x80000000U / target);
		}

		return rand32() > free_chance;
	}
}

/* Chooses a size of block to allocate, logarithmically favoring
 * smaller blocks (i.e. blocks twice as large are half as frequent
 */
static size_t rand_alloc_size(struct z_heap_stress_rec *sr)
{
	ARG_UNUSED(sr);

	/* Min scale of 4 means that the half of the requests in the
	 * smallest size have an average size of 8
	 */
	int scale = 4 + __builtin_clz(rand32());

	return rand32() & BIT_MASK(scale);
}

/* Returns the index of a randomly chosen block to free */
static size_t rand_free_choice(struct z_heap_stress_rec *sr)
{
	return rand32() % sr->blocks_alloced;
}

/* General purpose heap stress test.  Takes function pointers to allow
 * for testing multiple heap APIs with the same rig.  The alloc and
 * free functions are passed back the argument as a context pointer.
 * The "log" function is for readable user output.  The total_bytes
 * argument should reflect the size of the heap being tested.  The
 * scratch array is used to store temporary state and should be sized
 * about half as large as the heap itself. Returns true on success.
 */
void sys_heap_stress(void *(*alloc_fn)(void *arg, size_t bytes),
		     void (*free_fn)(void *arg, void *p),
		     void *arg, size_t total_bytes,
		     uint32_t op_count,
		     void *scratch_mem, size_t scratch_bytes,
		     int target_percent,
		     struct z_heap_stress_result *result)
{
	struct z_heap_stress_rec sr = {
	       .alloc_fn = alloc_fn,
	       .free_fn = free_fn,
	       .arg = arg,
	       .total_bytes = total_bytes,
	       .blocks = scratch_mem,
	       .nblocks = scratch_bytes / sizeof(struct z_heap_stress_block),
	       .target_percent = target_percent,
	};

	*result = (struct z_heap_stress_result) {0};

	for (uint32_t i = 0; i < op_count; i++) {
		if (rand_alloc_choice(&sr)) {
			size_t sz = rand_alloc_size(&sr);
			void *p = sr.alloc_fn(sr.arg, sz);

			result->total_allocs++;
			if (p != NULL) {
				result->successful_allocs++;
				sr.blocks[sr.blocks_alloced].ptr = p;
				sr.blocks[sr.blocks_alloced].sz = sz;
				sr.blocks_alloced++;
				sr.bytes_alloced += sz;
			}
		} else {
			int b = rand_free_choice(&sr);
			void *p = sr.blocks[b].ptr;
			size_t sz = sr.blocks[b].sz;

			result->total_frees++;
			sr.blocks[b] = sr.blocks[sr.blocks_alloced - 1];
			sr.blocks_alloced--;
			sr.bytes_alloced -= sz;
			sr.free_fn(sr.arg, p);
		}
		result->accumulated_in_use_bytes += sr.bytes_alloced;
	}
}

/*
 * Print heap info for debugging / analysis purpose
 */
void heap_print_info(struct z_heap *h, bool dump_chunks)
{
	int i, nb_buckets = bucket_idx(h, h->end_chunk) + 1;
	size_t free_bytes, allocated_bytes, total, overhead;

	printk("Heap at %p contains %d units in %d buckets\n\n",
	       chunk_buf(h), h->end_chunk, nb_buckets);

	printk("  bucket#    min units        total      largest      largest\n"
	       "             threshold       chunks      (units)      (bytes)\n"
	       "  -----------------------------------------------------------\n");
	for (i = 0; i < nb_buckets; i++) {
		chunkid_t first = h->buckets[i].next;
		chunksz_t largest = 0;
		int count = 0;

		if (first) {
			chunkid_t curr = first;
			do {
				count++;
				largest = MAX(largest, chunk_size(h, curr));
				curr = next_free_chunk(h, curr);
			} while (curr != first);
		}
		if (count) {
			printk("%9d %12d %12d %12d %12zd\n",
			       i, (1 << i) - 1 + min_chunk_size(h), count,
			       largest, chunksz_to_bytes(h, largest));
		}
	}

	if (dump_chunks) {
		printk("\nChunk dump:\n");
		for (chunkid_t c = 0; ; c = right_chunk(h, c)) {
			printk("chunk %4d: [%c] size=%-4d left=%-4d right=%d\n",
			       c,
			       chunk_used(h, c) ? '*'
			       : solo_free_header(h, c) ? '.'
			       : '-',
			       chunk_size(h, c),
			       left_chunk(h, c),
			       right_chunk(h, c));
			if (c == h->end_chunk) {
				break;
			}
		}
	}

	get_alloc_info(h, &allocated_bytes, &free_bytes);
	/* The end marker chunk has a header. It is part of the overhead. */
	total = h->end_chunk * CHUNK_UNIT + chunk_header_bytes(h);
	overhead = total - free_bytes - allocated_bytes;
	printk("\n%zd free bytes, %zd allocated bytes, overhead = %zd bytes (%zd.%zd%%)\n",
	       free_bytes, allocated_bytes, overhead,
	       (1000 * overhead + total/2) / total / 10,
	       (1000 * overhead + total/2) / total % 10);
}

void sys_heap_print_info(struct sys_heap *heap, bool dump_chunks)
{
	heap_print_info(heap->heap, dump_chunks);
}

#ifdef CONFIG_SYS_HEAP_RUNTIME_STATS

int sys_heap_runtime_stats_get(struct sys_heap *heap,
		struct sys_memory_stats *stats)
{
	if ((heap == NULL) || (stats == NULL)) {
		return -EINVAL;
	}

	stats->free_bytes = heap->heap->free_bytes;
	stats->allocated_bytes = heap->heap->allocated_bytes;
	stats->max_allocated_bytes = heap->heap->max_allocated_bytes;

	return 0;
}

int sys_heap_runtime_stats_reset_max(struct sys_heap *heap)
{
	if (heap == NULL) {
		return -EINVAL;
	}

	heap->heap->max_allocated_bytes = heap->heap->allocated_bytes;

	return 0;
}

#endif
