// Copyright Microsoft and CHERIoT Contributors.
// SPDX-License-Identifier: MIT

#define TEST_NAME "Futex"
#include "tests.hh"
#include <cheri.hh>
#include <cheriot-atomic.hh>
#include <errno.h>
#include <futex.h>
#include <interrupt.h>
#include <thread.h>
#include <thread_pool.h>

using namespace CHERI;
using namespace thread_pool;

#ifdef SAIL
DECLARE_AND_DEFINE_INTERRUPT_CAPABILITY(interruptCapability,
                                        FakeInterrupt,
                                        true,
                                        true);
#endif

void test_futex()
{
	static uint32_t futex;
	int             ret;
	// Make sure that waking a futex with no sleepers doesn't crash!
	ret = futex_wake(&futex, 1);
	TEST(ret == 0, "Waking a futex with no sleepers should return 0");
	// Wake in another thread, ensure that we don't wake until the futex value
	// has been set to 1.
	async([]() {
		futex = 1;
		futex_wake(&futex, 1);
	});
	debug_log("Calling blocking futex_wait");
	ret = futex_wait(&futex, 0);
	TEST(ret == 0, "futex_wait returned {}, expected 0", ret);
	TEST(futex == 1,
	     "Thread should not have woken up until the futex had been set to 1");
	// Check that a futex wait with a mismatched value returns immediately.
	debug_log("Calling futex_wait and expecting immediate return");
	ret = futex_wait(&futex, 0);
	TEST(ret == 0, "futex_wait returned {}, expected 0", ret);
	debug_log("Calling futex with timeout");
	{
		Timeout t{3};
		auto    err = futex_timed_wait(&t, &futex, 1);
		TEST(err == -ETIMEDOUT,
		     "futex_timed_wait returned {}, expected {}",
		     err,
		     -ETIMEDOUT);
		TEST(t.elapsed >= 3,
		     "futex_timed_wait timed out but elapsed ticks {} too small",
		     t.elapsed);
	}
	Timeout t{3};
	auto    err = futex_timed_wait(&t, &futex, 0);
	TEST(err == 0, "futex_timed_wait returned {}, expected {}", err, 0);
	// Some tests for invalid API usage.
	ret = futex_wait(nullptr, 0);
	TEST(ret == -EINVAL,
	     "futex_wait returned {} when called with a null pointer, expected {}",
	     ret,
	     -EINVAL);
	ret = futex_wake(nullptr, 0);
	TEST(ret == -EINVAL,
	     "futex_wake returned {} when called with a null pointer, expected {}",
	     ret,
	     -EINVAL);
	Capability fcap{&futex};
	fcap.permissions() &= PermissionSet::omnipotent().without(Permission::Load);
	ret = futex_wait(fcap, 0);
	TEST(
	  ret == -EINVAL,
	  "futex_wait returned {} when called without load permission, expected {}",
	  ret,
	  -EINVAL);
	fcap = &futex;
	fcap.permissions() &=
	  PermissionSet::omnipotent().without(Permission::Store);
	ret = futex_wake(fcap, 1);
	TEST(ret == -EINVAL,
	     "futex_wake returned {} when called without store permission, "
	     "expected {}",
	     ret,
	     -EINVAL);

#ifdef SAIL
	// If we're targeting Sail, also do some basic tests of the interrupt
	// capability.  We don't have an interrupt controller, so these tests are
	// quite rudimentary.
	Capability<const uint32_t> interruptFutex =
	  interrupt_futex_get(STATIC_SEALED_VALUE(interruptCapability));
	TEST(interruptFutex.is_valid(),
	     "Interrupt futex {} is not valid",
	     interruptFutex);
	TEST(!interruptFutex.permissions().contains(Permission::Store),
	     "Interrupt futex {} should not have store permission",
	     interruptFutex);
	TEST(*interruptFutex == 0,
	     "Interrupt futex {} for fake interrupt should not have fired but "
	     "shows {} interrupts",
	     interruptFutex,
	     *interruptFutex);
	TEST(interrupt_complete(STATIC_SEALED_VALUE(interruptCapability)) == 0,
	     "interrupt_complete returned an error unexpectedly");
	TEST(interrupt_complete(nullptr) != 0,
	     "interrupt_complete returned success unexpectedly");
#endif

	debug_log("Starting priority inheritance test");
	futex = 0;

	static cheriot::atomic<int> state;
	auto                        priorityBug = []() {
        if (thread_id_get() == 2)
        {
            debug_log("Medium-priority task starting");
            // We are the high priority thread, wait for the futex to be
            // acquired and then spin and never yield.
            while (state != 1)
            {
                Timeout t{3};
                thread_sleep(&t);
            }
            debug_log("Consuming all CPU on medium-priority thread");
            state = 2;
            while (state != 4) {}
            debug_log("Finishing medium-priority task");
        }
        else
        {
            debug_log("Low-priority task starting");
            futex = thread_id_get();
            state = 1;
            debug_log("Low-priority thread acquired futex, yielding");
            // Now the high priority thread should run.
            while (state != 3)
            {
                yield();
            }
            debug_log("Low-priority thread finished, unlocking");
            state = 4;
            futex = 0;
            futex_wake(&futex, 1);
        }
	};
	async(priorityBug);
	async(priorityBug);
	debug_log("Waiting for background threads to enter the right state");
	while (state != 2)
	{
		Timeout t{3};
		thread_sleep(&t);
	}
	debug_log("High-priority thread attempting to acquire futex owned by "
	          "low-priority thread without priority propagation");
	state       = 3;
	t.remaining = 1;
	futex_timed_wait(&t, &futex, futex, FutexNone);
	TEST(futex != 0, "Made progress surprisingly!");
	debug_log("High-priority thread attempting to acquire futex owned by "
	          "low-priority thread with priority propagation");
	t.remaining = 4;
	futex_timed_wait(&t, &futex, futex, FutexPriorityInheritance);
	TEST(futex == 0, "Failed to make progress!");

	futex       = 1234;
	t.remaining = 1;
	ret         = futex_timed_wait(&t, &futex, futex, FutexPriorityInheritance);
	TEST(ret == -EINVAL,
	     "PI futex with an invalid thread ID returned {}, should be {}",
	     ret,
	     -EINVAL);

	futex = 0;
	debug_log(
	  "Testing priority inheriting futex_timed_wait with zero thread ID");
	// zero is not a valid thread ID for priority inheriting futex. Previously
	// this caused a crash due to OOB access but better to return -EINVAL.
	ret = futex_timed_wait(&t, &futex, 0, FutexPriorityInheritance);
	TEST(ret == -EINVAL,
	     "PI futex with a zero thread ID returned {}, should be {}",
	     ret,
	     -EINVAL);
}
