/*
 * Copyright (c) 2021 Stephanos Ioannidis <root@stephanos.io>
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/*
 * @file Newlib thread-safety lock test
 *
 * This file contains a set of tests to verify that the newlib retargetable
 * locking interface is functional and the internal newlib locks function as
 * intended.
 */

#include <zephyr/kernel.h>
#include <zephyr/ztest.h>

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <envlock.h>

#define STACK_SIZE	(512 + CONFIG_TEST_EXTRA_STACK_SIZE)

#ifdef CONFIG_USERSPACE
#define THREAD_OPT	(K_USER | K_INHERIT_PERMS)
#else
#define THREAD_OPT	(0)
#endif /* CONFIG_USERSPACE */

static struct k_thread tdata;
static K_THREAD_STACK_DEFINE(tstack, STACK_SIZE);

/* Newlib internal lock functions */
extern void __sfp_lock_acquire(void);
extern void __sfp_lock_release(void);
extern void __sinit_lock_acquire(void);
extern void __sinit_lock_release(void);
extern void __tz_lock(void);
extern void __tz_unlock(void);

/* Static locks */
extern struct k_mutex __lock___sinit_recursive_mutex;
extern struct k_mutex __lock___sfp_recursive_mutex;
extern struct k_mutex __lock___atexit_recursive_mutex;
extern struct k_mutex __lock___malloc_recursive_mutex;
extern struct k_mutex __lock___env_recursive_mutex;
extern struct k_sem __lock___at_quick_exit_mutex;
extern struct k_sem __lock___tz_mutex;
extern struct k_sem __lock___dd_hash_mutex;
extern struct k_sem __lock___arc4random_mutex;

/**
 * @brief Test retargetable locking non-recursive (semaphore) interface
 *
 * This test verifies that a non-recursive lock (semaphore) can be dynamically
 * created, acquired, released and closed through the retargetable locking
 * interface.
 */
ZTEST(newlib_thread_safety_locks, test_retargetable_lock_sem)
{
	_LOCK_T lock = NULL;

	/* Dynamically allocate and initialise a new lock */
	__retarget_lock_init(&lock);
	zassert_not_null(lock, "non-recursive lock init failed");

	/* Acquire lock and verify acquisition */
	__retarget_lock_acquire(lock);
	zassert_equal(__retarget_lock_try_acquire(lock), 0,
		      "non-recursive lock acquisition failed");

	/* Release lock and verify release */
	__retarget_lock_release(lock);
	zassert_not_equal(__retarget_lock_try_acquire(lock), 0,
			  "non-recursive lock release failed");

	/* Close and deallocate lock */
	__retarget_lock_close(lock);
}

static void retargetable_lock_mutex_thread_acq(void *p1, void *p2, void *p3)
{
	_LOCK_T lock = p1;
	int ret;

	/*
	 * Attempt to lock the recursive lock from child thread and verify
	 * that it fails.
	 */
	ret = __retarget_lock_try_acquire_recursive(lock);
	zassert_equal(ret, 0, "recursive lock acquisition failed");
}

static void retargetable_lock_mutex_thread_rel(void *p1, void *p2, void *p3)
{
	_LOCK_T lock = p1;
	int ret;

	/*
	 * Attempt to lock the recursive lock from child thread and verify
	 * that it fails.
	 */
	ret = __retarget_lock_try_acquire_recursive(lock);
	zassert_not_equal(ret, 0, "recursive lock release failed");
}

/**
 * @brief Test retargetable locking recursive (mutex) interface
 *
 * This test verifies that a recursive lock (mutex) can be dynamically created,
 * acquired, released, and closed through the retargetable locking interface.
 */
