/*
 * Copyright (c) 2012-2014 Wind River Systems, Inc.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @file test memory pool and heap APIs
 *
 * This modules tests the following memory pool routines:
 *
 * - k_mem_pool_alloc(),
 * - k_mem_pool_free(),
 * - k_malloc(),
 * - k_free()
 */

#include <zephyr.h>
#include <tc_util.h>
#include <misc/util.h>

#define  ONE_SECOND     (sys_clock_ticks_per_sec)
#define  TENTH_SECOND   (sys_clock_ticks_per_sec / 10)

#define  NUM_BLOCKS     64

#define  DEFRAG_BLK_TEST 2222

/* size of stack area used by each thread */
#define STACKSIZE 512

K_SEM_DEFINE(ALTERNATE_SEM, 0, 1);
K_SEM_DEFINE(DEFRAG_SEM, 0, 1);
K_SEM_DEFINE(REGRESS_SEM, 0, 1);
K_SEM_DEFINE(HELPER_SEM, 0, 1);

K_MEM_POOL_DEFINE(POOL_ID, 64, 4096, 1, 4);
K_MEM_POOL_DEFINE(SECOND_POOL_ID, 16, 1024, 5, 4);

struct TEST_CASE {
	struct k_mem_block *block;      /* pointer to block data */
	struct k_mem_pool *pool_id;     /* pool ID */
	int size;                       /* request size in bytes */
	s32_t timeout;                /* # of ticks to wait */
	int rcode;                      /* expected return code */
};

typedef int (*pool_block_get_func_t)(struct k_mem_block *, struct k_mem_pool *,
				     int, s32_t);
typedef int (*pool_move_block_func_t)(struct k_mem_block *, struct k_mem_pool *);

static volatile int evidence;

static struct k_mem_block block_list[NUM_BLOCKS];
static struct k_mem_block helper_block;

static struct TEST_CASE get_set[] = {
	{ &block_list[0], &POOL_ID, 0, 0, 0 },
	{ &block_list[1], &POOL_ID, 1, 0, 0 },
	{ &block_list[2], &POOL_ID, 32, 0, 0 },
	{ &block_list[3], &POOL_ID, 64, 0, 0 },
	{ &block_list[4], &POOL_ID, 128, 0, 0 },
	{ &block_list[5], &POOL_ID, 256, 0, 0 },
	{ &block_list[6], &POOL_ID, 512, 0, 0 },
	{ &block_list[7], &POOL_ID, 1024, 0, 0 },
	{ &block_list[8], &POOL_ID, 2048, 0, -ENOMEM },
	{ &block_list[9], &POOL_ID, 4096, 0, -ENOMEM }
};

static struct TEST_CASE get_set2[] = {
	{ &block_list[0], &POOL_ID, 4096, 0, 0 },
	{ &block_list[1], &POOL_ID, 2048, 0, -ENOMEM },
	{ &block_list[2], &POOL_ID, 1024, 0, -ENOMEM },
	{ &block_list[3], &POOL_ID, 512, 0, -ENOMEM },
	{ &block_list[4], &POOL_ID, 256, 0, -ENOMEM }
};

static struct TEST_CASE getwt_set[] = {
	{ &block_list[0], &POOL_ID, 4096, TENTH_SECOND, 0 },
	{ &block_list[1], &POOL_ID, 2048, TENTH_SECOND, -EAGAIN },
	{ &block_list[2], &POOL_ID, 1024, TENTH_SECOND, -EAGAIN },
	{ &block_list[3], &POOL_ID, 512, TENTH_SECOND, -EAGAIN },
	{ &block_list[4], &POOL_ID, 256, TENTH_SECOND, -EAGAIN }
};

static struct TEST_CASE defrag[] = {
	{ &block_list[0], &POOL_ID, 64, 0, 0 },
	{ &block_list[1], &POOL_ID, 64, 0, 0 },
	{ &block_list[2], &POOL_ID, 64, 0, 0 },
	{ &block_list[3], &POOL_ID, 64, 0, 0 },
	{ &block_list[4], &POOL_ID, 256, 0, 0 },
	{ &block_list[5], &POOL_ID, 256, 0, 0 },
	{ &block_list[6], &POOL_ID, 256, 0, 0 },
	{ &block_list[7], &POOL_ID, 1024, 0, 0 },
	{ &block_list[8], &POOL_ID, 1024, 0, 0 },
	{ &block_list[9], &POOL_ID, 1024, 0, 0 }
};

/**
 *
 * @brief Compare the two blocks
 *
 * @return 0 if the same, non-zero if not the same
 */

