@@ -30,10 +30,6 @@ enum iree_hal_semaphore_flag_bits_t {
3030};
3131typedef uint32_t iree_hal_semaphore_flags_t ;
3232
33- //===----------------------------------------------------------------------===//
34- // iree_hal_semaphore_t
35- //===----------------------------------------------------------------------===//
36-
3733// The maximum valid payload value of an iree_hal_semaphore_t.
3834// Payload values larger than this indicate that the semaphore has failed.
3935//
@@ -56,8 +52,66 @@ typedef uint32_t iree_hal_semaphore_flags_t;
5652// https://vulkan.gpuinfo.org/displayextensionproperty.php?name=maxTimelineSemaphoreValueDifference
5753#define IREE_HAL_SEMAPHORE_MAX_VALUE (2147483647ull - 1)
5854
55+ // The minimum value for a semaphore that indicates failure. Any value
56+ // greater-than-or-equal-to (>=) this indicates the semaphore has failed.
57+ //
58+ // If the upper bit 63 is set then the value represents an iree_status_t.
59+ // Use iree_hal_semaphore_failure_as_status to convert a payload value to a
60+ // status. Not all implementations do (or can) support encoding statuses and may
61+ // only ever be able to set a failing semaphore to this value.
5962#define IREE_HAL_SEMAPHORE_FAILURE_VALUE (IREE_HAL_SEMAPHORE_MAX_VALUE + 1)
6063
64+ // Bit indicating that a failing semaphore value can be interpreted as an
65+ // iree_status_t.
66+ #define IREE_HAL_SEMAPHORE_FAILURE_VALUE_STATUS_BIT 0x8000000000000000ull
67+
68+ // Returns a semaphore payload value that encodes the given |status|.
69+ // Ownership of the status is transferred to the semaphore and it must be
70+ // freed by a consumer. Not all implementations can support failure status
71+ // payloads and this should only be used by those implementations that can.
72+ static inline uint64_t iree_hal_status_as_semaphore_failure (
73+ iree_status_t status ) {
74+ return IREE_HAL_SEMAPHORE_FAILURE_VALUE_STATUS_BIT |
75+ (((uint64_t )status ) >> 1 );
76+ }
77+
78+ // Returns OK if the |value| does not indicate an error.
79+ // Returns an error status if the semaphore payload value represents a failure.
80+ // If the payload contains an encoded iree_status_t it will be cloned and the
81+ // new copy will be returned to the caller.
82+ static inline iree_status_t iree_hal_semaphore_failure_as_status (
83+ uint64_t value ) {
84+ if (value >= IREE_HAL_SEMAPHORE_FAILURE_VALUE ) {
85+ if (value & IREE_HAL_SEMAPHORE_FAILURE_VALUE_STATUS_BIT ) {
86+ // The top bits of a pointer are sign-extended from bit 47 so we can
87+ // restore the top bit by left-shifting the upper bits and then
88+ // right-shifting with sign extension. We only use a single bit today and
89+ // so bit 62 should still be the original value of the pointer.
90+ // Note that if the status is just a code (no allocated pointer) this
91+ // clone is a no-op and the code will be returned without an allocation.
92+ //
93+ // See:
94+ // https://en.wikipedia.org/wiki/X86-64#Canonical_form_addresses
95+ return iree_status_clone ((iree_status_t )(((int64_t )value << 1 ) >> 1 ));
96+ } else {
97+ return iree_status_from_code (IREE_STATUS_INTERNAL );
98+ }
99+ } else {
100+ return iree_ok_status ();
101+ }
102+ }
103+
104+ // Frees an iree_status_t encoded in a semaphore |value|, if any.
105+ static inline void iree_hal_semaphore_failure_free (uint64_t value ) {
106+ if (value & IREE_HAL_SEMAPHORE_FAILURE_VALUE_STATUS_BIT ) {
107+ iree_status_free ((iree_status_t )(((int64_t )value << 1 ) >> 1 ));
108+ }
109+ }
110+
111+ //===----------------------------------------------------------------------===//
112+ // iree_hal_semaphore_t
113+ //===----------------------------------------------------------------------===//
114+
61115// Synchronization mechanism for host->device, device->host, host->host,
62116// and device->device notification. Semaphores behave like Vulkan timeline
63117// semaphores (or D3D12 fences) and contain a monotonically increasing
0 commit comments