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

#pragma once
#include <cdefs.h>

/**
 * The type of a thread-pool callback.  This is a CHERI callback so that it can
 * run in the compartment that schedule the work to run, but a different
 * thread.
 */
typedef __cheri_callback void (*ThreadPoolCallback)(void *);

/**
 * Message to a thread pool.  This encapsulates a simple closure that will be
 * invoked in the next available thread in a thread pool.
 */
struct ThreadPoolMessage
{
	/**
	 * The function pointer that will be called in the thread pool.
	 */
	ThreadPoolCallback invoke;
	/**
	 * The data associated with the asynchronous invocation.
	 */
	void *data;
};

__BEGIN_DECLS

/**
 * Invoke a function that takes a `void*` argument in another thread.  The
 * function will be invoked with `data` as the argument.  The `data` argument
 * must be sealed.
 *
 * This can block indefinitely until the thread pool is able to process a
 * message.
 *
 * FIXME: We should add a non-blocking variant of this.
 *
 * Returns 0 on success, -EINVAL if either of the arguments are invalid.
 */
int __cheri_compartment("thread_pool")
  thread_pool_async(ThreadPoolCallback fn, void *data);

/**
 * Run a thread pool.  This does not return, despite the claimed type, and can
 * be used as a thread entry point.
 */
int __cheri_compartment("thread_pool") thread_pool_run(void);
__END_DECLS

#ifdef __cplusplus
#	include <memory>
#	include <stdlib.h>
#	include <token.h>
#	include <type_traits>
#	include <cheri.hh>
/**
 * For C++ programmers, we provide some more user-friendly wrappers.
 */
namespace thread_pool
{
	/**
	 * Implementation details, should not be used outside of this header.
	 */
	namespace detail
	{
		/**
		 * Helper that generates a different sealing key per type using the
		 * allocator's token mechanism.
		 */
		template<typename T>
		inline SKey sealing_key_for_type()
		{
			static SKey key = token_key_new();
			return key;
		}

		/**
		 * Helper that provides a callback function for invoking and then
		 * freeing a sealed heap-allocated lambda.  The lambda is sealed with
		 * the software-defined sealing key constructed by the
		 * `sealing_key_for_type` helper.
		 */
		template<typename T>
		__cheri_callback void wrap_callback_lambda(void *rawFn)
		{
			auto key = sealing_key_for_type<T>();
			auto fn  = token_unseal(key, Sealed(static_cast<T *>(rawFn)));
			if (fn == nullptr)
			{
				return;
			}
			(*fn)();
			token_obj_destroy(MALLOC_CAPABILITY, key, static_cast<SObj>(rawFn));
		}

		/**
		 * Helper to wrap pure C function (including a stateless lambda) as a
		 * callback.
		 */
		template<typename Fn>
		__cheri_callback void wrap_callback_function(void *)
		{
			// C++ objects are guaranteed to have unique addresses and so a
			// zero-sized object is actually 1 byte and using `sizeof(Fn) == 1`
			// would not let us tell the difference between empty lambdas and
			// ones with a one-byte capture.  To ensure that this object is
			// really stateless, we make it a field of another type, marking it
			// as not requiring a unique address, and then check that the
			// offset of the following field is 0.
			struct Test
			{
				// The stateless callable object
				[[no_unique_address]] Fn f;
				// An field that can share the same address as `f` if `f` is
				// truly stateless.
				char b;
			};
			static_assert(offsetof(Test, b) == 0,
			              "Stateless callable object is not stateless");
			// Invoke an empty instance of this stateless callable object.
			Fn{}();
		}

	} // namespace detail

	/**
	 * Asynchronously invoke a lambda.  This moves the lambda to the heap and
	 * passes it to the thread pool's queue.  If the lambda copies any stack
	 * objects by reference then the copy will fail.
	 *
	 * Returns 0 on success, or compartment-call failures (ENOTENOUGHSTACK,
	 * ENOTENOUGHTRUSTEDSTACK) if the thread pool cannot be invoked.
	 */
	template<typename T>
	int async(T &&lambda)
	{
		// If this is a stateless function, just send a callback function
		// pointer, don't copy zero bytes of state to the heap.
		if constexpr (std::is_convertible_v<T, void (*)(void)>)
		{
			return thread_pool_async(
			  &detail::wrap_callback_function<std::remove_cvref_t<T>>, nullptr);
		}
		else
		{
			// If this is a stateful lambda, move it to the heap, create a
			// callback function that will invoke it and free it, and send a
			// pointer to the wrapper and the heap-allocated object.
			void *buffer;
			using LambdaType = std::remove_reference_t<decltype(lambda)>;
			// Allocate a new sealed object with a key that is unique to this
			// type.
			Timeout t{UnlimitedTimeout};
			void   *sealed = token_sealed_unsealed_alloc(
			    &t,
			    MALLOC_CAPABILITY,
			    detail::sealing_key_for_type<LambdaType>(),
			    sizeof(lambda),
			    &buffer);
			/*
			 * Copy the lambda into the new allocation.
			 *
			 * If the above allocation has failed, this will trap.
			 *
			 * Note: We silence a warning here because we *do* want to
			 * explicitly move, not forward.
			 */
			T *copy = new (buffer) T(
			  std::move(lambda)); // NOLINT(bugprone-move-forwarding-reference)
			// Create the wrapper that will unseal and invoke the lambda.
			ThreadPoolCallback invoke =
			  &detail::wrap_callback_lambda<LambdaType>;
			// Dispatch it.
			return thread_pool_async(invoke, sealed);
		}
	}
} // namespace thread_pool

#endif
