/* pool.c - test microkernel memory pool APIs */

/*
 * Copyright (c) 2012-2014 Wind River Systems, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
DESCRIPTION
This modules tests the following memory pool routines:

  task_mem_pool_alloc(),
  task_mem_pool_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

typedef struct {
	struct k_block *block;    /* pointer to block data */
	kmemory_pool_t  poolId;   /* pool ID */
	int       size;     /* request size in bytes */
	int32_t   timeout;  /* # of ticks to wait */
	int       rcode;    /* expected return code */
} TEST_CASE;

typedef int (*poolBlockGetFunc_t)(struct k_block *, kmemory_pool_t, int, int32_t);
typedef int (*poolMoveBlockFunc_t)(struct k_block *, kmemory_pool_t);

static volatile int evidence = 0;

static struct k_block  blockList[NUM_BLOCKS];
static struct k_block  helperBlock;

static TEST_CASE getSet[] = {
	{&blockList[0], POOL_ID, 0, 0, RC_OK},
	{&blockList[1], POOL_ID, 1, 0, RC_OK},
	{&blockList[2], POOL_ID, 32, 0, RC_OK},
	{&blockList[3], POOL_ID, 64, 0, RC_OK},
	{&blockList[4], POOL_ID, 128, 0, RC_OK},
	{&blockList[5], POOL_ID, 256, 0, RC_OK},
	{&blockList[6], POOL_ID, 512, 0, RC_OK},
	{&blockList[7], POOL_ID, 1024, 0, RC_OK},
	{&blockList[8], POOL_ID, 2048, 0, RC_FAIL},
	{&blockList[9], POOL_ID, 4096, 0, RC_FAIL}
};

static TEST_CASE getSet2[] = {
	{&blockList[0], POOL_ID, 4096, 0, RC_OK},
	{&blockList[1], POOL_ID, 2048, 0, RC_FAIL},
	{&blockList[2], POOL_ID, 1024, 0, RC_FAIL},
	{&blockList[3], POOL_ID, 512, 0, RC_FAIL},
	{&blockList[4], POOL_ID, 256, 0, RC_FAIL}
};

static TEST_CASE getwtSet[] = {
	{&blockList[0], POOL_ID, 4096, TENTH_SECOND, RC_OK},
	{&blockList[1], POOL_ID, 2048, TENTH_SECOND, RC_TIME},
	{&blockList[2], POOL_ID, 1024, TENTH_SECOND, RC_TIME},
	{&blockList[3], POOL_ID, 512, TENTH_SECOND, RC_TIME},
	{&blockList[4], POOL_ID, 256, TENTH_SECOND, RC_TIME}
};

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

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

int blockCompare(struct k_block *b1, struct k_block *b2)
{
	char *p1 = (char *) b1;
	char *p2 = (char *) b2;
	int  i;
	int  diff;

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

	return diff;
}

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

int poolBlockGetFunc(struct k_block *block, kmemory_pool_t pool, int size,
					 int32_t unused)
{
	ARG_UNUSED(unused);

	return task_mem_pool_alloc(block, pool, size, TICKS_NONE);
}

/**
 *
 * @brief Wrapper for task_mem_pool_alloc(TICKS_UNLIMITED)
 *
 * @return task_mem_pool_alloc() return value
 */

int poolBlockGetWFunc(struct k_block *block, kmemory_pool_t pool, int size,
					  int32_t unused)
{
	ARG_UNUSED(unused);

	return task_mem_pool_alloc(block, pool, size, TICKS_UNLIMITED);
}

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

int poolBlockGetWTFunc(struct k_block *block, kmemory_pool_t pool,
					   int size, int32_t timeout)
{
	return task_mem_pool_alloc(block, pool, size, timeout);
}

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

void freeBlocks(TEST_CASE *tests, int nTests)
{
	int  i;

	for (i = 0; i < nTests; i++) {
		if (tests[i].rcode == RC_OK) {
			task_mem_pool_free(tests[i].block);
		}
	}
}

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

