/*
 * Copyright (c) 2018 Intel Corporation.
 *
 * SPDX-License-Identifier: Apache-2.0
 */
#include <zephyr.h>
#include <tc_util.h>
#include <ztest.h>
#include <kernel.h>
#include <spinlock.h>

#define CPU1_STACK_SIZE 1024

K_THREAD_STACK_DEFINE(cpu1_stack, CPU1_STACK_SIZE);

static struct k_spinlock bounce_lock;

volatile int bounce_owner, bounce_done;

void test_spinlock_basic(void)
{
	k_spinlock_key_t key;
	static struct k_spinlock l;

	zassert_true(!l.locked, "Spinlock initialized to locked");

	key = k_spin_lock(&l);

	zassert_true(l.locked, "Spinlock failed to lock");

	k_spin_unlock(&l, key);

	zassert_true(!l.locked, "Spinlock failed to unlock");
}

void bounce_once(int id)
{
	int i, locked;
	k_spinlock_key_t key;

	/* Take the lock, check last owner and release if it was us.
	 * Wait for us to get the lock "after" another CPU
	 */
	locked = 0;
	for (i = 0; i < 10000; i++) {
		key = k_spin_lock(&bounce_lock);

		if (bounce_owner != id) {
			locked = 1;
			break;
		}

		k_spin_unlock(&bounce_lock, key);
		k_busy_wait(100);
	}

	if (!locked && bounce_done) {
		return;
	}

	zassert_true(locked, "Other cpu did not get lock in 10000 tries\n");

	/* Mark us as the owner, spin for a while validating that we
	 * never see another owner write to the protected data.
	 */
	bounce_owner = id;

	for (i = 0; i < 100; i++) {
		zassert_true(bounce_owner == id, "Locked data changed");
	}

	/* Release the lock */
	k_spin_unlock(&bounce_lock, key);
}

void cpu1_fn(int key, void *arg)
{
	ARG_UNUSED(key);
	ARG_UNUSED(arg);

	while (1) {
		bounce_once(4321);
	}
}

void test_spinlock_bounce(void)
{
	int i;

	_arch_start_cpu(1, cpu1_stack, CPU1_STACK_SIZE, cpu1_fn, 0);

	k_busy_wait(10);

	for (i = 0; i < 10000; i++) {
		bounce_once(1234);
	}

	bounce_done = 1;
}

void test_main(void)
{
	ztest_test_suite(test_spinlock,
			 ztest_unit_test(test_spinlock_basic),
			 ztest_unit_test(test_spinlock_bounce));
	ztest_run_test_suite(test_spinlock);
}