ZTEST(newlib_thread_safety_locks, test_retargetable_lock_mutex)
{
	_LOCK_T lock = NULL;
	k_tid_t tid;

	/* Dynamically allocate and initialise a new lock */
	__retarget_lock_init_recursive(&lock);
	zassert_not_null(lock, "recursive lock init failed");

	/* Acquire lock from parent thread */
	__retarget_lock_acquire_recursive(lock);

	/* Spawn a lock acquisition check thread and wait for exit */
	tid = k_thread_create(&tdata, tstack, STACK_SIZE,
			      retargetable_lock_mutex_thread_acq, lock,
			      NULL, NULL, K_PRIO_PREEMPT(0), THREAD_OPT,
			      K_NO_WAIT);

	k_thread_join(tid, K_FOREVER);

	/* Release lock from parent thread */
	__retarget_lock_release_recursive(lock);

	/* Spawn a lock release check thread and wait for exit */
	tid = k_thread_create(&tdata, tstack, STACK_SIZE,
			      retargetable_lock_mutex_thread_rel, lock,
			      NULL, NULL, K_PRIO_PREEMPT(0), THREAD_OPT,
			      K_NO_WAIT);

	k_thread_join(tid, K_FOREVER);

	/* Close and deallocate lock */
	__retarget_lock_close_recursive(lock);
}

static void sinit_lock_thread_acq(void *p1, void *p2, void *p3)
{
	int ret;

	/*
	 * Attempt to lock the sinit mutex from child thread using
	 * retargetable locking interface. This operation should fail if the
	 * __sinit_lock_acquire() implementation internally uses the
	 * retargetable locking interface.
	 */
	ret = __retarget_lock_try_acquire_recursive(
			(_LOCK_T)&__lock___sinit_recursive_mutex);

	zassert_equal(ret, 0, "__sinit_lock_acquire() is not using "
			      "retargetable locking interface");
}

static void sinit_lock_thread_rel(void *p1, void *p2, void *p3)
{
	int ret;

	/*
	 * Attempt to lock the sinit mutex from child thread using
	 * retargetable locking interface. This operation should succeed if the
	 * __sinit_lock_release() implementation internally uses the
	 * retargetable locking interface.
	 */
	ret = __retarget_lock_try_acquire_recursive(
			(_LOCK_T)&__lock___sinit_recursive_mutex);

	zassert_not_equal(ret, 0, "__sinit_lock_release() is not using "
				  "retargetable locking interface");

	/* Release sinit lock */
	__retarget_lock_release_recursive(
		(_LOCK_T)&__lock___sinit_recursive_mutex);
}

/**
 * @brief Test sinit lock functions
 *
 * This test calls the __sinit_lock_acquire() and __sinit_lock_release()
 * functions to verify that sinit lock is functional and its implementation
 * is provided by the retargetable locking interface.
 */
ZTEST(newlib_thread_safety_locks, test_sinit_lock)
{
	k_tid_t tid;

	/* Lock the sinit mutex from parent thread */
	__sinit_lock_acquire();

	/* Spawn a lock check thread and wait for exit */
	tid = k_thread_create(&tdata, tstack, STACK_SIZE,
			      sinit_lock_thread_acq, NULL, NULL, NULL,
			      K_PRIO_PREEMPT(0), THREAD_OPT, K_NO_WAIT);

	k_thread_join(tid, K_FOREVER);

	/* Unlock the sinit mutex from parent thread */
	__sinit_lock_release();

	/* Spawn an unlock check thread and wait for exit */
	tid = k_thread_create(&tdata, tstack, STACK_SIZE,
			      sinit_lock_thread_rel, NULL, NULL, NULL,
			      K_PRIO_PREEMPT(0), THREAD_OPT, K_NO_WAIT);

	k_thread_join(tid, K_FOREVER);
}

static void sfp_lock_thread_acq(void *p1, void *p2, void *p3)
{
	int ret;

	/*
	 * Attempt to lock the sfp mutex from child thread using retargetable
	 * locking interface. This operation should fail if the
	 * __sfp_lock_acquire() implementation internally uses the retargetable
	 * locking interface.
	 */
	ret = __retarget_lock_try_acquire_recursive(
			(_LOCK_T)&__lock___sfp_recursive_mutex);

	zassert_equal(ret, 0, "__sfp_lock_acquire() is not using "
			      "retargetable locking interface");
}