int poolBlockGetWork(char *string, poolBlockGetFunc_t func,
					 TEST_CASE *tests, int nTests)
{
	int  i;
	int  rv;

	for (i = 0; i < nTests; i++) {
		rv = func(tests[i].block, tests[i].poolId, 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 task_mem_pool_alloc(TICKS_NONE) API
 *
 * The pool is 4 kB in size.
 *
 * @return TC_PASS on success, TC_FAIL on failure
 */

int poolBlockGetTest(void)
{
	int  rv;   /* return value from task_mem_pool_alloc() */
	int  j;    /* loop counter */

	for (j = 0; j < 8; j++) {
		rv = poolBlockGetWork("task_mem_pool_alloc", poolBlockGetFunc,
							  getSet, ARRAY_SIZE(getSet));
		if (rv != TC_PASS) {
			return TC_FAIL;
		}

		freeBlocks(getSet, ARRAY_SIZE(getSet));

		rv = poolBlockGetWork("task_mem_pool_alloc", poolBlockGetFunc,
							  getSet2, ARRAY_SIZE(getSet2));
		if (rv != TC_PASS) {
			return TC_FAIL;
		}

		freeBlocks(getSet2, ARRAY_SIZE(getSet2));
	}

	return TC_PASS;
}

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

void HelperTask(void)
{
	task_sem_take(HELPER_SEM, TICKS_UNLIMITED);

	task_sem_give(REGRESS_SEM);
	task_mem_pool_free(&helperBlock);
}

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

int poolBlockGetTimeoutTest(void)
{
	struct k_block  block;
	int  rv;   /* return value from task_mem_pool_alloc() */
	int  j;    /* loop counter */

	for (j = 0; j < 8; j++) {
		rv = poolBlockGetWork("task_mem_pool_alloc", poolBlockGetWTFunc,
							  getwtSet, ARRAY_SIZE(getwtSet));
		if (rv != TC_PASS) {
			return TC_FAIL;
		}

		freeBlocks(getwtSet, ARRAY_SIZE(getwtSet));
	}

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

	rv = task_mem_pool_alloc(&block, POOL_ID, 3148, TICKS_NONE);
	if (rv != RC_FAIL) {
		TC_ERROR("Unexpectedly got size 3148 byte block from POOL_ID\n");
		return TC_FAIL;
	}

	task_sem_give(HELPER_SEM);    /* Activate HelperTask */
	rv = task_mem_pool_alloc(&block, POOL_ID, 3148, 20);
	if (rv != RC_OK) {
		TC_ERROR("Failed to get size 3148 byte block from POOL_ID\n");
		return TC_FAIL;
	}

	rv = task_sem_take(REGRESS_SEM, TICKS_NONE);
	if (rv != RC_OK) {
		TC_ERROR("Failed to get size 3148 byte block within 20 ticks\n");
		return TC_FAIL;
	}

	task_mem_pool_free(&block);

	return TC_PASS;
}

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

int poolBlockGetWaitTest(void)
{
	int  rv;

	rv = task_mem_pool_alloc(&blockList[0], POOL_ID, 3000, TICKS_UNLIMITED);
	if (rv != RC_OK) {
		TC_ERROR("task_mem_pool_alloc(3000) expected %d, got %d\n", RC_OK, rv);
		return TC_FAIL;
	}

	task_sem_give(ALTERNATE_SEM);    /* Wake AlternateTask */
	evidence = 0;
	rv = task_mem_pool_alloc(&blockList[1], POOL_ID, 128, TICKS_UNLIMITED);
	if (rv != RC_OK) {
		TC_ERROR("task_mem_pool_alloc(128) expected %d, got %d\n", RC_OK, rv);
		return TC_FAIL;
	}

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

	task_mem_pool_free(&blockList[1]);

	return TC_PASS;
}

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

void DefragTask(void)
{
	task_sem_take(DEFRAG_SEM, TICKS_UNLIMITED);     /* Wait to be activated */

	task_mem_pool_defragment(POOL_ID);

	task_sem_give(REGRESS_SEM);   /* DefragTask is finished */
}

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

int poolDefragTest(void)
{
	int      rv;
	struct k_block  newBlock;

	/* Get a bunch of blocks */

	rv = poolBlockGetWork("task_mem_pool_alloc", poolBlockGetFunc,
						  defrag, ARRAY_SIZE(defrag));
	if (rv != TC_PASS) {
		return TC_FAIL;
	}


	task_sem_give(DEFRAG_SEM);    /* Activate DefragTask */

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

	rv = task_mem_pool_alloc(&newBlock, POOL_ID, DEFRAG_BLK_TEST, 50);
	if (rv != RC_TIME) {
		TC_ERROR("task_mem_pool_alloc() returned %d, not %d\n", rv, RC_TIME);
		return TC_FAIL;
	}

	rv = task_sem_take(REGRESS_SEM, TICKS_NONE);
	if (rv != RC_OK) {
		TC_ERROR("DefragTask did not finish in allotted time!\n");
		return TC_FAIL;
	}

	/* Free the allocated blocks */

	freeBlocks(defrag, ARRAY_SIZE(defrag));

	return TC_PASS;
}

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

void AlternateTask(void)
{
	task_sem_take(ALTERNATE_SEM, TICKS_UNLIMITED);

	evidence = 1;

	task_mem_pool_free(&blockList[0]);

	evidence = 2;
}

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

void RegressionTask(void)
{
	int  tcRC;    /* test case return code */

	TC_START("Test Microkernel Memory Pools");

	TC_PRINT("Testing task_mem_pool_alloc(TICKS_NONE) ...\n");
	tcRC = poolBlockGetTest();
	if (tcRC != TC_PASS) {
		goto doneTests;
	}

	TC_PRINT("Testing task_mem_pool_alloc(timeout) ...\n");
	tcRC = poolBlockGetTimeoutTest();
	if (tcRC != TC_PASS) {
		goto doneTests;
	}

	TC_PRINT("Testing task_mem_pool_alloc(TICKS_UNLIMITED) ...\n");
	tcRC = poolBlockGetWaitTest();
	if (tcRC != TC_PASS) {
		goto doneTests;
	}

	TC_PRINT("Testing task_mem_pool_defragment() ...\n");
	tcRC = poolDefragTest();
	if (tcRC != TC_PASS) {
		goto doneTests;
	}

doneTests:
	TC_END_RESULT(tcRC);
	TC_END_REPORT(tcRC);
}
