/*
 * Copyright (c) 2012-2016 Wind River Systems, Inc.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @file
 * @brief Test kernel mutex APIs
 *
 *
 * This module demonstrates the kernel's priority inheritance algorithm.
 * A thread that owns a mutex is promoted to the priority level of the
 * highest-priority thread attempting to lock the mutex.
 *
 * In addition, recursive locking capabilities and the use of a private mutex
 * are also tested.
 *
 * This module tests the following mutex routines:
 *
 *    sys_mutex_lock
 *    sys_mutex_unlock
 *
 * Timeline for priority inheritance testing:
 *   - 0.0  sec: thread_05, thread_06, thread_07, thread_08, thread_09, sleep
 *             : main thread takes mutex_1 then sleeps
 *   - 0.0  sec: thread_11 sleeps
 *   - 0.5  sec: thread_09 wakes and waits on mutex_1
 *   - 1.0  sec: main thread (@ priority 9) takes mutex_2 then sleeps
 *   - 1.5  sec: thread_08 wakes and waits on mutex_2
 *   - 2.0  sec: main thread (@ priority 8) takes mutex_3 then sleeps
 *   - 2.5  sec: thread_07 wakes and waits on mutex_3
 *   - 3.0  sec: main thread (@ priority 7) takes mutex_4 then sleeps
 *   - 3.5  sec: thread_05 wakes and waits on mutex_4
 *   - 3.5  sec: thread_11 wakes and waits on mutex_3
 *   - 3.75 sec: thread_06 wakes and waits on mutex_4
 *   - 4.0  sec: main thread wakes (@ priority 5) then sleeps
 *   - 4.5  sec: thread_05 times out
 *   - 5.0  sec: main thread wakes (@ priority 6) then gives mutex_4
 *             : main thread (@ priority 7) sleeps
 *   - 5.5  sec: thread_07 times out on mutex_3
 *   - 6.0  sec: main thread (@ priority 8) gives mutex_3
 *             : main thread (@ priority 8) gives mutex_2
 *             : main thread (@ priority 9) gives mutex_1
 *             : main thread (@ priority 10) sleeps
 */

#include <zephyr/tc_util.h>
#include <zephyr/kernel.h>
#include <zephyr/ztest.h>
#include <zephyr/sys/mutex.h>

#define STACKSIZE (512 + CONFIG_TEST_EXTRA_STACK_SIZE)

static ZTEST_DMEM int tc_rc = TC_PASS;         /* test case return code */

ZTEST_BMEM SYS_MUTEX_DEFINE(private_mutex);


ZTEST_BMEM SYS_MUTEX_DEFINE(mutex_1);
ZTEST_BMEM SYS_MUTEX_DEFINE(mutex_2);
ZTEST_BMEM SYS_MUTEX_DEFINE(mutex_3);
ZTEST_BMEM SYS_MUTEX_DEFINE(mutex_4);

#ifdef CONFIG_USERSPACE
static SYS_MUTEX_DEFINE(no_access_mutex);
#endif
static ZTEST_BMEM SYS_MUTEX_DEFINE(not_my_mutex);
static ZTEST_BMEM SYS_MUTEX_DEFINE(bad_count_mutex);

#ifdef CONFIG_USERSPACE
#define ZTEST_USER_OR_NOT ZTEST_USER
#else
#define ZTEST_USER_OR_NOT ZTEST
#endif

#ifdef CONFIG_USERSPACE
#define PARTICIPANT_THREAD_OPTIONS (K_USER | K_INHERIT_PERMS)
#else
#define PARTICIPANT_THREAD_OPTIONS (0)
#endif

