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

/**
 * @file
 *
 * @brief Measure context switch time between cooperative threads
 *
 * This file contains thread (coop) context switch time measurement.
 * The thread starts two cooperative thread. One thread waits on a semaphore. The other,
 * after starting, releases a semaphore which enable the first thread to run.
 * Each thread increases a common global counter and context switch back and
 * forth by yielding the cpu. When counter reaches the maximal value, threads
 * stop and the average time of context switch is displayed.
 */
#include <kernel.h>
#include <timing/timing.h>
#include "utils.h"

/* number of context switches */
#define NCTXSWITCH 10000
#ifndef STACKSIZE
#define STACKSIZE (512 + CONFIG_TEST_EXTRA_STACKSIZE)
#endif

/* stack used by the threads */
static K_THREAD_STACK_DEFINE(thread_one_stack, STACKSIZE);
static K_THREAD_STACK_DEFINE(thread_two_stack, STACKSIZE);
static struct k_thread thread_one_data;
static struct k_thread thread_two_data;

static timing_t timestamp_start;
static timing_t timestamp_end;

/* context switches counter */
static volatile uint32_t ctx_switch_counter;

/* context switch balancer. Incremented by one thread, decremented by another*/
static volatile int ctx_switch_balancer;

K_SEM_DEFINE(sync_sema, 0, 1);

/**
 *
 * thread_onne
 *
 * Fiber makes all the test preparations: registers the interrupt handler,
 * gets the first timestamp and invokes the software interrupt.
 *
 * @return N/A
 */
static void thread_one(void)
{
	k_sem_take(&sync_sema, K_FOREVER);

	timestamp_start = timing_counter_get();

	while (ctx_switch_counter < NCTXSWITCH) {
		k_yield();
		ctx_switch_counter++;
		ctx_switch_balancer--;
	}

	timestamp_end = timing_counter_get();
}

/**
 *
 * @brief Check the time when it gets executed after the semaphore
 *
 * Fiber starts, waits on semaphore. When the interrupt handler releases
 * the semaphore, thread  measures the time.
 *
 * @return 0 on success
 */
static void thread_two(void)
{
	k_sem_give(&sync_sema);
	while (ctx_switch_counter < NCTXSWITCH) {
		k_yield();
		ctx_switch_counter++;
		ctx_switch_balancer++;
	}
}

/**
 *
 * @brief The test main function
 *
 * @return 0 on success
 */
int coop_ctx_switch(void)
{
	ctx_switch_counter = 0U;
	ctx_switch_balancer = 0;

	timing_start();
	bench_test_start();

	k_thread_create(&thread_one_data, thread_one_stack, STACKSIZE,
			(k_thread_entry_t)thread_one, NULL, NULL, NULL,
			K_PRIO_COOP(6), 0, K_NO_WAIT);
	k_thread_create(&thread_two_data, thread_two_stack, STACKSIZE,
			(k_thread_entry_t)thread_two, NULL, NULL, NULL,
			K_PRIO_COOP(6), 0, K_NO_WAIT);

	if (ctx_switch_balancer > 3 || ctx_switch_balancer < -3) {
		printk(" Balance is %d. FAILED", ctx_switch_balancer);
	} else if (bench_test_end() != 0) {
		error_count++;
		PRINT_OVERFLOW_ERROR();
	} else {
		uint32_t diff;

		diff = timing_cycles_get(&timestamp_start, &timestamp_end);
		PRINT_STATS_AVG("Average context switch time between threads (coop)", diff, ctx_switch_counter);
	}

	timing_stop();

	return 0;
}
