/*
 * 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 is 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 K_THREAD_STACK_ARRAY_DEFINE(tstack, THREAD_NUM, STACK_SIZE);
static struct k_thread tdata[THREAD_NUM];
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_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_create(&tdata[i], 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]);
	}
}
