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

/**
 * @file
 * This file contains the benchmarking code that measures the average time it
 * takes to perform context switches between threads using k_yield().
 *
 * When user threads are supported, there are four cases to consider. These are
 *   1. Kernel thread -> Kernel thread
 *   2. User thread   -> User thread
 *   3. Kernel thread -> User thread
 *   4. User thread   -> Kernel thread
 */

#include <zephyr/kernel.h>
#include <zephyr/timing/timing.h>
#include <stdlib.h>
#include <zephyr/timestamp.h>

#include "utils.h"
#include "timing_sc.h"

static void alt_thread_entry(void *p1, void *p2, void *p3)
{
	uint32_t  num_iterations;

	ARG_UNUSED(p2);
	ARG_UNUSED(p2);

	num_iterations = (uint32_t)(uintptr_t)p1;

	for (uint32_t i = 0; i < num_iterations; i++) {

		/* 3. Obtain the 'finish' timestamp */

		timestamp.sample = timing_timestamp_get();

		/* 4. Switch to <start_thread>  */

		k_yield();
	}

}

static void start_thread_entry(void *p1, void *p2, void *p3)
{
	uint64_t  sum = 0ull;
	uint32_t  num_iterations;
	timing_t  start;
	timing_t  finish;

	ARG_UNUSED(p2);
	ARG_UNUSED(p2);

	num_iterations = (uint32_t)(uintptr_t)p1;

	k_thread_start(&alt_thread);

	for (uint32_t i = 0; i < num_iterations; i++) {

		/* 1. Get 'start' timestamp */

		start = timing_timestamp_get();

		/* 2. Switch to <alt_thread> */

		k_yield();

		/* 5. Get the 'finish' timestamp obtained in <alt_thread> */

		finish = timestamp.sample;

		/* 6. Track the sum of elapsed times */

		sum += timing_cycles_get(&start, &finish);
	}

	/* Wait for <alt_thread> to complete */

	k_thread_join(&alt_thread, K_FOREVER);

	/* Record the number of cycles for use by the main thread */

	timestamp.cycles = sum;
}

static void thread_switch_yield_common(const char *description,
				       uint32_t num_iterations,
				       uint32_t start_options,
				       uint32_t alt_options,
				       int priority)
{
	uint64_t  sum;
	char summary[80];

	/* Create the two threads */

	k_thread_create(&start_thread, start_stack,
			K_THREAD_STACK_SIZEOF(start_stack),
			start_thread_entry,
			(void *)(uintptr_t)num_iterations, NULL, NULL,
			priority - 1, start_options, K_FOREVER);

	k_thread_create(&alt_thread, alt_stack,
			K_THREAD_STACK_SIZEOF(alt_stack),
			alt_thread_entry,
			(void *)(uintptr_t)num_iterations, NULL, NULL,
			priority - 1, alt_options, K_FOREVER);

	/* Grant access rights if necessary */

	if ((start_options & K_USER) == K_USER) {
		k_thread_access_grant(&start_thread, &alt_thread);
	}

	k_thread_start(&start_thread);

	/* Wait until <start_thread> finishes */

	k_thread_join(&start_thread, K_FOREVER);

	/* Get the sum total of measured cycles */

	sum = timestamp.cycles;

	sum -= timestamp_overhead_adjustment(start_options, alt_options);

	snprintf(summary, sizeof(summary),
		 "%s (%c -> %c)",
		 description,
		 (start_options & K_USER) == K_USER ? 'U' : 'K',
		 (alt_options & K_USER) == K_USER ? 'U' : 'K');

	PRINT_STATS_AVG(summary, (uint32_t)sum, num_iterations, 0, "");
}

void thread_switch_yield(uint32_t num_iterations, bool is_cooperative)
{
	int  priority;
	char description[60];

	priority = is_cooperative ? K_PRIO_COOP(6)
				  : k_thread_priority_get(k_current_get()) - 1;

	snprintf(description, sizeof(description),
		 "%s threads ctx switch via k_yield",
		 is_cooperative ? "Cooperative" : "Preemptive");

	/* Kernel -> Kernel */
	thread_switch_yield_common(description, num_iterations, 0, 0,
				   priority);

#if CONFIG_USERSPACE
	/* User   -> User   */
	thread_switch_yield_common(description, num_iterations, K_USER, K_USER,
				   priority);

	/* Kernel -> User   */
	thread_switch_yield_common(description, num_iterations, 0, K_USER,
				   priority);

	/* User   -> Kernel */
	thread_switch_yield_common(description, num_iterations, K_USER, 0,
				   priority);
#endif
}
