blob: c4bb21a883607d54aa0e3bf63e08237c3296b3e2 [file]
// Copyright 2022 The IREE Authors
//
// Licensed under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#ifndef IREE_BASE_WAIT_SOURCE_H_
#define IREE_BASE_WAIT_SOURCE_H_
#include "iree/base/attributes.h"
#include "iree/base/status.h"
#include "iree/base/time.h"
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
//===----------------------------------------------------------------------===//
// iree_wait_source_t
//===----------------------------------------------------------------------===//
typedef struct iree_wait_source_t iree_wait_source_t;
// Callback invoked when a wait source resolves.
// |status| is OK if the wait source reached its target value, or the failure
// status if the underlying primitive failed. Ownership of |status| transfers
// to the callback (the callback must consume or ignore it).
typedef void (*iree_wait_source_resolve_callback_t)(void* user_data,
iree_status_t status);
// Resolves a wait source by checking the current state and either invoking
// |callback| synchronously or registering for asynchronous notification.
//
// |wait_source| carries the target object and value. |timeout| bounds blocking
// for synchronous callers; asynchronous implementations ignore it (the caller
// manages deadlines externally).
//
// When |callback| is NULL the function operates synchronously: it blocks (up
// to |timeout|) and returns OK when the condition is met, or
// IREE_STATUS_DEADLINE_EXCEEDED if it is not met within the timeout, or the
// failure status of the underlying primitive.
//
// When |callback| is non-NULL the function may operate asynchronously: it
// returns OK if the callback was invoked synchronously or was successfully
// registered for later notification (the callback WILL fire eventually).
// Returns an error if registration failed — the callback will NOT fire.
//
// The callback may fire before this function returns (if the condition is
// already satisfied or the primitive has already failed). Callers must be
// prepared for reentrant callback invocation.
typedef iree_status_t (*iree_wait_source_resolve_fn_t)(
iree_wait_source_t wait_source, iree_timeout_t timeout,
iree_wait_source_resolve_callback_t callback, void* user_data);
// A wait source represents a future point in time on some primitive
// (semaphore timeline value, delay deadline, etc.).
typedef struct iree_wait_source_t {
// The object being waited on (e.g. a semaphore pointer).
void* self;
// Implementation-defined data (e.g. timeline value, deadline).
uint64_t data;
// Resolution function. NULL for immediate wait sources.
iree_wait_source_resolve_fn_t resolve;
} iree_wait_source_t;
// Returns a wait source that will always immediately return as resolved.
static inline iree_wait_source_t iree_wait_source_immediate(void) {
iree_wait_source_t v = {NULL, 0ull, NULL};
return v;
}
// Returns true if the |wait_source| is immediately resolved.
// This can be used to neuter waits in lists/sets.
static inline bool iree_wait_source_is_immediate(
iree_wait_source_t wait_source) {
return wait_source.resolve == NULL;
}
// Resolve function for iree_wait_source_delay.
IREE_API_EXPORT iree_status_t iree_wait_source_delay_resolve(
iree_wait_source_t wait_source, iree_timeout_t timeout,
iree_wait_source_resolve_callback_t callback, void* user_data);
// Returns a wait source that indicates a delay until a point in time.
// The source will remain unresolved until the |deadline_ns| is reached or
// exceeded and afterward return resolved.
static inline iree_wait_source_t iree_wait_source_delay(
iree_time_t deadline_ns) {
iree_wait_source_t v = {
NULL,
(uint64_t)deadline_ns,
iree_wait_source_delay_resolve,
};
return v;
}
// Returns true if the |wait_source| is a timed delay.
static inline bool iree_wait_source_is_delay(iree_wait_source_t wait_source) {
return wait_source.resolve == iree_wait_source_delay_resolve;
}
// Queries the state of a |wait_source| without waiting.
// |out_wait_status_code| will indicate the status of the source while the
// returned value indicates the status of the query. |out_wait_status_code| will
// be set to IREE_STATUS_DEFERRED if the wait source has not yet resolved and
// IREE_STATUS_OK otherwise.
IREE_API_EXPORT iree_status_t iree_wait_source_query(
iree_wait_source_t wait_source, iree_status_code_t* out_wait_status_code);
// Blocks the caller and waits for a |wait_source| to resolve.
// Returns IREE_STATUS_DEADLINE_EXCEEDED if |timeout| is reached before the
// wait source resolves. If the wait source resolved with a failure then the
// error status will be returned.
IREE_API_EXPORT iree_status_t iree_wait_source_wait_one(
iree_wait_source_t wait_source, iree_timeout_t timeout);
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
#endif // IREE_BASE_WAIT_SOURCE_H_