int block_compare(struct k_mem_block *b1, struct k_mem_block *b2)
{
	char *p1 = (char *) b1;
	char *p2 = (char *) b2;
	int i;
	int diff = 0;

	for (i = 0; i < sizeof(struct k_mem_block); i++) {
		diff = p2[i] - p1[i];
		if (diff != 0) {
			break;
		}
	}

	return diff;
}

/**
 *
 * @brief Wrapper for k_mem_pool_alloc()
 *
 * @return k_mem_pool_alloc() return value
 */

int pool_block_get_func(struct k_mem_block *block, struct k_mem_pool *pool,
			int size, s32_t unused)
{
	ARG_UNUSED(unused);

	return k_mem_pool_alloc(pool, block, size, K_NO_WAIT);
}

/**
 *
 * @brief Wrapper for k_mem_pool_alloc(K_FOREVER)
 *
 * @return k_mem_pool_alloc() return value
 */

int pool_block_get_w_func(struct k_mem_block *block, struct k_mem_pool *pool,
			  int size, s32_t unused)
{
	ARG_UNUSED(unused);

	return k_mem_pool_alloc(pool, block, size, K_FOREVER);
}

/**
 *
 * @brief Wrapper for k_mem_pool_alloc(timeout)
 *
 * @return k_mem_pool_alloc(timeout) return value
 */

int pool_block_get_wt_func(struct k_mem_block *block, struct k_mem_pool *pool,
			   int size, s32_t timeout)
{
	return k_mem_pool_alloc(pool, block, size, timeout);
}

/**
 *
 * @brief Free any blocks allocated in the test set
 *
 * @return N/A
 */

void free_blocks(struct TEST_CASE *tests, int n_tests)
{
	int i;

	for (i = 0; i < n_tests; i++) {
		if (tests[i].rcode == 0) {
			k_mem_pool_free(tests[i].block);
		}
	}
}

/**
 *
 * @brief Perform the work of getting blocks
 *
 * @return TC_PASS on success, TC_FAIL on failure
 */

int pool_block_get_work(char *string, pool_block_get_func_t func,
			struct TEST_CASE *tests, int n_tests)
{
	int i;
	int rv;

	for (i = 0; i < n_tests; i++) {
		rv = func(tests[i].block, tests[i].pool_id, tests[i].size,
			  tests[i].timeout);
		if (rv != tests[i].rcode) {
			TC_ERROR("%s() expected %d, got %d\n"
				 "size: %d, timeout: %d\n", string, tests[i].rcode, rv,
				 tests[i].size, tests[i].timeout);
			return TC_FAIL;
		}
	}

	return TC_PASS;
}

/**
 *
 * @brief Test the k_mem_pool_alloc(K_NO_WAIT) API
 *
 * The pool is 4 k_b in size.
 *
 * @return TC_PASS on success, TC_FAIL on failure
 */

int pool_block_get_test(void)
{
	int rv;         /* return value from k_mem_pool_alloc() */
	int j;          /* loop counter */

	for (j = 0; j < 8; j++) {
		rv = pool_block_get_work("k_mem_pool_alloc", pool_block_get_func,
					 get_set, ARRAY_SIZE(get_set));
		if (rv != TC_PASS) {
			return TC_FAIL;
		}

		free_blocks(get_set, ARRAY_SIZE(get_set));

		rv = pool_block_get_work("k_mem_pool_alloc", pool_block_get_func,
					 get_set2, ARRAY_SIZE(get_set2));
		if (rv != TC_PASS) {
			return TC_FAIL;
		}

		free_blocks(get_set2, ARRAY_SIZE(get_set2));
	}

	return TC_PASS;
}

/**
 *
 * @brief Helper task to pool_block_get_timeout_test()
 *
 * @return N/A
 */

void helper_task(void)
{
	k_sem_take(&HELPER_SEM, K_FOREVER);

	k_sem_give(&REGRESS_SEM);
	k_mem_pool_free(&helper_block);
}

/**
 *
 * @brief Test k_mem_pool_alloc(timeout)
 *
 * @return TC_PASS on success, TC_FAIL on failure
 */