static void sfp_lock_thread_rel(void *p1, void *p2, void *p3)
{
	int ret;

	/*
	 * Attempt to lock the sfp mutex from child thread using retargetable
	 * locking interface. This operation should succeed if the
	 * __sfp_lock_release() implementation internally uses the retargetable
	 * locking interface.
	 */
	ret = __retarget_lock_try_acquire_recursive(
			(_LOCK_T)&__lock___sfp_recursive_mutex);

	zassert_not_equal(ret, 0, "__sfp_lock_release() is not using "
				  "retargetable locking interface");

	/* Release sfp lock */
	__retarget_lock_release_recursive(
		(_LOCK_T)&__lock___sfp_recursive_mutex);
}

/**
 * @brief Test sfp lock functions
 *
 * This test calls the __sfp_lock_acquire() and __sfp_lock_release() functions
 * to verify that sfp lock is functional and its implementation is provided by
 * the retargetable locking interface.
 */
ZTEST(newlib_thread_safety_locks, test_sfp_lock)
{
	k_tid_t tid;

	/* Lock the sfp mutex from parent thread */
	__sfp_lock_acquire();

	/* Spawn a lock check thread and wait for exit */
	tid = k_thread_create(&tdata, tstack, STACK_SIZE,
			      sfp_lock_thread_acq, NULL, NULL, NULL,
			      K_PRIO_PREEMPT(0), THREAD_OPT, K_NO_WAIT);

	k_thread_join(tid, K_FOREVER);

	/* Unlock the sfp mutex from parent thread */
	__sfp_lock_release();

	/* Spawn an unlock check thread and wait for exit */
	tid = k_thread_create(&tdata, tstack, STACK_SIZE,
			      sfp_lock_thread_rel, NULL, NULL, NULL,
			      K_PRIO_PREEMPT(0), THREAD_OPT, K_NO_WAIT);

	k_thread_join(tid, K_FOREVER);
}

static void malloc_lock_thread_lock(void *p1, void *p2, void *p3)
{
	int ret;

	/*
	 * Attempt to lock the malloc mutex from child thread using
	 * retargetable locking interface. This operation should fail if the
	 * __malloc_lock() implementation internally uses the retargetable
	 * locking interface.
	 */
	ret = __retarget_lock_try_acquire_recursive(
			(_LOCK_T)&__lock___malloc_recursive_mutex);

	zassert_equal(ret, 0, "__malloc_lock() is not using retargetable "
			      "locking interface");
}

static void malloc_lock_thread_unlock(void *p1, void *p2, void *p3)
{
	int ret;

	/*
	 * Attempt to lock the malloc mutex from child thread using
	 * retargetable locking interface. This operation should succeed if the
	 * __malloc_unlock() implementation internally uses the retargetable
	 * locking interface.
	 */
	ret = __retarget_lock_try_acquire_recursive(
			(_LOCK_T)&__lock___malloc_recursive_mutex);

	zassert_not_equal(ret, 0, "__malloc_unlock() is not using "
				  "retargetable locking interface");

	/* Release malloc lock */
	__retarget_lock_release_recursive(
		(_LOCK_T)&__lock___malloc_recursive_mutex);
}

/**
 * @brief Test malloc lock functions
 *
 * This test calls the __malloc_lock() and __malloc_unlock() functions to
 * verify that malloc lock is functional and its implementation is provided by
 * the retargetable locking interface.
 */
ZTEST(newlib_thread_safety_locks, test_malloc_lock)
{
	k_tid_t tid;

	/* Lock the malloc mutex from parent thread */
	__malloc_lock(_REENT);

	/* Spawn a lock check thread and wait for exit */
	tid = k_thread_create(&tdata, tstack, STACK_SIZE,
			      malloc_lock_thread_lock, NULL, NULL, NULL,
			      K_PRIO_PREEMPT(0), THREAD_OPT, K_NO_WAIT);

	k_thread_join(tid, K_FOREVER);

	/* Unlock the malloc mutex from parent thread */
	__malloc_unlock(_REENT);

	/* Spawn an unlock check thread and wait for exit */
	tid = k_thread_create(&tdata, tstack, STACK_SIZE,
			      malloc_lock_thread_unlock, NULL, NULL, NULL,
			      K_PRIO_PREEMPT(0), THREAD_OPT, K_NO_WAIT);

	k_thread_join(tid, K_FOREVER);
}

