/*
 * Copyright (c) 2016 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @addtogroup t_mpool
 * @{
 * @defgroup t_mpool_concept test_mpool_concept
 * @brief TestPurpose: verify memory pool concepts.
 * @details All TESTPOINTs extracted from kernel documentation.
 * TESTPOINTs cover testable kernel behaviors that preserve across internal
 * implementation change or kernel version change.
 * As a black-box test, TESTPOINTs do not cover internal operations.
 *
 * TESTPOINTs duplicated to <kernel.h> are covered in API test:
 * - TESTPOINT: ensure that all memory blocks in the buffer are similarly
 * aligned to this boundary
 * - TESTPOINT: Following a successful allocation, the data field of the block
 * descriptor supplied by the thread indicates the starting address of the
 * memory block
 * - TESTPOINT: memory pool blocks can be recursively partitioned into quarters
 * until blocks of the minimum size are obtained
 * - TESTPOINT: if a suitable block can't be created, the allocation request
 * fails
 *
 * TESTPOINTs related to kconfig are covered in kconfig test:
 * - TESTPOINT: If the block set does not contain a free block, the memory pool
 * attempts to create one automatically by splitting a free block of a larger
 * size or by merging free blocks of smaller sizes
 *
 * TESTPOINTS related to multiple instances are covered in re-entrance test:
 * - TESTPOINT: More than one memory pool can be defined, if needed. For
 * example, different applications can utilize different memory pools
 * @}
 */

#include <ztest.h>
#include "test_mpool.h"

#define THREAD_NUM 3
K_MEM_POOL_DEFINE(mpool1, BLK_SIZE_MIN, BLK_SIZE_MAX, BLK_NUM_MAX, BLK_ALIGN);

static K_THREAD_STACK_ARRAY_DEFINE(tstack, THREAD_NUM, STACK_SIZE);
static struct k_thread tdata[THREAD_NUM];
static struct k_sem sync_sema;
static struct k_mem_block block_ok;

/*thread entry*/
void tmpool_alloc_wait_timeout(void *p1, void *p2, void *p3)
{
	struct k_mem_block block;

	zassert_true(k_mem_pool_alloc(&mpool1, &block, BLK_SIZE_MIN,
		TIMEOUT) == -EAGAIN, NULL);
	k_sem_give(&sync_sema);
}

void tmpool_alloc_wait_ok(void *p1, void *p2, void *p3)
{
	zassert_true(k_mem_pool_alloc(&mpool1, &block_ok, BLK_SIZE_MIN,
		TIMEOUT) == 0, NULL);
	k_sem_give(&sync_sema);
}

/*test cases*/
void test_mpool_alloc_wait_prio(void)
{
	struct k_mem_block block[BLK_NUM_MIN];
	k_tid_t tid[THREAD_NUM];

	k_sem_init(&sync_sema, 0, THREAD_NUM);
	/*allocated up all blocks*/
	for (int i = 0; i < BLK_NUM_MIN; i++) {
		zassert_true(k_mem_pool_alloc(&mpool1, &block[i], BLK_SIZE_MIN,
			K_NO_WAIT) == 0, NULL);
	}

	/**
	 * TESTPOINT: when a suitable memory block becomes available, it is
	 * given to the highest-priority thread that has waited the longest
	 */
	/**
	 * TESTPOINT: If a block of the desired size is unavailable, a thread
	 * can optionally wait for one to become available
	 */
	/*the low-priority thread*/
	tid[0] = k_thread_create(&tdata[0], tstack[0], STACK_SIZE,
		tmpool_alloc_wait_timeout, NULL, NULL, NULL,
		K_PRIO_PREEMPT(1), 0, 0);
	/*the highest-priority thread that has waited the longest*/
	tid[1] = k_thread_create(&tdata[1], tstack[1], STACK_SIZE,
		tmpool_alloc_wait_ok, NULL, NULL, NULL,
		K_PRIO_PREEMPT(0), 0, 10);
	/*the highest-priority thread that has waited shorter*/
	tid[2] = k_thread_create(&tdata[2], tstack[2], STACK_SIZE,
		tmpool_alloc_wait_timeout, NULL, NULL, NULL,
		K_PRIO_PREEMPT(0), 0, 20);
	/*relinquish CPU for above threads to start */
	k_sleep(30);
	/*free one block, expected to unblock thread "tid[1]"*/
	k_mem_pool_free(&block[0]);
	/*wait for all threads exit*/
	for (int i = 0; i < THREAD_NUM; i++) {
		k_sem_take(&sync_sema, K_FOREVER);
	}

	/*test case tear down*/
	for (int i = 0; i < THREAD_NUM; i++) {
		k_thread_abort(tid[i]);
	}
	k_mem_pool_free(&block_ok);
	for (int i = 1; i < BLK_NUM_MIN; i++) {
		k_mem_pool_free(&block[i]);
	}
}