int pool_block_get_timeout_test(void)
{
	struct k_mem_block block;
	int rv;         /* return value from k_mem_pool_alloc() */
	int j;          /* loop counter */

	for (j = 0; j < 8; j++) {
		rv = pool_block_get_work("k_mem_pool_alloc", pool_block_get_wt_func,
					 getwt_set, ARRAY_SIZE(getwt_set));
		if (rv != TC_PASS) {
			return TC_FAIL;
		}

		free_blocks(getwt_set, ARRAY_SIZE(getwt_set));
	}

	rv = k_mem_pool_alloc(&POOL_ID, &helper_block, 3148, 5);
	if (rv != 0) {
		TC_ERROR("Failed to get size 3148 byte block from POOL_ID\n");
		return TC_FAIL;
	}

	rv = k_mem_pool_alloc(&POOL_ID, &block, 3148, K_NO_WAIT);
	if (rv != -ENOMEM) {
		TC_ERROR("Unexpectedly got size 3148 "
			 "byte block from POOL_ID\n");
		return TC_FAIL;
	}

	k_sem_give(&HELPER_SEM);    /* Activate helper_task */
	rv = k_mem_pool_alloc(&POOL_ID, &block, 3148, 20);
	if (rv != 0) {
		TC_ERROR("Failed to get size 3148 byte block from POOL_ID\n");
		return TC_FAIL;
	}

	rv = k_sem_take(&REGRESS_SEM, K_NO_WAIT);
	if (rv != 0) {
		TC_ERROR("Failed to get size 3148 "
			 "byte block within 20 ticks\n");
		return TC_FAIL;
	}

	k_mem_pool_free(&block);

	return TC_PASS;
}

/**
 *
 * pool_block_get_wait_test -
 *
 * @return TC_PASS on success, TC_FAIL on failure
 */

int pool_block_get_wait_test(void)
{
	int rv;

	rv = k_mem_pool_alloc(&POOL_ID, &block_list[0], 3000, K_FOREVER);
	if (rv != 0) {
		TC_ERROR("k_mem_pool_alloc(3000) expected %d, got %d\n", 0, rv);
		return TC_FAIL;
	}

	k_sem_give(&ALTERNATE_SEM);    /* Wake alternate_task */
	evidence = 0;
	rv = k_mem_pool_alloc(&POOL_ID, &block_list[1], 128, K_FOREVER);
	if (rv != 0) {
		TC_ERROR("k_mem_pool_alloc(128) expected %d, got %d\n", 0, rv);
		return TC_FAIL;
	}

	switch (evidence) {
	case 0:
		TC_ERROR("k_mem_pool_alloc(128) did not block!\n");
		return TC_FAIL;
	case 1:
		break;
	case 2:
	default:
		TC_ERROR("Rescheduling did not occur "
			 "after k_mem_pool_free()\n");
		return TC_FAIL;
	}

	k_mem_pool_free(&block_list[1]);

	return TC_PASS;
}

/**
 *
 * @brief Task responsible for defragmenting the pool POOL_ID
 *
 * @return N/A
 */

void defrag_task(void)
{
	k_sem_take(&DEFRAG_SEM, K_FOREVER);     /* Wait to be activated */

	k_mem_pool_defrag(&POOL_ID);

	k_sem_give(&REGRESS_SEM);   /* defrag_task is finished */
}

/**
 *
 * pool_defrag_test -
 *
 * @return TC_PASS on success, TC_FAIL on failure
 */

int pool_defrag_test(void)
{
	int rv;
	struct k_mem_block new_block;

	/* Get a bunch of blocks */

	rv = pool_block_get_work("k_mem_pool_alloc", pool_block_get_func,
				 defrag, ARRAY_SIZE(defrag));
	if (rv != TC_PASS) {
		return TC_FAIL;
	}


	k_sem_give(&DEFRAG_SEM);    /* Activate defrag_task */

	/*
	 * Block on getting another block from the pool.
	 * This will allow defrag_task to execute so that we can get some
	 * better code coverage.  500 ms is expected to more than sufficient
	 * time for defrag_task to finish.
	 */

	rv = k_mem_pool_alloc(&POOL_ID, &new_block, DEFRAG_BLK_TEST, 500);
	if (rv != -EAGAIN) {
		TC_ERROR("k_mem_pool_alloc() returned %d, not %d\n", rv,
			 -EAGAIN);
		return TC_FAIL;
	}

	rv = k_sem_take(&REGRESS_SEM, K_NO_WAIT);
	if (rv != 0) {
		TC_ERROR("defrag_task did not finish in allotted time!\n");
		return TC_FAIL;
	}

	/* Free the allocated blocks */

	free_blocks(defrag, ARRAY_SIZE(defrag));

	return TC_PASS;
}

/**
 *
 * @brief Alternate task in the test suite
 *
 * This routine runs at a lower priority than Regression_task().
 *
 * @return N/A
 */