#define DEFINE_PARTICIPANT_THREAD(id)                               \
		K_THREAD_STACK_DEFINE(thread_##id##_stack_area, STACKSIZE); \
		struct k_thread thread_##id##_thread_data;                  \
		k_tid_t thread_##id##_tid;

#define CREATE_PARTICIPANT_THREAD(id, pri)                                     \
		k_thread_create(&thread_##id##_thread_data, thread_##id##_stack_area,  \
			K_THREAD_STACK_SIZEOF(thread_##id##_stack_area),                   \
			(k_thread_entry_t)thread_##id,                                     \
			NULL, NULL, NULL,                                                  \
			pri, PARTICIPANT_THREAD_OPTIONS, K_FOREVER);
#define START_PARTICIPANT_THREAD(id) k_thread_start(&(thread_##id##_thread_data));
#define JOIN_PARTICIPANT_THREAD(id) k_thread_join(&(thread_##id##_thread_data), K_FOREVER);

/**
 *
 * thread_05 -
 *
 */

void thread_05(void)
{
	int rv;

	k_sleep(K_MSEC(3500));

	/* Wait and boost owner priority to 5 */
	rv = sys_mutex_lock(&mutex_4, K_SECONDS(1));
	if (rv != -EAGAIN) {
		tc_rc = TC_FAIL;
		TC_ERROR("Failed to timeout on mutex %p\n", &mutex_4);
		return;
	}
}


/**
 *
 * thread_06 -
 *
 */

void thread_06(void)
{
	int rv;

	k_sleep(K_MSEC(3750));

	/*
	 * Wait for the mutex.  There is a higher priority level thread waiting
	 * on the mutex, so request will not immediately contribute to raising
	 * the priority of the owning thread (main thread).  When thread_05
	 * times out this thread will become the highest priority waiting
	 * thread. The priority of the owning thread (main thread) will not
	 * drop back to 7, but will instead drop to 6.
	 */

	rv = sys_mutex_lock(&mutex_4, K_SECONDS(2));
	if (rv != 0) {
		tc_rc = TC_FAIL;
		TC_ERROR("Failed to take mutex %p\n", &mutex_4);
		return;
	}

	sys_mutex_unlock(&mutex_4);
}

/**
 *
 * thread_07 -
 *
 */

void thread_07(void)
{
	int rv;

	k_sleep(K_MSEC(2500));

	/*
	 * Wait and boost owner priority to 7.  While waiting, another thread of
	 * a very low priority level will also wait for the mutex.  thread_07 is
	 * expected to time out around the 5.5 second mark.  When it times out,
	 * thread_11 will become the only waiting thread for this mutex and the
	 * priority of the owning main thread will drop to 8.
	 */

	rv = sys_mutex_lock(&mutex_3, K_SECONDS(3));
	if (rv != -EAGAIN) {
		tc_rc = TC_FAIL;
		TC_ERROR("Failed to timeout on mutex %p\n", &mutex_3);
		return;
	}

}

/**
 *
 * thread_08 -
 *
 */

void thread_08(void)
{
	int rv;

	k_sleep(K_MSEC(1500));

	/* Wait and boost owner priority to 8 */
	rv = sys_mutex_lock(&mutex_2, K_FOREVER);
	if (rv != 0) {
		tc_rc = TC_FAIL;
		TC_ERROR("Failed to take mutex %p\n", &mutex_2);
		return;
	}

	sys_mutex_unlock(&mutex_2);
}

/**
 *
 * thread_09 -
 *
 */

void thread_09(void)
{
	int rv;

	k_sleep(K_MSEC(500));	/* Allow lower priority thread to run */

	/*<mutex_1> is already locked. */
	rv = sys_mutex_lock(&mutex_1, K_NO_WAIT);
	if (rv != -EBUSY) {	/* This attempt to lock the mutex */
		/* should not succeed. */
		tc_rc = TC_FAIL;
		TC_ERROR("Failed to NOT take locked mutex %p\n", &mutex_1);
		return;
	}

	/* Wait and boost owner priority to 9 */
	rv = sys_mutex_lock(&mutex_1, K_FOREVER);
	if (rv != 0) {
		tc_rc = TC_FAIL;
		TC_ERROR("Failed to take mutex %p\n", &mutex_1);
		return;
	}

	sys_mutex_unlock(&mutex_1);
}

/**
 *
 * thread_11 -
 *
 */

void thread_11(void)
{
	int rv;

	k_sleep(K_MSEC(3500));
	rv = sys_mutex_lock(&mutex_3, K_FOREVER);
	if (rv != 0) {
		tc_rc = TC_FAIL;
		TC_ERROR("Failed to take mutex %p\n", &mutex_2);
		return;
	}
	sys_mutex_unlock(&mutex_3);
}

K_THREAD_STACK_DEFINE(thread_12_stack_area, STACKSIZE);
struct k_thread thread_12_thread_data;
extern void thread_12(void);



DEFINE_PARTICIPANT_THREAD(05);
DEFINE_PARTICIPANT_THREAD(06);
DEFINE_PARTICIPANT_THREAD(07);
DEFINE_PARTICIPANT_THREAD(08);
DEFINE_PARTICIPANT_THREAD(09);
DEFINE_PARTICIPANT_THREAD(11);

void create_participant_threads(void)
{
	CREATE_PARTICIPANT_THREAD(05, 5);
	CREATE_PARTICIPANT_THREAD(06, 6);
	CREATE_PARTICIPANT_THREAD(07, 7);
	CREATE_PARTICIPANT_THREAD(08, 8);
	CREATE_PARTICIPANT_THREAD(09, 9);
	CREATE_PARTICIPANT_THREAD(11, 11);
}

void start_participant_threads(void)
{
	START_PARTICIPANT_THREAD(05);
	START_PARTICIPANT_THREAD(06);
	START_PARTICIPANT_THREAD(07);
	START_PARTICIPANT_THREAD(08);
	START_PARTICIPANT_THREAD(09);
	START_PARTICIPANT_THREAD(11);
}

void join_participant_threads(void)
{
	JOIN_PARTICIPANT_THREAD(05);
	JOIN_PARTICIPANT_THREAD(06);
	JOIN_PARTICIPANT_THREAD(07);
	JOIN_PARTICIPANT_THREAD(08);
	JOIN_PARTICIPANT_THREAD(09);
	JOIN_PARTICIPANT_THREAD(11);
}

/**
 *
 * @brief Main thread to test thread_mutex_xxx interfaces
 *
 * This thread will lock on mutex_1, mutex_2, mutex_3 and mutex_4. It later
 * recursively locks private_mutex, releases it, then re-locks it.
 *
 */

ZTEST_USER_OR_NOT(mutex_complex, test_mutex)
{
	create_participant_threads();
	start_participant_threads();
	/*
	 * Main thread(test_main) priority was 10 but ztest thread runs at
	 * priority -1. To run the test smoothly make both main and ztest
	 * threads run at same priority level.
	 */
	k_thread_priority_set(k_current_get(), 10);

	int rv;
	int i;
	struct sys_mutex *mutexes[4] = { &mutex_1, &mutex_2, &mutex_3,
					 &mutex_4 };
	struct sys_mutex *givemutex[3] = { &mutex_3, &mutex_2, &mutex_1 };
	int priority[4] = { 9, 8, 7, 5 };
	int droppri[3] = { 8, 8, 9 };

	PRINT_LINE;

	/*
	 * 1st iteration: Take mutex_1; thread_09 waits on mutex_1
	 * 2nd iteration: Take mutex_2: thread_08 waits on mutex_2
	 * 3rd iteration: Take mutex_3; thread_07 waits on mutex_3
	 * 4th iteration: Take mutex_4; thread_05 waits on mutex_4
	 */

	for (i = 0; i < 4; i++) {
		rv = sys_mutex_lock(mutexes[i], K_NO_WAIT);
		zassert_equal(rv, 0, "Failed to lock mutex %p\n", mutexes[i]);
		k_sleep(K_SECONDS(1));

		rv = k_thread_priority_get(k_current_get());
		zassert_equal(rv, priority[i], "expected priority %d, not %d\n",
			      priority[i], rv);

		/* Catch any errors from other threads */
		zassert_equal(tc_rc, TC_PASS);
	}

	/* ~ 4 seconds have passed */

	TC_PRINT("Done LOCKING!  Current priority = %d\n",
		 k_thread_priority_get(k_current_get()));

	k_sleep(K_SECONDS(1));       /* thread_05 should time out */

	/* ~ 5 seconds have passed */

	rv = k_thread_priority_get(k_current_get());
	zassert_equal(rv, 6, "%s timed out and out priority should drop.\n",
		      "thread_05");
	zassert_equal(rv, 6, "Expected priority %d, not %d\n", 6, rv);

	sys_mutex_unlock(&mutex_4);
	rv = k_thread_priority_get(k_current_get());
	zassert_equal(rv, 7, "Gave %s and priority should drop.\n", "mutex_4");
	zassert_equal(rv, 7, "Expected priority %d, not %d\n", 7, rv);

	k_sleep(K_SECONDS(1));       /* thread_07 should time out */

	/* ~ 6 seconds have passed */

	for (i = 0; i < 3; i++) {
		rv = k_thread_priority_get(k_current_get());
		zassert_equal(rv, droppri[i], "Expected priority %d, not %d\n",
			      droppri[i], rv);
		sys_mutex_unlock(givemutex[i]);

		zassert_equal(tc_rc, TC_PASS);
	}

	rv = k_thread_priority_get(k_current_get());
	zassert_equal(rv, 10, "Expected priority %d, not %d\n", 10, rv);

	k_sleep(K_SECONDS(1));     /* Give thread_11 time to run */

	zassert_equal(tc_rc, TC_PASS);

	/* test recursive locking using a private mutex */

	TC_PRINT("Testing recursive locking\n");

	rv = sys_mutex_lock(&private_mutex, K_NO_WAIT);
	zassert_equal(rv, 0, "Failed to lock private mutex");

	rv = sys_mutex_lock(&private_mutex, K_NO_WAIT);
	zassert_equal(rv, 0, "Failed to recursively lock private mutex");

	/* Start thread */
	k_thread_create(&thread_12_thread_data, thread_12_stack_area, STACKSIZE,
			(k_thread_entry_t)thread_12, NULL, NULL, NULL,
			K_PRIO_PREEMPT(12), PARTICIPANT_THREAD_OPTIONS, K_NO_WAIT);
	k_sleep(K_MSEC(1));     /* Give thread_12 a chance to block on the mutex */

	sys_mutex_unlock(&private_mutex);
	sys_mutex_unlock(&private_mutex); /* thread_12 should now have lock */

	rv = sys_mutex_lock(&private_mutex, K_NO_WAIT);
	zassert_equal(rv, -EBUSY, "Unexpectedly got lock on private mutex");

	rv = sys_mutex_lock(&private_mutex, K_SECONDS(1));
	zassert_equal(rv, 0, "Failed to re-obtain lock on private mutex");

	sys_mutex_unlock(&private_mutex);
	join_participant_threads();
	TC_PRINT("Recursive locking tests successful\n");
}

/* We deliberately disable userspace, even on platforms that
 * support it, so that the alternate implementation of sys_mutex
 * (which is just a very thin wrapper to k_mutex) is exercised.
 * This requires us to not attempt to start the tests in user
 * mode, as this will otherwise fail an assertion in the thread code.
 */
ZTEST(mutex_complex, test_supervisor_access)
{
	int rv;

#ifdef CONFIG_USERSPACE
	/* coverage for get_k_mutex checks */
	rv = sys_mutex_lock((struct sys_mutex *)NULL, K_NO_WAIT);
	zassert_true(rv == -EINVAL, "accepted bad mutex pointer");
	rv = sys_mutex_lock((struct sys_mutex *)k_current_get(), K_NO_WAIT);
	zassert_true(rv == -EINVAL, "accepted object that was not a mutex");
	rv = sys_mutex_unlock((struct sys_mutex *)NULL);
	zassert_true(rv == -EINVAL, "accepted bad mutex pointer");
	rv = sys_mutex_unlock((struct sys_mutex *)k_current_get());
	zassert_true(rv == -EINVAL, "accepted object that was not a mutex");
#endif /* CONFIG_USERSPACE */

	rv = sys_mutex_unlock(&not_my_mutex);
	zassert_true(rv == -EPERM, "unlocked a mutex that wasn't owner");
	rv = sys_mutex_unlock(&bad_count_mutex);
	zassert_true(rv == -EINVAL, "mutex wasn't locked");
}

ZTEST_USER_OR_NOT(mutex_complex, test_user_access)
{
#ifdef CONFIG_USERSPACE
	int rv;

	rv = sys_mutex_lock(&no_access_mutex, K_NO_WAIT);
	zassert_true(rv == -EACCES, "accessed mutex not in memory domain");
	rv = sys_mutex_unlock(&no_access_mutex);
	zassert_true(rv == -EACCES, "accessed mutex not in memory domain");
#else
	ztest_test_skip();
#endif /* CONFIG_USERSPACE */
}

/*test case main entry*/
static void *sys_mutex_tests_setup(void)
{
	int rv;

/* We are on the main thread (supervisor thread).
 * Grant necessary permissions to the main thread.
 * The ztest thread (user thread) will inherit them.
 */
#ifdef CONFIG_USERSPACE
	k_thread_access_grant(k_current_get(),
				&thread_05_thread_data, &thread_05_stack_area,
				&thread_06_thread_data, &thread_06_stack_area,
				&thread_07_thread_data, &thread_07_stack_area,
				&thread_08_thread_data, &thread_08_stack_area,
				&thread_09_thread_data, &thread_09_stack_area,
				&thread_11_thread_data, &thread_11_stack_area,
				&thread_12_thread_data, &thread_12_stack_area);
#endif
	rv = sys_mutex_lock(&not_my_mutex, K_NO_WAIT);
	if (rv != 0) {
		TC_ERROR("Failed to take mutex %p\n", &not_my_mutex);
	}
	return NULL;
}

ZTEST_SUITE(mutex_complex, NULL, sys_mutex_tests_setup, NULL, NULL, NULL);
