/*
 * Copyright (c) 2019 Demant
 *
 * SPDX-License-Identifier: Apache-2.0
 */
#include <zephyr/kernel.h>
#include <zephyr/ztest.h>

/*
 * Test that meta-IRQs return to the cooperative thread they preempted.
 *
 * A meta-IRQ thread unblocks first a long-running low-priority
 * cooperative thread, sleeps a little, and then unblocks a
 * high-priority cooperative thread before the low-priority thread has
 * finished. The correct behavior is to continue execution of the
 * low-priority thread and schedule the high-priority thread
 * afterwards.
 */

#if defined(CONFIG_SMP) && CONFIG_MP_NUM_CPUS > 1
#error Meta-IRQ test requires single-CPU operation
#endif

#if CONFIG_NUM_METAIRQ_PRIORITIES < 1
#error Need one metairq priority
#endif

#if CONFIG_NUM_COOP_PRIORITIES < 2
#error Need two cooperative priorities
#endif


#define STACKSIZE 1024
#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 PARTICIPANT_THREAD_OPTIONS (0)
#define CREATE_PARTICIPANT_THREAD(id, pri, entry)                                      \
		k_thread_create(&thread_##id##_thread_data, thread_##id##_stack_area,  \
			K_THREAD_STACK_SIZEOF(thread_##id##_stack_area),               \
			(k_thread_entry_t)entry,                                       \
			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);


K_SEM_DEFINE(metairq_sem, 0, 1);
K_SEM_DEFINE(coop_sem1, 0, 1);
K_SEM_DEFINE(coop_sem2, 0, 1);

/* Variables to track progress of cooperative threads */
volatile int coop_cnt1;
volatile int coop_cnt2;

#define WAIT_MS  10 /* Time to wait/sleep between actions */
#define LOOP_CNT  4 /* Number of times low priority thread waits */

/* Meta-IRQ thread */
void metairq_thread(void)
{
	k_sem_take(&metairq_sem, K_FOREVER);

	printk("metairq start\n");

	coop_cnt1 = 0;
	coop_cnt2 = 0;

	printk("give sem2\n");
	k_sem_give(&coop_sem2);

	k_msleep(WAIT_MS);

	printk("give sem1\n");
	k_sem_give(&coop_sem1);

	printk("metairq end, should switch back to co-op thread2\n");

	k_sem_give(&metairq_sem);
}

/* High-priority cooperative thread */
void coop_thread1(void)
{
	int cnt1, cnt2;

	printk("thread1 take sem\n");
	k_sem_take(&coop_sem1, K_FOREVER);
	printk("thread1 got sem\n");

	/* Expect that low-priority thread has run to completion */
	cnt1 = coop_cnt1;
	zassert_equal(cnt1, 0, "Unexpected cnt1 at start: %d", cnt1);
	cnt2 = coop_cnt2;
	zassert_equal(cnt2, LOOP_CNT, "Unexpected cnt2 at start: %d", cnt2);

	printk("thread1 increments coop_cnt1\n");
	coop_cnt1++;

	/* Expect that both threads have run to completion */
	cnt1 = coop_cnt1;
	zassert_equal(cnt1, 1, "Unexpected cnt1 at end: %d", cnt1);
	cnt2 = coop_cnt2;
	zassert_equal(cnt2, LOOP_CNT, "Unexpected cnt2 at end: %d", cnt2);

	k_sem_give(&coop_sem1);
}

/* Low-priority cooperative thread */
void coop_thread2(void)
{
	int cnt1, cnt2;

	printk("thread2 take sem\n");
	k_sem_take(&coop_sem2, K_FOREVER);
	printk("thread2 got sem\n");

	/* Expect that this is run first */
	cnt1 = coop_cnt1;
	zassert_equal(cnt1, 0, "Unexpected cnt1 at start: %d", cnt1);
	cnt2 = coop_cnt2;
	zassert_equal(cnt2, 0, "Unexpected cnt2 at start: %d", cnt2);

	/* At some point before this loop has finished, the meta-irq thread
	 * will have woken up and given the semaphore which thread1 was
	 * waiting on. It then exits. We need to ensure that this thread
	 * continues to run after that instead of scheduling thread 1
	 * when the meta-irq exits.
	 */
	for (int i = 0; i < LOOP_CNT; i++) {
		printk("thread2 loop iteration %d\n", i);
		coop_cnt2++;
		k_busy_wait(WAIT_MS * 1000);
	}

	/* Expect that this runs to completion before high-priority
	 * thread is started
	 */
	cnt1 = coop_cnt1;
	zassert_equal(cnt1, 0, "Unexpected cnt1 at end: %d", cnt1);
	cnt2 = coop_cnt2;
	zassert_equal(cnt2, LOOP_CNT, "Unexpected cnt2 at end: %d", cnt2);

	k_sem_give(&coop_sem2);
}

DEFINE_PARTICIPANT_THREAD(metairq_thread_id);
DEFINE_PARTICIPANT_THREAD(coop_thread1_id);
DEFINE_PARTICIPANT_THREAD(coop_thread2_id);

void create_participant_threads(void)
{
	CREATE_PARTICIPANT_THREAD(metairq_thread_id, K_PRIO_COOP(0), metairq_thread);
	CREATE_PARTICIPANT_THREAD(coop_thread1_id, K_PRIO_COOP(1), coop_thread1);
	CREATE_PARTICIPANT_THREAD(coop_thread2_id, K_PRIO_COOP(2), coop_thread2);
}

void start_participant_threads(void)
{
	START_PARTICIPANT_THREAD(metairq_thread_id);
	START_PARTICIPANT_THREAD(coop_thread1_id);
	START_PARTICIPANT_THREAD(coop_thread2_id);
}

void join_participant_threads(void)
{
	JOIN_PARTICIPANT_THREAD(metairq_thread_id);
	JOIN_PARTICIPANT_THREAD(coop_thread1_id);
	JOIN_PARTICIPANT_THREAD(coop_thread2_id);
}

ZTEST(suite_preempt_metairq, test_preempt_metairq)
{
	create_participant_threads();
	start_participant_threads();

	/* This unit test function runs on the ztest thread when
	 * CONFIG_MULTITHREADING=y.
	 * The ztest thread has a priority of CONFIG_ZTEST_THREAD_PRIORITY=-1.
	 * So it is cooperative, which cannot be preempted by the coop_thread1
	 * and coop_thread2 created and started above.
	 * This test requires coop_thread1/2 to wait on coop_sem1/2 before the
	 * metairq thread starts.
	 * Below sleep ensures the ztest thread relinquish the cpu and give
	 * coop_thread1/2 a chance to run and wait on coop_sem1/2.
	 */
	k_msleep(10);

	/* Kick off meta-IRQ */
	k_sem_give(&metairq_sem);

	/* Wait for all threads to finish */
	k_sem_take(&coop_sem2, K_FOREVER);
	k_sem_take(&coop_sem1, K_FOREVER);
	k_sem_take(&metairq_sem, K_FOREVER);

	join_participant_threads();
}

ZTEST_SUITE(suite_preempt_metairq, NULL, NULL, NULL, NULL, NULL);