void alternate_task(void)
{
	k_sem_take(&ALTERNATE_SEM, K_FOREVER);

	evidence = 1;

	k_mem_pool_free(&block_list[0]);

	evidence = 2;
}

/**
 *
 * @brief Test the k_malloc() and k_free() APIs
 *
 * The heap memory pool is 256 bytes in size, and thus has only 4 blocks
 * of 64 bytes or a single block of 256 bytes. (Each block has a lesser
 * amount of usable space, due to the hidden block descriptor info the
 * kernel adds at the start of any block allocated from this memory pool.)
 *
 * @return TC_PASS on success, TC_FAIL on failure
 */

int pool_malloc_test(void)
{
	char *block[4];
	int j;     /* loop counter */

	TC_PRINT("Testing k_malloc() and k_free() ...\n");

	/* allocate a large block (which consumes the entire pool buffer) */
	block[0] = k_malloc(150);
	if (block[0] == NULL) {
		TC_ERROR("150 byte allocation failed\n");
		return TC_FAIL;
	}

	/* ensure a small block can no longer be allocated */
	block[1] = k_malloc(16);
	if (block[1] != NULL) {
		TC_ERROR("16 byte allocation did not fail\n");
		return TC_FAIL;
	}

	/* return the large block */
	k_free(block[0]);

	/* allocate a small block (triggers block splitting)*/
	block[0] = k_malloc(16);
	if (block[0] == NULL) {
		TC_ERROR("16 byte allocation 0 failed\n");
		return TC_FAIL;
	}

	/* ensure a large block can no longer be allocated */
	block[1] = k_malloc(80);
	if (block[1] != NULL) {
		TC_ERROR("80 byte allocation did not fail\n");
		return TC_FAIL;
	}

	/* ensure all remaining small blocks can be allocated */
	for (j = 1; j < 4; j++) {
		block[j] = k_malloc(16);
		if (block[j] == NULL) {
			TC_ERROR("16 byte allocation %d failed\n", j);
			return TC_FAIL;
		}
	}

	/* ensure a small block can no longer be allocated */
	if (k_malloc(8) != NULL) {
		TC_ERROR("8 byte allocation did not fail\n");
		return TC_FAIL;
	}

	/* return the small blocks to pool in a "random" order */
	k_free(block[2]);
	k_free(block[0]);
	k_free(block[3]);
	k_free(block[1]);

	/* allocate large block (triggers autodefragmentation) */
	block[0] = k_malloc(100);
	if (block[0] == NULL) {
		TC_ERROR("100 byte allocation failed\n");
		return TC_FAIL;
	}

	/* ensure a small block can no longer be allocated */
	if (k_malloc(32) != NULL) {
		TC_ERROR("32 byte allocation did not fail\n");
		return TC_FAIL;
	}

	return TC_PASS;
}

/**
 *
 * @brief Main task in the test suite
 *
 * This is the entry point to the memory pool test suite.
 *
 * @return N/A
 */

void main(void)
{
	int tc_rC;     /* test case return code */

	TC_START("Test Memory Pool and Heap APIs");

	TC_PRINT("Testing k_mem_pool_alloc(K_NO_WAIT) ...\n");
	tc_rC = pool_block_get_test();
	if (tc_rC != TC_PASS) {
		goto done_tests;
	}

	TC_PRINT("Testing k_mem_pool_alloc(timeout) ...\n");
	tc_rC = pool_block_get_timeout_test();
	if (tc_rC != TC_PASS) {
		goto done_tests;
	}

	TC_PRINT("Testing k_mem_pool_alloc(K_FOREVER) ...\n");
	tc_rC = pool_block_get_wait_test();
	if (tc_rC != TC_PASS) {
		goto done_tests;
	}

	TC_PRINT("Testing k_mem_pool_defragment() ...\n");
	tc_rC = pool_defrag_test();
	if (tc_rC != TC_PASS) {
		goto done_tests;
	}

	tc_rC = pool_malloc_test();
	if (tc_rC != TC_PASS) {
		goto done_tests;
	}

done_tests:
	TC_END_RESULT(tc_rC);
	TC_END_REPORT(tc_rC);
}



K_THREAD_DEFINE(t_alternate, STACKSIZE, alternate_task, NULL, NULL, NULL,
		6, 0, K_NO_WAIT);

K_THREAD_DEFINE(t_defrag, STACKSIZE, defrag_task, NULL, NULL, NULL,
		7, 0, K_NO_WAIT);

K_THREAD_DEFINE(t_helper, STACKSIZE, helper_task, NULL, NULL, NULL,
		7, 0, K_NO_WAIT);
