/*
 * Copyright (c) 2018 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/*
 * @file
 * @brief Test early sleeping
 *
 * This test verifies that k_sleep() can be used
 * to put the calling thread to sleep for a specified
 * number of ticks during system initialization.
 * In this test we are calling k_sleep() at POST_KERNEL
 * and APPLICATION level initialization sequence.
 *
 * Note: We can not call k_sleep() during PRE_KERNEL1
 * or PRE_KERNEL2 level because the core kernel objects
 * and devices initialization happens at these levels.
 */

#include <init.h>
#include <arch/cpu.h>
#include <sys_clock.h>
#include <stdbool.h>
#include <tc_util.h>
#include <ztest.h>

#define THREAD_STACK		(384 + CONFIG_TEST_EXTRA_STACKSIZE)

#define TEST_TICKS_TO_SLEEP	50

/* Helper thread data */
static K_THREAD_STACK_DEFINE(helper_tstack, THREAD_STACK);
static struct k_thread helper_tdata;
static k_tid_t  helper_ttid;

/* time that the thread was actually sleeping */
static int actual_sleep_ticks;
static int actual_post_kernel_sleep_ticks;
static int actual_app_sleep_ticks;

static bool test_failure = true;

static void helper_thread(void *p1, void *p2, void *p3)
{
	test_failure = false;
}

static int ticks_to_sleep(int ticks)
{
	u32_t start_time;
	u32_t stop_time;

	start_time = k_cycle_get_32();
	k_sleep(__ticks_to_ms(ticks));
	stop_time = k_cycle_get_32();

	return (stop_time - start_time) / sys_clock_hw_cycles_per_tick;
}


static int test_early_sleep_post_kernel(struct device *unused)
{
	ARG_UNUSED(unused);
	actual_post_kernel_sleep_ticks = ticks_to_sleep(TEST_TICKS_TO_SLEEP);
	return 0;
}

SYS_INIT(test_early_sleep_post_kernel,
		POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE);

static int test_early_sleep_app(struct device *unused)
{
	ARG_UNUSED(unused);
	actual_app_sleep_ticks = ticks_to_sleep(TEST_TICKS_TO_SLEEP);
	return 0;
}

SYS_INIT(test_early_sleep_app, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEVICE);

static void verify_early_sleep(void)
{
	TC_PRINT("Testing early sleeping\n");

	/*
	 * Main thread(test_main) priority is 0 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(), 0);

	TC_PRINT("msec per tick: %d, ticks to sleep: %d\n",
			_ms_per_tick, TEST_TICKS_TO_SLEEP);

	/* Create a lower priority thread */
	helper_ttid = k_thread_create(&helper_tdata,
				   helper_tstack, THREAD_STACK,
				   helper_thread, NULL, NULL, NULL,
				   k_thread_priority_get(k_current_get()) + 1,
				   K_INHERIT_PERMS, 0);

	TC_PRINT("k_sleep() ticks at POST_KERNEL level: %d\n",
					actual_post_kernel_sleep_ticks);
	zassert_true((actual_post_kernel_sleep_ticks + 1) >
					TEST_TICKS_TO_SLEEP, NULL);

	TC_PRINT("k_sleep() ticks at APPLICATION level: %d\n",
					actual_app_sleep_ticks);
	zassert_true((actual_app_sleep_ticks + 1) >
					TEST_TICKS_TO_SLEEP, NULL);

	actual_sleep_ticks = ticks_to_sleep(TEST_TICKS_TO_SLEEP);
	TC_PRINT("k_sleep() ticks on running system: %d\n",
					actual_sleep_ticks);
	zassert_true((actual_sleep_ticks + 1) >
					TEST_TICKS_TO_SLEEP, NULL);

	zassert_false(test_failure, "Lower priority thread not ran!!");
}

/*test case main entry*/
void test_main(void)
{
	ztest_test_suite(test_earlysleep,
			ztest_unit_test(verify_early_sleep));
	ztest_run_test_suite(test_earlysleep);
}
