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

#pragma once
/**
 * @file multiwaiter.h
 *
 * This file provides interfaces to the multi-waiter system.  A multi-waiter
 * object (or 'multiwaiter') is an object that allows a calling thread to
 * suspend execution until one of a set of events has occurred.
 *
 * The CHERIoT multiwaiter system is designed to avoid allocation (or
 * interaction with the allocator) on the fast path.  The scheduler may not
 * capture any of the arguments to the multiwaiter's wait call and expose them
 * to other threads unless they are heap allocated.  It must also be robust in
 * the presence of malicious code that attempts to concurrently mutate any data
 * structures while sleeping.
 *
 * The multiwaiter object is allocated with space to wait for *n* objects, up
 * to a fixed limit.  Each wait call provides a set of things to wait on and
 * will suspend until either one occurs or a timeout is reached.  On return,
 * the caller-provided list will be updated.  This list can be allocated on the
 * stack: the scheduler does not need to hold a copy of it between calls or
 * write to it from another thread.
 *
 * The multiwaiter should be used sparingly.  In the worst case, it can add a
 * linear-complexity overhead on all wake events.  Memory overhead and code
 * size have been the key optimisation goals for this design.  Unlike systems
 * such as `kqueue`, scalability has not been a priority in this design because
 * expected number of waited objects is small and so is the number of threads.
 */
#include <compartment.h>
#include <stdlib.h>
#include <timeout.h>

/**
 * The kind of event source to wait for in a multiwaiter.
 */
enum EventWaiterKind
{
	/// Event source is an event channel.
	EventWaiterEventChannel,
	/// Event source is a futex.
	EventWaiterFutex
};

enum [[clang::flag_enum]] EventWaiterEventChannelFlags{
  /// Automatically clear the bits we waited on.
  EventWaiterEventChannelClearOnExit = (1 << 24),
  /// Notify when all bits were set.
  EventWaiterEventChannelWaitAll = (1 << 26)};

/**
 * Structure describing a change to the set of managed event sources for an
 * event waiter.
 */
struct EventWaiterSource
{
	/**
	 * A pointer to the event source.  For a futex, this should be the memory
	 * address.  For other sources, it should be a pointer to an object of the
	 * corresponding type.
	 */
	void *eventSource;
	/**
	 * The kind of the event source.  This must match the pointer type.
	 */
	enum EventWaiterKind kind;
	/**
	 * Event-specific configuration.  This field is modified during the wait
	 * call.  The interpretation of this depends on `kind`:
	 *
	 * - `EventWaiterEventChannel`: The low 24 bits contain the bits to
	 *   monitor, the top bit indicates whether this event is triggered if all
	 *   of the bits are set (true) or some of them (false).  On return, this
	 *   contains the bits that have been set during the call.
	 * - `EventWaiterFutex`: This indicates the value to compare the futex word
	 *   against.  If they mismatch, the event fires immediately.
	 *
	 * If waiting for a futex, signal the event immediately if the value
	 * does not match.  On return, this is set to 1 if the futex is
	 * signaled, 0 otherwise.
	 */
	uint32_t value;
};

/**
 * Opqaue type for multiwaiter objects.  Callers will always see this as a
 * sealed object.
 */
struct MultiWaiter;

/**
 * Create a multiwaiter object.  This is a stateful object that can wait on at
 * most `maxItems` event sources.
 */
[[cheri::interrupt_state(disabled)]] int __cheri_compartment("sched")
  multiwaiter_create(Timeout             *timeout,
                     struct SObjStruct   *heapCapability,
                     struct MultiWaiter **ret,
                     size_t               maxItems);

/**
 * Destroy a multiwaiter object.
 */
[[cheri::interrupt_state(disabled)]] int __cheri_compartment("sched")
  multiwaiter_delete(struct SObjStruct *heapCapability, struct MultiWaiter *mw);

/**
 * Wait for events.  The first argument is the multiwaiter to wait on.  New
 * events can optionally be added by providing an array of `newEventsCount`
 * elements as the `newEvents` argument.
 *
 * Return values:
 *
 *  - On success, this function returns 0.
 *  - If the arguments are invalid, this function returns -EINVAL.
 *  - If the timeout is reached without any events being triggered then this
 *    returns -ETIMEOUT.
 */
[[cheri::interrupt_state(disabled)]] int __cheri_compartment("sched")
  multiwaiter_wait(Timeout                  *timeout,
                   struct MultiWaiter       *waiter,
                   struct EventWaiterSource *events,
                   size_t                    newEventsCount);
