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

/*
 * @file Newlib thread-safety stress test
 *
 * This file contains a set of tests to verify that the C standard functions
 * provided by newlib are thread safe (i.e. synchronised) and that the thread-
 * specific contexts are properly handled (i.e. re-entrant).
 */

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

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

#define THREAD_COUNT	(64)
#define STACK_SIZE	(512 + CONFIG_TEST_EXTRA_STACK_SIZE)
#define TEST_INTERVAL	(30) /* seconds */

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

static struct k_thread tdata[THREAD_COUNT];
static K_THREAD_STACK_ARRAY_DEFINE(tstack, THREAD_COUNT, STACK_SIZE);

static void malloc_thread(void *p1, void *p2, void *p3)
{
	static ZTEST_BMEM atomic_t count;
	bool *aborted = p1;
	int val;
	int *volatile ptr;

	while (*aborted == false) {
		/* Compute unique value specific to this iteration. */
		val = atomic_inc(&count);

		/* Allocate memory block and write a unique value to it. */
		ptr = malloc(sizeof(int));
		zassert_not_null(ptr, "Out of memory");
		*ptr = val;

		/* Busy wait to increase the likelihood of preemption. */
		k_busy_wait(10);

		/*
		 * Verify that the unique value previously written to the
		 * memory block is valid.  This value will become corrupted if
		 * the newlib heap is not properly synchronised.
		 */
		zassert_equal(*ptr, val, "Corrupted memory block");

		/* Free memory block. */
		free(ptr);
	}
}

/**
 * @brief Test thread safety of newlib memory management functions
 *
 * This test calls the malloc() and free() functions from multiple threads to
 * verify that no corruption occurs in the newlib memory heap.
 */
ZTEST(newlib_thread_safety_stress, test_malloc_thread_safety)
{
	int i;
	k_tid_t tid[THREAD_COUNT];
	static ZTEST_BMEM bool aborted;

	/* Create worker threads. */
	for (i = 0; i < ARRAY_SIZE(tid); i++) {
		tid[i] = k_thread_create(&tdata[i], tstack[i], STACK_SIZE,
					 malloc_thread, &aborted, NULL, NULL,
					 K_PRIO_PREEMPT(0), THREAD_OPT,
					 K_NO_WAIT);
	}

	TC_PRINT("Created %d worker threads.\n", THREAD_COUNT);

	/* Wait and see if any failures occur. */
	TC_PRINT("Waiting %d seconds to see if any failures occur ...\n",
		 TEST_INTERVAL);

	k_sleep(K_SECONDS(TEST_INTERVAL));

	/* Abort all worker threads. */
	aborted = true;

	for (i = 0; i < ARRAY_SIZE(tid); i++) {
		k_thread_join(tid[i], K_FOREVER);
	}
}
ZTEST_SUITE(newlib_thread_safety_stress, NULL, NULL, NULL, NULL, NULL);
