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

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

#define THREAD_NUM 3
#define STACK_SIZE (512 + CONFIG_TEST_EXTRA_STACK_SIZE)

K_MEM_SLAB_DEFINE(mslab1, BLK_SIZE, BLK_NUM, 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 void *block_ok;

/*thread entry*/
void tmslab_alloc_wait_timeout(void *p1, void *p2, void *p3)
{
	void *block;

	zassert_true(k_mem_slab_alloc(&mslab1, &block, TIMEOUT) == -EAGAIN,
		     NULL);
	k_sem_give(&sync_sema);
}

void tmslab_alloc_wait_ok(void *p1, void *p2, void *p3)
{
	zassert_true(k_mem_slab_alloc(&mslab1, &block_ok, TIMEOUT) == 0, NULL);
	k_sem_give(&sync_sema);
}

/*test cases*/
/**
 * @brief Verify alloc with multiple threads
 *
 * @details The test allocates all blocks of memory slab and
 * then spawns 3 threads with lowest priority and 2 more with
 * same priority higher than first thread with delay 10ms and
 * 20ms. Checks the behavior of alloc when requested by multiple
 * threads
 *
 * @ingroup kernel_memory_slab_tests
 *
 * @see k_mem_slab_alloc()
 * @see k_mem_slab_free()
 */
void test_mslab_alloc_wait_prio(void)
{
	void *block[BLK_NUM];
	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; i++) {
		zassert_equal(k_mem_slab_alloc(&mslab1, &block[i], K_NO_WAIT),
			      0, NULL);
	}

	/**
	 * TESTPOINT: Any number of threads may wait on an empty memory slab
	 * simultaneously; when a memory block becomes available, it is given to
	 * the highest-priority thread that has waited the longest.
	 */
	/**
	 * TESTPOINT: If all the blocks are currently in use, 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,
				 tmslab_alloc_wait_timeout, NULL, NULL, NULL,
				 K_PRIO_PREEMPT(1), 0, K_NO_WAIT);
	/*the highest-priority thread that has waited the longest*/
	tid[1] = k_thread_create(&tdata[1], tstack[1], STACK_SIZE,
				 tmslab_alloc_wait_ok, NULL, NULL, NULL,
				 K_PRIO_PREEMPT(0), 0, K_MSEC(10));
	/*the highest-priority thread that has waited shorter*/
	tid[2] = k_thread_create(&tdata[2], tstack[2], STACK_SIZE,
				 tmslab_alloc_wait_timeout, NULL, NULL, NULL,
				 K_PRIO_PREEMPT(0), 0, K_MSEC(20));
	/*relinquish CPU for above threads to start */
	k_msleep(30);
	/*free one block, expected to unblock thread "tid[1]"*/
	k_mem_slab_free(&mslab1, &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_slab_free(&mslab1, &block_ok);
	for (int i = 1; i < BLK_NUM; i++) {
		k_mem_slab_free(&mslab1, &block[i]);
	}
}
