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

/**
 * @addtogroup t_mpool
 * @{
 * @defgroup t_mpool_threadsafe test_mpool_threadsafe
 * @brief TestPurpose: verify API thread safe in multi-threads environment.
 * @details This's an extensive test. Multiple threads in same priority are
 * created, with time slice scheduling enabled in a very small slicing size:
 * 1 millisecond (refer to prj.conf).
 * All threads share a same entry function to invoke same kernel APIs.
 * Unless explicitly stated, kernel APIs are supposed to be thread safe.
 * Expect all threads should complete and exit the entry function normally.
 *
 * NOTE:
 * # API functionality is not TESTPOINT here. When invoked by multiple
 * threads, each API following its own behavior specification returns either
 * success or failure. Like, memory allocation successful or fail is pending on
 * whether any free memory blocks are available at the moment when the API is
 * invoked by a thread just got scheduled in.
 * # For kernel object APIs, more than one instance of the same object type are
 * created. Like, 4 threads operating on 2 instances, the test would cover the
 * kernel's code branches that handling "multiple threads accessing to a same
 * instance" and that handling "multiple instances serving simultaneously".
 * # The test adopts a slicing size in 1 millisecond. Thread safe theoretically
 * should work in a smaller slicing size. But this does not intent to stress
 * test that.
 * @}
 */

#include <ztest.h>
#include <atomic.h>
#define THREAD_NUM 4
#define STACK_SIZE (512 + CONFIG_TEST_EXTRA_STACKSIZE)
#define POOL_NUM 2
#define TIMEOUT 200
#define BLK_SIZE_MIN 4
#define BLK_SIZE_MAX 16
#define BLK_NUM_MIN 8
#define BLK_NUM_MAX 2
#define BLK_ALIGN BLK_SIZE_MIN

K_MEM_POOL_DEFINE(mpool1, BLK_SIZE_MIN, BLK_SIZE_MAX, BLK_NUM_MAX, BLK_ALIGN);
K_MEM_POOL_DEFINE(mpool2, BLK_SIZE_MIN, BLK_SIZE_MAX, BLK_NUM_MAX, BLK_ALIGN);
static char __noinit __stack tstack[THREAD_NUM][STACK_SIZE];
static struct k_mem_pool *pools[POOL_NUM] = {&mpool1, &mpool2};
static struct k_sem sync_sema;
static atomic_t pool_id;

/* thread entry simply invoke the APIs*/
static void tmpool_api(void *p1, void *p2, void *p3)
{
	struct k_mem_block block[BLK_NUM_MIN];
	int ret[BLK_NUM_MIN];
	struct k_mem_pool *pool = pools[atomic_inc(&pool_id) % POOL_NUM];

	memset(block, 0, sizeof(block));

	for (int i = 0; i < 4; i++) {
		ret[i] = k_mem_pool_alloc(pool, &block[i], BLK_SIZE_MIN,
			TIMEOUT);
	}
	ret[4] = k_mem_pool_alloc(pool, &block[4], BLK_SIZE_MAX, TIMEOUT);
	for (int i = 0; i < 5; i++) {
		if (ret[i] == 0) {
			k_mem_pool_free(&block[i]);
		}
	}
	k_mem_pool_defrag(pool);

	k_sem_give(&sync_sema);
}

/* test cases*/
void test_mpool_threadsafe(void)
{
	k_tid_t tid[THREAD_NUM];

	k_sem_init(&sync_sema, 0, THREAD_NUM);

	/* create multiple threads to invoke same memory pool APIs*/
	for (int i = 0; i < THREAD_NUM; i++) {
		tid[i] = k_thread_spawn(tstack[i], STACK_SIZE,
			tmpool_api, NULL, NULL, NULL,
			K_PRIO_PREEMPT(1), 0, 0);
	}
	/* TESTPOINT: all threads complete and exit the entry function*/
	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]);
	}
}