static void env_lock_thread_lock(void *p1, void *p2, void *p3)
{
	int ret;

	/*
	 * Attempt to lock the env mutex from child thread using
	 * retargetable locking interface. This operation should fail if the
	 * __env_lock() implementation internally uses the retargetable
	 * locking interface.
	 */
	ret = __retarget_lock_try_acquire_recursive(
			(_LOCK_T)&__lock___env_recursive_mutex);

	zassert_equal(ret, 0, "__env_lock() is not using retargetable "
			      "locking interface");
}

static void env_lock_thread_unlock(void *p1, void *p2, void *p3)
{
	int ret;

	/*
	 * Attempt to lock the env mutex from child thread using
	 * retargetable locking interface. This operation should succeed if the
	 * __env_unlock() implementation internally uses the retargetable
	 * locking interface.
	 */
	ret = __retarget_lock_try_acquire_recursive(
			(_LOCK_T)&__lock___env_recursive_mutex);

	zassert_not_equal(ret, 0, "__env_unlock() is not using "
				  "retargetable locking interface");

	/* Release env lock */
	__retarget_lock_release_recursive(
		(_LOCK_T)&__lock___env_recursive_mutex);
}

/**
 * @brief Test env lock functions
 *
 * This test calls the __env_lock() and __env_unlock() functions to verify
 * that env lock is functional and its implementation is provided by the
 * retargetable locking interface.
 */
ZTEST(newlib_thread_safety_locks, test_env_lock)
{
	k_tid_t tid;

	/* Lock the env mutex from parent thread */
	__env_lock(_REENT);

	/* Spawn a lock check thread and wait for exit */
	tid = k_thread_create(&tdata, tstack, STACK_SIZE,
			      env_lock_thread_lock, NULL, NULL, NULL,
			      K_PRIO_PREEMPT(0), THREAD_OPT, K_NO_WAIT);

	k_thread_join(tid, K_FOREVER);

	/* Unlock the env mutex from parent thread */
	__env_unlock(_REENT);

	/* Spawn an unlock check thread and wait for exit */
	tid = k_thread_create(&tdata, tstack, STACK_SIZE,
			      env_lock_thread_unlock, NULL, NULL, NULL,
			      K_PRIO_PREEMPT(0), THREAD_OPT, K_NO_WAIT);

	k_thread_join(tid, K_FOREVER);
}

/**
 * @brief Test tz lock functions
 *
 * This test calls the __tz_lock() and __tz_unlock() functions to verify that
 * tz lock is functional and its implementation is provided by the retargetable
 * locking interface.
 */
ZTEST(newlib_thread_safety_locks, test_tz_lock)
{
	/* Lock the tz semaphore */
	__tz_lock();

	/* Attempt to acquire lock and verify failure */
	zassert_equal(
		__retarget_lock_try_acquire((_LOCK_T)&__lock___tz_mutex), 0,
		"__tz_lock() is not using retargetable locking interface");

	/* Unlock the tz semaphore */
	__tz_unlock();

	/* Attempt to acquire lock and verify success */
	zassert_not_equal(
		__retarget_lock_try_acquire((_LOCK_T)&__lock___tz_mutex), 0,
		"__tz_unlock() is not using retargetable locking interface");

	/* Clean up */
	__retarget_lock_release((_LOCK_T)&__lock___tz_mutex);
}

void *newlib_thread_safety_locks_setup(void)
{
#ifdef CONFIG_USERSPACE
	k_thread_access_grant(k_current_get(), &tdata, &tstack);
#endif /* CONFIG_USERSPACE */
	return NULL;
}
ZTEST_SUITE(newlib_thread_safety_locks, NULL, newlib_thread_safety_locks_setup, NULL, NULL, NULL);
